From f1197a6db2bf1d667c02802bdb41e70634d12e0b Mon Sep 17 00:00:00 2001
From: elitsa
Date: Thu, 27 Dec 2018 13:23:20 +0100
Subject: [PATCH 01/84] Adding shortcuts for closing an infinite editor through
Escape key.
---
.../common/infiniteeditors/compositions/compositions.html | 1 +
.../src/views/common/infiniteeditors/copy/copy.html | 1 +
.../common/infiniteeditors/datatypepicker/datatypepicker.html | 3 ++-
.../infiniteeditors/datatypesettings/datatypesettings.html | 3 ++-
.../src/views/common/infiniteeditors/embed/embed.html | 1 +
.../views/common/infiniteeditors/iconpicker/iconpicker.html | 3 ++-
.../infiniteeditors/insertcodesnippet/insertcodesnippet.html | 1 +
.../views/common/infiniteeditors/insertfield/insertfield.html | 1 +
.../views/common/infiniteeditors/itempicker/itempicker.html | 1 +
.../views/common/infiniteeditors/linkpicker/linkpicker.html | 1 +
.../infiniteeditors/membergrouppicker/membergrouppicker.html | 1 +
.../src/views/common/infiniteeditors/move/move.html | 1 +
.../infiniteeditors/nodepermissions/nodepermissions.html | 1 +
.../infiniteeditors/propertysettings/propertysettings.html | 1 +
.../common/infiniteeditors/querybuilder/querybuilder.html | 3 ++-
.../src/views/common/infiniteeditors/rollback/rollback.html | 3 ++-
.../common/infiniteeditors/sectionpicker/sectionpicker.html | 3 ++-
.../infiniteeditors/templatesections/templatesections.html | 1 +
.../views/common/infiniteeditors/treepicker/treepicker.html | 1 +
.../infiniteeditors/usergrouppicker/usergrouppicker.html | 3 ++-
.../views/common/infiniteeditors/userpicker/userpicker.html | 3 ++-
.../stylesheets/infiniteeditors/richtextrule/richtextrule.html | 1 +
22 files changed, 30 insertions(+), 8 deletions(-)
diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/compositions/compositions.html b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/compositions/compositions.html
index 84fbab7cb2..bf74431d96 100644
--- a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/compositions/compositions.html
+++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/compositions/compositions.html
@@ -110,6 +110,7 @@
type="button"
button-style="link"
label-key="general_close"
+ shortcut="esc"
action="vm.close()">
@@ -138,4 +139,4 @@
-
\ No newline at end of file
+
diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/datatypesettings/datatypesettings.html b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/datatypesettings/datatypesettings.html
index b4ff894c4d..620f9f1731 100644
--- a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/datatypesettings/datatypesettings.html
+++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/datatypesettings/datatypesettings.html
@@ -52,6 +52,7 @@
type="button"
button-style="link"
label-key="general_close"
+ shortcut="esc"
action="vm.close()">
-
\ No newline at end of file
+
diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/embed/embed.html b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/embed/embed.html
index f14fb364ab..e48ec84b25 100644
--- a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/embed/embed.html
+++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/embed/embed.html
@@ -54,6 +54,7 @@
type="button"
button-style="link"
label-key="general_close"
+ shortcut="esc"
action="vm.close()">
@@ -75,4 +76,4 @@
-
\ No newline at end of file
+
diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/insertcodesnippet/insertcodesnippet.html b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/insertcodesnippet/insertcodesnippet.html
index 2ccbf11cc1..ea247c77e5 100644
--- a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/insertcodesnippet/insertcodesnippet.html
+++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/insertcodesnippet/insertcodesnippet.html
@@ -47,6 +47,7 @@
type="button"
button-style="link"
label-key="general_close"
+ shortcut="esc"
action="vm.close()">
diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/insertfield/insertfield.html b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/insertfield/insertfield.html
index 56bd498fd1..16f4bfb919 100644
--- a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/insertfield/insertfield.html
+++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/insertfield/insertfield.html
@@ -207,6 +207,7 @@
type="button"
button-style="link"
label-key="general_close"
+ shortcut="esc"
action="vm.close()">
diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/linkpicker/linkpicker.html b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/linkpicker/linkpicker.html
index a50ab4242d..71fcf2f493 100644
--- a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/linkpicker/linkpicker.html
+++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/linkpicker/linkpicker.html
@@ -120,6 +120,7 @@
type="button"
button-style="link"
label-key="general_close"
+ shortcut="esc"
action="vm.close()">
diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/propertysettings/propertysettings.html b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/propertysettings/propertysettings.html
index df5bbe8ca5..4c7f2613b5 100644
--- a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/propertysettings/propertysettings.html
+++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/propertysettings/propertysettings.html
@@ -155,6 +155,7 @@
type="button"
button-style="link"
label-key="general_close"
+ shortcut="esc"
action="vm.close()">
diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/querybuilder/querybuilder.html b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/querybuilder/querybuilder.html
index 4b6c6cc179..725871337d 100644
--- a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/querybuilder/querybuilder.html
+++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/querybuilder/querybuilder.html
@@ -193,6 +193,7 @@
type="button"
button-style="link"
label-key="general_close"
+ shortcut="esc"
action="vm.close()">
@@ -209,4 +210,4 @@
-
\ No newline at end of file
+
diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/rollback/rollback.html b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/rollback/rollback.html
index b5b925b266..d7ba57c1af 100644
--- a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/rollback/rollback.html
+++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/rollback/rollback.html
@@ -86,6 +86,7 @@
type="button"
button-style="link"
label-key="general_close"
+ shortcut="esc"
action="vm.close()">
-
\ No newline at end of file
+
diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/sectionpicker/sectionpicker.html b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/sectionpicker/sectionpicker.html
index 8ca1993dcc..2e88bf709c 100644
--- a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/sectionpicker/sectionpicker.html
+++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/sectionpicker/sectionpicker.html
@@ -38,6 +38,7 @@
type="button"
button-style="link"
label-key="general_close"
+ shortcut="esc"
action="vm.close()">
-
\ No newline at end of file
+
diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/templatesections/templatesections.html b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/templatesections/templatesections.html
index d6e3996287..5b946976d7 100644
--- a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/templatesections/templatesections.html
+++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/templatesections/templatesections.html
@@ -87,6 +87,7 @@
type="button"
button-style="link"
label-key="general_close"
+ shortcut="esc"
action="vm.close()">
diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/usergrouppicker/usergrouppicker.html b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/usergrouppicker/usergrouppicker.html
index e97d80648b..e2ae1ab524 100644
--- a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/usergrouppicker/usergrouppicker.html
+++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/usergrouppicker/usergrouppicker.html
@@ -84,6 +84,7 @@
type="button"
button-style="link"
label-key="general_close"
+ shortcut="esc"
action="vm.close()">
-
\ No newline at end of file
+
diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/userpicker/userpicker.html b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/userpicker/userpicker.html
index bc6c8b5761..e39d693b47 100644
--- a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/userpicker/userpicker.html
+++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/userpicker/userpicker.html
@@ -74,6 +74,7 @@
type="button"
button-style="link"
label-key="general_close"
+ shortcut="esc"
action="vm.close()">
-
\ No newline at end of file
+
diff --git a/src/Umbraco.Web.UI.Client/src/views/stylesheets/infiniteeditors/richtextrule/richtextrule.html b/src/Umbraco.Web.UI.Client/src/views/stylesheets/infiniteeditors/richtextrule/richtextrule.html
index a36f3ef6a2..557341fe1b 100644
--- a/src/Umbraco.Web.UI.Client/src/views/stylesheets/infiniteeditors/richtextrule/richtextrule.html
+++ b/src/Umbraco.Web.UI.Client/src/views/stylesheets/infiniteeditors/richtextrule/richtextrule.html
@@ -53,6 +53,7 @@
type="button"
button-style="link"
label-key="general_close"
+ shortcut="esc"
action="vm.close()">
Date: Thu, 3 Jan 2019 16:38:37 +0100
Subject: [PATCH 02/84] Fix for wrong sorting overload in MediaService (#3948)
---
src/Umbraco.Core/Services/MediaService.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/Umbraco.Core/Services/MediaService.cs b/src/Umbraco.Core/Services/MediaService.cs
index d1f11c619a..b95a8a258c 100644
--- a/src/Umbraco.Core/Services/MediaService.cs
+++ b/src/Umbraco.Core/Services/MediaService.cs
@@ -509,7 +509,7 @@ namespace Umbraco.Core.Services
public IEnumerable GetPagedChildren(int id, long pageIndex, int pageSize, out long totalChildren,
string orderBy, Direction orderDirection, bool orderBySystemField, string filter)
{
- return GetPagedChildren(id, pageIndex, pageSize, out totalChildren, orderBy, orderDirection, true, filter, null);
+ return GetPagedChildren(id, pageIndex, pageSize, out totalChildren, orderBy, orderDirection, orderBySystemField, filter, null);
}
///
From cc6c16894c288f422140482f55bd773e01df08f8 Mon Sep 17 00:00:00 2001
From: Kenn Jacobsen
Date: Sun, 6 Jan 2019 19:11:58 +0100
Subject: [PATCH 03/84] Safeguard the tags value converter against empty tags
---
.../ValueConverters/TagsValueConverter.cs | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/src/Umbraco.Core/PropertyEditors/ValueConverters/TagsValueConverter.cs b/src/Umbraco.Core/PropertyEditors/ValueConverters/TagsValueConverter.cs
index b085748487..204fde0c2e 100644
--- a/src/Umbraco.Core/PropertyEditors/ValueConverters/TagsValueConverter.cs
+++ b/src/Umbraco.Core/PropertyEditors/ValueConverters/TagsValueConverter.cs
@@ -42,16 +42,22 @@ namespace Umbraco.Core.PropertyEditors.ValueConverters
public override object ConvertDataToSource(PublishedPropertyType propertyType, object source, bool preview)
{
+ var sourceAsString = source?.ToString();
+ if(sourceAsString.IsNullOrWhiteSpace())
+ {
+ return new string[0];
+ }
+
// if Json storage type deserialzie and return as string array
if (JsonStorageType(propertyType.DataTypeId))
{
- var jArray = JsonConvert.DeserializeObject(source.ToString());
+ var jArray = JsonConvert.DeserializeObject(sourceAsString);
return jArray.ToObject();
}
// Otherwise assume CSV storage type and return as string array
var csvTags =
- source.ToString()
+ sourceAsString
.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries)
.ToArray();
return csvTags;
From 4564623899fb265f5dc1cb62ddbf7d43a169e4e1 Mon Sep 17 00:00:00 2001
From: Kenn Jacobsen
Date: Thu, 3 Jan 2019 21:04:59 +0100
Subject: [PATCH 04/84] Don't use a hardcoded folder type alias to determine
folder types in the list view
---
.../views/propertyeditors/listview/listview.controller.js | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/listview.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/listview.controller.js
index 118f1b81d2..df7a574c49 100644
--- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/listview.controller.js
+++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/listview.controller.js
@@ -1,4 +1,4 @@
-function listViewController($rootScope, $scope, $routeParams, $injector, $cookieStore, notificationsService, iconHelper, dialogService, editorState, localizationService, $location, appState, $timeout, $q, mediaResource, listViewHelper, userService, navigationService, treeService) {
+function listViewController($rootScope, $scope, $routeParams, $injector, $cookieStore, notificationsService, iconHelper, dialogService, editorState, localizationService, $location, appState, $timeout, $q, mediaResource, listViewHelper, userService, navigationService, treeService, mediaHelper) {
//this is a quick check to see if we're in create mode, if so just exit - we cannot show children for content
// that isn't created yet, if we continue this will use the parent id in the route params which isn't what
@@ -269,10 +269,12 @@ function listViewController($rootScope, $scope, $routeParams, $injector, $cookie
$scope.listViewResultSet = data;
//update all values for display
+ var section = appState.getSectionState("currentSection");
if ($scope.listViewResultSet.items) {
_.each($scope.listViewResultSet.items, function (e, index) {
setPropertyValues(e);
- if (e.contentTypeAlias === 'Folder') {
+ // create the folders collection (only for media list views)
+ if (section === "media" && !mediaHelper.hasFilePropertyType(e)) {
$scope.folders.push(e);
}
});
From d53d0b4271110d49dfc5bcaadff1c68ef6506385 Mon Sep 17 00:00:00 2001
From: Sebastiaan Janssen
Date: Mon, 7 Jan 2019 12:53:31 +0100
Subject: [PATCH 05/84] Add disabled state to toggle (#3967)
(cherry picked from commit d231db8ef25455c2d1f291b9b707e4d95a251a9f)
# Conflicts:
# src/Umbraco.Web.UI.Client/src/views/languages/edit.html
---
.../components/buttons/umbtoggle.directive.js | 4 ++++
.../src/less/components/buttons/umb-toggle.less | 10 ++++++++--
.../src/less/components/users/umb-permission.less | 6 ++++++
.../src/views/components/buttons/umb-toggle.html | 2 +-
4 files changed, 19 insertions(+), 3 deletions(-)
diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/buttons/umbtoggle.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/buttons/umbtoggle.directive.js
index e3c4cbf40c..c2c9ec068b 100644
--- a/src/Umbraco.Web.UI.Client/src/common/directives/components/buttons/umbtoggle.directive.js
+++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/buttons/umbtoggle.directive.js
@@ -18,6 +18,7 @@
@param {boolean} checked Set to true or false to toggle the switch.
+@param {boolean} disabled Set to true or false to disable the switch.
@param {callback} onClick The function which should be called when the toggle is clicked.
@param {string=} showLabels Set to true or false to show a "On" or "Off" label next to the switch.
@param {string=} labelOn Set a custom label for when the switched is turned on. It will default to "On".
@@ -115,6 +118,7 @@
templateUrl: 'views/components/buttons/umb-toggle.html',
scope: {
checked: "=",
+ disabled: "=",
onClick: "&",
labelOn: "@?",
labelOff: "@?",
diff --git a/src/Umbraco.Web.UI.Client/src/less/components/buttons/umb-toggle.less b/src/Umbraco.Web.UI.Client/src/less/components/buttons/umb-toggle.less
index 150963cbb2..4c30ae583c 100644
--- a/src/Umbraco.Web.UI.Client/src/less/components/buttons/umb-toggle.less
+++ b/src/Umbraco.Web.UI.Client/src/less/components/buttons/umb-toggle.less
@@ -28,7 +28,8 @@
.umb-toggle__toggle {
cursor: pointer;
- display: inline-block;
+ align-items: center;
+ display: flex;
width: 48px;
height: 24px;
background: @gray-8;
@@ -41,6 +42,11 @@
background-color: @green;
}
+.umb-toggle--disabled .umb-toggle__toggle {
+ cursor: not-allowed;
+ opacity: 0.8;
+}
+
.umb-toggle--checked .umb-toggle__handler {
transform: translate3d(24px, 0, 0) rotate(0);
}
@@ -63,7 +69,7 @@
.umb-toggle__icon {
position: absolute;
- top: 3px;
+ line-height: 1em;
text-decoration: none;
transition: all 0.2s ease;
}
diff --git a/src/Umbraco.Web.UI.Client/src/less/components/users/umb-permission.less b/src/Umbraco.Web.UI.Client/src/less/components/users/umb-permission.less
index 9447a48217..5855fbd528 100644
--- a/src/Umbraco.Web.UI.Client/src/less/components/users/umb-permission.less
+++ b/src/Umbraco.Web.UI.Client/src/less/components/users/umb-permission.less
@@ -21,6 +21,12 @@
cursor: pointer;
}
+.umb-permission--disabled .umb-permission__toggle,
+.umb-permission--disabled .umb-permission__content {
+ cursor: not-allowed;
+ opacity: 0.8;
+}
+
.umb-permission__description {
font-size: 13px;
color: @gray-5;
diff --git a/src/Umbraco.Web.UI.Client/src/views/components/buttons/umb-toggle.html b/src/Umbraco.Web.UI.Client/src/views/components/buttons/umb-toggle.html
index bc5c114bb6..c8039448fd 100644
--- a/src/Umbraco.Web.UI.Client/src/views/components/buttons/umb-toggle.html
+++ b/src/Umbraco.Web.UI.Client/src/views/components/buttons/umb-toggle.html
@@ -1,4 +1,4 @@
-
+
{{ displayLabelOff }}
From 21612454d07f0f491ff8e47d0a46583794209e61 Mon Sep 17 00:00:00 2001
From: Sebastiaan Janssen
Date: Mon, 7 Jan 2019 13:45:43 +0100
Subject: [PATCH 06/84] Update umbtoggle.directive.js
---
.../common/directives/components/buttons/umbtoggle.directive.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/buttons/umbtoggle.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/buttons/umbtoggle.directive.js
index c2c9ec068b..9bc0a027e0 100644
--- a/src/Umbraco.Web.UI.Client/src/common/directives/components/buttons/umbtoggle.directive.js
+++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/buttons/umbtoggle.directive.js
@@ -54,7 +54,7 @@
@param {boolean} checked Set to true or false to toggle the switch.
-@param {boolean} disabled Set to true or false to disable the switch.
+@param {boolean} disabled Set to true or false to disable/enable the switch.
@param {callback} onClick The function which should be called when the toggle is clicked.
@param {string=} showLabels Set to true or false to show a "On" or "Off" label next to the switch.
@param {string=} labelOn Set a custom label for when the switched is turned on. It will default to "On".
From f7c70bde1e11a5744bb5c8c9ca36aef50c0f0282 Mon Sep 17 00:00:00 2001
From: Shannon
Date: Mon, 7 Jan 2019 23:49:29 +1100
Subject: [PATCH 07/84] Fixing up the PublishedContentQuery.Search
implementation 3920
---
src/Umbraco.Examine/ContentValueSetBuilder.cs | 6 +-
.../ContentValueSetValidator.cs | 2 +-
src/Umbraco.Examine/MediaValueSetBuilder.cs | 2 +-
src/Umbraco.Examine/MemberValueSetBuilder.cs | 2 +-
src/Umbraco.Examine/Umbraco.Examine.csproj | 2 +-
.../UmbracoFieldDefinitionCollection.cs | 6 +-
src/Umbraco.Examine/UmbracoMemberIndex.cs | 31 +------
.../PublishedContentMoreTests.cs | 2 +-
src/Umbraco.Tests/Umbraco.Tests.csproj | 2 +-
.../UmbracoContentValueSetValidatorTests.cs | 6 +-
src/Umbraco.Web.UI/Umbraco.Web.UI.csproj | 2 +-
src/Umbraco.Web/ExamineExtensions.cs | 3 +-
src/Umbraco.Web/PublishedContentQuery.cs | 84 ++++++++++++++++++-
.../Routing/ContentFinderByLegacy404.cs | 2 +-
src/Umbraco.Web/Search/UmbracoTreeSearcher.cs | 6 +-
src/Umbraco.Web/Umbraco.Web.csproj | 2 +-
src/Umbraco.Web/UmbracoHelper.cs | 2 +-
17 files changed, 106 insertions(+), 56 deletions(-)
diff --git a/src/Umbraco.Examine/ContentValueSetBuilder.cs b/src/Umbraco.Examine/ContentValueSetBuilder.cs
index 07e5e4565b..18cd5e311f 100644
--- a/src/Umbraco.Examine/ContentValueSetBuilder.cs
+++ b/src/Umbraco.Examine/ContentValueSetBuilder.cs
@@ -44,7 +44,7 @@ namespace Umbraco.Examine
{"icon", c.ContentType.Icon.Yield()},
{UmbracoExamineIndex.PublishedFieldName, new object[] {c.Published ? 1 : 0}}, //Always add invariant published value
{"id", new object[] {c.Id}},
- {"key", new object[] {c.Key}},
+ {UmbracoExamineIndex.NodeKeyFieldName, new object[] {c.Key}},
{"parentID", new object[] {c.Level > 1 ? c.ParentId : -1}},
{"level", new object[] {c.Level}},
{"creatorID", new object[] {c.CreatorId}},
@@ -61,12 +61,12 @@ namespace Umbraco.Examine
{"writerName",(c.GetWriterProfile(_userService)?.Name ?? "??").Yield() },
{"writerID", new object[] {c.WriterId}},
{"template", new object[] {c.Template?.Id ?? 0}},
- {UmbracoContentIndex.VariesByCultureFieldName, new object[] {0}},
+ {UmbracoContentIndex.VariesByCultureFieldName, new object[] {"n"}},
};
if (isVariant)
{
- values[UmbracoContentIndex.VariesByCultureFieldName] = new object[] { 1 };
+ values[UmbracoContentIndex.VariesByCultureFieldName] = new object[] { "y" };
foreach (var culture in c.AvailableCultures)
{
diff --git a/src/Umbraco.Examine/ContentValueSetValidator.cs b/src/Umbraco.Examine/ContentValueSetValidator.cs
index d4f6ceb15f..bcceafc272 100644
--- a/src/Umbraco.Examine/ContentValueSetValidator.cs
+++ b/src/Umbraco.Examine/ContentValueSetValidator.cs
@@ -100,7 +100,7 @@ namespace Umbraco.Examine
//deal with variants, if there are unpublished variants than we need to remove them from the value set
if (valueSet.Values.TryGetValue(UmbracoContentIndex.VariesByCultureFieldName, out var variesByCulture)
- && variesByCulture.Count > 0 && variesByCulture[0].Equals(1))
+ && variesByCulture.Count > 0 && variesByCulture[0].Equals("y"))
{
//so this valueset is for a content that varies by culture, now check for non-published cultures and remove those values
foreach(var publishField in valueSet.Values.Where(x => x.Key.StartsWith($"{UmbracoExamineIndex.PublishedFieldName}_")).ToList())
diff --git a/src/Umbraco.Examine/MediaValueSetBuilder.cs b/src/Umbraco.Examine/MediaValueSetBuilder.cs
index f0e5e895e6..2676093eeb 100644
--- a/src/Umbraco.Examine/MediaValueSetBuilder.cs
+++ b/src/Umbraco.Examine/MediaValueSetBuilder.cs
@@ -32,7 +32,7 @@ namespace Umbraco.Examine
{
{"icon", m.ContentType.Icon.Yield()},
{"id", new object[] {m.Id}},
- {"key", new object[] {m.Key}},
+ {UmbracoExamineIndex.NodeKeyFieldName, new object[] {m.Key}},
{"parentID", new object[] {m.Level > 1 ? m.ParentId : -1}},
{"level", new object[] {m.Level}},
{"creatorID", new object[] {m.CreatorId}},
diff --git a/src/Umbraco.Examine/MemberValueSetBuilder.cs b/src/Umbraco.Examine/MemberValueSetBuilder.cs
index 9864aba18d..d9f0b7806d 100644
--- a/src/Umbraco.Examine/MemberValueSetBuilder.cs
+++ b/src/Umbraco.Examine/MemberValueSetBuilder.cs
@@ -23,7 +23,7 @@ namespace Umbraco.Examine
{
{"icon", m.ContentType.Icon.Yield()},
{"id", new object[] {m.Id}},
- {"key", new object[] {m.Key}},
+ {UmbracoExamineIndex.NodeKeyFieldName, new object[] {m.Key}},
{"parentID", new object[] {m.Level > 1 ? m.ParentId : -1}},
{"level", new object[] {m.Level}},
{"creatorID", new object[] {m.CreatorId}},
diff --git a/src/Umbraco.Examine/Umbraco.Examine.csproj b/src/Umbraco.Examine/Umbraco.Examine.csproj
index a68131da0d..6864329bff 100644
--- a/src/Umbraco.Examine/Umbraco.Examine.csproj
+++ b/src/Umbraco.Examine/Umbraco.Examine.csproj
@@ -48,7 +48,7 @@
-
+
diff --git a/src/Umbraco.Examine/UmbracoFieldDefinitionCollection.cs b/src/Umbraco.Examine/UmbracoFieldDefinitionCollection.cs
index 97d1f68727..43c9553400 100644
--- a/src/Umbraco.Examine/UmbracoFieldDefinitionCollection.cs
+++ b/src/Umbraco.Examine/UmbracoFieldDefinitionCollection.cs
@@ -30,7 +30,7 @@ namespace Umbraco.Examine
new FieldDefinition("createDate", FieldDefinitionTypes.DateTime),
new FieldDefinition("updateDate", FieldDefinitionTypes.DateTime),
- new FieldDefinition("key", FieldDefinitionTypes.InvariantCultureIgnoreCase),
+ new FieldDefinition(UmbracoExamineIndex.NodeKeyFieldName, FieldDefinitionTypes.InvariantCultureIgnoreCase),
new FieldDefinition("version", FieldDefinitionTypes.Raw),
new FieldDefinition("nodeType", FieldDefinitionTypes.InvariantCultureIgnoreCase),
new FieldDefinition("template", FieldDefinitionTypes.Raw),
@@ -40,9 +40,9 @@ namespace Umbraco.Examine
new FieldDefinition("email", FieldDefinitionTypes.EmailAddress),
new FieldDefinition(UmbracoExamineIndex.PublishedFieldName, FieldDefinitionTypes.Raw),
- new FieldDefinition(UmbracoExamineIndex.NodeKeyFieldName, FieldDefinitionTypes.Raw),
new FieldDefinition(UmbracoExamineIndex.IndexPathFieldName, FieldDefinitionTypes.Raw),
- new FieldDefinition(UmbracoExamineIndex.IconFieldName, FieldDefinitionTypes.Raw)
+ new FieldDefinition(UmbracoExamineIndex.IconFieldName, FieldDefinitionTypes.Raw),
+ new FieldDefinition(UmbracoContentIndex.VariesByCultureFieldName, FieldDefinitionTypes.Raw),
};
/////
diff --git a/src/Umbraco.Examine/UmbracoMemberIndex.cs b/src/Umbraco.Examine/UmbracoMemberIndex.cs
index 9782f94fe4..fbf8a1cc0f 100644
--- a/src/Umbraco.Examine/UmbracoMemberIndex.cs
+++ b/src/Umbraco.Examine/UmbracoMemberIndex.cs
@@ -32,35 +32,6 @@ namespace Umbraco.Examine
base(name, luceneDirectory, fieldDefinitions, analyzer, profilingLogger, validator)
{
}
-
- ///
- /// Overridden to ensure that the umbraco system field definitions are in place
- ///
- ///
- ///
- protected override FieldValueTypeCollection CreateFieldValueTypes(IReadOnlyDictionary indexValueTypesFactory = null)
- {
- var keyDef = new FieldDefinition("__key", FieldDefinitionTypes.Raw);
- FieldDefinitionCollection.TryAdd(keyDef);
-
- return base.CreateFieldValueTypes(indexValueTypesFactory);
- }
-
- ///
- /// Ensure some custom values are added to the index
- ///
- ///
- protected override void OnTransformingIndexValues(IndexingItemEventArgs e)
- {
- base.OnTransformingIndexValues(e);
-
- if (e.ValueSet.Values.TryGetValue("key", out var key) && e.ValueSet.Values.ContainsKey("__key") == false)
- {
- //double __ prefix means it will be indexed as culture invariant
- e.ValueSet.Values["__key"] = key;
- }
-
- }
-
+
}
}
diff --git a/src/Umbraco.Tests/PublishedContent/PublishedContentMoreTests.cs b/src/Umbraco.Tests/PublishedContent/PublishedContentMoreTests.cs
index c5b8e21870..5f3a51f4f6 100644
--- a/src/Umbraco.Tests/PublishedContent/PublishedContentMoreTests.cs
+++ b/src/Umbraco.Tests/PublishedContent/PublishedContentMoreTests.cs
@@ -195,7 +195,7 @@ namespace Umbraco.Tests.PublishedContent
[Test]
public void PublishedContentQueryTypedContentList()
{
- var query = new PublishedContentQuery(UmbracoContext.Current.ContentCache, UmbracoContext.Current.MediaCache);
+ var query = new PublishedContentQuery(UmbracoContext.Current.ContentCache, UmbracoContext.Current.MediaCache, UmbracoContext.Current.VariationContextAccessor);
var result = query.Content(new[] { 1, 2, 4 }).ToArray();
Assert.AreEqual(2, result.Length);
Assert.AreEqual(1, result[0].Id);
diff --git a/src/Umbraco.Tests/Umbraco.Tests.csproj b/src/Umbraco.Tests/Umbraco.Tests.csproj
index bed1281bf8..8eb6d086a1 100644
--- a/src/Umbraco.Tests/Umbraco.Tests.csproj
+++ b/src/Umbraco.Tests/Umbraco.Tests.csproj
@@ -77,7 +77,7 @@
-
+
1.8.9
diff --git a/src/Umbraco.Tests/UmbracoExamine/UmbracoContentValueSetValidatorTests.cs b/src/Umbraco.Tests/UmbracoExamine/UmbracoContentValueSetValidatorTests.cs
index 8d7a446ccb..08db6b35e0 100644
--- a/src/Umbraco.Tests/UmbracoExamine/UmbracoContentValueSetValidatorTests.cs
+++ b/src/Umbraco.Tests/UmbracoExamine/UmbracoContentValueSetValidatorTests.cs
@@ -237,7 +237,7 @@ namespace Umbraco.Tests.UmbracoExamine
{
["hello"] = "world",
["path"] = "-1,555",
- [UmbracoContentIndex.VariesByCultureFieldName] = 1,
+ [UmbracoContentIndex.VariesByCultureFieldName] = "y",
[UmbracoExamineIndex.PublishedFieldName] = 0
}));
Assert.AreEqual(ValueSetValidationResult.Failed, result);
@@ -247,7 +247,7 @@ namespace Umbraco.Tests.UmbracoExamine
{
["hello"] = "world",
["path"] = "-1,555",
- [UmbracoContentIndex.VariesByCultureFieldName] = 1,
+ [UmbracoContentIndex.VariesByCultureFieldName] = "y",
[UmbracoExamineIndex.PublishedFieldName] = 1
}));
Assert.AreEqual(ValueSetValidationResult.Valid, result);
@@ -257,7 +257,7 @@ namespace Umbraco.Tests.UmbracoExamine
{
["hello"] = "world",
["path"] = "-1,555",
- [UmbracoContentIndex.VariesByCultureFieldName] = 1,
+ [UmbracoContentIndex.VariesByCultureFieldName] = "y",
[$"{UmbracoExamineIndex.PublishedFieldName}_en-us"] = 1,
["hello_en-us"] = "world",
["title_en-us"] = "my title",
diff --git a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj
index 2fc199d06a..dae0781926 100644
--- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj
+++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj
@@ -88,7 +88,7 @@
-
+
diff --git a/src/Umbraco.Web/ExamineExtensions.cs b/src/Umbraco.Web/ExamineExtensions.cs
index f1ed6c0659..9a9fa98d95 100644
--- a/src/Umbraco.Web/ExamineExtensions.cs
+++ b/src/Umbraco.Web/ExamineExtensions.cs
@@ -1,4 +1,5 @@
-using System.Collections.Generic;
+using System;
+using System.Collections.Generic;
using System.Linq;
using Examine;
using Umbraco.Core;
diff --git a/src/Umbraco.Web/PublishedContentQuery.cs b/src/Umbraco.Web/PublishedContentQuery.cs
index 3d8f36ec1a..03a0e8dfb2 100644
--- a/src/Umbraco.Web/PublishedContentQuery.cs
+++ b/src/Umbraco.Web/PublishedContentQuery.cs
@@ -1,4 +1,5 @@
using System;
+using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
@@ -24,16 +25,19 @@ namespace Umbraco.Web
{
private readonly IPublishedContentCache _contentCache;
private readonly IPublishedMediaCache _mediaCache;
+ private readonly IVariationContextAccessor _variationContextAccessor;
///
/// Constructor used to return results from the caches
///
///
///
- public PublishedContentQuery(IPublishedContentCache contentCache, IPublishedMediaCache mediaCache)
+ ///
+ public PublishedContentQuery(IPublishedContentCache contentCache, IPublishedMediaCache mediaCache, IVariationContextAccessor variationContextAccessor)
{
_contentCache = contentCache ?? throw new ArgumentNullException(nameof(contentCache));
_mediaCache = mediaCache ?? throw new ArgumentNullException(nameof(mediaCache));
+ _variationContextAccessor = variationContextAccessor ?? throw new ArgumentNullException(nameof(variationContextAccessor));
}
#region Content
@@ -201,6 +205,9 @@ namespace Umbraco.Web
// default to max 500 results
var count = skip == 0 && take == 0 ? 500 : skip + take;
+ //set this to the specific culture or to the culture in the request
+ culture = culture ?? _variationContextAccessor.VariationContext.Culture;
+
ISearchResults results;
if (culture.IsNullOrWhiteSpace())
{
@@ -211,7 +218,7 @@ namespace Umbraco.Web
//get all index fields suffixed with the culture name supplied
var cultureFields = new List();
var fields = umbIndex.GetFields();
- var qry = searcher.CreateQuery().Field(UmbracoContentIndex.VariesByCultureFieldName, 1); //must vary by culture
+ var qry = searcher.CreateQuery().Field(UmbracoContentIndex.VariesByCultureFieldName, "y"); //must vary by culture
// ReSharper disable once LoopCanBeConvertedToQuery
foreach (var field in fields)
{
@@ -225,7 +232,8 @@ namespace Umbraco.Web
}
totalRecords = results.TotalItemCount;
- return results.ToPublishedSearchResults(_contentCache);
+
+ return new CultureContextualSearchResults(results.ToPublishedSearchResults(_contentCache), _variationContextAccessor, culture);
}
///
@@ -245,6 +253,76 @@ namespace Umbraco.Web
return results.ToPublishedSearchResults(_contentCache);
}
+ ///
+ /// This is used to contextualize the values in the search results when enumerating over them so that the correct culture values are used
+ ///
+ private class CultureContextualSearchResults : IEnumerable
+ {
+ private readonly IEnumerable _wrapped;
+ private readonly IVariationContextAccessor _variationContextAccessor;
+ private readonly string _culture;
+
+ public CultureContextualSearchResults(IEnumerable wrapped, IVariationContextAccessor variationContextAccessor, string culture)
+ {
+ _wrapped = wrapped;
+ _variationContextAccessor = variationContextAccessor;
+ _culture = culture;
+ }
+
+ public IEnumerator GetEnumerator()
+ {
+ //We need to change the current culture to what is requested and then change it back
+ var originalContext = _variationContextAccessor.VariationContext;
+ if (!_culture.IsNullOrWhiteSpace() && !_culture.InvariantEquals(originalContext.Culture))
+ _variationContextAccessor.VariationContext = new VariationContext(_culture);
+
+ //now the IPublishedContent returned will be contextualized to the culture specified and will be reset when the enumerator is disposed
+ return new CultureContextualSearchResultsEnumerator(_wrapped.GetEnumerator(), _variationContextAccessor, originalContext);
+ }
+
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return GetEnumerator();
+ }
+
+ ///
+ /// Resets the variation context when this is disposed
+ ///
+ private class CultureContextualSearchResultsEnumerator : IEnumerator
+ {
+ private readonly IEnumerator _wrapped;
+ private readonly IVariationContextAccessor _variationContextAccessor;
+ private readonly VariationContext _originalContext;
+
+ public CultureContextualSearchResultsEnumerator(IEnumerator wrapped, IVariationContextAccessor variationContextAccessor, VariationContext originalContext)
+ {
+ _wrapped = wrapped;
+ _variationContextAccessor = variationContextAccessor;
+ _originalContext = originalContext;
+ }
+
+ public void Dispose()
+ {
+ _wrapped.Dispose();
+ //reset
+ _variationContextAccessor.VariationContext = _originalContext;
+ }
+
+ public bool MoveNext()
+ {
+ return _wrapped.MoveNext();
+ }
+
+ public void Reset()
+ {
+ _wrapped.Reset();
+ }
+
+ public PublishedSearchResult Current => _wrapped.Current;
+ object IEnumerator.Current => Current;
+ }
+ }
+
///
/// Matches a culture iso name suffix
///
diff --git a/src/Umbraco.Web/Routing/ContentFinderByLegacy404.cs b/src/Umbraco.Web/Routing/ContentFinderByLegacy404.cs
index 99b4e22b5a..1f01270bc6 100644
--- a/src/Umbraco.Web/Routing/ContentFinderByLegacy404.cs
+++ b/src/Umbraco.Web/Routing/ContentFinderByLegacy404.cs
@@ -63,7 +63,7 @@ namespace Umbraco.Web.Routing
var error404 = NotFoundHandlerHelper.GetCurrentNotFoundPageId(
_contentConfigSection.Error404Collection.ToArray(),
_entityService,
- new PublishedContentQuery(frequest.UmbracoContext.ContentCache, frequest.UmbracoContext.MediaCache),
+ new PublishedContentQuery(frequest.UmbracoContext.ContentCache, frequest.UmbracoContext.MediaCache, frequest.UmbracoContext.VariationContextAccessor),
errorCulture);
IPublishedContent content = null;
diff --git a/src/Umbraco.Web/Search/UmbracoTreeSearcher.cs b/src/Umbraco.Web/Search/UmbracoTreeSearcher.cs
index 47e73d383c..a60e5f1d1b 100644
--- a/src/Umbraco.Web/Search/UmbracoTreeSearcher.cs
+++ b/src/Umbraco.Web/Search/UmbracoTreeSearcher.cs
@@ -367,9 +367,9 @@ namespace Umbraco.Web.Search
{
m.AdditionalData["Email"] = result.Values["email"];
}
- if (result.Values.ContainsKey("__key") && result.Values["__key"] != null)
+ if (result.Values.ContainsKey(UmbracoExamineIndex.NodeKeyFieldName) && result.Values[UmbracoExamineIndex.NodeKeyFieldName] != null)
{
- if (Guid.TryParse(result.Values["__key"], out var key))
+ if (Guid.TryParse(result.Values[UmbracoExamineIndex.NodeKeyFieldName], out var key))
{
m.Key = key;
}
@@ -416,7 +416,7 @@ namespace Umbraco.Web.Search
if (intId.Success)
{
//if it varies by culture, return the default language URL
- if (result.Values.TryGetValue(UmbracoContentIndex.VariesByCultureFieldName, out var varies) && varies == "1")
+ if (result.Values.TryGetValue(UmbracoContentIndex.VariesByCultureFieldName, out var varies) && varies == "y")
{
entity.AdditionalData["Url"] = _umbracoHelper.Url(intId.Result, defaultLang);
}
diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj
index 7a695ff4ef..83268bb78e 100755
--- a/src/Umbraco.Web/Umbraco.Web.csproj
+++ b/src/Umbraco.Web/Umbraco.Web.csproj
@@ -63,7 +63,7 @@
-
+
2.6.2.25
diff --git a/src/Umbraco.Web/UmbracoHelper.cs b/src/Umbraco.Web/UmbracoHelper.cs
index 6914efb3e2..f4be2a1700 100644
--- a/src/Umbraco.Web/UmbracoHelper.cs
+++ b/src/Umbraco.Web/UmbracoHelper.cs
@@ -106,7 +106,7 @@ namespace Umbraco.Web
/// Gets the query context.
///
public IPublishedContentQuery ContentQuery => _query ??
- (_query = new PublishedContentQuery(UmbracoContext.ContentCache, UmbracoContext.MediaCache));
+ (_query = new PublishedContentQuery(UmbracoContext.ContentCache, UmbracoContext.MediaCache, UmbracoContext.VariationContextAccessor));
///
/// Gets the Umbraco context.
From 4a1ae0573ffe1118233fa71527dc7be95004cfe9 Mon Sep 17 00:00:00 2001
From: Shannon
Date: Tue, 8 Jan 2019 13:25:07 +1100
Subject: [PATCH 08/84] Gets definitions dynamically applied for culture
specific fields.
---
src/Umbraco.Examine/ExamineExtensions.cs | 33 +++++++++-
src/Umbraco.Examine/Umbraco.Examine.csproj | 2 +-
.../UmbracoFieldDefinitionCollection.cs | 60 ++++++++++++-------
.../PublishedMediaCacheTests.cs | 2 +-
src/Umbraco.Tests/Umbraco.Tests.csproj | 2 +-
src/Umbraco.Web.UI/Umbraco.Web.UI.csproj | 2 +-
src/Umbraco.Web/PublishedContentQuery.cs | 19 +-----
src/Umbraco.Web/Umbraco.Web.csproj | 2 +-
8 files changed, 75 insertions(+), 47 deletions(-)
diff --git a/src/Umbraco.Examine/ExamineExtensions.cs b/src/Umbraco.Examine/ExamineExtensions.cs
index 525f0deaa1..4fe6c359d7 100644
--- a/src/Umbraco.Examine/ExamineExtensions.cs
+++ b/src/Umbraco.Examine/ExamineExtensions.cs
@@ -1,5 +1,7 @@
using System;
+using System.Collections.Generic;
using System.Linq;
+using System.Text.RegularExpressions;
using Examine;
using Examine.LuceneEngine.Providers;
using Lucene.Net.Analysis;
@@ -7,6 +9,7 @@ using Lucene.Net.Index;
using Lucene.Net.QueryParsers;
using Lucene.Net.Search;
using Lucene.Net.Store;
+using Umbraco.Core;
using Version = Lucene.Net.Util.Version;
using Umbraco.Core.Logging;
@@ -15,9 +18,35 @@ namespace Umbraco.Examine
///
/// Extension methods for the LuceneIndex
///
- internal static class ExamineExtensions
+ public static class ExamineExtensions
{
- public static bool TryParseLuceneQuery(string query)
+ ///
+ /// Matches a culture iso name suffix
+ ///
+ ///
+ /// myFieldName_en-us will match the "en-us"
+ ///
+ internal static readonly Regex CultureIsoCodeFieldNameMatchExpression = new Regex("^([_\\w]+)_([a-z]{2}-[a-z0-9]{2,4})$", RegexOptions.Compiled);
+
+ ///
+ /// Returns all index fields that are culture specific (suffixed)
+ ///
+ ///
+ ///
+ ///
+ public static IEnumerable GetCultureFields(this IUmbracoIndex index, string culture)
+ {
+ var allFields = index.GetFields();
+ // ReSharper disable once LoopCanBeConvertedToQuery
+ foreach (var field in allFields)
+ {
+ var match = CultureIsoCodeFieldNameMatchExpression.Match(field);
+ if (match.Success && match.Groups.Count == 3 && culture.InvariantEquals(match.Groups[2].Value))
+ yield return field;
+ }
+ }
+
+ internal static bool TryParseLuceneQuery(string query)
{
//TODO: I'd assume there would be a more strict way to parse the query but not that i can find yet, for now we'll
// also do this rudimentary check
diff --git a/src/Umbraco.Examine/Umbraco.Examine.csproj b/src/Umbraco.Examine/Umbraco.Examine.csproj
index 6864329bff..68df7b7ddd 100644
--- a/src/Umbraco.Examine/Umbraco.Examine.csproj
+++ b/src/Umbraco.Examine/Umbraco.Examine.csproj
@@ -48,7 +48,7 @@
-
+
diff --git a/src/Umbraco.Examine/UmbracoFieldDefinitionCollection.cs b/src/Umbraco.Examine/UmbracoFieldDefinitionCollection.cs
index 43c9553400..8030eaecaf 100644
--- a/src/Umbraco.Examine/UmbracoFieldDefinitionCollection.cs
+++ b/src/Umbraco.Examine/UmbracoFieldDefinitionCollection.cs
@@ -1,4 +1,7 @@
-using Examine;
+using System.Collections.Generic;
+using System.Text.RegularExpressions;
+using Examine;
+using Umbraco.Core;
namespace Umbraco.Examine
{
@@ -45,31 +48,42 @@ namespace Umbraco.Examine
new FieldDefinition(UmbracoContentIndex.VariesByCultureFieldName, FieldDefinitionTypes.Raw),
};
- /////
- ///// Overridden to dynamically add field definitions for culture variations
- /////
- /////
- /////
- /////
- //public override bool TryGetValue(string fieldName, out FieldDefinition fieldDefinition)
- //{
- // var result = base.TryGetValue(fieldName, out fieldDefinition);
- // if (result) return true;
- // //if the fieldName is not suffixed with _iso-Code
- // var underscoreIndex = fieldName.LastIndexOf('_');
- // if (underscoreIndex == -1) return false;
+ ///
+ /// Overridden to dynamically add field definitions for culture variations
+ ///
+ ///
+ ///
+ ///
+ ///
+ /// We need to do this so that we don't have to maintain a huge static list of all field names and their definitions
+ /// otherwise we'd have to dynamically add/remove definitions anytime languages are added/removed, etc...
+ /// For example, we have things like `nodeName` and `__Published` which are also used for culture fields like `nodeName_en-us`
+ /// and we don't want to have a full static list of all of these definitions when we can just define the one definition and then
+ /// dynamically apply that to culture specific fields.
+ ///
+ public override bool TryGetValue(string fieldName, out FieldDefinition fieldDefinition)
+ {
+ if (base.TryGetValue(fieldName, out fieldDefinition))
+ return true;
+ //before we use regex to match do some faster simple matching since this is going to execute quite a lot
+ if (!fieldName.Contains("_"))
+ return false;
+ if (!fieldName.Contains("-"))
+ return false;
+ var match = ExamineExtensions.CultureIsoCodeFieldNameMatchExpression.Match(fieldName);
+ if (match.Success && match.Groups.Count == 3)
+ {
+ var nonCultureFieldName = match.Groups[1].Value;
+ //check if there's a definition for this and if so return the field definition for the culture field based on the non-culture field
+ if (base.TryGetValue(nonCultureFieldName, out fieldDefinition))
+ return true;
+ }
+ return false;
+ }
- // var isoCode = fieldName.Substring(underscoreIndex);
- // if (isoCode.Length < 6) return false; //invalid isoCode
-
- // var hyphenIndex = isoCode.IndexOf('-');
- // if (hyphenIndex != 3) return false; //invalid isoCode
-
- // //we'll assume this is a valid isoCode
-
- //}
+
}
}
diff --git a/src/Umbraco.Tests/Cache/PublishedCache/PublishedMediaCacheTests.cs b/src/Umbraco.Tests/Cache/PublishedCache/PublishedMediaCacheTests.cs
index 5237b92ab8..d8a53bc829 100644
--- a/src/Umbraco.Tests/Cache/PublishedCache/PublishedMediaCacheTests.cs
+++ b/src/Umbraco.Tests/Cache/PublishedCache/PublishedMediaCacheTests.cs
@@ -201,7 +201,7 @@ namespace Umbraco.Tests.Cache.PublishedCache
{"creatorName", "Shannon"}
};
- var result = new SearchResult("1234", 1, 1, () => fields.ToDictionary(x => x.Key, x => new List { x.Value }));
+ var result = new SearchResult("1234", 1, () => fields.ToDictionary(x => x.Key, x => new List { x.Value }));
var store = new PublishedMediaCache(new XmlStore((XmlDocument)null, null, null, null), ServiceContext.MediaService, ServiceContext.UserService, new StaticCacheProvider(), ContentTypesCache);
var doc = store.CreateFromCacheValues(store.ConvertFromSearchResult(result));
diff --git a/src/Umbraco.Tests/Umbraco.Tests.csproj b/src/Umbraco.Tests/Umbraco.Tests.csproj
index 8eb6d086a1..8a6ca29b2c 100644
--- a/src/Umbraco.Tests/Umbraco.Tests.csproj
+++ b/src/Umbraco.Tests/Umbraco.Tests.csproj
@@ -77,7 +77,7 @@
-
+
1.8.9
diff --git a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj
index dae0781926..f3324be30f 100644
--- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj
+++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj
@@ -88,7 +88,7 @@
-
+
diff --git a/src/Umbraco.Web/PublishedContentQuery.cs b/src/Umbraco.Web/PublishedContentQuery.cs
index 03a0e8dfb2..2c4d08502e 100644
--- a/src/Umbraco.Web/PublishedContentQuery.cs
+++ b/src/Umbraco.Web/PublishedContentQuery.cs
@@ -216,17 +216,8 @@ namespace Umbraco.Web
else
{
//get all index fields suffixed with the culture name supplied
- var cultureFields = new List();
- var fields = umbIndex.GetFields();
+ var cultureFields = umbIndex.GetCultureFields(culture);
var qry = searcher.CreateQuery().Field(UmbracoContentIndex.VariesByCultureFieldName, "y"); //must vary by culture
- // ReSharper disable once LoopCanBeConvertedToQuery
- foreach (var field in fields)
- {
- var match = CultureIsoCodeFieldName.Match(field);
- if (match.Success && match.Groups.Count == 2 && culture.InvariantEquals(match.Groups[1].Value))
- cultureFields.Add(field);
- }
-
qry = qry.And().ManagedQuery(term, cultureFields.ToArray());
results = qry.Execute(count);
}
@@ -323,13 +314,7 @@ namespace Umbraco.Web
}
}
- ///
- /// Matches a culture iso name suffix
- ///
- ///
- /// myFieldName_en-us will match the "en-us"
- ///
- private static readonly Regex CultureIsoCodeFieldName = new Regex("^[_\\w]+_([a-z]{2}-[a-z0-9]{2,4})$", RegexOptions.Compiled);
+
#endregion
diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj
index 83268bb78e..fd9822d172 100755
--- a/src/Umbraco.Web/Umbraco.Web.csproj
+++ b/src/Umbraco.Web/Umbraco.Web.csproj
@@ -63,7 +63,7 @@
-
+
2.6.2.25
From 340a7e53836f172981794857b447c2e22a478e4f Mon Sep 17 00:00:00 2001
From: Shannon
Date: Tue, 8 Jan 2019 14:04:37 +1100
Subject: [PATCH 09/84] Changes published index flag to y/n instead of 1/0
---
src/Umbraco.Examine/ContentValueSetBuilder.cs | 4 ++--
src/Umbraco.Examine/ContentValueSetValidator.cs | 4 ++--
.../UmbracoContentValueSetValidatorTests.cs | 16 ++++++++--------
3 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/src/Umbraco.Examine/ContentValueSetBuilder.cs b/src/Umbraco.Examine/ContentValueSetBuilder.cs
index 18cd5e311f..0ffd9f3447 100644
--- a/src/Umbraco.Examine/ContentValueSetBuilder.cs
+++ b/src/Umbraco.Examine/ContentValueSetBuilder.cs
@@ -42,7 +42,7 @@ namespace Umbraco.Examine
var values = new Dictionary>
{
{"icon", c.ContentType.Icon.Yield()},
- {UmbracoExamineIndex.PublishedFieldName, new object[] {c.Published ? 1 : 0}}, //Always add invariant published value
+ {UmbracoExamineIndex.PublishedFieldName, new object[] {c.Published ? "y" : "n"}}, //Always add invariant published value
{"id", new object[] {c.Id}},
{UmbracoExamineIndex.NodeKeyFieldName, new object[] {c.Key}},
{"parentID", new object[] {c.Level > 1 ? c.ParentId : -1}},
@@ -76,7 +76,7 @@ namespace Umbraco.Examine
values[$"nodeName_{lowerCulture}"] = PublishedValuesOnly
? c.GetPublishName(culture).Yield()
: c.GetCultureName(culture).Yield();
- values[$"{UmbracoExamineIndex.PublishedFieldName}_{lowerCulture}"] = (c.IsCulturePublished(culture) ? 1 : 0).Yield();
+ values[$"{UmbracoExamineIndex.PublishedFieldName}_{lowerCulture}"] = (c.IsCulturePublished(culture) ? "y" : "n").Yield();
values[$"updateDate_{lowerCulture}"] = PublishedValuesOnly
? c.GetPublishDate(culture).Yield()
: c.GetUpdateDate(culture).Yield();
diff --git a/src/Umbraco.Examine/ContentValueSetValidator.cs b/src/Umbraco.Examine/ContentValueSetValidator.cs
index bcceafc272..9555566c53 100644
--- a/src/Umbraco.Examine/ContentValueSetValidator.cs
+++ b/src/Umbraco.Examine/ContentValueSetValidator.cs
@@ -95,7 +95,7 @@ namespace Umbraco.Examine
if (!valueSet.Values.TryGetValue(UmbracoExamineIndex.PublishedFieldName, out var published))
return ValueSetValidationResult.Failed;
- if (!published[0].Equals(1))
+ if (!published[0].Equals("y"))
return ValueSetValidationResult.Failed;
//deal with variants, if there are unpublished variants than we need to remove them from the value set
@@ -105,7 +105,7 @@ namespace Umbraco.Examine
//so this valueset is for a content that varies by culture, now check for non-published cultures and remove those values
foreach(var publishField in valueSet.Values.Where(x => x.Key.StartsWith($"{UmbracoExamineIndex.PublishedFieldName}_")).ToList())
{
- if (publishField.Value.Count <= 0 || !publishField.Value[0].Equals(1))
+ if (publishField.Value.Count <= 0 || !publishField.Value[0].Equals("y"))
{
//this culture is not published, so remove all of these culture values
var cultureSuffix = publishField.Key.Substring(publishField.Key.LastIndexOf('_'));
diff --git a/src/Umbraco.Tests/UmbracoExamine/UmbracoContentValueSetValidatorTests.cs b/src/Umbraco.Tests/UmbracoExamine/UmbracoContentValueSetValidatorTests.cs
index 08db6b35e0..8bdb0c71c7 100644
--- a/src/Umbraco.Tests/UmbracoExamine/UmbracoContentValueSetValidatorTests.cs
+++ b/src/Umbraco.Tests/UmbracoExamine/UmbracoContentValueSetValidatorTests.cs
@@ -179,7 +179,7 @@ namespace Umbraco.Tests.UmbracoExamine
{
["hello"] = "world",
["path"] = "-1,555",
- [UmbracoExamineIndex.PublishedFieldName] = 1
+ [UmbracoExamineIndex.PublishedFieldName] = "y"
}));
Assert.AreEqual(ValueSetValidationResult.Valid, result);
}
@@ -213,7 +213,7 @@ namespace Umbraco.Tests.UmbracoExamine
{
["hello"] = "world",
["path"] = "-1,555",
- [UmbracoExamineIndex.PublishedFieldName] = 0
+ [UmbracoExamineIndex.PublishedFieldName] = "n"
}));
Assert.AreEqual(ValueSetValidationResult.Failed, result);
@@ -222,7 +222,7 @@ namespace Umbraco.Tests.UmbracoExamine
{
["hello"] = "world",
["path"] = "-1,555",
- [UmbracoExamineIndex.PublishedFieldName] = 1
+ [UmbracoExamineIndex.PublishedFieldName] = "y"
}));
Assert.AreEqual(ValueSetValidationResult.Valid, result);
}
@@ -238,7 +238,7 @@ namespace Umbraco.Tests.UmbracoExamine
["hello"] = "world",
["path"] = "-1,555",
[UmbracoContentIndex.VariesByCultureFieldName] = "y",
- [UmbracoExamineIndex.PublishedFieldName] = 0
+ [UmbracoExamineIndex.PublishedFieldName] = "n"
}));
Assert.AreEqual(ValueSetValidationResult.Failed, result);
@@ -248,7 +248,7 @@ namespace Umbraco.Tests.UmbracoExamine
["hello"] = "world",
["path"] = "-1,555",
[UmbracoContentIndex.VariesByCultureFieldName] = "y",
- [UmbracoExamineIndex.PublishedFieldName] = 1
+ [UmbracoExamineIndex.PublishedFieldName] = "y"
}));
Assert.AreEqual(ValueSetValidationResult.Valid, result);
@@ -258,13 +258,13 @@ namespace Umbraco.Tests.UmbracoExamine
["hello"] = "world",
["path"] = "-1,555",
[UmbracoContentIndex.VariesByCultureFieldName] = "y",
- [$"{UmbracoExamineIndex.PublishedFieldName}_en-us"] = 1,
+ [$"{UmbracoExamineIndex.PublishedFieldName}_en-us"] = "y",
["hello_en-us"] = "world",
["title_en-us"] = "my title",
- [$"{UmbracoExamineIndex.PublishedFieldName}_es-es"] = 0,
+ [$"{UmbracoExamineIndex.PublishedFieldName}_es-es"] = "n",
["hello_es-ES"] = "world",
["title_es-ES"] = "my title",
- [UmbracoExamineIndex.PublishedFieldName] = 1
+ [UmbracoExamineIndex.PublishedFieldName] = "y"
});
Assert.AreEqual(10, valueSet.Values.Count());
Assert.IsTrue(valueSet.Values.ContainsKey($"{UmbracoExamineIndex.PublishedFieldName}_es-es"));
From 801e9da028a8153b987d6bb8f6ab67f1a80323ae Mon Sep 17 00:00:00 2001
From: Shannon
Date: Tue, 8 Jan 2019 16:37:16 +1100
Subject: [PATCH 10/84] Fixes issue with dynamically creating/storing field
definitions, latest examine update
---
build/NuSpecs/UmbracoCms.Web.nuspec | 2 +-
src/Umbraco.Examine/Umbraco.Examine.csproj | 2 +-
.../UmbracoFieldDefinitionCollection.cs | 15 +++++++++++----
src/Umbraco.Tests/Umbraco.Tests.csproj | 2 +-
src/Umbraco.Web.UI/Umbraco.Web.UI.csproj | 2 +-
src/Umbraco.Web/Umbraco.Web.csproj | 2 +-
6 files changed, 16 insertions(+), 9 deletions(-)
diff --git a/build/NuSpecs/UmbracoCms.Web.nuspec b/build/NuSpecs/UmbracoCms.Web.nuspec
index 35e79d8127..30fa303b30 100644
--- a/build/NuSpecs/UmbracoCms.Web.nuspec
+++ b/build/NuSpecs/UmbracoCms.Web.nuspec
@@ -25,7 +25,7 @@
-
+
diff --git a/src/Umbraco.Examine/Umbraco.Examine.csproj b/src/Umbraco.Examine/Umbraco.Examine.csproj
index 68df7b7ddd..1320f3b0d2 100644
--- a/src/Umbraco.Examine/Umbraco.Examine.csproj
+++ b/src/Umbraco.Examine/Umbraco.Examine.csproj
@@ -48,7 +48,7 @@
-
+
diff --git a/src/Umbraco.Examine/UmbracoFieldDefinitionCollection.cs b/src/Umbraco.Examine/UmbracoFieldDefinitionCollection.cs
index 8030eaecaf..1e7b51aa14 100644
--- a/src/Umbraco.Examine/UmbracoFieldDefinitionCollection.cs
+++ b/src/Umbraco.Examine/UmbracoFieldDefinitionCollection.cs
@@ -61,6 +61,11 @@ namespace Umbraco.Examine
/// For example, we have things like `nodeName` and `__Published` which are also used for culture fields like `nodeName_en-us`
/// and we don't want to have a full static list of all of these definitions when we can just define the one definition and then
/// dynamically apply that to culture specific fields.
+ ///
+ /// There is a caveat to this however, when a field definition is found for a non-culture field we will create and store a new field
+ /// definition for that culture so that the next time it needs to be looked up and used we are not allocating more objects. This does mean
+ /// however that if a language is deleted, the field definitions for that language will still exist in memory. This isn't going to cause any
+ /// problems and the mem will be cleared on next site restart but it's worth pointing out.
///
public override bool TryGetValue(string fieldName, out FieldDefinition fieldDefinition)
{
@@ -68,9 +73,7 @@ namespace Umbraco.Examine
return true;
//before we use regex to match do some faster simple matching since this is going to execute quite a lot
- if (!fieldName.Contains("_"))
- return false;
- if (!fieldName.Contains("-"))
+ if (!fieldName.Contains("_") || !fieldName.Contains("-"))
return false;
var match = ExamineExtensions.CultureIsoCodeFieldNameMatchExpression.Match(fieldName);
@@ -78,8 +81,12 @@ namespace Umbraco.Examine
{
var nonCultureFieldName = match.Groups[1].Value;
//check if there's a definition for this and if so return the field definition for the culture field based on the non-culture field
- if (base.TryGetValue(nonCultureFieldName, out fieldDefinition))
+ if (base.TryGetValue(nonCultureFieldName, out var existingFieldDefinition))
+ {
+ //now add a new field def
+ fieldDefinition = GetOrAdd(fieldName, s => new FieldDefinition(s, existingFieldDefinition.Type));
return true;
+ }
}
return false;
}
diff --git a/src/Umbraco.Tests/Umbraco.Tests.csproj b/src/Umbraco.Tests/Umbraco.Tests.csproj
index 8a6ca29b2c..1b048f1df0 100644
--- a/src/Umbraco.Tests/Umbraco.Tests.csproj
+++ b/src/Umbraco.Tests/Umbraco.Tests.csproj
@@ -77,7 +77,7 @@
-
+
1.8.9
diff --git a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj
index f3324be30f..89df5632ab 100644
--- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj
+++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj
@@ -88,7 +88,7 @@
-
+
diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj
index fd9822d172..9f65b0d16d 100755
--- a/src/Umbraco.Web/Umbraco.Web.csproj
+++ b/src/Umbraco.Web/Umbraco.Web.csproj
@@ -63,7 +63,7 @@
-
+
2.6.2.25
From 086157cff8fc7d34596244265a19caa847c6936b Mon Sep 17 00:00:00 2001
From: Sebastiaan Janssen
Date: Tue, 8 Jan 2019 12:50:36 +0100
Subject: [PATCH 11/84] Fixes #3990 All images uploaded to media section have
umbracoHeight / umbracoWidth of 200x200px
---
src/Umbraco.Core/IO/MediaFileSystem.cs | 3 ++-
src/Umbraco.Core/Media/Exif/ImageFile.cs | 9 +++++----
src/Umbraco.Core/Media/TypeDetector/JpegDetector.cs | 3 +--
.../Media/TypeDetector/RasterizedTypeDetector.cs | 6 +++++-
src/Umbraco.Core/Media/TypeDetector/TIFFDetector.cs | 10 +++++-----
5 files changed, 18 insertions(+), 13 deletions(-)
diff --git a/src/Umbraco.Core/IO/MediaFileSystem.cs b/src/Umbraco.Core/IO/MediaFileSystem.cs
index 39cd7ba7ad..a4305506bb 100644
--- a/src/Umbraco.Core/IO/MediaFileSystem.cs
+++ b/src/Umbraco.Core/IO/MediaFileSystem.cs
@@ -365,7 +365,8 @@ namespace Umbraco.Core.IO
{
var jpgInfo = ImageFile.FromStream(stream);
- if (jpgInfo.Format != ImageFileFormat.Unknown
+ if (jpgInfo != null
+ && jpgInfo.Format != ImageFileFormat.Unknown
&& jpgInfo.Properties.ContainsKey(ExifTag.PixelYDimension)
&& jpgInfo.Properties.ContainsKey(ExifTag.PixelXDimension))
{
diff --git a/src/Umbraco.Core/Media/Exif/ImageFile.cs b/src/Umbraco.Core/Media/Exif/ImageFile.cs
index 05a2a955c4..cfa0d90aa1 100644
--- a/src/Umbraco.Core/Media/Exif/ImageFile.cs
+++ b/src/Umbraco.Core/Media/Exif/ImageFile.cs
@@ -118,9 +118,9 @@ namespace Umbraco.Core.Media.Exif
/// The encoding to be used for text metadata when the source encoding is unknown.
/// The created from the file.
public static ImageFile FromStream(Stream stream, Encoding encoding)
- {
+ {
// JPEG
- if(JPEGDetector.IsOfType(stream))
+ if (JPEGDetector.IsOfType(stream))
{
return new JPEGFile(stream, encoding);
}
@@ -137,8 +137,9 @@ namespace Umbraco.Core.Media.Exif
return new SVGFile(stream);
}
- throw new NotValidImageFileException ();
- }
+ // We don't know
+ return null;
+ }
#endregion
}
}
diff --git a/src/Umbraco.Core/Media/TypeDetector/JpegDetector.cs b/src/Umbraco.Core/Media/TypeDetector/JpegDetector.cs
index 5b68f6ad88..73c8519bb6 100644
--- a/src/Umbraco.Core/Media/TypeDetector/JpegDetector.cs
+++ b/src/Umbraco.Core/Media/TypeDetector/JpegDetector.cs
@@ -7,8 +7,7 @@ namespace Umbraco.Core.Media.TypeDetector
public static bool IsOfType(Stream fileStream)
{
var header = GetFileHeader(fileStream);
-
- return header[0] == 0xff && header[1] == 0xD8;
+ return header != null && header[0] == 0xff && header[1] == 0xD8;
}
}
}
diff --git a/src/Umbraco.Core/Media/TypeDetector/RasterizedTypeDetector.cs b/src/Umbraco.Core/Media/TypeDetector/RasterizedTypeDetector.cs
index 9777d55c20..858b9342fe 100644
--- a/src/Umbraco.Core/Media/TypeDetector/RasterizedTypeDetector.cs
+++ b/src/Umbraco.Core/Media/TypeDetector/RasterizedTypeDetector.cs
@@ -7,9 +7,13 @@ namespace Umbraco.Core.Media.TypeDetector
public static byte[] GetFileHeader(Stream fileStream)
{
fileStream.Seek(0, SeekOrigin.Begin);
- byte[] header = new byte[8];
+ var header = new byte[8];
fileStream.Seek(0, SeekOrigin.Begin);
+ // Invalid header
+ if (fileStream.Read(header, 0, header.Length) != header.Length)
+ return null;
+
return header;
}
}
diff --git a/src/Umbraco.Core/Media/TypeDetector/TIFFDetector.cs b/src/Umbraco.Core/Media/TypeDetector/TIFFDetector.cs
index 2a6e42d0e0..6f4a05b7af 100644
--- a/src/Umbraco.Core/Media/TypeDetector/TIFFDetector.cs
+++ b/src/Umbraco.Core/Media/TypeDetector/TIFFDetector.cs
@@ -7,17 +7,17 @@ namespace Umbraco.Core.Media.TypeDetector
{
public static bool IsOfType(Stream fileStream)
{
- string tiffHeader = GetFileHeader(fileStream);
-
- return tiffHeader == "MM\x00\x2a" || tiffHeader == "II\x2a\x00";
+ var tiffHeader = GetFileHeader(fileStream);
+ return tiffHeader != null && tiffHeader == "MM\x00\x2a" || tiffHeader == "II\x2a\x00";
}
public static string GetFileHeader(Stream fileStream)
{
var header = RasterizedTypeDetector.GetFileHeader(fileStream);
+ if (header == null)
+ return null;
- string tiffHeader = Encoding.ASCII.GetString(header, 0, 4);
-
+ var tiffHeader = Encoding.ASCII.GetString(header, 0, 4);
return tiffHeader;
}
}
From e0a38a4d9b584b88b27e2c8eb0836c6308fe1f63 Mon Sep 17 00:00:00 2001
From: Sebastiaan Janssen
Date: Tue, 8 Jan 2019 15:53:58 +0100
Subject: [PATCH 12/84] Git clone includes a directory to clone to now,
should fix Azure Gallery release.
Tightened up the variables and paths.
---
build/azuregalleryrelease.ps1 | 40 +++++++++++++++++------------------
1 file changed, 20 insertions(+), 20 deletions(-)
diff --git a/build/azuregalleryrelease.ps1 b/build/azuregalleryrelease.ps1
index 502ca3010e..61505171a2 100644
--- a/build/azuregalleryrelease.ps1
+++ b/build/azuregalleryrelease.ps1
@@ -3,57 +3,57 @@
[string]$Directory
)
$workingDirectory = $Directory
-CD $workingDirectory
+CD "$($workingDirectory)"
# Clone repo
-$fullGitUrl = "https://$env:GIT_URL/$env:GIT_REPOSITORYNAME.git"
-git clone $fullGitUrl 2>&1 | % { $_.ToString() }
+$fullGitUrl = "https://$($env:GIT_URL)/$($env:GIT_REPOSITORYNAME).git"
+git clone $($fullGitUrl) $($env:GIT_REPOSITORYNAME) 2>&1 | % { $_.ToString() }
# Remove everything so that unzipping the release later will update everything
# Don't remove the readme file nor the git directory
Write-Host "Cleaning up git directory before adding new version"
-Remove-Item -Recurse $workingDirectory\$env:GIT_REPOSITORYNAME\* -Exclude README.md,.git
+Remove-Item -Recurse "$($workingDirectory)\$($env:GIT_REPOSITORYNAME)\*" -Exclude README.md,.git
# Find release zip
-$zipsDir = "$workingDirectory\$env:BUILD_DEFINITIONNAME\zips"
+$zipsDir = "$($workingDirectory)\$($env:BUILD_DEFINITIONNAME)\zips"
$pattern = "UmbracoCms.([0-9]{1,2}.[0-9]{1,3}.[0-9]{1,3}).zip"
-Write-Host "Searching for Umbraco release files in $workingDirectory\$zipsDir for a file with pattern $pattern"
-$file = (Get-ChildItem $zipsDir | Where-Object { $_.Name -match "$pattern" })
+Write-Host "Searching for Umbraco release files in $($zipsDir) for a file with pattern $($pattern)"
+$file = (Get-ChildItem "$($zipsDir)" | Where-Object { $_.Name -match "$($pattern)" })
if($file)
{
# Get release name
- $version = [regex]::Match($file.Name, $pattern).captures.groups[1].value
- $releaseName = "Umbraco $version"
- Write-Host "Found $releaseName"
+ $version = [regex]::Match($($file.Name), $($pattern)).captures.groups[1].value
+ $releaseName = "Umbraco $($version)"
+ Write-Host "Found $($releaseName)"
# Unzip into repository to update release
Add-Type -AssemblyName System.IO.Compression.FileSystem
- Write-Host "Unzipping $($file.FullName) to $workingDirectory\$env:GIT_REPOSITORYNAME"
- [System.IO.Compression.ZipFile]::ExtractToDirectory("$($file.FullName)", "$workingDirectory\$env:GIT_REPOSITORYNAME")
+ Write-Host "Unzipping $($file.FullName) to $($workingDirectory)\$($env:GIT_REPOSITORYNAME)"
+ [System.IO.Compression.ZipFile]::ExtractToDirectory("$($file.FullName)", "$($workingDirectory)\$($env:GIT_REPOSITORYNAME)")
# Telling git who we are
git config --global user.email "coffee@umbraco.com" 2>&1 | % { $_.ToString() }
git config --global user.name "Umbraco HQ" 2>&1 | % { $_.ToString() }
# Commit
- CD $env:GIT_REPOSITORYNAME
- Write-Host "Committing Umbraco $version Release from Build Output"
+ CD "$($workingDirectory)\$($env:GIT_REPOSITORYNAME)"
+ Write-Host "Committing Umbraco $($version) Release from Build Output"
git add . 2>&1 | % { $_.ToString() }
- git commit -m " Release $releaseName from Build Output" 2>&1 | % { $_.ToString() }
+ git commit -m " Release $($releaseName) from Build Output" 2>&1 | % { $_.ToString() }
# Tag the release
- git tag -a "v$version" -m "v$version"
+ git tag -a "v$($version)" -m "v$($version)"
# Push release to master
- $fullGitAuthUrl = "https://$($env:GIT_USERNAME):$GitHubPersonalAccessToken@$env:GIT_URL/$env:GIT_REPOSITORYNAME.git"
- git push $fullGitAuthUrl 2>&1 | % { $_.ToString() }
+ $fullGitAuthUrl = "https://$($env:GIT_USERNAME):$($GitHubPersonalAccessToken)@$($env:GIT_URL)/$($env:GIT_REPOSITORYNAME).git"
+ git push $($fullGitAuthUrl) 2>&1 | % { $_.ToString() }
#Push tag to master
- git push $fullGitAuthUrl --tags 2>&1 | % { $_.ToString() }
+ git push $($fullGitAuthUrl) --tags 2>&1 | % { $_.ToString() }
}
else
{
- Write-Error "Umbraco release file not found, searched in $workingDirectory\$zipsDir for a file with pattern $pattern - cancelling"
+ Write-Error "Umbraco release file not found, searched in $($workingDirectory)\$($zipsDir) for a file with pattern $($pattern) - canceling"
}
From caf7a6a1ca675a674ee400f4e3d0712a020e536f Mon Sep 17 00:00:00 2001
From: Sebastiaan Janssen
Date: Tue, 8 Jan 2019 21:32:47 +0100
Subject: [PATCH 13/84] Fixes #4000 - 7.13.0 Creating new node as an editor
causes exception
---
src/Umbraco.Web/Editors/ContentController.cs | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/src/Umbraco.Web/Editors/ContentController.cs b/src/Umbraco.Web/Editors/ContentController.cs
index 918f639bf1..6caf490e38 100644
--- a/src/Umbraco.Web/Editors/ContentController.cs
+++ b/src/Umbraco.Web/Editors/ContentController.cs
@@ -349,7 +349,9 @@ namespace Umbraco.Web.Editors
var mapped = AutoMapperExtensions.MapWithUmbracoContext(emptyContent, UmbracoContext);
// translate the content type name if applicable
mapped.ContentTypeName = Services.TextService.UmbracoDictionaryTranslate(mapped.ContentTypeName);
- mapped.DocumentType.Name = Services.TextService.UmbracoDictionaryTranslate(mapped.DocumentType.Name);
+ // if your user type doesn't have access to the Settings section it would not get this property mapped
+ if(mapped.DocumentType != null)
+ mapped.DocumentType.Name = Services.TextService.UmbracoDictionaryTranslate(mapped.DocumentType.Name);
//remove this tab if it exists: umbContainerView
var containerTab = mapped.Tabs.FirstOrDefault(x => x.Alias == Constants.Conventions.PropertyGroups.ListViewGroupName);
From 7658fba72574d4306f6fb7eee51ed0e1aecc0384 Mon Sep 17 00:00:00 2001
From: Sebastiaan Janssen
Date: Tue, 8 Jan 2019 12:50:36 +0100
Subject: [PATCH 14/84] Fixes #3990 All images uploaded to media section have
umbracoHeight / umbracoWidth of 200x200px
(cherry picked from commit 086157cff8fc7d34596244265a19caa847c6936b)
---
src/Umbraco.Core/IO/MediaFileSystem.cs | 3 ++-
src/Umbraco.Core/Media/Exif/ImageFile.cs | 9 +++++----
src/Umbraco.Core/Media/TypeDetector/JpegDetector.cs | 3 +--
.../Media/TypeDetector/RasterizedTypeDetector.cs | 6 +++++-
src/Umbraco.Core/Media/TypeDetector/TIFFDetector.cs | 10 +++++-----
5 files changed, 18 insertions(+), 13 deletions(-)
diff --git a/src/Umbraco.Core/IO/MediaFileSystem.cs b/src/Umbraco.Core/IO/MediaFileSystem.cs
index 39cd7ba7ad..a4305506bb 100644
--- a/src/Umbraco.Core/IO/MediaFileSystem.cs
+++ b/src/Umbraco.Core/IO/MediaFileSystem.cs
@@ -365,7 +365,8 @@ namespace Umbraco.Core.IO
{
var jpgInfo = ImageFile.FromStream(stream);
- if (jpgInfo.Format != ImageFileFormat.Unknown
+ if (jpgInfo != null
+ && jpgInfo.Format != ImageFileFormat.Unknown
&& jpgInfo.Properties.ContainsKey(ExifTag.PixelYDimension)
&& jpgInfo.Properties.ContainsKey(ExifTag.PixelXDimension))
{
diff --git a/src/Umbraco.Core/Media/Exif/ImageFile.cs b/src/Umbraco.Core/Media/Exif/ImageFile.cs
index 05a2a955c4..cfa0d90aa1 100644
--- a/src/Umbraco.Core/Media/Exif/ImageFile.cs
+++ b/src/Umbraco.Core/Media/Exif/ImageFile.cs
@@ -118,9 +118,9 @@ namespace Umbraco.Core.Media.Exif
/// The encoding to be used for text metadata when the source encoding is unknown.
/// The created from the file.
public static ImageFile FromStream(Stream stream, Encoding encoding)
- {
+ {
// JPEG
- if(JPEGDetector.IsOfType(stream))
+ if (JPEGDetector.IsOfType(stream))
{
return new JPEGFile(stream, encoding);
}
@@ -137,8 +137,9 @@ namespace Umbraco.Core.Media.Exif
return new SVGFile(stream);
}
- throw new NotValidImageFileException ();
- }
+ // We don't know
+ return null;
+ }
#endregion
}
}
diff --git a/src/Umbraco.Core/Media/TypeDetector/JpegDetector.cs b/src/Umbraco.Core/Media/TypeDetector/JpegDetector.cs
index 5b68f6ad88..73c8519bb6 100644
--- a/src/Umbraco.Core/Media/TypeDetector/JpegDetector.cs
+++ b/src/Umbraco.Core/Media/TypeDetector/JpegDetector.cs
@@ -7,8 +7,7 @@ namespace Umbraco.Core.Media.TypeDetector
public static bool IsOfType(Stream fileStream)
{
var header = GetFileHeader(fileStream);
-
- return header[0] == 0xff && header[1] == 0xD8;
+ return header != null && header[0] == 0xff && header[1] == 0xD8;
}
}
}
diff --git a/src/Umbraco.Core/Media/TypeDetector/RasterizedTypeDetector.cs b/src/Umbraco.Core/Media/TypeDetector/RasterizedTypeDetector.cs
index 9777d55c20..858b9342fe 100644
--- a/src/Umbraco.Core/Media/TypeDetector/RasterizedTypeDetector.cs
+++ b/src/Umbraco.Core/Media/TypeDetector/RasterizedTypeDetector.cs
@@ -7,9 +7,13 @@ namespace Umbraco.Core.Media.TypeDetector
public static byte[] GetFileHeader(Stream fileStream)
{
fileStream.Seek(0, SeekOrigin.Begin);
- byte[] header = new byte[8];
+ var header = new byte[8];
fileStream.Seek(0, SeekOrigin.Begin);
+ // Invalid header
+ if (fileStream.Read(header, 0, header.Length) != header.Length)
+ return null;
+
return header;
}
}
diff --git a/src/Umbraco.Core/Media/TypeDetector/TIFFDetector.cs b/src/Umbraco.Core/Media/TypeDetector/TIFFDetector.cs
index 2a6e42d0e0..6f4a05b7af 100644
--- a/src/Umbraco.Core/Media/TypeDetector/TIFFDetector.cs
+++ b/src/Umbraco.Core/Media/TypeDetector/TIFFDetector.cs
@@ -7,17 +7,17 @@ namespace Umbraco.Core.Media.TypeDetector
{
public static bool IsOfType(Stream fileStream)
{
- string tiffHeader = GetFileHeader(fileStream);
-
- return tiffHeader == "MM\x00\x2a" || tiffHeader == "II\x2a\x00";
+ var tiffHeader = GetFileHeader(fileStream);
+ return tiffHeader != null && tiffHeader == "MM\x00\x2a" || tiffHeader == "II\x2a\x00";
}
public static string GetFileHeader(Stream fileStream)
{
var header = RasterizedTypeDetector.GetFileHeader(fileStream);
+ if (header == null)
+ return null;
- string tiffHeader = Encoding.ASCII.GetString(header, 0, 4);
-
+ var tiffHeader = Encoding.ASCII.GetString(header, 0, 4);
return tiffHeader;
}
}
From 030fd4d37587e26078090d31905b26a6ddc0988f Mon Sep 17 00:00:00 2001
From: Sebastiaan Janssen
Date: Tue, 8 Jan 2019 15:53:58 +0100
Subject: [PATCH 15/84] Git clone includes a directory to clone to now,
should fix Azure Gallery release.
Tightened up the variables and paths.
(cherry picked from commit e0a38a4d9b584b88b27e2c8eb0836c6308fe1f63)
---
build/azuregalleryrelease.ps1 | 40 +++++++++++++++++------------------
1 file changed, 20 insertions(+), 20 deletions(-)
diff --git a/build/azuregalleryrelease.ps1 b/build/azuregalleryrelease.ps1
index 502ca3010e..61505171a2 100644
--- a/build/azuregalleryrelease.ps1
+++ b/build/azuregalleryrelease.ps1
@@ -3,57 +3,57 @@
[string]$Directory
)
$workingDirectory = $Directory
-CD $workingDirectory
+CD "$($workingDirectory)"
# Clone repo
-$fullGitUrl = "https://$env:GIT_URL/$env:GIT_REPOSITORYNAME.git"
-git clone $fullGitUrl 2>&1 | % { $_.ToString() }
+$fullGitUrl = "https://$($env:GIT_URL)/$($env:GIT_REPOSITORYNAME).git"
+git clone $($fullGitUrl) $($env:GIT_REPOSITORYNAME) 2>&1 | % { $_.ToString() }
# Remove everything so that unzipping the release later will update everything
# Don't remove the readme file nor the git directory
Write-Host "Cleaning up git directory before adding new version"
-Remove-Item -Recurse $workingDirectory\$env:GIT_REPOSITORYNAME\* -Exclude README.md,.git
+Remove-Item -Recurse "$($workingDirectory)\$($env:GIT_REPOSITORYNAME)\*" -Exclude README.md,.git
# Find release zip
-$zipsDir = "$workingDirectory\$env:BUILD_DEFINITIONNAME\zips"
+$zipsDir = "$($workingDirectory)\$($env:BUILD_DEFINITIONNAME)\zips"
$pattern = "UmbracoCms.([0-9]{1,2}.[0-9]{1,3}.[0-9]{1,3}).zip"
-Write-Host "Searching for Umbraco release files in $workingDirectory\$zipsDir for a file with pattern $pattern"
-$file = (Get-ChildItem $zipsDir | Where-Object { $_.Name -match "$pattern" })
+Write-Host "Searching for Umbraco release files in $($zipsDir) for a file with pattern $($pattern)"
+$file = (Get-ChildItem "$($zipsDir)" | Where-Object { $_.Name -match "$($pattern)" })
if($file)
{
# Get release name
- $version = [regex]::Match($file.Name, $pattern).captures.groups[1].value
- $releaseName = "Umbraco $version"
- Write-Host "Found $releaseName"
+ $version = [regex]::Match($($file.Name), $($pattern)).captures.groups[1].value
+ $releaseName = "Umbraco $($version)"
+ Write-Host "Found $($releaseName)"
# Unzip into repository to update release
Add-Type -AssemblyName System.IO.Compression.FileSystem
- Write-Host "Unzipping $($file.FullName) to $workingDirectory\$env:GIT_REPOSITORYNAME"
- [System.IO.Compression.ZipFile]::ExtractToDirectory("$($file.FullName)", "$workingDirectory\$env:GIT_REPOSITORYNAME")
+ Write-Host "Unzipping $($file.FullName) to $($workingDirectory)\$($env:GIT_REPOSITORYNAME)"
+ [System.IO.Compression.ZipFile]::ExtractToDirectory("$($file.FullName)", "$($workingDirectory)\$($env:GIT_REPOSITORYNAME)")
# Telling git who we are
git config --global user.email "coffee@umbraco.com" 2>&1 | % { $_.ToString() }
git config --global user.name "Umbraco HQ" 2>&1 | % { $_.ToString() }
# Commit
- CD $env:GIT_REPOSITORYNAME
- Write-Host "Committing Umbraco $version Release from Build Output"
+ CD "$($workingDirectory)\$($env:GIT_REPOSITORYNAME)"
+ Write-Host "Committing Umbraco $($version) Release from Build Output"
git add . 2>&1 | % { $_.ToString() }
- git commit -m " Release $releaseName from Build Output" 2>&1 | % { $_.ToString() }
+ git commit -m " Release $($releaseName) from Build Output" 2>&1 | % { $_.ToString() }
# Tag the release
- git tag -a "v$version" -m "v$version"
+ git tag -a "v$($version)" -m "v$($version)"
# Push release to master
- $fullGitAuthUrl = "https://$($env:GIT_USERNAME):$GitHubPersonalAccessToken@$env:GIT_URL/$env:GIT_REPOSITORYNAME.git"
- git push $fullGitAuthUrl 2>&1 | % { $_.ToString() }
+ $fullGitAuthUrl = "https://$($env:GIT_USERNAME):$($GitHubPersonalAccessToken)@$($env:GIT_URL)/$($env:GIT_REPOSITORYNAME).git"
+ git push $($fullGitAuthUrl) 2>&1 | % { $_.ToString() }
#Push tag to master
- git push $fullGitAuthUrl --tags 2>&1 | % { $_.ToString() }
+ git push $($fullGitAuthUrl) --tags 2>&1 | % { $_.ToString() }
}
else
{
- Write-Error "Umbraco release file not found, searched in $workingDirectory\$zipsDir for a file with pattern $pattern - cancelling"
+ Write-Error "Umbraco release file not found, searched in $($workingDirectory)\$($zipsDir) for a file with pattern $($pattern) - canceling"
}
From 51875539b98e51d4214d3c266ee5cef0ab681e49 Mon Sep 17 00:00:00 2001
From: Sebastiaan Janssen
Date: Tue, 8 Jan 2019 21:32:47 +0100
Subject: [PATCH 16/84] Fixes #4000 - 7.13.0 Creating new node as an editor
causes exception
(cherry picked from commit caf7a6a1ca675a674ee400f4e3d0712a020e536f)
---
src/Umbraco.Web/Editors/ContentController.cs | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/src/Umbraco.Web/Editors/ContentController.cs b/src/Umbraco.Web/Editors/ContentController.cs
index 918f639bf1..6caf490e38 100644
--- a/src/Umbraco.Web/Editors/ContentController.cs
+++ b/src/Umbraco.Web/Editors/ContentController.cs
@@ -349,7 +349,9 @@ namespace Umbraco.Web.Editors
var mapped = AutoMapperExtensions.MapWithUmbracoContext(emptyContent, UmbracoContext);
// translate the content type name if applicable
mapped.ContentTypeName = Services.TextService.UmbracoDictionaryTranslate(mapped.ContentTypeName);
- mapped.DocumentType.Name = Services.TextService.UmbracoDictionaryTranslate(mapped.DocumentType.Name);
+ // if your user type doesn't have access to the Settings section it would not get this property mapped
+ if(mapped.DocumentType != null)
+ mapped.DocumentType.Name = Services.TextService.UmbracoDictionaryTranslate(mapped.DocumentType.Name);
//remove this tab if it exists: umbContainerView
var containerTab = mapped.Tabs.FirstOrDefault(x => x.Alias == Constants.Conventions.PropertyGroups.ListViewGroupName);
From 5b17072d55a832a8a6b104294c0f2fe95983d5c3 Mon Sep 17 00:00:00 2001
From: Sebastiaan Janssen
Date: Tue, 8 Jan 2019 21:45:34 +0100
Subject: [PATCH 17/84] Bump version to 7.13.1
---
src/SolutionInfo.cs | 4 ++--
src/Umbraco.Core/Configuration/UmbracoVersion.cs | 2 +-
src/Umbraco.Web.UI/Umbraco.Web.UI.csproj | 4 ++--
3 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/src/SolutionInfo.cs b/src/SolutionInfo.cs
index 8b47029965..d2cdb661f5 100644
--- a/src/SolutionInfo.cs
+++ b/src/SolutionInfo.cs
@@ -11,5 +11,5 @@ using System.Resources;
[assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyFileVersion("7.13.0")]
-[assembly: AssemblyInformationalVersion("7.13.0")]
+[assembly: AssemblyFileVersion("7.13.1")]
+[assembly: AssemblyInformationalVersion("7.13.1")]
diff --git a/src/Umbraco.Core/Configuration/UmbracoVersion.cs b/src/Umbraco.Core/Configuration/UmbracoVersion.cs
index ab71fdb40d..a63aa16824 100644
--- a/src/Umbraco.Core/Configuration/UmbracoVersion.cs
+++ b/src/Umbraco.Core/Configuration/UmbracoVersion.cs
@@ -6,7 +6,7 @@ namespace Umbraco.Core.Configuration
{
public class UmbracoVersion
{
- private static readonly Version Version = new Version("7.13.0");
+ private static readonly Version Version = new Version("7.13.1");
///
/// Gets the current version of Umbraco.
diff --git a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj
index d9b25a3b31..512d8637d8 100644
--- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj
+++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj
@@ -1039,9 +1039,9 @@ xcopy "$(ProjectDir)"..\packages\SqlServerCE.4.0.0.1\x86\*.* "$(TargetDir)x86\"
True
True
- 7130
+ 7131
/
- http://localhost:7130
+ http://localhost:7131
False
False
From 0f61de8bcdc2fad57246f832e7a78101ec416d3c Mon Sep 17 00:00:00 2001
From: Sebastiaan Janssen
Date: Tue, 8 Jan 2019 21:49:17 +0100
Subject: [PATCH 18/84] Bumps version to 7.14.0
---
src/SolutionInfo.cs | 4 ++--
src/Umbraco.Core/Configuration/UmbracoVersion.cs | 2 +-
src/Umbraco.Web.UI/Umbraco.Web.UI.csproj | 4 ++--
3 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/src/SolutionInfo.cs b/src/SolutionInfo.cs
index 8b47029965..88380ddb5f 100644
--- a/src/SolutionInfo.cs
+++ b/src/SolutionInfo.cs
@@ -11,5 +11,5 @@ using System.Resources;
[assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyFileVersion("7.13.0")]
-[assembly: AssemblyInformationalVersion("7.13.0")]
+[assembly: AssemblyFileVersion("7.14.0")]
+[assembly: AssemblyInformationalVersion("7.14.0")]
diff --git a/src/Umbraco.Core/Configuration/UmbracoVersion.cs b/src/Umbraco.Core/Configuration/UmbracoVersion.cs
index ab71fdb40d..dc2283758b 100644
--- a/src/Umbraco.Core/Configuration/UmbracoVersion.cs
+++ b/src/Umbraco.Core/Configuration/UmbracoVersion.cs
@@ -6,7 +6,7 @@ namespace Umbraco.Core.Configuration
{
public class UmbracoVersion
{
- private static readonly Version Version = new Version("7.13.0");
+ private static readonly Version Version = new Version("7.14.0");
///
/// Gets the current version of Umbraco.
diff --git a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj
index d9b25a3b31..ad372bb13f 100644
--- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj
+++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj
@@ -1039,9 +1039,9 @@ xcopy "$(ProjectDir)"..\packages\SqlServerCE.4.0.0.1\x86\*.* "$(TargetDir)x86\"
True
True
- 7130
+ 7140
/
- http://localhost:7130
+ http://localhost:7140
False
False
From d19a23eec6b4ab6f76ad3126f8b68bee077102f4 Mon Sep 17 00:00:00 2001
From: Floris Robbemont
Date: Thu, 3 Jan 2019 16:38:37 +0100
Subject: [PATCH 19/84] Fix for wrong sorting overload in MediaService (#3948)
(cherry picked from commit 0852b20b311cbeb4efa6360c5e1e17720c4d7b16)
---
src/Umbraco.Core/Services/MediaService.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/Umbraco.Core/Services/MediaService.cs b/src/Umbraco.Core/Services/MediaService.cs
index d1f11c619a..b95a8a258c 100644
--- a/src/Umbraco.Core/Services/MediaService.cs
+++ b/src/Umbraco.Core/Services/MediaService.cs
@@ -509,7 +509,7 @@ namespace Umbraco.Core.Services
public IEnumerable GetPagedChildren(int id, long pageIndex, int pageSize, out long totalChildren,
string orderBy, Direction orderDirection, bool orderBySystemField, string filter)
{
- return GetPagedChildren(id, pageIndex, pageSize, out totalChildren, orderBy, orderDirection, true, filter, null);
+ return GetPagedChildren(id, pageIndex, pageSize, out totalChildren, orderBy, orderDirection, orderBySystemField, filter, null);
}
///
From a16e31c671b3756d6583c245615fddab50baa783 Mon Sep 17 00:00:00 2001
From: Kenn Jacobsen
Date: Sun, 6 Jan 2019 19:11:58 +0100
Subject: [PATCH 20/84] Safeguard the tags value converter against empty tags
(cherry picked from commit cc6c16894c288f422140482f55bd773e01df08f8)
---
.../ValueConverters/TagsValueConverter.cs | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/src/Umbraco.Core/PropertyEditors/ValueConverters/TagsValueConverter.cs b/src/Umbraco.Core/PropertyEditors/ValueConverters/TagsValueConverter.cs
index b085748487..204fde0c2e 100644
--- a/src/Umbraco.Core/PropertyEditors/ValueConverters/TagsValueConverter.cs
+++ b/src/Umbraco.Core/PropertyEditors/ValueConverters/TagsValueConverter.cs
@@ -42,16 +42,22 @@ namespace Umbraco.Core.PropertyEditors.ValueConverters
public override object ConvertDataToSource(PublishedPropertyType propertyType, object source, bool preview)
{
+ var sourceAsString = source?.ToString();
+ if(sourceAsString.IsNullOrWhiteSpace())
+ {
+ return new string[0];
+ }
+
// if Json storage type deserialzie and return as string array
if (JsonStorageType(propertyType.DataTypeId))
{
- var jArray = JsonConvert.DeserializeObject(source.ToString());
+ var jArray = JsonConvert.DeserializeObject(sourceAsString);
return jArray.ToObject();
}
// Otherwise assume CSV storage type and return as string array
var csvTags =
- source.ToString()
+ sourceAsString
.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries)
.ToArray();
return csvTags;
From ec60ba142aae54da0ebfbe70f125932f591c948a Mon Sep 17 00:00:00 2001
From: Sebastiaan Janssen
Date: Wed, 9 Jan 2019 10:50:27 +0100
Subject: [PATCH 21/84] Fixes #3993 Recent changes in color picker has caused
incompatibility with existing picker
---
.../propertyeditors/colorpicker/colorpicker.controller.js | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/colorpicker/colorpicker.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/colorpicker/colorpicker.controller.js
index abb26ef4a2..3a6ddc5cfd 100644
--- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/colorpicker/colorpicker.controller.js
+++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/colorpicker/colorpicker.controller.js
@@ -123,6 +123,11 @@ function ColorPickerController($scope) {
if (!$scope.model.value)
return false;
+ // Backwards compatibility, the color used to be stored as a hex value only
+ if ($scope.model.value.length === 6) {
+ $scope.model.value = { value: $scope.model.value, label: $scope.model.value };
+ }
+
// Complex color (value and label)?
if (!$scope.model.value.hasOwnProperty("value"))
return $scope.model.value === color.value;
From d41dbce60125cf9a8aa30e4d5a0bf39bddb59e1a Mon Sep 17 00:00:00 2001
From: Kenn Jacobsen
Date: Wed, 9 Jan 2019 11:20:34 +0100
Subject: [PATCH 22/84] Fix content picker dirty checking (#4003)
---
.../contentpicker/contentpicker.controller.js | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/contentpicker/contentpicker.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/contentpicker/contentpicker.controller.js
index c1fe21b1b5..ee8c193b4b 100644
--- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/contentpicker/contentpicker.controller.js
+++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/contentpicker/contentpicker.controller.js
@@ -35,7 +35,6 @@ function contentPickerController($scope, entityResource, editorState, iconHelper
return $scope.model.config.idType === "udi" ? i.udi : i.id;
});
$scope.model.value = trim(currIds.join(), ",");
- angularHelper.getCurrentForm($scope).$setDirty();
//Validate!
if ($scope.model.config && $scope.model.config.minNumber && parseInt($scope.model.config.minNumber) > $scope.renderModel.length) {
@@ -84,7 +83,10 @@ function contentPickerController($scope, entityResource, editorState, iconHelper
opacity: 0.7,
tolerance: "pointer",
scroll: true,
- zIndex: 6000
+ zIndex: 6000,
+ update: function (e, ui) {
+ angularHelper.getCurrentForm($scope).$setDirty();
+ }
};
if ($scope.model.config) {
From a809e35e5d07117c9a2d3d54050685c3253335da Mon Sep 17 00:00:00 2001
From: Robert
Date: Wed, 9 Jan 2019 11:29:42 +0100
Subject: [PATCH 23/84] Fixes - temp8-40120 tags-validation-bug
---
.../directives/components/tags/umbtagseditor.directive.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/tags/umbtagseditor.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/tags/umbtagseditor.directive.js
index 8bad5ae8fd..fea7528d5b 100644
--- a/src/Umbraco.Web.UI.Client/src/common/directives/components/tags/umbtagseditor.directive.js
+++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/tags/umbtagseditor.directive.js
@@ -189,7 +189,7 @@
*/
function validateMandatory() {
return {
- isValid: !vm.validation.mandatory || (vm.viewModel != null && vm.viewModel.length > 0),
+ isValid: !vm.validation.mandatory || (vm.viewModel != null && vm.viewModel.length > 0) || (vm.value != null && vm.value.length > 0),
errorMsg: "Value cannot be empty",
errorKey: "required"
};
From fe689e68551d20e8c733752132f5cc216e5db43f Mon Sep 17 00:00:00 2001
From: elitsa
Date: Wed, 9 Jan 2019 12:08:46 +0100
Subject: [PATCH 24/84] Added timeout to for rebinding editor shortcuts, and a
shortcut for a media picker.
---
.../src/common/services/editor.service.js | 10 ++++++----
.../infiniteeditors/mediapicker/mediapicker.html | 1 +
2 files changed, 7 insertions(+), 4 deletions(-)
diff --git a/src/Umbraco.Web.UI.Client/src/common/services/editor.service.js b/src/Umbraco.Web.UI.Client/src/common/services/editor.service.js
index 0d6432b01f..c495c4e7a1 100644
--- a/src/Umbraco.Web.UI.Client/src/common/services/editor.service.js
+++ b/src/Umbraco.Web.UI.Client/src/common/services/editor.service.js
@@ -162,7 +162,7 @@ When building a custom infinite editor view you can use the same components as a
(function () {
"use strict";
- function editorService(eventsService, keyboardService) {
+ function editorService(eventsService, keyboardService, $timeout) {
let editorsKeyboardShorcuts = [];
var editors = [];
@@ -246,9 +246,11 @@ When building a custom infinite editor view you can use the same components as a
// emit event to let components know an editor has been removed
eventsService.emit("appState.editors.close", args);
- // rebind keyboard shortcuts for the new editor in focus
- rebindKeyboardShortcuts();
-
+ $timeout(function() {
+ // rebind keyboard shortcuts for the new editor in focus
+ rebindKeyboardShortcuts();
+ }, 0);
+
}
/**
diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediapicker/mediapicker.html b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediapicker/mediapicker.html
index 3bb694cac6..cac412df8b 100644
--- a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediapicker/mediapicker.html
+++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediapicker/mediapicker.html
@@ -171,6 +171,7 @@
From 10cf10b33a4333a18e816ed5f11be2b5d7e91a6d Mon Sep 17 00:00:00 2001
From: Kenn Jacobsen
Date: Wed, 9 Jan 2019 12:22:55 +0100
Subject: [PATCH 25/84] Set form as dirty when removing a tag
---
.../src/views/propertyeditors/tags/tags.controller.js | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/tags/tags.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/tags/tags.controller.js
index 688ac7693f..a61930f877 100644
--- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/tags/tags.controller.js
+++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/tags/tags.controller.js
@@ -1,9 +1,12 @@
angular.module("umbraco")
.controller("Umbraco.PropertyEditors.TagsController",
- function ($scope) {
+ function ($scope, angularHelper) {
$scope.valueChanged = function(value) {
$scope.model.value = value;
+ // the model value seems to be a reference to the same array, so we need
+ // to set the form as dirty explicitly when the content of the array changes
+ angularHelper.getCurrentForm($scope).$setDirty();
}
}
From ff085c97ce4f8c7d7abb0510401ad0ddb17f2ae7 Mon Sep 17 00:00:00 2001
From: Sebastiaan Janssen
Date: Wed, 9 Jan 2019 14:57:17 +0100
Subject: [PATCH 26/84] Revert "Added eslintignore file"
This reverts commit 673735c2fed762d19fefec662bb79c435e49b763.
---
src/Umbraco.Web.UI/.eslintignore | 3 ---
src/Umbraco.Web.UI/Umbraco.Web.UI.csproj | 1 -
2 files changed, 4 deletions(-)
delete mode 100644 src/Umbraco.Web.UI/.eslintignore
diff --git a/src/Umbraco.Web.UI/.eslintignore b/src/Umbraco.Web.UI/.eslintignore
deleted file mode 100644
index 6cac59fac0..0000000000
--- a/src/Umbraco.Web.UI/.eslintignore
+++ /dev/null
@@ -1,3 +0,0 @@
-
-/Umbraco/**
-/Umbraco_Client/**
diff --git a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj
index 512d8637d8..dc9625f39e 100644
--- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj
+++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj
@@ -520,7 +520,6 @@
-
404handlers.config
From 944d47f669b59e65ce58a4a2f8baa38e34dfc0a1 Mon Sep 17 00:00:00 2001
From: Stephan
Date: Wed, 9 Jan 2019 17:39:32 +0100
Subject: [PATCH 27/84] Refactor filesystems registration
---
src/Umbraco.Core/Components/Composition.cs | 123 +++++++++---------
.../Components/CompositionExtensions.cs | 13 +-
.../Composing/CollectionBuilderBase.cs | 2 +-
.../Composers/FileSystemsComposer.cs | 31 +++--
.../Composing/CompositionExtensions.cs | 9 +-
.../Composing/FactoryExtensions.cs | 3 +
src/Umbraco.Core/Composing/IFactory.cs | 12 +-
src/Umbraco.Core/Composing/IRegister.cs | 21 ++-
.../Composing/LazyCollectionBuilderBase.cs | 2 +-
.../LightInject/LightInjectContainer.cs | 57 ++++----
.../Composing/OrderedCollectionBuilderBase.cs | 2 +-
.../Composing/RegisterExtensions.cs | 10 ++
.../Composing/TargetedServiceProvider.cs | 18 +++
.../WeightedCollectionBuilderBase.cs | 2 +-
src/Umbraco.Core/IO/SupportingFileSystems.cs | 11 ++
src/Umbraco.Core/Umbraco.Core.csproj | 2 +
src/Umbraco.Web/Composing/ModuleInjector.cs | 5 +-
17 files changed, 211 insertions(+), 112 deletions(-)
create mode 100644 src/Umbraco.Core/Composing/TargetedServiceProvider.cs
create mode 100644 src/Umbraco.Core/IO/SupportingFileSystems.cs
diff --git a/src/Umbraco.Core/Components/Composition.cs b/src/Umbraco.Core/Components/Composition.cs
index dd0b83dcb3..6cd8c8e5f0 100644
--- a/src/Umbraco.Core/Components/Composition.cs
+++ b/src/Umbraco.Core/Components/Composition.cs
@@ -17,7 +17,7 @@ namespace Umbraco.Core.Components
public class Composition : IRegister
{
private readonly Dictionary _builders = new Dictionary();
- private readonly Dictionary _uniques = new Dictionary();
+ private readonly Dictionary> _uniques = new Dictionary>();
private readonly IRegister _register;
///
@@ -81,14 +81,30 @@ namespace Umbraco.Core.Components
public void Register(Type serviceType, Type implementingType, Lifetime lifetime = Lifetime.Transient)
=> _register.Register(serviceType, implementingType, lifetime);
+ ///
+ public void RegisterFor(Type implementingType, Lifetime lifetime = Lifetime.Transient)
+ where TService : class
+ => _register.RegisterFor(implementingType, lifetime);
+
///
public void Register(Func factory, Lifetime lifetime = Lifetime.Transient)
+ where TService : class
=> _register.Register(factory, lifetime);
+ ///
+ public void RegisterFor(Func factory, Lifetime lifetime = Lifetime.Transient)
+ where TService : class
+ => _register.RegisterFor(factory, lifetime);
+
///
public void RegisterInstance(Type serviceType, object instance)
=> _register.RegisterInstance(serviceType, instance);
+ ///
+ public void RegisterInstanceFor(TService instance)
+ where TService : class
+ => _register.RegisterInstanceFor(instance);
+
///
public void RegisterAuto(Type serviceBaseType)
=> _register.RegisterAuto(serviceBaseType);
@@ -104,10 +120,12 @@ namespace Umbraco.Core.Components
onCreating();
foreach (var unique in _uniques.Values)
- unique.RegisterWith(_register);
+ unique(_register);
+ _uniques.Clear(); // no point keep them around
foreach (var builder in _builders.Values)
builder.RegisterWith(_register);
+ _builders.Clear(); // no point keep them around
Configs.RegisterWith(_register);
@@ -123,74 +141,63 @@ namespace Umbraco.Core.Components
#region Unique
- ///
- /// Registers a unique service.
- ///
- /// Unique services have one single implementation, and a Singleton lifetime.
- public void RegisterUnique(Type serviceType, Type implementingType)
- => _uniques[serviceType] = new Unique(serviceType, implementingType);
+ private string GetUniqueName()
+ => GetUniqueName(typeof(TService));
+
+ private string GetUniqueName(Type serviceType)
+ => serviceType.FullName;
+
+ private string GetUniqueName()
+ => GetUniqueName(typeof(TService), typeof(TTarget));
+
+ private string GetUniqueName(Type serviceType, Type targetType)
+ => serviceType.FullName + "::" + targetType.FullName;
///
/// Registers a unique service.
///
/// Unique services have one single implementation, and a Singleton lifetime.
- public void RegisterUnique(Type serviceType, object instance)
- => _uniques[serviceType] = new Unique(serviceType, instance);
+ public void RegisterUnique(Type serviceType, Type implementingType)
+ => _uniques[GetUniqueName(serviceType)] = register => register.Register(serviceType, implementingType, Lifetime.Singleton);
+
+ ///
+ /// Registers a unique service, for a target.
+ ///
+ /// Unique services have one single implementation, and a Singleton lifetime.
+ public void RegisterUniqueFor(Type implementingType)
+ where TService : class
+ => _uniques[GetUniqueName()] = register => register.RegisterFor(implementingType, Lifetime.Singleton);
+
+ ///
+ /// Registers a unique service.
+ ///
+ /// Unique services have one single implementation, and a Singleton lifetime.
+ public void RegisterUniqueInstance(Type serviceType, object instance)
+ => _uniques[GetUniqueName(serviceType)] = register => register.RegisterInstance(serviceType, instance);
+
+ ///
+ /// Registers a unique service, for a target.
+ ///
+ /// Unique services have one single implementation, and a Singleton lifetime.
+ public void RegisterUniqueInstanceFor(TService instance)
+ where TService : class
+ => _uniques[GetUniqueName()] = register => register.RegisterInstanceFor(instance);
///
/// Registers a unique service.
///
/// Unique services have one single implementation, and a Singleton lifetime.
public void RegisterUnique(Func factory)
- => _uniques[typeof(TService)] = new Unique(factory);
+ where TService : class
+ => _uniques[GetUniqueName()] = register => register.Register(factory, Lifetime.Singleton);
- private class Unique
- {
- private readonly Type _serviceType;
- private readonly Type _implementingType;
- private readonly object _instance;
-
- protected Unique(Type serviceType)
- {
- _serviceType = serviceType;
- }
-
- public Unique(Type serviceType, Type implementingType)
- : this(serviceType)
- {
- _implementingType = implementingType;
- }
-
- public Unique(Type serviceType, object instance)
- : this(serviceType)
- {
- _instance = instance;
- }
-
- public virtual void RegisterWith(IRegister register)
- {
- if (_implementingType != null)
- register.Register(_serviceType, _implementingType, Lifetime.Singleton);
- else if (_instance != null)
- register.RegisterInstance(_serviceType, _instance);
- }
- }
-
- private class Unique : Unique
- {
- private readonly Func _factory;
-
- public Unique(Func factory)
- : base(typeof(TService))
- {
- _factory = factory;
- }
-
- public override void RegisterWith(IRegister register)
- {
- register.Register(_factory, Lifetime.Singleton);
- }
- }
+ ///
+ /// Registers a unique service, for a target.
+ ///
+ /// Unique services have one single implementation, and a Singleton lifetime.
+ public void RegisterUniqueFor(Func factory)
+ where TService : class
+ => _uniques[GetUniqueName()] = register => register.RegisterFor(factory, Lifetime.Singleton);
#endregion
diff --git a/src/Umbraco.Core/Components/CompositionExtensions.cs b/src/Umbraco.Core/Components/CompositionExtensions.cs
index 93d190d17e..a4bc82cb4b 100644
--- a/src/Umbraco.Core/Components/CompositionExtensions.cs
+++ b/src/Umbraco.Core/Components/CompositionExtensions.cs
@@ -26,15 +26,16 @@ namespace Umbraco.Core.Components
/// The type of the filesystem.
/// The implementing type.
/// The composition.
- /// A factory method creating the supporting filesystem.
/// The register.
- public static void RegisterFileSystem(this Composition composition, Func supportingFileSystemFactory)
+ public static void RegisterFileSystem(this Composition composition)
where TImplementing : FileSystemWrapper, TFileSystem
+ where TFileSystem : class
{
composition.RegisterUnique(factory =>
{
var fileSystems = factory.GetInstance();
- return fileSystems.GetFileSystem(supportingFileSystemFactory(factory));
+ var supporting = factory.GetInstance();
+ return fileSystems.GetFileSystem(supporting.For());
});
}
@@ -43,15 +44,15 @@ namespace Umbraco.Core.Components
///
/// The type of the filesystem.
/// The composition.
- /// A factory method creating the supporting filesystem.
/// The register.
- public static void RegisterFileSystem(this Composition composition, Func supportingFileSystemFactory)
+ public static void RegisterFileSystem(this Composition composition)
where TFileSystem : FileSystemWrapper
{
composition.RegisterUnique(factory =>
{
var fileSystems = factory.GetInstance();
- return fileSystems.GetFileSystem(supportingFileSystemFactory(factory));
+ var supporting = factory.GetInstance();
+ return fileSystems.GetFileSystem(supporting.For());
});
}
diff --git a/src/Umbraco.Core/Composing/CollectionBuilderBase.cs b/src/Umbraco.Core/Composing/CollectionBuilderBase.cs
index 7633f6b001..41038ea4e9 100644
--- a/src/Umbraco.Core/Composing/CollectionBuilderBase.cs
+++ b/src/Umbraco.Core/Composing/CollectionBuilderBase.cs
@@ -12,7 +12,7 @@ namespace Umbraco.Core.Composing
/// The type of the items.
public abstract class CollectionBuilderBase : ICollectionBuilder
where TBuilder: CollectionBuilderBase
- where TCollection : IBuilderCollection
+ where TCollection : class, IBuilderCollection
{
private readonly List _types = new List();
private readonly object _locker = new object();
diff --git a/src/Umbraco.Core/Composing/Composers/FileSystemsComposer.cs b/src/Umbraco.Core/Composing/Composers/FileSystemsComposer.cs
index f1fb095406..ab4bd015de 100644
--- a/src/Umbraco.Core/Composing/Composers/FileSystemsComposer.cs
+++ b/src/Umbraco.Core/Composing/Composers/FileSystemsComposer.cs
@@ -12,10 +12,9 @@ namespace Umbraco.Core.Composing.Composers
*
* Create a component and use it to modify the composition by adding something like:
*
- * composition.Container.RegisterFileSystem(
- * factory => new PhysicalFileSystem("~/somewhere"));
+ * composition.RegisterUniqueFor(...);
*
- * return whatever supporting filesystem you like.
+ * and register whatever supporting filesystem you like.
*
*
* HOW TO IMPLEMENT MY OWN FILESYSTEM
@@ -30,12 +29,15 @@ namespace Umbraco.Core.Composing.Composers
* { }
* }
*
- * The ctor can have more parameters that will be resolved by the container.
+ * The ctor can have more parameters, that will be resolved by the container.
*
* Register your filesystem, in a component:
*
- * composition.Container.RegisterFileSystem(
- * factory => new PhysicalFileSystem("~/my"));
+ * composition.RegisterFileSystem();
+ *
+ * Register the underlying filesystem:
+ *
+ * composition.RegisterUniqueFor(...);
*
* And that's it, you can inject MyFileSystem wherever it's needed.
*
@@ -48,8 +50,8 @@ namespace Umbraco.Core.Composing.Composers
* Make the class implement the interface, then
* register your filesystem, in a component:
*
- * composition.Container.RegisterFileSystem(
- * factory => new PhysicalFileSystem("~/my"));
+ * composition.RegisterFileSystem();
+ * composition.RegisterUniqueFor(...);
*
* And that's it, you can inject IMyFileSystem wherever it's needed.
*
@@ -79,9 +81,16 @@ namespace Umbraco.Core.Composing.Composers
// register the scheme for media paths
composition.RegisterUnique();
- // register the IMediaFileSystem implementation with a supporting filesystem
- composition.RegisterFileSystem(
- factory => new PhysicalFileSystem("~/media"));
+ // register the IMediaFileSystem implementation
+ composition.RegisterFileSystem();
+
+ // register the supporting filesystems provider
+ composition.Register(factory => new SupportingFileSystems(factory), Lifetime.Singleton);
+
+ // register the IFileSystem supporting the IMediaFileSystem
+ // this is the only thing that need to be overriden to change the supporting filesystem
+ // and, SupportingFileSystem.For() returns the underlying filesystem
+ composition.RegisterUniqueFor(_ => new PhysicalFileSystem("~/media"));
return composition;
}
diff --git a/src/Umbraco.Core/Composing/CompositionExtensions.cs b/src/Umbraco.Core/Composing/CompositionExtensions.cs
index cfc465b59d..ac9a5d6409 100644
--- a/src/Umbraco.Core/Composing/CompositionExtensions.cs
+++ b/src/Umbraco.Core/Composing/CompositionExtensions.cs
@@ -51,11 +51,18 @@ namespace Umbraco.Core.Composing
public static void RegisterUnique(this Composition composition)
=> composition.RegisterUnique(typeof(TService), typeof(TImplementing));
+ ///
+ /// Registers a unique service with an implementation type, for a target.
+ ///
+ public static void RegisterUniqueFor(this Composition composition)
+ where TService : class
+ => composition.RegisterUniqueFor(typeof(TImplementing));
+
///
/// Registers a unique service with an implementing instance.
///
public static void RegisterUnique(this Composition composition, TService instance)
- => composition.RegisterUnique(typeof(TService), instance);
+ => composition.RegisterUniqueInstance(typeof(TService), instance);
#endregion
}
diff --git a/src/Umbraco.Core/Composing/FactoryExtensions.cs b/src/Umbraco.Core/Composing/FactoryExtensions.cs
index 2640b7f7e6..8027f2c7a1 100644
--- a/src/Umbraco.Core/Composing/FactoryExtensions.cs
+++ b/src/Umbraco.Core/Composing/FactoryExtensions.cs
@@ -17,6 +17,7 @@ namespace Umbraco.Core.Composing
/// An instance of the specified type.
/// Throws an exception if the factory failed to get an instance of the specified type.
public static T GetInstance(this IFactory factory)
+ where T : class
=> (T)factory.GetInstance(typeof(T));
///
@@ -28,6 +29,7 @@ namespace Umbraco.Core.Composing
/// of the specified type. Throws an exception if the factory does know how
/// to get an instance of the specified type, but failed to do so.
public static T TryGetInstance(this IFactory factory)
+ where T : class
=> (T)factory.TryGetInstance(typeof(T));
///
@@ -42,6 +44,7 @@ namespace Umbraco.Core.Composing
/// The arguments are used as dependencies by the factory.
///
public static T CreateInstance(this IFactory factory, params object[] args)
+ where T : class
=> (T)factory.CreateInstance(typeof(T), args);
///
diff --git a/src/Umbraco.Core/Composing/IFactory.cs b/src/Umbraco.Core/Composing/IFactory.cs
index 9a59b1c052..20fbe33737 100644
--- a/src/Umbraco.Core/Composing/IFactory.cs
+++ b/src/Umbraco.Core/Composing/IFactory.cs
@@ -28,6 +28,15 @@ namespace Umbraco.Core.Composing
/// Throws an exception if the container failed to get an instance of the specified type.
object GetInstance(Type type);
+ ///
+ /// Gets a targeted instance of a service.
+ ///
+ /// The type of the service.
+ /// The type of the target.
+ /// The instance of the specified type for the specified target.
+ /// Throws an exception if the container failed to get an instance of the specified type.
+ TService GetInstanceFor();
+
///
/// Tries to get an instance of a service.
///
@@ -48,7 +57,8 @@ namespace Umbraco.Core.Composing
/// Gets all instances of a service.
///
/// The type of the service.
- IEnumerable GetAllInstances();
+ IEnumerable GetAllInstances()
+ where TService : class;
///
/// Releases an instance.
diff --git a/src/Umbraco.Core/Composing/IRegister.cs b/src/Umbraco.Core/Composing/IRegister.cs
index 8ad3db5409..d145df8790 100644
--- a/src/Umbraco.Core/Composing/IRegister.cs
+++ b/src/Umbraco.Core/Composing/IRegister.cs
@@ -33,16 +33,35 @@ namespace Umbraco.Core.Composing
///
void Register(Type serviceType, Type implementingType, Lifetime lifetime = Lifetime.Transient);
+ ///
+ /// Registers a service with an implementation type, for a target.
+ ///
+ void RegisterFor(Type implementingType, Lifetime lifetime = Lifetime.Transient)
+ where TService : class;
+
///
/// Registers a service with an implementation factory.
///
- void Register(Func factory, Lifetime lifetime = Lifetime.Transient);
+ void Register(Func factory, Lifetime lifetime = Lifetime.Transient)
+ where TService : class;
+
+ ///
+ /// Registers a service with an implementation factory, for a target.
+ ///
+ void RegisterFor(Func factory, Lifetime lifetime = Lifetime.Transient)
+ where TService : class;
///
/// Registers a service with an implementing instance.
///
void RegisterInstance(Type serviceType, object instance);
+ ///
+ /// Registers a service with an implementing instance, for a target.
+ ///
+ void RegisterInstanceFor(TService instance)
+ where TService : class;
+
///
/// Registers a base type for auto-registration.
///
diff --git a/src/Umbraco.Core/Composing/LazyCollectionBuilderBase.cs b/src/Umbraco.Core/Composing/LazyCollectionBuilderBase.cs
index a1a06621e9..46b06daf7d 100644
--- a/src/Umbraco.Core/Composing/LazyCollectionBuilderBase.cs
+++ b/src/Umbraco.Core/Composing/LazyCollectionBuilderBase.cs
@@ -12,7 +12,7 @@ namespace Umbraco.Core.Composing
/// The type of the items.
public abstract class LazyCollectionBuilderBase : CollectionBuilderBase
where TBuilder : LazyCollectionBuilderBase
- where TCollection : IBuilderCollection
+ where TCollection : class, IBuilderCollection
{
private readonly List>> _producers = new List>>();
private readonly List _excluded = new List();
diff --git a/src/Umbraco.Core/Composing/LightInject/LightInjectContainer.cs b/src/Umbraco.Core/Composing/LightInject/LightInjectContainer.cs
index b39622f66a..4ccc0ba838 100644
--- a/src/Umbraco.Core/Composing/LightInject/LightInjectContainer.cs
+++ b/src/Umbraco.Core/Composing/LightInject/LightInjectContainer.cs
@@ -102,18 +102,25 @@ namespace Umbraco.Core.Composing.LightInject
///
public IFactory CreateFactory() => this;
+ private static string GetTargetedServiceName() => "TARGET:" + typeof(TTarget).FullName;
+
#region Factory
///
public object GetInstance(Type type)
=> Container.GetInstance(type);
+ ///
+ public TService GetInstanceFor()
+ => Container.GetInstance(GetTargetedServiceName());
+
///
public object TryGetInstance(Type type)
=> Container.TryGetInstance(type);
///
public IEnumerable GetAllInstances()
+ where T : class
=> Container.GetAllInstances();
///
@@ -139,19 +146,7 @@ namespace Umbraco.Core.Composing.LightInject
///
public void Register(Type serviceType, Lifetime lifetime = Lifetime.Transient)
{
- switch (lifetime)
- {
- case Lifetime.Transient:
- Container.Register(serviceType);
- break;
- case Lifetime.Request:
- case Lifetime.Scope:
- case Lifetime.Singleton:
- Container.Register(serviceType, GetLifetime(lifetime));
- break;
- default:
- throw new NotSupportedException($"Lifetime {lifetime} is not supported.");
- }
+ Container.Register(serviceType, GetLifetime(lifetime));
}
///
@@ -173,21 +168,24 @@ namespace Umbraco.Core.Composing.LightInject
}
///
- public void Register(Func factory, Lifetime lifetime = Lifetime.Transient)
+ public void RegisterFor(Type implementingType, Lifetime lifetime = Lifetime.Transient)
+ where TService : class
{
- switch (lifetime)
- {
- case Lifetime.Transient:
- Container.Register(f => factory(this));
- break;
- case Lifetime.Request:
- case Lifetime.Scope:
- case Lifetime.Singleton:
- Container.Register(f => factory(this), GetLifetime(lifetime));
- break;
- default:
- throw new NotSupportedException($"Lifetime {lifetime} is not supported.");
- }
+ Container.Register(typeof(TService), implementingType, GetTargetedServiceName(), GetLifetime(lifetime));
+ }
+
+ ///
+ public void Register(Func factory, Lifetime lifetime = Lifetime.Transient)
+ where TService : class
+ {
+ Container.Register(f => factory(this), GetLifetime(lifetime));
+ }
+
+ ///
+ public void RegisterFor(Func factory, Lifetime lifetime = Lifetime.Transient)
+ where TService : class
+ {
+ Container.Register(f => factory(this), GetTargetedServiceName(), GetLifetime(lifetime));
}
private ILifetime GetLifetime(Lifetime lifetime)
@@ -211,6 +209,11 @@ namespace Umbraco.Core.Composing.LightInject
public void RegisterInstance(Type serviceType, object instance)
=> Container.RegisterInstance(serviceType, instance);
+ ///
+ public void RegisterInstanceFor(TService instance)
+ where TService : class
+ => Container.RegisterInstance(typeof(TService), instance, GetTargetedServiceName());
+
///
public void RegisterAuto(Type serviceBaseType)
{
diff --git a/src/Umbraco.Core/Composing/OrderedCollectionBuilderBase.cs b/src/Umbraco.Core/Composing/OrderedCollectionBuilderBase.cs
index bde1bf96c5..241b84d8d2 100644
--- a/src/Umbraco.Core/Composing/OrderedCollectionBuilderBase.cs
+++ b/src/Umbraco.Core/Composing/OrderedCollectionBuilderBase.cs
@@ -11,7 +11,7 @@ namespace Umbraco.Core.Composing
/// The type of the items.
public abstract class OrderedCollectionBuilderBase : CollectionBuilderBase
where TBuilder : OrderedCollectionBuilderBase
- where TCollection : IBuilderCollection
+ where TCollection : class, IBuilderCollection
{
protected abstract TBuilder This { get; }
diff --git a/src/Umbraco.Core/Composing/RegisterExtensions.cs b/src/Umbraco.Core/Composing/RegisterExtensions.cs
index 4db1a2e9e4..9afa41e4b3 100644
--- a/src/Umbraco.Core/Composing/RegisterExtensions.cs
+++ b/src/Umbraco.Core/Composing/RegisterExtensions.cs
@@ -11,22 +11,32 @@
public static void Register(this IRegister register, Lifetime lifetime = Lifetime.Transient)
=> register.Register(typeof(TService), typeof(TImplementing), lifetime);
+ ///
+ /// Registers a service with an implementation type, for a target.
+ ///
+ public static void RegisterFor(this IRegister register, Lifetime lifetime = Lifetime.Transient)
+ where TService : class
+ => register.RegisterFor(typeof(TImplementing), lifetime);
+
///
/// Registers a service as its own implementation.
///
public static void Register(this IRegister register, Lifetime lifetime = Lifetime.Transient)
+ where TService : class
=> register.Register(typeof(TService), lifetime);
///
/// Registers a service with an implementing instance.
///
public static void RegisterInstance(this IRegister register, TService instance)
+ where TService : class
=> register.RegisterInstance(typeof(TService), instance);
///
/// Registers a base type for auto-registration.
///
public static void RegisterAuto(this IRegister register)
+ where TServiceBase : class
=> register.RegisterAuto(typeof(TServiceBase));
}
}
diff --git a/src/Umbraco.Core/Composing/TargetedServiceProvider.cs b/src/Umbraco.Core/Composing/TargetedServiceProvider.cs
new file mode 100644
index 0000000000..3f88e1bc28
--- /dev/null
+++ b/src/Umbraco.Core/Composing/TargetedServiceProvider.cs
@@ -0,0 +1,18 @@
+namespace Umbraco.Core.Composing
+{
+ ///
+ /// Provides a base class for targeted service factories.
+ ///
+ ///
+ public abstract class TargetedServiceProvider
+ {
+ private readonly IFactory _factory;
+
+ protected TargetedServiceProvider(IFactory factory)
+ {
+ _factory = factory;
+ }
+
+ public TService For() => _factory.GetInstanceFor();
+ }
+}
diff --git a/src/Umbraco.Core/Composing/WeightedCollectionBuilderBase.cs b/src/Umbraco.Core/Composing/WeightedCollectionBuilderBase.cs
index da47c53bf8..f8ecc11d98 100644
--- a/src/Umbraco.Core/Composing/WeightedCollectionBuilderBase.cs
+++ b/src/Umbraco.Core/Composing/WeightedCollectionBuilderBase.cs
@@ -12,7 +12,7 @@ namespace Umbraco.Core.Composing
/// The type of the items.
public abstract class WeightedCollectionBuilderBase : CollectionBuilderBase
where TBuilder : WeightedCollectionBuilderBase
- where TCollection : IBuilderCollection
+ where TCollection : class, IBuilderCollection
{
protected abstract TBuilder This { get; }
diff --git a/src/Umbraco.Core/IO/SupportingFileSystems.cs b/src/Umbraco.Core/IO/SupportingFileSystems.cs
new file mode 100644
index 0000000000..c13ae203ee
--- /dev/null
+++ b/src/Umbraco.Core/IO/SupportingFileSystems.cs
@@ -0,0 +1,11 @@
+using Umbraco.Core.Composing;
+
+namespace Umbraco.Core.IO
+{
+ public class SupportingFileSystems : TargetedServiceProvider
+ {
+ public SupportingFileSystems(IFactory factory)
+ : base(factory)
+ { }
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj
index a01bbf1746..a592fd0f0e 100755
--- a/src/Umbraco.Core/Umbraco.Core.csproj
+++ b/src/Umbraco.Core/Umbraco.Core.csproj
@@ -196,6 +196,7 @@
+
@@ -343,6 +344,7 @@
+
diff --git a/src/Umbraco.Web/Composing/ModuleInjector.cs b/src/Umbraco.Web/Composing/ModuleInjector.cs
index 01930d55fd..57ef766dea 100644
--- a/src/Umbraco.Web/Composing/ModuleInjector.cs
+++ b/src/Umbraco.Web/Composing/ModuleInjector.cs
@@ -1,5 +1,4 @@
-using System;
-using System.Web;
+using System.Web;
using Umbraco.Core;
using Umbraco.Core.Composing;
using Umbraco.Core.Exceptions;
@@ -11,7 +10,7 @@ namespace Umbraco.Web.Composing
///
/// The type of the injected module.
public abstract class ModuleInjector : IHttpModule
- where TModule : IHttpModule
+ where TModule : class, IHttpModule
{
protected TModule Module { get; private set; }
From d2baf0311976cc45d6161853c08336656091c344 Mon Sep 17 00:00:00 2001
From: Kenn Jacobsen
Date: Wed, 9 Jan 2019 11:20:34 +0100
Subject: [PATCH 28/84] Fix content picker dirty checking (#4003)
(cherry picked from commit d41dbce60125cf9a8aa30e4d5a0bf39bddb59e1a)
---
.../contentpicker/contentpicker.controller.js | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/contentpicker/contentpicker.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/contentpicker/contentpicker.controller.js
index c1fe21b1b5..ee8c193b4b 100644
--- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/contentpicker/contentpicker.controller.js
+++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/contentpicker/contentpicker.controller.js
@@ -35,7 +35,6 @@ function contentPickerController($scope, entityResource, editorState, iconHelper
return $scope.model.config.idType === "udi" ? i.udi : i.id;
});
$scope.model.value = trim(currIds.join(), ",");
- angularHelper.getCurrentForm($scope).$setDirty();
//Validate!
if ($scope.model.config && $scope.model.config.minNumber && parseInt($scope.model.config.minNumber) > $scope.renderModel.length) {
@@ -84,7 +83,10 @@ function contentPickerController($scope, entityResource, editorState, iconHelper
opacity: 0.7,
tolerance: "pointer",
scroll: true,
- zIndex: 6000
+ zIndex: 6000,
+ update: function (e, ui) {
+ angularHelper.getCurrentForm($scope).$setDirty();
+ }
};
if ($scope.model.config) {
From d69f0fe9ddf8c8d37f4fe4d27b5974cddf4f88d3 Mon Sep 17 00:00:00 2001
From: Sebastiaan Janssen
Date: Thu, 10 Jan 2019 15:35:48 +0100
Subject: [PATCH 29/84] #3993 Move color picker fix to correct method and
update backwards compatibility test
---
.../colorpicker/colorpicker.controller.js | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/colorpicker/colorpicker.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/colorpicker/colorpicker.controller.js
index 3a6ddc5cfd..9b3be511a4 100644
--- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/colorpicker/colorpicker.controller.js
+++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/colorpicker/colorpicker.controller.js
@@ -123,11 +123,6 @@ function ColorPickerController($scope) {
if (!$scope.model.value)
return false;
- // Backwards compatibility, the color used to be stored as a hex value only
- if ($scope.model.value.length === 6) {
- $scope.model.value = { value: $scope.model.value, label: $scope.model.value };
- }
-
// Complex color (value and label)?
if (!$scope.model.value.hasOwnProperty("value"))
return $scope.model.value === color.value;
@@ -144,6 +139,11 @@ function ColorPickerController($scope) {
if (!$scope.model.value)
return;
+ // Backwards compatibility, the color used to be stored as a hex value only
+ if (typeof $scope.model.value === "string") {
+ $scope.model.value = { value: $scope.model.value, label: $scope.model.value };
+ }
+
// Complex color (value and label)?
if (!$scope.model.value.hasOwnProperty("value"))
return;
From cc13b99787de8f94b40c0cd6d289b2b9bdc3251e Mon Sep 17 00:00:00 2001
From: Sebastian Hoffback
Date: Thu, 10 Jan 2019 11:21:17 +0100
Subject: [PATCH 30/84] Removed already deleted file canvasdesigner.panel.js
from canvasdesigner.loader.js
---
src/Umbraco.Web.UI.Client/src/canvasdesigner.loader.js | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/src/Umbraco.Web.UI.Client/src/canvasdesigner.loader.js b/src/Umbraco.Web.UI.Client/src/canvasdesigner.loader.js
index c5d2f70075..8ed149fee1 100644
--- a/src/Umbraco.Web.UI.Client/src/canvasdesigner.loader.js
+++ b/src/Umbraco.Web.UI.Client/src/canvasdesigner.loader.js
@@ -11,8 +11,7 @@ LazyLoad.js([
'../js/umbraco.security.js',
'../ServerVariables',
'../lib/spectrum/spectrum.js',
- '../js/umbraco.canvasdesigner.js',
- '../js/canvasdesigner.panel.js'
+ '../js/umbraco.canvasdesigner.js'
], function () {
jQuery(document).ready(function () {
angular.bootstrap(document, ['Umbraco.canvasdesigner']);
From 4170faf76eddee2bae14470ace42886e12601c3d Mon Sep 17 00:00:00 2001
From: Quan Tran
Date: Wed, 9 Jan 2019 09:02:15 +0100
Subject: [PATCH 31/84] add null checking
---
.../umbraco.presentation/umbraco/translation/details.aspx.cs | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/translation/details.aspx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/translation/details.aspx.cs
index 46a00927db..b8968d4329 100644
--- a/src/Umbraco.Web/umbraco.presentation/umbraco/translation/details.aspx.cs
+++ b/src/Umbraco.Web/umbraco.presentation/umbraco/translation/details.aspx.cs
@@ -88,7 +88,10 @@ namespace umbraco.presentation.umbraco.translation {
foreach (PropertyType pt in page.ContentType.PropertyTypes) {
pageRow = pageTable.NewRow();
pageRow[ui.Text("name")] = pt.Name;
- pageRow[ui.Text("value")] = page.getProperty(pt.Alias).Value;
+ if (page.getProperty(pt.Alias) != null && page.getProperty(pt.Alias).Value != null)
+ {
+ pageRow[ui.Text("value")] = page.getProperty(pt.Alias).Value;
+ }
pageTable.Rows.Add(pageRow);
}
From 59349dd355313063718c136b6b641de487af3e5b Mon Sep 17 00:00:00 2001
From: Quan Tran
Date: Thu, 10 Jan 2019 10:21:07 +0100
Subject: [PATCH 32/84] Fix - refine code
---
.../umbraco/translation/details.aspx.cs | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/translation/details.aspx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/translation/details.aspx.cs
index b8968d4329..d4ae4a8587 100644
--- a/src/Umbraco.Web/umbraco.presentation/umbraco/translation/details.aspx.cs
+++ b/src/Umbraco.Web/umbraco.presentation/umbraco/translation/details.aspx.cs
@@ -84,17 +84,19 @@ namespace umbraco.presentation.umbraco.translation {
pageRow[ui.Text("name")] = ui.Text("nodeName");
pageRow[ui.Text("value")] = page.Text;
pageTable.Rows.Add(pageRow);
-
- foreach (PropertyType pt in page.ContentType.PropertyTypes) {
+
+ foreach (PropertyType pt in page.ContentType.PropertyTypes)
+ {
pageRow = pageTable.NewRow();
pageRow[ui.Text("name")] = pt.Name;
- if (page.getProperty(pt.Alias) != null && page.getProperty(pt.Alias).Value != null)
+ var property = page.getProperty(pt.Alias);
+ if (property != null && property.Value != null)
{
- pageRow[ui.Text("value")] = page.getProperty(pt.Alias).Value;
+ pageRow[ui.Text("value")] = property.Value;
}
pageTable.Rows.Add(pageRow);
}
-
+
dg_fields.DataSource = pageTable;
dg_fields.DataBind();
}
From a5630a34480cd938f95ae992ec94bcb0b02b2547 Mon Sep 17 00:00:00 2001
From: Aaron Powell
Date: Fri, 11 Jan 2019 14:35:24 +1100
Subject: [PATCH 33/84] Fixing 4033 by using the right Logger instance
---
src/Umbraco.Core/Runtime/CoreRuntime.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/Umbraco.Core/Runtime/CoreRuntime.cs b/src/Umbraco.Core/Runtime/CoreRuntime.cs
index 5d2359d04c..cb6a1cb031 100644
--- a/src/Umbraco.Core/Runtime/CoreRuntime.cs
+++ b/src/Umbraco.Core/Runtime/CoreRuntime.cs
@@ -319,7 +319,7 @@ namespace Umbraco.Core.Runtime
/// Gets a profiler.
///
protected virtual IProfiler GetProfiler()
- => new LogProfiler(ProfilingLogger);
+ => new LogProfiler(Logger);
///
/// Gets the application caches.
From ba282ab81ab7ec85b3a6bf54c1c7a2d7adbae100 Mon Sep 17 00:00:00 2001
From: Stephan
Date: Fri, 11 Jan 2019 08:26:53 +0100
Subject: [PATCH 34/84] Comments
---
src/Umbraco.Web/IPublishedContentQuery.cs | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/src/Umbraco.Web/IPublishedContentQuery.cs b/src/Umbraco.Web/IPublishedContentQuery.cs
index c3a065b9dc..76e7be5e97 100644
--- a/src/Umbraco.Web/IPublishedContentQuery.cs
+++ b/src/Umbraco.Web/IPublishedContentQuery.cs
@@ -40,6 +40,7 @@ namespace Umbraco.Web
/// Optional index name.
///
/// When the is not specified, all cultures are searched.
+ /// While enumerating results, the ambient culture is changed to be the searched culture.
///
IEnumerable Search(string term, string culture = null, string indexName = null);
@@ -54,17 +55,24 @@ namespace Umbraco.Web
/// Optional index name.
///
/// When the is not specified, all cultures are searched.
+ /// While enumerating results, the ambient culture is changed to be the searched culture.
///
IEnumerable Search(string term, int skip, int take, out long totalRecords, string culture = null, string indexName = null);
///
/// Executes the query and converts the results to PublishedSearchResult.
///
+ ///
+ /// While enumerating results, the ambient culture is changed to be the searched culture.
+ ///
IEnumerable Search(IQueryExecutor query);
///
/// Executes the query and converts the results to PublishedSearchResult.
///
+ ///
+ /// While enumerating results, the ambient culture is changed to be the searched culture.
+ ///
IEnumerable Search(IQueryExecutor query, int skip, int take, out long totalRecords);
}
}
From 250c24de40f70a9f1b995934e45f394f1b4597ff Mon Sep 17 00:00:00 2001
From: Warren Buckley
Date: Fri, 11 Jan 2019 12:54:50 +0000
Subject: [PATCH 35/84] Adds in chart.js & the angular wrapper library
---
src/Umbraco.Web.UI.Client/package-lock.json | 56 ++++++++++++++++++-
src/Umbraco.Web.UI.Client/package.json | 2 +
src/Umbraco.Web/UI/JavaScript/JsInitialize.js | 5 +-
3 files changed, 60 insertions(+), 3 deletions(-)
diff --git a/src/Umbraco.Web.UI.Client/package-lock.json b/src/Umbraco.Web.UI.Client/package-lock.json
index 7c3fe8b4f9..b12843fbf7 100644
--- a/src/Umbraco.Web.UI.Client/package-lock.json
+++ b/src/Umbraco.Web.UI.Client/package-lock.json
@@ -852,6 +852,26 @@
"resolved": "https://registry.npmjs.org/angular-animate/-/angular-animate-1.7.5.tgz",
"integrity": "sha512-kU/fHIGf2a4a3bH7E1tzALTHk+QfoUSCK9fEcMFisd6ZWvNDwPzXWAilItqOC3EDiAXPmGHaNc9/aXiD9xrAxQ=="
},
+ "angular-chart.js": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/angular-chart.js/-/angular-chart.js-1.1.1.tgz",
+ "integrity": "sha1-SfDhjQgXYrbUyXkeSHr/L7sw9a4=",
+ "requires": {
+ "angular": "1.x",
+ "chart.js": "2.3.x"
+ },
+ "dependencies": {
+ "chart.js": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-2.3.0.tgz",
+ "integrity": "sha1-QEYOSOLEF8BfwzJc2E97AA3H19Y=",
+ "requires": {
+ "chartjs-color": "^2.0.0",
+ "moment": "^2.10.6"
+ }
+ }
+ }
+ },
"angular-cookies": {
"version": "1.7.5",
"resolved": "https://registry.npmjs.org/angular-cookies/-/angular-cookies-1.7.5.tgz",
@@ -1970,6 +1990,39 @@
"integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==",
"dev": true
},
+ "chart.js": {
+ "version": "2.7.3",
+ "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-2.7.3.tgz",
+ "integrity": "sha512-3+7k/DbR92m6BsMUYP6M0dMsMVZpMnwkUyNSAbqolHKsbIzH2Q4LWVEHHYq7v0fmEV8whXE0DrjANulw9j2K5g==",
+ "requires": {
+ "chartjs-color": "^2.1.0",
+ "moment": "^2.10.2"
+ }
+ },
+ "chartjs-color": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/chartjs-color/-/chartjs-color-2.2.0.tgz",
+ "integrity": "sha1-hKL7dVeH7YXDndbdjHsdiEKbrq4=",
+ "requires": {
+ "chartjs-color-string": "^0.5.0",
+ "color-convert": "^0.5.3"
+ },
+ "dependencies": {
+ "color-convert": {
+ "version": "0.5.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-0.5.3.tgz",
+ "integrity": "sha1-vbbGnOZg+t/+CwAHzER+G59ygr0="
+ }
+ }
+ },
+ "chartjs-color-string": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/chartjs-color-string/-/chartjs-color-string-0.5.0.tgz",
+ "integrity": "sha512-amWNvCOXlOUYxZVDSa0YOab5K/lmEhbFNKI55PWc4mlv28BDzA7zaoQTGxSBgJMHIW+hGX8YUrvw/FH4LyhwSQ==",
+ "requires": {
+ "color-name": "^1.0.0"
+ }
+ },
"chokidar": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.4.tgz",
@@ -2216,8 +2269,7 @@
"color-name": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
- "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
- "dev": true
+ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
},
"color-string": {
"version": "1.5.3",
diff --git a/src/Umbraco.Web.UI.Client/package.json b/src/Umbraco.Web.UI.Client/package.json
index 2002cca0a1..e35fdc3442 100644
--- a/src/Umbraco.Web.UI.Client/package.json
+++ b/src/Umbraco.Web.UI.Client/package.json
@@ -8,6 +8,7 @@
"ace-builds": "1.4.2",
"angular": "1.7.5",
"angular-animate": "1.7.5",
+ "angular-chart.js": "^1.1.1",
"angular-cookies": "1.7.5",
"angular-dynamic-locale": "0.1.37",
"angular-i18n": "1.7.5",
@@ -20,6 +21,7 @@
"angular-ui-sortable": "0.19.0",
"animejs": "2.2.0",
"bootstrap-social": "5.1.1",
+ "chart.js": "^2.7.3",
"clipboard": "2.0.4",
"diff": "3.5.0",
"flatpickr": "4.5.2",
diff --git a/src/Umbraco.Web/UI/JavaScript/JsInitialize.js b/src/Umbraco.Web/UI/JavaScript/JsInitialize.js
index 75ca46437a..62d294ee6f 100644
--- a/src/Umbraco.Web/UI/JavaScript/JsInitialize.js
+++ b/src/Umbraco.Web/UI/JavaScript/JsInitialize.js
@@ -23,8 +23,11 @@
'lib/ng-file-upload/ng-file-upload.min.js',
'lib/angular-local-storage/angular-local-storage.min.js',
+ 'lib/chart.js/chart.min.js',
+ 'lib/angular-chart.js/angular-chart.min.js',
+
'lib/umbraco/Extensions.js',
-
+
'lib/umbraco/NamespaceManager.js',
'lib/umbraco/LegacySpeechBubble.js',
From 8f1cd8110d9488bfc9608055b14ce4cccdbd0b92 Mon Sep 17 00:00:00 2001
From: Warren Buckley
Date: Fri, 11 Jan 2019 13:27:39 +0000
Subject: [PATCH 36/84] Adds in the missing chart.js & wrapper lib (part of it
was put in the solution it seems but not fully merged in correctly perhaps?!)
---
src/Umbraco.Web.UI.Client/gulpfile.js | 11 +++++++++++
src/Umbraco.Web.UI.Client/src/app.js | 5 +++--
2 files changed, 14 insertions(+), 2 deletions(-)
diff --git a/src/Umbraco.Web.UI.Client/gulpfile.js b/src/Umbraco.Web.UI.Client/gulpfile.js
index 0af327d148..22ac11b991 100644
--- a/src/Umbraco.Web.UI.Client/gulpfile.js
+++ b/src/Umbraco.Web.UI.Client/gulpfile.js
@@ -248,6 +248,17 @@ gulp.task('dependencies', function () {
"src": ["./node_modules/bootstrap-social/bootstrap-social.css"],
"base": "./node_modules/bootstrap-social"
},
+
+ {
+ "name": "angular-chart.js",
+ "src": ["./node_modules/angular-chart.js/dist/angular-chart.min.js"],
+ "base": "./node_modules/angular-chart.js/dist"
+ },
+ {
+ "name": "chart.js",
+ "src": ["./node_modules/chart.js/dist/chart.min.js"],
+ "base": "./node_modules/chart.js/dist"
+ },
{
"name": "clipboard",
"src": ["./node_modules/clipboard/dist/clipboard.min.js"],
diff --git a/src/Umbraco.Web.UI.Client/src/app.js b/src/Umbraco.Web.UI.Client/src/app.js
index c7b813c1bf..8e0eaa4943 100644
--- a/src/Umbraco.Web.UI.Client/src/app.js
+++ b/src/Umbraco.Web.UI.Client/src/app.js
@@ -14,7 +14,8 @@ var app = angular.module('umbraco', [
'ngMessages',
'tmh.dynamicLocale',
'ngFileUpload',
- 'LocalStorageModule'
+ 'LocalStorageModule',
+ 'chart.js'
]);
app.config(['$compileProvider', function ($compileProvider) {
@@ -76,7 +77,7 @@ angular.module("umbraco.viewcache", [])
var _op = (url.indexOf("?") > 0) ? "&" : "?";
url += _op + "umb__rnd=" + rnd;
}
-
+
return get(url, config);
};
return $delegate;
From fded793f8e96e40fe77fe87684932c04e8824835 Mon Sep 17 00:00:00 2001
From: Warren Buckley
Date: Fri, 11 Jan 2019 13:32:45 +0000
Subject: [PATCH 37/84] Removes the accidently Web.UI.csproj V7 port numbers
for IISExpress when merging up from V7 to V8
---
src/Umbraco.Web.UI/Umbraco.Web.UI.csproj | 6 ------
1 file changed, 6 deletions(-)
diff --git a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj
index 05bc1dca73..7a59b15eb3 100644
--- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj
+++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj
@@ -433,12 +433,6 @@
8000
/
http://localhost:8000
- 7140
- /
- http://localhost:7140
- 7131
- /
- http://localhost:7131
False
False
From ca75b2f4d369f4705d5df7efca00d2c006c04914 Mon Sep 17 00:00:00 2001
From: Stephan
Date: Fri, 11 Jan 2019 14:53:55 +0100
Subject: [PATCH 38/84] Fix recent Examine changes
---
.../XmlPublishedCache/DictionaryPublishedContent.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/Umbraco.Web/PublishedCache/XmlPublishedCache/DictionaryPublishedContent.cs b/src/Umbraco.Web/PublishedCache/XmlPublishedCache/DictionaryPublishedContent.cs
index a845be286f..6f6a39144a 100644
--- a/src/Umbraco.Web/PublishedCache/XmlPublishedCache/DictionaryPublishedContent.cs
+++ b/src/Umbraco.Web/PublishedCache/XmlPublishedCache/DictionaryPublishedContent.cs
@@ -52,7 +52,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
LoadedFromExamine = fromExamine;
ValidateAndSetProperty(valueDictionary, val => _id = Int32.Parse(val), "id", "nodeId", "__NodeId"); //should validate the int!
- ValidateAndSetProperty(valueDictionary, val => _key = Guid.Parse(val), "key");
+ ValidateAndSetProperty(valueDictionary, val => _key = Guid.Parse(val), "key", "__key", "__Key");
//ValidateAndSetProperty(valueDictionary, val => _templateId = int.Parse(val), "template", "templateId");
ValidateAndSetProperty(valueDictionary, val => _sortOrder = Int32.Parse(val), "sortOrder");
ValidateAndSetProperty(valueDictionary, val => _name = val, "nodeName");
From e88c789b88f85e36e672ce7881fec6d0995b7145 Mon Sep 17 00:00:00 2001
From: Kenn Jacobsen
Date: Fri, 11 Jan 2019 15:44:54 +0100
Subject: [PATCH 39/84] Add some defensive coding to avoid JS errors
---
.../components/content/umbcontentnodeinfo.directive.js | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/content/umbcontentnodeinfo.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/content/umbcontentnodeinfo.directive.js
index 71fbabe943..b65bf447e7 100644
--- a/src/Umbraco.Web.UI.Client/src/common/directives/components/content/umbcontentnodeinfo.directive.js
+++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/content/umbcontentnodeinfo.directive.js
@@ -97,9 +97,9 @@
}
//load in the audit trail if we are currently looking at the INFO tab
- if (umbVariantContentCtrl) {
+ if (umbVariantContentCtrl && umbVariantContentCtrl.editor) {
var activeApp = _.find(umbVariantContentCtrl.editor.content.apps, a => a.active);
- if (activeApp.alias === "umbInfo") {
+ if (activeApp && activeApp.alias === "umbInfo") {
isInfoTab = true;
loadAuditTrail();
loadRedirectUrls();
From 291d58900ff2ad3f4e3772857748301aa70a1f3b Mon Sep 17 00:00:00 2001
From: Kenn Jacobsen
Date: Sun, 13 Jan 2019 12:42:42 +0100
Subject: [PATCH 40/84] V8: Remember editor language between sessions (#4035)
---
.../src/controllers/navigation.controller.js | 21 ++++++++++++++-----
1 file changed, 16 insertions(+), 5 deletions(-)
diff --git a/src/Umbraco.Web.UI.Client/src/controllers/navigation.controller.js b/src/Umbraco.Web.UI.Client/src/controllers/navigation.controller.js
index 06b82d6eab..335fe99e7c 100644
--- a/src/Umbraco.Web.UI.Client/src/controllers/navigation.controller.js
+++ b/src/Umbraco.Web.UI.Client/src/controllers/navigation.controller.js
@@ -9,7 +9,7 @@
*
* @param {navigationService} navigationService A reference to the navigationService
*/
-function NavigationController($scope, $rootScope, $location, $log, $q, $routeParams, $timeout, treeService, appState, navigationService, keyboardService, historyService, eventsService, angularHelper, languageResource, contentResource) {
+function NavigationController($scope, $rootScope, $location, $log, $q, $routeParams, $timeout, $cookies, treeService, appState, navigationService, keyboardService, historyService, eventsService, angularHelper, languageResource, contentResource) {
//this is used to trigger the tree to start loading once everything is ready
var treeInitPromise = $q.defer();
@@ -344,9 +344,6 @@ function NavigationController($scope, $rootScope, $location, $log, $q, $routePar
$scope.languages = languages;
if ($scope.languages.length > 1) {
- var defaultLang = _.find($scope.languages, function (l) {
- return l.isDefault;
- });
//if there's already one set, check if it exists
var currCulture = null;
var mainCulture = $location.search().mculture;
@@ -356,7 +353,18 @@ function NavigationController($scope, $rootScope, $location, $log, $q, $routePar
});
}
if (!currCulture) {
- $location.search("mculture", defaultLang ? defaultLang.culture : null);
+ // no culture in the request, let's look for one in the cookie that's set when changing language
+ var defaultCulture = $cookies.get("UMB_MCULTURE");
+ if (!defaultCulture) {
+ // no luck either, look for the default language
+ var defaultLang = _.find($scope.languages, function (l) {
+ return l.isDefault;
+ });
+ if (defaultLang) {
+ defaultCulture = defaultLang.culture;
+ }
+ }
+ $location.search("mculture", defaultCulture ? defaultCulture : null);
}
}
@@ -391,6 +399,9 @@ function NavigationController($scope, $rootScope, $location, $log, $q, $routePar
$scope.selectLanguage = function (language) {
$location.search("mculture", language.culture);
+ // add the selected culture to a cookie so the user will log back into the same culture later on (cookie max age is one year = 31536000 seconds)
+ // NOTE: $cookies doesn't support max-age, so we need to go the good ol' JS way about setting the cookie
+ document.cookie = "UMB_MCULTURE=" +language.culture + ";path=/;max-age=31536000;";
// close the language selector
$scope.page.languageSelectorIsOpen = false;
From c619b79276be80db73442cee0b4dfd4b975bfed9 Mon Sep 17 00:00:00 2001
From: Bjarne Fyrstenborg
Date: Sun, 13 Jan 2019 13:06:16 +0100
Subject: [PATCH 41/84] Fix placeholder text when empty alias input after
generating alias (#4032)
---
.../components/umbGenerateAlias.directive.js | 34 +++++++++----------
1 file changed, 17 insertions(+), 17 deletions(-)
diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/umbGenerateAlias.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/umbGenerateAlias.directive.js
index 47d1431e13..56a18a217e 100644
--- a/src/Umbraco.Web.UI.Client/src/common/directives/components/umbGenerateAlias.directive.js
+++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/umbGenerateAlias.directive.js
@@ -86,20 +86,21 @@ angular.module("umbraco.directives")
function generateAlias(value) {
if (generateAliasTimeout) {
- $timeout.cancel(generateAliasTimeout);
+ $timeout.cancel(generateAliasTimeout);
}
- if( value !== undefined && value !== "" && value !== null) {
+ if (value !== undefined && value !== "" && value !== null) {
- scope.alias = "";
+ scope.alias = "";
scope.placeholderText = scope.labels.busy;
generateAliasTimeout = $timeout(function () {
updateAlias = true;
entityResource.getSafeAlias(value, true).then(function (safeAlias) {
if (updateAlias) {
- scope.alias = safeAlias.alias;
- }
+ scope.alias = safeAlias.alias;
+ }
+ scope.placeholderText = scope.labels.idle;
});
}, 500);
@@ -108,7 +109,6 @@ angular.module("umbraco.directives")
scope.alias = "";
scope.placeholderText = scope.labels.idle;
}
-
}
// if alias gets unlocked - stop watching alias
@@ -119,17 +119,17 @@ angular.module("umbraco.directives")
}));
// validate custom entered alias
- eventBindings.push(scope.$watch('alias', function(newValue, oldValue){
-
- if(scope.alias === "" && bindWatcher === true || scope.alias === null && bindWatcher === true) {
- // add watcher
- eventBindings.push(scope.$watch('aliasFrom', function(newValue, oldValue) {
- if(bindWatcher) {
- generateAlias(newValue);
- }
- }));
- }
-
+ eventBindings.push(scope.$watch('alias', function (newValue, oldValue) {
+ if (scope.alias === "" || scope.alias === null || scope.alias === undefined) {
+ if (bindWatcher === true) {
+ // add watcher
+ eventBindings.push(scope.$watch('aliasFrom', function (newValue, oldValue) {
+ if (bindWatcher) {
+ generateAlias(newValue);
+ }
+ }));
+ }
+ }
}));
// clean up
From 2ebd7a077cc5e71bd476f3f71d18d6ab16723e0c Mon Sep 17 00:00:00 2001
From: Bjarne Fyrstenborg
Date: Sun, 13 Jan 2019 13:06:16 +0100
Subject: [PATCH 42/84] Fix placeholder text when empty alias input after
generating alias (#4032)
(cherry picked from commit c619b79276be80db73442cee0b4dfd4b975bfed9)
---
.../components/umbGenerateAlias.directive.js | 34 +++++++++----------
1 file changed, 17 insertions(+), 17 deletions(-)
diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/umbGenerateAlias.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/umbGenerateAlias.directive.js
index 9b4bd17a12..b6c53d3876 100644
--- a/src/Umbraco.Web.UI.Client/src/common/directives/components/umbGenerateAlias.directive.js
+++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/umbGenerateAlias.directive.js
@@ -86,20 +86,21 @@ angular.module("umbraco.directives")
function generateAlias(value) {
if (generateAliasTimeout) {
- $timeout.cancel(generateAliasTimeout);
+ $timeout.cancel(generateAliasTimeout);
}
- if( value !== undefined && value !== "" && value !== null) {
+ if (value !== undefined && value !== "" && value !== null) {
- scope.alias = "";
+ scope.alias = "";
scope.placeholderText = scope.labels.busy;
generateAliasTimeout = $timeout(function () {
updateAlias = true;
entityResource.getSafeAlias(encodeURIComponent(value), true).then(function (safeAlias) {
if (updateAlias) {
- scope.alias = safeAlias.alias;
- }
+ scope.alias = safeAlias.alias;
+ }
+ scope.placeholderText = scope.labels.idle;
});
}, 500);
@@ -108,7 +109,6 @@ angular.module("umbraco.directives")
scope.alias = "";
scope.placeholderText = scope.labels.idle;
}
-
}
// if alias gets unlocked - stop watching alias
@@ -119,17 +119,17 @@ angular.module("umbraco.directives")
}));
// validate custom entered alias
- eventBindings.push(scope.$watch('alias', function(newValue, oldValue){
-
- if(scope.alias === "" && bindWatcher === true || scope.alias === null && bindWatcher === true) {
- // add watcher
- eventBindings.push(scope.$watch('aliasFrom', function(newValue, oldValue) {
- if(bindWatcher) {
- generateAlias(newValue);
- }
- }));
- }
-
+ eventBindings.push(scope.$watch('alias', function (newValue, oldValue) {
+ if (scope.alias === "" || scope.alias === null || scope.alias === undefined) {
+ if (bindWatcher === true) {
+ // add watcher
+ eventBindings.push(scope.$watch('aliasFrom', function (newValue, oldValue) {
+ if (bindWatcher) {
+ generateAlias(newValue);
+ }
+ }));
+ }
+ }
}));
// clean up
From cd6cdcfda468bba4c6d07bf9d9b1886ec072023b Mon Sep 17 00:00:00 2001
From: Kenn Jacobsen
Date: Sun, 13 Jan 2019 13:54:30 +0100
Subject: [PATCH 43/84] Visualize image transparency in upload and image
cropper thumbnails (#4050)
---
.../src/less/property-editors.less | 28 +++++++++++++++----
1 file changed, 22 insertions(+), 6 deletions(-)
diff --git a/src/Umbraco.Web.UI.Client/src/less/property-editors.less b/src/Umbraco.Web.UI.Client/src/less/property-editors.less
index e9d598a8cf..73de7aeee7 100644
--- a/src/Umbraco.Web.UI.Client/src/less/property-editors.less
+++ b/src/Umbraco.Web.UI.Client/src/less/property-editors.less
@@ -1,3 +1,5 @@
+@checkered-background: url(../img/checkered-background.png);
+
//
// Container styles
// --------------------------------------------------
@@ -386,7 +388,7 @@ div.umb-codeeditor .umb-btn-toolbar {
max-height:100%;
margin:auto;
display:block;
- background-image: url(../img/checkered-background.png);
+ background-image: @checkered-background;
}
.umb-sortable-thumbnails li .trashed {
@@ -599,12 +601,18 @@ div.umb-codeeditor .umb-btn-toolbar {
vertical-align: top;
}
- .gravity-container .viewport {
- max-width: 600px;
- }
+ .gravity-container {
+ border: 1px solid @gray-8;
+ line-height: 0;
- .gravity-container .viewport:hover {
- cursor: pointer;
+ .viewport {
+ max-width: 600px;
+ background: @checkered-background;
+
+ &:hover {
+ cursor: pointer;
+ }
+ }
}
.imagecropper {
@@ -617,6 +625,10 @@ div.umb-codeeditor .umb-btn-toolbar {
float: left;
max-width: 100%;
}
+
+ .viewport img {
+ background: @checkered-background;
+ }
}
.imagecropper .umb-cropper__container {
@@ -884,6 +896,10 @@ div.umb-codeeditor .umb-btn-toolbar {
list-style: none;
vertical-align: middle;
margin-bottom: 0;
+
+ img {
+ background: @checkered-background;
+ }
}
.umb-fileupload label {
From d1cfe847235198c49ae6640e56a0dc3d50fe35fd Mon Sep 17 00:00:00 2001
From: Kenn Jacobsen
Date: Sat, 12 Jan 2019 17:05:52 +0100
Subject: [PATCH 44/84] Set the form dirty when changing focal point and
editing crops
---
.../imaging/umbimagegravity.directive.js | 18 +++++++++---------
.../imagecropper/imagecropper.controller.js | 5 +++++
.../imagecropper/imagecropper.html | 3 ++-
3 files changed, 16 insertions(+), 10 deletions(-)
diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/imaging/umbimagegravity.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/imaging/umbimagegravity.directive.js
index bb364b79ee..7d1b1c5a18 100644
--- a/src/Umbraco.Web.UI.Client/src/common/directives/components/imaging/umbimagegravity.directive.js
+++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/imaging/umbimagegravity.directive.js
@@ -14,7 +14,8 @@ angular.module("umbraco.directives")
scope: {
src: '=',
center: "=",
- onImageLoaded: "&"
+ onImageLoaded: "&",
+ onGravityChanged: "&"
},
link: function(scope, element, attrs) {
@@ -52,7 +53,7 @@ angular.module("umbraco.directives")
calculateGravity(offsetX, offsetY);
- lazyEndEvent();
+ gravityChanged();
};
var setDimensions = function () {
@@ -77,12 +78,11 @@ angular.module("umbraco.directives")
scope.center.top = (scope.dimensions.top+10) / scope.dimensions.height;
};
- var lazyEndEvent = _.debounce(function(){
- scope.$apply(function(){
- scope.$emit("imageFocalPointStop");
- });
- }, 2000);
-
+ var gravityChanged = function () {
+ if (angular.isFunction(scope.onGravityChanged)) {
+ scope.onGravityChanged();
+ }
+ };
//Drag and drop positioning, using jquery ui draggable
//TODO ensure that the point doesnt go outside the box
@@ -100,7 +100,7 @@ angular.module("umbraco.directives")
calculateGravity(offsetX, offsetY);
});
- lazyEndEvent();
+ gravityChanged();
}
});
diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/imagecropper/imagecropper.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/imagecropper/imagecropper.controller.js
index 47442495f7..d9131e88a4 100644
--- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/imagecropper/imagecropper.controller.js
+++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/imagecropper/imagecropper.controller.js
@@ -52,6 +52,7 @@ angular.module('umbraco')
});
editedCrop.coordinates = $scope.currentCrop.coordinates;
$scope.close();
+ angularHelper.getCurrentForm($scope).$setDirty();
};
//reset the current crop
@@ -98,6 +99,10 @@ angular.module('umbraco')
$scope.hasDimensions = hasDimensions;
};
+ $scope.focalPointChanged = function () {
+ angularHelper.getCurrentForm($scope).$setDirty();
+ }
+
//on image selected, update the cropper
$scope.$on("filesSelected", function (ev, args) {
$scope.model.value = config;
diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/imagecropper/imagecropper.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/imagecropper/imagecropper.html
index a8f513f006..6e1cb52822 100644
--- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/imagecropper/imagecropper.html
+++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/imagecropper/imagecropper.html
@@ -40,7 +40,8 @@
+ on-image-loaded="imageLoaded(isCroppable, hasDimensions)"
+ on-gravity-changed="focalPointChanged()">
Remove file
From 0f7cb7c17737632bdd759300de003eb1f3095afe Mon Sep 17 00:00:00 2001
From: Kenn Jacobsen
Date: Fri, 11 Jan 2019 14:36:45 +0100
Subject: [PATCH 45/84] Use built-in localization for Nested Content + fix
element picker title
---
.../nestedcontent/nestedcontent.controller.js | 26 +++++--------------
.../nestedcontent/nestedcontent.html | 6 ++---
2 files changed, 9 insertions(+), 23 deletions(-)
diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/nestedcontent/nestedcontent.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/nestedcontent/nestedcontent.controller.js
index 6e67d2d251..79e00fa453 100644
--- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/nestedcontent/nestedcontent.controller.js
+++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/nestedcontent/nestedcontent.controller.js
@@ -81,25 +81,6 @@ angular.module("umbraco").controller("Umbraco.PropertyEditors.NestedContent.Prop
: undefined;
});
- $scope.editIconTitle = '';
- $scope.moveIconTitle = '';
- $scope.deleteIconTitle = '';
-
- // localize the edit icon title
- localizationService.localize('general_edit').then(function (value) {
- $scope.editIconTitle = value;
- });
-
- // localize the delete icon title
- localizationService.localize('general_delete').then(function (value) {
- $scope.deleteIconTitle = value;
- });
-
- // localize the move icon title
- localizationService.localize('actions_move').then(function (value) {
- $scope.moveIconTitle = value;
- });
-
$scope.nodes = [];
$scope.currentNode = undefined;
$scope.realCurrentNode = undefined;
@@ -116,6 +97,11 @@ angular.module("umbraco").controller("Umbraco.PropertyEditors.NestedContent.Prop
$scope.showIcons = $scope.model.config.showIcons || true;
$scope.wideMode = $scope.model.config.hideLabel == "1";
+ $scope.labels = {};
+ localizationService.localizeMany(["grid_insertControl"]).then(function(data) {
+ $scope.labels.docTypePickerTitle = data[0];
+ });
+
// helper to force the current form into the dirty state
$scope.setDirty = function () {
if ($scope.propertyForm) {
@@ -138,7 +124,7 @@ angular.module("umbraco").controller("Umbraco.PropertyEditors.NestedContent.Prop
}
$scope.overlayMenu = {
- title: localizationService.localize('grid_insertControl'),
+ title: $scope.labels.docTypePickerTitle,
show: false,
style: {},
filter: $scope.scaffolds.length > 15 ? true : false,
diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/nestedcontent/nestedcontent.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/nestedcontent/nestedcontent.html
index 1ff6666907..572021aebd 100644
--- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/nestedcontent/nestedcontent.html
+++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/nestedcontent/nestedcontent.html
@@ -12,13 +12,13 @@
From d350ab0789f7d97202bdff299ef32d9acce4b30e Mon Sep 17 00:00:00 2001
From: Kenn Jacobsen
Date: Fri, 11 Jan 2019 15:07:04 +0100
Subject: [PATCH 46/84] Ensure some spacing between properties within Nested
Content items
---
.../src/less/components/umb-nested-content.less | 7 +++++++
.../nestedcontent/nestedcontent.editor.html | 2 +-
2 files changed, 8 insertions(+), 1 deletion(-)
diff --git a/src/Umbraco.Web.UI.Client/src/less/components/umb-nested-content.less b/src/Umbraco.Web.UI.Client/src/less/components/umb-nested-content.less
index df8977a2bf..6ddd9d8d50 100644
--- a/src/Umbraco.Web.UI.Client/src/less/components/umb-nested-content.less
+++ b/src/Umbraco.Web.UI.Client/src/less/components/umb-nested-content.less
@@ -3,6 +3,13 @@
position: relative;
}
+.umb-nested-content-property-container {
+ position: relative;
+ &:not(:last-child){
+ margin-bottom: 12px;
+ }
+}
+
.umb-nested-content--not-supported {
opacity: 0.3;
pointer-events: none;
diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/nestedcontent/nestedcontent.editor.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/nestedcontent/nestedcontent.editor.html
index 83076b54a0..0cf67022c6 100644
--- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/nestedcontent/nestedcontent.editor.html
+++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/nestedcontent/nestedcontent.editor.html
@@ -1,5 +1,5 @@
-
+
From f620d0deca457d3733755a8e6bb71082511fd1f2 Mon Sep 17 00:00:00 2001
From: Steve
Date: Fri, 11 Jan 2019 11:16:46 +0000
Subject: [PATCH 47/84] Fixes #4016 unpublished content styling in list view
---
src/Umbraco.Web.UI.Client/src/less/components/umb-table.less | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/Umbraco.Web.UI.Client/src/less/components/umb-table.less b/src/Umbraco.Web.UI.Client/src/less/components/umb-table.less
index 2c1fc4a701..217d94bc00 100644
--- a/src/Umbraco.Web.UI.Client/src/less/components/umb-table.less
+++ b/src/Umbraco.Web.UI.Client/src/less/components/umb-table.less
@@ -165,7 +165,7 @@ input.umb-table__input {
}
-.-content :not(.with-unpublished-version).-unpublished {
+.-content .-unpublished:not(.with-unpublished-version) {
.umb-table__name > * {
opacity: .4;
}
From b354eda7ac9ed2f3f650ef4c169425f2d39dc1a7 Mon Sep 17 00:00:00 2001
From: Bjarne Fyrstenborg
Date: Tue, 8 Jan 2019 00:39:45 +0100
Subject: [PATCH 48/84] Add styles for umb-property-file-upload and move styles
for umb-upload-big-button
---
src/Umbraco.Web.UI.Client/src/less/belle.less | 1 +
.../components/umb-property-file-upload.less | 28 +++++++++++++++++++
.../src/less/property-editors.less | 13 +--------
.../upload/umb-property-file-upload.html | 3 +-
4 files changed, 32 insertions(+), 13 deletions(-)
create mode 100644 src/Umbraco.Web.UI.Client/src/less/components/umb-property-file-upload.less
diff --git a/src/Umbraco.Web.UI.Client/src/less/belle.less b/src/Umbraco.Web.UI.Client/src/less/belle.less
index a28c128706..a65b94444e 100644
--- a/src/Umbraco.Web.UI.Client/src/less/belle.less
+++ b/src/Umbraco.Web.UI.Client/src/less/belle.less
@@ -161,6 +161,7 @@
@import "components/umb-file-dropzone.less";
@import "components/umb-node-preview.less";
@import "components/umb-mini-editor.less";
+@import "components/umb-property-file-upload.less";
@import "components/users/umb-user-cards.less";
@import "components/users/umb-user-details.less";
diff --git a/src/Umbraco.Web.UI.Client/src/less/components/umb-property-file-upload.less b/src/Umbraco.Web.UI.Client/src/less/components/umb-property-file-upload.less
new file mode 100644
index 0000000000..08b1a1b5e1
--- /dev/null
+++ b/src/Umbraco.Web.UI.Client/src/less/components/umb-property-file-upload.less
@@ -0,0 +1,28 @@
+.umb-property-file-upload {
+
+ .umb-upload-button-big {
+ display: block;
+ padding: 20px;
+ opacity: 1;
+ border: 1px dashed @gray-8;
+ background: none;
+ text-align: center;
+ font-size: 14px;
+
+ &, &:hover {
+ color: @gray-8;
+ }
+
+ i.icon {
+ font-size: 55px;
+ line-height: 70px
+ }
+
+ input {
+ left: 0;
+ bottom: 0;
+ height: 100%;
+ width: 100%;
+ }
+ }
+}
diff --git a/src/Umbraco.Web.UI.Client/src/less/property-editors.less b/src/Umbraco.Web.UI.Client/src/less/property-editors.less
index 7e3d3f1491..3ec8c383da 100644
--- a/src/Umbraco.Web.UI.Client/src/less/property-editors.less
+++ b/src/Umbraco.Web.UI.Client/src/less/property-editors.less
@@ -699,7 +699,7 @@
//
// folder-browser
// --------------------------------------------------
-.umb-folderbrowser .add-link{
+.umb-folderbrowser .add-link {
display: inline-block;
height: 120px;
width: 120px;
@@ -708,17 +708,6 @@
line-height: 120px
}
-.umb-upload-button-big:hover{color: @gray-8;}
-
-.umb-upload-button-big {display: block}
-.umb-upload-button-big input {
- left: 0;
- bottom: 0;
- height: 100%;
- width: 100%;
-}
-
-
//
// File upload
// --------------------------------------------------
diff --git a/src/Umbraco.Web.UI.Client/src/views/components/upload/umb-property-file-upload.html b/src/Umbraco.Web.UI.Client/src/views/components/upload/umb-property-file-upload.html
index f205dffa57..dea532b7ea 100644
--- a/src/Umbraco.Web.UI.Client/src/views/components/upload/umb-property-file-upload.html
+++ b/src/Umbraco.Web.UI.Client/src/views/components/upload/umb-property-file-upload.html
@@ -1,4 +1,5 @@
-
+
+
Date: Tue, 8 Jan 2019 00:40:23 +0100
Subject: [PATCH 49/84] Only show extension if media item has a file
---
.../src/views/components/umb-media-grid.html | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/Umbraco.Web.UI.Client/src/views/components/umb-media-grid.html b/src/Umbraco.Web.UI.Client/src/views/components/umb-media-grid.html
index 2591789a36..360c6b2bb7 100644
--- a/src/Umbraco.Web.UI.Client/src/views/components/umb-media-grid.html
+++ b/src/Umbraco.Web.UI.Client/src/views/components/umb-media-grid.html
@@ -24,7 +24,7 @@
- .{{item.extension}}
+ .{{item.extension}}
From 9968cd257d072e049fdc163e6862cbe6da9c7487 Mon Sep 17 00:00:00 2001
From: Bjarne Fyrstenborg
Date: Tue, 8 Jan 2019 00:41:26 +0100
Subject: [PATCH 50/84] Rename wrapper class on umb-file-dropzone
---
.../src/less/components/umb-file-dropzone.less | 2 +-
.../src/views/components/upload/umb-file-dropzone.html | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/Umbraco.Web.UI.Client/src/less/components/umb-file-dropzone.less b/src/Umbraco.Web.UI.Client/src/less/components/umb-file-dropzone.less
index 4803c05f6e..b7c58ad3cf 100644
--- a/src/Umbraco.Web.UI.Client/src/less/components/umb-file-dropzone.less
+++ b/src/Umbraco.Web.UI.Client/src/less/components/umb-file-dropzone.less
@@ -1,5 +1,5 @@
-.umb-file-dropzone-directive{
+.umb-file-dropzone {
// drop zone
// tall and small version - animate height
diff --git a/src/Umbraco.Web.UI.Client/src/views/components/upload/umb-file-dropzone.html b/src/Umbraco.Web.UI.Client/src/views/components/upload/umb-file-dropzone.html
index 9d2997625e..c99655b7fc 100644
--- a/src/Umbraco.Web.UI.Client/src/views/components/upload/umb-file-dropzone.html
+++ b/src/Umbraco.Web.UI.Client/src/views/components/upload/umb-file-dropzone.html
@@ -1,4 +1,4 @@
-
+
From 1213551ca951db86acc0fda3f40b0a1d4efad4a5 Mon Sep 17 00:00:00 2001
From: Bjarne Fyrstenborg
Date: Tue, 8 Jan 2019 00:40:23 +0100
Subject: [PATCH 51/84] Only show extension if media item has a file
(cherry picked from commit 168febae248cb80a6c87ca9d0c840b70f97121fc)
---
.../src/views/components/umb-media-grid.html | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/Umbraco.Web.UI.Client/src/views/components/umb-media-grid.html b/src/Umbraco.Web.UI.Client/src/views/components/umb-media-grid.html
index bad1ccc1ce..e97c91b414 100644
--- a/src/Umbraco.Web.UI.Client/src/views/components/umb-media-grid.html
+++ b/src/Umbraco.Web.UI.Client/src/views/components/umb-media-grid.html
@@ -23,7 +23,7 @@
- .{{item.extension}}
+ .{{item.extension}}
From 8d1733fd1275ba18f3420e995613bc52e0b51344 Mon Sep 17 00:00:00 2001
From: Jannik Anker
Date: Tue, 2 Oct 2018 18:43:12 +0200
Subject: [PATCH 52/84] Issue 3018 - non-admin users cannot create groups
---
.../Editors/UserGroupEditorAuthorizationHelper.cs | 14 +++++++++++++-
src/Umbraco.Web/Editors/UserGroupsController.cs | 11 ++++++++++-
2 files changed, 23 insertions(+), 2 deletions(-)
diff --git a/src/Umbraco.Web/Editors/UserGroupEditorAuthorizationHelper.cs b/src/Umbraco.Web/Editors/UserGroupEditorAuthorizationHelper.cs
index 6bc39b376d..5e6458f93a 100644
--- a/src/Umbraco.Web/Editors/UserGroupEditorAuthorizationHelper.cs
+++ b/src/Umbraco.Web/Editors/UserGroupEditorAuthorizationHelper.cs
@@ -53,6 +53,18 @@ namespace Umbraco.Web.Editors
if (currentUser.IsAdmin())
return Attempt.Succeed();
+ // var derp = ((userGroupSave.Id == null || (int)userGroupSave.Id <= 0) && Services.SectionService.GetAllowedSections(Security.CurrentUser.Id).Select(x => x.Alias).Contains(Constants.Applications.Users)) ? Attempt.Succeed() : Attempt.Failed();
+
+ var existingGroups = _userService.GetUserGroupsByAlias(groupAliases);
+
+ if(!existingGroups.Any())
+ {
+ // We're dealing with new groups,
+ // so authorization should be given to any user with access to Users section
+ if (currentUser.AllowedSections.Contains(Constants.Applications.Users))
+ return Attempt.Succeed();
+ }
+
var userGroups = currentUser.Groups.Select(x => x.Alias).ToArray();
var missingAccess = groupAliases.Except(userGroups).ToArray();
return missingAccess.Length == 0
@@ -119,4 +131,4 @@ namespace Umbraco.Web.Editors
return Attempt.Succeed();
}
}
-}
\ No newline at end of file
+}
diff --git a/src/Umbraco.Web/Editors/UserGroupsController.cs b/src/Umbraco.Web/Editors/UserGroupsController.cs
index 66011e01b2..7d08560b6f 100644
--- a/src/Umbraco.Web/Editors/UserGroupsController.cs
+++ b/src/Umbraco.Web/Editors/UserGroupsController.cs
@@ -30,6 +30,7 @@ namespace Umbraco.Web.Editors
//authorize that the user has access to save this user group
var authHelper = new UserGroupEditorAuthorizationHelper(
Services.UserService, Services.ContentService, Services.MediaService, Services.EntityService);
+
var isAuthorized = authHelper.AuthorizeGroupAccess(Security.CurrentUser, userGroupSave.Alias);
if (isAuthorized == false)
throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.Unauthorized, isAuthorized.Result));
@@ -50,6 +51,14 @@ namespace Umbraco.Web.Editors
if (isAuthorized == false)
throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.Unauthorized, isAuthorized.Result));
+ //current user needs to be added to a new group if not an admin (possibly only if no other users are added?) to avoid a 401
+ if(!Security.CurrentUser.IsAdmin() && (userGroupSave.Id == null || Convert.ToInt32(userGroupSave.Id) >= 0)/* && !userGroupSave.Users.Any() */)
+ {
+ var userIds = userGroupSave.Users.ToList();
+ userIds.Add(Security.CurrentUser.Id);
+ userGroupSave.Users = userIds;
+ }
+
//save the group
Services.UserService.Save(userGroupSave.PersistedUserGroup, userGroupSave.Users.ToArray());
@@ -148,4 +157,4 @@ namespace Umbraco.Web.Editors
Services.TextService.Localize("speechBubbles/deleteUserGroupSuccess", new[] {userGroups[0].Name}));
}
}
-}
\ No newline at end of file
+}
From 1224f682977d32b0526fa36d0605618b31fdca1f Mon Sep 17 00:00:00 2001
From: Jannik Anker
Date: Tue, 2 Oct 2018 18:45:44 +0200
Subject: [PATCH 53/84] Issue 3018 - non-admin users cannot create groups
(derpness cleanup)
---
src/Umbraco.Web/Editors/UserGroupEditorAuthorizationHelper.cs | 2 --
1 file changed, 2 deletions(-)
diff --git a/src/Umbraco.Web/Editors/UserGroupEditorAuthorizationHelper.cs b/src/Umbraco.Web/Editors/UserGroupEditorAuthorizationHelper.cs
index 5e6458f93a..1f7601379e 100644
--- a/src/Umbraco.Web/Editors/UserGroupEditorAuthorizationHelper.cs
+++ b/src/Umbraco.Web/Editors/UserGroupEditorAuthorizationHelper.cs
@@ -53,8 +53,6 @@ namespace Umbraco.Web.Editors
if (currentUser.IsAdmin())
return Attempt.Succeed();
- // var derp = ((userGroupSave.Id == null || (int)userGroupSave.Id <= 0) && Services.SectionService.GetAllowedSections(Security.CurrentUser.Id).Select(x => x.Alias).Contains(Constants.Applications.Users)) ? Attempt.Succeed() : Attempt.Failed();
-
var existingGroups = _userService.GetUserGroupsByAlias(groupAliases);
if(!existingGroups.Any())
From 282ac2b9c5da047cb6b725a74500a18e21890c73 Mon Sep 17 00:00:00 2001
From: christophnz
Date: Fri, 14 Dec 2018 22:46:35 +1300
Subject: [PATCH 54/84] Added 2 HtmlHelper extension methods for rendering
RelatedLinks, including Unit tests
---
.../Mvc/HtmlHelperExtensionMethodsTests.cs | 29 +++++++++++++++--
src/Umbraco.Web/HtmlHelperRenderExtensions.cs | 32 +++++++++++++++++++
2 files changed, 59 insertions(+), 2 deletions(-)
diff --git a/src/Umbraco.Tests/Web/Mvc/HtmlHelperExtensionMethodsTests.cs b/src/Umbraco.Tests/Web/Mvc/HtmlHelperExtensionMethodsTests.cs
index adf5772f76..e7e4f363c1 100644
--- a/src/Umbraco.Tests/Web/Mvc/HtmlHelperExtensionMethodsTests.cs
+++ b/src/Umbraco.Tests/Web/Mvc/HtmlHelperExtensionMethodsTests.cs
@@ -29,5 +29,30 @@ namespace Umbraco.Tests.Web.Mvc
var output = _htmlHelper.Wrap("div", "hello world", new {style = "color:red;", onclick = "void();"});
Assert.AreEqual("hello world
", output.ToHtmlString());
}
- }
-}
\ No newline at end of file
+
+ [Test]
+ public void GetRelatedLinkHtml_Simple()
+ {
+ var relatedLink = new Umbraco.Web.Models.RelatedLink {
+ Caption = "Link Caption",
+ NewWindow = true,
+ Link = "https://www.google.com/"
+ };
+ var output = _htmlHelper.GetRelatedLinkHtml(relatedLink);
+ Assert.AreEqual("Link Caption ", output.ToHtmlString());
+ }
+
+ [Test]
+ public void GetRelatedLinkHtml_HtmlAttributes()
+ {
+ var relatedLink = new Umbraco.Web.Models.RelatedLink
+ {
+ Caption = "Link Caption",
+ NewWindow = true,
+ Link = "https://www.google.com/"
+ };
+ var output = _htmlHelper.GetRelatedLinkHtml(relatedLink, new { @class = "test-class"});
+ Assert.AreEqual("Link Caption ", output.ToHtmlString());
+ }
+ }
+}
diff --git a/src/Umbraco.Web/HtmlHelperRenderExtensions.cs b/src/Umbraco.Web/HtmlHelperRenderExtensions.cs
index 30b4e64e33..90bc97ca19 100644
--- a/src/Umbraco.Web/HtmlHelperRenderExtensions.cs
+++ b/src/Umbraco.Web/HtmlHelperRenderExtensions.cs
@@ -965,5 +965,37 @@ namespace Umbraco.Web
#endregion
+ #region RelatedLink
+
+ ///
+ /// Renders an anchor element for a RelatedLink instance.
+ /// Format: <a href="relatedLink.Link" target="_blank/_self">relatedLink.Caption</a>
+ ///
+ /// The HTML helper instance that this method extends.
+ /// The RelatedLink instance
+ /// An anchor element
+ public static MvcHtmlString GetRelatedLinkHtml(this HtmlHelper htmlHelper, RelatedLink relatedLink)
+ {
+ return htmlHelper.GetRelatedLinkHtml(relatedLink, null);
+ }
+
+ ///
+ /// Renders an anchor element for a RelatedLink instance, accepting htmlAttributes.
+ /// Format: <a href="relatedLink.Link" target="_blank/_self" htmlAttributes>relatedLink.Caption</a>
+ ///
+ /// The HTML helper instance that this method extends.
+ /// The RelatedLink instance
+ /// An object that contains the HTML attributes to set for the element.
+ ///
+ public static MvcHtmlString GetRelatedLinkHtml(this HtmlHelper htmlHelper, RelatedLink relatedLink, object htmlAttributes)
+ {
+ var tagBuilder = new TagBuilder("a");
+ tagBuilder.MergeAttributes(HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
+ tagBuilder.MergeAttribute("href", relatedLink.Link);
+ tagBuilder.MergeAttribute("target", relatedLink.NewWindow ? "_blank" : "_self");
+ tagBuilder.InnerHtml = HttpUtility.HtmlEncode(relatedLink.Caption);
+ return MvcHtmlString.Create(tagBuilder.ToString(TagRenderMode.Normal));
+ }
+ #endregion
}
}
From 74986d24f15637093bb1b6662ea4351e40e417fc Mon Sep 17 00:00:00 2001
From: Kenn Jacobsen
Date: Sun, 13 Jan 2019 15:49:37 +0100
Subject: [PATCH 55/84] V8: Add "Move" option for deleted items in the content
tree (#3931)
---
.../content/content.restore.controller.js | 128 +++++++++++++-----
.../src/views/content/restore.html | 109 +++++++++++----
src/Umbraco.Web.UI/Umbraco/config/lang/en.xml | 4 +-
.../Umbraco/config/lang/en_us.xml | 4 +-
4 files changed, 180 insertions(+), 65 deletions(-)
diff --git a/src/Umbraco.Web.UI.Client/src/views/content/content.restore.controller.js b/src/Umbraco.Web.UI.Client/src/views/content/content.restore.controller.js
index 859e6281c0..24457f6980 100644
--- a/src/Umbraco.Web.UI.Client/src/views/content/content.restore.controller.js
+++ b/src/Umbraco.Web.UI.Client/src/views/content/content.restore.controller.js
@@ -1,26 +1,91 @@
angular.module("umbraco").controller("Umbraco.Editors.Content.RestoreController",
- function ($scope, relationResource, contentResource, entityResource, navigationService, appState, treeService, localizationService) {
+ function ($scope, relationResource, contentResource, entityResource, navigationService, appState, treeService, userService) {
$scope.source = _.clone($scope.currentNode);
- $scope.error = null;
- $scope.success = false;
+ $scope.error = null;
$scope.loading = true;
+ $scope.moving = false;
+ $scope.success = false;
+
+ $scope.dialogTreeApi = {};
+ $scope.searchInfo = {
+ showSearch: false,
+ results: [],
+ selectedSearchResults: []
+ }
+ $scope.treeModel = {
+ hideHeader: false
+ }
+ userService.getCurrentUser().then(function (userData) {
+ $scope.treeModel.hideHeader = userData.startContentIds.length > 0 && userData.startContentIds.indexOf(-1) == -1;
+ });
+
+ function nodeSelectHandler(args) {
+
+ if (args && args.event) {
+ args.event.preventDefault();
+ args.event.stopPropagation();
+ }
+
+ if ($scope.target) {
+ //un-select if there's a current one selected
+ $scope.target.selected = false;
+ }
+
+ $scope.target = args.node;
+ $scope.target.selected = true;
+
+ }
+
+ function nodeExpandedHandler(args) {
+ // open mini list view for list views
+ if (args.node.metaData.isContainer) {
+ openMiniListView(args.node);
+ }
+ }
+
+ $scope.hideSearch = function () {
+ $scope.searchInfo.showSearch = false;
+ $scope.searchInfo.results = [];
+ }
+
+ // method to select a search result
+ $scope.selectResult = function (evt, result) {
+ result.selected = result.selected === true ? false : true;
+ nodeSelectHandler(evt, { event: evt, node: result });
+ };
+
+ //callback when there are search results
+ $scope.onSearchResults = function (results) {
+ $scope.searchInfo.results = results;
+ $scope.searchInfo.showSearch = true;
+ };
+
+ $scope.onTreeInit = function () {
+ $scope.dialogTreeApi.callbacks.treeNodeSelect(nodeSelectHandler);
+ $scope.dialogTreeApi.callbacks.treeNodeExpanded(nodeExpandedHandler);
+ }
+
+ // Mini list view
+ $scope.selectListViewNode = function (node) {
+ node.selected = node.selected === true ? false : true;
+ nodeSelectHandler({}, { node: node });
+ };
+
+ $scope.closeMiniListView = function () {
+ $scope.miniListView = undefined;
+ };
+
+ function openMiniListView(node) {
+ $scope.miniListView = node;
+ }
relationResource.getByChildId($scope.source.id, "relateParentDocumentOnDelete").then(function (data) {
$scope.loading = false;
if (!data.length) {
- localizationService.localizeMany(["recycleBin_itemCannotBeRestored", "recycleBin_noRestoreRelation"])
- .then(function(values) {
- $scope.success = false;
- $scope.error = {
- errorMsg: values[0],
- data: {
- Message: values[1]
- }
- }
- });
+ $scope.moving = true;
return;
}
@@ -30,40 +95,32 @@ angular.module("umbraco").controller("Umbraco.Editors.Content.RestoreController"
$scope.target = { id: -1, name: "Root" };
} else {
- $scope.loading = true;
+ $scope.loading = true;
+
entityResource.getById($scope.relation.parentId, "Document").then(function (data) {
$scope.loading = false;
- $scope.target = data;
- // make sure the target item isn't in the recycle bin
- if($scope.target.path.indexOf("-20") !== -1) {
- localizationService.localizeMany(["recycleBin_itemCannotBeRestored", "recycleBin_restoreUnderRecycled"])
- .then(function (values) {
- $scope.success = false;
- $scope.error = {
- errorMsg: values[0],
- data: {
- Message: values[1].replace('%0%', $scope.target.name)
- }
- }
- });
- $scope.success = false;
- }
+ $scope.target = data;
+ // make sure the target item isn't in the recycle bin
+ if ($scope.target.path.indexOf("-20") !== -1) {
+ $scope.moving = true;
+ $scope.target = null;
+ }
}, function (err) {
- $scope.success = false;
- $scope.error = err;
$scope.loading = false;
+ $scope.error = err;
});
}
}, function (err) {
- $scope.success = false;
- $scope.error = err;
+ $scope.loading = false;
+ $scope.error = err;
});
$scope.restore = function () {
$scope.loading = true;
- // this code was copied from `content.move.controller.js`
+
+ // this code was copied from `content.move.controller.js`
contentResource.move({ parentId: $scope.target.id, id: $scope.source.id })
.then(function (path) {
@@ -88,9 +145,8 @@ angular.module("umbraco").controller("Umbraco.Editors.Content.RestoreController"
});
}, function (err) {
- $scope.success = false;
- $scope.error = err;
$scope.loading = false;
+ $scope.error = err;
});
};
diff --git a/src/Umbraco.Web.UI.Client/src/views/content/restore.html b/src/Umbraco.Web.UI.Client/src/views/content/restore.html
index 83a69effb6..ead6ed91ab 100644
--- a/src/Umbraco.Web.UI.Client/src/views/content/restore.html
+++ b/src/Umbraco.Web.UI.Client/src/views/content/restore.html
@@ -1,34 +1,93 @@
-
-
+
+
+
+
-
-
+
+
+
{{error.errorMsg}}
+
{{error.data.Message}}
+
+
-
- Restore {{source.name}} under {{target.name}} ?
-
+
+
+ {{source.name}}
+ was restored under
+ was moved underneath
+ {{target.name}}
+
+
Ok
+
-
-
-
{{error.errorMsg}}
-
{{error.data.Message}}
-
-
+
-
-
- {{source.name}} was moved underneath {{target.name}}
-
-
Ok
-
+
+ Restore {{source.name}} under {{target.name}} ?
+
-
+
+
+
+
+
+
Cannot automatically restore this item
+
There is no location where this item can be automatically restored. You can move the item manually using the tree below.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
diff --git a/src/Umbraco.Web.UI/Umbraco/config/lang/en.xml b/src/Umbraco.Web.UI/Umbraco/config/lang/en.xml
index 69f106a775..993286f4c6 100644
--- a/src/Umbraco.Web.UI/Umbraco/config/lang/en.xml
+++ b/src/Umbraco.Web.UI/Umbraco/config/lang/en.xml
@@ -1968,8 +1968,8 @@ To manage your website, simply open the Umbraco back office and start adding con
Trashed content with Id: {0} related to original parent content with Id: {1}
Trashed media with Id: {0} related to original parent media item with Id: {1}
Cannot automatically restore this item
-
There is no 'restore' relation found for this node. Use the Move menu item to move it manually.
-
The item you want to restore it under ('%0%') is in the recycle bin. Use the Move menu item to move the item manually.
+
There is no location where this item can be automatically restored. You can move the item manually using the tree below.
+
was restored under
Direction
diff --git a/src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml b/src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml
index eaa1c6c39e..b15ff24729 100644
--- a/src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml
+++ b/src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml
@@ -2024,8 +2024,8 @@ To manage your website, simply open the Umbraco back office and start adding con
Trashed content with Id: {0} related to original parent content with Id: {1}
Trashed media with Id: {0} related to original parent media item with Id: {1}
Cannot automatically restore this item
-
There is no 'restore' relation found for this node. Use the Move menu item to move it manually.
-
The item you want to restore it under ('%0%') is in the recycle bin. Use the Move menu item to move the item manually.
+
There is no location where this item can be automatically restored. You can move the item manually using the tree below.
+
was restored under
Direction
From 3b8a570c3c3356c745aa8a51d5347e0173d4e03b Mon Sep 17 00:00:00 2001
From: Kenn Jacobsen
Date: Sun, 13 Jan 2019 15:53:42 +0100
Subject: [PATCH 56/84] V8: Safeguard against invalid culture in UMB_MCULTURE
cookie (#4051)
---
.../src/controllers/navigation.controller.js | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/src/Umbraco.Web.UI.Client/src/controllers/navigation.controller.js b/src/Umbraco.Web.UI.Client/src/controllers/navigation.controller.js
index 335fe99e7c..e023c6d23c 100644
--- a/src/Umbraco.Web.UI.Client/src/controllers/navigation.controller.js
+++ b/src/Umbraco.Web.UI.Client/src/controllers/navigation.controller.js
@@ -355,7 +355,9 @@ function NavigationController($scope, $rootScope, $location, $log, $q, $routePar
if (!currCulture) {
// no culture in the request, let's look for one in the cookie that's set when changing language
var defaultCulture = $cookies.get("UMB_MCULTURE");
- if (!defaultCulture) {
+ if (!defaultCulture || !_.find($scope.languages, function (l) {
+ return l.culture.toLowerCase() === defaultCulture.toLowerCase();
+ })) {
// no luck either, look for the default language
var defaultLang = _.find($scope.languages, function (l) {
return l.isDefault;
@@ -399,9 +401,10 @@ function NavigationController($scope, $rootScope, $location, $log, $q, $routePar
$scope.selectLanguage = function (language) {
$location.search("mculture", language.culture);
- // add the selected culture to a cookie so the user will log back into the same culture later on (cookie max age is one year = 31536000 seconds)
- // NOTE: $cookies doesn't support max-age, so we need to go the good ol' JS way about setting the cookie
- document.cookie = "UMB_MCULTURE=" +language.culture + ";path=/;max-age=31536000;";
+ // add the selected culture to a cookie so the user will log back into the same culture later on (cookie lifetime = one year)
+ var expireDate = new Date();
+ expireDate.setDate(expireDate.getDate() + 365);
+ $cookies.put("UMB_MCULTURE", language.culture, {path: "/", expires: expireDate});
// close the language selector
$scope.page.languageSelectorIsOpen = false;
From be44741bf986c1961fed8ff7119f6e10b1b984fa Mon Sep 17 00:00:00 2001
From: Anders Bjerner
Date: Sun, 13 Jan 2019 15:58:31 +0100
Subject: [PATCH 57/84] Localized parts of the codefile and template resources
(#3495)
---
.../src/common/resources/codefile.resource.js | 17 +++++++++++++----
.../src/common/resources/template.resource.js | 7 +++++--
.../src/views/partialviews/create.html | 2 +-
.../src/views/partialviews/delete.controller.js | 6 ++++++
.../src/views/partialviews/delete.html | 7 +++++++
.../src/views/templates/delete.controller.js | 7 +++++++
.../src/views/templates/delete.html | 9 ++++++++-
src/Umbraco.Web.UI/umbraco/config/lang/da.xml | 7 +++++++
src/Umbraco.Web.UI/umbraco/config/lang/en.xml | 7 +++++++
.../umbraco/config/lang/en_us.xml | 7 +++++++
10 files changed, 68 insertions(+), 8 deletions(-)
diff --git a/src/Umbraco.Web.UI.Client/src/common/resources/codefile.resource.js b/src/Umbraco.Web.UI.Client/src/common/resources/codefile.resource.js
index 7cd55b268a..c7bbbe9227 100644
--- a/src/Umbraco.Web.UI.Client/src/common/resources/codefile.resource.js
+++ b/src/Umbraco.Web.UI.Client/src/common/resources/codefile.resource.js
@@ -3,7 +3,7 @@
* @name umbraco.resources.codefileResource
* @description Loads in data for files that contain code such as js scripts, partial views and partial view macros
**/
-function codefileResource($q, $http, umbDataFormatter, umbRequestHelper) {
+function codefileResource($q, $http, umbDataFormatter, umbRequestHelper, localizationService) {
return {
@@ -106,13 +106,16 @@ function codefileResource($q, $http, umbDataFormatter, umbRequestHelper) {
*
*/
deleteByPath: function (type, virtualpath) {
+
+ var promise = localizationService.localize("codefile_deleteItemFailed", [virtualpath]);
+
return umbRequestHelper.resourcePromise(
$http.post(
umbRequestHelper.getApiUrl(
"codeFileApiBaseUrl",
"Delete",
[{ type: type }, { virtualPath: virtualpath}])),
- "Failed to delete item: " + virtualpath);
+ promise);
},
/**
@@ -236,13 +239,19 @@ function codefileResource($q, $http, umbDataFormatter, umbRequestHelper) {
*
*/
- createContainer: function(type, parentId, name) {
+ createContainer: function (type, parentId, name) {
+
+ // Is the parent ID numeric?
+ var key = "codefile_createFolderFailedBy" + (isNaN(parseInt(parentId)) ? "Name" : "Id");
+
+ var promise = localizationService.localize(key, [parentId]);
+
return umbRequestHelper.resourcePromise(
$http.post(umbRequestHelper.getApiUrl(
"codeFileApiBaseUrl",
"PostCreateContainer",
{ type: type, parentId: parentId, name: encodeURIComponent(name) })),
- 'Failed to create a folder under parent id ' + parentId);
+ promise);
}
};
diff --git a/src/Umbraco.Web.UI.Client/src/common/resources/template.resource.js b/src/Umbraco.Web.UI.Client/src/common/resources/template.resource.js
index f969864ba1..377bb415fc 100644
--- a/src/Umbraco.Web.UI.Client/src/common/resources/template.resource.js
+++ b/src/Umbraco.Web.UI.Client/src/common/resources/template.resource.js
@@ -3,7 +3,7 @@
* @name umbraco.resources.templateResource
* @description Loads in data for templates
**/
-function templateResource($q, $http, umbDataFormatter, umbRequestHelper) {
+function templateResource($q, $http, umbDataFormatter, umbRequestHelper, localizationService) {
return {
@@ -152,13 +152,16 @@ function templateResource($q, $http, umbDataFormatter, umbRequestHelper) {
*
*/
deleteById: function(id) {
+
+ var promise = localizationService.localize("template_deleteByIdFailed", [id]);
+
return umbRequestHelper.resourcePromise(
$http.post(
umbRequestHelper.getApiUrl(
"templateApiBaseUrl",
"DeleteById",
[{ id: id }])),
- "Failed to delete item " + id);
+ promise);
},
/**
diff --git a/src/Umbraco.Web.UI.Client/src/views/partialviews/create.html b/src/Umbraco.Web.UI.Client/src/views/partialviews/create.html
index 4d15ab6c01..5cd739adf5 100644
--- a/src/Umbraco.Web.UI.Client/src/views/partialviews/create.html
+++ b/src/Umbraco.Web.UI.Client/src/views/partialviews/create.html
@@ -57,7 +57,7 @@
-
+
diff --git a/src/Umbraco.Web.UI.Client/src/views/partialviews/delete.controller.js b/src/Umbraco.Web.UI.Client/src/views/partialviews/delete.controller.js
index b25ac3c7b8..1e615ad0d4 100644
--- a/src/Umbraco.Web.UI.Client/src/views/partialviews/delete.controller.js
+++ b/src/Umbraco.Web.UI.Client/src/views/partialviews/delete.controller.js
@@ -12,6 +12,9 @@ function PartialViewsDeleteController($scope, codefileResource, treeService, nav
//mark it for deletion (used in the UI)
$scope.currentNode.loading = true;
+
+ // Reset the error message
+ $scope.error = null;
codefileResource.deleteByPath('partialViews', $scope.currentNode.id)
.then(function() {
@@ -21,6 +24,9 @@ function PartialViewsDeleteController($scope, codefileResource, treeService, nav
//TODO: Need to sync tree, etc...
treeService.removeNode($scope.currentNode);
navigationService.hideMenu();
+ }, function (err) {
+ $scope.currentNode.loading = false;
+ $scope.error = err;
});
};
diff --git a/src/Umbraco.Web.UI.Client/src/views/partialviews/delete.html b/src/Umbraco.Web.UI.Client/src/views/partialviews/delete.html
index 0f75e8514e..c0fdf2c77f 100644
--- a/src/Umbraco.Web.UI.Client/src/views/partialviews/delete.html
+++ b/src/Umbraco.Web.UI.Client/src/views/partialviews/delete.html
@@ -1,6 +1,13 @@
+
+
+
{{error.errorMsg}}
+
{{error.data.message}}
+
+
+
Are you sure you want to delete {{currentNode.name}} ?
diff --git a/src/Umbraco.Web.UI.Client/src/views/templates/delete.controller.js b/src/Umbraco.Web.UI.Client/src/views/templates/delete.controller.js
index 8995cb1a31..d019a44a10 100644
--- a/src/Umbraco.Web.UI.Client/src/views/templates/delete.controller.js
+++ b/src/Umbraco.Web.UI.Client/src/views/templates/delete.controller.js
@@ -12,6 +12,10 @@ function TemplatesDeleteController($scope, templateResource , treeService, navig
//mark it for deletion (used in the UI)
$scope.currentNode.loading = true;
+
+ // Reset the error message
+ $scope.error = null;
+
templateResource.deleteById($scope.currentNode.id).then(function () {
$scope.currentNode.loading = false;
@@ -21,6 +25,9 @@ function TemplatesDeleteController($scope, templateResource , treeService, navig
//TODO: Need to sync tree, etc...
treeService.removeNode($scope.currentNode);
navigationService.hideMenu();
+ }, function (err) {
+ $scope.currentNode.loading = false;
+ $scope.error = err;
});
};
diff --git a/src/Umbraco.Web.UI.Client/src/views/templates/delete.html b/src/Umbraco.Web.UI.Client/src/views/templates/delete.html
index 34648aa43e..c98677f764 100644
--- a/src/Umbraco.Web.UI.Client/src/views/templates/delete.html
+++ b/src/Umbraco.Web.UI.Client/src/views/templates/delete.html
@@ -1,11 +1,18 @@
+
+
+
{{error.errorMsg}}
+
{{error.data.message}}
+
+
+
Are you sure you want to delete {{currentNode.name}} ?
-
+
diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/da.xml b/src/Umbraco.Web.UI/umbraco/config/lang/da.xml
index 658dd091f6..b4ab08422e 100644
--- a/src/Umbraco.Web.UI/umbraco/config/lang/da.xml
+++ b/src/Umbraco.Web.UI/umbraco/config/lang/da.xml
@@ -182,6 +182,11 @@
Overførsel af egenskaber kunne ikke fuldføres, da en eller flere egenskaber er indstillet til at blive overført mere end én gang.
Kun andre dokumenttyper, der er gyldige på denne placering, vises.
+
+
Oprettelse af mappen under parent med ID %0% fejlede
+
Oprettelse af mappen under parent med navnet %0% fejlede
+
Sletning af filen/mappen fejlede: %0%
+
Udgivet
Om siden
@@ -282,6 +287,7 @@
Hvor ønsker du at oprette den nye %0%
Opret under
Vælg den dokumenttype, du vil oprette en indholdsskabelon til
+
Angiv et navn for mappen
Vælg en type og skriv en titel
"dokument typer".]]>
"media typer".]]>
@@ -1158,6 +1164,7 @@ Mange hilsner fra Umbraco robotten
+
Sletning af skabelonen med ID %0% fejlede
Rediger skabelon
Sektioner
diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/en.xml b/src/Umbraco.Web.UI/umbraco/config/lang/en.xml
index cd5f32da0d..7d3bfa7c99 100644
--- a/src/Umbraco.Web.UI/umbraco/config/lang/en.xml
+++ b/src/Umbraco.Web.UI/umbraco/config/lang/en.xml
@@ -188,6 +188,11 @@
Could not complete property mapping as one or more properties have more than one mapping defined.
Only alternate types valid for the current location are displayed.
+
+
Failed to create a folder under parent with ID %0%
+
Failed to create a folder under parent with name %0%
+
Failed to delete item: %0%
+
Is Published
About this page
@@ -290,6 +295,7 @@
Where do you want to create the new %0%
Create an item under
Select the document type you want to make a content template for
+
Enter a folder name
Choose a type and a title
"document types".]]>
"media types".]]>
@@ -1483,6 +1489,7 @@ To manage your website, simply open the Umbraco back office and start adding con
+
Failed to delete template with ID %0%
Edit template
Sections
diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml b/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml
index 88b736a34f..0a1756038f 100644
--- a/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml
+++ b/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml
@@ -189,6 +189,11 @@
Could not complete property mapping as one or more properties have more than one mapping defined.
Only alternate types valid for the current location are displayed.
+
+
Failed to create a folder under parent with ID %0%
+
Failed to create a folder under parent with name %0%
+
Failed to delete item: %0%
+
Is Published
About this page
@@ -292,6 +297,7 @@
Where do you want to create the new %0%
Create an item under
Select the document type you want to make a content template for
+
Enter a folder name
Choose a type and a title
"document types".]]>
"media types".]]>
@@ -1481,6 +1487,7 @@ To manage your website, simply open the Umbraco back office and start adding con
Styles
+
Failed to delete template with ID %0%
Edit template
Sections
From 941baf09cefe0cf32aae027c17f820f68e1390b9 Mon Sep 17 00:00:00 2001
From: Kenn Jacobsen
Date: Sun, 13 Jan 2019 16:17:44 +0100
Subject: [PATCH 58/84] Fix linkpicker overlay issues (#3718)
---
.../linkpicker/linkpicker.controller.js | 41 +++++++++++--------
1 file changed, 24 insertions(+), 17 deletions(-)
diff --git a/src/Umbraco.Web.UI.Client/src/views/common/overlays/linkpicker/linkpicker.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/overlays/linkpicker/linkpicker.controller.js
index 7b890edbf4..fcce34621b 100644
--- a/src/Umbraco.Web.UI.Client/src/views/common/overlays/linkpicker/linkpicker.controller.js
+++ b/src/Umbraco.Web.UI.Client/src/views/common/overlays/linkpicker/linkpicker.controller.js
@@ -25,30 +25,31 @@ angular.module("umbraco").controller("Umbraco.Overlays.LinkPickerController",
$scope.showTarget = $scope.model.hideTarget !== true;
if (dialogOptions.currentTarget) {
- $scope.model.target = dialogOptions.currentTarget;
+ // clone the current target so we don't accidentally update the caller's model while manipulating $scope.model.target
+ $scope.model.target = angular.copy(dialogOptions.currentTarget);
//if we have a node ID, we fetch the current node to build the form data
if ($scope.model.target.id || $scope.model.target.udi) {
//will be either a udi or an int
var id = $scope.model.target.udi ? $scope.model.target.udi : $scope.model.target.id;
- if (!$scope.model.target.path) {
+ // is it a content link?
+ if (!$scope.model.target.isMedia) {
+ // get the content path
+ entityResource.getPath(id, "Document").then(function(path) {
+ //now sync the tree to this path
+ $scope.dialogTreeEventHandler.syncTree({
+ path: path,
+ tree: "content"
+ });
+ });
- entityResource.getPath(id, "Document").then(function (path) {
- $scope.model.target.path = path;
- //now sync the tree to this path
- $scope.dialogTreeEventHandler.syncTree({
- path: $scope.model.target.path,
- tree: "content"
- });
- });
- }
-
- // if a link exists, get the properties to build the anchor name list
- contentResource.getById(id).then(function (resp) {
- $scope.model.target.url = resp.urls[0];
- $scope.anchorValues = tinyMceService.getAnchorNames(JSON.stringify(resp.properties));
- });
+ // get the content properties to build the anchor name list
+ contentResource.getById(id).then(function (resp) {
+ $scope.model.target.url = resp.urls[0];
+ $scope.anchorValues = tinyMceService.getAnchorNames(JSON.stringify(resp.properties));
+ });
+ }
} else if ($scope.model.target.url.length) {
// a url but no id/udi indicates an external link - trim the url to remove the anchor/qs
// only do the substring if there's a # or a ?
@@ -122,6 +123,12 @@ angular.module("umbraco").controller("Umbraco.Overlays.LinkPickerController",
$scope.mediaPickerOverlay.show = false;
$scope.mediaPickerOverlay = null;
+
+ // make sure the content tree has nothing highlighted
+ $scope.dialogTreeEventHandler.syncTree({
+ path: "-1",
+ tree: "content"
+ });
}
};
});
From 92c278c593353aaa4af3011f68242734cc4e66b4 Mon Sep 17 00:00:00 2001
From: Sebastiaan Janssen
Date: Mon, 14 Jan 2019 07:12:21 +0100
Subject: [PATCH 59/84] Adds missing translation, fixes #4054
---
src/Umbraco.Web.UI/Umbraco/config/lang/en.xml | 1 +
src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml | 1 +
2 files changed, 2 insertions(+)
diff --git a/src/Umbraco.Web.UI/Umbraco/config/lang/en.xml b/src/Umbraco.Web.UI/Umbraco/config/lang/en.xml
index 02b10fe22f..386d3af518 100644
--- a/src/Umbraco.Web.UI/Umbraco/config/lang/en.xml
+++ b/src/Umbraco.Web.UI/Umbraco/config/lang/en.xml
@@ -1254,6 +1254,7 @@ To manage your website, simply open the Umbraco back office and start adding con
This Content Type uses
as a Master Content Type. Tabs from Master Content Types are not shown and can only be edited on the Master Content Type itself
No properties defined on this tab. Click on the "add a new property" link at the top to create a new property.
+ Create matching template
Add icon
diff --git a/src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml b/src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml
index 83d6b9224b..5de373f571 100644
--- a/src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml
+++ b/src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml
@@ -1278,6 +1278,7 @@ To manage your website, simply open the Umbraco back office and start adding con
This Content Type uses
as a Master Content Type. Tabs from Master Content Types are not shown and can only be edited on the Master Content Type itself
No properties defined on this tab. Click on the "add a new property" link at the top to create a new property.
+ Create matching template
Add icon
From eb6b172be26e30ef5a3b4808e0ca4d3216978d51 Mon Sep 17 00:00:00 2001
From: Stephan
Date: Fri, 11 Jan 2019 16:24:16 +0100
Subject: [PATCH 60/84] Cleanup
---
.../PublishedCache/NuCache/PublishedSnapshotService.cs | 3 ---
1 file changed, 3 deletions(-)
diff --git a/src/Umbraco.Web/PublishedCache/NuCache/PublishedSnapshotService.cs b/src/Umbraco.Web/PublishedCache/NuCache/PublishedSnapshotService.cs
index 3aa33f0e2f..0647e1c806 100755
--- a/src/Umbraco.Web/PublishedCache/NuCache/PublishedSnapshotService.cs
+++ b/src/Umbraco.Web/PublishedCache/NuCache/PublishedSnapshotService.cs
@@ -3,7 +3,6 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
-using System.Web.Hosting;
using CSharpTest.Net.Collections;
using Newtonsoft.Json;
using Umbraco.Core;
@@ -15,7 +14,6 @@ using Umbraco.Core.Models;
using Umbraco.Core.Models.Membership;
using Umbraco.Core.Models.PublishedContent;
using Umbraco.Core.Persistence;
-using Umbraco.Core.Persistence.DatabaseModelDefinitions;
using Umbraco.Core.Persistence.Dtos;
using Umbraco.Core.Persistence.Repositories;
using Umbraco.Core.Persistence.Repositories.Implement;
@@ -26,7 +24,6 @@ using Umbraco.Core.Services.Implement;
using Umbraco.Web.Cache;
using Umbraco.Web.Install;
using Umbraco.Web.PublishedCache.NuCache.DataSource;
-using Umbraco.Web.PublishedCache.XmlPublishedCache;
using Umbraco.Web.Routing;
namespace Umbraco.Web.PublishedCache.NuCache
From c17ee34edb380229b55a8bd812d88517b921e5a8 Mon Sep 17 00:00:00 2001
From: Stephan
Date: Fri, 11 Jan 2019 16:34:58 +0100
Subject: [PATCH 61/84] Support enlisting in exiting scope contexts (why not?)
---
src/Umbraco.Core/Scoping/ScopeContext.cs | 30 +++++++++++++-----------
src/Umbraco.Tests/Scoping/ScopeTests.cs | 16 ++++---------
2 files changed, 20 insertions(+), 26 deletions(-)
diff --git a/src/Umbraco.Core/Scoping/ScopeContext.cs b/src/Umbraco.Core/Scoping/ScopeContext.cs
index dd26fda85e..4ba1999474 100644
--- a/src/Umbraco.Core/Scoping/ScopeContext.cs
+++ b/src/Umbraco.Core/Scoping/ScopeContext.cs
@@ -7,27 +7,32 @@ namespace Umbraco.Core.Scoping
internal class ScopeContext : IScopeContext, IInstanceIdentifiable
{
private Dictionary _enlisted;
- private bool _exiting;
public void ScopeExit(bool completed)
{
if (_enlisted == null)
return;
- _exiting = true;
+ // fixme - can we create infinite loops?
+ // fixme - what about nested events? will they just be plainly ignored = really bad?
List exceptions = null;
- foreach (var enlisted in _enlisted.Values.OrderBy(x => x.Priority))
+ List orderedEnlisted;
+ while ((orderedEnlisted = _enlisted.Values.OrderBy(x => x.Priority).ToList()).Count > 0)
{
- try
+ _enlisted.Clear();
+ foreach (var enlisted in orderedEnlisted)
{
- enlisted.Execute(completed);
- }
- catch (Exception e)
- {
- if (exceptions == null)
- exceptions = new List();
- exceptions.Add(e);
+ try
+ {
+ enlisted.Execute(completed);
+ }
+ catch (Exception e)
+ {
+ if (exceptions == null)
+ exceptions = new List();
+ exceptions.Add(e);
+ }
}
}
@@ -74,9 +79,6 @@ namespace Umbraco.Core.Scoping
public T Enlist(string key, Func creator, Action action = null, int priority = 100)
{
- if (_exiting)
- throw new InvalidOperationException("Cannot enlist now, context is exiting.");
-
var enlistedObjects = _enlisted ?? (_enlisted = new Dictionary());
if (enlistedObjects.TryGetValue(key, out var enlisted))
diff --git a/src/Umbraco.Tests/Scoping/ScopeTests.cs b/src/Umbraco.Tests/Scoping/ScopeTests.cs
index 3f2740291b..6c5e9a74b5 100644
--- a/src/Umbraco.Tests/Scoping/ScopeTests.cs
+++ b/src/Umbraco.Tests/Scoping/ScopeTests.cs
@@ -540,7 +540,7 @@ namespace Umbraco.Tests.Scoping
var scopeProvider = ScopeProvider;
bool? completed = null;
- Exception exception = null;
+ bool? completed2 = null;
Assert.IsNull(scopeProvider.AmbientScope);
using (var scope = scopeProvider.CreateScope())
@@ -551,15 +551,7 @@ namespace Umbraco.Tests.Scoping
// at that point the scope is gone, but the context is still there
var ambientContext = scopeProvider.AmbientContext;
-
- try
- {
- ambientContext.Enlist("another", c2 => { });
- }
- catch (Exception e)
- {
- exception = e;
- }
+ ambientContext.Enlist("another", c2 => { completed2 = c2; });
});
if (complete)
scope.Complete();
@@ -567,8 +559,8 @@ namespace Umbraco.Tests.Scoping
Assert.IsNull(scopeProvider.AmbientScope);
Assert.IsNull(scopeProvider.AmbientContext);
Assert.IsNotNull(completed);
- Assert.IsNotNull(exception);
- Assert.IsInstanceOf(exception);
+ Assert.AreEqual(complete,completed.Value);
+ Assert.AreEqual(complete, completed2.Value);
}
[Test]
From 05fbf6c38a91cbc0e611c510b1d785b888f11c99 Mon Sep 17 00:00:00 2001
From: Stephan
Date: Mon, 14 Jan 2019 08:05:37 +0100
Subject: [PATCH 62/84] Fix DistributedCacheBinder ContentService.TreeChanged
event
---
src/Umbraco.Web/Cache/DistributedCacheBinder_Handlers.cs | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/Umbraco.Web/Cache/DistributedCacheBinder_Handlers.cs b/src/Umbraco.Web/Cache/DistributedCacheBinder_Handlers.cs
index 81b133b9ef..d522e54de6 100644
--- a/src/Umbraco.Web/Cache/DistributedCacheBinder_Handlers.cs
+++ b/src/Umbraco.Web/Cache/DistributedCacheBinder_Handlers.cs
@@ -142,8 +142,8 @@ namespace Umbraco.Web.Cache
() => ContentService.Saved -= ContentService_Saved);
Bind(() => ContentService.Copied += ContentService_Copied, // needed for permissions
() => ContentService.Copied -= ContentService_Copied);
- Bind(() => ContentService.TreeChanged += ContentService_Changed,// handles all content changes
- () => ContentService.TreeChanged -= ContentService_Changed);
+ Bind(() => ContentService.TreeChanged += ContentService_TreeChanged,// handles all content changes
+ () => ContentService.TreeChanged -= ContentService_TreeChanged);
// TreeChanged should also deal with this
//Bind(() => ContentService.SavedBlueprint += ContentService_SavedBlueprint,
@@ -206,7 +206,7 @@ namespace Umbraco.Web.Cache
{
}
- private void ContentService_Changed(IContentService sender, TreeChange.EventArgs args)
+ private void ContentService_TreeChanged(IContentService sender, TreeChange.EventArgs args)
{
_distributedCache.RefreshContentCache(args.Changes.ToArray());
}
From 561b359a721ef002e98c2beb48d374ad683736e1 Mon Sep 17 00:00:00 2001
From: Stephan
Date: Mon, 14 Jan 2019 08:53:04 +0100
Subject: [PATCH 63/84] Name change
---
.../{TargetedServiceProvider.cs => TargetedServiceFactory.cs} | 4 ++--
src/Umbraco.Core/IO/SupportingFileSystems.cs | 4 ++--
src/Umbraco.Core/Umbraco.Core.csproj | 2 +-
3 files changed, 5 insertions(+), 5 deletions(-)
rename src/Umbraco.Core/Composing/{TargetedServiceProvider.cs => TargetedServiceFactory.cs} (76%)
diff --git a/src/Umbraco.Core/Composing/TargetedServiceProvider.cs b/src/Umbraco.Core/Composing/TargetedServiceFactory.cs
similarity index 76%
rename from src/Umbraco.Core/Composing/TargetedServiceProvider.cs
rename to src/Umbraco.Core/Composing/TargetedServiceFactory.cs
index 3f88e1bc28..53022c0043 100644
--- a/src/Umbraco.Core/Composing/TargetedServiceProvider.cs
+++ b/src/Umbraco.Core/Composing/TargetedServiceFactory.cs
@@ -4,11 +4,11 @@
/// Provides a base class for targeted service factories.
///
///
- public abstract class TargetedServiceProvider
+ public abstract class TargetedServiceFactory
{
private readonly IFactory _factory;
- protected TargetedServiceProvider(IFactory factory)
+ protected TargetedServiceFactory(IFactory factory)
{
_factory = factory;
}
diff --git a/src/Umbraco.Core/IO/SupportingFileSystems.cs b/src/Umbraco.Core/IO/SupportingFileSystems.cs
index c13ae203ee..43ac2ba85a 100644
--- a/src/Umbraco.Core/IO/SupportingFileSystems.cs
+++ b/src/Umbraco.Core/IO/SupportingFileSystems.cs
@@ -2,10 +2,10 @@
namespace Umbraco.Core.IO
{
- public class SupportingFileSystems : TargetedServiceProvider
+ public class SupportingFileSystems : TargetedServiceFactory
{
public SupportingFileSystems(IFactory factory)
: base(factory)
{ }
}
-}
\ No newline at end of file
+}
diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj
index a592fd0f0e..609befd233 100755
--- a/src/Umbraco.Core/Umbraco.Core.csproj
+++ b/src/Umbraco.Core/Umbraco.Core.csproj
@@ -196,7 +196,7 @@
-
+
From a68b19f1ee2bbd58975a14a91533b5c7f5c9daf9 Mon Sep 17 00:00:00 2001
From: Stephan
Date: Mon, 14 Jan 2019 14:28:19 +0100
Subject: [PATCH 64/84] More composition / filesystems fixes
---
src/Umbraco.Core/Components/Composition.cs | 94 +++++++++++--------
.../Composing/CompositionExtensions.cs | 2 +-
src/Umbraco.Core/Composing/IFactory.cs | 7 --
src/Umbraco.Core/Composing/IRegister.cs | 45 ++++-----
.../LightInject/LightInjectContainer.cs | 65 +++++--------
.../MixedLightInjectScopeManagerProvider.cs | 3 +
.../Composing/RegisterExtensions.cs | 6 +-
src/Umbraco.Core/Configuration/Configs.cs | 2 +-
.../Composing/ContainerConformingTests.cs | 8 +-
9 files changed, 115 insertions(+), 117 deletions(-)
diff --git a/src/Umbraco.Core/Components/Composition.cs b/src/Umbraco.Core/Components/Composition.cs
index 6cd8c8e5f0..6df86d793f 100644
--- a/src/Umbraco.Core/Components/Composition.cs
+++ b/src/Umbraco.Core/Components/Composition.cs
@@ -81,29 +81,34 @@ namespace Umbraco.Core.Components
public void Register(Type serviceType, Type implementingType, Lifetime lifetime = Lifetime.Transient)
=> _register.Register(serviceType, implementingType, lifetime);
- ///
- public void RegisterFor(Type implementingType, Lifetime lifetime = Lifetime.Transient)
- where TService : class
- => _register.RegisterFor(implementingType, lifetime);
-
///
public void Register(Func factory, Lifetime lifetime = Lifetime.Transient)
where TService : class
=> _register.Register(factory, lifetime);
+ ///
+ public void Register(Type serviceType, object instance)
+ => _register.Register(serviceType, instance);
+
+ ///
+ public void RegisterFor(Lifetime lifetime = Lifetime.Transient)
+ where TService : class
+ => _register.RegisterFor(lifetime);
+
+ ///
+ public void RegisterFor(Type implementingType, Lifetime lifetime = Lifetime.Transient)
+ where TService : class
+ => _register.RegisterFor(implementingType, lifetime);
+
///
public void RegisterFor(Func factory, Lifetime lifetime = Lifetime.Transient)
where TService : class
=> _register.RegisterFor(factory, lifetime);
///
- public void RegisterInstance(Type serviceType, object instance)
- => _register.RegisterInstance(serviceType, instance);
-
- ///
- public void RegisterInstanceFor(TService instance)
+ public void RegisterFor(TService instance)
where TService : class
- => _register.RegisterInstanceFor(instance);
+ => _register.RegisterFor(instance);
///
public void RegisterAuto(Type serviceBaseType)
@@ -154,37 +159,21 @@ namespace Umbraco.Core.Components
=> serviceType.FullName + "::" + targetType.FullName;
///
- /// Registers a unique service.
+ /// Registers a unique service as its own implementation.
+ ///
+ /// Unique services have one single implementation, and a Singleton lifetime.
+ public void RegisterUnique(Type serviceType)
+ => _uniques[GetUniqueName(serviceType)] = register => register.Register(serviceType, Lifetime.Singleton);
+
+ ///
+ /// Registers a unique service with an implementation type.
///
/// Unique services have one single implementation, and a Singleton lifetime.
public void RegisterUnique(Type serviceType, Type implementingType)
=> _uniques[GetUniqueName(serviceType)] = register => register.Register(serviceType, implementingType, Lifetime.Singleton);
///
- /// Registers a unique service, for a target.
- ///
- /// Unique services have one single implementation, and a Singleton lifetime.
- public void RegisterUniqueFor(Type implementingType)
- where TService : class
- => _uniques[GetUniqueName()] = register => register.RegisterFor(implementingType, Lifetime.Singleton);
-
- ///
- /// Registers a unique service.
- ///
- /// Unique services have one single implementation, and a Singleton lifetime.
- public void RegisterUniqueInstance(Type serviceType, object instance)
- => _uniques[GetUniqueName(serviceType)] = register => register.RegisterInstance(serviceType, instance);
-
- ///
- /// Registers a unique service, for a target.
- ///
- /// Unique services have one single implementation, and a Singleton lifetime.
- public void RegisterUniqueInstanceFor(TService instance)
- where TService : class
- => _uniques[GetUniqueName()] = register => register.RegisterInstanceFor(instance);
-
- ///
- /// Registers a unique service.
+ /// Registers a unique service with an implementation factory.
///
/// Unique services have one single implementation, and a Singleton lifetime.
public void RegisterUnique(Func factory)
@@ -192,13 +181,44 @@ namespace Umbraco.Core.Components
=> _uniques[GetUniqueName()] = register => register.Register(factory, Lifetime.Singleton);
///
- /// Registers a unique service, for a target.
+ /// Registers a unique service with an implementing instance.
+ ///
+ /// Unique services have one single implementation, and a Singleton lifetime.
+ public void RegisterUnique(Type serviceType, object instance)
+ => _uniques[GetUniqueName(serviceType)] = register => register.Register(serviceType, instance);
+
+ ///
+ /// Registers a unique service for a target, as its own implementation.
+ ///
+ /// Unique services have one single implementation, and a Singleton lifetime.
+ public void RegisterUniqueFor()
+ where TService : class
+ => _uniques[GetUniqueName()] = register => register.RegisterFor(Lifetime.Singleton);
+
+ ///
+ /// Registers a unique service for a target, with an implementing type.
+ ///
+ /// Unique services have one single implementation, and a Singleton lifetime.
+ public void RegisterUniqueFor(Type implementingType)
+ where TService : class
+ => _uniques[GetUniqueName()] = register => register.RegisterFor(implementingType, Lifetime.Singleton);
+
+ ///
+ /// Registers a unique service for a target, with an implementation factory.
///
/// Unique services have one single implementation, and a Singleton lifetime.
public void RegisterUniqueFor(Func factory)
where TService : class
=> _uniques[GetUniqueName()] = register => register.RegisterFor(factory, Lifetime.Singleton);
+ ///
+ /// Registers a unique service for a target, with an implementing instance.
+ ///
+ /// Unique services have one single implementation, and a Singleton lifetime.
+ public void RegisterUniqueFor(TService instance)
+ where TService : class
+ => _uniques[GetUniqueName()] = register => register.RegisterFor(instance);
+
#endregion
#region Collection Builders
diff --git a/src/Umbraco.Core/Composing/CompositionExtensions.cs b/src/Umbraco.Core/Composing/CompositionExtensions.cs
index ac9a5d6409..2307d757c9 100644
--- a/src/Umbraco.Core/Composing/CompositionExtensions.cs
+++ b/src/Umbraco.Core/Composing/CompositionExtensions.cs
@@ -62,7 +62,7 @@ namespace Umbraco.Core.Composing
/// Registers a unique service with an implementing instance.
///
public static void RegisterUnique(this Composition composition, TService instance)
- => composition.RegisterUniqueInstance(typeof(TService), instance);
+ => composition.RegisterUnique(typeof(TService), instance);
#endregion
}
diff --git a/src/Umbraco.Core/Composing/IFactory.cs b/src/Umbraco.Core/Composing/IFactory.cs
index 20fbe33737..768b9207a3 100644
--- a/src/Umbraco.Core/Composing/IFactory.cs
+++ b/src/Umbraco.Core/Composing/IFactory.cs
@@ -3,13 +3,6 @@ using System.Collections.Generic;
namespace Umbraco.Core.Composing
{
- // Implementing:
- //
- // The factory
- // - always picks the constructor with the most parameters
- // - supports Lazy parameters (and prefers them over non-Lazy) in constructors
- // - what happens with 'releasing' is unclear
-
///
/// Defines a service factory for Umbraco.
///
diff --git a/src/Umbraco.Core/Composing/IRegister.cs b/src/Umbraco.Core/Composing/IRegister.cs
index d145df8790..3e6aed67ee 100644
--- a/src/Umbraco.Core/Composing/IRegister.cs
+++ b/src/Umbraco.Core/Composing/IRegister.cs
@@ -2,17 +2,6 @@
namespace Umbraco.Core.Composing
{
- // Implementing:
- //
- // The register
- // - supports registering a service, even after some instances of other services have been created
- // - supports re-registering a service, as long as no instance of that service has been created
- // - throws when re-registering a service, and an instance of that service has been created
- //
- // - registers only one implementation of a nameless service, re-registering replaces the previous
- // registration - names are required to register multiple implementations - and getting an
- // IEnumerable of the service, nameless, returns them all
-
///
/// Defines a service register for Umbraco.
///
@@ -33,12 +22,6 @@ namespace Umbraco.Core.Composing
///
void Register(Type serviceType, Type implementingType, Lifetime lifetime = Lifetime.Transient);
- ///
- /// Registers a service with an implementation type, for a target.
- ///
- void RegisterFor(Type implementingType, Lifetime lifetime = Lifetime.Transient)
- where TService : class;
-
///
/// Registers a service with an implementation factory.
///
@@ -46,20 +29,32 @@ namespace Umbraco.Core.Composing
where TService : class;
///
- /// Registers a service with an implementation factory, for a target.
+ /// Registers a service with an implementing instance.
+ ///
+ void Register(Type serviceType, object instance);
+
+ ///
+ /// Registers a service for a target, as its own implementation.
+ ///
+ void RegisterFor(Lifetime lifetime = Lifetime.Transient)
+ where TService : class;
+
+ ///
+ /// Registers a service for a target, with an implementation type.
+ ///
+ void RegisterFor(Type implementingType, Lifetime lifetime = Lifetime.Transient)
+ where TService : class;
+
+ ///
+ /// Registers a service for a target, with an implementation factory.
///
void RegisterFor(Func factory, Lifetime lifetime = Lifetime.Transient)
where TService : class;
///
- /// Registers a service with an implementing instance.
+ /// Registers a service for a target, with an implementing instance.
///
- void RegisterInstance(Type serviceType, object instance);
-
- ///
- /// Registers a service with an implementing instance, for a target.
- ///
- void RegisterInstanceFor(TService instance)
+ void RegisterFor(TService instance)
where TService : class;
///
diff --git a/src/Umbraco.Core/Composing/LightInject/LightInjectContainer.cs b/src/Umbraco.Core/Composing/LightInject/LightInjectContainer.cs
index 4ccc0ba838..d8a554ee8c 100644
--- a/src/Umbraco.Core/Composing/LightInject/LightInjectContainer.cs
+++ b/src/Umbraco.Core/Composing/LightInject/LightInjectContainer.cs
@@ -145,9 +145,7 @@ namespace Umbraco.Core.Composing.LightInject
///
public void Register(Type serviceType, Lifetime lifetime = Lifetime.Transient)
- {
- Container.Register(serviceType, GetLifetime(lifetime));
- }
+ => Container.Register(serviceType, GetLifetime(lifetime));
///
public void Register(Type serviceType, Type implementingType, Lifetime lifetime = Lifetime.Transient)
@@ -167,13 +165,6 @@ namespace Umbraco.Core.Composing.LightInject
}
}
- ///
- public void RegisterFor(Type implementingType, Lifetime lifetime = Lifetime.Transient)
- where TService : class
- {
- Container.Register(typeof(TService), implementingType, GetTargetedServiceName(), GetLifetime(lifetime));
- }
-
///
public void Register(Func factory, Lifetime lifetime = Lifetime.Transient)
where TService : class
@@ -181,13 +172,36 @@ namespace Umbraco.Core.Composing.LightInject
Container.Register(f => factory(this), GetLifetime(lifetime));
}
+ ///
+ public void Register(Type serviceType, object instance)
+ => Container.RegisterInstance(serviceType, instance);
+
+ ///
+ public void RegisterFor(Lifetime lifetime = Lifetime.Transient)
+ where TService : class
+ => RegisterFor(typeof(TService), lifetime);
+
+ ///
+ public void RegisterFor(Type implementingType, Lifetime lifetime = Lifetime.Transient)
+ where TService : class
+ {
+ // note that there can only be one implementation or instance registered "for" a service
+ Container.Register(typeof(TService), implementingType, GetTargetedServiceName(), GetLifetime(lifetime));
+ }
+
///
public void RegisterFor(Func factory, Lifetime lifetime = Lifetime.Transient)
where TService : class
{
+ // note that there can only be one implementation or instance registered "for" a service
Container.Register(f => factory(this), GetTargetedServiceName(), GetLifetime(lifetime));
}
+ ///
+ public void RegisterFor(TService instance)
+ where TService : class
+ => Container.RegisterInstance(typeof(TService), instance, GetTargetedServiceName());
+
private ILifetime GetLifetime(Lifetime lifetime)
{
switch (lifetime)
@@ -205,15 +219,6 @@ namespace Umbraco.Core.Composing.LightInject
}
}
- ///
- public void RegisterInstance(Type serviceType, object instance)
- => Container.RegisterInstance(serviceType, instance);
-
- ///
- public void RegisterInstanceFor(TService instance)
- where TService : class
- => Container.RegisterInstance(typeof(TService), instance, GetTargetedServiceName());
-
///
public void RegisterAuto(Type serviceBaseType)
{
@@ -226,17 +231,6 @@ namespace Umbraco.Core.Composing.LightInject
}, null);
}
- // was the Light-Inject specific way of dealing with args, but we've replaced it with our own
- // beware! does NOT work on singletons, see https://github.com/seesharper/LightInject/issues/294
- //
- /////
- //public void RegisterConstructorDependency(Func factory)
- // => Container.RegisterConstructorDependency((f, x) => factory(this, x));
- //
- /////
- //public void RegisterConstructorDependency(Func factory)
- // => Container.RegisterConstructorDependency((f, x, a) => factory(this, x, a));
-
#endregion
#region Control
@@ -259,21 +253,14 @@ namespace Umbraco.Core.Composing.LightInject
private class AssemblyScanner : IAssemblyScanner
{
- //private readonly IAssemblyScanner _scanner;
-
- //public AssemblyScanner(IAssemblyScanner scanner)
- //{
- // _scanner = scanner;
- //}
-
public void Scan(Assembly assembly, IServiceRegistry serviceRegistry, Func lifetime, Func shouldRegister, Func serviceNameProvider)
{
- // nothing - we *could* scan non-Umbraco assemblies, though
+ // nothing - we don't want LightInject to scan
}
public void Scan(Assembly assembly, IServiceRegistry serviceRegistry)
{
- // nothing - we *could* scan non-Umbraco assemblies, though
+ // nothing - we don't want LightInject to scan
}
}
diff --git a/src/Umbraco.Core/Composing/LightInject/MixedLightInjectScopeManagerProvider.cs b/src/Umbraco.Core/Composing/LightInject/MixedLightInjectScopeManagerProvider.cs
index 470079c6c0..897c58dd43 100644
--- a/src/Umbraco.Core/Composing/LightInject/MixedLightInjectScopeManagerProvider.cs
+++ b/src/Umbraco.Core/Composing/LightInject/MixedLightInjectScopeManagerProvider.cs
@@ -13,6 +13,9 @@ namespace Umbraco.Core.Composing.LightInject
// of PerWebRequestScopeManagerProvider - but all delegates see is the mixed one - and therefore
// they can transition without issues.
//
+ // The PerWebRequestScopeManager maintains the scope in HttpContext and LightInject registers a
+ // module (PreApplicationStartMethod) which disposes it on EndRequest
+ //
// the mixed provider is installed in container.ConfigureUmbracoCore() and then,
// when doing eg container.EnableMvc() or anything that does container.EnablePerWebRequestScope()
// we need to take great care to preserve the mixed scope manager provider!
diff --git a/src/Umbraco.Core/Composing/RegisterExtensions.cs b/src/Umbraco.Core/Composing/RegisterExtensions.cs
index 9afa41e4b3..d1eacc0c0f 100644
--- a/src/Umbraco.Core/Composing/RegisterExtensions.cs
+++ b/src/Umbraco.Core/Composing/RegisterExtensions.cs
@@ -14,7 +14,7 @@
///
/// Registers a service with an implementation type, for a target.
///
- public static void RegisterFor(this IRegister register, Lifetime lifetime = Lifetime.Transient)
+ public static void RegisterFor(this IRegister register, Lifetime lifetime = Lifetime.Transient)
where TService : class
=> register.RegisterFor(typeof(TImplementing), lifetime);
@@ -28,9 +28,9 @@
///
/// Registers a service with an implementing instance.
///
- public static void RegisterInstance(this IRegister register, TService instance)
+ public static void Register(this IRegister register, TService instance)
where TService : class
- => register.RegisterInstance(typeof(TService), instance);
+ => register.Register(typeof(TService), instance);
///
/// Registers a base type for auto-registration.
diff --git a/src/Umbraco.Core/Configuration/Configs.cs b/src/Umbraco.Core/Configuration/Configs.cs
index 3dbbe5d4ff..51e1a327a0 100644
--- a/src/Umbraco.Core/Configuration/Configs.cs
+++ b/src/Umbraco.Core/Configuration/Configs.cs
@@ -100,7 +100,7 @@ namespace Umbraco.Core.Configuration
if (_registerings == null)
throw new InvalidOperationException("Configurations have already been registered.");
- register.RegisterInstance(this);
+ register.Register(this);
foreach (var registering in _registerings.Values)
registering(register);
diff --git a/src/Umbraco.Tests/Composing/ContainerConformingTests.cs b/src/Umbraco.Tests/Composing/ContainerConformingTests.cs
index 9585c98cb2..21ea961636 100644
--- a/src/Umbraco.Tests/Composing/ContainerConformingTests.cs
+++ b/src/Umbraco.Tests/Composing/ContainerConformingTests.cs
@@ -194,8 +194,8 @@ namespace Umbraco.Tests.Composing
var register = GetRegister();
// define two instances
- register.RegisterInstance(typeof(Thing1), new Thing1());
- register.RegisterInstance(typeof(Thing1), new Thing2());
+ register.Register(typeof(Thing1), new Thing1());
+ register.Register(typeof(Thing1), new Thing2());
var factory = register.CreateFactory();
@@ -212,8 +212,8 @@ namespace Umbraco.Tests.Composing
var register = GetRegister();
// define two instances
- register.RegisterInstance(typeof(IThing), new Thing1());
- register.RegisterInstance(typeof(IThing), new Thing2());
+ register.Register(typeof(IThing), new Thing1());
+ register.Register(typeof(IThing), new Thing2());
var factory = register.CreateFactory();
From e2fe1c82608244e3bb77596079f7884bff8beaaf Mon Sep 17 00:00:00 2001
From: Stephan
Date: Mon, 14 Jan 2019 15:01:24 +0100
Subject: [PATCH 65/84] Refactor IValueConnector for Deploy
---
src/Umbraco.Core/Deploy/IValueConnector.cs | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/src/Umbraco.Core/Deploy/IValueConnector.cs b/src/Umbraco.Core/Deploy/IValueConnector.cs
index 35304e3fde..92589ab6cf 100644
--- a/src/Umbraco.Core/Deploy/IValueConnector.cs
+++ b/src/Umbraco.Core/Deploy/IValueConnector.cs
@@ -17,19 +17,19 @@ namespace Umbraco.Core.Deploy
IEnumerable PropertyEditorAliases { get; }
///
- /// Gets the deploy property corresponding to a content property.
+ /// Gets the deploy property value corresponding to a content property value, and gather dependencies.
///
- /// The content property.
+ /// The content property value.
/// The content dependencies.
/// The deploy property value.
- string GetValue(Property property, ICollection dependencies);
+ string ToArtifact(object value, ICollection dependencies);
///
- /// Sets a content property value using a deploy property.
+ /// Gets the content property value corresponding to a deploy property value.
///
- /// The content item.
- /// The property alias.
/// The deploy property value.
- void SetValue(IContentBase content, string alias, string value);
+ /// The current content property value.
+ /// The content property value.
+ object FromArtifact(string value, object currentValue);
}
}
From 9ba3f4769056ed9889a2662ea1083b4ac59d0d7a Mon Sep 17 00:00:00 2001
From: Stephan
Date: Mon, 14 Jan 2019 15:55:18 +0100
Subject: [PATCH 66/84] Cleanup
---
.../Components/CompositionExtensions.cs | 16 ++++++++++++++++
.../Composing/Composers/FileSystemsComposer.cs | 4 ++--
src/Umbraco.Core/Composing/IRegister.cs | 16 ++++++++++++++++
3 files changed, 34 insertions(+), 2 deletions(-)
diff --git a/src/Umbraco.Core/Components/CompositionExtensions.cs b/src/Umbraco.Core/Components/CompositionExtensions.cs
index a4bc82cb4b..bb23e89b81 100644
--- a/src/Umbraco.Core/Components/CompositionExtensions.cs
+++ b/src/Umbraco.Core/Components/CompositionExtensions.cs
@@ -281,6 +281,22 @@ namespace Umbraco.Core.Components
composition.RegisterUnique(_ => helper);
}
+ ///
+ /// Sets the underlying media filesystem.
+ ///
+ /// A composition.
+ /// A filesystem factory.
+ public static void SetMediaFileSystem(this Composition composition, Func filesystemFactory)
+ => composition.RegisterUniqueFor(filesystemFactory);
+
+ ///
+ /// Sets the underlying media filesystem.
+ ///
+ /// A composition.
+ /// A filesystem factory.
+ public static void SetMediaFileSystem(this Composition composition, Func filesystemFactory)
+ => composition.RegisterUniqueFor(_ => filesystemFactory());
+
#endregion
}
}
diff --git a/src/Umbraco.Core/Composing/Composers/FileSystemsComposer.cs b/src/Umbraco.Core/Composing/Composers/FileSystemsComposer.cs
index ab4bd015de..4c598f27e4 100644
--- a/src/Umbraco.Core/Composing/Composers/FileSystemsComposer.cs
+++ b/src/Umbraco.Core/Composing/Composers/FileSystemsComposer.cs
@@ -88,9 +88,9 @@ namespace Umbraco.Core.Composing.Composers
composition.Register(factory => new SupportingFileSystems(factory), Lifetime.Singleton);
// register the IFileSystem supporting the IMediaFileSystem
- // this is the only thing that need to be overriden to change the supporting filesystem
+ // THIS IS THE ONLY THING THAT NEEDS TO CHANGE, IN ORDER TO REPLACE THE UNDERLYING FILESYSTEM
// and, SupportingFileSystem.For() returns the underlying filesystem
- composition.RegisterUniqueFor(_ => new PhysicalFileSystem("~/media"));
+ composition.SetMediaFileSystem(() => new PhysicalFileSystem("~/media"));
return composition;
}
diff --git a/src/Umbraco.Core/Composing/IRegister.cs b/src/Umbraco.Core/Composing/IRegister.cs
index 3e6aed67ee..cbf12f54a3 100644
--- a/src/Umbraco.Core/Composing/IRegister.cs
+++ b/src/Umbraco.Core/Composing/IRegister.cs
@@ -36,24 +36,40 @@ namespace Umbraco.Core.Composing
///
/// Registers a service for a target, as its own implementation.
///
+ ///
+ /// There can only be one implementation or instanced registered for a service and target;
+ /// what happens if many are registered is not specified.
+ ///
void RegisterFor(Lifetime lifetime = Lifetime.Transient)
where TService : class;
///
/// Registers a service for a target, with an implementation type.
///
+ ///
+ /// There can only be one implementation or instanced registered for a service and target;
+ /// what happens if many are registered is not specified.
+ ///
void RegisterFor(Type implementingType, Lifetime lifetime = Lifetime.Transient)
where TService : class;
///
/// Registers a service for a target, with an implementation factory.
///
+ ///
+ /// There can only be one implementation or instanced registered for a service and target;
+ /// what happens if many are registered is not specified.
+ ///
void RegisterFor(Func factory, Lifetime lifetime = Lifetime.Transient)
where TService : class;
///
/// Registers a service for a target, with an implementing instance.
///
+ ///
+ /// There can only be one implementation or instanced registered for a service and target;
+ /// what happens if many are registered is not specified.
+ ///
void RegisterFor(TService instance)
where TService : class;
From 4ad2505bea438f3e0d35c02cce350d7d58c13d93 Mon Sep 17 00:00:00 2001
From: Stephan
Date: Mon, 14 Jan 2019 15:48:24 +0100
Subject: [PATCH 67/84] Identify element types
---
.../Migrations/Upgrade/UmbracoPlan.cs | 1 +
.../V_8_0_0/AddContentTypeIsElementColumn.cs | 15 ++++++++++
src/Umbraco.Core/Models/ContentTypeBase.cs | 10 +++++++
.../Models/ContentTypeBaseExtensions.cs | 3 +-
src/Umbraco.Core/Models/IContentTypeBase.cs | 12 +++++++-
.../PublishedContent/PublishedItemType.cs | 7 ++++-
.../Persistence/Dtos/ContentTypeDto.cs | 4 +++
.../Factories/ContentTypeFactory.cs | 2 ++
.../Persistence/Mappers/ContentTypeMapper.cs | 1 +
.../Persistence/Mappers/MediaTypeMapper.cs | 1 +
.../Persistence/Mappers/MemberTypeMapper.cs | 1 +
.../Implement/ContentTypeRepositoryBase.cs | 6 ++--
.../Services/EntityXmlSerializer.cs | 3 +-
.../Services/Implement/PackagingService.cs | 4 +++
src/Umbraco.Core/Umbraco.Core.csproj | 1 +
.../PublishedContent/PublishedContentTests.cs | 1 -
.../Services/ContentTypeServiceTests.cs | 30 +++++++++++++++++++
.../ContentEditing/ContentItemDisplay.cs | 8 ++++-
.../Models/Mapping/ContentMapperProfile.cs | 5 ++--
19 files changed, 105 insertions(+), 10 deletions(-)
create mode 100644 src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/AddContentTypeIsElementColumn.cs
diff --git a/src/Umbraco.Core/Migrations/Upgrade/UmbracoPlan.cs b/src/Umbraco.Core/Migrations/Upgrade/UmbracoPlan.cs
index b469c02a3c..9ec970f1fe 100644
--- a/src/Umbraco.Core/Migrations/Upgrade/UmbracoPlan.cs
+++ b/src/Umbraco.Core/Migrations/Upgrade/UmbracoPlan.cs
@@ -121,6 +121,7 @@ namespace Umbraco.Core.Migrations.Upgrade
To("{648A2D5F-7467-48F8-B309-E99CEEE00E2A}"); // fixed version
To("{C39BF2A7-1454-4047-BBFE-89E40F66ED63}");
To("{64EBCE53-E1F0-463A-B40B-E98EFCCA8AE2}");
+ To("{0009109C-A0B8-4F3F-8FEB-C137BBDDA268}");
//FINAL
diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/AddContentTypeIsElementColumn.cs b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/AddContentTypeIsElementColumn.cs
new file mode 100644
index 0000000000..1df11a3e99
--- /dev/null
+++ b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/AddContentTypeIsElementColumn.cs
@@ -0,0 +1,15 @@
+using Umbraco.Core.Persistence.Dtos;
+
+namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
+{
+ public class AddContentTypeIsElementColumn : MigrationBase
+ {
+ public AddContentTypeIsElementColumn(IMigrationContext context) : base(context)
+ { }
+
+ public override void Migrate()
+ {
+ AddColumn("isElement");
+ }
+ }
+}
diff --git a/src/Umbraco.Core/Models/ContentTypeBase.cs b/src/Umbraco.Core/Models/ContentTypeBase.cs
index 88b1179f6d..b6ea9f50a0 100644
--- a/src/Umbraco.Core/Models/ContentTypeBase.cs
+++ b/src/Umbraco.Core/Models/ContentTypeBase.cs
@@ -26,6 +26,7 @@ namespace Umbraco.Core.Models
private string _thumbnail = "folder.png";
private bool _allowedAsRoot; // note: only one that's not 'pure element type'
private bool _isContainer;
+ private bool _isElement;
private PropertyGroupCollection _propertyGroups;
private PropertyTypeCollection _noGroupPropertyTypes;
private IEnumerable _allowedContentTypes;
@@ -90,6 +91,7 @@ namespace Umbraco.Core.Models
public readonly PropertyInfo IconSelector = ExpressionHelper.GetPropertyInfo(x => x.Icon);
public readonly PropertyInfo ThumbnailSelector = ExpressionHelper.GetPropertyInfo(x => x.Thumbnail);
public readonly PropertyInfo AllowedAsRootSelector = ExpressionHelper.GetPropertyInfo(x => x.AllowedAsRoot);
+ public readonly PropertyInfo IsElementSelector = ExpressionHelper.GetPropertyInfo(x => x.IsElement);
public readonly PropertyInfo IsContainerSelector = ExpressionHelper.GetPropertyInfo(x => x.IsContainer);
public readonly PropertyInfo AllowedContentTypesSelector = ExpressionHelper.GetPropertyInfo>(x => x.AllowedContentTypes);
public readonly PropertyInfo PropertyGroupsSelector = ExpressionHelper.GetPropertyInfo(x => x.PropertyGroups);
@@ -180,6 +182,14 @@ namespace Umbraco.Core.Models
set => SetPropertyValueAndDetectChanges(value, ref _isContainer, Ps.Value.IsContainerSelector);
}
+ ///
+ [DataMember]
+ public bool IsElement
+ {
+ get => _isElement;
+ set => SetPropertyValueAndDetectChanges(value, ref _isElement, Ps.Value.IsElementSelector);
+ }
+
///
/// Gets or sets a list of integer Ids for allowed ContentTypes
///
diff --git a/src/Umbraco.Core/Models/ContentTypeBaseExtensions.cs b/src/Umbraco.Core/Models/ContentTypeBaseExtensions.cs
index 8af48bb881..adbc3de54f 100644
--- a/src/Umbraco.Core/Models/ContentTypeBaseExtensions.cs
+++ b/src/Umbraco.Core/Models/ContentTypeBaseExtensions.cs
@@ -15,7 +15,8 @@ namespace Umbraco.Core.Models
{
var type = contentType.GetType();
var itemType = PublishedItemType.Unknown;
- if (typeof(IContentType).IsAssignableFrom(type)) itemType = PublishedItemType.Content;
+ if (contentType.IsElement) itemType = PublishedItemType.Element;
+ else if (typeof(IContentType).IsAssignableFrom(type)) itemType = PublishedItemType.Content;
else if (typeof(IMediaType).IsAssignableFrom(type)) itemType = PublishedItemType.Media;
else if (typeof(IMemberType).IsAssignableFrom(type)) itemType = PublishedItemType.Member;
return itemType;
diff --git a/src/Umbraco.Core/Models/IContentTypeBase.cs b/src/Umbraco.Core/Models/IContentTypeBase.cs
index a1d4aee02f..787e347b37 100644
--- a/src/Umbraco.Core/Models/IContentTypeBase.cs
+++ b/src/Umbraco.Core/Models/IContentTypeBase.cs
@@ -25,7 +25,7 @@ namespace Umbraco.Core.Models
/// the icon (eg. icon-home ) along with an optional CSS class name representing the
/// color (eg. icon-blue ). Put together, the value for this scenario would be
/// icon-home color-blue .
- ///
+ ///
/// If a class name for the color isn't specified, the icon color will default to black.
///
string Icon { get; set; }
@@ -48,6 +48,16 @@ namespace Umbraco.Core.Models
///
bool IsContainer { get; set; }
+ ///
+ /// Gets or sets a value indicating whether this content type is for an element.
+ ///
+ ///
+ /// By default a content type is for a true media, member or document, but
+ /// it can also be for an element, ie a subset that can for instance be used in
+ /// nested content.
+ ///
+ bool IsElement { get; set; }
+
///
/// Gets or sets the content variation of the content type.
///
diff --git a/src/Umbraco.Core/Models/PublishedContent/PublishedItemType.cs b/src/Umbraco.Core/Models/PublishedContent/PublishedItemType.cs
index e55fe66945..42e9c9538d 100644
--- a/src/Umbraco.Core/Models/PublishedContent/PublishedItemType.cs
+++ b/src/Umbraco.Core/Models/PublishedContent/PublishedItemType.cs
@@ -4,13 +4,18 @@
/// The type of published element.
///
/// Can be a simple element, or a document, a media, a member.
- public enum PublishedItemType // fixme - need to rename to PublishedElementType but then conflicts?
+ public enum PublishedItemType
{
///
/// Unknown.
///
Unknown = 0,
+ ///
+ /// An element.
+ ///
+ Element,
+
///
/// A document.
///
diff --git a/src/Umbraco.Core/Persistence/Dtos/ContentTypeDto.cs b/src/Umbraco.Core/Persistence/Dtos/ContentTypeDto.cs
index d930abc54c..4f3a67aa91 100644
--- a/src/Umbraco.Core/Persistence/Dtos/ContentTypeDto.cs
+++ b/src/Umbraco.Core/Persistence/Dtos/ContentTypeDto.cs
@@ -41,6 +41,10 @@ namespace Umbraco.Core.Persistence.Dtos
[Constraint(Default = "0")]
public bool IsContainer { get; set; }
+ [Column("isElement")]
+ [Constraint(Default = "0")]
+ public bool IsElement { get; set; }
+
[Column("allowAtRoot")]
[Constraint(Default = "0")]
public bool AllowAtRoot { get; set; }
diff --git a/src/Umbraco.Core/Persistence/Factories/ContentTypeFactory.cs b/src/Umbraco.Core/Persistence/Factories/ContentTypeFactory.cs
index 38a1aa2aab..7a04a6d0d9 100644
--- a/src/Umbraco.Core/Persistence/Factories/ContentTypeFactory.cs
+++ b/src/Umbraco.Core/Persistence/Factories/ContentTypeFactory.cs
@@ -107,6 +107,7 @@ namespace Umbraco.Core.Persistence.Factories
entity.CreatorId = dto.NodeDto.UserId ?? Constants.Security.UnknownUserId;
entity.AllowedAsRoot = dto.AllowAtRoot;
entity.IsContainer = dto.IsContainer;
+ entity.IsElement = dto.IsElement;
entity.Trashed = dto.NodeDto.Trashed;
entity.Variations = (ContentVariation) dto.Variations;
}
@@ -132,6 +133,7 @@ namespace Umbraco.Core.Persistence.Factories
NodeId = entity.Id,
AllowAtRoot = entity.AllowedAsRoot,
IsContainer = entity.IsContainer,
+ IsElement = entity.IsElement,
Variations = (byte) entity.Variations,
NodeDto = BuildNodeDto(entity, nodeObjectType)
};
diff --git a/src/Umbraco.Core/Persistence/Mappers/ContentTypeMapper.cs b/src/Umbraco.Core/Persistence/Mappers/ContentTypeMapper.cs
index c692a75474..a24963bace 100644
--- a/src/Umbraco.Core/Persistence/Mappers/ContentTypeMapper.cs
+++ b/src/Umbraco.Core/Persistence/Mappers/ContentTypeMapper.cs
@@ -35,6 +35,7 @@ namespace Umbraco.Core.Persistence.Mappers
CacheMap(src => src.Description, dto => dto.Description);
CacheMap(src => src.Icon, dto => dto.Icon);
CacheMap(src => src.IsContainer, dto => dto.IsContainer);
+ CacheMap(src => src.IsElement, dto => dto.IsElement);
CacheMap(src => src.Thumbnail, dto => dto.Thumbnail);
}
}
diff --git a/src/Umbraco.Core/Persistence/Mappers/MediaTypeMapper.cs b/src/Umbraco.Core/Persistence/Mappers/MediaTypeMapper.cs
index 3f5a6e24bc..6cf83bc7aa 100644
--- a/src/Umbraco.Core/Persistence/Mappers/MediaTypeMapper.cs
+++ b/src/Umbraco.Core/Persistence/Mappers/MediaTypeMapper.cs
@@ -35,6 +35,7 @@ namespace Umbraco.Core.Persistence.Mappers
CacheMap(src => src.Description, dto => dto.Description);
CacheMap(src => src.Icon, dto => dto.Icon);
CacheMap(src => src.IsContainer, dto => dto.IsContainer);
+ CacheMap(src => src.IsElement, dto => dto.IsElement);
CacheMap(src => src.Thumbnail, dto => dto.Thumbnail);
}
}
diff --git a/src/Umbraco.Core/Persistence/Mappers/MemberTypeMapper.cs b/src/Umbraco.Core/Persistence/Mappers/MemberTypeMapper.cs
index 28dc19171f..9a4e4ec040 100644
--- a/src/Umbraco.Core/Persistence/Mappers/MemberTypeMapper.cs
+++ b/src/Umbraco.Core/Persistence/Mappers/MemberTypeMapper.cs
@@ -35,6 +35,7 @@ namespace Umbraco.Core.Persistence.Mappers
CacheMap(src => src.Description, dto => dto.Description);
CacheMap(src => src.Icon, dto => dto.Icon);
CacheMap(src => src.IsContainer, dto => dto.IsContainer);
+ CacheMap(src => src.IsElement, dto => dto.IsElement);
CacheMap(src => src.Thumbnail, dto => dto.Thumbnail);
}
}
diff --git a/src/Umbraco.Core/Persistence/Repositories/Implement/ContentTypeRepositoryBase.cs b/src/Umbraco.Core/Persistence/Repositories/Implement/ContentTypeRepositoryBase.cs
index 662254d1ee..683df047f8 100644
--- a/src/Umbraco.Core/Persistence/Repositories/Implement/ContentTypeRepositoryBase.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/Implement/ContentTypeRepositoryBase.cs
@@ -1283,7 +1283,7 @@ AND umbracoNode.id <> @id",
if (db == null) throw new ArgumentNullException(nameof(db));
var sql = @"SELECT cmsContentType.pk as ctPk, cmsContentType.alias as ctAlias, cmsContentType.allowAtRoot as ctAllowAtRoot, cmsContentType.description as ctDesc, cmsContentType.variations as ctVariations,
- cmsContentType.icon as ctIcon, cmsContentType.isContainer as ctIsContainer, cmsContentType.nodeId as ctId, cmsContentType.thumbnail as ctThumb,
+ cmsContentType.icon as ctIcon, cmsContentType.isContainer as ctIsContainer, cmsContentType.IsElement as ctIsElement, cmsContentType.nodeId as ctId, cmsContentType.thumbnail as ctThumb,
AllowedTypes.AllowedId as ctaAllowedId, AllowedTypes.SortOrder as ctaSortOrder, AllowedTypes.alias as ctaAlias,
ParentTypes.parentContentTypeId as chtParentId, ParentTypes.parentContentTypeKey as chtParentKey,
umbracoNode.createDate as nCreateDate, umbracoNode." + sqlSyntax.GetQuotedColumnName("level") + @" as nLevel, umbracoNode.nodeObjectType as nObjectType, umbracoNode.nodeUser as nUser,
@@ -1384,6 +1384,7 @@ AND umbracoNode.id <> @id",
Description = currCt.ctDesc,
Icon = currCt.ctIcon,
IsContainer = currCt.ctIsContainer,
+ IsElement = currCt.ctIsElement,
NodeId = currCt.ctId,
PrimaryKey = currCt.ctPk,
Thumbnail = currCt.ctThumb,
@@ -1422,7 +1423,7 @@ AND umbracoNode.id <> @id",
var sql = @"SELECT cmsDocumentType.IsDefault as dtIsDefault, cmsDocumentType.templateNodeId as dtTemplateId,
cmsContentType.pk as ctPk, cmsContentType.alias as ctAlias, cmsContentType.allowAtRoot as ctAllowAtRoot, cmsContentType.description as ctDesc, cmsContentType.variations as ctVariations,
- cmsContentType.icon as ctIcon, cmsContentType.isContainer as ctIsContainer, cmsContentType.nodeId as ctId, cmsContentType.thumbnail as ctThumb,
+ cmsContentType.icon as ctIcon, cmsContentType.isContainer as ctIsContainer, cmsContentType.IsElement as ctIsElement, cmsContentType.nodeId as ctId, cmsContentType.thumbnail as ctThumb,
AllowedTypes.AllowedId as ctaAllowedId, AllowedTypes.SortOrder as ctaSortOrder, AllowedTypes.alias as ctaAlias,
ParentTypes.parentContentTypeId as chtParentId,ParentTypes.parentContentTypeKey as chtParentKey,
umbracoNode.createDate as nCreateDate, umbracoNode." + sqlSyntax.GetQuotedColumnName("level") + @" as nLevel, umbracoNode.nodeObjectType as nObjectType, umbracoNode.nodeUser as nUser,
@@ -1559,6 +1560,7 @@ AND umbracoNode.id <> @id",
Description = currCt.ctDesc,
Icon = currCt.ctIcon,
IsContainer = currCt.ctIsContainer,
+ IsElement = currCt.ctIsElement,
NodeId = currCt.ctId,
PrimaryKey = currCt.ctPk,
Thumbnail = currCt.ctThumb,
diff --git a/src/Umbraco.Core/Services/EntityXmlSerializer.cs b/src/Umbraco.Core/Services/EntityXmlSerializer.cs
index d938e032a8..38d5471bb7 100644
--- a/src/Umbraco.Core/Services/EntityXmlSerializer.cs
+++ b/src/Umbraco.Core/Services/EntityXmlSerializer.cs
@@ -337,7 +337,8 @@ namespace Umbraco.Core.Services
new XElement("Thumbnail", contentType.Thumbnail),
new XElement("Description", contentType.Description),
new XElement("AllowAtRoot", contentType.AllowedAsRoot.ToString()),
- new XElement("IsListView", contentType.IsContainer.ToString()));
+ new XElement("IsListView", contentType.IsContainer.ToString()),
+ new XElement("IsElement", contentType.IsElement.ToString()));
var masterContentType = contentType.ContentTypeComposition.FirstOrDefault(x => x.Id == contentType.ParentId);
if(masterContentType != null)
diff --git a/src/Umbraco.Core/Services/Implement/PackagingService.cs b/src/Umbraco.Core/Services/Implement/PackagingService.cs
index 106d2b9f12..8f6c287cf1 100644
--- a/src/Umbraco.Core/Services/Implement/PackagingService.cs
+++ b/src/Umbraco.Core/Services/Implement/PackagingService.cs
@@ -578,6 +578,10 @@ namespace Umbraco.Core.Services.Implement
if (isListView != null)
contentType.IsContainer = isListView.Value.InvariantEquals("true");
+ var isElement = infoElement.Element("IsElement");
+ if (isListView != null)
+ contentType.IsElement = isElement.Value.InvariantEquals("true");
+
//Name of the master corresponds to the parent and we need to ensure that the Parent Id is set
var masterElement = infoElement.Element("Master");
if (masterElement != null)
diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj
index a01bbf1746..33858c0f91 100755
--- a/src/Umbraco.Core/Umbraco.Core.csproj
+++ b/src/Umbraco.Core/Umbraco.Core.csproj
@@ -375,6 +375,7 @@
+
diff --git a/src/Umbraco.Tests/PublishedContent/PublishedContentTests.cs b/src/Umbraco.Tests/PublishedContent/PublishedContentTests.cs
index 914956dce1..ab65ac82b1 100644
--- a/src/Umbraco.Tests/PublishedContent/PublishedContentTests.cs
+++ b/src/Umbraco.Tests/PublishedContent/PublishedContentTests.cs
@@ -233,7 +233,6 @@ namespace Umbraco.Tests.PublishedContent
}
[Test]
- [Ignore("Fails as long as PublishedContentModel is internal.")] // fixme
public void Is_Last_From_Where_Filter2()
{
var doc = GetNode(1173);
diff --git a/src/Umbraco.Tests/Services/ContentTypeServiceTests.cs b/src/Umbraco.Tests/Services/ContentTypeServiceTests.cs
index b1a8fa26a8..8dc8a2b45c 100644
--- a/src/Umbraco.Tests/Services/ContentTypeServiceTests.cs
+++ b/src/Umbraco.Tests/Services/ContentTypeServiceTests.cs
@@ -22,6 +22,36 @@ namespace Umbraco.Tests.Services
[UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerTest, PublishedRepositoryEvents = true)]
public class ContentTypeServiceTests : TestWithSomeContentBase
{
+ [Test]
+ public void CanSaveAndGetIsElement()
+ {
+ //create content type with a property type that varies by culture
+ IContentType contentType = MockedContentTypes.CreateBasicContentType();
+ contentType.Variations = ContentVariation.Nothing;
+ var contentCollection = new PropertyTypeCollection(true);
+ contentCollection.Add(new PropertyType("test", ValueStorageType.Ntext)
+ {
+ Alias = "title",
+ Name = "Title",
+ Description = "",
+ Mandatory = false,
+ SortOrder = 1,
+ DataTypeId = -88,
+ Variations = ContentVariation.Nothing
+ });
+ contentType.PropertyGroups.Add(new PropertyGroup(contentCollection) { Name = "Content", SortOrder = 1 });
+ ServiceContext.ContentTypeService.Save(contentType);
+
+ contentType = ServiceContext.ContentTypeService.Get(contentType.Id);
+ Assert.IsFalse(contentType.IsElement);
+
+ contentType.IsElement = true;
+ ServiceContext.ContentTypeService.Save(contentType);
+
+ contentType = ServiceContext.ContentTypeService.Get(contentType.Id);
+ Assert.IsTrue(contentType.IsElement);
+ }
+
[Test]
public void Change_Content_Type_Variation_Clears_Redirects()
{
diff --git a/src/Umbraco.Web/Models/ContentEditing/ContentItemDisplay.cs b/src/Umbraco.Web/Models/ContentEditing/ContentItemDisplay.cs
index 4908025351..80358bfc7a 100644
--- a/src/Umbraco.Web/Models/ContentEditing/ContentItemDisplay.cs
+++ b/src/Umbraco.Web/Models/ContentEditing/ContentItemDisplay.cs
@@ -86,6 +86,12 @@ namespace Umbraco.Web.Models.ContentEditing
[DataMember(Name = "isContainer")]
public bool IsContainer { get; set; }
+ ///
+ /// Indicates if the content is configured as an element
+ ///
+ [DataMember(Name = "isElement")]
+ public bool IsElement { get; set; }
+
///
/// Property indicating if this item is part of a list view parent
///
@@ -117,7 +123,7 @@ namespace Umbraco.Web.Models.ContentEditing
///
[DataMember(Name = "updateDate")]
public DateTime UpdateDate { get; set; }
-
+
[DataMember(Name = "template")]
public string TemplateAlias { get; set; }
diff --git a/src/Umbraco.Web/Models/Mapping/ContentMapperProfile.cs b/src/Umbraco.Web/Models/Mapping/ContentMapperProfile.cs
index 6de3bdc02c..1caf81a1eb 100644
--- a/src/Umbraco.Web/Models/Mapping/ContentMapperProfile.cs
+++ b/src/Umbraco.Web/Models/Mapping/ContentMapperProfile.cs
@@ -46,6 +46,7 @@ namespace Umbraco.Web.Models.Mapping
.ForMember(dest => dest.ContentTypeAlias, opt => opt.MapFrom(src => src.ContentType.Alias))
.ForMember(dest => dest.ContentTypeName, opt => opt.MapFrom(src => src.ContentType.Name))
.ForMember(dest => dest.IsContainer, opt => opt.MapFrom(src => src.ContentType.IsContainer))
+ .ForMember(dest => dest.IsElement, opt => opt.MapFrom(src => src.ContentType.IsElement))
.ForMember(dest => dest.IsBlueprint, opt => opt.MapFrom(src => src.Blueprint))
.ForMember(dest => dest.IsChildOfListView, opt => opt.ResolveUsing(childOfListViewResolver))
.ForMember(dest => dest.Trashed, opt => opt.MapFrom(src => src.Trashed))
@@ -59,7 +60,7 @@ namespace Umbraco.Web.Models.Mapping
.ForMember(dest => dest.AllowedTemplates, opt =>
opt.MapFrom(content => content.ContentType.AllowedTemplates
.Where(t => t.Alias.IsNullOrWhiteSpace() == false && t.Name.IsNullOrWhiteSpace() == false)
- .ToDictionary(t => t.Alias, t => t.Name)))
+ .ToDictionary(t => t.Alias, t => t.Name)))
.ForMember(dest => dest.AllowedActions, opt => opt.ResolveUsing(src => actionButtonsResolver.Resolve(src)))
.ForMember(dest => dest.AdditionalData, opt => opt.Ignore());
@@ -140,5 +141,5 @@ namespace Umbraco.Web.Models.Mapping
return source.CultureInfos.TryGetValue(culture, out var name) && !name.Name.IsNullOrWhiteSpace() ? name.Name : $"(({source.Name}))";
}
}
- }
+ }
}
From 9bc047c03f50e4795fc0d13b71af8218889d1e5a Mon Sep 17 00:00:00 2001
From: Robert
Date: Tue, 15 Jan 2019 10:17:26 +0100
Subject: [PATCH 68/84] Adding code to re-validate on value change
---
.../directives/components/tags/umbtagseditor.directive.js | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/tags/umbtagseditor.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/tags/umbtagseditor.directive.js
index fea7528d5b..125f5ffb65 100644
--- a/src/Umbraco.Web.UI.Client/src/common/directives/components/tags/umbtagseditor.directive.js
+++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/tags/umbtagseditor.directive.js
@@ -182,6 +182,9 @@
else {
vm.onValueChanged({ value: [] });
}
+
+ //this is required to re-validate
+ $scope.propertyForm.tagCount.$setViewValue($scope.model.value.length);
}
/**
@@ -189,7 +192,7 @@
*/
function validateMandatory() {
return {
- isValid: !vm.validation.mandatory || (vm.viewModel != null && vm.viewModel.length > 0) || (vm.value != null && vm.value.length > 0),
+ isValid: !vm.validation.mandatory || (vm.viewModel != null && vm.viewModel.length > 0),
errorMsg: "Value cannot be empty",
errorKey: "required"
};
From 0092cac394037f1ec2696718954e6e4be4f1d90a Mon Sep 17 00:00:00 2001
From: Robert
Date: Tue, 15 Jan 2019 10:31:12 +0100
Subject: [PATCH 69/84] DRY
---
.../components/tags/umbtagseditor.directive.js | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/tags/umbtagseditor.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/tags/umbtagseditor.directive.js
index 125f5ffb65..92c9d57ee8 100644
--- a/src/Umbraco.Web.UI.Client/src/common/directives/components/tags/umbtagseditor.directive.js
+++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/tags/umbtagseditor.directive.js
@@ -130,8 +130,7 @@
if (!changes.value.isFirstChange() && changes.value.currentValue !== changes.value.previousValue) {
configureViewModel();
- //this is required to re-validate
- vm.tagEditorForm.tagCount.$setViewValue(vm.viewModel.length);
+ reValidate()
}
}
@@ -183,8 +182,7 @@
vm.onValueChanged({ value: [] });
}
- //this is required to re-validate
- $scope.propertyForm.tagCount.$setViewValue($scope.model.value.length);
+ reValidate();
}
/**
@@ -273,8 +271,12 @@
return ($.inArray(suggestion.value, vm.viewModel) === -1);
});
}
-
-
+
+ function reValidate() {
+ //this is required to re-validate
+ vm.tagEditorForm.tagCount.$setViewValue(vm.viewModel.length);
+ {
+
}
})();
From ba38b67b9d4cdd58d33a729b62181700b3d51dbe Mon Sep 17 00:00:00 2001
From: Stephan
Date: Tue, 15 Jan 2019 11:30:30 +0100
Subject: [PATCH 70/84] Support IContentType.IsElement
---
.../services/umbdataformatter.service.js | 18 +++++++--------
.../permissions/permissions.controller.js | 22 +++++++------------
.../views/permissions/permissions.html | 20 +++++++++++++++--
src/Umbraco.Web.UI/Umbraco/config/lang/en.xml | 2 ++
.../Umbraco/config/lang/en_us.xml | 2 ++
.../ContentTypeCompositionDisplay.cs | 4 ++++
.../Models/ContentEditing/ContentTypeSave.cs | 3 +++
7 files changed, 46 insertions(+), 25 deletions(-)
diff --git a/src/Umbraco.Web.UI.Client/src/common/services/umbdataformatter.service.js b/src/Umbraco.Web.UI.Client/src/common/services/umbdataformatter.service.js
index e31742e660..1e6fc5d643 100644
--- a/src/Umbraco.Web.UI.Client/src/common/services/umbdataformatter.service.js
+++ b/src/Umbraco.Web.UI.Client/src/common/services/umbdataformatter.service.js
@@ -64,7 +64,7 @@
var saveModel = _.pick(displayModel,
'compositeContentTypes', 'isContainer', 'allowAsRoot', 'allowedTemplates', 'allowedContentTypes',
'alias', 'description', 'thumbnail', 'name', 'id', 'icon', 'trashed',
- 'key', 'parentId', 'alias', 'path', 'allowCultureVariant');
+ 'key', 'parentId', 'alias', 'path', 'allowCultureVariant', 'isElement');
//TODO: Map these
saveModel.allowedTemplates = _.map(displayModel.allowedTemplates, function (t) { return t.alias; });
@@ -262,7 +262,7 @@
saveModel[props[m]] = startId.id;
}
- saveModel.parentId = -1;
+ saveModel.parentId = -1;
return saveModel;
},
@@ -293,7 +293,7 @@
});
saveModel.email = propEmail.value.trim();
saveModel.username = propLogin.value.trim();
-
+
saveModel.password = this.formatChangePasswordModel(propPass.value);
var selectedGroups = [];
@@ -336,7 +336,7 @@
/** formats the display model used to display the media to the model used to save the media */
formatMediaPostData: function (displayModel, action) {
- //NOTE: the display model inherits from the save model so we can in theory just post up the display model but
+ //NOTE: the display model inherits from the save model so we can in theory just post up the display model but
// we don't want to post all of the data as it is unecessary.
var saveModel = {
id: displayModel.id,
@@ -354,7 +354,7 @@
/** formats the display model used to display the content to the model used to save the content */
formatContentPostData: function (displayModel, action) {
- //NOTE: the display model inherits from the save model so we can in theory just post up the display model but
+ //NOTE: the display model inherits from the save model so we can in theory just post up the display model but
// we don't want to post all of the data as it is unecessary.
var saveModel = {
id: displayModel.id,
@@ -379,7 +379,7 @@
var propExpireDate = displayModel.removeDate;
var propReleaseDate = displayModel.releaseDate;
var propTemplate = displayModel.template;
-
+
saveModel.expireDate = propExpireDate ? propExpireDate : null;
saveModel.releaseDate = propReleaseDate ? propReleaseDate : null;
saveModel.templateAlias = propTemplate ? propTemplate : null;
@@ -389,8 +389,8 @@
/**
* This formats the server GET response for a content display item
- * @param {} displayModel
- * @returns {}
+ * @param {} displayModel
+ * @returns {}
*/
formatContentGetData: function(displayModel) {
@@ -418,7 +418,7 @@
}
});
});
-
+
//now assign this same invariant property instance to the same index of the other variants property array
for (var j = 1; j < displayModel.variants.length; j++) {
diff --git a/src/Umbraco.Web.UI.Client/src/views/documenttypes/views/permissions/permissions.controller.js b/src/Umbraco.Web.UI.Client/src/views/documenttypes/views/permissions/permissions.controller.js
index 4a7a870618..317fe094ae 100644
--- a/src/Umbraco.Web.UI.Client/src/views/documenttypes/views/permissions/permissions.controller.js
+++ b/src/Umbraco.Web.UI.Client/src/views/documenttypes/views/permissions/permissions.controller.js
@@ -25,6 +25,7 @@
vm.removeChild = removeChild;
vm.toggleAllowAsRoot = toggleAllowAsRoot;
vm.toggleAllowCultureVariants = toggleAllowCultureVariants;
+ vm.toggleIsElement = toggleIsElement;
/* ---------- INIT ---------- */
@@ -84,25 +85,18 @@
$scope.model.allowedContentTypes.splice(selectedChildIndex, 1);
}
- /**
- * Toggle the $scope.model.allowAsRoot value to either true or false
- */
- function toggleAllowAsRoot(){
- if($scope.model.allowAsRoot){
- $scope.model.allowAsRoot = false;
- return;
- }
+ // note: "safe toggling" here ie handling cases where the value is undefined, etc
- $scope.model.allowAsRoot = true;
+ function toggleAllowAsRoot() {
+ $scope.model.allowAsRoot = $scope.model.allowAsRoot ? false : true;
}
function toggleAllowCultureVariants() {
- if ($scope.model.allowCultureVariant) {
- $scope.model.allowCultureVariant = false;
- return;
- }
+ $scope.model.allowCultureVariant = $scope.model.allowCultureVariant ? false : true;
+ }
- $scope.model.allowCultureVariant = true;
+ function toggleIsElement() {
+ $scope.model.isElement = $scope.model.isElement ? false : true;
}
}
diff --git a/src/Umbraco.Web.UI.Client/src/views/documenttypes/views/permissions/permissions.html b/src/Umbraco.Web.UI.Client/src/views/documenttypes/views/permissions/permissions.html
index ec1e528f8c..0d74c655d7 100644
--- a/src/Umbraco.Web.UI.Client/src/views/documenttypes/views/permissions/permissions.html
+++ b/src/Umbraco.Web.UI.Client/src/views/documenttypes/views/permissions/permissions.html
@@ -53,9 +53,25 @@
hotkey="alt+shift+v">
-
+
-
+
+
+
diff --git a/src/Umbraco.Web.UI/Umbraco/config/lang/en.xml b/src/Umbraco.Web.UI/Umbraco/config/lang/en.xml
index 386d3af518..987203442a 100644
--- a/src/Umbraco.Web.UI/Umbraco/config/lang/en.xml
+++ b/src/Umbraco.Web.UI/Umbraco/config/lang/en.xml
@@ -1518,6 +1518,8 @@ To manage your website, simply open the Umbraco back office and start adding con
Allow varying by culture
Allow editors to create content of this type in different languages
Allow varying by culture
+ Is an Element type
+ An Element type is meant to be used for instance in Nested Content, and not in the tree
Building models
diff --git a/src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml b/src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml
index 5de373f571..1860d3afc9 100644
--- a/src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml
+++ b/src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml
@@ -1559,6 +1559,8 @@ To manage your website, simply open the Umbraco back office and start adding con
Allow varying by culture
Allow editors to create content of this type in different languages
Allow varying by culture
+ Is an Element type
+ An Element type is meant to be used for instance in Nested Content, and not in the tree
Add language
diff --git a/src/Umbraco.Web/Models/ContentEditing/ContentTypeCompositionDisplay.cs b/src/Umbraco.Web/Models/ContentEditing/ContentTypeCompositionDisplay.cs
index 7211ddbf61..e5e74c2749 100644
--- a/src/Umbraco.Web/Models/ContentEditing/ContentTypeCompositionDisplay.cs
+++ b/src/Umbraco.Web/Models/ContentEditing/ContentTypeCompositionDisplay.cs
@@ -26,6 +26,10 @@ namespace Umbraco.Web.Models.ContentEditing
[DataMember(Name = "isContainer")]
public bool IsContainer { get; set; }
+ //Element
+ [DataMember(Name = "isElement")]
+ public bool IsElement { get; set; }
+
[DataMember(Name = "listViewEditorName")]
[ReadOnly(true)]
public string ListViewEditorName { get; set; }
diff --git a/src/Umbraco.Web/Models/ContentEditing/ContentTypeSave.cs b/src/Umbraco.Web/Models/ContentEditing/ContentTypeSave.cs
index c2ec70d3dc..b1d24c5fd2 100644
--- a/src/Umbraco.Web/Models/ContentEditing/ContentTypeSave.cs
+++ b/src/Umbraco.Web/Models/ContentEditing/ContentTypeSave.cs
@@ -25,6 +25,9 @@ namespace Umbraco.Web.Models.ContentEditing
[DataMember(Name = "isContainer")]
public bool IsContainer { get; set; }
+ [DataMember(Name = "isElement")]
+ public bool IsElement { get; set; }
+
[DataMember(Name = "allowAsRoot")]
public bool AllowAsRoot { get; set; }
From 5b1ca92184fa9962a7306f0db09ac36c37d5f777 Mon Sep 17 00:00:00 2001
From: Bjarke Berg
Date: Tue, 15 Jan 2019 12:12:35 +0100
Subject: [PATCH 71/84] Fixes for tag validation and build
---
.../components/tags/umbtagseditor.directive.js | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/tags/umbtagseditor.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/tags/umbtagseditor.directive.js
index 92c9d57ee8..3d784c999f 100644
--- a/src/Umbraco.Web.UI.Client/src/common/directives/components/tags/umbtagseditor.directive.js
+++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/tags/umbtagseditor.directive.js
@@ -181,7 +181,7 @@
else {
vm.onValueChanged({ value: [] });
}
-
+
reValidate();
}
@@ -190,7 +190,7 @@
*/
function validateMandatory() {
return {
- isValid: !vm.validation.mandatory || (vm.viewModel != null && vm.viewModel.length > 0),
+ isValid: !vm.validation.mandatory || (vm.viewModel != null && vm.viewModel.length > 0)|| (vm.value != null && vm.value.length > 0),
errorMsg: "Value cannot be empty",
errorKey: "required"
};
@@ -271,12 +271,12 @@
return ($.inArray(suggestion.value, vm.viewModel) === -1);
});
}
-
+
function reValidate() {
//this is required to re-validate
vm.tagEditorForm.tagCount.$setViewValue(vm.viewModel.length);
- {
-
+ }
+
}
})();
From a5efc25c8152db9a4d38b138a0e3f46c9cc5ea93 Mon Sep 17 00:00:00 2001
From: Bjarke Berg
Date: Tue, 15 Jan 2019 12:23:14 +0100
Subject: [PATCH 72/84] Revert "Support IContentType.IsElement"
This reverts commit ba38b67b
---
.../services/umbdataformatter.service.js | 18 +++++++--------
.../permissions/permissions.controller.js | 22 ++++++++++++-------
.../views/permissions/permissions.html | 20 ++---------------
src/Umbraco.Web.UI/Umbraco/config/lang/en.xml | 2 --
.../Umbraco/config/lang/en_us.xml | 2 --
.../ContentTypeCompositionDisplay.cs | 4 ----
.../Models/ContentEditing/ContentTypeSave.cs | 3 ---
7 files changed, 25 insertions(+), 46 deletions(-)
diff --git a/src/Umbraco.Web.UI.Client/src/common/services/umbdataformatter.service.js b/src/Umbraco.Web.UI.Client/src/common/services/umbdataformatter.service.js
index 1e6fc5d643..e31742e660 100644
--- a/src/Umbraco.Web.UI.Client/src/common/services/umbdataformatter.service.js
+++ b/src/Umbraco.Web.UI.Client/src/common/services/umbdataformatter.service.js
@@ -64,7 +64,7 @@
var saveModel = _.pick(displayModel,
'compositeContentTypes', 'isContainer', 'allowAsRoot', 'allowedTemplates', 'allowedContentTypes',
'alias', 'description', 'thumbnail', 'name', 'id', 'icon', 'trashed',
- 'key', 'parentId', 'alias', 'path', 'allowCultureVariant', 'isElement');
+ 'key', 'parentId', 'alias', 'path', 'allowCultureVariant');
//TODO: Map these
saveModel.allowedTemplates = _.map(displayModel.allowedTemplates, function (t) { return t.alias; });
@@ -262,7 +262,7 @@
saveModel[props[m]] = startId.id;
}
- saveModel.parentId = -1;
+ saveModel.parentId = -1;
return saveModel;
},
@@ -293,7 +293,7 @@
});
saveModel.email = propEmail.value.trim();
saveModel.username = propLogin.value.trim();
-
+
saveModel.password = this.formatChangePasswordModel(propPass.value);
var selectedGroups = [];
@@ -336,7 +336,7 @@
/** formats the display model used to display the media to the model used to save the media */
formatMediaPostData: function (displayModel, action) {
- //NOTE: the display model inherits from the save model so we can in theory just post up the display model but
+ //NOTE: the display model inherits from the save model so we can in theory just post up the display model but
// we don't want to post all of the data as it is unecessary.
var saveModel = {
id: displayModel.id,
@@ -354,7 +354,7 @@
/** formats the display model used to display the content to the model used to save the content */
formatContentPostData: function (displayModel, action) {
- //NOTE: the display model inherits from the save model so we can in theory just post up the display model but
+ //NOTE: the display model inherits from the save model so we can in theory just post up the display model but
// we don't want to post all of the data as it is unecessary.
var saveModel = {
id: displayModel.id,
@@ -379,7 +379,7 @@
var propExpireDate = displayModel.removeDate;
var propReleaseDate = displayModel.releaseDate;
var propTemplate = displayModel.template;
-
+
saveModel.expireDate = propExpireDate ? propExpireDate : null;
saveModel.releaseDate = propReleaseDate ? propReleaseDate : null;
saveModel.templateAlias = propTemplate ? propTemplate : null;
@@ -389,8 +389,8 @@
/**
* This formats the server GET response for a content display item
- * @param {} displayModel
- * @returns {}
+ * @param {} displayModel
+ * @returns {}
*/
formatContentGetData: function(displayModel) {
@@ -418,7 +418,7 @@
}
});
});
-
+
//now assign this same invariant property instance to the same index of the other variants property array
for (var j = 1; j < displayModel.variants.length; j++) {
diff --git a/src/Umbraco.Web.UI.Client/src/views/documenttypes/views/permissions/permissions.controller.js b/src/Umbraco.Web.UI.Client/src/views/documenttypes/views/permissions/permissions.controller.js
index 317fe094ae..4a7a870618 100644
--- a/src/Umbraco.Web.UI.Client/src/views/documenttypes/views/permissions/permissions.controller.js
+++ b/src/Umbraco.Web.UI.Client/src/views/documenttypes/views/permissions/permissions.controller.js
@@ -25,7 +25,6 @@
vm.removeChild = removeChild;
vm.toggleAllowAsRoot = toggleAllowAsRoot;
vm.toggleAllowCultureVariants = toggleAllowCultureVariants;
- vm.toggleIsElement = toggleIsElement;
/* ---------- INIT ---------- */
@@ -85,18 +84,25 @@
$scope.model.allowedContentTypes.splice(selectedChildIndex, 1);
}
- // note: "safe toggling" here ie handling cases where the value is undefined, etc
+ /**
+ * Toggle the $scope.model.allowAsRoot value to either true or false
+ */
+ function toggleAllowAsRoot(){
+ if($scope.model.allowAsRoot){
+ $scope.model.allowAsRoot = false;
+ return;
+ }
- function toggleAllowAsRoot() {
- $scope.model.allowAsRoot = $scope.model.allowAsRoot ? false : true;
+ $scope.model.allowAsRoot = true;
}
function toggleAllowCultureVariants() {
- $scope.model.allowCultureVariant = $scope.model.allowCultureVariant ? false : true;
- }
+ if ($scope.model.allowCultureVariant) {
+ $scope.model.allowCultureVariant = false;
+ return;
+ }
- function toggleIsElement() {
- $scope.model.isElement = $scope.model.isElement ? false : true;
+ $scope.model.allowCultureVariant = true;
}
}
diff --git a/src/Umbraco.Web.UI.Client/src/views/documenttypes/views/permissions/permissions.html b/src/Umbraco.Web.UI.Client/src/views/documenttypes/views/permissions/permissions.html
index 0d74c655d7..ec1e528f8c 100644
--- a/src/Umbraco.Web.UI.Client/src/views/documenttypes/views/permissions/permissions.html
+++ b/src/Umbraco.Web.UI.Client/src/views/documenttypes/views/permissions/permissions.html
@@ -53,25 +53,9 @@
hotkey="alt+shift+v">
-
+
-
-
-
+
diff --git a/src/Umbraco.Web.UI/Umbraco/config/lang/en.xml b/src/Umbraco.Web.UI/Umbraco/config/lang/en.xml
index 987203442a..386d3af518 100644
--- a/src/Umbraco.Web.UI/Umbraco/config/lang/en.xml
+++ b/src/Umbraco.Web.UI/Umbraco/config/lang/en.xml
@@ -1518,8 +1518,6 @@ To manage your website, simply open the Umbraco back office and start adding con
Allow varying by culture
Allow editors to create content of this type in different languages
Allow varying by culture
- Is an Element type
- An Element type is meant to be used for instance in Nested Content, and not in the tree
Building models
diff --git a/src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml b/src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml
index 1860d3afc9..5de373f571 100644
--- a/src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml
+++ b/src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml
@@ -1559,8 +1559,6 @@ To manage your website, simply open the Umbraco back office and start adding con
Allow varying by culture
Allow editors to create content of this type in different languages
Allow varying by culture
- Is an Element type
- An Element type is meant to be used for instance in Nested Content, and not in the tree
Add language
diff --git a/src/Umbraco.Web/Models/ContentEditing/ContentTypeCompositionDisplay.cs b/src/Umbraco.Web/Models/ContentEditing/ContentTypeCompositionDisplay.cs
index e5e74c2749..7211ddbf61 100644
--- a/src/Umbraco.Web/Models/ContentEditing/ContentTypeCompositionDisplay.cs
+++ b/src/Umbraco.Web/Models/ContentEditing/ContentTypeCompositionDisplay.cs
@@ -26,10 +26,6 @@ namespace Umbraco.Web.Models.ContentEditing
[DataMember(Name = "isContainer")]
public bool IsContainer { get; set; }
- //Element
- [DataMember(Name = "isElement")]
- public bool IsElement { get; set; }
-
[DataMember(Name = "listViewEditorName")]
[ReadOnly(true)]
public string ListViewEditorName { get; set; }
diff --git a/src/Umbraco.Web/Models/ContentEditing/ContentTypeSave.cs b/src/Umbraco.Web/Models/ContentEditing/ContentTypeSave.cs
index b1d24c5fd2..c2ec70d3dc 100644
--- a/src/Umbraco.Web/Models/ContentEditing/ContentTypeSave.cs
+++ b/src/Umbraco.Web/Models/ContentEditing/ContentTypeSave.cs
@@ -25,9 +25,6 @@ namespace Umbraco.Web.Models.ContentEditing
[DataMember(Name = "isContainer")]
public bool IsContainer { get; set; }
- [DataMember(Name = "isElement")]
- public bool IsElement { get; set; }
-
[DataMember(Name = "allowAsRoot")]
public bool AllowAsRoot { get; set; }
From ff6a9ba97f17bddd64edb1da5cc0a8858fb336f9 Mon Sep 17 00:00:00 2001
From: Bjarke Berg
Date: Tue, 15 Jan 2019 12:23:45 +0100
Subject: [PATCH 73/84] Revert "Identify element types"
This reverts commit 4ad2505b
---
.../Migrations/Upgrade/UmbracoPlan.cs | 1 -
.../V_8_0_0/AddContentTypeIsElementColumn.cs | 15 ----------
src/Umbraco.Core/Models/ContentTypeBase.cs | 10 -------
.../Models/ContentTypeBaseExtensions.cs | 3 +-
src/Umbraco.Core/Models/IContentTypeBase.cs | 12 +-------
.../PublishedContent/PublishedItemType.cs | 7 +----
.../Persistence/Dtos/ContentTypeDto.cs | 4 ---
.../Factories/ContentTypeFactory.cs | 2 --
.../Persistence/Mappers/ContentTypeMapper.cs | 1 -
.../Persistence/Mappers/MediaTypeMapper.cs | 1 -
.../Persistence/Mappers/MemberTypeMapper.cs | 1 -
.../Implement/ContentTypeRepositoryBase.cs | 6 ++--
.../Services/EntityXmlSerializer.cs | 3 +-
.../Services/Implement/PackagingService.cs | 4 ---
src/Umbraco.Core/Umbraco.Core.csproj | 1 -
.../PublishedContent/PublishedContentTests.cs | 1 +
.../Services/ContentTypeServiceTests.cs | 30 -------------------
.../ContentEditing/ContentItemDisplay.cs | 8 +----
.../Models/Mapping/ContentMapperProfile.cs | 5 ++--
19 files changed, 10 insertions(+), 105 deletions(-)
delete mode 100644 src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/AddContentTypeIsElementColumn.cs
diff --git a/src/Umbraco.Core/Migrations/Upgrade/UmbracoPlan.cs b/src/Umbraco.Core/Migrations/Upgrade/UmbracoPlan.cs
index 9ec970f1fe..b469c02a3c 100644
--- a/src/Umbraco.Core/Migrations/Upgrade/UmbracoPlan.cs
+++ b/src/Umbraco.Core/Migrations/Upgrade/UmbracoPlan.cs
@@ -121,7 +121,6 @@ namespace Umbraco.Core.Migrations.Upgrade
To("{648A2D5F-7467-48F8-B309-E99CEEE00E2A}"); // fixed version
To("{C39BF2A7-1454-4047-BBFE-89E40F66ED63}");
To("{64EBCE53-E1F0-463A-B40B-E98EFCCA8AE2}");
- To("{0009109C-A0B8-4F3F-8FEB-C137BBDDA268}");
//FINAL
diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/AddContentTypeIsElementColumn.cs b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/AddContentTypeIsElementColumn.cs
deleted file mode 100644
index 1df11a3e99..0000000000
--- a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/AddContentTypeIsElementColumn.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-using Umbraco.Core.Persistence.Dtos;
-
-namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
-{
- public class AddContentTypeIsElementColumn : MigrationBase
- {
- public AddContentTypeIsElementColumn(IMigrationContext context) : base(context)
- { }
-
- public override void Migrate()
- {
- AddColumn("isElement");
- }
- }
-}
diff --git a/src/Umbraco.Core/Models/ContentTypeBase.cs b/src/Umbraco.Core/Models/ContentTypeBase.cs
index b6ea9f50a0..88b1179f6d 100644
--- a/src/Umbraco.Core/Models/ContentTypeBase.cs
+++ b/src/Umbraco.Core/Models/ContentTypeBase.cs
@@ -26,7 +26,6 @@ namespace Umbraco.Core.Models
private string _thumbnail = "folder.png";
private bool _allowedAsRoot; // note: only one that's not 'pure element type'
private bool _isContainer;
- private bool _isElement;
private PropertyGroupCollection _propertyGroups;
private PropertyTypeCollection _noGroupPropertyTypes;
private IEnumerable _allowedContentTypes;
@@ -91,7 +90,6 @@ namespace Umbraco.Core.Models
public readonly PropertyInfo IconSelector = ExpressionHelper.GetPropertyInfo(x => x.Icon);
public readonly PropertyInfo ThumbnailSelector = ExpressionHelper.GetPropertyInfo(x => x.Thumbnail);
public readonly PropertyInfo AllowedAsRootSelector = ExpressionHelper.GetPropertyInfo(x => x.AllowedAsRoot);
- public readonly PropertyInfo IsElementSelector = ExpressionHelper.GetPropertyInfo(x => x.IsElement);
public readonly PropertyInfo IsContainerSelector = ExpressionHelper.GetPropertyInfo(x => x.IsContainer);
public readonly PropertyInfo AllowedContentTypesSelector = ExpressionHelper.GetPropertyInfo>(x => x.AllowedContentTypes);
public readonly PropertyInfo PropertyGroupsSelector = ExpressionHelper.GetPropertyInfo(x => x.PropertyGroups);
@@ -182,14 +180,6 @@ namespace Umbraco.Core.Models
set => SetPropertyValueAndDetectChanges(value, ref _isContainer, Ps.Value.IsContainerSelector);
}
- ///
- [DataMember]
- public bool IsElement
- {
- get => _isElement;
- set => SetPropertyValueAndDetectChanges(value, ref _isElement, Ps.Value.IsElementSelector);
- }
-
///
/// Gets or sets a list of integer Ids for allowed ContentTypes
///
diff --git a/src/Umbraco.Core/Models/ContentTypeBaseExtensions.cs b/src/Umbraco.Core/Models/ContentTypeBaseExtensions.cs
index adbc3de54f..8af48bb881 100644
--- a/src/Umbraco.Core/Models/ContentTypeBaseExtensions.cs
+++ b/src/Umbraco.Core/Models/ContentTypeBaseExtensions.cs
@@ -15,8 +15,7 @@ namespace Umbraco.Core.Models
{
var type = contentType.GetType();
var itemType = PublishedItemType.Unknown;
- if (contentType.IsElement) itemType = PublishedItemType.Element;
- else if (typeof(IContentType).IsAssignableFrom(type)) itemType = PublishedItemType.Content;
+ if (typeof(IContentType).IsAssignableFrom(type)) itemType = PublishedItemType.Content;
else if (typeof(IMediaType).IsAssignableFrom(type)) itemType = PublishedItemType.Media;
else if (typeof(IMemberType).IsAssignableFrom(type)) itemType = PublishedItemType.Member;
return itemType;
diff --git a/src/Umbraco.Core/Models/IContentTypeBase.cs b/src/Umbraco.Core/Models/IContentTypeBase.cs
index 787e347b37..a1d4aee02f 100644
--- a/src/Umbraco.Core/Models/IContentTypeBase.cs
+++ b/src/Umbraco.Core/Models/IContentTypeBase.cs
@@ -25,7 +25,7 @@ namespace Umbraco.Core.Models
/// the icon (eg. icon-home ) along with an optional CSS class name representing the
/// color (eg. icon-blue ). Put together, the value for this scenario would be
/// icon-home color-blue .
- ///
+ ///
/// If a class name for the color isn't specified, the icon color will default to black.
///
string Icon { get; set; }
@@ -48,16 +48,6 @@ namespace Umbraco.Core.Models
///
bool IsContainer { get; set; }
- ///
- /// Gets or sets a value indicating whether this content type is for an element.
- ///
- ///
- /// By default a content type is for a true media, member or document, but
- /// it can also be for an element, ie a subset that can for instance be used in
- /// nested content.
- ///
- bool IsElement { get; set; }
-
///
/// Gets or sets the content variation of the content type.
///
diff --git a/src/Umbraco.Core/Models/PublishedContent/PublishedItemType.cs b/src/Umbraco.Core/Models/PublishedContent/PublishedItemType.cs
index 42e9c9538d..e55fe66945 100644
--- a/src/Umbraco.Core/Models/PublishedContent/PublishedItemType.cs
+++ b/src/Umbraco.Core/Models/PublishedContent/PublishedItemType.cs
@@ -4,18 +4,13 @@
/// The type of published element.
///
/// Can be a simple element, or a document, a media, a member.
- public enum PublishedItemType
+ public enum PublishedItemType // fixme - need to rename to PublishedElementType but then conflicts?
{
///
/// Unknown.
///
Unknown = 0,
- ///
- /// An element.
- ///
- Element,
-
///
/// A document.
///
diff --git a/src/Umbraco.Core/Persistence/Dtos/ContentTypeDto.cs b/src/Umbraco.Core/Persistence/Dtos/ContentTypeDto.cs
index 4f3a67aa91..d930abc54c 100644
--- a/src/Umbraco.Core/Persistence/Dtos/ContentTypeDto.cs
+++ b/src/Umbraco.Core/Persistence/Dtos/ContentTypeDto.cs
@@ -41,10 +41,6 @@ namespace Umbraco.Core.Persistence.Dtos
[Constraint(Default = "0")]
public bool IsContainer { get; set; }
- [Column("isElement")]
- [Constraint(Default = "0")]
- public bool IsElement { get; set; }
-
[Column("allowAtRoot")]
[Constraint(Default = "0")]
public bool AllowAtRoot { get; set; }
diff --git a/src/Umbraco.Core/Persistence/Factories/ContentTypeFactory.cs b/src/Umbraco.Core/Persistence/Factories/ContentTypeFactory.cs
index 7a04a6d0d9..38a1aa2aab 100644
--- a/src/Umbraco.Core/Persistence/Factories/ContentTypeFactory.cs
+++ b/src/Umbraco.Core/Persistence/Factories/ContentTypeFactory.cs
@@ -107,7 +107,6 @@ namespace Umbraco.Core.Persistence.Factories
entity.CreatorId = dto.NodeDto.UserId ?? Constants.Security.UnknownUserId;
entity.AllowedAsRoot = dto.AllowAtRoot;
entity.IsContainer = dto.IsContainer;
- entity.IsElement = dto.IsElement;
entity.Trashed = dto.NodeDto.Trashed;
entity.Variations = (ContentVariation) dto.Variations;
}
@@ -133,7 +132,6 @@ namespace Umbraco.Core.Persistence.Factories
NodeId = entity.Id,
AllowAtRoot = entity.AllowedAsRoot,
IsContainer = entity.IsContainer,
- IsElement = entity.IsElement,
Variations = (byte) entity.Variations,
NodeDto = BuildNodeDto(entity, nodeObjectType)
};
diff --git a/src/Umbraco.Core/Persistence/Mappers/ContentTypeMapper.cs b/src/Umbraco.Core/Persistence/Mappers/ContentTypeMapper.cs
index a24963bace..c692a75474 100644
--- a/src/Umbraco.Core/Persistence/Mappers/ContentTypeMapper.cs
+++ b/src/Umbraco.Core/Persistence/Mappers/ContentTypeMapper.cs
@@ -35,7 +35,6 @@ namespace Umbraco.Core.Persistence.Mappers
CacheMap(src => src.Description, dto => dto.Description);
CacheMap(src => src.Icon, dto => dto.Icon);
CacheMap(src => src.IsContainer, dto => dto.IsContainer);
- CacheMap(src => src.IsElement, dto => dto.IsElement);
CacheMap(src => src.Thumbnail, dto => dto.Thumbnail);
}
}
diff --git a/src/Umbraco.Core/Persistence/Mappers/MediaTypeMapper.cs b/src/Umbraco.Core/Persistence/Mappers/MediaTypeMapper.cs
index 6cf83bc7aa..3f5a6e24bc 100644
--- a/src/Umbraco.Core/Persistence/Mappers/MediaTypeMapper.cs
+++ b/src/Umbraco.Core/Persistence/Mappers/MediaTypeMapper.cs
@@ -35,7 +35,6 @@ namespace Umbraco.Core.Persistence.Mappers
CacheMap(src => src.Description, dto => dto.Description);
CacheMap(src => src.Icon, dto => dto.Icon);
CacheMap(src => src.IsContainer, dto => dto.IsContainer);
- CacheMap(src => src.IsElement, dto => dto.IsElement);
CacheMap(src => src.Thumbnail, dto => dto.Thumbnail);
}
}
diff --git a/src/Umbraco.Core/Persistence/Mappers/MemberTypeMapper.cs b/src/Umbraco.Core/Persistence/Mappers/MemberTypeMapper.cs
index 9a4e4ec040..28dc19171f 100644
--- a/src/Umbraco.Core/Persistence/Mappers/MemberTypeMapper.cs
+++ b/src/Umbraco.Core/Persistence/Mappers/MemberTypeMapper.cs
@@ -35,7 +35,6 @@ namespace Umbraco.Core.Persistence.Mappers
CacheMap(src => src.Description, dto => dto.Description);
CacheMap(src => src.Icon, dto => dto.Icon);
CacheMap(src => src.IsContainer, dto => dto.IsContainer);
- CacheMap(src => src.IsElement, dto => dto.IsElement);
CacheMap(src => src.Thumbnail, dto => dto.Thumbnail);
}
}
diff --git a/src/Umbraco.Core/Persistence/Repositories/Implement/ContentTypeRepositoryBase.cs b/src/Umbraco.Core/Persistence/Repositories/Implement/ContentTypeRepositoryBase.cs
index 683df047f8..662254d1ee 100644
--- a/src/Umbraco.Core/Persistence/Repositories/Implement/ContentTypeRepositoryBase.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/Implement/ContentTypeRepositoryBase.cs
@@ -1283,7 +1283,7 @@ AND umbracoNode.id <> @id",
if (db == null) throw new ArgumentNullException(nameof(db));
var sql = @"SELECT cmsContentType.pk as ctPk, cmsContentType.alias as ctAlias, cmsContentType.allowAtRoot as ctAllowAtRoot, cmsContentType.description as ctDesc, cmsContentType.variations as ctVariations,
- cmsContentType.icon as ctIcon, cmsContentType.isContainer as ctIsContainer, cmsContentType.IsElement as ctIsElement, cmsContentType.nodeId as ctId, cmsContentType.thumbnail as ctThumb,
+ cmsContentType.icon as ctIcon, cmsContentType.isContainer as ctIsContainer, cmsContentType.nodeId as ctId, cmsContentType.thumbnail as ctThumb,
AllowedTypes.AllowedId as ctaAllowedId, AllowedTypes.SortOrder as ctaSortOrder, AllowedTypes.alias as ctaAlias,
ParentTypes.parentContentTypeId as chtParentId, ParentTypes.parentContentTypeKey as chtParentKey,
umbracoNode.createDate as nCreateDate, umbracoNode." + sqlSyntax.GetQuotedColumnName("level") + @" as nLevel, umbracoNode.nodeObjectType as nObjectType, umbracoNode.nodeUser as nUser,
@@ -1384,7 +1384,6 @@ AND umbracoNode.id <> @id",
Description = currCt.ctDesc,
Icon = currCt.ctIcon,
IsContainer = currCt.ctIsContainer,
- IsElement = currCt.ctIsElement,
NodeId = currCt.ctId,
PrimaryKey = currCt.ctPk,
Thumbnail = currCt.ctThumb,
@@ -1423,7 +1422,7 @@ AND umbracoNode.id <> @id",
var sql = @"SELECT cmsDocumentType.IsDefault as dtIsDefault, cmsDocumentType.templateNodeId as dtTemplateId,
cmsContentType.pk as ctPk, cmsContentType.alias as ctAlias, cmsContentType.allowAtRoot as ctAllowAtRoot, cmsContentType.description as ctDesc, cmsContentType.variations as ctVariations,
- cmsContentType.icon as ctIcon, cmsContentType.isContainer as ctIsContainer, cmsContentType.IsElement as ctIsElement, cmsContentType.nodeId as ctId, cmsContentType.thumbnail as ctThumb,
+ cmsContentType.icon as ctIcon, cmsContentType.isContainer as ctIsContainer, cmsContentType.nodeId as ctId, cmsContentType.thumbnail as ctThumb,
AllowedTypes.AllowedId as ctaAllowedId, AllowedTypes.SortOrder as ctaSortOrder, AllowedTypes.alias as ctaAlias,
ParentTypes.parentContentTypeId as chtParentId,ParentTypes.parentContentTypeKey as chtParentKey,
umbracoNode.createDate as nCreateDate, umbracoNode." + sqlSyntax.GetQuotedColumnName("level") + @" as nLevel, umbracoNode.nodeObjectType as nObjectType, umbracoNode.nodeUser as nUser,
@@ -1560,7 +1559,6 @@ AND umbracoNode.id <> @id",
Description = currCt.ctDesc,
Icon = currCt.ctIcon,
IsContainer = currCt.ctIsContainer,
- IsElement = currCt.ctIsElement,
NodeId = currCt.ctId,
PrimaryKey = currCt.ctPk,
Thumbnail = currCt.ctThumb,
diff --git a/src/Umbraco.Core/Services/EntityXmlSerializer.cs b/src/Umbraco.Core/Services/EntityXmlSerializer.cs
index 38d5471bb7..d938e032a8 100644
--- a/src/Umbraco.Core/Services/EntityXmlSerializer.cs
+++ b/src/Umbraco.Core/Services/EntityXmlSerializer.cs
@@ -337,8 +337,7 @@ namespace Umbraco.Core.Services
new XElement("Thumbnail", contentType.Thumbnail),
new XElement("Description", contentType.Description),
new XElement("AllowAtRoot", contentType.AllowedAsRoot.ToString()),
- new XElement("IsListView", contentType.IsContainer.ToString()),
- new XElement("IsElement", contentType.IsElement.ToString()));
+ new XElement("IsListView", contentType.IsContainer.ToString()));
var masterContentType = contentType.ContentTypeComposition.FirstOrDefault(x => x.Id == contentType.ParentId);
if(masterContentType != null)
diff --git a/src/Umbraco.Core/Services/Implement/PackagingService.cs b/src/Umbraco.Core/Services/Implement/PackagingService.cs
index 8f6c287cf1..106d2b9f12 100644
--- a/src/Umbraco.Core/Services/Implement/PackagingService.cs
+++ b/src/Umbraco.Core/Services/Implement/PackagingService.cs
@@ -578,10 +578,6 @@ namespace Umbraco.Core.Services.Implement
if (isListView != null)
contentType.IsContainer = isListView.Value.InvariantEquals("true");
- var isElement = infoElement.Element("IsElement");
- if (isListView != null)
- contentType.IsElement = isElement.Value.InvariantEquals("true");
-
//Name of the master corresponds to the parent and we need to ensure that the Parent Id is set
var masterElement = infoElement.Element("Master");
if (masterElement != null)
diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj
index 7d65a46f49..609befd233 100755
--- a/src/Umbraco.Core/Umbraco.Core.csproj
+++ b/src/Umbraco.Core/Umbraco.Core.csproj
@@ -377,7 +377,6 @@
-
diff --git a/src/Umbraco.Tests/PublishedContent/PublishedContentTests.cs b/src/Umbraco.Tests/PublishedContent/PublishedContentTests.cs
index ab65ac82b1..914956dce1 100644
--- a/src/Umbraco.Tests/PublishedContent/PublishedContentTests.cs
+++ b/src/Umbraco.Tests/PublishedContent/PublishedContentTests.cs
@@ -233,6 +233,7 @@ namespace Umbraco.Tests.PublishedContent
}
[Test]
+ [Ignore("Fails as long as PublishedContentModel is internal.")] // fixme
public void Is_Last_From_Where_Filter2()
{
var doc = GetNode(1173);
diff --git a/src/Umbraco.Tests/Services/ContentTypeServiceTests.cs b/src/Umbraco.Tests/Services/ContentTypeServiceTests.cs
index 8dc8a2b45c..b1a8fa26a8 100644
--- a/src/Umbraco.Tests/Services/ContentTypeServiceTests.cs
+++ b/src/Umbraco.Tests/Services/ContentTypeServiceTests.cs
@@ -22,36 +22,6 @@ namespace Umbraco.Tests.Services
[UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerTest, PublishedRepositoryEvents = true)]
public class ContentTypeServiceTests : TestWithSomeContentBase
{
- [Test]
- public void CanSaveAndGetIsElement()
- {
- //create content type with a property type that varies by culture
- IContentType contentType = MockedContentTypes.CreateBasicContentType();
- contentType.Variations = ContentVariation.Nothing;
- var contentCollection = new PropertyTypeCollection(true);
- contentCollection.Add(new PropertyType("test", ValueStorageType.Ntext)
- {
- Alias = "title",
- Name = "Title",
- Description = "",
- Mandatory = false,
- SortOrder = 1,
- DataTypeId = -88,
- Variations = ContentVariation.Nothing
- });
- contentType.PropertyGroups.Add(new PropertyGroup(contentCollection) { Name = "Content", SortOrder = 1 });
- ServiceContext.ContentTypeService.Save(contentType);
-
- contentType = ServiceContext.ContentTypeService.Get(contentType.Id);
- Assert.IsFalse(contentType.IsElement);
-
- contentType.IsElement = true;
- ServiceContext.ContentTypeService.Save(contentType);
-
- contentType = ServiceContext.ContentTypeService.Get(contentType.Id);
- Assert.IsTrue(contentType.IsElement);
- }
-
[Test]
public void Change_Content_Type_Variation_Clears_Redirects()
{
diff --git a/src/Umbraco.Web/Models/ContentEditing/ContentItemDisplay.cs b/src/Umbraco.Web/Models/ContentEditing/ContentItemDisplay.cs
index 80358bfc7a..4908025351 100644
--- a/src/Umbraco.Web/Models/ContentEditing/ContentItemDisplay.cs
+++ b/src/Umbraco.Web/Models/ContentEditing/ContentItemDisplay.cs
@@ -86,12 +86,6 @@ namespace Umbraco.Web.Models.ContentEditing
[DataMember(Name = "isContainer")]
public bool IsContainer { get; set; }
- ///
- /// Indicates if the content is configured as an element
- ///
- [DataMember(Name = "isElement")]
- public bool IsElement { get; set; }
-
///
/// Property indicating if this item is part of a list view parent
///
@@ -123,7 +117,7 @@ namespace Umbraco.Web.Models.ContentEditing
///
[DataMember(Name = "updateDate")]
public DateTime UpdateDate { get; set; }
-
+
[DataMember(Name = "template")]
public string TemplateAlias { get; set; }
diff --git a/src/Umbraco.Web/Models/Mapping/ContentMapperProfile.cs b/src/Umbraco.Web/Models/Mapping/ContentMapperProfile.cs
index 1caf81a1eb..6de3bdc02c 100644
--- a/src/Umbraco.Web/Models/Mapping/ContentMapperProfile.cs
+++ b/src/Umbraco.Web/Models/Mapping/ContentMapperProfile.cs
@@ -46,7 +46,6 @@ namespace Umbraco.Web.Models.Mapping
.ForMember(dest => dest.ContentTypeAlias, opt => opt.MapFrom(src => src.ContentType.Alias))
.ForMember(dest => dest.ContentTypeName, opt => opt.MapFrom(src => src.ContentType.Name))
.ForMember(dest => dest.IsContainer, opt => opt.MapFrom(src => src.ContentType.IsContainer))
- .ForMember(dest => dest.IsElement, opt => opt.MapFrom(src => src.ContentType.IsElement))
.ForMember(dest => dest.IsBlueprint, opt => opt.MapFrom(src => src.Blueprint))
.ForMember(dest => dest.IsChildOfListView, opt => opt.ResolveUsing(childOfListViewResolver))
.ForMember(dest => dest.Trashed, opt => opt.MapFrom(src => src.Trashed))
@@ -60,7 +59,7 @@ namespace Umbraco.Web.Models.Mapping
.ForMember(dest => dest.AllowedTemplates, opt =>
opt.MapFrom(content => content.ContentType.AllowedTemplates
.Where(t => t.Alias.IsNullOrWhiteSpace() == false && t.Name.IsNullOrWhiteSpace() == false)
- .ToDictionary(t => t.Alias, t => t.Name)))
+ .ToDictionary(t => t.Alias, t => t.Name)))
.ForMember(dest => dest.AllowedActions, opt => opt.ResolveUsing(src => actionButtonsResolver.Resolve(src)))
.ForMember(dest => dest.AdditionalData, opt => opt.Ignore());
@@ -141,5 +140,5 @@ namespace Umbraco.Web.Models.Mapping
return source.CultureInfos.TryGetValue(culture, out var name) && !name.Name.IsNullOrWhiteSpace() ? name.Name : $"(({source.Name}))";
}
}
- }
+ }
}
From 93ba694106d2f435126a495b8111df01ed3e43b8 Mon Sep 17 00:00:00 2001
From: Stephan
Date: Tue, 15 Jan 2019 13:36:30 +0100
Subject: [PATCH 74/84] Upgrade ModelsBuilder (bugfix)
---
build/NuSpecs/UmbracoCms.nuspec | 2 +-
src/Umbraco.Web.UI/Umbraco.Web.UI.csproj | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/build/NuSpecs/UmbracoCms.nuspec b/build/NuSpecs/UmbracoCms.nuspec
index 565d693979..1b7a1c5ae1 100644
--- a/build/NuSpecs/UmbracoCms.nuspec
+++ b/build/NuSpecs/UmbracoCms.nuspec
@@ -22,7 +22,7 @@
not want this to happen as the alpha of the next major is, really, the next major already.
-->
-
+
diff --git a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj
index 7a59b15eb3..ca4acd9d66 100644
--- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj
+++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj
@@ -107,7 +107,7 @@
- 8.0.0-alpha.31
+ 8.0.0-alpha.32
From 5995a7ec843e5ca50d36a98eb4f7fd0de03e4cb4 Mon Sep 17 00:00:00 2001
From: Bjarke Berg
Date: Tue, 15 Jan 2019 15:05:04 +0100
Subject: [PATCH 75/84] a small change to let Git see changes
---
src/Umbraco.Core/Migrations/Upgrade/UmbracoPlan.cs | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/Umbraco.Core/Migrations/Upgrade/UmbracoPlan.cs b/src/Umbraco.Core/Migrations/Upgrade/UmbracoPlan.cs
index 9ec970f1fe..51935e6517 100644
--- a/src/Umbraco.Core/Migrations/Upgrade/UmbracoPlan.cs
+++ b/src/Umbraco.Core/Migrations/Upgrade/UmbracoPlan.cs
@@ -123,6 +123,7 @@ namespace Umbraco.Core.Migrations.Upgrade
To("{64EBCE53-E1F0-463A-B40B-E98EFCCA8AE2}");
To("{0009109C-A0B8-4F3F-8FEB-C137BBDDA268}");
+
//FINAL
From 11ffafacdf42a461b793df8a3e32fda1c88b6a4f Mon Sep 17 00:00:00 2001
From: Bjarke Berg
Date: Tue, 15 Jan 2019 15:12:59 +0100
Subject: [PATCH 76/84] Revert "Revert "Identify element types""
This reverts commit ff6a9ba9
---
.../Migrations/Upgrade/UmbracoPlan.cs | 1 +
.../V_8_0_0/AddContentTypeIsElementColumn.cs | 15 ++++++++++
src/Umbraco.Core/Models/ContentTypeBase.cs | 10 +++++++
.../Models/ContentTypeBaseExtensions.cs | 3 +-
src/Umbraco.Core/Models/IContentTypeBase.cs | 12 +++++++-
.../PublishedContent/PublishedItemType.cs | 7 ++++-
.../Persistence/Dtos/ContentTypeDto.cs | 4 +++
.../Factories/ContentTypeFactory.cs | 2 ++
.../Persistence/Mappers/ContentTypeMapper.cs | 1 +
.../Persistence/Mappers/MediaTypeMapper.cs | 1 +
.../Persistence/Mappers/MemberTypeMapper.cs | 1 +
.../Implement/ContentTypeRepositoryBase.cs | 6 ++--
.../Services/EntityXmlSerializer.cs | 3 +-
.../Services/Implement/PackagingService.cs | 4 +++
src/Umbraco.Core/Umbraco.Core.csproj | 1 +
.../PublishedContent/PublishedContentTests.cs | 1 -
.../Services/ContentTypeServiceTests.cs | 30 +++++++++++++++++++
.../ContentEditing/ContentItemDisplay.cs | 8 ++++-
.../Models/Mapping/ContentMapperProfile.cs | 5 ++--
19 files changed, 105 insertions(+), 10 deletions(-)
create mode 100644 src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/AddContentTypeIsElementColumn.cs
diff --git a/src/Umbraco.Core/Migrations/Upgrade/UmbracoPlan.cs b/src/Umbraco.Core/Migrations/Upgrade/UmbracoPlan.cs
index b469c02a3c..9ec970f1fe 100644
--- a/src/Umbraco.Core/Migrations/Upgrade/UmbracoPlan.cs
+++ b/src/Umbraco.Core/Migrations/Upgrade/UmbracoPlan.cs
@@ -121,6 +121,7 @@ namespace Umbraco.Core.Migrations.Upgrade
To("{648A2D5F-7467-48F8-B309-E99CEEE00E2A}"); // fixed version
To("{C39BF2A7-1454-4047-BBFE-89E40F66ED63}");
To("{64EBCE53-E1F0-463A-B40B-E98EFCCA8AE2}");
+ To("{0009109C-A0B8-4F3F-8FEB-C137BBDDA268}");
//FINAL
diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/AddContentTypeIsElementColumn.cs b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/AddContentTypeIsElementColumn.cs
new file mode 100644
index 0000000000..1df11a3e99
--- /dev/null
+++ b/src/Umbraco.Core/Migrations/Upgrade/V_8_0_0/AddContentTypeIsElementColumn.cs
@@ -0,0 +1,15 @@
+using Umbraco.Core.Persistence.Dtos;
+
+namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
+{
+ public class AddContentTypeIsElementColumn : MigrationBase
+ {
+ public AddContentTypeIsElementColumn(IMigrationContext context) : base(context)
+ { }
+
+ public override void Migrate()
+ {
+ AddColumn("isElement");
+ }
+ }
+}
diff --git a/src/Umbraco.Core/Models/ContentTypeBase.cs b/src/Umbraco.Core/Models/ContentTypeBase.cs
index 88b1179f6d..b6ea9f50a0 100644
--- a/src/Umbraco.Core/Models/ContentTypeBase.cs
+++ b/src/Umbraco.Core/Models/ContentTypeBase.cs
@@ -26,6 +26,7 @@ namespace Umbraco.Core.Models
private string _thumbnail = "folder.png";
private bool _allowedAsRoot; // note: only one that's not 'pure element type'
private bool _isContainer;
+ private bool _isElement;
private PropertyGroupCollection _propertyGroups;
private PropertyTypeCollection _noGroupPropertyTypes;
private IEnumerable _allowedContentTypes;
@@ -90,6 +91,7 @@ namespace Umbraco.Core.Models
public readonly PropertyInfo IconSelector = ExpressionHelper.GetPropertyInfo(x => x.Icon);
public readonly PropertyInfo ThumbnailSelector = ExpressionHelper.GetPropertyInfo(x => x.Thumbnail);
public readonly PropertyInfo AllowedAsRootSelector = ExpressionHelper.GetPropertyInfo(x => x.AllowedAsRoot);
+ public readonly PropertyInfo IsElementSelector = ExpressionHelper.GetPropertyInfo(x => x.IsElement);
public readonly PropertyInfo IsContainerSelector = ExpressionHelper.GetPropertyInfo(x => x.IsContainer);
public readonly PropertyInfo AllowedContentTypesSelector = ExpressionHelper.GetPropertyInfo>(x => x.AllowedContentTypes);
public readonly PropertyInfo PropertyGroupsSelector = ExpressionHelper.GetPropertyInfo(x => x.PropertyGroups);
@@ -180,6 +182,14 @@ namespace Umbraco.Core.Models
set => SetPropertyValueAndDetectChanges(value, ref _isContainer, Ps.Value.IsContainerSelector);
}
+ ///
+ [DataMember]
+ public bool IsElement
+ {
+ get => _isElement;
+ set => SetPropertyValueAndDetectChanges(value, ref _isElement, Ps.Value.IsElementSelector);
+ }
+
///
/// Gets or sets a list of integer Ids for allowed ContentTypes
///
diff --git a/src/Umbraco.Core/Models/ContentTypeBaseExtensions.cs b/src/Umbraco.Core/Models/ContentTypeBaseExtensions.cs
index 8af48bb881..adbc3de54f 100644
--- a/src/Umbraco.Core/Models/ContentTypeBaseExtensions.cs
+++ b/src/Umbraco.Core/Models/ContentTypeBaseExtensions.cs
@@ -15,7 +15,8 @@ namespace Umbraco.Core.Models
{
var type = contentType.GetType();
var itemType = PublishedItemType.Unknown;
- if (typeof(IContentType).IsAssignableFrom(type)) itemType = PublishedItemType.Content;
+ if (contentType.IsElement) itemType = PublishedItemType.Element;
+ else if (typeof(IContentType).IsAssignableFrom(type)) itemType = PublishedItemType.Content;
else if (typeof(IMediaType).IsAssignableFrom(type)) itemType = PublishedItemType.Media;
else if (typeof(IMemberType).IsAssignableFrom(type)) itemType = PublishedItemType.Member;
return itemType;
diff --git a/src/Umbraco.Core/Models/IContentTypeBase.cs b/src/Umbraco.Core/Models/IContentTypeBase.cs
index a1d4aee02f..787e347b37 100644
--- a/src/Umbraco.Core/Models/IContentTypeBase.cs
+++ b/src/Umbraco.Core/Models/IContentTypeBase.cs
@@ -25,7 +25,7 @@ namespace Umbraco.Core.Models
/// the icon (eg. icon-home ) along with an optional CSS class name representing the
/// color (eg. icon-blue ). Put together, the value for this scenario would be
/// icon-home color-blue .
- ///
+ ///
/// If a class name for the color isn't specified, the icon color will default to black.
///
string Icon { get; set; }
@@ -48,6 +48,16 @@ namespace Umbraco.Core.Models
///
bool IsContainer { get; set; }
+ ///
+ /// Gets or sets a value indicating whether this content type is for an element.
+ ///
+ ///
+ /// By default a content type is for a true media, member or document, but
+ /// it can also be for an element, ie a subset that can for instance be used in
+ /// nested content.
+ ///
+ bool IsElement { get; set; }
+
///
/// Gets or sets the content variation of the content type.
///
diff --git a/src/Umbraco.Core/Models/PublishedContent/PublishedItemType.cs b/src/Umbraco.Core/Models/PublishedContent/PublishedItemType.cs
index e55fe66945..42e9c9538d 100644
--- a/src/Umbraco.Core/Models/PublishedContent/PublishedItemType.cs
+++ b/src/Umbraco.Core/Models/PublishedContent/PublishedItemType.cs
@@ -4,13 +4,18 @@
/// The type of published element.
///
/// Can be a simple element, or a document, a media, a member.
- public enum PublishedItemType // fixme - need to rename to PublishedElementType but then conflicts?
+ public enum PublishedItemType
{
///
/// Unknown.
///
Unknown = 0,
+ ///
+ /// An element.
+ ///
+ Element,
+
///
/// A document.
///
diff --git a/src/Umbraco.Core/Persistence/Dtos/ContentTypeDto.cs b/src/Umbraco.Core/Persistence/Dtos/ContentTypeDto.cs
index d930abc54c..4f3a67aa91 100644
--- a/src/Umbraco.Core/Persistence/Dtos/ContentTypeDto.cs
+++ b/src/Umbraco.Core/Persistence/Dtos/ContentTypeDto.cs
@@ -41,6 +41,10 @@ namespace Umbraco.Core.Persistence.Dtos
[Constraint(Default = "0")]
public bool IsContainer { get; set; }
+ [Column("isElement")]
+ [Constraint(Default = "0")]
+ public bool IsElement { get; set; }
+
[Column("allowAtRoot")]
[Constraint(Default = "0")]
public bool AllowAtRoot { get; set; }
diff --git a/src/Umbraco.Core/Persistence/Factories/ContentTypeFactory.cs b/src/Umbraco.Core/Persistence/Factories/ContentTypeFactory.cs
index 38a1aa2aab..7a04a6d0d9 100644
--- a/src/Umbraco.Core/Persistence/Factories/ContentTypeFactory.cs
+++ b/src/Umbraco.Core/Persistence/Factories/ContentTypeFactory.cs
@@ -107,6 +107,7 @@ namespace Umbraco.Core.Persistence.Factories
entity.CreatorId = dto.NodeDto.UserId ?? Constants.Security.UnknownUserId;
entity.AllowedAsRoot = dto.AllowAtRoot;
entity.IsContainer = dto.IsContainer;
+ entity.IsElement = dto.IsElement;
entity.Trashed = dto.NodeDto.Trashed;
entity.Variations = (ContentVariation) dto.Variations;
}
@@ -132,6 +133,7 @@ namespace Umbraco.Core.Persistence.Factories
NodeId = entity.Id,
AllowAtRoot = entity.AllowedAsRoot,
IsContainer = entity.IsContainer,
+ IsElement = entity.IsElement,
Variations = (byte) entity.Variations,
NodeDto = BuildNodeDto(entity, nodeObjectType)
};
diff --git a/src/Umbraco.Core/Persistence/Mappers/ContentTypeMapper.cs b/src/Umbraco.Core/Persistence/Mappers/ContentTypeMapper.cs
index c692a75474..a24963bace 100644
--- a/src/Umbraco.Core/Persistence/Mappers/ContentTypeMapper.cs
+++ b/src/Umbraco.Core/Persistence/Mappers/ContentTypeMapper.cs
@@ -35,6 +35,7 @@ namespace Umbraco.Core.Persistence.Mappers
CacheMap(src => src.Description, dto => dto.Description);
CacheMap(src => src.Icon, dto => dto.Icon);
CacheMap(src => src.IsContainer, dto => dto.IsContainer);
+ CacheMap(src => src.IsElement, dto => dto.IsElement);
CacheMap(src => src.Thumbnail, dto => dto.Thumbnail);
}
}
diff --git a/src/Umbraco.Core/Persistence/Mappers/MediaTypeMapper.cs b/src/Umbraco.Core/Persistence/Mappers/MediaTypeMapper.cs
index 3f5a6e24bc..6cf83bc7aa 100644
--- a/src/Umbraco.Core/Persistence/Mappers/MediaTypeMapper.cs
+++ b/src/Umbraco.Core/Persistence/Mappers/MediaTypeMapper.cs
@@ -35,6 +35,7 @@ namespace Umbraco.Core.Persistence.Mappers
CacheMap(src => src.Description, dto => dto.Description);
CacheMap(src => src.Icon, dto => dto.Icon);
CacheMap(src => src.IsContainer, dto => dto.IsContainer);
+ CacheMap(src => src.IsElement, dto => dto.IsElement);
CacheMap(src => src.Thumbnail, dto => dto.Thumbnail);
}
}
diff --git a/src/Umbraco.Core/Persistence/Mappers/MemberTypeMapper.cs b/src/Umbraco.Core/Persistence/Mappers/MemberTypeMapper.cs
index 28dc19171f..9a4e4ec040 100644
--- a/src/Umbraco.Core/Persistence/Mappers/MemberTypeMapper.cs
+++ b/src/Umbraco.Core/Persistence/Mappers/MemberTypeMapper.cs
@@ -35,6 +35,7 @@ namespace Umbraco.Core.Persistence.Mappers
CacheMap(src => src.Description, dto => dto.Description);
CacheMap(src => src.Icon, dto => dto.Icon);
CacheMap(src => src.IsContainer, dto => dto.IsContainer);
+ CacheMap(src => src.IsElement, dto => dto.IsElement);
CacheMap(src => src.Thumbnail, dto => dto.Thumbnail);
}
}
diff --git a/src/Umbraco.Core/Persistence/Repositories/Implement/ContentTypeRepositoryBase.cs b/src/Umbraco.Core/Persistence/Repositories/Implement/ContentTypeRepositoryBase.cs
index 662254d1ee..683df047f8 100644
--- a/src/Umbraco.Core/Persistence/Repositories/Implement/ContentTypeRepositoryBase.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/Implement/ContentTypeRepositoryBase.cs
@@ -1283,7 +1283,7 @@ AND umbracoNode.id <> @id",
if (db == null) throw new ArgumentNullException(nameof(db));
var sql = @"SELECT cmsContentType.pk as ctPk, cmsContentType.alias as ctAlias, cmsContentType.allowAtRoot as ctAllowAtRoot, cmsContentType.description as ctDesc, cmsContentType.variations as ctVariations,
- cmsContentType.icon as ctIcon, cmsContentType.isContainer as ctIsContainer, cmsContentType.nodeId as ctId, cmsContentType.thumbnail as ctThumb,
+ cmsContentType.icon as ctIcon, cmsContentType.isContainer as ctIsContainer, cmsContentType.IsElement as ctIsElement, cmsContentType.nodeId as ctId, cmsContentType.thumbnail as ctThumb,
AllowedTypes.AllowedId as ctaAllowedId, AllowedTypes.SortOrder as ctaSortOrder, AllowedTypes.alias as ctaAlias,
ParentTypes.parentContentTypeId as chtParentId, ParentTypes.parentContentTypeKey as chtParentKey,
umbracoNode.createDate as nCreateDate, umbracoNode." + sqlSyntax.GetQuotedColumnName("level") + @" as nLevel, umbracoNode.nodeObjectType as nObjectType, umbracoNode.nodeUser as nUser,
@@ -1384,6 +1384,7 @@ AND umbracoNode.id <> @id",
Description = currCt.ctDesc,
Icon = currCt.ctIcon,
IsContainer = currCt.ctIsContainer,
+ IsElement = currCt.ctIsElement,
NodeId = currCt.ctId,
PrimaryKey = currCt.ctPk,
Thumbnail = currCt.ctThumb,
@@ -1422,7 +1423,7 @@ AND umbracoNode.id <> @id",
var sql = @"SELECT cmsDocumentType.IsDefault as dtIsDefault, cmsDocumentType.templateNodeId as dtTemplateId,
cmsContentType.pk as ctPk, cmsContentType.alias as ctAlias, cmsContentType.allowAtRoot as ctAllowAtRoot, cmsContentType.description as ctDesc, cmsContentType.variations as ctVariations,
- cmsContentType.icon as ctIcon, cmsContentType.isContainer as ctIsContainer, cmsContentType.nodeId as ctId, cmsContentType.thumbnail as ctThumb,
+ cmsContentType.icon as ctIcon, cmsContentType.isContainer as ctIsContainer, cmsContentType.IsElement as ctIsElement, cmsContentType.nodeId as ctId, cmsContentType.thumbnail as ctThumb,
AllowedTypes.AllowedId as ctaAllowedId, AllowedTypes.SortOrder as ctaSortOrder, AllowedTypes.alias as ctaAlias,
ParentTypes.parentContentTypeId as chtParentId,ParentTypes.parentContentTypeKey as chtParentKey,
umbracoNode.createDate as nCreateDate, umbracoNode." + sqlSyntax.GetQuotedColumnName("level") + @" as nLevel, umbracoNode.nodeObjectType as nObjectType, umbracoNode.nodeUser as nUser,
@@ -1559,6 +1560,7 @@ AND umbracoNode.id <> @id",
Description = currCt.ctDesc,
Icon = currCt.ctIcon,
IsContainer = currCt.ctIsContainer,
+ IsElement = currCt.ctIsElement,
NodeId = currCt.ctId,
PrimaryKey = currCt.ctPk,
Thumbnail = currCt.ctThumb,
diff --git a/src/Umbraco.Core/Services/EntityXmlSerializer.cs b/src/Umbraco.Core/Services/EntityXmlSerializer.cs
index d938e032a8..38d5471bb7 100644
--- a/src/Umbraco.Core/Services/EntityXmlSerializer.cs
+++ b/src/Umbraco.Core/Services/EntityXmlSerializer.cs
@@ -337,7 +337,8 @@ namespace Umbraco.Core.Services
new XElement("Thumbnail", contentType.Thumbnail),
new XElement("Description", contentType.Description),
new XElement("AllowAtRoot", contentType.AllowedAsRoot.ToString()),
- new XElement("IsListView", contentType.IsContainer.ToString()));
+ new XElement("IsListView", contentType.IsContainer.ToString()),
+ new XElement("IsElement", contentType.IsElement.ToString()));
var masterContentType = contentType.ContentTypeComposition.FirstOrDefault(x => x.Id == contentType.ParentId);
if(masterContentType != null)
diff --git a/src/Umbraco.Core/Services/Implement/PackagingService.cs b/src/Umbraco.Core/Services/Implement/PackagingService.cs
index 106d2b9f12..8f6c287cf1 100644
--- a/src/Umbraco.Core/Services/Implement/PackagingService.cs
+++ b/src/Umbraco.Core/Services/Implement/PackagingService.cs
@@ -578,6 +578,10 @@ namespace Umbraco.Core.Services.Implement
if (isListView != null)
contentType.IsContainer = isListView.Value.InvariantEquals("true");
+ var isElement = infoElement.Element("IsElement");
+ if (isListView != null)
+ contentType.IsElement = isElement.Value.InvariantEquals("true");
+
//Name of the master corresponds to the parent and we need to ensure that the Parent Id is set
var masterElement = infoElement.Element("Master");
if (masterElement != null)
diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj
index 609befd233..7d65a46f49 100755
--- a/src/Umbraco.Core/Umbraco.Core.csproj
+++ b/src/Umbraco.Core/Umbraco.Core.csproj
@@ -377,6 +377,7 @@
+
diff --git a/src/Umbraco.Tests/PublishedContent/PublishedContentTests.cs b/src/Umbraco.Tests/PublishedContent/PublishedContentTests.cs
index 914956dce1..ab65ac82b1 100644
--- a/src/Umbraco.Tests/PublishedContent/PublishedContentTests.cs
+++ b/src/Umbraco.Tests/PublishedContent/PublishedContentTests.cs
@@ -233,7 +233,6 @@ namespace Umbraco.Tests.PublishedContent
}
[Test]
- [Ignore("Fails as long as PublishedContentModel is internal.")] // fixme
public void Is_Last_From_Where_Filter2()
{
var doc = GetNode(1173);
diff --git a/src/Umbraco.Tests/Services/ContentTypeServiceTests.cs b/src/Umbraco.Tests/Services/ContentTypeServiceTests.cs
index b1a8fa26a8..8dc8a2b45c 100644
--- a/src/Umbraco.Tests/Services/ContentTypeServiceTests.cs
+++ b/src/Umbraco.Tests/Services/ContentTypeServiceTests.cs
@@ -22,6 +22,36 @@ namespace Umbraco.Tests.Services
[UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerTest, PublishedRepositoryEvents = true)]
public class ContentTypeServiceTests : TestWithSomeContentBase
{
+ [Test]
+ public void CanSaveAndGetIsElement()
+ {
+ //create content type with a property type that varies by culture
+ IContentType contentType = MockedContentTypes.CreateBasicContentType();
+ contentType.Variations = ContentVariation.Nothing;
+ var contentCollection = new PropertyTypeCollection(true);
+ contentCollection.Add(new PropertyType("test", ValueStorageType.Ntext)
+ {
+ Alias = "title",
+ Name = "Title",
+ Description = "",
+ Mandatory = false,
+ SortOrder = 1,
+ DataTypeId = -88,
+ Variations = ContentVariation.Nothing
+ });
+ contentType.PropertyGroups.Add(new PropertyGroup(contentCollection) { Name = "Content", SortOrder = 1 });
+ ServiceContext.ContentTypeService.Save(contentType);
+
+ contentType = ServiceContext.ContentTypeService.Get(contentType.Id);
+ Assert.IsFalse(contentType.IsElement);
+
+ contentType.IsElement = true;
+ ServiceContext.ContentTypeService.Save(contentType);
+
+ contentType = ServiceContext.ContentTypeService.Get(contentType.Id);
+ Assert.IsTrue(contentType.IsElement);
+ }
+
[Test]
public void Change_Content_Type_Variation_Clears_Redirects()
{
diff --git a/src/Umbraco.Web/Models/ContentEditing/ContentItemDisplay.cs b/src/Umbraco.Web/Models/ContentEditing/ContentItemDisplay.cs
index 4908025351..80358bfc7a 100644
--- a/src/Umbraco.Web/Models/ContentEditing/ContentItemDisplay.cs
+++ b/src/Umbraco.Web/Models/ContentEditing/ContentItemDisplay.cs
@@ -86,6 +86,12 @@ namespace Umbraco.Web.Models.ContentEditing
[DataMember(Name = "isContainer")]
public bool IsContainer { get; set; }
+ ///
+ /// Indicates if the content is configured as an element
+ ///
+ [DataMember(Name = "isElement")]
+ public bool IsElement { get; set; }
+
///
/// Property indicating if this item is part of a list view parent
///
@@ -117,7 +123,7 @@ namespace Umbraco.Web.Models.ContentEditing
///
[DataMember(Name = "updateDate")]
public DateTime UpdateDate { get; set; }
-
+
[DataMember(Name = "template")]
public string TemplateAlias { get; set; }
diff --git a/src/Umbraco.Web/Models/Mapping/ContentMapperProfile.cs b/src/Umbraco.Web/Models/Mapping/ContentMapperProfile.cs
index 6de3bdc02c..1caf81a1eb 100644
--- a/src/Umbraco.Web/Models/Mapping/ContentMapperProfile.cs
+++ b/src/Umbraco.Web/Models/Mapping/ContentMapperProfile.cs
@@ -46,6 +46,7 @@ namespace Umbraco.Web.Models.Mapping
.ForMember(dest => dest.ContentTypeAlias, opt => opt.MapFrom(src => src.ContentType.Alias))
.ForMember(dest => dest.ContentTypeName, opt => opt.MapFrom(src => src.ContentType.Name))
.ForMember(dest => dest.IsContainer, opt => opt.MapFrom(src => src.ContentType.IsContainer))
+ .ForMember(dest => dest.IsElement, opt => opt.MapFrom(src => src.ContentType.IsElement))
.ForMember(dest => dest.IsBlueprint, opt => opt.MapFrom(src => src.Blueprint))
.ForMember(dest => dest.IsChildOfListView, opt => opt.ResolveUsing(childOfListViewResolver))
.ForMember(dest => dest.Trashed, opt => opt.MapFrom(src => src.Trashed))
@@ -59,7 +60,7 @@ namespace Umbraco.Web.Models.Mapping
.ForMember(dest => dest.AllowedTemplates, opt =>
opt.MapFrom(content => content.ContentType.AllowedTemplates
.Where(t => t.Alias.IsNullOrWhiteSpace() == false && t.Name.IsNullOrWhiteSpace() == false)
- .ToDictionary(t => t.Alias, t => t.Name)))
+ .ToDictionary(t => t.Alias, t => t.Name)))
.ForMember(dest => dest.AllowedActions, opt => opt.ResolveUsing(src => actionButtonsResolver.Resolve(src)))
.ForMember(dest => dest.AdditionalData, opt => opt.Ignore());
@@ -140,5 +141,5 @@ namespace Umbraco.Web.Models.Mapping
return source.CultureInfos.TryGetValue(culture, out var name) && !name.Name.IsNullOrWhiteSpace() ? name.Name : $"(({source.Name}))";
}
}
- }
+ }
}
From 0b9705ca3f44b73bb3cc7e9d2386a979abe9a5da Mon Sep 17 00:00:00 2001
From: Bjarke Berg
Date: Tue, 15 Jan 2019 15:13:10 +0100
Subject: [PATCH 77/84] Revert "Revert "Support IContentType.IsElement""
This reverts commit a5efc25c
---
.../services/umbdataformatter.service.js | 18 +++++++--------
.../permissions/permissions.controller.js | 22 +++++++------------
.../views/permissions/permissions.html | 20 +++++++++++++++--
src/Umbraco.Web.UI/Umbraco/config/lang/en.xml | 2 ++
.../Umbraco/config/lang/en_us.xml | 2 ++
.../ContentTypeCompositionDisplay.cs | 4 ++++
.../Models/ContentEditing/ContentTypeSave.cs | 3 +++
7 files changed, 46 insertions(+), 25 deletions(-)
diff --git a/src/Umbraco.Web.UI.Client/src/common/services/umbdataformatter.service.js b/src/Umbraco.Web.UI.Client/src/common/services/umbdataformatter.service.js
index e31742e660..1e6fc5d643 100644
--- a/src/Umbraco.Web.UI.Client/src/common/services/umbdataformatter.service.js
+++ b/src/Umbraco.Web.UI.Client/src/common/services/umbdataformatter.service.js
@@ -64,7 +64,7 @@
var saveModel = _.pick(displayModel,
'compositeContentTypes', 'isContainer', 'allowAsRoot', 'allowedTemplates', 'allowedContentTypes',
'alias', 'description', 'thumbnail', 'name', 'id', 'icon', 'trashed',
- 'key', 'parentId', 'alias', 'path', 'allowCultureVariant');
+ 'key', 'parentId', 'alias', 'path', 'allowCultureVariant', 'isElement');
//TODO: Map these
saveModel.allowedTemplates = _.map(displayModel.allowedTemplates, function (t) { return t.alias; });
@@ -262,7 +262,7 @@
saveModel[props[m]] = startId.id;
}
- saveModel.parentId = -1;
+ saveModel.parentId = -1;
return saveModel;
},
@@ -293,7 +293,7 @@
});
saveModel.email = propEmail.value.trim();
saveModel.username = propLogin.value.trim();
-
+
saveModel.password = this.formatChangePasswordModel(propPass.value);
var selectedGroups = [];
@@ -336,7 +336,7 @@
/** formats the display model used to display the media to the model used to save the media */
formatMediaPostData: function (displayModel, action) {
- //NOTE: the display model inherits from the save model so we can in theory just post up the display model but
+ //NOTE: the display model inherits from the save model so we can in theory just post up the display model but
// we don't want to post all of the data as it is unecessary.
var saveModel = {
id: displayModel.id,
@@ -354,7 +354,7 @@
/** formats the display model used to display the content to the model used to save the content */
formatContentPostData: function (displayModel, action) {
- //NOTE: the display model inherits from the save model so we can in theory just post up the display model but
+ //NOTE: the display model inherits from the save model so we can in theory just post up the display model but
// we don't want to post all of the data as it is unecessary.
var saveModel = {
id: displayModel.id,
@@ -379,7 +379,7 @@
var propExpireDate = displayModel.removeDate;
var propReleaseDate = displayModel.releaseDate;
var propTemplate = displayModel.template;
-
+
saveModel.expireDate = propExpireDate ? propExpireDate : null;
saveModel.releaseDate = propReleaseDate ? propReleaseDate : null;
saveModel.templateAlias = propTemplate ? propTemplate : null;
@@ -389,8 +389,8 @@
/**
* This formats the server GET response for a content display item
- * @param {} displayModel
- * @returns {}
+ * @param {} displayModel
+ * @returns {}
*/
formatContentGetData: function(displayModel) {
@@ -418,7 +418,7 @@
}
});
});
-
+
//now assign this same invariant property instance to the same index of the other variants property array
for (var j = 1; j < displayModel.variants.length; j++) {
diff --git a/src/Umbraco.Web.UI.Client/src/views/documenttypes/views/permissions/permissions.controller.js b/src/Umbraco.Web.UI.Client/src/views/documenttypes/views/permissions/permissions.controller.js
index 4a7a870618..317fe094ae 100644
--- a/src/Umbraco.Web.UI.Client/src/views/documenttypes/views/permissions/permissions.controller.js
+++ b/src/Umbraco.Web.UI.Client/src/views/documenttypes/views/permissions/permissions.controller.js
@@ -25,6 +25,7 @@
vm.removeChild = removeChild;
vm.toggleAllowAsRoot = toggleAllowAsRoot;
vm.toggleAllowCultureVariants = toggleAllowCultureVariants;
+ vm.toggleIsElement = toggleIsElement;
/* ---------- INIT ---------- */
@@ -84,25 +85,18 @@
$scope.model.allowedContentTypes.splice(selectedChildIndex, 1);
}
- /**
- * Toggle the $scope.model.allowAsRoot value to either true or false
- */
- function toggleAllowAsRoot(){
- if($scope.model.allowAsRoot){
- $scope.model.allowAsRoot = false;
- return;
- }
+ // note: "safe toggling" here ie handling cases where the value is undefined, etc
- $scope.model.allowAsRoot = true;
+ function toggleAllowAsRoot() {
+ $scope.model.allowAsRoot = $scope.model.allowAsRoot ? false : true;
}
function toggleAllowCultureVariants() {
- if ($scope.model.allowCultureVariant) {
- $scope.model.allowCultureVariant = false;
- return;
- }
+ $scope.model.allowCultureVariant = $scope.model.allowCultureVariant ? false : true;
+ }
- $scope.model.allowCultureVariant = true;
+ function toggleIsElement() {
+ $scope.model.isElement = $scope.model.isElement ? false : true;
}
}
diff --git a/src/Umbraco.Web.UI.Client/src/views/documenttypes/views/permissions/permissions.html b/src/Umbraco.Web.UI.Client/src/views/documenttypes/views/permissions/permissions.html
index ec1e528f8c..0d74c655d7 100644
--- a/src/Umbraco.Web.UI.Client/src/views/documenttypes/views/permissions/permissions.html
+++ b/src/Umbraco.Web.UI.Client/src/views/documenttypes/views/permissions/permissions.html
@@ -53,9 +53,25 @@
hotkey="alt+shift+v">
-
+
-
+
+
+
diff --git a/src/Umbraco.Web.UI/Umbraco/config/lang/en.xml b/src/Umbraco.Web.UI/Umbraco/config/lang/en.xml
index 386d3af518..987203442a 100644
--- a/src/Umbraco.Web.UI/Umbraco/config/lang/en.xml
+++ b/src/Umbraco.Web.UI/Umbraco/config/lang/en.xml
@@ -1518,6 +1518,8 @@ To manage your website, simply open the Umbraco back office and start adding con
Allow varying by culture
Allow editors to create content of this type in different languages
Allow varying by culture
+ Is an Element type
+ An Element type is meant to be used for instance in Nested Content, and not in the tree
Building models
diff --git a/src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml b/src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml
index 5de373f571..1860d3afc9 100644
--- a/src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml
+++ b/src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml
@@ -1559,6 +1559,8 @@ To manage your website, simply open the Umbraco back office and start adding con
Allow varying by culture
Allow editors to create content of this type in different languages
Allow varying by culture
+ Is an Element type
+ An Element type is meant to be used for instance in Nested Content, and not in the tree
Add language
diff --git a/src/Umbraco.Web/Models/ContentEditing/ContentTypeCompositionDisplay.cs b/src/Umbraco.Web/Models/ContentEditing/ContentTypeCompositionDisplay.cs
index 7211ddbf61..e5e74c2749 100644
--- a/src/Umbraco.Web/Models/ContentEditing/ContentTypeCompositionDisplay.cs
+++ b/src/Umbraco.Web/Models/ContentEditing/ContentTypeCompositionDisplay.cs
@@ -26,6 +26,10 @@ namespace Umbraco.Web.Models.ContentEditing
[DataMember(Name = "isContainer")]
public bool IsContainer { get; set; }
+ //Element
+ [DataMember(Name = "isElement")]
+ public bool IsElement { get; set; }
+
[DataMember(Name = "listViewEditorName")]
[ReadOnly(true)]
public string ListViewEditorName { get; set; }
diff --git a/src/Umbraco.Web/Models/ContentEditing/ContentTypeSave.cs b/src/Umbraco.Web/Models/ContentEditing/ContentTypeSave.cs
index c2ec70d3dc..b1d24c5fd2 100644
--- a/src/Umbraco.Web/Models/ContentEditing/ContentTypeSave.cs
+++ b/src/Umbraco.Web/Models/ContentEditing/ContentTypeSave.cs
@@ -25,6 +25,9 @@ namespace Umbraco.Web.Models.ContentEditing
[DataMember(Name = "isContainer")]
public bool IsContainer { get; set; }
+ [DataMember(Name = "isElement")]
+ public bool IsElement { get; set; }
+
[DataMember(Name = "allowAsRoot")]
public bool AllowAsRoot { get; set; }
From f9cd22d908ddfbfb09dd8ef0b6d033b1f32f18d1 Mon Sep 17 00:00:00 2001
From: Robert
Date: Tue, 15 Jan 2019 15:43:10 +0100
Subject: [PATCH 78/84] Added a comment explaining why we need the delay
---
.../src/common/services/editor.service.js | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/src/Umbraco.Web.UI.Client/src/common/services/editor.service.js b/src/Umbraco.Web.UI.Client/src/common/services/editor.service.js
index c495c4e7a1..721efe251c 100644
--- a/src/Umbraco.Web.UI.Client/src/common/services/editor.service.js
+++ b/src/Umbraco.Web.UI.Client/src/common/services/editor.service.js
@@ -245,7 +245,9 @@ When building a custom infinite editor view you can use the same components as a
// emit event to let components know an editor has been removed
eventsService.emit("appState.editors.close", args);
-
+
+ // delay required to map the properties to the correct editor due
+ // to another delay in the closing animation of the editor
$timeout(function() {
// rebind keyboard shortcuts for the new editor in focus
rebindKeyboardShortcuts();
From 1bd5127bcf6d05b2f38a0c0121ae1e399c6ae63c Mon Sep 17 00:00:00 2001
From: Stephan
Date: Tue, 15 Jan 2019 17:27:18 +0100
Subject: [PATCH 79/84] Actually run HealthCheck notifier
---
src/Umbraco.Web/Scheduling/SchedulerComponent.cs | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/Umbraco.Web/Scheduling/SchedulerComponent.cs b/src/Umbraco.Web/Scheduling/SchedulerComponent.cs
index e4bc74b7f2..cd4f5ac933 100644
--- a/src/Umbraco.Web/Scheduling/SchedulerComponent.cs
+++ b/src/Umbraco.Web/Scheduling/SchedulerComponent.cs
@@ -149,6 +149,7 @@ namespace Umbraco.Web.Scheduling
var periodInMilliseconds = healthCheckConfig.NotificationSettings.PeriodInHours * 60 * 60 * 1000;
var task = new HealthCheckNotifier(_healthCheckRunner, delayInMilliseconds, periodInMilliseconds, healthChecks, notifications, _runtime, logger);
+ _healthCheckRunner.TryAdd(task);
return task;
}
From 477075662163857ba32cea0a4989f1ab9438f7f4 Mon Sep 17 00:00:00 2001
From: Stephan
Date: Tue, 15 Jan 2019 18:41:02 +0100
Subject: [PATCH 80/84] Bugfix ContentCacheRefresher
---
src/Umbraco.Web/Cache/ContentCacheRefresher.cs | 10 ++++------
1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/src/Umbraco.Web/Cache/ContentCacheRefresher.cs b/src/Umbraco.Web/Cache/ContentCacheRefresher.cs
index 22f1554269..b0192e9e75 100644
--- a/src/Umbraco.Web/Cache/ContentCacheRefresher.cs
+++ b/src/Umbraco.Web/Cache/ContentCacheRefresher.cs
@@ -44,16 +44,14 @@ namespace Umbraco.Web.Cache
public override void Refresh(JsonPayload[] payloads)
{
- var runtimeCache = Current.ApplicationCache.RuntimeCache;
-
- runtimeCache.ClearCacheObjectTypes();
+ CacheHelper.RuntimeCache.ClearCacheObjectTypes();
var idsRemoved = new HashSet();
+ var isolatedCache = CacheHelper.IsolatedRuntimeCache.GetOrCreateCache();
foreach (var payload in payloads)
{
- // remove that one
- runtimeCache.ClearCacheItem(RepositoryCacheKeys.GetKey(payload.Id));
+ isolatedCache.ClearCacheItem(RepositoryCacheKeys.GetKey(payload.Id));
_idkMap.ClearCache(payload.Id);
@@ -61,7 +59,7 @@ namespace Umbraco.Web.Cache
if (payload.ChangeTypes.HasTypesAny(TreeChangeTypes.RefreshBranch | TreeChangeTypes.Remove))
{
var pathid = "," + payload.Id + ",";
- runtimeCache.ClearCacheObjectTypes((k, v) => v.Path.Contains(pathid));
+ isolatedCache.ClearCacheObjectTypes((k, v) => v.Path.Contains(pathid));
}
//if the item is being completely removed, we need to refresh the domains cache if any domain was assigned to the content
From eb3d3e129c8a96583155239a85efacd1b825199f Mon Sep 17 00:00:00 2001
From: Stephan
Date: Tue, 15 Jan 2019 19:15:06 +0100
Subject: [PATCH 81/84] Bugfix package service
---
src/Umbraco.Core/Services/Implement/PackagingService.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/Umbraco.Core/Services/Implement/PackagingService.cs b/src/Umbraco.Core/Services/Implement/PackagingService.cs
index 8f6c287cf1..99ee7a098b 100644
--- a/src/Umbraco.Core/Services/Implement/PackagingService.cs
+++ b/src/Umbraco.Core/Services/Implement/PackagingService.cs
@@ -579,7 +579,7 @@ namespace Umbraco.Core.Services.Implement
contentType.IsContainer = isListView.Value.InvariantEquals("true");
var isElement = infoElement.Element("IsElement");
- if (isListView != null)
+ if (isElement != null)
contentType.IsElement = isElement.Value.InvariantEquals("true");
//Name of the master corresponds to the parent and we need to ensure that the Parent Id is set
From d4edbc8e791a9d944c737e0882b973672787147a Mon Sep 17 00:00:00 2001
From: Stephan
Date: Tue, 15 Jan 2019 19:38:52 +0100
Subject: [PATCH 82/84] Fix tests
---
.../PublishedContent/PublishedContentTests.cs | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/src/Umbraco.Tests/PublishedContent/PublishedContentTests.cs b/src/Umbraco.Tests/PublishedContent/PublishedContentTests.cs
index ab65ac82b1..603464e18b 100644
--- a/src/Umbraco.Tests/PublishedContent/PublishedContentTests.cs
+++ b/src/Umbraco.Tests/PublishedContent/PublishedContentTests.cs
@@ -69,8 +69,9 @@ namespace Umbraco.Tests.PublishedContent
factory.CreatePropertyType("testRecursive", 1),
};
var compositionAliases = new[] { "MyCompositionAlias" };
- var type = new AutoPublishedContentType(0, "anything", compositionAliases, propertyTypes);
- ContentTypesCache.GetPublishedContentTypeByAlias = alias => type;
+ var anythingType = new AutoPublishedContentType(0, "anything", compositionAliases, propertyTypes);
+ var homeType = new AutoPublishedContentType(0, "home", compositionAliases, propertyTypes);
+ ContentTypesCache.GetPublishedContentTypeByAlias = alias => alias.InvariantEquals("home") ? homeType : anythingType;
}
protected override TypeLoader CreateTypeLoader(IRuntimeCacheProvider runtimeCache, IGlobalSettings globalSettings, IProfilingLogger logger)
@@ -236,6 +237,7 @@ namespace Umbraco.Tests.PublishedContent
public void Is_Last_From_Where_Filter2()
{
var doc = GetNode(1173);
+ var ct = doc.ContentType;
var items = doc.Children
.Select(x => x.CreateModel()) // linq, returns IEnumerable
@@ -454,11 +456,11 @@ namespace Umbraco.Tests.PublishedContent
{
var doc = GetNode(1046); // has child nodes
- var model = doc.FirstChild(x => true); // predicate
+ var model = doc.FirstChild(x => true); // predicate
Assert.IsNotNull(model);
Assert.IsTrue(model.Id == 1173);
- Assert.IsInstanceOf(model);
+ Assert.IsInstanceOf(model);
Assert.IsInstanceOf(model);
doc = GetNode(1175); // does not have child nodes
From 26b31f1fc88598bb1a201c55c4c06d269ceec438 Mon Sep 17 00:00:00 2001
From: Stephan
Date: Wed, 16 Jan 2019 10:01:04 +0100
Subject: [PATCH 83/84] Fix Git repository issue with casing of some filepaths
---
src/Umbraco.Web.UI/umbraco/config/lang/nb.xml | 963 -------------
.../umbraco/config/lang/zh_tw.xml | 1269 -----------------
2 files changed, 2232 deletions(-)
delete mode 100644 src/Umbraco.Web.UI/umbraco/config/lang/nb.xml
delete mode 100644 src/Umbraco.Web.UI/umbraco/config/lang/zh_tw.xml
diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/nb.xml b/src/Umbraco.Web.UI/umbraco/config/lang/nb.xml
deleted file mode 100644
index d51d41e558..0000000000
--- a/src/Umbraco.Web.UI/umbraco/config/lang/nb.xml
+++ /dev/null
@@ -1,963 +0,0 @@
-
-
-
- The Umbraco community
- http://our.umbraco.org/documentation/Extending-Umbraco/Language-Files
-
-
- Angi domene
- Revisjoner
- Bla gjennom
- Skift dokumenttype
- Kopier
- Opprett
- Opprett pakke
- Slett
- Deaktiver
- Tøm papirkurv
- Eksporter dokumenttype
- Importer dokumenttype
- Importer pakke
- Rediger i Canvas
- Logg av
- Flytt
- Varslinger
- Offentlig tilgang
- Publiser
- Avpubliser
- Oppdater noder
- Republiser hele siten
- Gjenopprett
- Rettigheter
- Reverser
- Send til publisering
- Send til oversetting
- Sorter
- Oversett
- Oppdater
-
-
- Ingen tilgang.
- Legg til domene
- Fjern
- Ugyldig node.
- Ugyldig domeneformat.
- Domene er allerede tilknyttet.
- Språk
- Domene
- Domene '%0%' er nå opprettet og tilknyttet siden
- Domenet '%0%' er nå slettet
- Domenet '%0%' er allerede tilknyttet
- Domenet '%0%' er nå oppdatert
- eller rediger eksisterende domener
- Stier med ett nivå støttes, f.eks. "eksempel.com/no". Imidlertid bør det unngås. Bruk heller språkinnstillingen over.]]>
- Arv
- Språk
- Vil også gjelde denne noden, med mindre et underordnet domene også gjelder.]]>
- Domener
-
-
- Viser for
-
-
- Velg
- Gjør noe annet
- Fet
- Reduser innrykk
- Sett inn skjemafelt
- Sett inn grafisk overskrift
- Rediger HTML
- Øk innrykk
- Kursiv
- Midtstill
- Juster tekst venstre
- Juster tekst høyre
- Sett inn lenke
- Sett inn lokal lenke (anker)
- Punktmerking
- Nummerering
- Sett inn makro
- Sett inn bilde
- Rediger relasjoner
- Tilbake til listen
- Lagre
- Lagre og publiser
- Lagre og planlegge
- Lagre og send til publisering
- Forhåndsvis
- Forhåndsvisning er deaktivert siden det ikke er angitt noen mal
- Velg formattering
- Vis stiler
- Sett inn tabell
-
-
- For å endre det valge innholdets dokumenttype, velger du først en ny dokumenttype som er gyldig på gjeldende plassering.
- Kontroller deretter at alle egenskaper blir overført riktig til den nye dokumenttypen og klikk på Lagre.
- Innholdet har blitt republisert.
- Nåværende egenskap
- Nåværende type
- Du kan ikke endre dokumenttype, ettersom det ikke er andre gyldige dokumenttyper på denne plasseringen.
- Dokumenttype endret
- Overfør egenskaper
- Overfør til egenskap
- Ny mal
- Ny type
- ingen
- Innhold
- Velg ny dokumenttype
- Dokumenttypen på det valgte innhold ble endret til [new type], og følgende egenskaper ble overført:
- til
- Overføringen av egenskaper kunne ikke fullføres da en eller flere egenskaper er satt til å bli overført mer enn en gang.
- Kun andre dokumenttyper som er gyldige for denne plasseringen vises.
-
-
- Publisert
- Om siden
- Alias
- (hvordan du ville beskrevet bildet over telefon)
- Alternative lenker
- Klikk for å redigere denne noden
- Opprettet av
- Opprinnelig forfatter
- Oppdatert av
- Opprettet den
- Tidspunkt for opprettelse
- Dokumenttype
- Redigerer
- Utløpsdato
- Denne noden er endret siden siste publisering
- Denne noden er enda ikke publisert
- Sist publisert
- Det er ingen elementer å vise i listen.
- Mediatype
- Link til media
- Medlemsgruppe
- Rolle
- Medlemstype
- Ingen dato valgt
- Sidetittel
- Egenskaper
- Dette dokumentet er publisert, men ikke synlig ettersom den overliggende siden '%0%' ikke er publisert
- Intern feil: dokumentet er publisert men finnes ikke i hurtigbuffer
- Publisert
- Publiseringsstatus
- Publiseringsdato
- Dato for avpublisering
- Fjern dato
- Sorteringsrekkefølgen er oppdatert
- Trekk og slipp nodene eller klikk på kolonneoverskriftene for å sortere. Du kan velge flere noder ved å holde shift eller control tastene mens du velger.
- Statistikk
- Tittel (valgfri)
- Alternativ tekst (valgfri)
- Type
- Avpubliser
- Sist endret
- Tidspunkt for siste endring
- Fjern fil
- Lenke til dokument
- Medlem av gruppe(ne)
- Ikke medlem av gruppe(ne)
- Undersider
- Åpne i vindu
-
-
- Klikk for å laste opp
-
-
- Opprett et nytt medlem
- Alle medlemmer
-
-
- Hvor ønsker du å oprette den nye %0%
- Opprett under
- Velg en type og skriv en tittel
- "dokumenttyper".]]>
- "mediatyper".]]>
-
-
- Til ditt nettsted
- - Skjul
- Hvis Umbraco ikke starter, kan det skyldes at pop-up vinduer ikke er tillatt
- er åpnet i nytt vindu
- Omstart
- Besøk
- Velkommen
-
-
- Stay
- Discard changes
- You have unsaved changes
- Are you sure you want to navigate away from this page? - you have unsaved changes
-
-
- Done
- Deleted %0% item
- Deleted %0% items
- Deleted %0% out of %1% item
- Deleted %0% out of %1% items
- Published %0% item
- Published %0% items
- Published %0% out of %1% item
- Published %0% out of %1% items
- Unpublished %0% item
- Unpublished %0% items
- Unpublished %0% out of %1% item
- Unpublished %0% out of %1% items
- Moved %0% item
- Moved %0% items
- Moved %0% out of %1% item
- Moved %0% out of %1% items
- Copied %0% item
- Copied %0% items
- Copied %0% out of %1% item
- Copied %0% out of %1% items
-
-
- Navn på lokal link
- Rediger domener
- Lukk dette vinduet
- Er du sikker på at du vil slette
- Er du sikker på at du vil deaktivere
- Er du sikker på at du vil forlate Umbraco?
- Er du sikker?
- Klipp ut
- Rediger ordboksnøkkel
- Rediger språk
- Sett inn lokal link
- Sett inn spesialtegn
- Sett inn grafisk overskrift
- Sett inn bilde
- Sett inn lenke
- Sett inn makro
- Sett inn tabell
- Sist redigert
- Lenke
- Intern link:
- Ved lokal link, sett inn "#" foran link
- Åpne i nytt vindu?
- Makroinnstillinger
- Denne makroen har ingen egenskaper du kan endre
- Lim inn
- Endre rettigheter for
- Innholdet i papirkurven blir nå slettet. Vennligst ikke lukk dette vinduet mens denne operasjonen foregår
- Papirkurven er nå tom
- Når elementer blir slettet fra papirkurven vil de være slettet for alltid
- regexlib.com tjenesten opplever for tiden problemer som vi ikke har kontroll over. Vi beklager denne ubeleiligheten.]]>
- Søk etter et regulært uttrykk for å legge inn validering til et felt. Eksempel: 'email, 'zip-code' 'url'
- Fjern makro
- Obligatorisk
- Nettstedet er indeksert
- Hurtigbufferen er blitt oppdatert. Alt publisert innhold er nå à jour. Alt upublisert innhold er fortsatt ikke publisert.
- Hurtigbufferen for siden vil bli oppdatert. Alt publisert innhold vil bli oppdatert, mens upublisert innhold vil forbli upublisert.
- Antall kolonner
- Antall rader
- Sett en plassholder-ID Ved å sette en ID på plassholderen kan du legge inn innhold i denne malen fra underliggende maler, ved å referere denne ID'en ved hjelp av et <asp:content /> element.]]>
- Velg en plassholder ID fra listen under. Du kan bare velge ID'er fra den gjeldende malens overordnede mal.]]>
- Klikk på bildet for å se det i full størrelse
- Velg punkt
- Se buffret node
-
-
- %0%' under. Du kan legge til flere språk under 'språk' i menyen til venstre.]]>
- Språk
-
-
- Skriv inn ditt brukernavn
- Skriv inn ditt passord
- Navngi %0%...
- Skriv inn navn...
- Søk...
- Filtrer...
- Skriv inn nøkkelord (trykk på Enter etter hvert nøkkelord)...
-
-
- Tillatte underordnede noder
- Opprett
- Slett arkfane
- Beskrivelse
- Ny arkfane
- Arkfane
- Miniatyrbilde
- Opprett brukerdefinert listevisning
- Fjern brukerdefinert listevisning
-
-
- Legg til forhåndsverdi
- Database datatype
- Kontrollelement GUID
- Kontrollelement
- Knapper
- Aktiver avanserte instillinger for
- Aktiver kontektsmeny
- Maksimum standard størrelse på innsatte bilder
- Beslektede stilark
- Vis etikett
- Bredde og høyde
-
-
- Dine data har blitt lagret, men før du kan publisere denne siden må du rette noen feil:
- Den gjeldende Membership Provider støtter ikke endring av passord. (EnablePasswordRetrieval må være satt til sann)
- %0% finnes allerede
- Det var feil i dokumentet:
- Det var feil i skjemaet:
- Passordet bør være minst %0% tegn og inneholde minst %1% numeriske tegn
- %0% må være et heltall
- %0% under %1% er obligatorisk
- %0% er obligatorisk
- %0% under %1% er ikke i et korrekt format
- %0% er ikke i et korrekt format
-
-
- Filtypen er deaktivert av administrator
- NB! Selv om CodeMirror er aktivert i konfigurasjon er det deaktivert i Internet Explorer pga. ustabilitet.
- Fyll ut både alias og navn på den nye egenskapstypen!
- Det er et problem med lese/skrive rettighetene til en fil eller mappe
- Tittel mangler
- Type mangler
- Du er i ferd med å gjøre bildet større enn originalen. Det vil forringe kvaliteten på bildet, ønsker du å fortsette?
- Startnode er slettet. Kontakt din administrator
- Du må markere innhold før du kan endre stil
- Det er ingen aktive stiler eller formateringer på denne siden
- Sett markøren til venstre i de 2 cellene du ønsker å slå sammen
- Du kan ikke dele en celle som allerede er delt.
-
-
- Om
- Handling
- Muligheter
- Legg til
- Alias
- Er du sikker?
- Ramme
- av
- Avbryt
- Cellemargin
- Velg
- Lukk
- Lukk vindu
- Kommentar
- Bekreft
- Behold proposjoner
- Fortsett
- Kopier
- Opprett
- Database
- Dato
- Standard
- Slett
- Slettet
- Sletter...
- Design
- Dimensjoner
- Ned
- Last ned
- Rediger
- Endret
- Elementer
- E-post
- Feil
- Finn
- Høyde
- Hjelp
- Ikon
- Importer
- Indre margin
- Sett inn
- Installer
- Justering
- Språk
- Layout
- Laster
- Låst
- Logg inn
- Logg ut
- Logg ut
- Makro
- Flytt
- Navn
- Ny
- Neste
- Nei
- av
- OK
- Åpne
- eller
- Passord
- Sti
- Plassholder ID
- Ett øyeblikk...
- Forrige
- Egenskaper
- E-post som innholdet i skjemaet skal sendes til
- Papirkurv
- Gjenværende
- Gi nytt navn
- Forny
- Påkrevd
- Prøv igjen
- Rettigheter
- Søk
- Server
- Vis
- Hvilken side skal vises etter at skjemaet er sendt
- Størrelse
- Sorter
- Send
- Type
- Søk...
- Opp
- Oppdater
- Oppgrader
- Last opp
- Url
- Bruker
- Brukernavn
- Verdi
- Visning
- Velkommen...
- Bredde
- Ja
- Mappe
- Søkeresultater
- Sorter
- Avslutt sortering
- Eksempel
- Bytt passord
- til
- Listevisning
- Lagrer...
- nåværende
- Innbygging
- Hent
- valgt
-
-
- Bakgrunnsfarge
- Fet
- Tekstfarge
- Skrifttype
- Tekst
-
-
- Side
-
-
- Installasjonsprogrammet kan ikke koble til databasen
- Kunne ikke lagre Web.Config-filen. Vennligst endre databasens tilkoblingsstreng manuelt.
- Din database er funnet og identifisert som
- Databasekonfigurasjon
- installer-knappen for å installere Umbraco %0% databasen]]>
- Neste for å fortsette.]]>
- Databasen ble ikke funnet! Vennligst sjekk at informasjonen i "connection string" i "web.config"-filen er korrekt.
For å fortsette, vennligst rediger "web.config"-filen (bruk Visual Studio eller din favoritteditor), rull ned til bunnen, og legg til tilkoblingsstrengen for din database i nøkkelen "umbracoDbDSN" og lagre filen.
Klikk prøv på nytt når du er ferdig. Mer informasjon om redigering av web.config her.
]]>
- Vennligst kontakt din ISP om nødvendig. Hvis du installerer på en lokal maskin eller server, må du kanskje skaffe informasjonen fra din systemadministrator.]]>
- Trykk på knappen oppgrader for å oppgradere databasen din til Umbraco %0% Ikke vær urolig - intet innhold vil bli slettet og alt vil fortsette å virke etterpå!
]]>
- Trykk Neste for å fortsette.]]>
- neste for å fortsette konfigurasjonsveiviseren]]>
- Passordet til standardbrukeren må endres!]]>
- Standardbrukeren har blitt deaktivert eller har ingen tilgang til Umbraco!Ingen videre handling er nødvendig. Klikk neste for å fortsette.]]>
- Passordet til standardbrukeren har blitt forandret etter installasjonen!Ingen videre handling er nødvendig. Klikk Neste for å fortsette.]]>
- Passordet er blitt endret!
- Få en god start med våre introduksjonsvideoer
- Ved å klikke på Neste-knappen (eller endre UmbracoConfigurationStatus i Web.config), godtar du lisensen for denne programvaren som angitt i boksen nedenfor. Legg merke til at denne Umbraco distribusjon består av to ulike lisenser, åpen kilde MIT lisens for rammen og Umbraco frivareverktøy lisens som dekker brukergrensesnittet.
- Ikke installert.
- Berørte filer og mapper
- Mer informasjon om å sette opp rettigheter for Umbraco her
- Du må gi ASP.NET brukeren rettigheter til å endre de følgende filer og mapper
- Rettighetene er nesten perfekt satt opp! Du kan kjøre Umbraco uten problemer, men du vil ikke være i stand til å installere de anbefalte pakkene for å utnytte Umbraco fullt ut.]]>
- Hvordan løse problemet
- Klikk her for å lese tekstversjonen
- innføringsvideo om å sette opp rettigheter for Umbraco eller les tekstversjonen.]]>
- Rettighetsinnstillingene kan være et problem! Du kan kjøre Umbraco uten problemer, men du vil ikke være i stand til å installere de anbefalte pakkene for å utnytte Umbraco fullt ut.]]>
- Rettighetsinstillingene er ikke klargjort for Umbraco! For å kunne kjøre Umbraco, må du oppdatere rettighetsinnstillingene dine.]]>
- Rettighetsinnstillingene er perfekt! Du er klar for å kjøre Umbraco og installere pakker!]]>
- Løser mappeproblem
- Følg denne linken for mer informasjon om problemer med ASP.NET og oppretting av mapper
- Konfigurerer mappetillatelser
-
- Jeg ønsker å starte fra bunnen.
- lær hvordan) Du kan fortsatt velge å installere Runway senere. Vennligst gå til Utvikler-seksjonen og velg Pakker.]]>
- Du har akkurat satt opp en ren Umbraco plattform. Hva vil du gjøre nå?
- Runway er installert
- Dette er vår liste av anbefalte moduler- Kryss av de du ønsker å installere, eller se denfulle listen av moduler ]]>
- Bare anbefalt for erfarne brukere
- Jeg vil starte med en enkel webside
- "Runway" er en enkel webside som utstyrer deg med noen grunnleggende dokumenttyper og maler. Veiviseren kan sette opp Runway for deg automatisk, men du kan enkelt endre, utvide eller slette den. Runway er ikke nødvendig, og du kan enkelt bruke Umbraco uten den. Imidlertidig tilbyr Runway et enkelt fundament basert på de beste metodene for å hjelpe deg i gang fortere enn noensinne. Hvis du velger å installere Runway, kan du også velge blant grunnleggende byggeklosser kalt Runway Moduler for å forøke dine Runway-sider. Sider inkludert i Runway: Hjemmeside, Komme-i-gang, Installere moduler. Valgfrie Moduler: Toppnavigasjon, Sidekart, Kontakt, Galleri. ]]>
- Hva er Runway
- Steg 1/5 Godta lisens
- Steg 2/5 Database konfigurasjon
- Steg 3/5: Valider filrettigheter
- Steg 4/5: Skjekk Umbraco sikkerheten
- Steg 5/5: Umbraco er klar for deg til å starte!
- Tusen takk for at du valgte Umbraco!
- Se ditt nye nettsted Du har installert Runway, hvorfor ikke se hvordan ditt nettsted ser ut.]]>
- Mer hjelp og info Få hjelp fra vårt prisbelønte samfunn, bla gjennom dokumentasjonen eller se noen gratis videoer på hvordan man bygger et enkelt nettsted, hvordan bruke pakker og en rask guide til Umbraco terminologi]]>
- Umbraco %0% er installert og klar til bruk
- web.config filen, og oppdatere AppSetting-nøkkelen UmbracoConfigurationStatus til verdien '%0%' ]]>
- starte øyeblikkelig ved å klikke på "Start Umbraco" knappen nedenfor. Hvis du er ny på Umbraco , kan du finne mange ressurser på våre komme-i-gang sider.]]>
- Start Umbraco For å administrere din webside, åpne Umbraco og begynn å legge til innhold, oppdatere maler og stilark eller utvide funksjonaliteten]]>
- Tilkobling til databasen mislyktes.
- Umbraco Versjon 3
- Umbraco Versjon 4
- Se
- Umbraco %0% for en ny installasjon eller oppgradering fra versjon 3.0. Trykk "neste" for å starte veiviseren.]]>
-
-
- Språkkode
- Språk
-
-
- Du har vært inaktiv og vil logges ut automatisk om
- Forny innlogging for å lagre
-
-
- Da er det søndag!
- Smil, det er mandag!
- Hurra, det er tirsdag!
- For en herlig onsdag!
- Gledelig torsdag!
- Endelig fredag!
- Gledelig lørdag
- Logg på nedenfor
- Logg på med
- Din sesjon er utløpt
- © 2001 - %0% umbraco.com ]]>
-
-
- Skrivebord
- Seksjoner
- Innhold
-
-
- Velg side over...
- %0% er nå kopiert til %1%
- Kopier til
- %0% er nå flyttet til %1%
- Flytt til
- har blitt valgt som rot til ditt nye innhold, klikk 'ok' nedenfor.
- Ingen node er valgt, vennligst velg en node i listen over før du klikker 'fortsett'
- Gjeldende nodes type tillates ikke under valgt node
- Gjeldende node kan ikke legges under en underordnet node
- Denne noden kan ikke ligge på rotnivå
- Handlingen tillates ikke. Du mangler tilgang til en eller flere underordnede noder.
- Relater kopierte elementer til original(e)
-
-
- Rediger dine varsler for %0%
-
- Hei %0%
-
- Dette er en automatisk mail for å informere om at handlingen '%1%'
- er blitt utført på siden '%2%'
- av brukeren '%3%'
-
-
-
-
Rettelser:
-
-
-
-
-
- Ha en fin dag!
- Vennlig hilsen Umbraco roboten
-
]]>
- [%0%] Varsling om %1% utført på %2%
- Varslinger
-
-
- Umbraco-pakker har vanligvis endelsen ".umb" eller ".zip".]]>
- Utvikler
- Demonstrasjon
- Dokumentasjon
- Metadata
- Pakkenavn
- Pakken inneholder ingen elementer
- Du kan trygt fjerne pakken fra systemet ved å klikke "avinstaller pakke" nedenfor.]]>
- Ingen oppdateringer tilgjengelig
- Alternativer for pakke
- Lesmeg for pakke
- Pakkebrønn
- Bekreft avinstallering
- Pakken ble avinstallert
- Pakken ble vellykket avinstallert
- Avinstaller pakke
- Advarsel: alle dokumenter, media, etc. som som er avhengig av elementene du sletter, vil slutte å virke, noe som kan føre til ustabilitet, så avinstaller med forsiktighet. Hvis du er i tvil, kontakt pakkeutvikleren.]]>
- Last ned oppdatering fra pakkeregisteret
- Oppgrader pakke
- Oppgraderingsinstrukser
- Det er en oppdatering tilgjengelig for denne pakken. Du kan laste den ned direkte fra pakkebrønnen.
- Pakkeversjon
- Pakkeversjonshistorie
- Se pakkens nettsted
-
-
- Lim inn med full formattering (Anbefales ikke)
- Teksten du er i ferd med å lime inn, inneholder spesialtegn eller formattering. Dette kan skyldes at du kopierer fra f.eks. Microsoft Word. Umbraco kan fjerne denne spesialformatteringen automatisk slik at innholdet er mer velegnet for visning på en webside.
- Lim inn som ren tekst, dvs. fjern al formattering
- Lim inn og fjern uegnet formatering (anbefalt)
-
-
- Avansert: Beskytt ved å velge hvilke brukergrupper som har tilgang til siden
- ved å bruke Umbraco's medlems-grupper]]>
- Du må opprette en medlemsgruppe før du kan bruke rollebasert autentikasjon.
- Feilside
- Brukt når personer logger på, men ikke har tilgang
- Hvordan vil du beskytte siden din?
- %0% er nå beskyttet
- Beskyttelse fjernet fra %0%
- Innloggingsside
- Velg siden som har loginformularet
- Fjern beskyttelse
- Velg sidene som inneholder login-skjema og feilmelding ved feil innolgging.
- Velg rollene som har tilgang til denne siden
- Sett brukernavn og passord for denne siden
- Enkelt: Beskytt ved hjelp av brukernavn og passord
- Om du ønsker å bruke enkel autentisering via ett enkelt brukernavn og passord
-
-
- %0% kunne ikke publiseres fordi den har planlagt utgivelsesdato.
- %0% ble ikke publisert. Ett eller flere felter ble ikke godkjent av validering.
- %0% kunne ikke publiseres fordi et tredjepartstillegg avbrøt handlingen.
- %0% kan ikke publiseres fordi en overordnet side ikke er publisert.
- Inkluder upubliserte undersider
- Publiserer - vennligst vent...
- %0% av %1% sider har blitt publisert...
- %0% er nå publisert
- %0% og alle undersider er nå publisert
- Publiser alle undersider
- ok for å publisere %0% og dermed gjøre innholdet synlig for alle. Du kan publisere denne siden og alle dens undersider ved å krysse av Publiser alle undersider nedenfor.]]>
-
-
- Du har ikke konfigurert noen godkjente farger
-
-
- skriv inn ekstern lenke
- velg en intern side
- Tittel
- Lenke
- Åpne i nytt vindu
- Skriv inn en tekst
- Skriv inn en lenke
-
-
- Nullstill
-
-
- Gjeldende versjon
- Rød tekst vil ikke bli vist i den valgte versjonen. , grønn betyr lagt til ]]>
- Dokumentet er tilbakeført til en tidligere versjon
- Dette viser den valgte versjonen som HTML, bruk avviksvisningen hvis du ønsker å se forksjellene mellom to versjoner samtidig.
- Tilbakefør til
- Velg versjon
- Vis
-
-
- Rediger scriptfilen
-
-
- Concierge
- Innhold
- Courier
- Utvikler
- Umbraco konfigurasjonsveiviser
- Mediaarkiv
- Medlemmer
- Nyhetsbrev
- Innstillinger
- Statistikk
- Oversettelse
- Brukere
- Hjelp
- Skjemaer
-
-
- De beste Umbraco opplæringsvideoer
-
-
- Standardmal
- Ordboksnøkkel
- For å importere en dokumenttype, finn ".udt" filen på datamaskinen din ved å klikke "Utforsk" knappen og klikk "Importer" (du vil bli spurt om bekreftelse i det neste skjermbildet)
- Ny tittel på arkfane
- Nodetype
- Type
- Stilark
- Script
- Stilark-egenskap
- Arkfane
- Tittel på arkfane
- Arkfaner
- Hovedinnholdstype aktivert
- Denne dokumenttypen bruker
- som hoveddokumenttype. Arkfaner fra hoveddokumenttyper vises ikke og kan kun endres på hoveddokumenttypen selv.
- Ingen egenskaper definert i denne arkfanen. Klikk på "legg til ny egenskap" lenken i toppen for å opprette en ny egenskap.
-
-
- Sort order
- Creation date
- Sortering ferdig.
- Dra elementene opp eller ned for å arrangere dem. Du kan også klikke kolonneoverskriftene for å sortere alt på en gang.
-
-
-
- En feil oppsto
- Utilstrekkelige brukertillatelser, kunne ikke fullføre operasjonen
- Avbrutt
- Handlingen ble avbrutt av et tredjepartstillegg
- Publisering ble avbrutt av et tredjepartstillegg
- Egenskaptypen finnes allerede
- Egenskapstype opprettet
- DataType: %1%]]>
- Egenskapstype slettet
- Innholdstype lagret
- Du har opprettet en arkfane
- Arkfane slettet
- Arkfane med id: %0% slettet
- Stilarket ble ikke lagret
- Stilarket ble lagret
- Stilark lagret uten feil
- Datatype lagret
- Ordbokelement lagret
- Publiseringen feilet fordi den overliggende siden ikke er publisert
- Innhold publisert
- og er nå synlig for besøkende
- Innhold lagret
- Husk å publisere for å gjøre endringene synlig for besøkende
- Sendt for godkjenning
- Endringer har blitt sendt til godkjenning
- Media lagret
- Media lagret uten feil
- Medlem lagret
- Stilarksegenskap lagret
- Stilark lagret
- Mal lagret
- Feil ved lagring av bruker (sjekk loggen)
- Bruker lagret
- Brukertypen lagret
- Filen ble ikke lagret
- Filen kunne ikke lagres. Vennligst sjekk filrettigheter
- Filen ble lagret
- Filen ble lagret uten feil
- Språk lagret
- Malen ble ikke lagret
- Vennligst forviss deg om at du ikke har to maler med samme alias
- Malen ble lagret
- Malen ble lagret uten feil!
- Innhold avpublisert
- Delmal lagret
- Delmal lagret uten feil
- Delmal ble ikke lagret!
- En feil oppsto ved lagring av delmal
-
-
- Bruk CSS syntaks f.eks: h1, .redHeader, .blueText
- Rediger stilark
- Rediger egenskap for stilark
- Navn for å identifisere stilarksegenskapen i rik-tekst editoren
- Forhåndsvis
- Stiler
-
-
- Rediger mal
- Sett inn innholdsområde
- Sett inn plassholder for innholdsområde
- Sett inn ordbokselement
- Sett inn makro
- Sett inn Umbraco sidefelt
- Hovedmal
- Hurtigguide til Umbraco sine maltagger
- Mal
-
-
- Image
- Macro
- Sett inn element
- Velg layout
- Legg til rad
- Legg til innhold
- Slipp innhold
- Raden har tilpasset design
- Innholdstypen er ikke tillatt her
- Innholdstypen er tillatt her
- Klikk for å bygge inn
- Klikk for å sette inn et bilde
- Bildetekst...
- Skriv her...
- Rutenettoppsett
- Et oppsett er det overordnede arbeidsområdet til ditt rutenett - du vil typisk kun behøve ett eller to
- Legg til rutenettoppsett
- Juster oppsettet ved å konfigurere kolonnebredder og legge til ytterligere seksjoner
- Radkonfigurasjoner
- Rader er forhåndsdefinerte celler arrangert vannrett
- Legg til radkonfigurasjon
- Juster raden ved å sette cellebredder og legge til flere celler
- Kolonner
- Totalt antall kolonner i rutenettet
- Innstillinger
- Konfigurer hvilke innstillinger brukeren kan endre
- Stiler
- Konfigurer hvilke stiler redaktørene kan endre
- Tillatt alle editorer
- Tillat alle radkonfigurasjoner
- Bruk som standard
- Velg ekstra
- Velg standard
- er lagt til
-
-
- Alternativt felt
- Alternativ tekst
- Store/små bokstaver
- Encoding
- Felt som skal settes inn
- Konverter linjeskift
- Erstatter et linjeskift med htmltaggen <br>
- Egendefinerte felt
- Ja, kun dato
- Formatter som dato
- HTML koding
- Formater spesialtegn med tilsvarende HTML-tegn.
- Denne teksten vil settes inn etter verdien av feltet
- Denne teksten vil settes inn før verdien av feltet
- Små bokstaver
- Ingen
- Sett inn etter felt
- Sett inn før felt
- Rekursivt
- Standardfelter
- Store bokstaver
- URL koding
- Dersom innholdet av feltene skal sendes til en URL skal spesialtegn formatteres
- Denne teksten vil benyttes dersom feltene over er tomme
- Dette feltet vil benyttes dersom feltet over er tomt
- Ja, med klokkeslett. Dato/tid separator:
-
-
- Oversettelses detaljer
- Last ned XML DTD
- Felt
- Inkluder undersider
-
- Ingen oversettelses-bruker funnet. Vennligst opprett en oversettelses-bruker før du begynner å sende innhold til oversetting
- Siden '%0%' har blitt sendt til oversetting
- Send til oversetting
- Antall ord
- Oversett til
- Oversetting fullført.
- Du kan forhåndsvise sidene du nettopp har oversatt ved å klikke nedenfor. Hvis den originale siden finnes, vil du få en sammenligning av sidene.
- Oversetting mislykkes, XML filen kan være korrupt
- Alternativer for oversetting
- Oversetter
- Last opp XML med oversettelse
-
-
- Hurtigbufferleser
- Papirkurv
- Opprettede pakker
- Datatyper
- Ordbok
- Installerte pakker
- Installer utseende
- Installer startpakke
- Språk
- Installer lokal pakke
- Makroer
- Mediatyper
- Medlemmer
- Medlemsgrupper
- Roller
- Medlemstyper
- Dokumenttyper
- Pakker
- Pakker
- Installer fra pakkeregister
- Installer Runway
- Runway moduler
- Skriptfiler
- Skript
- Stiler
- Maler
- Brukertillatelser
- Brukertyper typer
- Brukere
-
-
- Ny oppdatering er klar
- %0% er klar, klikk her for å laste ned
- Ingen forbindelse til server
- Kunne ikke sjekke etter ny oppdatering. Se trace for mere info.
-
-
- Administrator
- Kategorifelt
- Bytt passord
- Nytt passord
- Bekreft nytt passord
- Du kan endre passordet til Umbraco ved å fylle ut skjemaet under og klikke "Bytt passord" knappen.
- Innholdskanal
- Beskrivelsesfelt
- Deaktiver bruker
- Dokumenttype
- Redaktør
- Utdragsfelt
- Språk
- Brukernavn
- Øverste nivå i Media
- Moduler
- Deaktiver tilgang til Umbraco
- Passord
- Nullstill passord
- Passordet er endret
- Bekreft nytt passord
- Nytt passord
- Nytt passord kan ikke være blankt
- Gjeldende passord
- Feil passord
- Nytt og bekreftet passord må være like
- Nytt og bekreftet passord må være like
- Overskriv tillatelser på undernoder
- Du redigerer for øyeblikket tillatelser for sidene:
- Velg sider for å redigere deres tillatelser
- Søk i alle undersider
- Startnode
- Navn
- Brukertillatelser
- Forfatter
- Endre
- Din profil
- Din historikk
- Sesjonen utløper om
-
-
diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/zh_tw.xml b/src/Umbraco.Web.UI/umbraco/config/lang/zh_tw.xml
deleted file mode 100644
index 0a87631329..0000000000
--- a/src/Umbraco.Web.UI/umbraco/config/lang/zh_tw.xml
+++ /dev/null
@@ -1,1269 +0,0 @@
-
-
-
- The Umbraco community
- http://our.umbraco.org/documentation/Extending-Umbraco/Language-Files
-
-
- 管理主機名稱
- 跟蹤審計
- 流覽節點
- 改變文檔類型
- 複製
- 創建
- 創建擴展包
- 刪除
- 禁用
- 清空回收站
- 匯出文檔類型
- 導入文檔類型
- 導入擴展包
- 即時編輯模式
- 退出
- 移動
- 提醒
- 公眾存取權限
- 發佈
- 取消發佈
- 重新載入節點
- 重新發佈整站
- 回復
- 許可權
- 回滾
- 提交至發佈者
- 發送給翻譯
- 排序
- 提交至發佈者
- 翻譯
- 更新
- 預設值
-
-
- 禁止訪問
- 添加功能變數名稱
- 移除
- 錯誤的節點
- 功能變數名稱錯誤
- 功能變數名稱重複
- 語言
- 功能變數名稱
- 新功能變數名稱 '%0%' 已創建
- 功能變數名稱 '%0%' 已刪除
- 功能變數名稱 '%0%' 已使用
- 功能變數名稱 '%0%' 已更新
- 編輯當前功能變數名稱
-
- 繼承
- 語言
- 或從父節點繼承文化設定。
- 也會改變目前節點設定,除非下方網域有其他項目。]]>
- 功能變數名稱
-
-
- 查看
-
-
- 清除選擇
- 選擇
- 做別的事情
- 粗體
- 取消段落縮進
- 插入表單字段
- 插入圖片標題
- 編輯Html
- 段落縮進
- 斜體
- 居中
- 左對齊
- 右對齊
- 插入連結
- 插入本地連結(錨點)
- 圓點列表
- 數字清單
- 插入巨集
- 插入圖片
- 編輯關聯
- 回到清單
- 保存
- 保存並發佈
- 保存並提交審核
- 保存清單檢視
- 預覽
- 因未設置範本無法預覽
- 選擇樣式
- 顯示樣式
- 插入表格
-
-
- 要更改所選節點的文檔類型,先在列表中選擇合適的文檔類型。
- 然後設置當前文檔類型到新文檔類型的各欄位間的對應映射關係並保存。
- 內容已被重新發佈
- 當前屬性
- 當前類型
- 不能改變文檔類型,因為沒有可替代的類型。
- 文檔類型已更改
- 要映射的欄位
- 映射欄位
- 新範本
- 新類型
- 無
- 內容
- 選擇新的文檔類型
- 選中文檔的類型已被成功更改為[new type],以下欄位被映射:
- 至
- 不能完成欄位映射,因為存在一個欄位映射至多欄位的問題。
- 僅顯示可作為替代的文檔類型。
-
-
- 已發表
- 關於本頁
- 別名
- (圖片的替代文本)
- 替代連結
- 點擊編輯
- 創建者
- 創建者
- 更新者
- 創建時間
- 此文件創建的日期時間
- 文檔類型
- 編輯
- 過期於
- 該項發佈之後有更改
- 該項沒有發佈
- 最近發佈
- 沒有可供顯示的項目
- 此列表中沒有可供顯示的項目
- 媒體類型
- 媒體連結位址
- 會員組
- 角色
- 會員類型
- 沒有選擇時間
- 頁標題
- 屬性
- 該文檔不可見,因為其上級 '%0%' 未發佈。
- 糟糕:該文檔已發佈,但是沒有更新至緩存(內部錯誤)
- 糟糕:沒辦法連結到此網址(內部錯誤-請參見記錄)
- 糟糕:此文件已經發表,但是網址和其他內容相衝 %0%
- 發佈
- 發佈狀態
- 發佈於
- 取消發表於
- 清空時間
- 排序完成
- 拖拽項目或按一下列頭即可排序,可以按住Shift多選。
- 統計
- 標題(可選)
- 其他說明文字(可選)
- 類型
- 取消發佈
- 最近編輯
- 本文件修改時間
- 移除文件
- 連結到文檔
- 會員組成員
- 非會員組成員
- 子項目
- 目標
- 預計發表的時間(伺服器端)
- 這是什麼意思?]]>
-
-
- 點選以便上傳
- 或按這裡選擇檔案
- 檔案大小上限為
-
-
- 新增一位會員
- 所有會員
-
-
- 您想在哪裡創建 %0%
- 創建在
- 選擇類型和標題
- "文檔類型"處變更。]]>
- "媒體類型"處變更。]]>
- 文檔類型沒有相關範本
- 沒有資料夾
- 新資料類別
-
-
- 流覽您的網站
- - 隱藏
- 如果Umbraco沒有打開,您可能需要允許彈出式視窗。
- 已經在新視窗中打開
- 重啟
- 訪問
- 歡迎
-
-
- 留下
- 放棄變更
- 您有未存檔的變更
- 您確定要離開本頁? - 您有未存檔的變更
-
-
- 完成
- 刪除 %0% 個項目
- 刪除 %0% 個項目
- 刪除 %1% 個中的 %0% 個項目
- 刪除 %1% 個中的 %0% 個項目
- 已發佈 %0% 個項目
- 已發佈 %0% 個項目
- 已發佈 %1% 個中的 %0% 個項目
- 已發佈 %1% 個中的 %0% 個項目
- 取消發佈 %0% 個項目
- 取消發佈 %0% 個項目
- 取消發佈 %1 個中的 %0% 個項目
- 取消發佈 %1 個中的 %0% 個項目
- 移動 %0% 個項目
- 移動 %0% 個項目
- 移動 %1 個中的 %0% 個項目
- 移動 %1 個中的 %0% 個項目
- 複製 %0% 個項目
- 複製 %0% 個項目
- 複製 %1 個中的 %0% 個項目
- 複製 %1 個中的 %0% 個項目
-
-
- 錨點名稱
- 管理主機名稱
- 關閉窗口
- 您確定要刪除嗎
- 您確定要禁用嗎
- 您確定嗎?
- 您確定嗎?
- 剪切
- 編輯字典項
- 編輯語言
- 插入本地連結
- 插入字元
- 插入圖片標題
- 插入圖片
- 插入連結
- 插入巨集
- 插入表格
- 最近編輯
- 連結
- 內部連結:
- 本地連結請用“#”號開頭
- 在新視窗中打開?
- 巨集設置
- 本巨集沒有包含您可以編輯的屬性
- 粘貼
- 編輯許可權
- 正在清空回收站,請不要關閉窗口。
- 回收站已清空
- 從回收站刪除的項目將不可恢復
- regexlib.com的網站服務目前出現些狀況,而我們無能為力。我們對此不便感到十分抱歉。]]>
- 查找規則運算式來驗證輸入,如: 'email、'zip-code'、'url'。
- 移除巨集
- 必填項目
- 網站已重建索引
- 網站緩存已刷新,所有已發佈的內容更新生效。
- 網站緩存將會刷新,所有已發佈的內容將會更新。
- 表格列數
- 表格行數
- 設定預留位置代碼 以便您要在子範本中插入內容到本範本時,填入此代碼到 <asp:content /> 裡面。]]>
- 選擇預留位置代碼 於此清單中。您只能選擇目前父範本中的代碼。]]>
- 點擊圖片查看完整大小
- 拾取項
- 查看緩存項
- 與原本相關
- 最友善的社群
- 頁面連結
- 打開此連結文檔至新視窗或標籤頁
- 媒體連結
- 選擇媒體
- 選擇圖示
- 選擇項目
- 選擇連結
- 選擇巨集
- 選擇內容
- 選擇會員
- 選擇會員群組
- 沒有找到任何圖示
- 本巨集沒有需要參數
- 外部登入提供者
- 例外細節
- 詳細記錄
- 內部例外
- 連結您的
- 取消連結您的
- 帳戶
- 選擇編輯器
-
-
- %0%' 編輯不同語言版本, 您可以在左方選單「語言」中增添新的語言
- ]]>
- 語言名稱
-
-
- 輸入您的使用者名稱
- 輸入您的密碼
- 確認您的密碼
- 命名此 %0%...
- 輸入一個名稱
- 標籤...
- 輸入一段描述...
- 搜尋請輸入...
- 過濾請輸入...
- 增加標籤(每個標籤後請按輸入鍵)...
- 輸入您的電子郵件
-
-
- 允許子項節點類型
- 創建
- 刪除選項卡
- 描述
- 新建選項卡
- 選項卡
- 縮略圖
- 新增自訂清單檢視
- 移除自訂清單檢視
-
-
- 添加預設值
- 資料庫資料類型
- 資料類型唯一標識
- 渲染控制項
- 按鈕
- 允許高級設置
- 允許快顯功能表
- 插入圖片預設最大
- 關聯的樣式表
- 顯示標籤
- 寬和高
-
-
- 資料已保存,但是發佈前您需要修正一些錯誤:
- 當前成員提供程式不支援修改密碼(EnablePasswordRetrieval的值應該為true)
- %0% 已存在
- 發現錯誤:
- 發現錯誤:
- 密碼最少%0%位元,且至少包含%1%位元非字母數位記號
- %0% 必須是整數
- %1% 中的 %0% 欄位是必填項
- %0% 是必填項
- %1% 中的 %0% 格式不正確
- %0% 格式不正確
-
-
- 收到伺服器傳來的錯誤
- 該檔案類型已被管理員禁用
- 注意,儘管配置中允許CodeMirror,但是它在IE上不夠穩定,所以無法在IE運行。
- 請為新的屬性類型填寫名稱和別名!
- 許可權有問題,訪問指定文檔或資料夾失敗!
- 讀取片段視圖腳本錯誤(檔案:%0%)
- 讀取使用者控制項 %0% 錯誤
- 請輸入標題
- 請選擇類型
- 圖片尺寸大於原始尺寸不會提高圖片品質,您確定要把圖片尺寸變大嗎?
- 預設打開頁面不存在,請聯繫管理員
- 請先選擇內容,再設置樣式。
- 沒有可用的樣式
- 請把游標放在您要合併的兩個儲存格中的左邊儲存格
- 非合併儲存格不能分離。
-
-
- 關於
- 操作
- 操作
- 添加
- 別名
- 所有
- 您確定嗎?
- 回去
- 邊框
- 或
- 取消
- 儲存格邊距
- 選擇
- 關閉
- 關閉窗口
- 備註
- 確認
- 強制屬性
- 繼續
- 複製
- 創建
- 資料庫
- 時間
- 默認
- 刪除
- 已刪除
- 正在刪除…
- 設計
- 規格
- 下
- 下載
- 編輯
- 已編輯
- 元素
- 郵箱
- 錯誤
- 查找文檔
- 高
- 幫助
- 圖示
- 導入
- 內邊距
- 插入
- 安裝
- 不合格
- 對齊
- 語言
- 佈局
- 載入中
- 鎖定
- 登入
- 退出
- 登出
- 巨集
- 必要
- 移動
- 名稱
- 新的
- 下一步
- 否
- 屬於
- 確定
- 打開
- 或
- 密碼
- 路徑
- 預留位置代碼
- 請稍候…
- 上一步
- 屬性
- 接收資料郵箱
- 回收站
- 保持狀態中
- 重命名
- 更新
- 必要
- 重試
- 許可權
- 搜索
- 伺服器
- 顯示
- 在發送時預覽
- 大小
- 排序
- 送出
- 類型
- 輸入內容開始搜尋…
- 上
- 更新
- 更新
- 上傳
- 連結位址
- 用戶
- 用戶名
- 值
- 查看
- 歡迎…
- 寬
- 是
- 資料夾
- 搜尋結果
- 重新排列
- 我已經完成排列
- 預覽
- 更改密碼
- 到
- 清單檢視
- 存檔中...
- 目前
- 內嵌
- 選取的
-
-
- 藍
-
-
- 增加標籤頁
- 增加屬性
- 增加編輯器
- 增加範本
- 增加子節點
- 增加子項目
- 編輯資料類別
- 瀏覽區塊
- 捷徑
- 顯示捷徑
- 開關清單檢視
- 開關是否允許為根項目
-
-
- 背景色
- 粗體
- 前景色
- 字體
- 文本
-
-
- 頁面
-
-
- 無法連接到資料庫。
- 無法保存web.config檔,請手工修改。
- 發現資料庫
- 資料庫配置
- 安裝 按鈕來安裝Umbraco資料庫 %0%
- ]]>
- 下一步繼續。]]>
- 沒有找到資料庫!請確認檔案"web.config"中的字串"connection string"是否正確。
- 請編輯檔案"web.config" (例如使用Visual Studio或您喜歡的編輯器),移動到檔案底部,並在名稱為"UmbracoDbDSN"的字串中設定資料庫連結資訊,並存檔。
-
- 點選重試 按鈕當上述步驟完成。
-
- 在此查詢更多編輯web.config的資訊。
]]>
-
- 若需要時,請聯繫您的網路公司。如果您在本地機器或伺服器安裝的話,您也許需要聯絡系統管理者。]]>
-
- 點選升級 按鈕來升級Umbraco資料庫 %0%
-
- 請別擔心 - 不會刪除任何資料而且馬上就會繼續運作!
-
- ]]>
- 點選下一步 繼續。]]>
- 下一步繼續設定精靈。]]>
- 預設使用者的密碼必須更改!]]>
- 預設使用者已經被暫停或沒有Umbraco的使用權!不需更多的操作步驟。點選下一步 繼續。]]>
- 安裝後預設使用者的密碼已經成功修改!不需更多的操作步驟。點選下一步 繼續。]]>
- 密碼已更改
- 作為入門者,從視頻教程開始吧!
- 點擊下一步 (或在Web.config中自行修改UmbracoConfigurationStatus),意味著您接受上述授權合約。
- 安裝失敗。
- 受影響的檔和資料夾
- 此處查看更多資訊
- 您需要對以下檔和資料夾授於ASP.NET用戶修改許可權
- 您的權限設定幾近完美!
- 您可以正常執行Umbraco沒有任何問題,只差您將沒有辦法安裝那些建議需要全部許可權的插件。]]>
- 如何解決
- 點擊閱讀文字版
- 影片教學來瞭解如何設定Umbraco的資料夾權限或閱讀文字版本。]]>
- 您的權限可能有點小問題!
-
- 您可以正常執行Umbraco沒有任何問題,然而您將無法新增資料夾或安裝那些可以讓Umbraco發揮全力的插件。]]>
- 您的權限設定尚未未完成!
-
- 您需要更新權限設定才能執行Umbraco。]]>
- 您的權限設定完美無瑕!
- 您已經準備好執行Umbraco和安裝插件!]]>
- 解決資料夾問題
- 點此查看ASP.NET和創建資料夾的問題解決方案
- 設置資料夾許可權
-
- 我要從頭開始
- 學習該怎麼做)
- 您晚點仍可以選擇安裝Runway,請至開發者區域選擇安裝。
- ]]>
- 您剛剛安裝了一個乾淨的系統,要繼續嗎?
- “Runway”已安裝
-
- 這是我們的模組推薦清單,選取您想要安裝的項目,或者至 查詢完整清單 。
- ]]>
- 僅推薦高級用戶使用
- 給我一個簡單的網站
-
- "Runway"是一個提供基本檔案類別和範本的簡單網站。安裝程式會自動幫您設定Runway,
- 但你仍可輕易編輯,擴充或移除它。它並非必要項目而且您可以在沒它的情況下完美執行Umbraco。然而,
- Runway提供一個輕鬆簡便但基於寶貴經驗的平台讓您可以更快開始。
- 如果您安裝Runway,您還可以選擇名為「Runway模組」的基本區塊來加強Runway頁面。
-
-
- 內含於Runway: 首頁,準備開始頁面,模組安裝頁面。
- 可選模組: 上方瀏覽列,網站地圖,聯絡,藝廊。
-
- ]]>
- “Runway”是什麼?
- 步驟 1/5:接受授權合約
- 步驟 2/5:資料庫配置
- 步驟 3/5:文件許可權驗證
- 步驟 4/5:系統安全性
- 步驟 5/5:一切就緒,可以開始使用系統。
- 感謝選擇我們的產品
- 參觀您的新網站
-您剛安裝好Runway,何不瞧瞧它的模樣。]]>
- 更多的幫忙與資訊
-從我們獲獎的社群得到幫助,瀏覽文件,或觀看免費影片來瞭解如何輕鬆架設網站,如何使用插件,和瞭解Umbraco項目名稱的快速上手指引。]]>
- 系統 %0% 安裝完畢
- /web.config 檔案並且更新AppSetting中的字串UmbracoConfigurationStatus 內容為 '%0%' 。]]>
- 快速開始指引。 如果您是Umbraco的新成員 ,
-您可以在其中找到相當多的資源。]]>
- 啟動Umbraco
-想要管理您的網站時,只需開啟Umbraco後台便可增加內容,更新範本和樣式表,或增添新功能。]]>
- 無法連接到資料庫。
- 系統版本 3
- 系統版本 4
- 觀看
-
- 點選"下一步" 來啟動精靈。]]>
-
-
- 語言代碼
- 語言名稱
-
-
- 使用者在空閒狀態下將會自動登出
- 已更新,繼續工作。
-
-
- 超級星期天快樂
- 瘋狂星期一快樂
- 熱鬧星期二快樂
- 美妙星期三快樂
- 悅耳星期四快樂
- 時髦星期五快樂
- 喵喵星期六快樂
- 下方登入
- 登入使用
- 連線時間過了
- © 2001 - %0% Umbraco.com ]]>
- 忘記密碼?
- 一封內有重設密碼連結的電子郵件已經寄出給您
- 一封內有重設密碼連結的電子郵件已經寄到此信箱
- 回到登入畫面
- 請輸入新密碼
- 您的密碼已經更新
- 您點選的連結是無效或過期的
- Umbraco:重設密碼
- 您登入到後台的使用者名稱是:%0% 點選這裡 來重設您的密碼或將此連結複製/貼上到您的瀏覽器:
%1%
]]>
-
-
- 儀錶板
- 區域
- 內容
-
-
- 選擇上面的頁面…
- %0% 被複製到 %1%
- 將 %0% 複製到
- %0% 已被移動到 %1%
- 將 %0% 移動到
- 作為內容的根結點,點“確定”。
- 尚未選擇節點,請選擇一個節點點擊“確定”。
- 類型不符不允許選擇
- 該項不能移到其子項
- 當前節點不能建在根節點下
- 您在子項的許可權不夠,不允許該操作。
- 複本和原本建立關聯
-
-
- 為 %0% 編寫通知
-
- 哈嘍 %0%
-
- 這是一封自動產生的信件來通知您 %1% 工作
- 已經在頁面 %2% 上由使用者 %3% 執行完成
-
-
-
-
更新摘要:
-
-
-
-
-
- 祝您有美好的一天!
- Umbraco機器人 謹上
-
]]>
- 在 %2%,[%0%] 關於 %1% 的通告已執行。
- 通知
-
-
-
- 按鈕並點選該檔案。Umbraco擴展包通常有「.zip」的副檔名。
- ]]>
- 作者
- 演示
- 文檔
- 中繼資料
- 名稱
- 擴展包不含任何項
-
- 您可以點選下方「移除擴展包」來安全地移除此項目。]]>
- 無可用更新
- 選項
- 說明
- 程式庫
- 確認卸載
- 已卸載
- 擴展包卸載成功
- 卸載
-
- 注意: 任何文檔,媒體或需要這些項目才能運作的物件將會停止運作,並可能使得系統不穩定,
- 請小心移除。若有疑慮,請聯絡擴展包作者。]]>
- 從程式庫下載更新
- 更新擴展包
- 更新說明
- 擴展包有可用的更新,您可以從程式庫網站更新。
- 版本
- 版本歷史
- 訪問擴展包網站
- 擴展包已安裝
- 這個擴展包無法安裝,它需要Umbraco至少是版本 %0%
- 移除中...
- 下載中...
- 匯入中...
- 安裝中...
- 重新啟動中,請稍後...
- 都好了,您的瀏覽器將重新整理,請稍待...
-
-
- 帶格式粘貼(不推薦)
- 您所粘貼的文本含有特殊字元或格式,Umbraco將清除以適應網頁。
- 無格式粘貼
- 粘貼並移除格式(推薦)
-
-
- 基於角色的保護
- 請使用Umbraco的會員群組。]]>
- 使用基於角色的授權需要首先建立會員組。
- 錯誤頁
- 當用戶登錄後訪問沒有許可權的頁時顯示該頁
- 選擇限制訪問此頁的方式
- %0% 現在處於受保護狀態
- %0% 的保護被取消
- 登錄頁
- 選擇公開的登錄入口
- 取消保護
- 選擇一個包含登錄表單和提示資訊的頁
- 選擇訪問該頁的角色類型
- 為此頁設置帳號和密碼
- 單用戶保護
- 如果您只希望提供一個用戶名和密碼就能訪問
-
-
-
-
-
-
-
- 包含未發佈的子項
- 正在發佈,請稍候…
- %0% 中的 %1% 頁面已發佈…
- %0% 已發佈
- %0% 及其子項已發佈
- 發佈 %0% 及其子項
- 發佈按鈕來將%0% 的內容設定為公開。
- 您可以同時發佈本頁以及其子項目若您點選下面的包含子頁 。
- ]]>
-
-
- 您尚未設定任何許可顏色
-
-
- 輸入外部連結
- 選擇內部連結
- 標題
- 連結
- 新視窗
- 輸入新標題
- 輸入連結
-
-
- 重設
-
-
- 當前版本
- 紅色 文字將不會顯示於所選版本,而綠色 表示增加部分。]]>
- 文檔已回滾
- 這顯示所選版本的HTML格式,如果您想要比較兩版本的差異,請使用比較檢視
- 回滾至
- 選擇版本
- 查看
-
-
- 編輯腳本
-
-
- Concierge
- 內容
- Courier
- 開發
- 設定精靈
- 媒體
- 會員
- 消息
- 設置
- 統計
- 翻譯
- 用戶
- 說明
- 表單
-
-
- 最好的Umbraco影片教學
-
-
- 預設範本
- 字典鍵
- 要導入文檔類型,請點擊“流覽”按鈕,再點擊“導入”,然後在您電腦上查找 ".udt"檔導入(下一頁中需要您再次確認)
- 新建選項卡標題
- 節點類型
- 類型
- 樣式表
- 腳本
- 樣式表屬性
- 選項卡
- 選項卡標題
- 選項卡
- 主控文件類型啟動
- 該文檔類型使用
- 作為主控文件類型. 主控文件類型的標籤只能在主控文件類型裡修改。
- 沒有欄位設置在該標籤頁
- 增加圖示
-
-
- 排列順序
- 增添時間
- 排序完成。
- 上下拖拽項目或按一下列頭進行排序
-
-
-
- 驗證
- 驗證錯誤一定要修正才能儲存項目
- 失敗
- 使用者權限不足,無法完成操作
- 已取消
- 操作被協力廠商外掛程式取消
- 發佈被協力廠商外掛程式取消
- 屬性類型已存在
- 屬性類型已創建
- 資料類別:%1%]]>
- 屬性類型已刪除
- 內容類別型已保存
- 選項卡已創建
- 選項卡已刪除
- id為%0%的選項卡已刪除
- 樣式表未保存
- 樣式表已保存
- 樣式表保存,無錯誤。
- 資料類型已保存
- 字典項已保存
- 因為上級頁面未發佈導致發佈失敗!
- 內容已發佈
- 公眾可見
- 內容已保存
- 請發佈以使更改生效
- 提交審核
- 更改已提交審核
- 媒體已保存
- 媒體已保存
- 會員已保存
- 樣式表屬性已保存
- 樣式表已保存
- 範本已保存
- 保存使用者出錯(請查看日誌)
- 用戶已保存
- 用戶類型已保存
- 檔未保存
- 檔無法保存,請檢查許可權。
- 檔保存
- 檔保存,無錯誤。
- 語言已保存
- 媒體類別已儲存
- 會員類別已儲存
- 範本未保存
- 範本別名相同
- 範本已保存
- 範本保存,無錯誤。
- 內容已取消發佈
- 片段視圖已保存
- 片段視圖保存,無錯誤。
- 片段視圖未保存
- 片段視圖因為錯誤未能保存
-
-
- 使用CSS語法,如:h1、.redHeader、.blueTex。
- 編輯樣式表
- 編輯樣式屬性
- 編輯器中的樣式屬性名
- 預覽
- 樣式
-
-
- 編輯範本
- 插入內容區
- 插入內容預留位置
- 插入字典項
- 插入巨集
- 插入頁欄位
- 母版
- 範本標籤快速指南
- 範本
-
-
- Image
- Macro
- 選擇內容類別
- 選擇排列方式
- 新增一行
- 新增內容
- 放棄內容
- 設定已儲存
- 此處不允許有內容
- 此處允許有內容
- 點選來內嵌
- 點選來插入圖片
- 圖片標題...
- 在此填寫...
- 網格排列方式
- 排列是指網格編輯器的整體工作區域,通常您只需要一種或兩種排列方式
- 增加網格排列方式
- 藉由設定列寬以及增加新的區域來調整排列方式
- 行設定
- 行是預先水平排列的格子
- 增加行設定
- 藉由設定小格寬度和增添小格來調整此行
- 列
- 網格排列方式的列總數
- 設定
- 調整設定編輯器可以改變的項目
- 樣式
- 調整樣式編輯器可以改變的項目
- 允許所有編輯器
- 允許所有行設定
- 定為預設
- 選擇額外
- 選擇預設
- 已增加
-
-
- 組合
- 您沒有增加任何選項卡
- 繼承的表格
- 增加屬性
- 必要標籤
- 允許清單檢視
- 允許內容項目顯示成可以排列及搜尋的清單,子項目不會被顯示
- 允許的範本
- 選擇哪些範本編輯器可以使用於此類別的內容
- 允許為根項目
- 允許編輯器新增此類別的內容為根項目
- 允許子節點種類
- 允許某些特定種類能夠成為此種類內容的子項目
- 選擇子節點
- 從已存在的文檔類別中繼承選項卡以及屬性。新選項卡將被新增至目前文檔種類或合併至已存在同名的選項卡中。
- 此內容種類已經用於集合中,因此不能重複添加本身。
- 沒有可用於集合的內容種類。
- 可用的編輯器
- 重複使用
- 編輯器設定
- 設定
- 是,刪除
- 已移至下層
- 已複製至下層
- 選擇要移動的資料夾
- 選擇要複製的資料夾
- 至下方樹狀結構
- 所有文檔種類
- 所有文檔
- 所有媒體項目
- 使用此文檔種類的將被永久刪除,請確認您也想要將它們刪除。
- 使用此媒體種類的將被永久刪除,請確認您也想要將它們刪除。
- 使用此會員種類的將被永久刪除,請確認您也想要將它們刪除。
- 以及所有使用此種類的文件項目
- 以及所有使用此種類的媒體項目
- 以及所有使用此種類的會員項目
- 會員可以編輯
- 顯示於會員資料
-
-
- 替代欄位
- 替代文本
- 大小寫
- 編碼
- 選取欄位
- 轉換分行符號
- 將換行符號取代成為HTML標籤 <br>
- 自訂欄位
- 是,僅日期
- 格式化時間
- HTML編碼
- 將替換HTML中的特殊字元
- 將在欄位值後插入
- 將在欄位值前插入
- 小寫
- 無
- 欄位後插入
- 欄位前插入
- 遞迴
- 標準欄位
- 大寫
- URL編碼
- 將格式化URL中的特殊字元
- 當上面欄位值為空時使用
- 該欄位僅在主欄位為空時使用
- 是,含時間,分隔符號為:
-
-
- 翻譯詳情
- 下載 XML DTD
- 欄位
- 包含子頁
-
- 沒有翻譯員,請創建翻譯員角色的用戶。
- 頁面'%0%'已經發送給翻譯
- 發送頁面'%0%'以便翻譯
- 總字數
- 翻譯到
- 翻譯完成。
- 您可以流覽剛翻譯的頁面,如果原始頁存在,您將得到兩者的比較。
- 翻譯失敗,XML可能損壞了。
- 翻譯選項
- 翻譯員
- 上傳翻譯的xml
-
-
- 緩存流覽
- 回收站
- 創建擴展包
- 資料類型
- 字典
- 已安裝的擴展包
- 安裝皮膚
- 安裝新手套件
- 語言
- 安裝本地擴展包
- 巨集
- 媒體類型
- 會員
- 會員組
- 角色
- 會員類型
- 文檔類型
- 相關類型
- 擴展包
- 擴展包
- 從線上程式庫安裝
- 安裝Runway
- Runway模組
- Scripting文件
- 腳本
- 樣式表
- 範本
-
-
- 有可用更新
- %0%已就緒,點擊這裡下載
- 無到伺服器的連接
- 檢查更新失敗
-
-
- 管理員
- 分類欄位
- 更改密碼
- 更改密碼
- 確認新密碼
- 要改變密碼,請在框中輸入新密碼,然後按一下“更改密碼”。
- 內容頻道
- 描述欄位
- 禁用用戶
- 文檔類型
- 編輯
- 排除欄位
- 語言
- 登錄
- 默認打開媒體項
- 區域
- 禁用後臺管理介面
- 舊的密碼
- 密碼
- 重設密碼
- 您的密碼已更改!
- 重輸密碼
- 輸入新密碼
- 新密碼不能為空!
- 當前密碼
- 密碼錯誤
- 新密碼和重輸入的密碼不一致,請重試!
- 重輸的密碼和原密碼不一致!
- 替換子項許可權設置
- 您正在修改存取權限的頁面:
- 選擇要修改許可權的頁
- 搜索子物件
- 預設打開內容項
- 用戶名
- 用戶許可權
- 撰稿人
- 改變
- 您的個人檔案
- 您的歷程記錄
- 連線到期於
-
-
- 驗證
- 以電子郵件驗證
- 以數字驗證
- 以網址驗證
- ...或輸入自訂驗證
- 必要欄位
-
-
-
- 數值已設為推薦值:%0%
- 在設定檔 %3% 中XPath %2% 的數值設為 %1% 。
- 在設定檔 %3% 中XPath %2% 的預期值設為 %1% ,但卻是 %0%。
- 在設定檔 %3% 中XPath %2% 的值為非預期值 %0%。
-
- 自訂錯誤設定為 %0%
- 自訂錯誤設定為 %0。建議在上線前改為 %1%。
- 自訂錯誤成功設定為 %0%
- 巨集錯誤設為 %0%
- 巨集錯誤設為 %0%,如此一來,當巨集有任何錯誤時會阻止某些或全部頁面正常載入。改正會將此設定 %1%。
- 巨集錯誤已設為 %0%
-
- 嘗試略過IIS自訂錯誤目前設為 %0%,而且您使用的IIS版本為 %1%。
- 嘗試略過IIS自訂錯誤目前設為 %0%,然而在您使用的IIS版本為 %2% 時,建議設定是 %1%。
- 嘗試略過IIS自訂錯誤已成功設為 %0%。
-
- 檔案不存在:%0%。
- '%1%'中無法找到'%0%' 。]]>
- 有錯誤產生,請參閱下列錯誤的紀錄:%0%。
- 憑證驗證錯誤:%0%
- 網址探查錯誤:%0% - '%1%'
- 您目前使用HTTPS瀏覽本站:%0%
- 在您的web.config檔案中,appSetting的umbracoUseSSL是設為false。當您開始使用HTTPS時,應將其改為 true。
- 在您的web.config檔案中,appSetting的umbracoUseSSL是設為 %0%,您的cookies %0% 標成安全。
- 無法在您的web.config檔案中,更新appSetting的umbracoUseSSL設定,錯誤訊息:%0%
-
- 開啟HTTPS
- 在web.config檔案中,將appSetting的umbracoUseSSL設true。
- 在您的web.config檔案中,appSetting的umbracoUseSSL已設為 true,您的cookies 將被標成安全。
- 修正
- 無法修正比較種類檢查為'ShouldNotEqual'。
- 用提供的數值無法修正比較種類檢查為'ShouldEqual'。
- 沒有提供要修正檢查的數值。
- 偵錯編輯模式關閉。
- 偵錯編輯模式目前已開啟。上線前建議將其關閉。
- 偵錯編輯模式已成功關閉。
- 詳細記錄模式已關閉。
- 詳細記錄模式目前已開啟。上線前建議將其關閉。
- 詳細記錄模式已成功關閉。
- 所有資料夾已有正確權限設定。
-
- %0%。]]>
- %0%。如果無須寫入,不需採取行動。]]>
- 所有檔案已有正確權限設定。
-
- %0%。]]>
- %0%。如果無須寫入,不需採取行動。]]>
- X-Frame-Options 設定能控制網站是否可以被其他人IFRAMEd已找到。]]>
- X-Frame-Options 設定能控制網站是否可以被其他人IFRAMEd沒有找到。]]>
- 調整設定的標頭
- 在 web.config 的 httpProtocol/customHeaders 區域增加設定來防止本站被別的網站IFRAMEd。
- 在 web.config 的 httpProtocol/customHeaders 區域已經增加設定來防止本站被別的網站IFRAMEd。
- 無法更新web.config檔案,錯誤:%0%
-
- %0%。]]>
- 在標頭中沒有找到揭露網站技術的資訊。
- 在 Web.config 檔案中,找不到 system.net/mailsettings。
- 在 Web.config 檔案中的 system.net/mailsettings,沒有設定 host 。
- SMTP設定正確,而且服務正常運作。
- SMTP伺服器 %0% : %1% 無法連接。請確認在Web.config 檔案中 system.net/mailsettings 設定正確。
- %0%。]]>
- %0%。]]>
-
-
- 停止網址追蹤器
- 啟動網址追蹤器
- 原本網址
- 轉址成
- 沒有任何轉址
- 當發佈後的頁面改名或移動時,會自動轉址至新網頁。
- 移除
- 您確定要移除從 %0% 到 %1% 的轉址嗎?
- 轉址已移除。
- 移除轉址錯誤。
-
- 您確定要停止轉址追蹤器?
- 轉址追蹤器已停止。
- 停止轉址追蹤器錯誤,更多資訊請參閱您的紀錄檔。
- 轉址追蹤器已開啟。
- 啟動轉址追蹤器錯誤,更多資訊請參閱您的紀錄檔。
-
-
From d0016d6a7e86b42969757ba38839d538f9c3fc1f Mon Sep 17 00:00:00 2001
From: Stephan
Date: Wed, 16 Jan 2019 10:40:04 +0100
Subject: [PATCH 84/84] Upgrade to MB -alpha.33 supporting elements
---
build/NuSpecs/UmbracoCms.nuspec | 2 +-
src/Umbraco.Web.UI/Umbraco.Web.UI.csproj | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/build/NuSpecs/UmbracoCms.nuspec b/build/NuSpecs/UmbracoCms.nuspec
index 1b7a1c5ae1..3cb3d0d875 100644
--- a/build/NuSpecs/UmbracoCms.nuspec
+++ b/build/NuSpecs/UmbracoCms.nuspec
@@ -22,7 +22,7 @@
not want this to happen as the alpha of the next major is, really, the next major already.
-->
-
+
diff --git a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj
index ca4acd9d66..6967ac74c2 100644
--- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj
+++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj
@@ -107,7 +107,7 @@
- 8.0.0-alpha.32
+ 8.0.0-alpha.33