From e4df2f42054e517eb39b47bc381abc5f0ef068da Mon Sep 17 00:00:00 2001 From: Jeavon Date: Thu, 3 Oct 2019 17:46:18 +0100 Subject: [PATCH 01/68] Add ability for editors to search for media items by file name as well as node name. --- src/Umbraco.Examine/MediaValueSetBuilder.cs | 34 +++++++++++++++++-- .../UmbracoExamine/IndexInitializer.cs | 11 +++++- .../Models/Mapping/EntityMapDefinition.cs | 9 +++++ src/Umbraco.Web/Search/UmbracoTreeSearcher.cs | 1 + 4 files changed, 51 insertions(+), 4 deletions(-) diff --git a/src/Umbraco.Examine/MediaValueSetBuilder.cs b/src/Umbraco.Examine/MediaValueSetBuilder.cs index 3839d008b3..e6e7d620d9 100644 --- a/src/Umbraco.Examine/MediaValueSetBuilder.cs +++ b/src/Umbraco.Examine/MediaValueSetBuilder.cs @@ -1,9 +1,12 @@ -using Examine; +using System; +using Examine; using System.Collections.Generic; using System.Linq; +using Newtonsoft.Json; using Umbraco.Core; using Umbraco.Core.Models; using Umbraco.Core.PropertyEditors; +using Umbraco.Core.PropertyEditors.ValueConverters; using Umbraco.Core.Services; using Umbraco.Core.Strings; @@ -13,14 +16,16 @@ namespace Umbraco.Examine { private readonly UrlSegmentProviderCollection _urlSegmentProviders; private readonly IUserService _userService; + private readonly IRuntimeState _runtimeState; public MediaValueSetBuilder(PropertyEditorCollection propertyEditors, UrlSegmentProviderCollection urlSegmentProviders, - IUserService userService) + IUserService userService, IRuntimeState runtimeState) : base(propertyEditors, false) { _urlSegmentProviders = urlSegmentProviders; _userService = userService; + _runtimeState = runtimeState; } /// @@ -29,6 +34,28 @@ namespace Umbraco.Examine foreach (var m in media) { var urlValue = m.GetUrlSegment(_urlSegmentProviders); + + var umbracoFilePath = string.Empty; + var umbracoFile = string.Empty; + + var umbracoFileSource = m.GetValue(Constants.Conventions.Media.File); + + if (umbracoFileSource.DetectIsJson()) + { + var cropper = JsonConvert.DeserializeObject(m.GetValue(Constants.Conventions.Media.File)); + if (cropper != null) + { + umbracoFilePath = cropper.Src; + } + } + else + { + umbracoFilePath = umbracoFileSource; + } + + var uri = new Uri(_runtimeState.ApplicationUrl.GetLeftPart(UriPartial.Authority) + umbracoFilePath); + umbracoFile = uri.Segments.Last(); + var values = new Dictionary> { {"icon", m.ContentType.Icon?.Yield() ?? Enumerable.Empty()}, @@ -44,7 +71,8 @@ namespace Umbraco.Examine {"urlName", urlValue?.Yield() ?? Enumerable.Empty()}, {"path", m.Path?.Yield() ?? Enumerable.Empty()}, {"nodeType", m.ContentType.Id.ToString().Yield() }, - {"creatorName", (m.GetCreatorProfile(_userService)?.Name ?? "??").Yield()} + {"creatorName", (m.GetCreatorProfile(_userService)?.Name ?? "??").Yield()}, + {"__umbracoFile", new object[] {umbracoFile}} }; foreach (var property in m.Properties) diff --git a/src/Umbraco.Tests/UmbracoExamine/IndexInitializer.cs b/src/Umbraco.Tests/UmbracoExamine/IndexInitializer.cs index f7b1799d63..8ac9bc59ea 100644 --- a/src/Umbraco.Tests/UmbracoExamine/IndexInitializer.cs +++ b/src/Umbraco.Tests/UmbracoExamine/IndexInitializer.cs @@ -7,6 +7,7 @@ using Lucene.Net.Analysis; using Lucene.Net.Analysis.Standard; using Lucene.Net.Store; using Moq; +using Umbraco.Core; using Umbraco.Core.Logging; using Umbraco.Core.Models; using Umbraco.Core.Models.Membership; @@ -44,11 +45,19 @@ namespace Umbraco.Tests.UmbracoExamine public static MediaIndexPopulator GetMediaIndexRebuilder(PropertyEditorCollection propertyEditors, IMediaService mediaService) { - var mediaValueSetBuilder = new MediaValueSetBuilder(propertyEditors, new UrlSegmentProviderCollection(new[] { new DefaultUrlSegmentProvider() }), GetMockUserService()); + var mediaValueSetBuilder = new MediaValueSetBuilder(propertyEditors, new UrlSegmentProviderCollection(new[] { new DefaultUrlSegmentProvider() }), GetMockUserService(), MockRuntimeState(RuntimeLevel.Run)); var mediaIndexDataSource = new MediaIndexPopulator(null, mediaService, mediaValueSetBuilder); return mediaIndexDataSource; } + public static IRuntimeState MockRuntimeState(RuntimeLevel level) + { + var runtimeState = Mock.Of(); + Mock.Get(runtimeState).Setup(x => x.Level).Returns(level); + return runtimeState; + } + + public static IContentService GetMockContentService() { long longTotalRecs; diff --git a/src/Umbraco.Web/Models/Mapping/EntityMapDefinition.cs b/src/Umbraco.Web/Models/Mapping/EntityMapDefinition.cs index eb474e4cbe..7e88590552 100644 --- a/src/Umbraco.Web/Models/Mapping/EntityMapDefinition.cs +++ b/src/Umbraco.Web/Models/Mapping/EntityMapDefinition.cs @@ -180,6 +180,15 @@ namespace Umbraco.Web.Models.Mapping target.Name = source.Values.ContainsKey("nodeName") ? source.Values["nodeName"] : "[no name]"; + if (source.Values.ContainsKey("__umbracoFile")) + { + var umbracoFile = source.Values["__umbracoFile"]; + if (umbracoFile != null) + { + target.Name = $"{target.Name} ({umbracoFile})"; + } + } + if (source.Values.ContainsKey(UmbracoExamineIndex.NodeKeyFieldName)) { if (Guid.TryParse(source.Values[UmbracoExamineIndex.NodeKeyFieldName], out var key)) diff --git a/src/Umbraco.Web/Search/UmbracoTreeSearcher.cs b/src/Umbraco.Web/Search/UmbracoTreeSearcher.cs index c3c3dc75ce..23f13c2f33 100644 --- a/src/Umbraco.Web/Search/UmbracoTreeSearcher.cs +++ b/src/Umbraco.Web/Search/UmbracoTreeSearcher.cs @@ -85,6 +85,7 @@ namespace Umbraco.Web.Search break; case UmbracoEntityTypes.Media: type = "media"; + fields = new[] { "__umbracoFile" }; var allMediaStartNodes = _umbracoContext.Security.CurrentUser.CalculateMediaStartNodeIds(_entityService); AppendPath(sb, UmbracoObjectTypes.Media, allMediaStartNodes, searchFrom, ignoreUserStartNodes, _entityService); break; From 72147ab8f24a0634e3f99dca43733106d30b0474 Mon Sep 17 00:00:00 2001 From: Jeavon Date: Fri, 4 Oct 2019 10:34:10 +0100 Subject: [PATCH 02/68] Fixing Examine unit tests --- src/Umbraco.Tests/UmbracoExamine/IndexInitializer.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Umbraco.Tests/UmbracoExamine/IndexInitializer.cs b/src/Umbraco.Tests/UmbracoExamine/IndexInitializer.cs index 8ac9bc59ea..87b4400d58 100644 --- a/src/Umbraco.Tests/UmbracoExamine/IndexInitializer.cs +++ b/src/Umbraco.Tests/UmbracoExamine/IndexInitializer.cs @@ -54,6 +54,8 @@ namespace Umbraco.Tests.UmbracoExamine { var runtimeState = Mock.Of(); Mock.Get(runtimeState).Setup(x => x.Level).Returns(level); + Mock.Get(runtimeState).SetupGet(m => m.ApplicationUrl).Returns(new Uri("https://LocalHost/umbraco")); + return runtimeState; } From 68866e9faf5ad7cad911fe67697bb04d0d99d5cb Mon Sep 17 00:00:00 2001 From: Jeavon Date: Fri, 4 Oct 2019 11:17:36 +0100 Subject: [PATCH 03/68] Adding a constant for the new field name --- src/Umbraco.Examine/MediaValueSetBuilder.cs | 2 +- src/Umbraco.Examine/UmbracoExamineIndex.cs | 1 + src/Umbraco.Web/Models/Mapping/EntityMapDefinition.cs | 4 ++-- src/Umbraco.Web/Search/UmbracoTreeSearcher.cs | 2 +- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/Umbraco.Examine/MediaValueSetBuilder.cs b/src/Umbraco.Examine/MediaValueSetBuilder.cs index e6e7d620d9..db8299dd6d 100644 --- a/src/Umbraco.Examine/MediaValueSetBuilder.cs +++ b/src/Umbraco.Examine/MediaValueSetBuilder.cs @@ -72,7 +72,7 @@ namespace Umbraco.Examine {"path", m.Path?.Yield() ?? Enumerable.Empty()}, {"nodeType", m.ContentType.Id.ToString().Yield() }, {"creatorName", (m.GetCreatorProfile(_userService)?.Name ?? "??").Yield()}, - {"__umbracoFile", new object[] {umbracoFile}} + {UmbracoExamineIndex.UmbracoFileFieldName, new object[] {umbracoFile}} }; foreach (var property in m.Properties) diff --git a/src/Umbraco.Examine/UmbracoExamineIndex.cs b/src/Umbraco.Examine/UmbracoExamineIndex.cs index 24952050da..916ef95d1c 100644 --- a/src/Umbraco.Examine/UmbracoExamineIndex.cs +++ b/src/Umbraco.Examine/UmbracoExamineIndex.cs @@ -32,6 +32,7 @@ namespace Umbraco.Examine /// public const string IndexPathFieldName = SpecialFieldPrefix + "Path"; public const string NodeKeyFieldName = SpecialFieldPrefix + "Key"; + public const string UmbracoFileFieldName = SpecialFieldPrefix + "umbracoFile"; public const string IconFieldName = SpecialFieldPrefix + "Icon"; public const string PublishedFieldName = SpecialFieldPrefix + "Published"; diff --git a/src/Umbraco.Web/Models/Mapping/EntityMapDefinition.cs b/src/Umbraco.Web/Models/Mapping/EntityMapDefinition.cs index 7e88590552..5219ab8b54 100644 --- a/src/Umbraco.Web/Models/Mapping/EntityMapDefinition.cs +++ b/src/Umbraco.Web/Models/Mapping/EntityMapDefinition.cs @@ -180,9 +180,9 @@ namespace Umbraco.Web.Models.Mapping target.Name = source.Values.ContainsKey("nodeName") ? source.Values["nodeName"] : "[no name]"; - if (source.Values.ContainsKey("__umbracoFile")) + if (source.Values.ContainsKey(UmbracoExamineIndex.UmbracoFileFieldName)) { - var umbracoFile = source.Values["__umbracoFile"]; + var umbracoFile = source.Values[UmbracoExamineIndex.UmbracoFileFieldName]; if (umbracoFile != null) { target.Name = $"{target.Name} ({umbracoFile})"; diff --git a/src/Umbraco.Web/Search/UmbracoTreeSearcher.cs b/src/Umbraco.Web/Search/UmbracoTreeSearcher.cs index 23f13c2f33..84889e76c0 100644 --- a/src/Umbraco.Web/Search/UmbracoTreeSearcher.cs +++ b/src/Umbraco.Web/Search/UmbracoTreeSearcher.cs @@ -85,7 +85,7 @@ namespace Umbraco.Web.Search break; case UmbracoEntityTypes.Media: type = "media"; - fields = new[] { "__umbracoFile" }; + fields = new[] { UmbracoExamineIndex.UmbracoFileFieldName }; var allMediaStartNodes = _umbracoContext.Security.CurrentUser.CalculateMediaStartNodeIds(_entityService); AppendPath(sb, UmbracoObjectTypes.Media, allMediaStartNodes, searchFrom, ignoreUserStartNodes, _entityService); break; From 7130c99810afcb39230cb36213d850091020a24d Mon Sep 17 00:00:00 2001 From: Jeavon Date: Fri, 4 Oct 2019 17:44:26 +0100 Subject: [PATCH 04/68] Rename new field and ensure Id is also searchable --- src/Umbraco.Examine/UmbracoExamineIndex.cs | 2 +- src/Umbraco.Web/Search/UmbracoTreeSearcher.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Examine/UmbracoExamineIndex.cs b/src/Umbraco.Examine/UmbracoExamineIndex.cs index 916ef95d1c..e1dd77b994 100644 --- a/src/Umbraco.Examine/UmbracoExamineIndex.cs +++ b/src/Umbraco.Examine/UmbracoExamineIndex.cs @@ -32,7 +32,7 @@ namespace Umbraco.Examine /// public const string IndexPathFieldName = SpecialFieldPrefix + "Path"; public const string NodeKeyFieldName = SpecialFieldPrefix + "Key"; - public const string UmbracoFileFieldName = SpecialFieldPrefix + "umbracoFile"; + public const string UmbracoFileFieldName = "umbracoFileSrc"; public const string IconFieldName = SpecialFieldPrefix + "Icon"; public const string PublishedFieldName = SpecialFieldPrefix + "Published"; diff --git a/src/Umbraco.Web/Search/UmbracoTreeSearcher.cs b/src/Umbraco.Web/Search/UmbracoTreeSearcher.cs index 84889e76c0..a98cd8f212 100644 --- a/src/Umbraco.Web/Search/UmbracoTreeSearcher.cs +++ b/src/Umbraco.Web/Search/UmbracoTreeSearcher.cs @@ -85,7 +85,7 @@ namespace Umbraco.Web.Search break; case UmbracoEntityTypes.Media: type = "media"; - fields = new[] { UmbracoExamineIndex.UmbracoFileFieldName }; + fields = new[] { "id", "__NodeId", UmbracoExamineIndex.UmbracoFileFieldName}; var allMediaStartNodes = _umbracoContext.Security.CurrentUser.CalculateMediaStartNodeIds(_entityService); AppendPath(sb, UmbracoObjectTypes.Media, allMediaStartNodes, searchFrom, ignoreUserStartNodes, _entityService); break; From 61465ed997fcd639d8c41c7e5ebaf680bac79d76 Mon Sep 17 00:00:00 2001 From: Jeavon Date: Fri, 4 Oct 2019 18:30:35 +0100 Subject: [PATCH 05/68] Add null check to umbracoFilePath and used Yield extension method --- src/Umbraco.Examine/MediaValueSetBuilder.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Examine/MediaValueSetBuilder.cs b/src/Umbraco.Examine/MediaValueSetBuilder.cs index db8299dd6d..20c92eb982 100644 --- a/src/Umbraco.Examine/MediaValueSetBuilder.cs +++ b/src/Umbraco.Examine/MediaValueSetBuilder.cs @@ -53,8 +53,11 @@ namespace Umbraco.Examine umbracoFilePath = umbracoFileSource; } + if (!string.IsNullOrEmpty(umbracoFilePath)) + { var uri = new Uri(_runtimeState.ApplicationUrl.GetLeftPart(UriPartial.Authority) + umbracoFilePath); umbracoFile = uri.Segments.Last(); + } var values = new Dictionary> { @@ -72,7 +75,7 @@ namespace Umbraco.Examine {"path", m.Path?.Yield() ?? Enumerable.Empty()}, {"nodeType", m.ContentType.Id.ToString().Yield() }, {"creatorName", (m.GetCreatorProfile(_userService)?.Name ?? "??").Yield()}, - {UmbracoExamineIndex.UmbracoFileFieldName, new object[] {umbracoFile}} + {UmbracoExamineIndex.UmbracoFileFieldName, umbracoFile.Yield()} }; foreach (var property in m.Properties) From 82af5f26e54275281f02292918950081e3d8ad51 Mon Sep 17 00:00:00 2001 From: Jeavon Date: Wed, 9 Oct 2019 16:16:19 +0100 Subject: [PATCH 06/68] Added a fix to handle hyphens in file names --- src/Umbraco.Web/Search/UmbracoTreeSearcher.cs | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Web/Search/UmbracoTreeSearcher.cs b/src/Umbraco.Web/Search/UmbracoTreeSearcher.cs index a98cd8f212..5e2d0afc65 100644 --- a/src/Umbraco.Web/Search/UmbracoTreeSearcher.cs +++ b/src/Umbraco.Web/Search/UmbracoTreeSearcher.cs @@ -203,11 +203,26 @@ namespace Umbraco.Web.Search foreach (var f in fields) { + var queryWordsReplaced = new string[querywords.Length]; + + // when searching file names containing hyphens we need to replace the hyphens with spaces + if (f.Equals(UmbracoExamineIndex.UmbracoFileFieldName)) + { + for (var index = 0; index < querywords.Length; index++) + { + queryWordsReplaced[index] = querywords[index].Replace("\\-", " ").Trim(" "); + } + } + else + { + queryWordsReplaced = querywords; + } + //additional fields normally sb.Append(f); sb.Append(":"); sb.Append("("); - foreach (var w in querywords) + foreach (var w in queryWordsReplaced) { sb.Append(w.ToLower()); sb.Append("* "); From 0c957c2fd9e494785c6623256dc8ae0f456cfb7b Mon Sep 17 00:00:00 2001 From: Jeavon Date: Wed, 9 Oct 2019 16:46:57 +0100 Subject: [PATCH 07/68] Also replace underscores --- src/Umbraco.Web/Search/UmbracoTreeSearcher.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web/Search/UmbracoTreeSearcher.cs b/src/Umbraco.Web/Search/UmbracoTreeSearcher.cs index 5e2d0afc65..fd87dd0660 100644 --- a/src/Umbraco.Web/Search/UmbracoTreeSearcher.cs +++ b/src/Umbraco.Web/Search/UmbracoTreeSearcher.cs @@ -210,7 +210,7 @@ namespace Umbraco.Web.Search { for (var index = 0; index < querywords.Length; index++) { - queryWordsReplaced[index] = querywords[index].Replace("\\-", " ").Trim(" "); + queryWordsReplaced[index] = querywords[index].Replace("\\-", " ").Replace("_", " ").Trim(" "); } } else From 702aa41ff2a8801c5f24976dc9ee103afb0f4754 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Kottal?= Date: Wed, 9 Oct 2019 22:19:28 +0200 Subject: [PATCH 08/68] Adds nametemplates for grid editors --- .../Configuration/Grid/IGridEditorConfig.cs | 1 + src/Umbraco.Core/PropertyEditors/GridEditor.cs | 3 +++ .../views/propertyeditors/grid/grid.controller.js | 13 ++++++++++++- .../src/views/propertyeditors/grid/grid.html | 4 ++-- src/Umbraco.Web.UI/config/grid.editors.config.js | 5 ++++- 5 files changed, 22 insertions(+), 4 deletions(-) diff --git a/src/Umbraco.Core/Configuration/Grid/IGridEditorConfig.cs b/src/Umbraco.Core/Configuration/Grid/IGridEditorConfig.cs index e447f7f493..9a11b0ef3e 100644 --- a/src/Umbraco.Core/Configuration/Grid/IGridEditorConfig.cs +++ b/src/Umbraco.Core/Configuration/Grid/IGridEditorConfig.cs @@ -6,6 +6,7 @@ namespace Umbraco.Core.Configuration.Grid public interface IGridEditorConfig { string Name { get; } + string NameTemplate { get; } string Alias { get; } string View { get; } string Render { get; } diff --git a/src/Umbraco.Core/PropertyEditors/GridEditor.cs b/src/Umbraco.Core/PropertyEditors/GridEditor.cs index 986eed9ccc..cc3561fbc2 100644 --- a/src/Umbraco.Core/PropertyEditors/GridEditor.cs +++ b/src/Umbraco.Core/PropertyEditors/GridEditor.cs @@ -18,6 +18,9 @@ namespace Umbraco.Core.PropertyEditors [JsonProperty("name", Required = Required.Always)] public string Name { get; set; } + [JsonProperty("nameTemplate")] + public string NameTemplate { get; set; } + [JsonProperty("alias", Required = Required.Always)] public string Alias { get; set; } diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.controller.js index ccc390252b..0a4ab83dea 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.controller.js @@ -8,7 +8,8 @@ angular.module("umbraco") angularHelper, $element, eventsService, - editorService + editorService, + $interpolate ) { // Grid status variables @@ -680,6 +681,11 @@ angular.module("umbraco") $scope.showRowConfigurations = !$scope.showRowConfigurations; }; + $scope.getTemplateName = function (control) { + if (control.editor.nameExp) return control.editor.nameExp(control) + return control.editor.name; + } + // ********************************************* // Initialization @@ -923,6 +929,11 @@ angular.module("umbraco") localizationService.localize("grid_" + value.alias, undefined, value.name).then(function (v) { value.name = v; }); + // setup nametemplate + + value.nameExp = !!value.nameTemplate + ? $interpolate(value.nameTemplate) + : undefined; }); $scope.contentReady = true; diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.html index 6b739a9b86..3995ed703d 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.html +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.html @@ -182,7 +182,7 @@
- {{control.editor.name}} + {{ getTemplateName(control) }}
@@ -190,7 +190,7 @@
- {{control.editor.name}} + {{ getTemplateName(control) }}
diff --git a/src/Umbraco.Web.UI/config/grid.editors.config.js b/src/Umbraco.Web.UI/config/grid.editors.config.js index 12fa726f21..49b843689b 100644 --- a/src/Umbraco.Web.UI/config/grid.editors.config.js +++ b/src/Umbraco.Web.UI/config/grid.editors.config.js @@ -7,12 +7,14 @@ }, { "name": "Image", + "nameTemplate": "{{ 'Image: ' + (value.udi | ncNodeName) }}", "alias": "media", "view": "media", "icon": "icon-picture" }, { "name": "Macro", + "nameTemplate": "{{ 'Macro: ' + value.macroAlias }}", "alias": "macro", "view": "macro", "icon": "icon-settings-alt" @@ -25,6 +27,7 @@ }, { "name": "Headline", + "nameTemplate": "{{ 'Headline: ' + value }}", "alias": "headline", "view": "textstring", "icon": "icon-coin", @@ -43,4 +46,4 @@ "markup": "
#value#
" } } -] \ No newline at end of file +] From 0ee9c2d327a1e8629db99a0292732175eec205df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Tue, 22 Oct 2019 15:22:34 +0200 Subject: [PATCH 09/68] ability to disable confirm button in umb-confirm --- src/Umbraco.Web.UI.Client/src/views/components/umb-confirm.html | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Umbraco.Web.UI.Client/src/views/components/umb-confirm.html b/src/Umbraco.Web.UI.Client/src/views/components/umb-confirm.html index 384c5ccaf7..d8e4f09b8a 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/umb-confirm.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/umb-confirm.html @@ -14,6 +14,7 @@ action="confirm()" button-style="{{confirmButtonStyle || 'primary'}}" state="confirmButtonState" + disabled="confirmDisabled === true" label-key="{{confirmLabelKey || 'general_ok'}}">
From 98df5eae6739fd1529910028e2fb687289af2718 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Tue, 22 Oct 2019 15:22:52 +0200 Subject: [PATCH 10/68] never underline icons in table --- src/Umbraco.Web.UI.Client/src/less/components/umb-table.less | 1 + 1 file changed, 1 insertion(+) 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 5e766b7578..94c0318fca 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 @@ -161,6 +161,7 @@ input.umb-table__input { line-height: 20px; color: @ui-option-type; vertical-align: bottom; + text-decoration: none; } .umb-table-body__checkicon, From 0f07ecba5463257d4b641e669f2c46ce2ffaf761 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Tue, 22 Oct 2019 15:23:46 +0200 Subject: [PATCH 11/68] umb-confirm ability to set wether the confirm button is disabled via confirmDisabled --- .../src/common/directives/components/umbconfirm.directive.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/umbconfirm.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/umbconfirm.directive.js index 1ddd09357a..9114cfb1c1 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/umbconfirm.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/umbconfirm.directive.js @@ -56,6 +56,7 @@ function confirmDirective() { onCancel: '=', caption: '@', confirmButtonStyle: '@', + confirmDisabled: ' Date: Tue, 22 Oct 2019 15:24:36 +0200 Subject: [PATCH 12/68] links to edit references --- .../src/views/datatypes/delete.html | 20 +++++++++---------- .../datatypes/views/datatype.references.html | 4 ++-- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/datatypes/delete.html b/src/Umbraco.Web.UI.Client/src/views/datatypes/delete.html index 6c415e9f38..32140cf6f2 100644 --- a/src/Umbraco.Web.UI.Client/src/views/datatypes/delete.html +++ b/src/Umbraco.Web.UI.Client/src/views/datatypes/delete.html @@ -49,9 +49,9 @@ - - {{::relation.name}} - {{::property.name}}{{$last ? '' : ', '}} + + {{::reference.name}} + {{::property.name}}{{$last ? '' : ', '}} @@ -73,9 +73,9 @@ - - {{::relation.name}} - {{::property.name}}{{$last ? '' : ', '}} + + {{::reference.name}} + {{::property.name}}{{$last ? '' : ', '}} @@ -97,9 +97,9 @@ - - {{::relation.name}} - {{::property.name}}{{$last ? '' : ', '}} + + {{::reference.name}} + {{::property.name}}{{$last ? '' : ', '}} @@ -112,7 +112,7 @@
- {{::reference.name}}
{{::reference.alias}}
{{::reference.properties | umbCmsJoinArray:', ':'name'}}
- + @@ -98,7 +98,7 @@
{{::reference.name}}
{{::reference.alias}}
{{::reference.properties | umbCmsJoinArray:', ':'name'}}
- + From 89e6cc3611c688177b7b405da40f35a5680b355d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Tue, 22 Oct 2019 15:26:59 +0200 Subject: [PATCH 13/68] do close dialog, even thought people might open in a tab. --- src/Umbraco.Web.UI.Client/src/views/datatypes/delete.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/datatypes/delete.html b/src/Umbraco.Web.UI.Client/src/views/datatypes/delete.html index 32140cf6f2..aedb7c7545 100644 --- a/src/Umbraco.Web.UI.Client/src/views/datatypes/delete.html +++ b/src/Umbraco.Web.UI.Client/src/views/datatypes/delete.html @@ -50,7 +50,7 @@ - {{::reference.name}} + {{::reference.name}} {{::property.name}}{{$last ? '' : ', '}} @@ -74,7 +74,7 @@ - {{::reference.name}} + {{::reference.name}} {{::property.name}}{{$last ? '' : ', '}} @@ -98,7 +98,7 @@ - {{::reference.name}} + {{::reference.name}} {{::property.name}}{{$last ? '' : ', '}} From 6776d6cde6d4e73a87c1eae23078aa715fc74999 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Tue, 22 Oct 2019 15:35:50 +0200 Subject: [PATCH 14/68] hide dialog if opening reference in this tab/window. --- .../src/views/datatypes/datatype.delete.controller.js | 6 ++++++ src/Umbraco.Web.UI.Client/src/views/datatypes/delete.html | 6 +++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/datatypes/datatype.delete.controller.js b/src/Umbraco.Web.UI.Client/src/views/datatypes/datatype.delete.controller.js index c6c58d9fa6..4542cde343 100644 --- a/src/Umbraco.Web.UI.Client/src/views/datatypes/datatype.delete.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/datatypes/datatype.delete.controller.js @@ -51,6 +51,12 @@ function DataTypeDeleteController($scope, dataTypeResource, treeService, navigat navigationService.hideDialog(); }; + vm.onReferenceClicked = function(event) { + if (event.metaKey !== true) { + navigationService.hideDialog(); + } + }; + vm.labels = {}; localizationService .localize("editdatatype_acceptDeleteConsequence", [$scope.currentNode.name]) diff --git a/src/Umbraco.Web.UI.Client/src/views/datatypes/delete.html b/src/Umbraco.Web.UI.Client/src/views/datatypes/delete.html index aedb7c7545..52adfcccec 100644 --- a/src/Umbraco.Web.UI.Client/src/views/datatypes/delete.html +++ b/src/Umbraco.Web.UI.Client/src/views/datatypes/delete.html @@ -50,7 +50,7 @@ - {{::reference.name}} + {{::reference.name}} {{::property.name}}{{$last ? '' : ', '}} @@ -74,7 +74,7 @@ - {{::reference.name}} + {{::reference.name}} {{::property.name}}{{$last ? '' : ', '}} @@ -98,7 +98,7 @@ - {{::reference.name}} + {{::reference.name}} {{::property.name}}{{$last ? '' : ', '}} From f20394556cb59bafe5fbba30c5c60db7c1c31d1f Mon Sep 17 00:00:00 2001 From: elitsa Date: Fri, 25 Oct 2019 11:58:04 +0200 Subject: [PATCH 15/68] Removed trailing newlines --- .../src/views/propertyeditors/grid/grid.controller.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.controller.js index 0a4ab83dea..32f495e32b 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.controller.js @@ -662,7 +662,6 @@ angular.module("umbraco") return ((spans / $scope.model.config.items.columns) * 100).toFixed(8); }; - $scope.clearPrompt = function (scopedObject, e) { scopedObject.deletePrompt = false; e.preventDefault(); @@ -686,7 +685,6 @@ angular.module("umbraco") return control.editor.name; } - // ********************************************* // Initialization // these methods are called from ng-init on the template From 76bbf01cbe647708583f8284a010f014752cbab0 Mon Sep 17 00:00:00 2001 From: Jeavon Date: Tue, 29 Oct 2019 15:25:10 +0000 Subject: [PATCH 16/68] Changed field to a List as suggested in review --- src/Umbraco.Tests/UmbracoExamine/IndexInitializer.cs | 2 +- src/Umbraco.Web/Search/UmbracoTreeSearcher.cs | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Umbraco.Tests/UmbracoExamine/IndexInitializer.cs b/src/Umbraco.Tests/UmbracoExamine/IndexInitializer.cs index 87b4400d58..5c9c965cd1 100644 --- a/src/Umbraco.Tests/UmbracoExamine/IndexInitializer.cs +++ b/src/Umbraco.Tests/UmbracoExamine/IndexInitializer.cs @@ -54,7 +54,7 @@ namespace Umbraco.Tests.UmbracoExamine { var runtimeState = Mock.Of(); Mock.Get(runtimeState).Setup(x => x.Level).Returns(level); - Mock.Get(runtimeState).SetupGet(m => m.ApplicationUrl).Returns(new Uri("https://LocalHost/umbraco")); + Mock.Get(runtimeState).SetupGet(m => m.ApplicationUrl).Returns(new Uri("https://localhost/umbraco")); return runtimeState; } diff --git a/src/Umbraco.Web/Search/UmbracoTreeSearcher.cs b/src/Umbraco.Web/Search/UmbracoTreeSearcher.cs index 7a62097490..463f4b09df 100644 --- a/src/Umbraco.Web/Search/UmbracoTreeSearcher.cs +++ b/src/Umbraco.Web/Search/UmbracoTreeSearcher.cs @@ -67,7 +67,7 @@ namespace Umbraco.Web.Search string type; var indexName = Constants.UmbracoIndexes.InternalIndexName; - var fields = new[] { "id", "__NodeId", "__Key" }; + var fields = new List { "id", "__NodeId", "__Key" }; // TODO: WE should try to allow passing in a lucene raw query, however we will still need to do some manual string // manipulation for things like start paths, member types, etc... @@ -87,7 +87,7 @@ namespace Umbraco.Web.Search case UmbracoEntityTypes.Member: indexName = Constants.UmbracoIndexes.MembersIndexName; type = "member"; - fields = new[] { "id", "__NodeId", "__Key", "email", "loginName" }; + fields.AddRange(new[]{ "email", "loginName"}); if (searchFrom != null && searchFrom != Constants.Conventions.MemberTypes.AllMembersListId && searchFrom.Trim() != "-1") { sb.Append("+__NodeTypeAlias:"); @@ -97,7 +97,7 @@ namespace Umbraco.Web.Search break; case UmbracoEntityTypes.Media: type = "media"; - fields = new[] { "id", "__NodeId", UmbracoExamineIndex.UmbracoFileFieldName}; + fields.AddRange(new[] { UmbracoExamineIndex.UmbracoFileFieldName }); var allMediaStartNodes = _umbracoContext.Security.CurrentUser.CalculateMediaStartNodeIds(_entityService); AppendPath(sb, UmbracoObjectTypes.Media, allMediaStartNodes, searchFrom, ignoreUserStartNodes, _entityService); break; @@ -162,7 +162,7 @@ namespace Umbraco.Web.Search return _mapper.MapEnumerable(results); } - private bool BuildQuery(StringBuilder sb, string query, string searchFrom, string[] fields, string type) + private bool BuildQuery(StringBuilder sb, string query, string searchFrom, List fields, string type) { //build a lucene query: // the nodeName will be boosted 10x without wildcards From 501f9495a9c794894f0ade1a591f5fe5752cd78b Mon Sep 17 00:00:00 2001 From: Bjarke Berg Date: Thu, 26 Sep 2019 10:05:41 +0200 Subject: [PATCH 17/68] Bumb version to 8.3 --- src/SolutionInfo.cs | 4 ++-- src/Umbraco.Web.UI/Umbraco.Web.UI.csproj | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/SolutionInfo.cs b/src/SolutionInfo.cs index 31a9953b23..bf3a271d32 100644 --- a/src/SolutionInfo.cs +++ b/src/SolutionInfo.cs @@ -18,5 +18,5 @@ using System.Resources; [assembly: AssemblyVersion("8.0.0")] // these are FYI and changed automatically -[assembly: AssemblyFileVersion("8.2.2")] -[assembly: AssemblyInformationalVersion("8.2.2")] +[assembly: AssemblyFileVersion("8.3.0")] +[assembly: AssemblyInformationalVersion("8.3.0")] diff --git a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj index 10ca65357d..6c20e8c765 100644 --- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj +++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj @@ -345,9 +345,9 @@ False True - 8220 + 8300 / - http://localhost:8220/ + http://localhost:8300/ False False From 6b318207c78e30c09f0ba93e824d3296b819aad0 Mon Sep 17 00:00:00 2001 From: Rasmus John Pedersen Date: Thu, 26 Sep 2019 16:32:58 +0200 Subject: [PATCH 18/68] Disable rename alias of system user groups --- .../editor/umbeditorheader.directive.js | 3 ++- .../src/less/components/umb-locked-field.less | 3 ++- .../components/editor/umb-editor-header.html | 2 +- .../views/components/umb-generate-alias.html | 2 +- .../src/views/users/group.html | 1 + .../Filters/UserGroupValidateAttribute.cs | 13 +++++++++++++ .../Models/ContentEditing/UserGroupBasic.cs | 6 ++++++ .../Models/Mapping/UserMapDefinition.cs | 18 +++++++++++------- 8 files changed, 37 insertions(+), 11 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/editor/umbeditorheader.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/editor/umbeditorheader.directive.js index 76c2e585f8..ebb780c36e 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/editor/umbeditorheader.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/editor/umbeditorheader.directive.js @@ -195,6 +195,7 @@ Use this directive to construct a header inside the main editor window. @param {string=} icon Show and edit the content icon. Opens an overlay to change the icon. @param {boolean=} hideIcon Set to true to hide icon. @param {string=} alias show and edit the content alias. +@param {boolean=} aliasLocked Set to true to lock the alias. @param {boolean=} hideAlias Set to true to hide alias. @param {string=} description Add a description to the content. @param {boolean=} hideDescription Set to true to hide description. @@ -207,7 +208,6 @@ Use this directive to construct a header inside the main editor window. function EditorHeaderDirective(editorService) { function link(scope) { - scope.vm = {}; scope.vm.dropdownOpen = false; scope.vm.currentVariant = ""; @@ -262,6 +262,7 @@ Use this directive to construct a header inside the main editor window. icon: "=", hideIcon: "@", alias: "=", + aliasLocked: "<", hideAlias: "=", description: "=", hideDescription: "@", diff --git a/src/Umbraco.Web.UI.Client/src/less/components/umb-locked-field.less b/src/Umbraco.Web.UI.Client/src/less/components/umb-locked-field.less index 8d9ae86ce7..3dd169e892 100644 --- a/src/Umbraco.Web.UI.Client/src/less/components/umb-locked-field.less +++ b/src/Umbraco.Web.UI.Client/src/less/components/umb-locked-field.less @@ -29,7 +29,8 @@ color: @gray-3; } -input.umb-locked-field__input { +input.umb-locked-field__input, +.umb-locked-field__text { background: rgba(255, 255, 255, 0); // if using transparent it will hide the text in safari border-color: transparent !important; font-size: 13px; diff --git a/src/Umbraco.Web.UI.Client/src/views/components/editor/umb-editor-header.html b/src/Umbraco.Web.UI.Client/src/views/components/editor/umb-editor-header.html index aca27da7be..824caa87a9 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/editor/umb-editor-header.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/editor/umb-editor-header.html @@ -46,7 +46,7 @@ ng-if="!hideAlias" alias="$parent.alias" alias-from="$parent.name" - enable-lock="true" + enable-lock="aliasLocked !== true" validation-position="'right'" server-validation-field="Alias"> diff --git a/src/Umbraco.Web.UI.Client/src/views/components/umb-generate-alias.html b/src/Umbraco.Web.UI.Client/src/views/components/umb-generate-alias.html index 9d68ea1b63..836e8fc3f1 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/umb-generate-alias.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/umb-generate-alias.html @@ -1,5 +1,5 @@
- {{ alias }} + {{ alias }}
[DataMember(Name = "userCount")] public int UserCount { get; set; } + + /// + /// Is the user group a system group e.g. "Administrators", "Sensitive data" or "Translators" + /// + [DataMember(Name = "isSystemUserGroup")] + public bool IsSystemUserGroup { get; set; } } } diff --git a/src/Umbraco.Web/Models/Mapping/UserMapDefinition.cs b/src/Umbraco.Web/Models/Mapping/UserMapDefinition.cs index 4acda1e552..abbb67c4aa 100644 --- a/src/Umbraco.Web/Models/Mapping/UserMapDefinition.cs +++ b/src/Umbraco.Web/Models/Mapping/UserMapDefinition.cs @@ -138,7 +138,7 @@ namespace Umbraco.Web.Models.Mapping } // Umbraco.Code.MapAll -ContentStartNode -UserCount -MediaStartNode -Key -Sections - // Umbraco.Code.MapAll -Notifications -Udi -Trashed -AdditionalData + // Umbraco.Code.MapAll -Notifications -Udi -Trashed -AdditionalData -IsSystemUserGroup private void Map(IReadOnlyUserGroup source, UserGroupBasic target, MapperContext context) { target.Alias = source.Alias; @@ -147,11 +147,11 @@ namespace Umbraco.Web.Models.Mapping target.Name = source.Name; target.ParentId = -1; target.Path = "-1," + source.Id; - MapUserGroupBasic(target, source.AllowedSections, source.StartContentId, source.StartMediaId, context); + MapUserGroupBasic(target, source.Alias, source.AllowedSections, source.StartContentId, source.StartMediaId, context); } // Umbraco.Code.MapAll -ContentStartNode -MediaStartNode -Sections -Notifications - // Umbraco.Code.MapAll -Udi -Trashed -AdditionalData + // Umbraco.Code.MapAll -Udi -Trashed -AdditionalData -IsSystemUserGroup private void Map(IUserGroup source, UserGroupBasic target, MapperContext context) { target.Alias = source.Alias; @@ -162,7 +162,7 @@ namespace Umbraco.Web.Models.Mapping target.ParentId = -1; target.Path = "-1," + source.Id; target.UserCount = source.UserCount; - MapUserGroupBasic(target, source.AllowedSections, source.StartContentId, source.StartMediaId, context); + MapUserGroupBasic(target, source.Alias, source.AllowedSections, source.StartContentId, source.StartMediaId, context); } // Umbraco.Code.MapAll -Udi -Trashed -AdditionalData -AssignedPermissions @@ -198,7 +198,7 @@ namespace Umbraco.Web.Models.Mapping } // Umbraco.Code.MapAll -ContentStartNode -MediaStartNode -Sections -Notifications -Udi - // Umbraco.Code.MapAll -Trashed -AdditionalData -Users -AssignedPermissions + // Umbraco.Code.MapAll -Trashed -AdditionalData -Users -AssignedPermissions -IsSystemUserGroup private void Map(IUserGroup source, UserGroupDisplay target, MapperContext context) { target.Alias = source.Alias; @@ -211,7 +211,7 @@ namespace Umbraco.Web.Models.Mapping target.Path = "-1," + source.Id; target.UserCount = source.UserCount; - MapUserGroupBasic(target, source.AllowedSections, source.StartContentId, source.StartMediaId, context); + MapUserGroupBasic(target, source.Alias, source.AllowedSections, source.StartContentId, source.StartMediaId, context); //Important! Currently we are never mapping to multiple UserGroupDisplay objects but if we start doing that // this will cause an N+1 and we'll need to change how this works. @@ -334,8 +334,12 @@ namespace Umbraco.Web.Models.Mapping // helpers - private void MapUserGroupBasic(UserGroupBasic target, IEnumerable sourceAllowedSections, int? sourceStartContentId, int? sourceStartMediaId, MapperContext context) + private void MapUserGroupBasic(UserGroupBasic target, string alias, IEnumerable sourceAllowedSections, int? sourceStartContentId, int? sourceStartMediaId, MapperContext context) { + target.IsSystemUserGroup = alias == Constants.Security.AdminGroupAlias + || alias == Constants.Security.TranslatorGroupAlias + || alias == Constants.Security.SensitiveDataGroupAlias; + var allSections = _sectionService.GetSections(); target.Sections = context.MapEnumerable(allSections.Where(x => sourceAllowedSections.Contains(x.Alias))); From 640f042acfe3c0dce198b88fa8e362ccb5ecc5e7 Mon Sep 17 00:00:00 2001 From: Rasmus John Pedersen Date: Thu, 26 Sep 2019 18:39:54 +0200 Subject: [PATCH 19/68] Disallow deleting "Sensitive data" user group --- .../Models/Membership/UserGroupExtensions.cs | 13 +++++++++++++ .../users/views/groups/groups.controller.js | 2 +- .../src/views/users/views/groups/groups.html | 2 +- .../Filters/UserGroupValidateAttribute.cs | 13 ++++--------- .../Editors/UserGroupsController.cs | 4 ++-- .../Models/Mapping/UserMapDefinition.cs | 19 ++++++++++--------- 6 files changed, 31 insertions(+), 22 deletions(-) diff --git a/src/Umbraco.Core/Models/Membership/UserGroupExtensions.cs b/src/Umbraco.Core/Models/Membership/UserGroupExtensions.cs index 3903fe405b..b1d0189c56 100644 --- a/src/Umbraco.Core/Models/Membership/UserGroupExtensions.cs +++ b/src/Umbraco.Core/Models/Membership/UserGroupExtensions.cs @@ -15,6 +15,12 @@ namespace Umbraco.Core.Models.Membership return new ReadOnlyUserGroup(group.Id, group.Name, group.Icon, group.StartContentId, group.StartMediaId, group.Alias, group.AllowedSections, group.Permissions); } + public static bool IsSystemUserGroup(this IUserGroup group) => + IsSystemUserGroup(group.Alias); + + public static bool IsSystemUserGroup(this IReadOnlyUserGroup group) => + IsSystemUserGroup(group.Alias); + public static IReadOnlyUserGroup ToReadOnlyGroup(this UserGroupDto group) { return new ReadOnlyUserGroup(group.Id, group.Name, group.Icon, @@ -22,5 +28,12 @@ namespace Umbraco.Core.Models.Membership group.UserGroup2AppDtos.Select(x => x.AppAlias).ToArray(), group.DefaultPermissions == null ? Enumerable.Empty() : group.DefaultPermissions.ToCharArray().Select(x => x.ToString())); } + + private static bool IsSystemUserGroup(this string groupAlias) + { + return groupAlias == Constants.Security.AdminGroupAlias + || groupAlias == Constants.Security.SensitiveDataGroupAlias + || groupAlias == Constants.Security.TranslatorGroupAlias; + } } } diff --git a/src/Umbraco.Web.UI.Client/src/views/users/views/groups/groups.controller.js b/src/Umbraco.Web.UI.Client/src/views/users/views/groups/groups.controller.js index 1e51d4585e..b21859f5c4 100644 --- a/src/Umbraco.Web.UI.Client/src/views/users/views/groups/groups.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/users/views/groups/groups.controller.js @@ -81,7 +81,7 @@ } // Disallow selection of the admin/translators group, the checkbox is not visible in the UI, but clicking(and thus selecting) is still possible. // Currently selection can only be used for deleting, and the Controller will also disallow deleting the admin group. - if (userGroup.alias === "admin" || userGroup.alias === "translator") + if (userGroup.isSystemUserGroup) return; listViewHelper.selectHandler(userGroup, $index, vm.userGroups, vm.selection, $event); diff --git a/src/Umbraco.Web.UI.Client/src/views/users/views/groups/groups.html b/src/Umbraco.Web.UI.Client/src/views/users/views/groups/groups.html index 5d1496d90f..4d252a3ae0 100644 --- a/src/Umbraco.Web.UI.Client/src/views/users/views/groups/groups.html +++ b/src/Umbraco.Web.UI.Client/src/views/users/views/groups/groups.html @@ -86,7 +86,7 @@
+ ng-class="{'-selected': group.selected, '-selectable': group.hasAccess && !group.isSystemUserGroup}">
diff --git a/src/Umbraco.Web/Editors/Filters/UserGroupValidateAttribute.cs b/src/Umbraco.Web/Editors/Filters/UserGroupValidateAttribute.cs index 7d465a9ddc..78cd8e6a4d 100644 --- a/src/Umbraco.Web/Editors/Filters/UserGroupValidateAttribute.cs +++ b/src/Umbraco.Web/Editors/Filters/UserGroupValidateAttribute.cs @@ -51,16 +51,11 @@ namespace Umbraco.Web.Editors.Filters return; } - if (persisted.Alias != userGroupSave.Alias) + if (persisted.Alias != userGroupSave.Alias && persisted.IsSystemUserGroup()) { - if (persisted.Alias == Constants.Security.AdminGroupAlias - || persisted.Alias == Constants.Security.SensitiveDataGroupAlias - || persisted.Alias == Constants.Security.TranslatorGroupAlias) - { - var message = $"User group with alias: {persisted.Alias} cannot be changed"; - actionContext.Response = actionContext.Request.CreateErrorResponse(HttpStatusCode.BadRequest, message); - return; - } + var message = $"User group with alias: {persisted.Alias} cannot be changed"; + actionContext.Response = actionContext.Request.CreateErrorResponse(HttpStatusCode.BadRequest, message); + return; } //map the model to the persisted instance diff --git a/src/Umbraco.Web/Editors/UserGroupsController.cs b/src/Umbraco.Web/Editors/UserGroupsController.cs index 1b64722735..b081ca6137 100644 --- a/src/Umbraco.Web/Editors/UserGroupsController.cs +++ b/src/Umbraco.Web/Editors/UserGroupsController.cs @@ -154,8 +154,8 @@ namespace Umbraco.Web.Editors public HttpResponseMessage PostDeleteUserGroups([FromUri] int[] userGroupIds) { var userGroups = Services.UserService.GetAllUserGroups(userGroupIds) - //never delete the admin group or translators group - .Where(x => x.Alias != Constants.Security.AdminGroupAlias && x.Alias != Constants.Security.TranslatorGroupAlias) + //never delete the admin group, sensitive data or translators group + .Where(x => !x.IsSystemUserGroup()) .ToArray(); foreach (var userGroup in userGroups) { diff --git a/src/Umbraco.Web/Models/Mapping/UserMapDefinition.cs b/src/Umbraco.Web/Models/Mapping/UserMapDefinition.cs index abbb67c4aa..88960fb189 100644 --- a/src/Umbraco.Web/Models/Mapping/UserMapDefinition.cs +++ b/src/Umbraco.Web/Models/Mapping/UserMapDefinition.cs @@ -147,7 +147,9 @@ namespace Umbraco.Web.Models.Mapping target.Name = source.Name; target.ParentId = -1; target.Path = "-1," + source.Id; - MapUserGroupBasic(target, source.Alias, source.AllowedSections, source.StartContentId, source.StartMediaId, context); + target.IsSystemUserGroup = source.IsSystemUserGroup(); + + MapUserGroupBasic(target, source.AllowedSections, source.StartContentId, source.StartMediaId, context); } // Umbraco.Code.MapAll -ContentStartNode -MediaStartNode -Sections -Notifications @@ -162,7 +164,9 @@ namespace Umbraco.Web.Models.Mapping target.ParentId = -1; target.Path = "-1," + source.Id; target.UserCount = source.UserCount; - MapUserGroupBasic(target, source.Alias, source.AllowedSections, source.StartContentId, source.StartMediaId, context); + target.IsSystemUserGroup = source.IsSystemUserGroup(); + + MapUserGroupBasic(target, source.AllowedSections, source.StartContentId, source.StartMediaId, context); } // Umbraco.Code.MapAll -Udi -Trashed -AdditionalData -AssignedPermissions @@ -198,7 +202,7 @@ namespace Umbraco.Web.Models.Mapping } // Umbraco.Code.MapAll -ContentStartNode -MediaStartNode -Sections -Notifications -Udi - // Umbraco.Code.MapAll -Trashed -AdditionalData -Users -AssignedPermissions -IsSystemUserGroup + // Umbraco.Code.MapAll -Trashed -AdditionalData -Users -AssignedPermissions private void Map(IUserGroup source, UserGroupDisplay target, MapperContext context) { target.Alias = source.Alias; @@ -210,8 +214,9 @@ namespace Umbraco.Web.Models.Mapping target.ParentId = -1; target.Path = "-1," + source.Id; target.UserCount = source.UserCount; + target.IsSystemUserGroup = source.IsSystemUserGroup(); - MapUserGroupBasic(target, source.Alias, source.AllowedSections, source.StartContentId, source.StartMediaId, context); + MapUserGroupBasic(target, source.AllowedSections, source.StartContentId, source.StartMediaId, context); //Important! Currently we are never mapping to multiple UserGroupDisplay objects but if we start doing that // this will cause an N+1 and we'll need to change how this works. @@ -334,12 +339,8 @@ namespace Umbraco.Web.Models.Mapping // helpers - private void MapUserGroupBasic(UserGroupBasic target, string alias, IEnumerable sourceAllowedSections, int? sourceStartContentId, int? sourceStartMediaId, MapperContext context) + private void MapUserGroupBasic(UserGroupBasic target, IEnumerable sourceAllowedSections, int? sourceStartContentId, int? sourceStartMediaId, MapperContext context) { - target.IsSystemUserGroup = alias == Constants.Security.AdminGroupAlias - || alias == Constants.Security.TranslatorGroupAlias - || alias == Constants.Security.SensitiveDataGroupAlias; - var allSections = _sectionService.GetSections(); target.Sections = context.MapEnumerable(allSections.Where(x => sourceAllowedSections.Contains(x.Alias))); From 73fc648718288191e66e4dd6da1984b9ea8c8212 Mon Sep 17 00:00:00 2001 From: Shannon Date: Thu, 10 Oct 2019 20:45:16 +1100 Subject: [PATCH 20/68] Adds logic to ensure you can't change to a culture that is already assigned + test --- .../Implement/LanguageRepository.cs | 13 ++++++++++++ .../Repositories/LanguageRepositoryTest.cs | 21 ++++++++++++++++++- 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Core/Persistence/Repositories/Implement/LanguageRepository.cs b/src/Umbraco.Core/Persistence/Repositories/Implement/LanguageRepository.cs index 8597bbf19f..4c452ad554 100644 --- a/src/Umbraco.Core/Persistence/Repositories/Implement/LanguageRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/Implement/LanguageRepository.cs @@ -182,6 +182,19 @@ namespace Umbraco.Core.Persistence.Repositories.Implement throw new InvalidOperationException($"Cannot save the default language ({entity.IsoCode}) as non-default. Make another language the default language instead."); } + if (entity.IsPropertyDirty(nameof(ILanguage.IsoCode))) + { + //if the iso code is changing, ensure there's not another lang with the same code already assigned + var sameCode = Sql() + .SelectCount() + .From() + .Where(x => x.IsoCode == entity.IsoCode && x.Id != entity.Id); + + var countOfSameCode = Database.ExecuteScalar(sameCode); + if (countOfSameCode > 0) + throw new InvalidOperationException($"Cannot update the language to a new culture: {entity.IsoCode} since that culture is already assigned to another language entity."); + } + // fallback cycles are detected at service level // update diff --git a/src/Umbraco.Tests/Persistence/Repositories/LanguageRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/LanguageRepositoryTest.cs index 03c1713268..85a3374cea 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/LanguageRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/LanguageRepositoryTest.cs @@ -1,4 +1,5 @@ -using System.Globalization; +using System; +using System.Globalization; using System.Linq; using Moq; using NUnit.Framework; @@ -297,6 +298,24 @@ namespace Umbraco.Tests.Persistence.Repositories } } + [Test] + public void Perform_Update_With_Existing_Culture() + { + // Arrange + var provider = TestObjects.GetScopeProvider(Logger); + using (var scope = provider.CreateScope()) + { + var repository = CreateRepository(provider); + + // Act + var language = repository.Get(5); + language.IsoCode = "da-DK"; + language.CultureName = "da-DK"; + + Assert.Throws(() => repository.Save(language)); + } + } + [Test] public void Can_Perform_Delete_On_LanguageRepository() { From a7eb693053d9793309630a0430c017f5420030fa Mon Sep 17 00:00:00 2001 From: Shannon Date: Mon, 14 Oct 2019 15:21:00 +1100 Subject: [PATCH 21/68] updates logic for cache refreshers for languages to deal with updating nucache and examine --- .../Cache/ContentCacheRefresher.cs | 45 ++++---- .../Cache/LanguageCacheRefresher.cs | 108 ++++++++++++++++-- src/Umbraco.Web/Search/ExamineComponent.cs | 26 ++++- 3 files changed, 142 insertions(+), 37 deletions(-) diff --git a/src/Umbraco.Web/Cache/ContentCacheRefresher.cs b/src/Umbraco.Web/Cache/ContentCacheRefresher.cs index 21b97d980d..5acd94d12c 100644 --- a/src/Umbraco.Web/Cache/ContentCacheRefresher.cs +++ b/src/Umbraco.Web/Cache/ContentCacheRefresher.cs @@ -97,13 +97,7 @@ namespace Umbraco.Web.Cache //if (Suspendable.PageCacheRefresher.CanUpdateDocumentCache) // ... - _publishedSnapshotService.Notify(payloads, out _, out var publishedChanged); - - if (payloads.Any(x => x.ChangeTypes.HasType(TreeChangeTypes.RefreshAll)) || publishedChanged) - { - // when a public version changes - AppCaches.ClearPartialViewCache(); - } + NotifyPublishedSnapshotService(_publishedSnapshotService, AppCaches, payloads); base.Refresh(payloads); } @@ -111,30 +105,35 @@ namespace Umbraco.Web.Cache // these events should never trigger // everything should be PAYLOAD/JSON - public override void RefreshAll() - { - throw new NotSupportedException(); - } + public override void RefreshAll() => throw new NotSupportedException(); - public override void Refresh(int id) - { - throw new NotSupportedException(); - } + public override void Refresh(int id) => throw new NotSupportedException(); - public override void Refresh(Guid id) - { - throw new NotSupportedException(); - } + public override void Refresh(Guid id) => throw new NotSupportedException(); - public override void Remove(int id) - { - throw new NotSupportedException(); - } + public override void Remove(int id) => throw new NotSupportedException(); #endregion #region Json + /// + /// Refreshes the publish snapshot service and if there are published changes ensures that partial view caches are refreshed too + /// + /// + /// + /// + internal static void NotifyPublishedSnapshotService(IPublishedSnapshotService service, AppCaches appCaches, JsonPayload[] payloads) + { + service.Notify(payloads, out _, out var publishedChanged); + + if (payloads.Any(x => x.ChangeTypes.HasType(TreeChangeTypes.RefreshAll)) || publishedChanged) + { + // when a public version changes + appCaches.ClearPartialViewCache(); + } + } + public class JsonPayload { public JsonPayload(int id, TreeChangeTypes changeTypes) diff --git a/src/Umbraco.Web/Cache/LanguageCacheRefresher.cs b/src/Umbraco.Web/Cache/LanguageCacheRefresher.cs index 9093124609..03102ec969 100644 --- a/src/Umbraco.Web/Cache/LanguageCacheRefresher.cs +++ b/src/Umbraco.Web/Cache/LanguageCacheRefresher.cs @@ -8,7 +8,9 @@ using Umbraco.Web.PublishedCache; namespace Umbraco.Web.Cache { - public sealed class LanguageCacheRefresher : CacheRefresherBase + public sealed class LanguageCacheRefresher : PayloadCacheRefresherBase + + //CacheRefresherBase { public LanguageCacheRefresher(AppCaches appCaches, IPublishedSnapshotService publishedSnapshotService, IDomainService domainService) : base(appCaches) @@ -33,21 +35,62 @@ namespace Umbraco.Web.Cache #region Refresher - public override void Refresh(int id) + public override void Refresh(JsonPayload[] payloads) { + if (payloads.Length == 0) return; + + var clearDictionary = false; + var clearContent = false; + + //clear all no matter what type of payload ClearAllIsolatedCacheByEntityType(); - RefreshDomains(id); - base.Refresh(id); + + foreach (var payload in payloads) + { + RefreshDomains(payload.Id); + + switch (payload.ChangeType) + { + case JsonPayload.LanguageChangeType.Update: + clearDictionary = true; + break; + case JsonPayload.LanguageChangeType.Remove: + clearDictionary = true; + clearContent = true; + break; + case JsonPayload.LanguageChangeType.ChangeCulture: + clearDictionary = true; + clearContent = true; + break; + } + } + + if (clearDictionary) + { + ClearAllIsolatedCacheByEntityType(); + } + + //if this flag is set, we will tell the published snapshot service to refresh ALL content + if (clearContent) + { + var clearContentPayload = new[] { new ContentCacheRefresher.JsonPayload(0, null, TreeChangeTypes.RefreshAll) }; + ContentCacheRefresher.NotifyPublishedSnapshotService(_publishedSnapshotService, AppCaches, clearContentPayload); + } + + // then trigger event + base.Refresh(payloads); } - public override void Remove(int id) - { - ClearAllIsolatedCacheByEntityType(); - //if a language is removed, then all dictionary cache needs to be removed - ClearAllIsolatedCacheByEntityType(); - RefreshDomains(id); - base.Remove(id); - } + // these events should never trigger + // everything should be PAYLOAD/JSON + + public override void RefreshAll() => throw new NotSupportedException(); + + public override void Refresh(int id) => throw new NotSupportedException(); + + public override void Refresh(Guid id) => throw new NotSupportedException(); + + public override void Remove(int id) => throw new NotSupportedException(); #endregion @@ -69,5 +112,46 @@ namespace Umbraco.Web.Cache _publishedSnapshotService.Notify(assignedDomains.Select(x => new DomainCacheRefresher.JsonPayload(x.Id, DomainChangeTypes.Remove)).ToArray()); } } + + #region Json + + public class JsonPayload + { + public JsonPayload(int id, string isoCode, LanguageChangeType changeType) + { + Id = id; + IsoCode = isoCode; + ChangeType = changeType; + } + + public int Id { get; } + public string IsoCode { get; } + public LanguageChangeType ChangeType { get; } + + public enum LanguageChangeType + { + /// + /// A new languages has been added + /// + Add = 0, + + /// + /// A language has been deleted + /// + Remove = 1, + + /// + /// A language has been updated - but it's culture remains the same + /// + Update = 2, + + /// + /// A language has been updated - it's culture has changed + /// + ChangeCulture = 3 + } + } + + #endregion } } diff --git a/src/Umbraco.Web/Search/ExamineComponent.cs b/src/Umbraco.Web/Search/ExamineComponent.cs index f34b1f862b..149b4d1436 100644 --- a/src/Umbraco.Web/Search/ExamineComponent.cs +++ b/src/Umbraco.Web/Search/ExamineComponent.cs @@ -27,6 +27,7 @@ namespace Umbraco.Web.Search private readonly IPublishedContentValueSetBuilder _publishedContentValueSetBuilder; private readonly IValueSetBuilder _mediaValueSetBuilder; private readonly IValueSetBuilder _memberValueSetBuilder; + private readonly BackgroundIndexRebuilder _backgroundIndexRebuilder; private static object _isConfiguredLocker = new object(); private readonly IScopeProvider _scopeProvider; private readonly ServiceContext _services; @@ -47,7 +48,8 @@ namespace Umbraco.Web.Search IContentValueSetBuilder contentValueSetBuilder, IPublishedContentValueSetBuilder publishedContentValueSetBuilder, IValueSetBuilder mediaValueSetBuilder, - IValueSetBuilder memberValueSetBuilder) + IValueSetBuilder memberValueSetBuilder, + BackgroundIndexRebuilder backgroundIndexRebuilder) { _services = services; _scopeProvider = scopeProvider; @@ -56,7 +58,7 @@ namespace Umbraco.Web.Search _publishedContentValueSetBuilder = publishedContentValueSetBuilder; _mediaValueSetBuilder = mediaValueSetBuilder; _memberValueSetBuilder = memberValueSetBuilder; - + _backgroundIndexRebuilder = backgroundIndexRebuilder; _mainDom = mainDom; _logger = profilingLogger; _indexCreator = indexCreator; @@ -111,6 +113,7 @@ namespace Umbraco.Web.Search ContentTypeCacheRefresher.CacheUpdated += ContentTypeCacheRefresherUpdated; MediaCacheRefresher.CacheUpdated += MediaCacheRefresherUpdated; MemberCacheRefresher.CacheUpdated += MemberCacheRefresherUpdated; + LanguageCacheRefresher.CacheUpdated += LanguageCacheRefresherUpdated; } public void Terminate() @@ -320,6 +323,25 @@ namespace Umbraco.Web.Search } } + private void LanguageCacheRefresherUpdated(LanguageCacheRefresher sender, CacheRefresherEventArgs e) + { + if (!(e.MessageObject is LanguageCacheRefresher.JsonPayload[] payloads)) + return; + + if (payloads.Length == 0) return; + + var removedOrCultureChanged = payloads.Any(x => + x.ChangeType == LanguageCacheRefresher.JsonPayload.LanguageChangeType.ChangeCulture + || x.ChangeType == LanguageCacheRefresher.JsonPayload.LanguageChangeType.Remove); + + if (removedOrCultureChanged) + { + //if a lang is removed or it's culture has changed, we need to rebuild the indexes since + //field names and values in the index have a string culture value. + _backgroundIndexRebuilder.RebuildIndexes(false); + } + } + /// /// Updates indexes based on content type changes /// From 37fce725ff649bbd0fb981b999f239006dfc2f84 Mon Sep 17 00:00:00 2001 From: Shannon Date: Mon, 14 Oct 2019 10:04:51 +0200 Subject: [PATCH 22/68] Updates UI to allow updating a culture for a language and warn the user if they are changing it, updates the controller to be able to udpate a culture on a lang --- .../src/views/languages/edit.controller.js | 119 +- .../src/views/languages/overlays/change.html | 7 + src/Umbraco.Web.UI/Umbraco/config/lang/en.xml | 1 + .../Umbraco/config/lang/en_us.xml | 4317 +++++++++-------- .../Cache/DistributedCacheExtensions.cs | 12 +- src/Umbraco.Web/Editors/LanguageController.cs | 35 +- 6 files changed, 2280 insertions(+), 2211 deletions(-) create mode 100644 src/Umbraco.Web.UI.Client/src/views/languages/overlays/change.html diff --git a/src/Umbraco.Web.UI.Client/src/views/languages/edit.controller.js b/src/Umbraco.Web.UI.Client/src/views/languages/edit.controller.js index a11aa8bff8..5f1c46de4c 100644 --- a/src/Umbraco.Web.UI.Client/src/views/languages/edit.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/languages/edit.controller.js @@ -1,7 +1,7 @@ (function () { "use strict"; - function LanguagesEditController($scope, $timeout, $location, $routeParams, navigationService, notificationsService, localizationService, languageResource, contentEditingHelper, formHelper, eventsService) { + function LanguagesEditController($scope, $q, $timeout, $location, $routeParams, overlayService, navigationService, notificationsService, localizationService, languageResource, contentEditingHelper, formHelper, eventsService) { var vm = this; @@ -20,6 +20,8 @@ vm.toggleMandatory = toggleMandatory; vm.toggleDefault = toggleDefault; + var currCulture = null; + function init() { // localize labels @@ -32,7 +34,8 @@ "languages_addLanguage", "languages_noFallbackLanguageOption", "languages_fallbackLanguageDescription", - "languages_fallbackLanguage" + "languages_fallbackLanguage", + "defaultdialogs_confirmSure" ]; localizationService.localizeMany(labelKeys).then(function (values) { @@ -43,6 +46,7 @@ vm.labels.defaultLanguageHelp = values[4]; vm.labels.addLanguage = values[5]; vm.labels.noFallbackLanguageOption = values[6]; + vm.labels.areYouSure = values[9]; $scope.properties = { fallbackLanguage: { @@ -53,46 +57,56 @@ }; if ($routeParams.create) { - vm.page.name = vm.labels.addLanguage; - languageResource.getCultures().then(function (culturesDictionary) { - var cultures = []; - angular.forEach(culturesDictionary, function (value, key) { - cultures.push({ - name: key, - displayName: value - }); - }); - vm.availableCultures = cultures; - }); + vm.page.name = vm.labels.addLanguage; } }); vm.loading = true; - languageResource.getAll().then(function (languages) { + + var promises = []; + + //load all culture/languages + promises.push(languageResource.getCultures().then(function (culturesDictionary) { + var cultures = []; + angular.forEach(culturesDictionary, function (value, key) { + cultures.push({ + name: key, + displayName: value + }); + }); + vm.availableCultures = cultures; + })); + + //load all possible fallback languages + promises.push(languageResource.getAll().then(function (languages) { vm.availableLanguages = languages.filter(function (l) { return $routeParams.id != l.id; }); vm.loading = false; - }); + })); if (!$routeParams.create) { - vm.loading = true; - - languageResource.getById($routeParams.id).then(function(lang) { + promises.push(languageResource.getById($routeParams.id).then(function(lang) { vm.language = lang; vm.page.name = vm.language.name; - /* we need to store the initial default state so we can disabel the toggle if it is the default. + /* we need to store the initial default state so we can disable the toggle if it is the default. we need to prevent from not having a default language. */ vm.initIsDefault = angular.copy(vm.language.isDefault); - vm.loading = false; makeBreadcrumbs(); - }); + + //store to check if we are changing the lang culture + currCulture = vm.language.culture; + })); } + $q.all(promises, function () { + vm.loading = false; + }); + $timeout(function () { navigationService.syncTree({ tree: "languages", path: "-1" }); }); @@ -103,31 +117,54 @@ if (formHelper.submitForm({ scope: $scope })) { vm.page.saveButtonState = "busy"; - languageResource.save(vm.language).then(function (lang) { + //check if the culture is being changed + if (currCulture && vm.language.culture !== currCulture) { - formHelper.resetForm({ scope: $scope }); + const changeCultureAlert = { + title: vm.labels.areYouSure, + view: "views/languages/overlays/change.html", + submitButtonLabelKey: "general_continue", + submit: function (model) { + saveLanguage(); + overlayService.close(); + }, + close: function () { + overlayService.close(); + vm.page.saveButtonState = "init"; + } + }; - vm.language = lang; - vm.page.saveButtonState = "success"; - localizationService.localize("speechBubbles_languageSaved").then(function(value){ - notificationsService.success(value); - }); - - // emit event when language is created or updated/saved - var args = { language: lang, isNew: $routeParams.create ? true : false }; - eventsService.emit("editors.languages.languageSaved", args); - - back(); - - }, function (err) { - vm.page.saveButtonState = "error"; - - formHelper.handleError(err); - - }); + overlayService.open(changeCultureAlert); + } + else { + saveLanguage(); + } } + } + function saveLanguage() { + languageResource.save(vm.language).then(function (lang) { + formHelper.resetForm({ scope: $scope }); + + vm.language = lang; + vm.page.saveButtonState = "success"; + localizationService.localize("speechBubbles_languageSaved").then(function (value) { + notificationsService.success(value); + }); + + // emit event when language is created or updated/saved + var args = { language: lang, isNew: $routeParams.create ? true : false }; + eventsService.emit("editors.languages.languageSaved", args); + + back(); + + }, function (err) { + vm.page.saveButtonState = "error"; + + formHelper.handleError(err); + + }); } function back() { diff --git a/src/Umbraco.Web.UI.Client/src/views/languages/overlays/change.html b/src/Umbraco.Web.UI.Client/src/views/languages/overlays/change.html new file mode 100644 index 0000000000..c5e813fa51 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/views/languages/overlays/change.html @@ -0,0 +1,7 @@ +
+ +
+ Changing the culture for a language may be an expensive operation and will result in the content cache and indexes being rebuilt. +
+ +
diff --git a/src/Umbraco.Web.UI/Umbraco/config/lang/en.xml b/src/Umbraco.Web.UI/Umbraco/config/lang/en.xml index 7f15cab2c2..fefab08c4b 100644 --- a/src/Umbraco.Web.UI/Umbraco/config/lang/en.xml +++ b/src/Umbraco.Web.UI/Umbraco/config/lang/en.xml @@ -414,6 +414,7 @@ Click to add a Macro Insert table This will delete the language + Changing the culture for a language may be an expensive operation and will result in the content cache and indexes being rebuilt Last Edited Link Internal link: 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 08c8829a73..60e711f8e3 100644 --- a/src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml +++ b/src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml @@ -1,2157 +1,2168 @@ - - - - The Umbraco community - https://our.umbraco.com/documentation/Extending-Umbraco/Language-Files - - - Culture and Hostnames - Audit Trail - Browse Node - Change Document Type - Copy - Create - Export - Create Package - Create group - Delete - Disable - Empty recycle bin - Enable - Export Document Type - Import Document Type - Import Package - Edit in Canvas - Exit - Move - Notifications - Public access - Publish - Unpublish - Reload - Republish entire site - Rename - Restore - Set permissions for the page %0% - Choose where to copy - Choose where to move - to in the tree structure below - was moved to - was copied to - was deleted - Permissions - Rollback - Send To Publish - Send To Translation - Set group - Sort - Translate - Update - Set permissions - Unlock - Create Content Template - Resend Invitation - - - Content - Administration - Structure - Other - - - Allow access to assign culture and hostnames - Allow access to view a node's history log - Allow access to view a node - Allow access to change document type for a node - Allow access to copy a node - Allow access to create nodes - Allow access to delete nodes - Allow access to move a node - Allow access to set and change public access for a node - Allow access to publish a node - Allow access to unpublish a node - Allow access to change permissions for a node - Allow access to roll back a node to a previous state - Allow access to send a node for approval before publishing - Allow access to send a node for translation - Allow access to change the sort order for nodes - Allow access to translate a node - Allow access to save a node - Allow access to create a Content Template - - - Content - Info - - - Permission denied. - Add new Domain - remove - Invalid node. - One or more domains have an invalid format. - Domain has already been assigned. - Language - Domain - New domain '%0%' has been created - Domain '%0%' is deleted - Domain '%0%' has already been assigned - Domain '%0%' has been updated - Edit Current Domains - - - Inherit - Culture - or inherit culture from parent nodes. Will also apply
- to the current node, unless a domain below applies too.]]>
- Domains - - - Clear selection - Select - Do something else - Bold - Cancel Paragraph Indent - Insert form field - Insert graphic headline - Edit Html - Indent Paragraph - Italic - Center - Justify Left - Justify Right - Insert Link - Insert local link (anchor) - Bullet List - Numeric List - Insert macro - Insert picture - Publish and close - Publish with descendants - Edit relations - Return to list - Save - Save and close - Save and publish - Save and schedule - Send for approval - Save list view - Schedule - Preview - Preview is disabled because there's no template assigned - Choose style - Show styles - Insert table - Generate models and close - Save and generate models - Undo - Redo - Rollback - Delete tag - Cancel - Confirm - More publishing options - - - Viewing for - Content deleted - Content unpublished - Content unpublished for languages: %0% - Content published - Content published for languages: %0% - Content saved - Content saved for languages: %0% - Content moved - Content copied - Content rolled back - Content sent for publishing - Content sent for publishing for languages: %0% - Sort child items performed by user - Copy - Publish - Publish - Move - Save - Save - Delete - Unpublish - Unpublish - Rollback - Send To Publish - Send To Publish - Sort - History (all variants) - - - To change the document type for the selected content, first select from the list of valid types for this location. - Then confirm and/or amend the mapping of properties from the current type to the new, and click Save. - The content has been re-published. - Current Property - Current type - The document type cannot be changed, as there are no alternatives valid for this location. An alternative will be valid if it is allowed under the parent of the selected content item and that all existing child content items are allowed to be created under it. - Document Type Changed - Map Properties - Map to Property - New Template - New Type - none - Content - Select New Document Type - The document type of the selected content has been successfully changed to [new type] and the following properties mapped: - to - 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% - The folder name cannot contain illegal characters. - Failed to delete item: %0% - - - Is Published - About this page - Alias - (how would you describe the picture over the phone) - Alternative Links - Click to edit this item - Created by - Original author - Updated by - Created - Date/time this document was created - Document Type - Editing - Remove at - This item has been changed after publication - This item is not published - Last published - There are no items to show - There are no items to show in the list. - No child items have been added - No members have been added - Media Type - Link to media item(s) - Member Group - Role - Member Type - No changes have been made - No date chosen - Page title - This media item has no link - No content can be added for this item - Properties - This document is published but is not visible because the parent '%0%' is unpublished - This culture is published but is not visible because it is unpublished on parent '%0%' - This document is published but is not in the cache - Could not get the url - This document is published but its url would collide with content %0% - This document is published but its url cannot be routed - Publish - Published - Published (pending changes)> - Publication Status - Publish with descendants to publish %0% and all content items underneath and thereby making their content publicly available.]]> - Publish with descendants to publish the selected languages and the same languages of content items underneath and thereby making their content publicly available.]]> - Publish at - Unpublish at - Clear Date - Set date - Sortorder is updated - To sort the nodes, simply drag the nodes or click one of the column headers. You can select multiple nodes by holding the "shift" or "control" key while selecting - Statistics - Title (optional) - Alternative text (optional) - Type - Unpublish - Draft - Not created - Last edited - Date/time this document was edited - Remove file(s) - Link to document - Member of group(s) - Not a member of group(s) - Child items - Target - This translates to the following time on the server: - What does this mean?]]> - Are you sure you want to delete this item? - Property %0% uses editor %1% which is not supported by Nested Content. - No content types are configured for this property. - Add another text box - Remove this text box - Content root - Include drafts: also publish unpublished content items. - This value is hidden. If you need access to view this value please contact your website administrator. - This value is hidden. - What languages would you like to publish? All languages with content are saved! - What languages would you like to publish? - What languages would you like to save? - All languages with content are saved on creation! - What languages would you like to send for approval? - What languages would you like to schedule? - Select the languages to unpublish. Unpublishing a mandatory language will unpublish all languages. - Published Languages - Unpublished Languages - Unmodified Languages - These languages haven't been created - Ready to Publish? - Ready to Save? - Send for approval - Select the date and time to publish and/or unpublish the content item. - Create new - Paste from clipboard - - - Create a new Content Template from '%0%' - Blank - Select a Content Template - Content Template created - A Content Template was created from '%0%' - Another Content Template with the same name already exists - A Content Template is predefined content that an editor can select to use as the basis for creating new content - - - Click to upload - or click here to choose files - You can drag files here to upload. - Cannot upload this file, it does not have an approved file type - Max file size is - Media root - Failed to move media - Parent and destination folders cannot be the same - Failed to copy media - Failed to create a folder under parent id %0% - Failed to rename the folder with id %0% - Drag and drop your file(s) into the area - - - Create a new member - All Members - Member groups have no additional properties for editing. - - - 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 within the Settings section, by editing the Allowed child node types under Permissions.]]> - The selected page in the content tree doesn't allow for any pages to be created below it. - Edit permissions for this document type - Media Types Types within the Settings section, by editing the Allowed child node types under Permissions.]]> - The selected media in the tree doesn't allow for any other media to be created below it. - Edit permissions for this media type Document Type without a template - New folder - New data type - New JavaScript file - New empty partial view - New partial view macro - New partial view from snippet - New partial view macro from snippet - New partial view macro (without macro) - New style sheet file - New Rich Text Editor style sheet file - - - Browse your website - - Hide - If Umbraco isn't opening, you might need to allow popups from this site - has opened in a new window - Restart - Visit - Welcome - - - Stay - Discard changes - You have unsaved changes - Are you sure you want to navigate away from this page? - you have unsaved changes - Publishing will make the selected items visible on the site. - Unpublishing will remove the selected items and all their descendants from the site. - Unpublishing will remove this page and all its descendants from the site. - You have unsaved changes. Making changes to the Document Type will discard the 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 - - - Link title - Link - Anchor / querystring - Name - Close this window - Are you sure you want to delete - Are you sure you want to disable - Are you sure? - Are you sure? - Cut - Edit Dictionary Item - Edit Language - Insert local link - Insert character - Insert graphic headline - Insert picture - Insert link - Click to add a Macro - Insert table - This will delete the language - Last Edited - Link - Internal link: - When using local links, insert "#" in front of link - Open in new window? - Macro Settings - This macro does not contain any properties you can edit - Paste - Edit permissions for - Set permissions for - Set permissions for %0% for user group %1% - Select the users groups you want to set permissions for - The items in the recycle bin are now being deleted. Please do not close this window while this operation takes place - The recycle bin is now empty - When items are deleted from the recycle bin, they will be gone forever - regexlib.com's webservice is currently experiencing some problems, which we have no control over. We are very sorry for this inconvenience.]]> - Search for a regular expression to add validation to a form field. Example: 'email, 'zip-code' 'url' - Remove Macro - Required Field - Site is reindexed - The website cache has been refreshed. All publish content is now up to date. While all unpublished content is still unpublished - The website cache will be refreshed. All published content will be updated, while unpublished content will stay unpublished. - Number of columns - Number of rows - Click on the image to see full size - Pick item - View Cache Item - Relate to original - Include descendants - The friendliest community - Link to page - Opens the linked document in a new window or tab - Link to media - Select content start node - Select media - Select media type - Select icon - Select item - Select link - Select macro - Select content - Select content type - Select media start node - Select member - Select member group - Select member type - Select node - Select sections - Select users - No icons were found - There are no parameters for this macro - There are no macros available to insert - External login providers - Exception Details - Stacktrace - Inner Exception - Link your - Un-link your - account - Select editor - Select snippet - This will delete the node and all its languages. If you only want to delete one language go and unpublish it instead. - - - There are no dictionary items. - - - %0%' below - ]]> - Culture Name - - Dictionary overview - - - Configured Searchers - Shows properties and tools for any configured Searcher (i.e. such as a multi-index searcher) - Field values - Health status - The health status of the index and if it can be read - Indexers - Index info - Lists the properties of the index - Manage Examine's indexes - Allows you to view the details of each index and provides some tools for managing the indexes - Rebuild index - - Depending on how much content there is in your site this could take a while.
- It is not recommended to rebuild an index during times of high website traffic or when editors are editing content. - ]]> -
- Searchers - Search the index and view the results - Tools - Tools to manage the index - - - Enter your username - Enter your password - Confirm your password - Name the %0%... - Enter a name... - Enter an email... - Enter a username... - Label... - Enter a description... - Type to search... - Type to filter... - Type to add tags (press enter after each tag)... - Enter your email - Enter a message... - Your username is usually your email - #value or ?key=value - Enter alias... - Generating alias... - Create item - Edit - Name - - - Create custom list view - Remove custom list view - A content type, media type or member type with this alias already exists - - - Renamed - Enter a new folder name here - %0% was renamed to %1% - - - Add prevalue - Database datatype - Property editor GUID - Property editor - Buttons - Enable advanced settings for - Enable context menu - Maximum default size of inserted images - Related stylesheets - Show label - Width and height - All property types & property data - using this data type will be deleted permanently, please confirm you want to delete these as well - Yes, delete - and all property types & property data using this data type - Select the folder to move - to in the tree structure below - was moved underneath - - - Your data has been saved, but before you can publish this page there are some errors you need to fix first: - The current membership provider does not support changing password (EnablePasswordRetrieval need to be true) - %0% already exists - There were errors: - There were errors: - The password should be a minimum of %0% characters long and contain at least %1% non-alpha numeric character(s) - %0% must be an integer - The %0% field in the %1% tab is mandatory - %0% is a mandatory field - %0% at %1% is not in a correct format - %0% is not in a correct format - - - Received an error from the server - The specified file type has been disallowed by the administrator - NOTE! Even though CodeMirror is enabled by configuration, it is disabled in Internet Explorer because it's not stable enough. - Please fill both alias and name on the new property type! - There is a problem with read/write access to a specific file or folder - Error loading Partial View script (file: %0%) - Please enter a title - Please choose a type - You're about to make the picture larger than the original size. Are you sure that you want to proceed? - Startnode deleted, please contact your administrator - Please mark content before changing style - No active styles available - Please place cursor at the left of the two cells you wish to merge - You cannot split a cell that hasn't been merged. - This property is invalid - - - Options - About - Action - Actions - Add - Alias - All - Are you sure? - Back - Back to overview - Border - by - Cancel - Cell margin - Choose - Close - Close Window - Comment - Confirm - Constrain - Constrain proportions - Content - Continue - Copy - Create - Database - Date - Default - Delete - Deleted - Deleting... - Design - Dictionary - Dimensions - Down - Download - Edit - Edited - Elements - Email - Error - Field - Find - First - General - Groups - Group - Height - Help - Hide - History - Icon - Id - Import - Include subfolders in search - Info - Inner margin - Insert - Install - Invalid - Justify - Label - Language - Last - Layout - Links - Loading - Locked - Login - Log off - Logout - Macro - Mandatory - Message - Move - Name - New - Next - No - of - Off - OK - Open - On - or - Order by - Password - Path - One moment please... - Previous - Properties - Rebuild - Email to receive form data - Recycle Bin - Your recycle bin is empty - Reload - Remaining - Remove - Rename - Renew - Required - Retrieve - Retry - Permissions - Scheduled Publishing - Search - Sorry, we can not find what you are looking for. - No items have been added - Server - Settings - Show - Show page on Send - Size - Sort - Status - Submit - Type - Type to search... - under - Up - Update - Upgrade - Upload - Url - User - Username - Value - View - Welcome... - Width - Yes - Folder - Search results - Reorder - I am done reordering - Preview - Change password - to - List view - Saving... - current - Embed - selected - - - Blue - - - Add group - Add property - Add editor - Add template - Add child node - Add child - Edit data type - Navigate sections - Shortcuts - show shortcuts - Toggle list view - Toggle allow as root - Comment/Uncomment lines - Remove line - Copy Lines Up - Copy Lines Down - Move Lines Up - Move Lines Down - General - Editor - Toggle allow culture variants - - - Background color - Bold - Text color - Font - Text - - - Page - - - The installer cannot connect to the database. - Could not save the web.config file. Please modify the connection string manually. - Your database has been found and is identified as - Database configuration - install button to install the Umbraco %0% database - ]]> - Next to proceed.]]> - Database not found! Please check that the information in the "connection string" of the "web.config" file is correct.

-

To proceed, please edit the "web.config" file (using Visual Studio or your favourite text editor), scroll to the bottom, add the connection string for your database in the key named "UmbracoDbDSN" and save the file.

-

- Click the retry button when - done.
- More information on editing web.config here.

]]>
- - Please contact your ISP if necessary. - If you're installing on a local machine or server you might need information from your system administrator.]]> - - Press the upgrade button to upgrade your database to Umbraco %0%

-

- Don't worry - no content will be deleted and everything will continue working afterwards! -

- ]]>
- Press Next to - proceed. ]]> - next to continue the configuration wizard]]> - The Default users' password needs to be changed!]]> - The Default user has been disabled or has no access to Umbraco!

No further actions needs to be taken. Click Next to proceed.]]> - The Default user's password has been successfully changed since the installation!

No further actions needs to be taken. Click Next to proceed.]]> - The password is changed! - Get a great start, watch our introduction videos - By clicking the next button (or modifying the umbracoConfigurationStatus in web.config), you accept the license for this software as specified in the box below. Notice that this Umbraco distribution consists of two different licenses, the open source MIT license for the framework and the Umbraco freeware license that covers the UI. - Not installed yet. - Affected files and folders - More information on setting up permissions for Umbraco here - You need to grant ASP.NET modify permissions to the following files/folders - Your permission settings are almost perfect!

- You can run Umbraco without problems, but you will not be able to install packages which are recommended to take full advantage of Umbraco.]]>
- How to Resolve - Click here to read the text version - video tutorial on setting up folder permissions for Umbraco or read the text version.]]> - Your permission settings might be an issue! -

- You can run Umbraco without problems, but you will not be able to create folders or install packages which are recommended to take full advantage of Umbraco.]]>
- Your permission settings are not ready for Umbraco! -

- In order to run Umbraco, you'll need to update your permission settings.]]>
- Your permission settings are perfect!

- You are ready to run Umbraco and install packages!]]>
- Resolving folder issue - Follow this link for more information on problems with ASP.NET and creating folders - Setting up folder permissions - - I want to start from scratch - learn how) - You can still choose to install Runway later on. Please go to the Developer section and choose Packages. - ]]> - You've just set up a clean Umbraco platform. What do you want to do next? - Runway is installed - - This is our list of recommended modules, check off the ones you would like to install, or view the full list of modules - ]]> - Only recommended for experienced users - I want to start with a simple website - - "Runway" is a simple website providing some basic document types and templates. The installer can set up Runway for you automatically, - but you can easily edit, extend or remove it. It's not necessary and you can perfectly use Umbraco without it. However, - Runway offers an easy foundation based on best practices to get you started faster than ever. - If you choose to install Runway, you can optionally select basic building blocks called Runway Modules to enhance your Runway pages. -

- - Included with Runway: Home page, Getting Started page, Installing Modules page.
- Optional Modules: Top Navigation, Sitemap, Contact, Gallery. -
- ]]>
- What is Runway - Step 1/5 Accept license - Step 2/5: Database configuration - Step 3/5: Validating File Permissions - Step 4/5: Check Umbraco security - Step 5/5: Umbraco is ready to get you started - Thank you for choosing Umbraco - Browse your new site -You installed Runway, so why not see how your new website looks.]]> - Further help and information -Get help from our award winning community, browse the documentation or watch some free videos on how to build a simple site, how to use packages and a quick guide to the Umbraco terminology]]> - Umbraco %0% is installed and ready for use - /web.config file and update the AppSetting key UmbracoConfigurationStatus in the bottom to the value of '%0%'.]]> - started instantly by clicking the "Launch Umbraco" button below.
If you are new to Umbraco, -you can find plenty of resources on our getting started pages.]]>
- Launch Umbraco -To manage your website, simply open the Umbraco back office and start adding content, updating the templates and stylesheets or add new functionality]]> - Connection to database failed. - Umbraco Version 3 - Umbraco Version 4 - Watch - Umbraco %0% for a fresh install or upgrading from version 3.0. -

- Press "next" to start the wizard.]]>
- - - Culture Code - Culture Name - - - You've been idle and logout will automatically occur in - Renew now to save your work - - - Happy super Sunday - Happy manic Monday - Happy tubular Tuesday - Happy wonderful Wednesday - Happy thunderous Thursday - Happy funky Friday - Happy Caturday - Log in below - Sign in with - Session timed out - © 2001 - %0%
Umbraco.com

]]>
- Forgotten password? - An email will be sent to the address specified with a link to reset your password - An email with password reset instructions will be sent to the specified address if it matched our records - Show password - Hide password - Return to login form - Please provide a new password - Your Password has been updated - The link you have clicked on is invalid or has expired - Umbraco: Reset Password - - - - - - - - - - - -
- - - - - -
- -
- -
-
- - - - - - -
-
-
- - - - -
- - - - -
-

- Password reset requested -

-

- Your username to login to the Umbraco back-office is: %0% -

-

- - - - - - -
- - Click this link to reset your password - -
-

-

If you cannot click on the link, copy and paste this URL into your browser window:

- - - - -
- - %1% - -
-

-
-
-


-
-
- - - ]]>
- - - Dashboard - Sections - Content - - - Choose page above... - %0% has been copied to %1% - Select where the document %0% should be copied to below - %0% has been moved to %1% - Select where the document %0% should be moved to below - has been selected as the root of your new content, click 'ok' below. - No node selected yet, please select a node in the list above before clicking 'ok' - The current node is not allowed under the chosen node because of its type - The current node cannot be moved to one of its subpages - The current node cannot exist at the root - The action isn't allowed since you have insufficient permissions on 1 or more child documents. - Relate copied items to original - - - %0%]]> - Notification settings saved for - - The following languages have been modified %0% - - - - - - - - - - - -
- - - - - -
- -
- -
-
- - - - - - -
-
-
- - - - -
- - - - -
-

- Hi %0%, -

-

- This is an automated mail to inform you that the task '%1%' has been performed on the page '%2%' by the user '%3%' -

- - - - - - -
- -
- EDIT
-
-

-

Update summary:

- %6% -

-

- Have a nice day!

- Cheers from the Umbraco robot -

-
-
-


-
-
- - - ]]>
- The following languages have been modified:

- %0% - ]]>
- [%0%] Notification about %1% performed on %2% - Notifications - - - Actions - Created - Create package - - button and locating the package. Umbraco packages usually have a ".umb" or ".zip" extension. - ]]> - This will delete the package - Drop to upload - Include all child nodes - or click here to choose package file - Upload package - Install a local package by selecting it from your machine. Only install packages from sources you know and trust - Upload another package - Cancel and upload another package - I accept - terms of use - Path to file - Absolute path to file (ie: /bin/umbraco.bin) - Installed - Installed packages - Install local - Finish - This package has no configuration view - No packages have been created yet - You don’t have any packages installed - 'Packages' icon in the top right of your screen]]> - Package Actions - Author URL - Package Content - Package Files - Icon URL - Install package - License - License URL - Package Properties - Search for packages - Results for - We couldn’t find anything for - Please try searching for another package or browse through the categories - Popular - New releases - has - karma points - Information - Owner - Contributors - Created - Current version - .NET version - Downloads - Likes - Compatibility - This package is compatible with the following versions of Umbraco, as reported by community members. Full compatability cannot be guaranteed for versions reported below 100% - External sources - Author - Documentation - Package meta data - Package name - Package doesn't contain any items -
- You can safely remove this from the system by clicking "uninstall package" below.]]>
- Package options - Package readme - Package repository - Confirm package uninstall - Package was uninstalled - The package was successfully uninstalled - Uninstall package - - Notice: any documents, media etc depending on the items you remove, will stop working, and could lead to system instability, - so uninstall with caution. If in doubt, contact the package author.]]> - Package version - Upgrading from version - Package already installed - This package cannot be installed, it requires a minimum Umbraco version of - Uninstalling... - Downloading... - Importing... - Installing... - Restarting, please wait... - All done, your browser will now refresh, please wait... - Please click 'Finish' to complete installation and reload the page. - Uploading package... - - - Paste with full formatting (Not recommended) - The text you're trying to paste contains special characters or formatting. This could be caused by copying text from Microsoft Word. Umbraco can remove special characters or formatting automatically, so the pasted content will be more suitable for the web. - Paste as raw text without any formatting at all - Paste, but remove formatting (Recommended) - - - Group based protection - If you want to grant access to all members of specific member groups - You need to create a member group before you can use group based authentication - Error Page - Used when people are logged on, but do not have access - %0%]]> - %0% is now protected]]> - %0%]]> - Login Page - Choose the page that contains the login form - Remove protection... - %0%?]]> - Select the pages that contain login form and error messages - %0%]]> - %0%]]> - Specific members protection - If you wish to grant access to specific members - - - Insufficient user permissions to publish all descendant documents - - - - - - - - Validation failed for required language '%0%'. This language was saved but not published. - Publishing in progress - please wait... - %0% out of %1% pages have been published... - %0% has been published - %0% and subpages have been published - Publish %0% and all its subpages - Publish to publish %0% and thereby making its content publicly available.

- You can publish this page and all its subpages by checking Include unpublished subpages below. - ]]>
- - - You have not configured any approved colors - - - You can only select items of type(s): %0% - You have picked a content item currently deleted or in the recycle bin - You have picked content items currently deleted or in the recycle bin - - - You have picked a media item currently deleted or in the recycle bin - You have picked media items currently deleted or in the recycle bin - Trashed - - - enter external link - choose internal page - Caption - Link - Open in new window - enter the display caption - Enter the link - - - Reset crop - Save crop - Add new crop - Done - Undo edits - - - Select a version to compare with the current version - Current version - Red text will not be shown in the selected version. , green means added]]> - Document has been rolled back - This displays the selected version as HTML, if you wish to see the difference between 2 versions at the same time, use the diff view - Rollback to - Select version - View - - - Edit script file - - - Content - Forms - Media - Members - Packages - Settings - Translation - Users - - - The best Umbraco video tutorials - - - Default template - To import a document type, find the ".udt" file on your computer by clicking the "Browse" button and click "Import" (you'll be asked for confirmation on the next screen) - New Tab Title - Node type - Type - Stylesheet - Script - Tab - Tab Title - Tabs - Master Content Type enabled - 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 - - - Sort order - Creation date - Sorting complete. - Drag the different items up or down below to set how they should be arranged. Or click the column headers to sort the entire collection of items - - This node has no child nodes to sort - - - Validation - Validation errors must be fixed before the item can be saved - Failed - Saved - Insufficient user permissions, could not complete the operation - Cancelled - Operation was cancelled by a 3rd party add-in - Property type already exists - Property type created - DataType: %1%]]> - Propertytype deleted - Document Type saved - Tab created - Tab deleted - Tab with id: %0% deleted - Stylesheet not saved - Stylesheet saved - Stylesheet saved without any errors - Datatype saved - Dictionary item saved - Content published - and is visible on the website - %0% documents published and visible on the website - %0% published and visible on the website - %0% documents published for languages %1% and visible on the website - Content saved - Remember to publish to make changes visible - A schedule for publishing has been updated - %0% saved - Sent For Approval - Changes have been sent for approval - %0% changes have been sent for approval - Media saved - Media saved without any errors - Member saved - Member group saved - Stylesheet Property Saved - Stylesheet saved - Template saved - Error saving user (check log) - User Saved - User type saved - User group saved - File not saved - file could not be saved. Please check file permissions - File saved - File saved without any errors - Language saved - Media Type saved - Member Type saved - Member Group saved - Template not saved - Please make sure that you do not have 2 templates with the same alias - Template saved - Template saved without any errors! - Content unpublished - Content variation %0% unpublished - The mandatory language '%0%' was unpublished. All languages for this content item are now unpublished. - Partial view saved - Partial view saved without any errors! - Partial view not saved - An error occurred saving the file. - Permissions saved for - Deleted %0% user groups - %0% was deleted - Enabled %0% users - Disabled %0% users - %0% is now enabled - %0% is now disabled - User groups have been set - Unlocked %0% users - %0% is now unlocked - Member was exported to file - An error occurred while exporting the member - User %0% was deleted - Invite user - Invitation has been re-sent to %0% - Cannot publish the document since the required '%0%' is not published - Validation failed for language '%0%' - Document type was exported to file - An error occurred while exporting the document type - The release date cannot be in the past - Cannot schedule the document for publishing since the required '%0%' is not published - Cannot schedule the document for publishing since the required '%0%' has a publish date later than a non mandatory language - The expire date cannot be in the past - The expire date cannot be before the release date - - - Add style - Edit style - Rich text editor styles - Define the styles that should be available in the rich text editor for this stylesheet - Edit stylesheet - Edit stylesheet property - The name displayed in the editor style selector - Preview - How the text will look like in the rich text editor. - Selector - Uses CSS syntax, e.g. "h1" or ".redHeader" - Styles - The CSS that should be applied in the rich text editor, e.g. "color:red;" - Code - Rich Text Editor - - - Failed to delete template with ID %0% - Edit template - Sections - Insert content area - Insert content area placeholder - Insert - Choose what to insert into your template - Dictionary item - A dictionary item is a placeholder for a translatable piece of text, which makes it easy to create designs for multilingual websites. - Macro - - A Macro is a configurable component which is great for - reusable parts of your design, where you need the option to provide parameters, - such as galleries, forms and lists. - - Value - Displays the value of a named field from the current page, with options to modify the value or fallback to alternative values. - Partial view - - A partial view is a separate template file which can be rendered inside another - template, it's great for reusing markup or for separating complex templates into separate files. - - Master template - No master - Render child template - @RenderBody() placeholder. - ]]> - Define a named section - @section { ... }. This can be rendered in a - specific area of the parent of this template, by using @RenderSection. - ]]> - Render a named section - @RenderSection(name) placeholder. - This renders an area of a child template which is wrapped in a corresponding @section [name]{ ... } definition. - ]]> - Section Name - Section is mandatory - - If mandatory, the child template must contain a @section definition, otherwise an error is shown. - - Query builder - items returned, in - I want - all content - content of type "%0%" - from - my website - where - and - is - is not - before - before (including selected date) - after - after (including selected date) - equals - does not equal - contains - does not contain - greater than - greater than or equal to - less than - less than or equal to - Id - Name - Created Date - Last Updated Date - order by - ascending - descending - Template - - - Image - Macro - Choose type of content - Choose a layout - Add a row - Add content - Drop content - Settings applied - This content is not allowed here - This content is allowed here - Click to embed - Click to insert image - Image caption... - Write here... - Grid Layouts - Layouts are the overall work area for the grid editor, usually you only need one or two different layouts - Add Grid Layout - Adjust the layout by setting column widths and adding additional sections - Row configurations - Rows are predefined cells arranged horizontally - Add row configuration - Adjust the row by setting cell widths and adding additional cells - Columns - Total combined number of columns in the grid layout - Settings - Configure what settings editors can change - Styles - Configure what styling editors can change - Allow all editors - Allow all row configurations - Maximum items - Leave blank or set to 0 for unlimited - Set as default - Choose extra - Choose default - are added - - - Compositions - Group - You have not added any groups - Add group - Inherited from - Add property - Required label - Enable list view - Configures the content item to show a sortable and searchable list of its children, the children will not be shown in the tree - Allowed Templates - Choose which templates editors are allowed to use on content of this type - Allow as root - Allow editors to create content of this type in the root of the content tree - Allowed child node types - Allow content of the specified types to be created underneath content of this type - Choose child node - Inherit tabs and properties from an existing document type. New tabs will be added to the current document type or merged if a tab with an identical name exists. - This content type is used in a composition, and therefore cannot be composed itself. - There are no content types available to use as a composition. - Create new - Use existing - Editor settings - Configuration - Yes, delete - was moved underneath - was copied underneath - Select the folder to move - Select the folder to copy - to in the tree structure below - All Document types - All Documents - All media items - using this document type will be deleted permanently, please confirm you want to delete these as well. - using this media type will be deleted permanently, please confirm you want to delete these as well. - using this member type will be deleted permanently, please confirm you want to delete these as well - and all documents using this type - and all media items using this type - and all members using this type - Member can edit - Allow this property value to be edited by the member on their profile page - Is sensitive data - Hide this property value from content editors that don't have access to view sensitive information - Show on member profile - Allow this property value to be displayed on the member profile page - tab has no sort order - Where is this composition used? - This composition is currently used in the composition of the following content types: - Allow varying by culture - Allow editors to create content of this type in different languages - Allow varying by culture - Element type - Is an Element type - An Element type is meant to be used for instance in Nested Content, and not in the tree - This is not applicable for an Element type - You have made changes to this property. Are you sure you want to discard them? - - - Add language - Mandatory language - Properties on this language have to be filled out before the node can be published. - Default language - An Umbraco site can only have one default language set. - Switching default language may result in default content missing. - Falls back to - No fall back language - To allow multi-lingual content to fall back to another language if not present in the requested language, select it here. - Fall back language - - - Add parameter - Edit parameter - Enter macro name - Parameters - Define the parameters that should be available when using this macro. - Select partial view macro file - - - Building models - this can take a bit of time, don't worry - Models generated - Models could not be generated - Models generation has failed, see exception in U log - - - Add fallback field - Fallback field - Add default value - Default value - Fallback field - Default value - Casing - Encoding - Choose field - Convert line breaks - Yes, convert line breaks - Replaces line breaks with 'br' html tag - Custom Fields - Date only - Format and encoding - Format as date - Format the value as a date, or a date with time, according to the active culture - HTML encode - Will replace special characters by their HTML equivalent. - Will be inserted after the field value - Will be inserted before the field value - Lowercase - Modify output - None - Output sample - Insert after field - Insert before field - Recursive - Yes, make it recursive - Separator - Standard Fields - Uppercase - URL encode - Will format special characters in URLs - Will only be used when the field values above are empty - This field will only be used if the primary field is empty - Date and time - - - Translation details - Download XML DTD - Fields - Include subpages - - No translator users found. Please create a translator user before you start sending content to translation - The page '%0%' has been send to translation - Send the page '%0%' to translation - Total words - Translate to - Translation completed. - You can preview the pages, you've just translated, by clicking below. If the original page is found, you will get a comparison of the 2 pages. - Translation failed, the XML file might be corrupt - Translation options - Translator - Upload translation XML - - - Content - Content Templates - Media - Cache Browser - Recycle Bin - Created packages - Data Types - Dictionary - Installed packages - Install skin - Install starter kit - Languages - Install local package - Macros - Media Types - Members - Member Groups - Member Roles - Member Types - Document Types - Relation Types - Packages - Packages - Partial Views - Partial View Macro Files - Install from repository - Install Runway - Runway modules - Scripting Files - Scripts - Stylesheets - Templates - Log Viewer - Users - Settings - Templating - Third Party - - - New update ready - %0% is ready, click here for download - No connection to server - Error checking for update. Please review trace-stack for further information - - - Access - Based on the assigned groups and start nodes, the user has access to the following nodes - Assign access - Administrator - Category field - User created - Change Your Password - Change photo - New password - hasn't been locked out - The password hasn't been changed - Confirm new password - You can change your password for accessing the Umbraco Back Office by filling out the form below and click the 'Change Password' button - Content Channel - Create another user - Create new users to give them access to Umbraco. When a new user is created a password will be generated that you can share with the user. - Description field - Disable User - Document Type - Editor - Excerpt field - Failed login attempts - Go to user profile - Add groups to assign access and permissions - Invite another user - Invite new users to give them access to Umbraco. An invite email will be sent to the user with information on how to log in to Umbraco. Invites last for 72 hours. - Language - Set the language you will see in menus and dialogs - Last lockout date - Last login - Password last changed - Username - Media start node - Limit the media library to a specific start node - Media start nodes - Limit the media library to specific start nodes - Sections - Disable Umbraco Access - has not logged in yet - Old password - Password - Reset password - Your password has been changed! - Please confirm the new password - Enter your new password - Your new password cannot be blank! - Current password - Invalid current password - There was a difference between the new password and the confirmed password. Please try again! - The confirmed password doesn't match the new password! - Replace child node permissions - You are currently modifying permissions for the pages: - Select pages to modify their permissions - Remove photo - Default permissions - Granular permissions - Set permissions for specific nodes - Profile - Search all children - Add sections to give users access - Select user groups - No start node selected - No start nodes selected - Content start node - Limit the content tree to a specific start node - Content start nodes - Limit the content tree to specific start nodes - User last updated - has been created - The new user has successfully been created. To log in to Umbraco use the password below. - User management - Name - User permissions - User group - has been invited - An invitation has been sent to the new user with details about how to log in to Umbraco. - Hello there and welcome to Umbraco! In just 1 minute you’ll be good to go, we just need you to setup a password and add a picture for your avatar. - Welcome to Umbraco! Unfortunately your invite has expired. Please contact your administrator and ask them to resend it. - Uploading a photo of yourself will make it easy for other users to recognize you. Click the circle above to upload your photo. - Writer - Change - Your profile - Your recent history - Session expires in - Invite user - Create user - Send invite - Back to users - Umbraco: Invitation - - - - - - - - - - - -
- - - - - -
- -
- -
-
- - - - - - -
-
-
- - - - -
- - - - -
-

- Hi %0%, -

-

- You have been invited by %1% to the Umbraco Back Office. -

-

- Message from %1%: -
- %2% -

- - - - - - -
- - - - - - -
- - Click this link to accept the invite - -
-
-

If you cannot click on the link, copy and paste this URL into your browser window:

- - - - -
- - %3% - -
-

-
-
-


-
-
- - ]]>
- Invite - Resending invitation... - Delete User - Are you sure you wish to delete this user account? - All - Active - Disabled - Locked out - Invited - Inactive - Name (A-Z) - Name (Z-A) - Newest - Oldest - Last login - - - Validation - Validate as an email address - Validate as a number - Validate as a URL - ...or enter a custom validation - Field is mandatory - Enter a regular expression - You need to add at least - You can only have - items - items selected - Invalid date - Not a number - Invalid email - Value cannot be null - Value cannot be empty - Value is invalid, it does not match the correct pattern - Custom validation - - - - Value is set to the recommended value: '%0%'. - Value was set to '%1%' for XPath '%2%' in configuration file '%3%'. - Expected value '%1%' for '%2%' in configuration file '%3%', but found '%0%'. - Found unexpected value '%0%' for '%2%' in configuration file '%3%'. - - Custom errors are set to '%0%'. - Custom errors are currently set to '%0%'. It is recommended to set this to '%1%' before go live. - Custom errors successfully set to '%0%'. - MacroErrors are set to '%0%'. - MacroErrors are set to '%0%' which will prevent some or all pages in your site from loading completely if there are any errors in macros. Rectifying this will set the value to '%1%'. - MacroErrors are now set to '%0%'. - - Try Skip IIS Custom Errors is set to '%0%' and you're using IIS version '%1%'. - Try Skip IIS Custom Errors is currently '%0%'. It is recommended to set this to '%1%' for your IIS version (%2%). - Try Skip IIS Custom Errors successfully set to '%0%'. - - File does not exist: '%0%'. - '%0%' in config file '%1%'.]]> - There was an error, check log for full error: %0%. - Database - The database schema is correct for this version of Umbraco - %0% problems were detected with your database schema (Check the log for details) - Some errors were detected while validating the database schema against the current version of Umbraco. - Your website's certificate is valid. - Certificate validation error: '%0%' - Your website's SSL certificate has expired. - Your website's SSL certificate is expiring in %0% days. - Error pinging the URL %0% - '%1%' - You are currently %0% viewing the site using the HTTPS scheme. - The appSetting 'Umbraco.Core.UseHttps' is set to 'false' in your web.config file. Once you access this site using the HTTPS scheme, that should be set to 'true'. - The appSetting 'Umbraco.Core.UseHttps' is set to '%0%' in your web.config file, your cookies are %1% marked as secure. - Could not update the 'Umbraco.Core.UseHttps' setting in your web.config file. Error: %0% - - Enable HTTPS - Sets umbracoSSL setting to true in the appSettings of the web.config file. - The appSetting 'Umbraco.Core.UseHttps' is now set to 'true' in your web.config file, your cookies will be marked as secure. - Fix - Cannot fix a check with a value comparison type of 'ShouldNotEqual'. - Cannot fix a check with a value comparison type of 'ShouldEqual' with a provided value. - Value to fix check not provided. - Debug compilation mode is disabled. - Debug compilation mode is currently enabled. It is recommended to disable this setting before go live. - Debug compilation mode successfully disabled. - Trace mode is disabled. - Trace mode is currently enabled. It is recommended to disable this setting before go live. - Trace mode successfully disabled. - All folders have the correct permissions set. - - %0%.]]> - %0%. If they aren't being written to no action need be taken.]]> - All files have the correct permissions set. - - %0%.]]> - %0%. If they aren't being written to no action need be taken.]]> - X-Frame-Options used to control whether a site can be IFRAMEd by another was found.]]> - X-Frame-Options used to control whether a site can be IFRAMEd by another was not found.]]> - Set Header in Config - Adds a value to the httpProtocol/customHeaders section of web.config to prevent the site being IFRAMEd by other websites. - A setting to create a header preventing IFRAMEing of the site by other websites has been added to your web.config file. - Could not update web.config file. Error: %0% - X-Content-Type-Options used to protect against MIME sniffing vulnerabilities was found.]]> - X-Content-Type-Options used to protect against MIME sniffing vulnerabilities was not found.]]> - Adds a value to the httpProtocol/customHeaders section of web.config to protect against MIME sniffing vulnerabilities. - A setting to create a header protecting against MIME sniffing vulnerabilities has been added to your web.config file. - Strict-Transport-Security, also known as the HSTS-header, was found.]]> - Strict-Transport-Security was not found.]]> - Adds the header 'Strict-Transport-Security' with the value 'max-age=10886400' to the httpProtocol/customHeaders section of web.config. Use this fix only if you will have your domains running with https for the next 18 weeks (minimum). - The HSTS header has been added to your web.config file. - X-XSS-Protection was found.]]> - X-XSS-Protection was not found.]]> - Adds the header 'X-XSS-Protection' with the value '1; mode=block' to the httpProtocol/customHeaders section of web.config. - The X-XSS-Protection header has been added to your web.config file. - - %0%.]]> - No headers revealing information about the website technology were found. - In the Web.config file, system.net/mailsettings could not be found. - In the Web.config file system.net/mailsettings section, the host is not configured. - SMTP settings are configured correctly and the service is operating as expected. - The SMTP server configured with host '%0%' and port '%1%' could not be reached. Please check to ensure the SMTP settings in the Web.config file system.net/mailsettings are correct. - %0%.]]> - %0%.]]> -

Results of the scheduled Umbraco Health Checks run on %0% at %1% are as follows:

%2%]]>
- Umbraco Health Check Status: %0% - - - Disable URL tracker - Enable URL tracker - Culture - Original URL - Redirected To - Redirect Url Management - The following URLs redirect to this content item: - No redirects have been made - When a published page gets renamed or moved a redirect will automatically be made to the new page. - Are you sure you want to remove the redirect from '%0%' to '%1%'? - Redirect URL removed. - Error removing redirect URL. - This will remove the redirect - Are you sure you want to disable the URL tracker? - URL tracker has now been disabled. - Error disabling the URL tracker, more information can be found in your log file. - URL tracker has now been enabled. - Error enabling the URL tracker, more information can be found in your log file. - - - No Dictionary items to choose from - - - %0% characters left.]]> - %1% too many.]]> - - - 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 location where this item can be automatically restored. You can move the item manually using the tree below. - was restored under - - - Direction - Parent to child - Bidirectional - Parent - Child - Count - Relations - Created - Comment - Name - No relations for this relation type. - Relation Type - Relations - - - Getting Started - Redirect URL Management - Content - Welcome - Examine Management - Published Status - Models Builder - Health Check + + + + The Umbraco community + https://our.umbraco.com/documentation/Extending-Umbraco/Language-Files + + + Culture and Hostnames + Audit Trail + Browse Node + Change Document Type + Copy + Create + Export + Create Package + Create group + Delete + Disable + Empty recycle bin + Enable + Export Document Type + Import Document Type + Import Package + Edit in Canvas + Exit + Move + Notifications + Public access + Publish + Unpublish + Reload + Republish entire site + Rename + Restore + Set permissions for the page %0% + Choose where to copy + Choose where to move + to in the tree structure below + was moved to + was copied to + was deleted + Permissions + Rollback + Send To Publish + Send To Translation + Set group + Sort + Translate + Update + Set permissions + Unlock + Create Content Template + Resend Invitation + + + Content + Administration + Structure + Other + + + Allow access to assign culture and hostnames + Allow access to view a node's history log + Allow access to view a node + Allow access to change document type for a node + Allow access to copy a node + Allow access to create nodes + Allow access to delete nodes + Allow access to move a node + Allow access to set and change public access for a node + Allow access to publish a node + Allow access to unpublish a node + Allow access to change permissions for a node + Allow access to roll back a node to a previous state + Allow access to send a node for approval before publishing + Allow access to send a node for translation + Allow access to change the sort order for nodes + Allow access to translate a node + Allow access to save a node + Allow access to create a Content Template + + + Content + Info + + + Permission denied. + Add new Domain + remove + Invalid node. + One or more domains have an invalid format. + Domain has already been assigned. + Language + Domain + New domain '%0%' has been created + Domain '%0%' is deleted + Domain '%0%' has already been assigned + Domain '%0%' has been updated + Edit Current Domains + + + Inherit + Culture + or inherit culture from parent nodes. Will also apply
+ to the current node, unless a domain below applies too.]]>
+ Domains + + + Clear selection + Select + Do something else + Bold + Cancel Paragraph Indent + Insert form field + Insert graphic headline + Edit Html + Indent Paragraph + Italic + Center + Justify Left + Justify Right + Insert Link + Insert local link (anchor) + Bullet List + Numeric List + Insert macro + Insert picture + Publish and close + Publish with descendants + Edit relations + Return to list + Save + Save and close + Save and publish + Save and schedule + Send for approval + Save list view + Schedule + Preview + Preview is disabled because there's no template assigned + Choose style + Show styles + Insert table + Generate models and close + Save and generate models + Undo + Redo + Rollback + Delete tag + Cancel + Confirm + More publishing options + + + Viewing for + Content deleted + Content unpublished + Content unpublished for languages: %0% + Content published + Content published for languages: %0% + Content saved + Content saved for languages: %0% + Content moved + Content copied + Content rolled back + Content sent for publishing + Content sent for publishing for languages: %0% + Sort child items performed by user + Copy + Publish + Publish + Move + Save + Save + Delete + Unpublish + Unpublish + Rollback + Send To Publish + Send To Publish + Sort + History (all variants) + + + To change the document type for the selected content, first select from the list of valid types for this location. + Then confirm and/or amend the mapping of properties from the current type to the new, and click Save. + The content has been re-published. + Current Property + Current type + The document type cannot be changed, as there are no alternatives valid for this location. An alternative will be valid if it is allowed under the parent of the selected content item and that all existing child content items are allowed to be created under it. + Document Type Changed + Map Properties + Map to Property + New Template + New Type + none + Content + Select New Document Type + The document type of the selected content has been successfully changed to [new type] and the following properties mapped: + to + 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% + The folder name cannot contain illegal characters. + Failed to delete item: %0% + + + Is Published + About this page + Alias + (how would you describe the picture over the phone) + Alternative Links + Click to edit this item + Created by + Original author + Updated by + Created + Date/time this document was created + Document Type + Editing + Remove at + This item has been changed after publication + This item is not published + Last published + There are no items to show + There are no items to show in the list. + No child items have been added + No members have been added + Media Type + Link to media item(s) + Member Group + Role + Member Type + No changes have been made + No date chosen + Page title + This media item has no link + No content can be added for this item + Properties + This document is published but is not visible because the parent '%0%' is unpublished + This culture is published but is not visible because it is unpublished on parent '%0%' + This document is published but is not in the cache + Could not get the url + This document is published but its url would collide with content %0% + This document is published but its url cannot be routed + Publish + Published + Published (pending changes)> + Publication Status + Publish with descendants to publish %0% and all content items underneath and thereby making their content publicly available.]]> + Publish with descendants to publish the selected languages and the same languages of content items underneath and thereby making their content publicly available.]]> + Publish at + Unpublish at + Clear Date + Set date + Sortorder is updated + To sort the nodes, simply drag the nodes or click one of the column headers. You can select multiple nodes by holding the "shift" or "control" key while selecting + Statistics + Title (optional) + Alternative text (optional) + Type + Unpublish + Draft + Not created + Last edited + Date/time this document was edited + Remove file(s) + Link to document + Member of group(s) + Not a member of group(s) + Child items + Target + This translates to the following time on the server: + What does this mean?]]> + Are you sure you want to delete this item? + Property %0% uses editor %1% which is not supported by Nested Content. + No content types are configured for this property. + Add another text box + Remove this text box + Content root + Include drafts: also publish unpublished content items. + This value is hidden. If you need access to view this value please contact your website administrator. + This value is hidden. + What languages would you like to publish? All languages with content are saved! + What languages would you like to publish? + What languages would you like to save? + All languages with content are saved on creation! + What languages would you like to send for approval? + What languages would you like to schedule? + Select the languages to unpublish. Unpublishing a mandatory language will unpublish all languages. + Published Languages + Unpublished Languages + Unmodified Languages + These languages haven't been created + Ready to Publish? + Ready to Save? + Send for approval + Select the date and time to publish and/or unpublish the content item. + Create new + Paste from clipboard + + + Create a new Content Template from '%0%' + Blank + Select a Content Template + Content Template created + A Content Template was created from '%0%' + Another Content Template with the same name already exists + A Content Template is predefined content that an editor can select to use as the basis for creating new content + + + Click to upload + or click here to choose files + You can drag files here to upload. + Cannot upload this file, it does not have an approved file type + Max file size is + Media root + Failed to move media + Parent and destination folders cannot be the same + Failed to copy media + Failed to create a folder under parent id %0% + Failed to rename the folder with id %0% + Drag and drop your file(s) into the area + + + Create a new member + All Members + Member groups have no additional properties for editing. + + + 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 within the Settings section, by editing the Allowed child node types under Permissions.]]> + The selected page in the content tree doesn't allow for any pages to be created below it. + Edit permissions for this document type + Media Types Types within the Settings section, by editing the Allowed child node types under Permissions.]]> + The selected media in the tree doesn't allow for any other media to be created below it. + Edit permissions for this media type Document Type without a template + New folder + New data type + New JavaScript file + New empty partial view + New partial view macro + New partial view from snippet + New partial view macro from snippet + New partial view macro (without macro) + New style sheet file + New Rich Text Editor style sheet file + + + Browse your website + - Hide + If Umbraco isn't opening, you might need to allow popups from this site + has opened in a new window + Restart + Visit + Welcome + + + Stay + Discard changes + You have unsaved changes + Are you sure you want to navigate away from this page? - you have unsaved changes + Publishing will make the selected items visible on the site. + Unpublishing will remove the selected items and all their descendants from the site. + Unpublishing will remove this page and all its descendants from the site. + You have unsaved changes. Making changes to the Document Type will discard the 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 + + + Link title + Link + Anchor / querystring + Name + Close this window + Are you sure you want to delete + Are you sure you want to disable + Are you sure? + Are you sure? + Cut + Edit Dictionary Item + Edit Language + Insert local link + Insert character + Insert graphic headline + Insert picture + Insert link + Click to add a Macro + Insert table + This will delete the language + Changing the culture for a language may be an expensive operation and will result in the content cache and indexes being rebuilt + Last Edited + Link + Internal link: + When using local links, insert "#" in front of link + Open in new window? + Macro Settings + This macro does not contain any properties you can edit + Paste + Edit permissions for + Set permissions for + Set permissions for %0% for user group %1% + Select the users groups you want to set permissions for + The items in the recycle bin are now being deleted. Please do not close this window while this operation takes place + The recycle bin is now empty + When items are deleted from the recycle bin, they will be gone forever + regexlib.com's webservice is currently experiencing some problems, which we have no control over. We are very sorry for this inconvenience.]]> + Search for a regular expression to add validation to a form field. Example: 'email, 'zip-code' 'url' + Remove Macro + Required Field + Site is reindexed + The website cache has been refreshed. All publish content is now up to date. While all unpublished content is still unpublished + The website cache will be refreshed. All published content will be updated, while unpublished content will stay unpublished. + Number of columns + Number of rows + Click on the image to see full size + Pick item + View Cache Item + Relate to original + Include descendants + The friendliest community + Link to page + Opens the linked document in a new window or tab + Link to media + Select content start node + Select media + Select media type + Select icon + Select item + Select link + Select macro + Select content + Select content type + Select media start node + Select member + Select member group + Select member type + Select node + Select sections + Select users + No icons were found + There are no parameters for this macro + There are no macros available to insert + External login providers + Exception Details + Stacktrace + Inner Exception + Link your + Un-link your + account + Select editor + Select snippet + This will delete the node and all its languages. If you only want to delete one language go and unpublish it instead. + + + There are no dictionary items. + + + %0%' below + ]]> + Culture Name + + Dictionary overview + + + Configured Searchers + Shows properties and tools for any configured Searcher (i.e. such as a multi-index searcher) + Field values + Health status + The health status of the index and if it can be read + Indexers + Index info + Lists the properties of the index + Manage Examine's indexes + Allows you to view the details of each index and provides some tools for managing the indexes + Rebuild index + + Depending on how much content there is in your site this could take a while.
+ It is not recommended to rebuild an index during times of high website traffic or when editors are editing content. + ]]> +
+ Searchers + Search the index and view the results + Tools + Tools to manage the index + + + Enter your username + Enter your password + Confirm your password + Name the %0%... + Enter a name... + Enter an email... + Enter a username... + Label... + Enter a description... + Type to search... + Type to filter... + Type to add tags (press enter after each tag)... + Enter your email + Enter a message... + Your username is usually your email + #value or ?key=value + Enter alias... + Generating alias... + Create item + Edit + Name + + + Create custom list view + Remove custom list view + A content type, media type or member type with this alias already exists + + + Renamed + Enter a new folder name here + %0% was renamed to %1% + + + Add prevalue + Database datatype + Property editor GUID + Property editor + Buttons + Enable advanced settings for + Enable context menu + Maximum default size of inserted images + Related stylesheets + Show label + Width and height + All property types & property data + using this data type will be deleted permanently, please confirm you want to delete these as well + Yes, delete + and all property types & property data using this data type + Select the folder to move + to in the tree structure below + was moved underneath + + + Your data has been saved, but before you can publish this page there are some errors you need to fix first: + The current membership provider does not support changing password (EnablePasswordRetrieval need to be true) + %0% already exists + There were errors: + There were errors: + The password should be a minimum of %0% characters long and contain at least %1% non-alpha numeric character(s) + %0% must be an integer + The %0% field in the %1% tab is mandatory + %0% is a mandatory field + %0% at %1% is not in a correct format + %0% is not in a correct format + + + Received an error from the server + The specified file type has been disallowed by the administrator + NOTE! Even though CodeMirror is enabled by configuration, it is disabled in Internet Explorer because it's not stable enough. + Please fill both alias and name on the new property type! + There is a problem with read/write access to a specific file or folder + Error loading Partial View script (file: %0%) + Please enter a title + Please choose a type + You're about to make the picture larger than the original size. Are you sure that you want to proceed? + Startnode deleted, please contact your administrator + Please mark content before changing style + No active styles available + Please place cursor at the left of the two cells you wish to merge + You cannot split a cell that hasn't been merged. + This property is invalid + + + Options + About + Action + Actions + Add + Alias + All + Are you sure? + Back + Back to overview + Border + by + Cancel + Cell margin + Choose + Close + Close Window + Comment + Confirm + Constrain + Constrain proportions + Content + Continue + Copy + Create + Database + Date + Default + Delete + Deleted + Deleting... + Design + Dictionary + Dimensions + Down + Download + Edit + Edited + Elements + Email + Error + Field + Find + First + General + Groups + Group + Height + Help + Hide + History + Icon + Id + Import + Include subfolders in search + Info + Inner margin + Insert + Install + Invalid + Justify + Label + Language + Last + Layout + Links + Loading + Locked + Login + Log off + Logout + Macro + Mandatory + Message + Move + Name + New + Next + No + of + Off + OK + Open + On + or + Order by + Password + Path + One moment please... + Previous + Properties + Rebuild + Email to receive form data + Recycle Bin + Your recycle bin is empty + Reload + Remaining + Remove + Rename + Renew + Required + Retrieve + Retry + Permissions + Scheduled Publishing + Search + Sorry, we can not find what you are looking for. + No items have been added + Server + Settings + Show + Show page on Send + Size + Sort + Status + Submit + Type + Type to search... + under + Up + Update + Upgrade + Upload + Url + User + Username + Value + View + Welcome... + Width + Yes + Folder + Search results + Reorder + I am done reordering + Preview + Change password + to + List view + Saving... + current + Embed + selected + + + Blue + + + Add group + Add property + Add editor + Add template + Add child node + Add child + Edit data type + Navigate sections + Shortcuts + show shortcuts + Toggle list view + Toggle allow as root + Comment/Uncomment lines + Remove line + Copy Lines Up + Copy Lines Down + Move Lines Up + Move Lines Down + General + Editor + Toggle allow culture variants + + + Background color + Bold + Text color + Font + Text + + + Page + + + The installer cannot connect to the database. + Could not save the web.config file. Please modify the connection string manually. + Your database has been found and is identified as + Database configuration + install button to install the Umbraco %0% database + ]]> + Next to proceed.]]> + Database not found! Please check that the information in the "connection string" of the "web.config" file is correct.

+

To proceed, please edit the "web.config" file (using Visual Studio or your favourite text editor), scroll to the bottom, add the connection string for your database in the key named "UmbracoDbDSN" and save the file.

+

+ Click the retry button when + done.
+ More information on editing web.config here.

]]>
+ + Please contact your ISP if necessary. + If you're installing on a local machine or server you might need information from your system administrator.]]> + + Press the upgrade button to upgrade your database to Umbraco %0%

+

+ Don't worry - no content will be deleted and everything will continue working afterwards! +

+ ]]>
+ Press Next to + proceed. ]]> + next to continue the configuration wizard]]> + The Default users' password needs to be changed!]]> + The Default user has been disabled or has no access to Umbraco!

No further actions needs to be taken. Click Next to proceed.]]> + The Default user's password has been successfully changed since the installation!

No further actions needs to be taken. Click Next to proceed.]]> + The password is changed! + Get a great start, watch our introduction videos + By clicking the next button (or modifying the umbracoConfigurationStatus in web.config), you accept the license for this software as specified in the box below. Notice that this Umbraco distribution consists of two different licenses, the open source MIT license for the framework and the Umbraco freeware license that covers the UI. + Not installed yet. + Affected files and folders + More information on setting up permissions for Umbraco here + You need to grant ASP.NET modify permissions to the following files/folders + Your permission settings are almost perfect!

+ You can run Umbraco without problems, but you will not be able to install packages which are recommended to take full advantage of Umbraco.]]>
+ How to Resolve + Click here to read the text version + video tutorial on setting up folder permissions for Umbraco or read the text version.]]> + Your permission settings might be an issue! +

+ You can run Umbraco without problems, but you will not be able to create folders or install packages which are recommended to take full advantage of Umbraco.]]>
+ Your permission settings are not ready for Umbraco! +

+ In order to run Umbraco, you'll need to update your permission settings.]]>
+ Your permission settings are perfect!

+ You are ready to run Umbraco and install packages!]]>
+ Resolving folder issue + Follow this link for more information on problems with ASP.NET and creating folders + Setting up folder permissions + + I want to start from scratch + learn how) + You can still choose to install Runway later on. Please go to the Developer section and choose Packages. + ]]> + You've just set up a clean Umbraco platform. What do you want to do next? + Runway is installed + + This is our list of recommended modules, check off the ones you would like to install, or view the full list of modules + ]]> + Only recommended for experienced users + I want to start with a simple website + + "Runway" is a simple website providing some basic document types and templates. The installer can set up Runway for you automatically, + but you can easily edit, extend or remove it. It's not necessary and you can perfectly use Umbraco without it. However, + Runway offers an easy foundation based on best practices to get you started faster than ever. + If you choose to install Runway, you can optionally select basic building blocks called Runway Modules to enhance your Runway pages. +

+ + Included with Runway: Home page, Getting Started page, Installing Modules page.
+ Optional Modules: Top Navigation, Sitemap, Contact, Gallery. +
+ ]]>
+ What is Runway + Step 1/5 Accept license + Step 2/5: Database configuration + Step 3/5: Validating File Permissions + Step 4/5: Check Umbraco security + Step 5/5: Umbraco is ready to get you started + Thank you for choosing Umbraco + Browse your new site +You installed Runway, so why not see how your new website looks.]]> + Further help and information +Get help from our award winning community, browse the documentation or watch some free videos on how to build a simple site, how to use packages and a quick guide to the Umbraco terminology]]> + Umbraco %0% is installed and ready for use + /web.config file and update the AppSetting key UmbracoConfigurationStatus in the bottom to the value of '%0%'.]]> + started instantly by clicking the "Launch Umbraco" button below.
If you are new to Umbraco, +you can find plenty of resources on our getting started pages.]]>
+ Launch Umbraco +To manage your website, simply open the Umbraco back office and start adding content, updating the templates and stylesheets or add new functionality]]> + Connection to database failed. + Umbraco Version 3 + Umbraco Version 4 + Watch + Umbraco %0% for a fresh install or upgrading from version 3.0. +

+ Press "next" to start the wizard.]]>
+ + + Culture Code + Culture Name + + + You've been idle and logout will automatically occur in + Renew now to save your work + + + Happy super Sunday + Happy manic Monday + Happy tubular Tuesday + Happy wonderful Wednesday + Happy thunderous Thursday + Happy funky Friday + Happy Caturday + Log in below + Sign in with + Session timed out + © 2001 - %0%
Umbraco.com

]]>
+ Forgotten password? + An email will be sent to the address specified with a link to reset your password + An email with password reset instructions will be sent to the specified address if it matched our records + Show password + Hide password + Return to login form + Please provide a new password + Your Password has been updated + The link you have clicked on is invalid or has expired + Umbraco: Reset Password + + + + + + + + + + + +
+ + + + + +
+ +
+ +
+
+ + + + + + +
+
+
+ + + + +
+ + + + +
+

+ Password reset requested +

+

+ Your username to login to the Umbraco back-office is: %0% +

+

+ + + + + + +
+ + Click this link to reset your password + +
+

+

If you cannot click on the link, copy and paste this URL into your browser window:

+ + + + +
+ + %1% + +
+

+
+
+


+
+
+ + + ]]>
+ + + Dashboard + Sections + Content + + + Choose page above... + %0% has been copied to %1% + Select where the document %0% should be copied to below + %0% has been moved to %1% + Select where the document %0% should be moved to below + has been selected as the root of your new content, click 'ok' below. + No node selected yet, please select a node in the list above before clicking 'ok' + The current node is not allowed under the chosen node because of its type + The current node cannot be moved to one of its subpages + The current node cannot exist at the root + The action isn't allowed since you have insufficient permissions on 1 or more child documents. + Relate copied items to original + + + %0%]]> + Notification settings saved for + + The following languages have been modified %0% + + + + + + + + + + + +
+ + + + + +
+ +
+ +
+
+ + + + + + +
+
+
+ + + + +
+ + + + +
+

+ Hi %0%, +

+

+ This is an automated mail to inform you that the task '%1%' has been performed on the page '%2%' by the user '%3%' +

+ + + + + + +
+ +
+ EDIT
+
+

+

Update summary:

+ %6% +

+

+ Have a nice day!

+ Cheers from the Umbraco robot +

+
+
+


+
+
+ + + ]]>
+ The following languages have been modified:

+ %0% + ]]>
+ [%0%] Notification about %1% performed on %2% + Notifications + + + Actions + Created + Create package + + button and locating the package. Umbraco packages usually have a ".umb" or ".zip" extension. + ]]> + This will delete the package + Drop to upload + Include all child nodes + or click here to choose package file + Upload package + Install a local package by selecting it from your machine. Only install packages from sources you know and trust + Upload another package + Cancel and upload another package + I accept + terms of use + Path to file + Absolute path to file (ie: /bin/umbraco.bin) + Installed + Installed packages + Install local + Finish + This package has no configuration view + No packages have been created yet + You don’t have any packages installed + 'Packages' icon in the top right of your screen]]> + Package Actions + Author URL + Package Content + Package Files + Icon URL + Install package + License + License URL + Package Properties + Search for packages + Results for + We couldn’t find anything for + Please try searching for another package or browse through the categories + Popular + New releases + has + karma points + Information + Owner + Contributors + Created + Current version + .NET version + Downloads + Likes + Compatibility + This package is compatible with the following versions of Umbraco, as reported by community members. Full compatability cannot be guaranteed for versions reported below 100% + External sources + Author + Documentation + Package meta data + Package name + Package doesn't contain any items +
+ You can safely remove this from the system by clicking "uninstall package" below.]]>
+ Package options + Package readme + Package repository + Confirm package uninstall + Package was uninstalled + The package was successfully uninstalled + Uninstall package + + Notice: any documents, media etc depending on the items you remove, will stop working, and could lead to system instability, + so uninstall with caution. If in doubt, contact the package author.]]> + Package version + Upgrading from version + Package already installed + This package cannot be installed, it requires a minimum Umbraco version of + Uninstalling... + Downloading... + Importing... + Installing... + Restarting, please wait... + All done, your browser will now refresh, please wait... + Please click 'Finish' to complete installation and reload the page. + Uploading package... + + + Paste with full formatting (Not recommended) + The text you're trying to paste contains special characters or formatting. This could be caused by copying text from Microsoft Word. Umbraco can remove special characters or formatting automatically, so the pasted content will be more suitable for the web. + Paste as raw text without any formatting at all + Paste, but remove formatting (Recommended) + + + Group based protection + If you want to grant access to all members of specific member groups + You need to create a member group before you can use group based authentication + Error Page + Used when people are logged on, but do not have access + %0%]]> + %0% is now protected]]> + %0%]]> + Login Page + Choose the page that contains the login form + Remove protection... + %0%?]]> + Select the pages that contain login form and error messages + %0%]]> + %0%]]> + Specific members protection + If you wish to grant access to specific members + + + Insufficient user permissions to publish all descendant documents + + + + + + + + Validation failed for required language '%0%'. This language was saved but not published. + Publishing in progress - please wait... + %0% out of %1% pages have been published... + %0% has been published + %0% and subpages have been published + Publish %0% and all its subpages + Publish to publish %0% and thereby making its content publicly available.

+ You can publish this page and all its subpages by checking Include unpublished subpages below. + ]]>
+ + + You have not configured any approved colors + + + You can only select items of type(s): %0% + You have picked a content item currently deleted or in the recycle bin + You have picked content items currently deleted or in the recycle bin + + + Deleted item + You have picked a media item currently deleted or in the recycle bin + You have picked media items currently deleted or in the recycle bin + Trashed + + + enter external link + choose internal page + Caption + Link + Open in new window + enter the display caption + Enter the link + + + Reset crop + Save crop + Add new crop + Done + Undo edits + + + Select a version to compare with the current version + Current version + Red text will not be shown in the selected version. , green means added]]> + Document has been rolled back + This displays the selected version as HTML, if you wish to see the difference between 2 versions at the same time, use the diff view + Rollback to + Select version + View + + + Edit script file + + + Content + Forms + Media + Members + Packages + Settings + Translation + Users + + + The best Umbraco video tutorials + + + Default template + To import a document type, find the ".udt" file on your computer by clicking the "Browse" button and click "Import" (you'll be asked for confirmation on the next screen) + New Tab Title + Node type + Type + Stylesheet + Script + Tab + Tab Title + Tabs + Master Content Type enabled + 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 + + + Sort order + Creation date + Sorting complete. + Drag the different items up or down below to set how they should be arranged. Or click the column headers to sort the entire collection of items + + This node has no child nodes to sort + + + Validation + Validation errors must be fixed before the item can be saved + Failed + Saved + Insufficient user permissions, could not complete the operation + Cancelled + Operation was cancelled by a 3rd party add-in + Property type already exists + Property type created + DataType: %1%]]> + Propertytype deleted + Document Type saved + Tab created + Tab deleted + Tab with id: %0% deleted + Stylesheet not saved + Stylesheet saved + Stylesheet saved without any errors + Datatype saved + Dictionary item saved + Content published + and is visible on the website + %0% documents published and visible on the website + %0% published and visible on the website + %0% documents published for languages %1% and visible on the website + Content saved + Remember to publish to make changes visible + A schedule for publishing has been updated + %0% saved + Sent For Approval + Changes have been sent for approval + %0% changes have been sent for approval + Media saved + Media saved without any errors + Member saved + Member group saved + Stylesheet Property Saved + Stylesheet saved + Template saved + Error saving user (check log) + User Saved + User type saved + User group saved + File not saved + file could not be saved. Please check file permissions + File saved + File saved without any errors + Language saved + Media Type saved + Member Type saved + Member Group saved + Template not saved + Please make sure that you do not have 2 templates with the same alias + Template saved + Template saved without any errors! + Content unpublished + Content variation %0% unpublished + The mandatory language '%0%' was unpublished. All languages for this content item are now unpublished. + Partial view saved + Partial view saved without any errors! + Partial view not saved + An error occurred saving the file. + Permissions saved for + Deleted %0% user groups + %0% was deleted + Enabled %0% users + Disabled %0% users + %0% is now enabled + %0% is now disabled + User groups have been set + Unlocked %0% users + %0% is now unlocked + Member was exported to file + An error occurred while exporting the member + User %0% was deleted + Invite user + Invitation has been re-sent to %0% + Cannot publish the document since the required '%0%' is not published + Validation failed for language '%0%' + Document type was exported to file + An error occurred while exporting the document type + The release date cannot be in the past + Cannot schedule the document for publishing since the required '%0%' is not published + Cannot schedule the document for publishing since the required '%0%' has a publish date later than a non mandatory language + The expire date cannot be in the past + The expire date cannot be before the release date + + + Add style + Edit style + Rich text editor styles + Define the styles that should be available in the rich text editor for this stylesheet + Edit stylesheet + Edit stylesheet property + The name displayed in the editor style selector + Preview + How the text will look like in the rich text editor. + Selector + Uses CSS syntax, e.g. "h1" or ".redHeader" + Styles + The CSS that should be applied in the rich text editor, e.g. "color:red;" + Code + Rich Text Editor + + + Failed to delete template with ID %0% + Edit template + Sections + Insert content area + Insert content area placeholder + Insert + Choose what to insert into your template + Dictionary item + A dictionary item is a placeholder for a translatable piece of text, which makes it easy to create designs for multilingual websites. + Macro + + A Macro is a configurable component which is great for + reusable parts of your design, where you need the option to provide parameters, + such as galleries, forms and lists. + + Value + Displays the value of a named field from the current page, with options to modify the value or fallback to alternative values. + Partial view + + A partial view is a separate template file which can be rendered inside another + template, it's great for reusing markup or for separating complex templates into separate files. + + Master template + No master + Render child template + @RenderBody() placeholder. + ]]> + Define a named section + @section { ... }. This can be rendered in a + specific area of the parent of this template, by using @RenderSection. + ]]> + Render a named section + @RenderSection(name) placeholder. + This renders an area of a child template which is wrapped in a corresponding @section [name]{ ... } definition. + ]]> + Section Name + Section is mandatory + + If mandatory, the child template must contain a @section definition, otherwise an error is shown. + + Query builder + items returned, in + I want + all content + content of type "%0%" + from + my website + where + and + is + is not + before + before (including selected date) + after + after (including selected date) + equals + does not equal + contains + does not contain + greater than + greater than or equal to + less than + less than or equal to + Id + Name + Created Date + Last Updated Date + order by + ascending + descending + Template + + + Image + Macro + Choose type of content + Choose a layout + Add a row + Add content + Drop content + Settings applied + This content is not allowed here + This content is allowed here + Click to embed + Click to insert image + Image caption... + Write here... + Grid Layouts + Layouts are the overall work area for the grid editor, usually you only need one or two different layouts + Add Grid Layout + Adjust the layout by setting column widths and adding additional sections + Row configurations + Rows are predefined cells arranged horizontally + Add row configuration + Adjust the row by setting cell widths and adding additional cells + Columns + Total combined number of columns in the grid layout + Settings + Configure what settings editors can change + Styles + Configure what styling editors can change + Allow all editors + Allow all row configurations + Maximum items + Leave blank or set to 0 for unlimited + Set as default + Choose extra + Choose default + are added + + + Compositions + Group + You have not added any groups + Add group + Inherited from + Add property + Required label + Enable list view + Configures the content item to show a sortable and searchable list of its children, the children will not be shown in the tree + Allowed Templates + Choose which templates editors are allowed to use on content of this type + Allow as root + Allow editors to create content of this type in the root of the content tree + Allowed child node types + Allow content of the specified types to be created underneath content of this type + Choose child node + Inherit tabs and properties from an existing document type. New tabs will be added to the current document type or merged if a tab with an identical name exists. + This content type is used in a composition, and therefore cannot be composed itself. + There are no content types available to use as a composition. + Create new + Use existing + Editor settings + Configuration + Yes, delete + was moved underneath + was copied underneath + Select the folder to move + Select the folder to copy + to in the tree structure below + All Document types + All Documents + All media items + using this document type will be deleted permanently, please confirm you want to delete these as well. + using this media type will be deleted permanently, please confirm you want to delete these as well. + using this member type will be deleted permanently, please confirm you want to delete these as well + and all documents using this type + and all media items using this type + and all members using this type + Member can edit + Allow this property value to be edited by the member on their profile page + Is sensitive data + Hide this property value from content editors that don't have access to view sensitive information + Show on member profile + Allow this property value to be displayed on the member profile page + tab has no sort order + Where is this composition used? + This composition is currently used in the composition of the following content types: + Allow varying by culture + Allow editors to create content of this type in different languages + Allow varying by culture + Element type + Is an Element type + An Element type is meant to be used for instance in Nested Content, and not in the tree + This is not applicable for an Element type + You have made changes to this property. Are you sure you want to discard them? + + + Add language + Mandatory language + Properties on this language have to be filled out before the node can be published. + Default language + An Umbraco site can only have one default language set. + Switching default language may result in default content missing. + Falls back to + No fall back language + To allow multi-lingual content to fall back to another language if not present in the requested language, select it here. + Fall back language + + + Add parameter + Edit parameter + Enter macro name + Parameters + Define the parameters that should be available when using this macro. + Select partial view macro file + + + Building models + this can take a bit of time, don't worry + Models generated + Models could not be generated + Models generation has failed, see exception in U log + + + Add fallback field + Fallback field + Add default value + Default value + Fallback field + Default value + Casing + Encoding + Choose field + Convert line breaks + Yes, convert line breaks + Replaces line breaks with 'br' html tag + Custom Fields + Date only + Format and encoding + Format as date + Format the value as a date, or a date with time, according to the active culture + HTML encode + Will replace special characters by their HTML equivalent. + Will be inserted after the field value + Will be inserted before the field value + Lowercase + Modify output + None + Output sample + Insert after field + Insert before field + Recursive + Yes, make it recursive + Separator + Standard Fields + Uppercase + URL encode + Will format special characters in URLs + Will only be used when the field values above are empty + This field will only be used if the primary field is empty + Date and time + + + Translation details + Download XML DTD + Fields + Include subpages + + No translator users found. Please create a translator user before you start sending content to translation + The page '%0%' has been send to translation + Send the page '%0%' to translation + Total words + Translate to + Translation completed. + You can preview the pages, you've just translated, by clicking below. If the original page is found, you will get a comparison of the 2 pages. + Translation failed, the XML file might be corrupt + Translation options + Translator + Upload translation XML + + + Content + Content Templates + Media + Cache Browser + Recycle Bin + Created packages + Data Types + Dictionary + Installed packages + Install skin + Install starter kit + Languages + Install local package + Macros + Media Types + Members + Member Groups + Member Roles + Member Types + Document Types + Relation Types + Packages + Packages + Partial Views + Partial View Macro Files + Install from repository + Install Runway + Runway modules + Scripting Files + Scripts + Stylesheets + Templates + Log Viewer + Users + Settings + Templating + Third Party + + + New update ready + %0% is ready, click here for download + No connection to server + Error checking for update. Please review trace-stack for further information + + + Access + Based on the assigned groups and start nodes, the user has access to the following nodes + Assign access + Administrator + Category field + User created + Change Your Password + Change photo + New password + hasn't been locked out + The password hasn't been changed + Confirm new password + You can change your password for accessing the Umbraco Back Office by filling out the form below and click the 'Change Password' button + Content Channel + Create another user + Create new users to give them access to Umbraco. When a new user is created a password will be generated that you can share with the user. + Description field + Disable User + Document Type + Editor + Excerpt field + Failed login attempts + Go to user profile + Add groups to assign access and permissions + Invite another user + Invite new users to give them access to Umbraco. An invite email will be sent to the user with information on how to log in to Umbraco. Invites last for 72 hours. + Language + Set the language you will see in menus and dialogs + Last lockout date + Last login + Password last changed + Username + Media start node + Limit the media library to a specific start node + Media start nodes + Limit the media library to specific start nodes + Sections + Disable Umbraco Access + has not logged in yet + Old password + Password + Reset password + Your password has been changed! + Please confirm the new password + Enter your new password + Your new password cannot be blank! + Current password + Invalid current password + There was a difference between the new password and the confirmed password. Please try again! + The confirmed password doesn't match the new password! + Replace child node permissions + You are currently modifying permissions for the pages: + Select pages to modify their permissions + Remove photo + Default permissions + Granular permissions + Set permissions for specific nodes + Profile + Search all children + Add sections to give users access + Select user groups + No start node selected + No start nodes selected + Content start node + Limit the content tree to a specific start node + Content start nodes + Limit the content tree to specific start nodes + User last updated + has been created + The new user has successfully been created. To log in to Umbraco use the password below. + User management + Name + User permissions + User group + has been invited + An invitation has been sent to the new user with details about how to log in to Umbraco. + Hello there and welcome to Umbraco! In just 1 minute you’ll be good to go, we just need you to setup a password and add a picture for your avatar. + Welcome to Umbraco! Unfortunately your invite has expired. Please contact your administrator and ask them to resend it. + Uploading a photo of yourself will make it easy for other users to recognize you. Click the circle above to upload your photo. + Writer + Change + Your profile + Your recent history + Session expires in + Invite user + Create user + Send invite + Back to users + Umbraco: Invitation + + + + + + + + + + + +
+ + + + + +
+ +
+ +
+
+ + + + + + +
+
+
+ + + + +
+ + + + +
+

+ Hi %0%, +

+

+ You have been invited by %1% to the Umbraco Back Office. +

+

+ Message from %1%: +
+ %2% +

+ + + + + + +
+ + + + + + +
+ + Click this link to accept the invite + +
+
+

If you cannot click on the link, copy and paste this URL into your browser window:

+ + + + +
+ + %3% + +
+

+
+
+


+
+
+ + ]]>
+ Invite + Resending invitation... + Delete User + Are you sure you wish to delete this user account? + All + Active + Disabled + Locked out + Invited + Inactive + Name (A-Z) + Name (Z-A) + Newest + Oldest + Last login + + + Validation + Validate as an email address + Validate as a number + Validate as a URL + ...or enter a custom validation + Field is mandatory + Enter a regular expression + You need to add at least + You can only have + items + items selected + Invalid date + Not a number + Invalid email + Value cannot be null + Value cannot be empty + Value is invalid, it does not match the correct pattern + Custom validation + + + + Value is set to the recommended value: '%0%'. + Value was set to '%1%' for XPath '%2%' in configuration file '%3%'. + Expected value '%1%' for '%2%' in configuration file '%3%', but found '%0%'. + Found unexpected value '%0%' for '%2%' in configuration file '%3%'. + + Custom errors are set to '%0%'. + Custom errors are currently set to '%0%'. It is recommended to set this to '%1%' before go live. + Custom errors successfully set to '%0%'. + MacroErrors are set to '%0%'. + MacroErrors are set to '%0%' which will prevent some or all pages in your site from loading completely if there are any errors in macros. Rectifying this will set the value to '%1%'. + MacroErrors are now set to '%0%'. + + Try Skip IIS Custom Errors is set to '%0%' and you're using IIS version '%1%'. + Try Skip IIS Custom Errors is currently '%0%'. It is recommended to set this to '%1%' for your IIS version (%2%). + Try Skip IIS Custom Errors successfully set to '%0%'. + + File does not exist: '%0%'. + '%0%' in config file '%1%'.]]> + There was an error, check log for full error: %0%. + Database - The database schema is correct for this version of Umbraco + %0% problems were detected with your database schema (Check the log for details) + Some errors were detected while validating the database schema against the current version of Umbraco. + Your website's certificate is valid. + Certificate validation error: '%0%' + Your website's SSL certificate has expired. + Your website's SSL certificate is expiring in %0% days. + Error pinging the URL %0% - '%1%' + You are currently %0% viewing the site using the HTTPS scheme. + The appSetting 'Umbraco.Core.UseHttps' is set to 'false' in your web.config file. Once you access this site using the HTTPS scheme, that should be set to 'true'. + The appSetting 'Umbraco.Core.UseHttps' is set to '%0%' in your web.config file, your cookies are %1% marked as secure. + Could not update the 'Umbraco.Core.UseHttps' setting in your web.config file. Error: %0% + + Enable HTTPS + Sets umbracoSSL setting to true in the appSettings of the web.config file. + The appSetting 'Umbraco.Core.UseHttps' is now set to 'true' in your web.config file, your cookies will be marked as secure. + Fix + Cannot fix a check with a value comparison type of 'ShouldNotEqual'. + Cannot fix a check with a value comparison type of 'ShouldEqual' with a provided value. + Value to fix check not provided. + Debug compilation mode is disabled. + Debug compilation mode is currently enabled. It is recommended to disable this setting before go live. + Debug compilation mode successfully disabled. + Trace mode is disabled. + Trace mode is currently enabled. It is recommended to disable this setting before go live. + Trace mode successfully disabled. + All folders have the correct permissions set. + + %0%.]]> + %0%. If they aren't being written to no action need be taken.]]> + All files have the correct permissions set. + + %0%.]]> + %0%. If they aren't being written to no action need be taken.]]> + X-Frame-Options used to control whether a site can be IFRAMEd by another was found.]]> + X-Frame-Options used to control whether a site can be IFRAMEd by another was not found.]]> + Set Header in Config + Adds a value to the httpProtocol/customHeaders section of web.config to prevent the site being IFRAMEd by other websites. + A setting to create a header preventing IFRAMEing of the site by other websites has been added to your web.config file. + Could not update web.config file. Error: %0% + X-Content-Type-Options used to protect against MIME sniffing vulnerabilities was found.]]> + X-Content-Type-Options used to protect against MIME sniffing vulnerabilities was not found.]]> + Adds a value to the httpProtocol/customHeaders section of web.config to protect against MIME sniffing vulnerabilities. + A setting to create a header protecting against MIME sniffing vulnerabilities has been added to your web.config file. + Strict-Transport-Security, also known as the HSTS-header, was found.]]> + Strict-Transport-Security was not found.]]> + Adds the header 'Strict-Transport-Security' with the value 'max-age=10886400' to the httpProtocol/customHeaders section of web.config. Use this fix only if you will have your domains running with https for the next 18 weeks (minimum). + The HSTS header has been added to your web.config file. + X-XSS-Protection was found.]]> + X-XSS-Protection was not found.]]> + Adds the header 'X-XSS-Protection' with the value '1; mode=block' to the httpProtocol/customHeaders section of web.config. + The X-XSS-Protection header has been added to your web.config file. + + %0%.]]> + No headers revealing information about the website technology were found. + In the Web.config file, system.net/mailsettings could not be found. + In the Web.config file system.net/mailsettings section, the host is not configured. + SMTP settings are configured correctly and the service is operating as expected. + The SMTP server configured with host '%0%' and port '%1%' could not be reached. Please check to ensure the SMTP settings in the Web.config file system.net/mailsettings are correct. + %0%.]]> + %0%.]]> +

Results of the scheduled Umbraco Health Checks run on %0% at %1% are as follows:

%2%]]>
+ Umbraco Health Check Status: %0% + + + Disable URL tracker + Enable URL tracker + Culture + Original URL + Redirected To + Redirect Url Management + The following URLs redirect to this content item: + No redirects have been made + When a published page gets renamed or moved a redirect will automatically be made to the new page. + Are you sure you want to remove the redirect from '%0%' to '%1%'? + Redirect URL removed. + Error removing redirect URL. + This will remove the redirect + Are you sure you want to disable the URL tracker? + URL tracker has now been disabled. + Error disabling the URL tracker, more information can be found in your log file. + URL tracker has now been enabled. + Error enabling the URL tracker, more information can be found in your log file. + + + No Dictionary items to choose from + + + %0% characters left.]]> + %1% too many.]]> + + + 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 location where this item can be automatically restored. You can move the item manually using the tree below. + was restored under + + + Direction + Parent to child + Bidirectional + Parent + Child + Count + Relations + Created + Comment + Name + No relations for this relation type. + Relation Type + Relations + + + Getting Started + Redirect URL Management + Content + Welcome + Examine Management + Published Status + Models Builder + Health Check Profiling - Getting Started - Install Umbraco Forms - - + Getting Started + Install Umbraco Forms + + Go back Active layout: Jump to - group - -
+ group + passed + warning + failed + suggestion + Check passed + Check failed + Open backoffice search + Open/Close backoffice help + Open/Close your profile options + +
diff --git a/src/Umbraco.Web/Cache/DistributedCacheExtensions.cs b/src/Umbraco.Web/Cache/DistributedCacheExtensions.cs index 80c49e279c..579448e264 100644 --- a/src/Umbraco.Web/Cache/DistributedCacheExtensions.cs +++ b/src/Umbraco.Web/Cache/DistributedCacheExtensions.cs @@ -266,13 +266,21 @@ namespace Umbraco.Web.Cache public static void RefreshLanguageCache(this DistributedCache dc, ILanguage language) { if (language == null) return; - dc.Refresh(LanguageCacheRefresher.UniqueId, language.Id); + + var payload = new LanguageCacheRefresher.JsonPayload(language.Id, language.IsoCode, + language.WasPropertyDirty(nameof(ILanguage.IsoCode)) + ? LanguageCacheRefresher.JsonPayload.LanguageChangeType.ChangeCulture + : LanguageCacheRefresher.JsonPayload.LanguageChangeType.Update); + + dc.RefreshByPayload(LanguageCacheRefresher.UniqueId, new[] { payload }); } public static void RemoveLanguageCache(this DistributedCache dc, ILanguage language) { if (language == null) return; - dc.Remove(LanguageCacheRefresher.UniqueId, language.Id); + + var payload = new LanguageCacheRefresher.JsonPayload(language.Id, language.IsoCode, LanguageCacheRefresher.JsonPayload.LanguageChangeType.Remove); + dc.RefreshByPayload(LanguageCacheRefresher.UniqueId, new[] { payload }); } #endregion diff --git a/src/Umbraco.Web/Editors/LanguageController.cs b/src/Umbraco.Web/Editors/LanguageController.cs index 650dcea6e9..cb7fde23db 100644 --- a/src/Umbraco.Web/Editors/LanguageController.cs +++ b/src/Umbraco.Web/Editors/LanguageController.cs @@ -99,24 +99,28 @@ namespace Umbraco.Web.Editors throw new HttpResponseException(Request.CreateValidationErrorResponse(ModelState)); // this is prone to race conditions but the service will not let us proceed anyways - var existing = Services.LocalizationService.GetLanguageByIsoCode(language.IsoCode); + var existingByCulture = Services.LocalizationService.GetLanguageByIsoCode(language.IsoCode); // the localization service might return the generic language even when queried for specific ones (e.g. "da" when queried for "da-DK") // - we need to handle that explicitly - if (existing?.IsoCode != language.IsoCode) + if (existingByCulture?.IsoCode != language.IsoCode) { - existing = null; + existingByCulture = null; } - if (existing != null && language.Id != existing.Id) + if (existingByCulture != null && language.Id != existingByCulture.Id) { //someone is trying to create a language that already exist ModelState.AddModelError("IsoCode", "The language " + language.IsoCode + " already exists"); throw new HttpResponseException(Request.CreateValidationErrorResponse(ModelState)); } - if (existing == null) + var existingById = language.Id != default ? Services.LocalizationService.GetLanguageById(language.Id) : null; + + if (existingById == null) { + //Creating a new lang... + CultureInfo culture; try { @@ -141,38 +145,39 @@ namespace Umbraco.Web.Editors return Mapper.Map(newLang); } - existing.IsMandatory = language.IsMandatory; + existingById.IsMandatory = language.IsMandatory; // note that the service will prevent the default language from being "un-defaulted" // but does not hurt to test here - though the UI should prevent it too - if (existing.IsDefault && !language.IsDefault) + if (existingById.IsDefault && !language.IsDefault) { ModelState.AddModelError("IsDefault", "Cannot un-default the default language."); throw new HttpResponseException(Request.CreateValidationErrorResponse(ModelState)); } - existing.IsDefault = language.IsDefault; - existing.FallbackLanguageId = language.FallbackLanguageId; + existingById.IsDefault = language.IsDefault; + existingById.FallbackLanguageId = language.FallbackLanguageId; + existingById.IsoCode = language.IsoCode; // modifying an existing language can create a fallback, verify // note that the service will check again, dealing with race conditions - if (existing.FallbackLanguageId.HasValue) + if (existingById.FallbackLanguageId.HasValue) { var languages = Services.LocalizationService.GetAllLanguages().ToDictionary(x => x.Id, x => x); - if (!languages.ContainsKey(existing.FallbackLanguageId.Value)) + if (!languages.ContainsKey(existingById.FallbackLanguageId.Value)) { ModelState.AddModelError("FallbackLanguage", "The selected fall back language does not exist."); throw new HttpResponseException(Request.CreateValidationErrorResponse(ModelState)); } - if (CreatesCycle(existing, languages)) + if (CreatesCycle(existingById, languages)) { - ModelState.AddModelError("FallbackLanguage", $"The selected fall back language {languages[existing.FallbackLanguageId.Value].IsoCode} would create a circular path."); + ModelState.AddModelError("FallbackLanguage", $"The selected fall back language {languages[existingById.FallbackLanguageId.Value].IsoCode} would create a circular path."); throw new HttpResponseException(Request.CreateValidationErrorResponse(ModelState)); } } - Services.LocalizationService.Save(existing); - return Mapper.Map(existing); + Services.LocalizationService.Save(existingById); + return Mapper.Map(existingById); } // see LocalizationService From 22de853dee25c811092925cc88a85837e4c69020 Mon Sep 17 00:00:00 2001 From: Shannon Date: Mon, 14 Oct 2019 22:02:42 +1100 Subject: [PATCH 23/68] ensures the domain cache is totally refreshed when changing langs --- src/Umbraco.Web/Cache/DomainCacheRefresher.cs | 20 ++------- .../Cache/LanguageCacheRefresher.cs | 45 +++++++++---------- .../NuCache/PublishedSnapshotService.cs | 18 ++++++++ 3 files changed, 44 insertions(+), 39 deletions(-) diff --git a/src/Umbraco.Web/Cache/DomainCacheRefresher.cs b/src/Umbraco.Web/Cache/DomainCacheRefresher.cs index 37b0a483a6..4ffe4e2717 100644 --- a/src/Umbraco.Web/Cache/DomainCacheRefresher.cs +++ b/src/Umbraco.Web/Cache/DomainCacheRefresher.cs @@ -47,25 +47,13 @@ namespace Umbraco.Web.Cache // these events should never trigger // everything should be PAYLOAD/JSON - public override void RefreshAll() - { - throw new NotSupportedException(); - } + public override void RefreshAll() => throw new NotSupportedException(); - public override void Refresh(int id) - { - throw new NotSupportedException(); - } + public override void Refresh(int id) => throw new NotSupportedException(); - public override void Refresh(Guid id) - { - throw new NotSupportedException(); - } + public override void Refresh(Guid id) => throw new NotSupportedException(); - public override void Remove(int id) - { - throw new NotSupportedException(); - } + public override void Remove(int id) => throw new NotSupportedException(); #endregion diff --git a/src/Umbraco.Web/Cache/LanguageCacheRefresher.cs b/src/Umbraco.Web/Cache/LanguageCacheRefresher.cs index 03102ec969..2877874e5a 100644 --- a/src/Umbraco.Web/Cache/LanguageCacheRefresher.cs +++ b/src/Umbraco.Web/Cache/LanguageCacheRefresher.cs @@ -5,6 +5,7 @@ using Umbraco.Core.Models; using Umbraco.Core.Services; using Umbraco.Core.Services.Changes; using Umbraco.Web.PublishedCache; +using static Umbraco.Web.Cache.LanguageCacheRefresher.JsonPayload; namespace Umbraco.Web.Cache { @@ -12,11 +13,10 @@ namespace Umbraco.Web.Cache //CacheRefresherBase { - public LanguageCacheRefresher(AppCaches appCaches, IPublishedSnapshotService publishedSnapshotService, IDomainService domainService) + public LanguageCacheRefresher(AppCaches appCaches, IPublishedSnapshotService publishedSnapshotService) : base(appCaches) { _publishedSnapshotService = publishedSnapshotService; - _domainService = domainService; } #region Define @@ -45,20 +45,21 @@ namespace Umbraco.Web.Cache //clear all no matter what type of payload ClearAllIsolatedCacheByEntityType(); + //clear all no matter what type of payload + RefreshDomains(); + foreach (var payload in payloads) { - RefreshDomains(payload.Id); - switch (payload.ChangeType) { - case JsonPayload.LanguageChangeType.Update: + case LanguageChangeType.Update: clearDictionary = true; break; - case JsonPayload.LanguageChangeType.Remove: + case LanguageChangeType.Remove: clearDictionary = true; clearContent = true; break; - case JsonPayload.LanguageChangeType.ChangeCulture: + case LanguageChangeType.ChangeCulture: clearDictionary = true; clearContent = true; break; @@ -70,11 +71,13 @@ namespace Umbraco.Web.Cache ClearAllIsolatedCacheByEntityType(); } - //if this flag is set, we will tell the published snapshot service to refresh ALL content + //if this flag is set, we will tell the published snapshot service to refresh ALL content and evict ALL IContent items if (clearContent) { + ContentCacheRefresher.RefreshContentTypes(AppCaches); // we need to evict all IContent items + //now refresh all nucache var clearContentPayload = new[] { new ContentCacheRefresher.JsonPayload(0, null, TreeChangeTypes.RefreshAll) }; - ContentCacheRefresher.NotifyPublishedSnapshotService(_publishedSnapshotService, AppCaches, clearContentPayload); + ContentCacheRefresher.NotifyPublishedSnapshotService(_publishedSnapshotService, AppCaches, clearContentPayload); } // then trigger event @@ -94,23 +97,19 @@ namespace Umbraco.Web.Cache #endregion - private void RefreshDomains(int langId) + /// + /// Clears all domain caches + /// + private void RefreshDomains() { - var assignedDomains = _domainService.GetAll(true).Where(x => x.LanguageId.HasValue && x.LanguageId.Value == langId).ToList(); + ClearAllIsolatedCacheByEntityType(); - if (assignedDomains.Count > 0) - { - // TODO: this is duplicating the logic in DomainCacheRefresher BUT we cannot inject that into this because it it not registered explicitly in the container, - // and we cannot inject the CacheRefresherCollection since that would be a circular reference, so what is the best way to call directly in to the - // DomainCacheRefresher? + // note: must do what's above FIRST else the repositories still have the old cached + // content and when the PublishedCachesService is notified of changes it does not see + // the new content... - ClearAllIsolatedCacheByEntityType(); - // note: must do what's above FIRST else the repositories still have the old cached - // content and when the PublishedCachesService is notified of changes it does not see - // the new content... - // notify - _publishedSnapshotService.Notify(assignedDomains.Select(x => new DomainCacheRefresher.JsonPayload(x.Id, DomainChangeTypes.Remove)).ToArray()); - } + var payloads = new[] { new DomainCacheRefresher.JsonPayload(0, DomainChangeTypes.RefreshAll) }; + _publishedSnapshotService.Notify(payloads); } #region Json diff --git a/src/Umbraco.Web/PublishedCache/NuCache/PublishedSnapshotService.cs b/src/Umbraco.Web/PublishedCache/NuCache/PublishedSnapshotService.cs index bf6012816a..23c2131a82 100755 --- a/src/Umbraco.Web/PublishedCache/NuCache/PublishedSnapshotService.cs +++ b/src/Umbraco.Web/PublishedCache/NuCache/PublishedSnapshotService.cs @@ -260,6 +260,8 @@ namespace Umbraco.Web.PublishedCache.NuCache ContentTypeService.ScopedRefreshedEntity += OnContentTypeRefreshedEntity; MediaTypeService.ScopedRefreshedEntity += OnMediaTypeRefreshedEntity; MemberTypeService.ScopedRefreshedEntity += OnMemberTypeRefreshedEntity; + + LocalizationService.SavedLanguage += OnLanguageSaved; } private void TearDownRepositoryEvents() @@ -277,6 +279,8 @@ namespace Umbraco.Web.PublishedCache.NuCache ContentTypeService.ScopedRefreshedEntity -= OnContentTypeRefreshedEntity; MediaTypeService.ScopedRefreshedEntity -= OnMediaTypeRefreshedEntity; MemberTypeService.ScopedRefreshedEntity -= OnMemberTypeRefreshedEntity; + + LocalizationService.SavedLanguage -= OnLanguageSaved; } public override void Dispose() @@ -1309,6 +1313,20 @@ namespace Umbraco.Web.PublishedCache.NuCache RebuildMemberDbCache(contentTypeIds: memberTypeIds); } + /// + /// If a is ever saved with a different culture, we need to rebuild all of the content nucache table + /// + /// + /// + private void OnLanguageSaved(ILocalizationService sender, Core.Events.SaveEventArgs e) + { + var cultureChanged = e.SavedEntities.Any(x => x.WasPropertyDirty(nameof(ILanguage.IsoCode))); + if(cultureChanged) + { + RebuildContentDbCache(); + } + } + private ContentNuDto GetDto(IContentBase content, bool published) { // should inject these in ctor From 58f50be33738b48fdc22afdcbbf0af0928d34cfb Mon Sep 17 00:00:00 2001 From: Shannon Date: Mon, 14 Oct 2019 22:09:47 +1100 Subject: [PATCH 24/68] simplifies lang refresher a bit --- src/Umbraco.Web/Cache/LanguageCacheRefresher.cs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/Umbraco.Web/Cache/LanguageCacheRefresher.cs b/src/Umbraco.Web/Cache/LanguageCacheRefresher.cs index 2877874e5a..8463acd6e0 100644 --- a/src/Umbraco.Web/Cache/LanguageCacheRefresher.cs +++ b/src/Umbraco.Web/Cache/LanguageCacheRefresher.cs @@ -45,9 +45,6 @@ namespace Umbraco.Web.Cache //clear all no matter what type of payload ClearAllIsolatedCacheByEntityType(); - //clear all no matter what type of payload - RefreshDomains(); - foreach (var payload in payloads) { switch (payload.ChangeType) @@ -56,9 +53,6 @@ namespace Umbraco.Web.Cache clearDictionary = true; break; case LanguageChangeType.Remove: - clearDictionary = true; - clearContent = true; - break; case LanguageChangeType.ChangeCulture: clearDictionary = true; clearContent = true; @@ -74,6 +68,8 @@ namespace Umbraco.Web.Cache //if this flag is set, we will tell the published snapshot service to refresh ALL content and evict ALL IContent items if (clearContent) { + //clear all domain caches + RefreshDomains(); ContentCacheRefresher.RefreshContentTypes(AppCaches); // we need to evict all IContent items //now refresh all nucache var clearContentPayload = new[] { new ContentCacheRefresher.JsonPayload(0, null, TreeChangeTypes.RefreshAll) }; From 5125772de543413c9d81458997dc41151bc6c1bb Mon Sep 17 00:00:00 2001 From: Shannon Date: Wed, 16 Oct 2019 15:00:13 +1100 Subject: [PATCH 25/68] ensures nucache table isn't rebuilt when adding a new lang --- .../PublishedCache/NuCache/PublishedSnapshotService.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Web/PublishedCache/NuCache/PublishedSnapshotService.cs b/src/Umbraco.Web/PublishedCache/NuCache/PublishedSnapshotService.cs index 23c2131a82..948019e8cc 100755 --- a/src/Umbraco.Web/PublishedCache/NuCache/PublishedSnapshotService.cs +++ b/src/Umbraco.Web/PublishedCache/NuCache/PublishedSnapshotService.cs @@ -1320,7 +1320,8 @@ namespace Umbraco.Web.PublishedCache.NuCache /// private void OnLanguageSaved(ILocalizationService sender, Core.Events.SaveEventArgs e) { - var cultureChanged = e.SavedEntities.Any(x => x.WasPropertyDirty(nameof(ILanguage.IsoCode))); + //culture changed on an existing language + var cultureChanged = e.SavedEntities.Any(x => !x.WasPropertyDirty(nameof(ILanguage.Id)) && x.WasPropertyDirty(nameof(ILanguage.IsoCode))); if(cultureChanged) { RebuildContentDbCache(); From 57288236250352f7e05bc14917db5999a7bcb651 Mon Sep 17 00:00:00 2001 From: Shannon Date: Wed, 16 Oct 2019 15:49:19 +1100 Subject: [PATCH 26/68] Fixes tests - Nucache tests were not disposing the snapshot service so was binding to all events!! renames the test snapshot service to avoid confusion --- ...dSnapshotService.cs => XmlPublishedSnapshotService.cs} | 6 +++--- src/Umbraco.Tests/LegacyXmlPublishedCache/XmlStore.cs | 2 +- .../PublishedContent/NuCacheChildrenTests.cs | 6 ++++++ src/Umbraco.Tests/PublishedContent/NuCacheTests.cs | 7 +++++++ src/Umbraco.Tests/Scoping/ScopedXmlTests.cs | 2 +- src/Umbraco.Tests/TestHelpers/TestWithDatabaseBase.cs | 8 ++++---- src/Umbraco.Tests/Umbraco.Tests.csproj | 2 +- src/Umbraco.Tests/Web/Mvc/UmbracoViewPageTests.cs | 4 ++-- 8 files changed, 25 insertions(+), 12 deletions(-) rename src/Umbraco.Tests/LegacyXmlPublishedCache/{PublishedSnapshotService.cs => XmlPublishedSnapshotService.cs} (97%) diff --git a/src/Umbraco.Tests/LegacyXmlPublishedCache/PublishedSnapshotService.cs b/src/Umbraco.Tests/LegacyXmlPublishedCache/XmlPublishedSnapshotService.cs similarity index 97% rename from src/Umbraco.Tests/LegacyXmlPublishedCache/PublishedSnapshotService.cs rename to src/Umbraco.Tests/LegacyXmlPublishedCache/XmlPublishedSnapshotService.cs index 394a33d777..ec6b854a46 100644 --- a/src/Umbraco.Tests/LegacyXmlPublishedCache/PublishedSnapshotService.cs +++ b/src/Umbraco.Tests/LegacyXmlPublishedCache/XmlPublishedSnapshotService.cs @@ -21,7 +21,7 @@ namespace Umbraco.Tests.LegacyXmlPublishedCache /// /// Implements a published snapshot service. /// - internal class PublishedSnapshotService : PublishedSnapshotServiceBase + internal class XmlPublishedSnapshotService : PublishedSnapshotServiceBase { private readonly XmlStore _xmlStore; private readonly RoutesCache _routesCache; @@ -41,7 +41,7 @@ namespace Umbraco.Tests.LegacyXmlPublishedCache #region Constructors // used in WebBootManager + tests - public PublishedSnapshotService(ServiceContext serviceContext, + public XmlPublishedSnapshotService(ServiceContext serviceContext, IPublishedContentTypeFactory publishedContentTypeFactory, IScopeProvider scopeProvider, IAppCache requestCache, @@ -65,7 +65,7 @@ namespace Umbraco.Tests.LegacyXmlPublishedCache } // used in some tests - internal PublishedSnapshotService(ServiceContext serviceContext, + internal XmlPublishedSnapshotService(ServiceContext serviceContext, IPublishedContentTypeFactory publishedContentTypeFactory, IScopeProvider scopeProvider, IAppCache requestCache, diff --git a/src/Umbraco.Tests/LegacyXmlPublishedCache/XmlStore.cs b/src/Umbraco.Tests/LegacyXmlPublishedCache/XmlStore.cs index 3b675c2f07..447104b7cd 100644 --- a/src/Umbraco.Tests/LegacyXmlPublishedCache/XmlStore.cs +++ b/src/Umbraco.Tests/LegacyXmlPublishedCache/XmlStore.cs @@ -32,7 +32,7 @@ namespace Umbraco.Tests.LegacyXmlPublishedCache /// Represents the Xml storage for the Xml published cache. /// /// - /// One instance of is instantiated by the and + /// One instance of is instantiated by the and /// then passed to all instances that are created (one per request). /// This class should *not* be public. /// diff --git a/src/Umbraco.Tests/PublishedContent/NuCacheChildrenTests.cs b/src/Umbraco.Tests/PublishedContent/NuCacheChildrenTests.cs index c116c12f59..5acba4b609 100644 --- a/src/Umbraco.Tests/PublishedContent/NuCacheChildrenTests.cs +++ b/src/Umbraco.Tests/PublishedContent/NuCacheChildrenTests.cs @@ -41,6 +41,12 @@ namespace Umbraco.Tests.PublishedContent private ContentType _contentTypeVariant; private TestDataSource _source; + [TearDown] + public void Teardown() + { + _snapshotService?.Dispose(); + } + private void Init(IEnumerable kits) { Current.Reset(); diff --git a/src/Umbraco.Tests/PublishedContent/NuCacheTests.cs b/src/Umbraco.Tests/PublishedContent/NuCacheTests.cs index 44df5c20cb..0e05e6baad 100644 --- a/src/Umbraco.Tests/PublishedContent/NuCacheTests.cs +++ b/src/Umbraco.Tests/PublishedContent/NuCacheTests.cs @@ -36,6 +36,12 @@ namespace Umbraco.Tests.PublishedContent private ContentType _contentType; private PropertyType _propertyType; + [TearDown] + public void Teardown() + { + _snapshotService?.Dispose(); + } + private void Init() { Current.Reset(); @@ -303,5 +309,6 @@ namespace Umbraco.Tests.PublishedContent Assert.IsFalse(c2.IsPublished("dk-DA")); Assert.IsTrue(c2.IsPublished("de-DE")); } + } } diff --git a/src/Umbraco.Tests/Scoping/ScopedXmlTests.cs b/src/Umbraco.Tests/Scoping/ScopedXmlTests.cs index 34482a79fa..91a6934e18 100644 --- a/src/Umbraco.Tests/Scoping/ScopedXmlTests.cs +++ b/src/Umbraco.Tests/Scoping/ScopedXmlTests.cs @@ -73,7 +73,7 @@ namespace Umbraco.Tests.Scoping // xmlStore.Xml - the actual main xml document // publishedContentCache.GetXml() - the captured xml - private static XmlStore XmlStore => (Current.Factory.GetInstance() as PublishedSnapshotService).XmlStore; + private static XmlStore XmlStore => (Current.Factory.GetInstance() as XmlPublishedSnapshotService).XmlStore; private static XmlDocument XmlMaster => XmlStore.Xml; private static XmlDocument XmlInContext => ((PublishedContentCache) Umbraco.Web.Composing.Current.UmbracoContext.Content).GetXml(false); diff --git a/src/Umbraco.Tests/TestHelpers/TestWithDatabaseBase.cs b/src/Umbraco.Tests/TestHelpers/TestWithDatabaseBase.cs index 9cc2b97445..050de4fcb9 100644 --- a/src/Umbraco.Tests/TestHelpers/TestWithDatabaseBase.cs +++ b/src/Umbraco.Tests/TestHelpers/TestWithDatabaseBase.cs @@ -259,7 +259,7 @@ namespace Umbraco.Tests.TestHelpers var publishedSnapshotAccessor = new UmbracoContextPublishedSnapshotAccessor(Umbraco.Web.Composing.Current.UmbracoContextAccessor); var variationContextAccessor = new TestVariationContextAccessor(); - var service = new PublishedSnapshotService( + var service = new XmlPublishedSnapshotService( ServiceContext, Factory.GetInstance(), ScopeProvider, @@ -357,14 +357,14 @@ namespace Umbraco.Tests.TestHelpers protected UmbracoContext GetUmbracoContext(string url, int templateId = 1234, RouteData routeData = null, bool setSingleton = false, IUmbracoSettingsSection umbracoSettings = null, IEnumerable urlProviders = null, IEnumerable mediaUrlProviders = null, IGlobalSettings globalSettings = null, IPublishedSnapshotService snapshotService = null) { // ensure we have a PublishedCachesService - var service = snapshotService ?? PublishedSnapshotService as PublishedSnapshotService; + var service = snapshotService ?? PublishedSnapshotService as XmlPublishedSnapshotService; if (service == null) throw new Exception("Not a proper XmlPublishedCache.PublishedCachesService."); - if (service is PublishedSnapshotService) + if (service is XmlPublishedSnapshotService) { // re-initialize PublishedCacheService content with an Xml source with proper template id - ((PublishedSnapshotService)service).XmlStore.GetXmlDocument = () => + ((XmlPublishedSnapshotService)service).XmlStore.GetXmlDocument = () => { var doc = new XmlDocument(); doc.LoadXml(GetXmlContent(templateId)); diff --git a/src/Umbraco.Tests/Umbraco.Tests.csproj b/src/Umbraco.Tests/Umbraco.Tests.csproj index fcf73fbffa..39826fcc38 100644 --- a/src/Umbraco.Tests/Umbraco.Tests.csproj +++ b/src/Umbraco.Tests/Umbraco.Tests.csproj @@ -511,7 +511,7 @@ - + diff --git a/src/Umbraco.Tests/Web/Mvc/UmbracoViewPageTests.cs b/src/Umbraco.Tests/Web/Mvc/UmbracoViewPageTests.cs index 5c291c9601..9ca17675af 100644 --- a/src/Umbraco.Tests/Web/Mvc/UmbracoViewPageTests.cs +++ b/src/Umbraco.Tests/Web/Mvc/UmbracoViewPageTests.cs @@ -29,7 +29,7 @@ namespace Umbraco.Tests.Web.Mvc [UmbracoTest(WithApplication = true)] public class UmbracoViewPageTests : UmbracoTestBase { - private PublishedSnapshotService _service; + private XmlPublishedSnapshotService _service; [TearDown] public override void TearDown() @@ -421,7 +421,7 @@ namespace Umbraco.Tests.Web.Mvc var scopeProvider = TestObjects.GetScopeProvider(Mock.Of()); var factory = Mock.Of(); var umbracoContextAccessor = Mock.Of(); - _service = new PublishedSnapshotService(svcCtx, factory, scopeProvider, cache, + _service = new XmlPublishedSnapshotService(svcCtx, factory, scopeProvider, cache, null, null, umbracoContextAccessor, null, null, null, new TestDefaultCultureAccessor(), From e77eb746558165bc56a52b8a1b55f8370044e65c Mon Sep 17 00:00:00 2001 From: Bjarke Berg Date: Mon, 4 Nov 2019 11:54:19 +0100 Subject: [PATCH 27/68] post cherry pick fix --- src/Umbraco.Web/Cache/LanguageCacheRefresher.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Umbraco.Web/Cache/LanguageCacheRefresher.cs b/src/Umbraco.Web/Cache/LanguageCacheRefresher.cs index 8463acd6e0..e7d77207e3 100644 --- a/src/Umbraco.Web/Cache/LanguageCacheRefresher.cs +++ b/src/Umbraco.Web/Cache/LanguageCacheRefresher.cs @@ -46,7 +46,7 @@ namespace Umbraco.Web.Cache ClearAllIsolatedCacheByEntityType(); foreach (var payload in payloads) - { + { switch (payload.ChangeType) { case LanguageChangeType.Update: @@ -72,8 +72,8 @@ namespace Umbraco.Web.Cache RefreshDomains(); ContentCacheRefresher.RefreshContentTypes(AppCaches); // we need to evict all IContent items //now refresh all nucache - var clearContentPayload = new[] { new ContentCacheRefresher.JsonPayload(0, null, TreeChangeTypes.RefreshAll) }; - ContentCacheRefresher.NotifyPublishedSnapshotService(_publishedSnapshotService, AppCaches, clearContentPayload); + var clearContentPayload = new[] { new ContentCacheRefresher.JsonPayload(0, TreeChangeTypes.RefreshAll) }; + ContentCacheRefresher.NotifyPublishedSnapshotService(_publishedSnapshotService, AppCaches, clearContentPayload); } // then trigger event From 1c70d04ce29fd750055227cabac2bccd44cc1d0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Kottal?= Date: Tue, 5 Nov 2019 15:33:07 +0100 Subject: [PATCH 28/68] Moves editor name part out of template. Adds null checking in templates --- .../src/views/propertyeditors/grid/grid.controller.js | 11 +++++++++-- src/Umbraco.Web.UI/config/grid.editors.config.js | 7 ++++--- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.controller.js index 32f495e32b..5dce84d5dc 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.controller.js @@ -681,8 +681,15 @@ angular.module("umbraco") }; $scope.getTemplateName = function (control) { - if (control.editor.nameExp) return control.editor.nameExp(control) - return control.editor.name; + var templateName = control.editor.name; + if (control.editor.nameExp) { + var valueOfTemplate = control.editor.nameExp(control); + if (valueOfTemplate != "") { + templateName += ": "; + templateName += valueOfTemplate; + } + } + return templateName; } // ********************************************* diff --git a/src/Umbraco.Web.UI/config/grid.editors.config.js b/src/Umbraco.Web.UI/config/grid.editors.config.js index 49b843689b..210d167f9e 100644 --- a/src/Umbraco.Web.UI/config/grid.editors.config.js +++ b/src/Umbraco.Web.UI/config/grid.editors.config.js @@ -7,14 +7,14 @@ }, { "name": "Image", - "nameTemplate": "{{ 'Image: ' + (value.udi | ncNodeName) }}", + "nameTemplate": "{{ value && value.udi ? (value.udi | ncNodeName) : '' }}", "alias": "media", "view": "media", "icon": "icon-picture" }, { "name": "Macro", - "nameTemplate": "{{ 'Macro: ' + value.macroAlias }}", + "nameTemplate": "{{ value && value.macroAlias ? value.macroAlias : '' }}", "alias": "macro", "view": "macro", "icon": "icon-settings-alt" @@ -27,7 +27,7 @@ }, { "name": "Headline", - "nameTemplate": "{{ 'Headline: ' + value }}", + "nameTemplate": "{{ value }}", "alias": "headline", "view": "textstring", "icon": "icon-coin", @@ -38,6 +38,7 @@ }, { "name": "Quote", + "nameTemplate": "{{ value ? value.substring(0,32) + (value.length > 32 ? '...' : '') : '' }}", "alias": "quote", "view": "textstring", "icon": "icon-quote", From c70d82d32bd22d95c02b14b1e78d7a060e86338a Mon Sep 17 00:00:00 2001 From: Bjarke Berg Date: Thu, 7 Nov 2019 14:10:06 +0100 Subject: [PATCH 29/68] AB3649 - Moved ManifestSection --- .../Manifest/ManifestSection.cs | 0 src/Umbraco.Core/Umbraco.Core.csproj | 1 - 2 files changed, 1 deletion(-) rename src/{Umbraco.Core => Umbraco.Abstractions}/Manifest/ManifestSection.cs (100%) diff --git a/src/Umbraco.Core/Manifest/ManifestSection.cs b/src/Umbraco.Abstractions/Manifest/ManifestSection.cs similarity index 100% rename from src/Umbraco.Core/Manifest/ManifestSection.cs rename to src/Umbraco.Abstractions/Manifest/ManifestSection.cs diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index 085a830fbf..b6084e695a 100755 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -392,7 +392,6 @@ - From 466610bd328603e3d30ceb2ef463769f871cc0f4 Mon Sep 17 00:00:00 2001 From: Paul Seal Date: Thu, 7 Nov 2019 12:18:57 +0000 Subject: [PATCH 30/68] - added delete title to trash icons in the grid --- .../src/views/propertyeditors/grid/grid.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.html index 3995ed703d..e889067321 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.html +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.html @@ -95,7 +95,7 @@
- +
- + Date: Sun, 27 Oct 2019 10:40:03 +0000 Subject: [PATCH 31/68] Changed the styling of Resend Invitation button and fixed the margin --- .../src/less/components/users/umb-user-details.less | 5 +++++ .../src/views/users/views/user/details.html | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/less/components/users/umb-user-details.less b/src/Umbraco.Web.UI.Client/src/less/components/users/umb-user-details.less index 9ddad03b48..7caec3c78e 100644 --- a/src/Umbraco.Web.UI.Client/src/less/components/users/umb-user-details.less +++ b/src/Umbraco.Web.UI.Client/src/less/components/users/umb-user-details.less @@ -63,6 +63,10 @@ a.umb-user-details-details__back-link { .umb-user-details-details__sidebar { flex: 0 0 @sidebarwidth; + + .umb-button{ + margin-left:0px; + } } @media (max-width: 768px) { @@ -101,6 +105,7 @@ a.umb-user-details-details__back-link { .umb-user-details-details__information-item { margin-bottom: 10px; font-size: 13px; + margin-top:10px; } .umb-user-details-details__information-item-label { diff --git a/src/Umbraco.Web.UI.Client/src/views/users/views/user/details.html b/src/Umbraco.Web.UI.Client/src/views/users/views/user/details.html index e759be5e7a..ee77e4c14e 100644 --- a/src/Umbraco.Web.UI.Client/src/views/users/views/user/details.html +++ b/src/Umbraco.Web.UI.Client/src/views/users/views/user/details.html @@ -322,7 +322,7 @@ rows="4"> Date: Thu, 7 Nov 2019 12:44:58 +0000 Subject: [PATCH 32/68] Accessibility Improvement - Open Template in info content app changed from anchor tag to button --- .../src/views/components/content/umb-content-node-info.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/components/content/umb-content-node-info.html b/src/Umbraco.Web.UI.Client/src/views/components/content/umb-content-node-info.html index da093f72fe..d72e977010 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/content/umb-content-node-info.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/content/umb-content-node-info.html @@ -169,9 +169,9 @@ ng-change="updateTemplate(node.template)"> - +
From 41915080b2745207cdf596921d955831394d2f2e Mon Sep 17 00:00:00 2001 From: andyneil Date: Thu, 7 Nov 2019 15:01:22 +0000 Subject: [PATCH 33/68] Fix incorrect data types for default member properties. (#7086) Issue https://github.com/umbraco/Umbraco-CMS/issues/7051 --- src/Umbraco.Core/Constants-Conventions.cs | 18 ++++++++++++------ .../Implement/MemberTypeRepository.cs | 13 +++++++++++-- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/src/Umbraco.Core/Constants-Conventions.cs b/src/Umbraco.Core/Constants-Conventions.cs index 6c9407667a..e78c498e66 100644 --- a/src/Umbraco.Core/Constants-Conventions.cs +++ b/src/Umbraco.Core/Constants-Conventions.cs @@ -221,7 +221,8 @@ namespace Umbraco.Core FailedPasswordAttempts, new PropertyType(PropertyEditors.Aliases.Label, ValueStorageType.Integer, true, FailedPasswordAttempts) { - Name = FailedPasswordAttemptsLabel + Name = FailedPasswordAttemptsLabel, + DataTypeId = Constants.DataTypes.LabelInt } }, { @@ -242,35 +243,40 @@ namespace Umbraco.Core LastLockoutDate, new PropertyType(PropertyEditors.Aliases.Label, ValueStorageType.Date, true, LastLockoutDate) { - Name = LastLockoutDateLabel + Name = LastLockoutDateLabel, + DataTypeId = Constants.DataTypes.LabelDateTime } }, { LastLoginDate, new PropertyType(PropertyEditors.Aliases.Label, ValueStorageType.Date, true, LastLoginDate) { - Name = LastLoginDateLabel + Name = LastLoginDateLabel, + DataTypeId = Constants.DataTypes.LabelDateTime } }, { LastPasswordChangeDate, new PropertyType(PropertyEditors.Aliases.Label, ValueStorageType.Date, true, LastPasswordChangeDate) { - Name = LastPasswordChangeDateLabel + Name = LastPasswordChangeDateLabel, + DataTypeId = Constants.DataTypes.LabelDateTime } }, { PasswordAnswer, new PropertyType(PropertyEditors.Aliases.Label, ValueStorageType.Nvarchar, true, PasswordAnswer) { - Name = PasswordAnswerLabel + Name = PasswordAnswerLabel, + DataTypeId = Constants.DataTypes.LabelString } }, { PasswordQuestion, new PropertyType(PropertyEditors.Aliases.Label, ValueStorageType.Nvarchar, true, PasswordQuestion) { - Name = PasswordQuestionLabel + Name = PasswordQuestionLabel, + DataTypeId = Constants.DataTypes.LabelString } } }; diff --git a/src/Umbraco.Core/Persistence/Repositories/Implement/MemberTypeRepository.cs b/src/Umbraco.Core/Persistence/Repositories/Implement/MemberTypeRepository.cs index ee651819bf..c3b95dbd8f 100644 --- a/src/Umbraco.Core/Persistence/Repositories/Implement/MemberTypeRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/Implement/MemberTypeRepository.cs @@ -225,8 +225,17 @@ namespace Umbraco.Core.Persistence.Repositories.Implement if (builtinProperties.ContainsKey(propertyType.Alias)) { //this reset's its current data type reference which will be re-assigned based on the property editor assigned on the next line - propertyType.DataTypeId = 0; - propertyType.DataTypeKey = default; + var propDefinition = builtinProperties[propertyType.Alias]; + if (propDefinition != null) + { + propertyType.DataTypeId = propDefinition.DataTypeId; + propertyType.DataTypeKey = propDefinition.DataTypeKey; + } + else + { + propertyType.DataTypeId = 0; + propertyType.DataTypeKey = default; + } } } } From 0d2c2846d4e9c3d44c956650db33fc2955a394a3 Mon Sep 17 00:00:00 2001 From: Richard Thompson Date: Thu, 7 Nov 2019 14:55:21 +0000 Subject: [PATCH 34/68] Corrected the model variable name The model variable name is registerModel rather than profileModel. --- .../Umbraco/PartialViewMacros/Templates/RegisterMember.cshtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI/Umbraco/PartialViewMacros/Templates/RegisterMember.cshtml b/src/Umbraco.Web.UI/Umbraco/PartialViewMacros/Templates/RegisterMember.cshtml index ca6f09bd97..17ed95ea31 100644 --- a/src/Umbraco.Web.UI/Umbraco/PartialViewMacros/Templates/RegisterMember.cshtml +++ b/src/Umbraco.Web.UI/Umbraco/PartialViewMacros/Templates/RegisterMember.cshtml @@ -85,7 +85,7 @@ else easily change it. For example, if you wanted to render a custom editor for this field called "MyEditor" you would create a file at ~/Views/Shared/EditorTemplates/MyEditor.cshtml", then you will change the next line of code to render your specific editor template like: - @Html.EditorFor(m => profileModel.MemberProperties[i].Value, "MyEditor") + @Html.EditorFor(m => registerModel.MemberProperties[i].Value, "MyEditor") *@ @Html.EditorFor(m => registerModel.MemberProperties[i].Value) @Html.HiddenFor(m => registerModel.MemberProperties[i].Alias) From 118d50671f02433982b72a2b6b2e6327969df21b Mon Sep 17 00:00:00 2001 From: Bjarke Berg Date: Fri, 8 Nov 2019 10:57:24 +0100 Subject: [PATCH 35/68] AB3649 - Moved Manifest stuff --- .../Manifest/ManifestContentAppDefinition.cs | 8 +------- .../Models/EntityContainer.cs | 0 .../IManifestValueValidator.cs | 0 .../PropertyEditors/IValueFormatValidator.cs | 0 .../IValueRequiredValidator.cs | 0 .../PropertyEditors/IValueValidator.cs | 0 .../ManifestValueValidatorCollection.cs | 0 ...ManifestValueValidatorCollectionBuilder.cs | 9 +++++++++ .../Validators/DecimalValidator.cs | 2 +- .../Validators/EmailValidator.cs | 2 +- .../Validators/IntegerValidator.cs | 2 +- .../Umbraco.Abstractions.csproj | 1 + src/Umbraco.Core/Manifest/IManifestFilter.cs | 1 + .../Manifest/ManifestContentAppFactory.cs | 7 +++++-- src/Umbraco.Core/Manifest/ManifestParser.cs | 17 ++++++++++------- ...ManifestValueValidatorCollectionBuilder.cs | 9 --------- .../Validators/RegexValidator.cs | 2 +- .../Validators/RequiredValidator.cs | 2 +- src/Umbraco.Core/Umbraco.Core.csproj | 19 ++++--------------- .../Manifest/ManifestContentAppTests.cs | 3 ++- .../Manifest/ManifestParserTests.cs | 2 +- .../ContentAppFactoryCollectionBuilder.cs | 3 ++- 22 files changed, 41 insertions(+), 48 deletions(-) rename src/{Umbraco.Core => Umbraco.Abstractions}/Manifest/ManifestContentAppDefinition.cs (92%) rename src/{Umbraco.Core => Umbraco.Abstractions}/Models/EntityContainer.cs (100%) rename src/{Umbraco.Core => Umbraco.Abstractions}/PropertyEditors/IManifestValueValidator.cs (100%) rename src/{Umbraco.Core => Umbraco.Abstractions}/PropertyEditors/IValueFormatValidator.cs (100%) rename src/{Umbraco.Core => Umbraco.Abstractions}/PropertyEditors/IValueRequiredValidator.cs (100%) rename src/{Umbraco.Core => Umbraco.Abstractions}/PropertyEditors/IValueValidator.cs (100%) rename src/{Umbraco.Core => Umbraco.Abstractions}/PropertyEditors/ManifestValueValidatorCollection.cs (100%) create mode 100644 src/Umbraco.Abstractions/PropertyEditors/ManifestValueValidatorCollectionBuilder.cs rename src/{Umbraco.Core => Umbraco.Abstractions}/PropertyEditors/Validators/DecimalValidator.cs (92%) rename src/{Umbraco.Core => Umbraco.Abstractions}/PropertyEditors/Validators/EmailValidator.cs (92%) rename src/{Umbraco.Core => Umbraco.Abstractions}/PropertyEditors/Validators/IntegerValidator.cs (92%) delete mode 100644 src/Umbraco.Core/PropertyEditors/ManifestValueValidatorCollectionBuilder.cs diff --git a/src/Umbraco.Core/Manifest/ManifestContentAppDefinition.cs b/src/Umbraco.Abstractions/Manifest/ManifestContentAppDefinition.cs similarity index 92% rename from src/Umbraco.Core/Manifest/ManifestContentAppDefinition.cs rename to src/Umbraco.Abstractions/Manifest/ManifestContentAppDefinition.cs index 2aafcd8b74..35293a6377 100644 --- a/src/Umbraco.Core/Manifest/ManifestContentAppDefinition.cs +++ b/src/Umbraco.Abstractions/Manifest/ManifestContentAppDefinition.cs @@ -1,7 +1,5 @@ using System; using System.Runtime.Serialization; -using Umbraco.Core.Composing; -using Umbraco.Core.IO; namespace Umbraco.Core.Manifest { @@ -65,11 +63,7 @@ namespace Umbraco.Core.Manifest /// Gets or sets the view for rendering the content app. /// [DataMember(Name = "view")] - public string View - { - get => _view; - set => _view = Current.IOHelper.ResolveVirtualUrl(value); - } + public string View { get; set; } /// /// Gets or sets the list of 'show' conditions for the content app. diff --git a/src/Umbraco.Core/Models/EntityContainer.cs b/src/Umbraco.Abstractions/Models/EntityContainer.cs similarity index 100% rename from src/Umbraco.Core/Models/EntityContainer.cs rename to src/Umbraco.Abstractions/Models/EntityContainer.cs diff --git a/src/Umbraco.Core/PropertyEditors/IManifestValueValidator.cs b/src/Umbraco.Abstractions/PropertyEditors/IManifestValueValidator.cs similarity index 100% rename from src/Umbraco.Core/PropertyEditors/IManifestValueValidator.cs rename to src/Umbraco.Abstractions/PropertyEditors/IManifestValueValidator.cs diff --git a/src/Umbraco.Core/PropertyEditors/IValueFormatValidator.cs b/src/Umbraco.Abstractions/PropertyEditors/IValueFormatValidator.cs similarity index 100% rename from src/Umbraco.Core/PropertyEditors/IValueFormatValidator.cs rename to src/Umbraco.Abstractions/PropertyEditors/IValueFormatValidator.cs diff --git a/src/Umbraco.Core/PropertyEditors/IValueRequiredValidator.cs b/src/Umbraco.Abstractions/PropertyEditors/IValueRequiredValidator.cs similarity index 100% rename from src/Umbraco.Core/PropertyEditors/IValueRequiredValidator.cs rename to src/Umbraco.Abstractions/PropertyEditors/IValueRequiredValidator.cs diff --git a/src/Umbraco.Core/PropertyEditors/IValueValidator.cs b/src/Umbraco.Abstractions/PropertyEditors/IValueValidator.cs similarity index 100% rename from src/Umbraco.Core/PropertyEditors/IValueValidator.cs rename to src/Umbraco.Abstractions/PropertyEditors/IValueValidator.cs diff --git a/src/Umbraco.Core/PropertyEditors/ManifestValueValidatorCollection.cs b/src/Umbraco.Abstractions/PropertyEditors/ManifestValueValidatorCollection.cs similarity index 100% rename from src/Umbraco.Core/PropertyEditors/ManifestValueValidatorCollection.cs rename to src/Umbraco.Abstractions/PropertyEditors/ManifestValueValidatorCollection.cs diff --git a/src/Umbraco.Abstractions/PropertyEditors/ManifestValueValidatorCollectionBuilder.cs b/src/Umbraco.Abstractions/PropertyEditors/ManifestValueValidatorCollectionBuilder.cs new file mode 100644 index 0000000000..0ebda864f6 --- /dev/null +++ b/src/Umbraco.Abstractions/PropertyEditors/ManifestValueValidatorCollectionBuilder.cs @@ -0,0 +1,9 @@ +using Umbraco.Core.Composing; + +namespace Umbraco.Core.PropertyEditors +{ + public class ManifestValueValidatorCollectionBuilder : LazyCollectionBuilderBase + { + protected override ManifestValueValidatorCollectionBuilder This => this; + } +} diff --git a/src/Umbraco.Core/PropertyEditors/Validators/DecimalValidator.cs b/src/Umbraco.Abstractions/PropertyEditors/Validators/DecimalValidator.cs similarity index 92% rename from src/Umbraco.Core/PropertyEditors/Validators/DecimalValidator.cs rename to src/Umbraco.Abstractions/PropertyEditors/Validators/DecimalValidator.cs index 86db995566..f464044923 100644 --- a/src/Umbraco.Core/PropertyEditors/Validators/DecimalValidator.cs +++ b/src/Umbraco.Abstractions/PropertyEditors/Validators/DecimalValidator.cs @@ -6,7 +6,7 @@ namespace Umbraco.Core.PropertyEditors.Validators /// /// A validator that validates that the value is a valid decimal /// - internal sealed class DecimalValidator : IManifestValueValidator + public sealed class DecimalValidator : IManifestValueValidator { /// public string ValidationName => "Decimal"; diff --git a/src/Umbraco.Core/PropertyEditors/Validators/EmailValidator.cs b/src/Umbraco.Abstractions/PropertyEditors/Validators/EmailValidator.cs similarity index 92% rename from src/Umbraco.Core/PropertyEditors/Validators/EmailValidator.cs rename to src/Umbraco.Abstractions/PropertyEditors/Validators/EmailValidator.cs index 4df11e4f60..8fb6d0c31b 100644 --- a/src/Umbraco.Core/PropertyEditors/Validators/EmailValidator.cs +++ b/src/Umbraco.Abstractions/PropertyEditors/Validators/EmailValidator.cs @@ -6,7 +6,7 @@ namespace Umbraco.Core.PropertyEditors.Validators /// /// A validator that validates an email address /// - internal sealed class EmailValidator : IManifestValueValidator + public sealed class EmailValidator : IManifestValueValidator { /// public string ValidationName => "Email"; diff --git a/src/Umbraco.Core/PropertyEditors/Validators/IntegerValidator.cs b/src/Umbraco.Abstractions/PropertyEditors/Validators/IntegerValidator.cs similarity index 92% rename from src/Umbraco.Core/PropertyEditors/Validators/IntegerValidator.cs rename to src/Umbraco.Abstractions/PropertyEditors/Validators/IntegerValidator.cs index 335ddf7724..5274ff484b 100644 --- a/src/Umbraco.Core/PropertyEditors/Validators/IntegerValidator.cs +++ b/src/Umbraco.Abstractions/PropertyEditors/Validators/IntegerValidator.cs @@ -6,7 +6,7 @@ namespace Umbraco.Core.PropertyEditors.Validators /// /// A validator that validates that the value is a valid integer /// - internal sealed class IntegerValidator : IManifestValueValidator + public sealed class IntegerValidator : IManifestValueValidator { /// public string ValidationName => "Integer"; diff --git a/src/Umbraco.Abstractions/Umbraco.Abstractions.csproj b/src/Umbraco.Abstractions/Umbraco.Abstractions.csproj index a5e5a94520..b3a1b4fa25 100644 --- a/src/Umbraco.Abstractions/Umbraco.Abstractions.csproj +++ b/src/Umbraco.Abstractions/Umbraco.Abstractions.csproj @@ -7,6 +7,7 @@ + diff --git a/src/Umbraco.Core/Manifest/IManifestFilter.cs b/src/Umbraco.Core/Manifest/IManifestFilter.cs index 505f13d385..88e00a3966 100644 --- a/src/Umbraco.Core/Manifest/IManifestFilter.cs +++ b/src/Umbraco.Core/Manifest/IManifestFilter.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; + namespace Umbraco.Core.Manifest { /// diff --git a/src/Umbraco.Core/Manifest/ManifestContentAppFactory.cs b/src/Umbraco.Core/Manifest/ManifestContentAppFactory.cs index 1c50a4b895..e2c3ee48fa 100644 --- a/src/Umbraco.Core/Manifest/ManifestContentAppFactory.cs +++ b/src/Umbraco.Core/Manifest/ManifestContentAppFactory.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Text.RegularExpressions; +using Umbraco.Core.IO; using Umbraco.Core.Models; using Umbraco.Core.Models.ContentEditing; using Umbraco.Core.Models.Membership; @@ -31,10 +32,12 @@ namespace Umbraco.Core.Manifest public class ManifestContentAppFactory : IContentAppFactory { private readonly ManifestContentAppDefinition _definition; + private readonly IIOHelper _ioHelper; - public ManifestContentAppFactory(ManifestContentAppDefinition definition) + public ManifestContentAppFactory(ManifestContentAppDefinition definition, IIOHelper ioHelper) { _definition = definition; + _ioHelper = ioHelper; } private ContentApp _app; @@ -132,7 +135,7 @@ namespace Umbraco.Core.Manifest Alias = _definition.Alias, Name = _definition.Name, Icon = _definition.Icon, - View = _definition.View, + View = _ioHelper.ResolveVirtualUrl(_definition.View), Weight = _definition.Weight }); } diff --git a/src/Umbraco.Core/Manifest/ManifestParser.cs b/src/Umbraco.Core/Manifest/ManifestParser.cs index cac904a520..7f2a1825b4 100644 --- a/src/Umbraco.Core/Manifest/ManifestParser.cs +++ b/src/Umbraco.Core/Manifest/ManifestParser.cs @@ -5,7 +5,6 @@ using System.Linq; using System.Text; using Newtonsoft.Json; using Umbraco.Core.Cache; -using Umbraco.Core.Composing; using Umbraco.Core.Exceptions; using Umbraco.Core.IO; using Umbraco.Core.Logging; @@ -22,6 +21,7 @@ namespace Umbraco.Core.Manifest private readonly IAppPolicyCache _cache; private readonly ILogger _logger; + private readonly IIOHelper _ioHelper; private readonly ManifestValueValidatorCollection _validators; private readonly ManifestFilterCollection _filters; @@ -30,28 +30,31 @@ namespace Umbraco.Core.Manifest /// /// Initializes a new instance of the class. /// - public ManifestParser(AppCaches appCaches, ManifestValueValidatorCollection validators, ManifestFilterCollection filters, ILogger logger) - : this(appCaches, validators, filters, "~/App_Plugins", logger) + public ManifestParser(AppCaches appCaches, ManifestValueValidatorCollection validators, ManifestFilterCollection filters, ILogger logger, IIOHelper ioHelper) + : this(appCaches, validators, filters, "~/App_Plugins", logger, ioHelper) { } /// /// Initializes a new instance of the class. /// - private ManifestParser(AppCaches appCaches, ManifestValueValidatorCollection validators, ManifestFilterCollection filters, string path, ILogger logger) + private ManifestParser(AppCaches appCaches, ManifestValueValidatorCollection validators, ManifestFilterCollection filters, string path, ILogger logger, IIOHelper ioHelper) { if (appCaches == null) throw new ArgumentNullException(nameof(appCaches)); _cache = appCaches.RuntimeCache; + _ioHelper = ioHelper; _validators = validators ?? throw new ArgumentNullException(nameof(validators)); _filters = filters ?? throw new ArgumentNullException(nameof(filters)); if (string.IsNullOrWhiteSpace(path)) throw new ArgumentNullOrEmptyException(nameof(path)); + Path = path; _logger = logger ?? throw new ArgumentNullException(nameof(logger)); + } public string Path { get => _path; - set => _path = value.StartsWith("~/") ? Current.IOHelper.MapPath(value) : value; + set => _path = value.StartsWith("~/") ? _ioHelper.MapPath(value) : value; } /// @@ -166,9 +169,9 @@ namespace Umbraco.Core.Manifest // scripts and stylesheets are raw string, must process here for (var i = 0; i < manifest.Scripts.Length; i++) - manifest.Scripts[i] = Current.IOHelper.ResolveVirtualUrl(manifest.Scripts[i]); + manifest.Scripts[i] = _ioHelper.ResolveVirtualUrl(manifest.Scripts[i]); for (var i = 0; i < manifest.Stylesheets.Length; i++) - manifest.Stylesheets[i] = Current.IOHelper.ResolveVirtualUrl(manifest.Stylesheets[i]); + manifest.Stylesheets[i] = _ioHelper.ResolveVirtualUrl(manifest.Stylesheets[i]); // add property editors that are also parameter editors, to the parameter editors list // (the manifest format is kinda legacy) diff --git a/src/Umbraco.Core/PropertyEditors/ManifestValueValidatorCollectionBuilder.cs b/src/Umbraco.Core/PropertyEditors/ManifestValueValidatorCollectionBuilder.cs deleted file mode 100644 index 8f7c68c813..0000000000 --- a/src/Umbraco.Core/PropertyEditors/ManifestValueValidatorCollectionBuilder.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Umbraco.Core.Composing; - -namespace Umbraco.Core.PropertyEditors -{ - internal class ManifestValueValidatorCollectionBuilder : LazyCollectionBuilderBase - { - protected override ManifestValueValidatorCollectionBuilder This => this; - } -} diff --git a/src/Umbraco.Core/PropertyEditors/Validators/RegexValidator.cs b/src/Umbraco.Core/PropertyEditors/Validators/RegexValidator.cs index e405fa3a3e..4036adba42 100644 --- a/src/Umbraco.Core/PropertyEditors/Validators/RegexValidator.cs +++ b/src/Umbraco.Core/PropertyEditors/Validators/RegexValidator.cs @@ -11,7 +11,7 @@ namespace Umbraco.Core.PropertyEditors.Validators /// /// A validator that validates that the value against a regular expression. /// - internal sealed class RegexValidator : IValueFormatValidator, IManifestValueValidator + public sealed class RegexValidator : IValueFormatValidator, IManifestValueValidator { private readonly ILocalizedTextService _textService; private string _regex; diff --git a/src/Umbraco.Core/PropertyEditors/Validators/RequiredValidator.cs b/src/Umbraco.Core/PropertyEditors/Validators/RequiredValidator.cs index c51f572817..e83997b170 100644 --- a/src/Umbraco.Core/PropertyEditors/Validators/RequiredValidator.cs +++ b/src/Umbraco.Core/PropertyEditors/Validators/RequiredValidator.cs @@ -8,7 +8,7 @@ namespace Umbraco.Core.PropertyEditors.Validators /// /// A validator that validates that the value is not null or empty (if it is a string) /// - internal sealed class RequiredValidator : IValueRequiredValidator, IManifestValueValidator + public sealed class RequiredValidator : IValueRequiredValidator, IManifestValueValidator { private readonly ILocalizedTextService _textService; diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index 68a6260fe3..f22a29075f 100755 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -193,6 +193,7 @@ + @@ -271,6 +272,9 @@ + + + @@ -285,7 +289,6 @@ - @@ -390,7 +393,6 @@ - @@ -483,9 +485,6 @@ - - - @@ -560,7 +559,6 @@ - @@ -582,7 +580,6 @@ - @@ -1002,22 +999,14 @@ - - - - - - - - diff --git a/src/Umbraco.Tests/Manifest/ManifestContentAppTests.cs b/src/Umbraco.Tests/Manifest/ManifestContentAppTests.cs index 1e02f562e3..c949e0bb67 100644 --- a/src/Umbraco.Tests/Manifest/ManifestContentAppTests.cs +++ b/src/Umbraco.Tests/Manifest/ManifestContentAppTests.cs @@ -6,6 +6,7 @@ using NUnit.Framework; using Umbraco.Core.Manifest; using Umbraco.Core.Models; using Umbraco.Core.Models.Membership; +using Umbraco.Web.Composing; namespace Umbraco.Tests.Manifest { @@ -67,7 +68,7 @@ namespace Umbraco.Tests.Manifest private void AssertDefinition(object source, bool expected, string[] show, IReadOnlyUserGroup[] groups) { var definition = JsonConvert.DeserializeObject("{" + (show.Length == 0 ? "" : " \"show\": [" + string.Join(",", show.Select(x => "\"" + x + "\"")) + "] ") + "}"); - var factory = new ManifestContentAppFactory(definition); + var factory = new ManifestContentAppFactory(definition, Current.IOHelper); var app = factory.GetContentAppFor(source, groups); if (expected) Assert.IsNotNull(app); diff --git a/src/Umbraco.Tests/Manifest/ManifestParserTests.cs b/src/Umbraco.Tests/Manifest/ManifestParserTests.cs index 1c90f68d62..0fcb7ac9e0 100644 --- a/src/Umbraco.Tests/Manifest/ManifestParserTests.cs +++ b/src/Umbraco.Tests/Manifest/ManifestParserTests.cs @@ -44,7 +44,7 @@ namespace Umbraco.Tests.Manifest new RequiredValidator(Mock.Of()), new RegexValidator(Mock.Of(), null) }; - _parser = new ManifestParser(AppCaches.Disabled, new ManifestValueValidatorCollection(validators), new ManifestFilterCollection(Array.Empty()), Mock.Of()); + _parser = new ManifestParser(AppCaches.Disabled, new ManifestValueValidatorCollection(validators), new ManifestFilterCollection(Array.Empty()), Mock.Of(), Current.IOHelper); } [Test] diff --git a/src/Umbraco.Web/ContentApps/ContentAppFactoryCollectionBuilder.cs b/src/Umbraco.Web/ContentApps/ContentAppFactoryCollectionBuilder.cs index 170b9169ef..4e86b407b5 100644 --- a/src/Umbraco.Web/ContentApps/ContentAppFactoryCollectionBuilder.cs +++ b/src/Umbraco.Web/ContentApps/ContentAppFactoryCollectionBuilder.cs @@ -2,6 +2,7 @@ using System.Linq; using Umbraco.Core; using Umbraco.Core.Composing; +using Umbraco.Core.IO; using Umbraco.Core.Logging; using Umbraco.Core.Manifest; using Umbraco.Core.Models.ContentEditing; @@ -28,7 +29,7 @@ namespace Umbraco.Web.ContentApps // its dependencies too, and that can create cycles or other oddities var manifestParser = factory.GetInstance(); - return base.CreateItems(factory).Concat(manifestParser.Manifest.ContentApps.Select(x => new ManifestContentAppFactory(x))); + return base.CreateItems(factory).Concat(manifestParser.Manifest.ContentApps.Select(x => new ManifestContentAppFactory(x, Current.IOHelper))); } } } From ed82bd05c66d8098a1c02d4dc67966e5e607ebe9 Mon Sep 17 00:00:00 2001 From: Bjarke Berg Date: Fri, 8 Nov 2019 14:27:27 +0100 Subject: [PATCH 36/68] AB3649 - Abstracted IPropertyType, IProperty and IPropertyValue --- src/Umbraco.Abstractions/Models/IProperty.cs | 100 ++++++++++++++++++ .../Models/IPropertyType.cs | 43 ++++++++ .../Models/IPropertyValue.cs | 34 ++++++ .../ConfigurationFieldAttribute.cs | 0 .../PropertyEditors/GridEditor.cs | 35 +++--- .../PropertyEditors/IConfigurationEditor.cs | 0 .../CompositionExtensions_Essentials.cs | 2 + .../ContentVariationExtensions.cs | 12 +-- src/Umbraco.Core/IO/IMediaFileSystem.cs | 4 +- src/Umbraco.Core/IO/MediaFileSystem.cs | 4 +- .../Manifest/DataEditorConverter.cs | 26 ++++- .../Manifest/ManifestDashboard.cs | 8 +- src/Umbraco.Core/Manifest/ManifestParser.cs | 15 ++- src/Umbraco.Core/Models/IDataValueEditor.cs | 8 +- src/Umbraco.Core/Models/Property.cs | 36 +++---- src/Umbraco.Core/Models/PropertyType.cs | 6 +- .../ConfigurationFieldsExtensions.cs | 34 ------ .../PropertyEditors/DataValueEditor.cs | 15 +-- .../Services/PropertyValidationService.cs | 6 +- src/Umbraco.Core/Umbraco.Core.csproj | 19 ++-- .../Umbraco.ModelsBuilder.Embedded.csproj | 4 +- src/Umbraco.Tests/App.config | 4 + src/Umbraco.Tests/Models/PropertyTypeTests.cs | 10 +- src/Umbraco.Tests/Testing/UmbracoTestBase.cs | 1 + src/Umbraco.Tests/Umbraco.Tests.csproj | 2 +- src/Umbraco.Web.UI/Umbraco.Web.UI.csproj | 4 +- .../PropertyEditors/DateValueEditor.cs | 2 +- .../PropertyEditors/GridPropertyEditor.cs | 2 +- .../ImageCropperPropertyValueEditor.cs | 4 +- .../MultiUrlPickerValueEditor.cs | 2 +- .../MultipleTextStringPropertyEditor.cs | 2 +- .../PropertyEditors/MultipleValueEditor.cs | 2 +- .../NestedContentPropertyEditor.cs | 4 +- .../PropertyEditors/RichTextPropertyEditor.cs | 2 +- .../PropertyEditors/TextOnlyValueEditor.cs | 2 +- src/Umbraco.Web/Umbraco.Web.csproj | 3 +- 36 files changed, 311 insertions(+), 146 deletions(-) create mode 100644 src/Umbraco.Abstractions/Models/IProperty.cs create mode 100644 src/Umbraco.Abstractions/Models/IPropertyType.cs create mode 100644 src/Umbraco.Abstractions/Models/IPropertyValue.cs rename src/{Umbraco.Core => Umbraco.Abstractions}/PropertyEditors/ConfigurationFieldAttribute.cs (100%) rename src/{Umbraco.Core => Umbraco.Abstractions}/PropertyEditors/GridEditor.cs (68%) rename src/{Umbraco.Core => Umbraco.Abstractions}/PropertyEditors/IConfigurationEditor.cs (100%) delete mode 100644 src/Umbraco.Core/PropertyEditors/ConfigurationFieldsExtensions.cs diff --git a/src/Umbraco.Abstractions/Models/IProperty.cs b/src/Umbraco.Abstractions/Models/IProperty.cs new file mode 100644 index 0000000000..308f4ae851 --- /dev/null +++ b/src/Umbraco.Abstractions/Models/IProperty.cs @@ -0,0 +1,100 @@ +using System; +using System.Collections.Generic; +using Umbraco.Core.Models.Entities; + +namespace Umbraco.Core.Models +{ + public interface IProperty + { + /// + /// Returns the PropertyType, which this Property is based on + /// + IPropertyType PropertyType { get; } + + /// + /// Gets the list of values. + /// + IReadOnlyCollection Values { get; set; } + + /// + /// Returns the Alias of the PropertyType, which this Property is based on + /// + string Alias { get; } + + /// + int Id { get; set; } + + /// + Guid Key { get; set; } + + /// + DateTime CreateDate { get; set; } + + /// + DateTime UpdateDate { get; set; } + + /// + DateTime? DeleteDate { get; set; } // no change tracking - not persisted + + /// + bool HasIdentity { get; } + + /// + /// Gets the value. + /// + object GetValue(string culture = null, string segment = null, bool published = false); + + /// + /// Sets a value. + /// + void SetValue(object value, string culture = null, string segment = null); + + /// + /// Resets the entity identity. + /// + void ResetIdentity(); + + bool Equals(EntityBase other); + bool Equals(object obj); + int GetHashCode(); + object DeepClone(); + + /// + bool IsDirty(); + + /// + bool IsPropertyDirty(string propertyName); + + /// + IEnumerable GetDirtyProperties(); + + /// + /// Saves dirty properties so they can be checked with WasDirty. + void ResetDirtyProperties(); + + /// + bool WasDirty(); + + /// + bool WasPropertyDirty(string propertyName); + + /// + void ResetWereDirtyProperties(); + + /// + void ResetDirtyProperties(bool rememberDirty); + + /// + IEnumerable GetWereDirtyProperties(); + + /// + /// Disables change tracking. + /// + void DisableChangeTracking(); + + /// + /// Enables change tracking. + /// + void EnableChangeTracking(); + } +} diff --git a/src/Umbraco.Abstractions/Models/IPropertyType.cs b/src/Umbraco.Abstractions/Models/IPropertyType.cs new file mode 100644 index 0000000000..4447a858ab --- /dev/null +++ b/src/Umbraco.Abstractions/Models/IPropertyType.cs @@ -0,0 +1,43 @@ +using System; +using System.Runtime.Serialization; +using Umbraco.Core.Models.Entities; + +namespace Umbraco.Core.Models +{ + public interface IPropertyType : IEntity + { + [DataMember] + string Name { get; } + [DataMember] + string Alias { get; } + [DataMember] + string Description { get; } + [DataMember] + int DataTypeId { get; } + [DataMember] + Guid DataTypeKey { get; } + [DataMember] + string PropertyEditorAlias { get; } + [DataMember] + ValueStorageType ValueStorageType { get; } + [DataMember] + Lazy PropertyGroupId { get; } + [DataMember] + bool Mandatory { get; } + [DataMember] + int SortOrder { get; } + [DataMember] + string ValidationRegExp { get; } + + bool SupportsPublishing { get; } + + ContentVariation Variations { get; } + + + + bool SupportsVariation(string culture, string segment, bool wildcards = false); + object ConvertAssignedValue(object value); + + + } +} diff --git a/src/Umbraco.Abstractions/Models/IPropertyValue.cs b/src/Umbraco.Abstractions/Models/IPropertyValue.cs new file mode 100644 index 0000000000..abc459a72f --- /dev/null +++ b/src/Umbraco.Abstractions/Models/IPropertyValue.cs @@ -0,0 +1,34 @@ +namespace Umbraco.Core.Models +{ + public interface IPropertyValue + { + /// + /// Gets or sets the culture of the property. + /// + /// The culture is either null (invariant) or a non-empty string. If the property is + /// set with an empty or whitespace value, its value is converted to null. + string Culture { get; set; } + + /// + /// Gets or sets the segment of the property. + /// + /// The segment is either null (neutral) or a non-empty string. If the property is + /// set with an empty or whitespace value, its value is converted to null. + string Segment { get; set; } + + /// + /// Gets or sets the edited value of the property. + /// + object EditedValue { get; set; } + + /// + /// Gets or sets the published value of the property. + /// + object PublishedValue { get; set; } + + /// + /// Clones the property value. + /// + IPropertyValue Clone(); + } +} diff --git a/src/Umbraco.Core/PropertyEditors/ConfigurationFieldAttribute.cs b/src/Umbraco.Abstractions/PropertyEditors/ConfigurationFieldAttribute.cs similarity index 100% rename from src/Umbraco.Core/PropertyEditors/ConfigurationFieldAttribute.cs rename to src/Umbraco.Abstractions/PropertyEditors/ConfigurationFieldAttribute.cs diff --git a/src/Umbraco.Core/PropertyEditors/GridEditor.cs b/src/Umbraco.Abstractions/PropertyEditors/GridEditor.cs similarity index 68% rename from src/Umbraco.Core/PropertyEditors/GridEditor.cs rename to src/Umbraco.Abstractions/PropertyEditors/GridEditor.cs index 388e79675c..7af72cf5ea 100644 --- a/src/Umbraco.Core/PropertyEditors/GridEditor.cs +++ b/src/Umbraco.Abstractions/PropertyEditors/GridEditor.cs @@ -1,48 +1,37 @@ using System.Collections.Generic; -using Newtonsoft.Json; -using Umbraco.Core.Composing; +using System.Runtime.Serialization; using Umbraco.Core.Configuration.Grid; -using Umbraco.Core.IO; namespace Umbraco.Core.PropertyEditors { + + [DataContract] public class GridEditor : IGridEditorConfig { - private string _view; - private string _render; - public GridEditor() { Config = new Dictionary(); } - [JsonProperty("name", Required = Required.Always)] + [DataMember(Name = "name", IsRequired = true)] public string Name { get; set; } - [JsonProperty("nameTemplate")] + [DataMember(Name = "nameTemplate")] public string NameTemplate { get; set; } - [JsonProperty("alias", Required = Required.Always)] + [DataMember(Name = "alias", IsRequired = true)] public string Alias { get; set; } - [JsonProperty("view", Required = Required.Always)] - public string View - { - get => _view; - set => _view = Current.IOHelper.ResolveVirtualUrl(value); - } + [DataMember(Name = "view", IsRequired = true)] + public string View{ get; set; } - [JsonProperty("render")] - public string Render - { - get => _render; - set => _render = Current.IOHelper.ResolveVirtualUrl(value); - } + [DataMember(Name = "render")] + public string Render { get; set; } - [JsonProperty("icon", Required = Required.Always)] + [DataMember(Name = "icon", IsRequired = true)] public string Icon { get; set; } - [JsonProperty("config")] + [DataMember(Name = "config")] public IDictionary Config { get; set; } protected bool Equals(GridEditor other) diff --git a/src/Umbraco.Core/PropertyEditors/IConfigurationEditor.cs b/src/Umbraco.Abstractions/PropertyEditors/IConfigurationEditor.cs similarity index 100% rename from src/Umbraco.Core/PropertyEditors/IConfigurationEditor.cs rename to src/Umbraco.Abstractions/PropertyEditors/IConfigurationEditor.cs diff --git a/src/Umbraco.Core/CompositionExtensions_Essentials.cs b/src/Umbraco.Core/CompositionExtensions_Essentials.cs index b85479716c..34c9492072 100644 --- a/src/Umbraco.Core/CompositionExtensions_Essentials.cs +++ b/src/Umbraco.Core/CompositionExtensions_Essentials.cs @@ -1,5 +1,6 @@ using Umbraco.Core.Cache; using Umbraco.Core.Composing; +using Umbraco.Core.IO; using Umbraco.Core.Logging; using Umbraco.Core.Persistence; @@ -30,6 +31,7 @@ namespace Umbraco.Core composition.RegisterUnique(factory => factory.GetInstance().SqlContext); composition.RegisterUnique(typeLoader); composition.RegisterUnique(state); + composition.RegisterUnique(); } } } diff --git a/src/Umbraco.Core/ContentVariationExtensions.cs b/src/Umbraco.Core/ContentVariationExtensions.cs index 5b157307ab..bdcf300f3f 100644 --- a/src/Umbraco.Core/ContentVariationExtensions.cs +++ b/src/Umbraco.Core/ContentVariationExtensions.cs @@ -50,18 +50,18 @@ namespace Umbraco.Core /// Determines whether the property type varies by culture. /// /// And then it could also vary by segment. - public static bool VariesByCulture(this PropertyType propertyType) => propertyType.Variations.VariesByCulture(); + public static bool VariesByCulture(this IPropertyType propertyType) => propertyType.Variations.VariesByCulture(); /// /// Determines whether the property type varies by segment. /// /// And then it could also vary by culture. - public static bool VariesBySegment(this PropertyType propertyType) => propertyType.Variations.VariesBySegment(); + public static bool VariesBySegment(this IPropertyType propertyType) => propertyType.Variations.VariesBySegment(); /// /// Determines whether the property type varies by culture and segment. /// - public static bool VariesByCultureAndSegment(this PropertyType propertyType) => propertyType.Variations.VariesByCultureAndSegment(); + public static bool VariesByCultureAndSegment(this IPropertyType propertyType) => propertyType.Variations.VariesByCultureAndSegment(); /// /// Determines whether the content type is invariant. @@ -161,13 +161,13 @@ namespace Umbraco.Core if (variation.VariesByCulture()) { // varies by culture - // in exact mode, the culture cannot be null + // in exact mode, the culture cannot be null if (exact && culture == null) { if (throwIfInvalid) throw new NotSupportedException($"Culture may not be null because culture variation is enabled."); return false; - } + } } else { @@ -180,7 +180,7 @@ namespace Umbraco.Core throw new NotSupportedException($"Culture \"{culture}\" is invalid because culture variation is disabled."); return false; } - } + } // if it does not vary by segment // the segment cannot have a value diff --git a/src/Umbraco.Core/IO/IMediaFileSystem.cs b/src/Umbraco.Core/IO/IMediaFileSystem.cs index ed88516135..8ed0ba60ca 100644 --- a/src/Umbraco.Core/IO/IMediaFileSystem.cs +++ b/src/Umbraco.Core/IO/IMediaFileSystem.cs @@ -52,7 +52,7 @@ namespace Umbraco.Core.IO /// If an is provided then that file (and associated thumbnails if any) is deleted /// before the new file is saved, and depending on the media path scheme, the folder may be reused for the new file. /// - string StoreFile(IContentBase content, PropertyType propertyType, string filename, Stream filestream, string oldpath); + string StoreFile(IContentBase content, IPropertyType propertyType, string filename, Stream filestream, string oldpath); /// /// Copies a media file as a new media file, associated to a property of a content item. @@ -61,6 +61,6 @@ namespace Umbraco.Core.IO /// The property type owning the copy of the media file. /// The filesystem-relative path to the source media file. /// The filesystem-relative path to the copy of the media file. - string CopyFile(IContentBase content, PropertyType propertyType, string sourcepath); + string CopyFile(IContentBase content, IPropertyType propertyType, string sourcepath); } } diff --git a/src/Umbraco.Core/IO/MediaFileSystem.cs b/src/Umbraco.Core/IO/MediaFileSystem.cs index 2de7bc2f81..edcbfadf0d 100644 --- a/src/Umbraco.Core/IO/MediaFileSystem.cs +++ b/src/Umbraco.Core/IO/MediaFileSystem.cs @@ -88,7 +88,7 @@ namespace Umbraco.Core.IO #region Associated Media Files /// - public string StoreFile(IContentBase content, PropertyType propertyType, string filename, Stream filestream, string oldpath) + public string StoreFile(IContentBase content, IPropertyType propertyType, string filename, Stream filestream, string oldpath) { if (content == null) throw new ArgumentNullException(nameof(content)); if (propertyType == null) throw new ArgumentNullException(nameof(propertyType)); @@ -107,7 +107,7 @@ namespace Umbraco.Core.IO } /// - public string CopyFile(IContentBase content, PropertyType propertyType, string sourcepath) + public string CopyFile(IContentBase content, IPropertyType propertyType, string sourcepath) { if (content == null) throw new ArgumentNullException(nameof(content)); if (propertyType == null) throw new ArgumentNullException(nameof(propertyType)); diff --git a/src/Umbraco.Core/Manifest/DataEditorConverter.cs b/src/Umbraco.Core/Manifest/DataEditorConverter.cs index 86982e17f2..86347d3894 100644 --- a/src/Umbraco.Core/Manifest/DataEditorConverter.cs +++ b/src/Umbraco.Core/Manifest/DataEditorConverter.cs @@ -1,6 +1,8 @@ using System; using Newtonsoft.Json; using Newtonsoft.Json.Linq; +using Umbraco.Core.Composing; +using Umbraco.Core.IO; using Umbraco.Core.Logging; using Umbraco.Core.PropertyEditors; using Umbraco.Core.Serialization; @@ -13,13 +15,15 @@ namespace Umbraco.Core.Manifest internal class DataEditorConverter : JsonReadConverter { private readonly ILogger _logger; + private readonly IIOHelper _ioHelper; /// /// Initializes a new instance of the class. /// - public DataEditorConverter(ILogger logger) + public DataEditorConverter(ILogger logger, IIOHelper ioHelper) { _logger = logger; + _ioHelper = ioHelper; } /// @@ -62,11 +66,11 @@ namespace Umbraco.Core.Manifest PrepareForPropertyEditor(jobject, dataEditor); else PrepareForParameterEditor(jobject, dataEditor); - + base.Deserialize(jobject, target, serializer); } - private static void PrepareForPropertyEditor(JObject jobject, DataEditor target) + private void PrepareForPropertyEditor(JObject jobject, DataEditor target) { if (jobject["editor"] == null) throw new InvalidOperationException("Missing 'editor' value."); @@ -86,6 +90,9 @@ namespace Umbraco.Core.Manifest if (jobject["editor"]["validation"] is JObject validation) jobject["editor"]["validation"] = RewriteValidators(validation); + if(jobject["editor"]["view"] is JValue view) + jobject["editor"]["view"] = RewriteVirtualUrl(view); + if (jobject["prevalues"] is JObject config) { // explicitly assign a configuration editor of type ConfigurationEditor @@ -100,6 +107,9 @@ namespace Umbraco.Core.Manifest { if (field["validation"] is JObject fvalidation) field["validation"] = RewriteValidators(fvalidation); + + if(field["view"] is JValue fview) + field["view"] = RewriteVirtualUrl(fview); } } @@ -118,7 +128,12 @@ namespace Umbraco.Core.Manifest } } - private static void PrepareForParameterEditor(JObject jobject, DataEditor target) + private string RewriteVirtualUrl(JValue view) + { + return _ioHelper.ResolveVirtualUrl(view.Value as string); + } + + private void PrepareForParameterEditor(JObject jobject, DataEditor target) { // in a manifest, a parameter editor looks like: // @@ -148,6 +163,9 @@ namespace Umbraco.Core.Manifest jobject["defaultConfig"] = config; jobject.Remove("config"); } + + if(jobject["editor"]?["view"] is JValue view) // We need to null check, if view do not exists, then editor do not exists + jobject["editor"]["view"] = RewriteVirtualUrl(view); } private static JArray RewriteValidators(JObject validation) diff --git a/src/Umbraco.Core/Manifest/ManifestDashboard.cs b/src/Umbraco.Core/Manifest/ManifestDashboard.cs index 33af12e3cd..2642ca3646 100644 --- a/src/Umbraco.Core/Manifest/ManifestDashboard.cs +++ b/src/Umbraco.Core/Manifest/ManifestDashboard.cs @@ -9,8 +9,6 @@ namespace Umbraco.Core.Manifest { public class ManifestDashboard : IDashboard { - private string _view; - [JsonProperty("alias", Required = Required.Always)] public string Alias { get; set; } @@ -19,11 +17,7 @@ namespace Umbraco.Core.Manifest public int Weight { get; set; } [JsonProperty("view", Required = Required.Always)] - public string View - { - get => _view; - set => _view = Current.IOHelper.ResolveVirtualUrl(value); - } + public string View { get; set; } [JsonProperty("sections")] public string[] Sections { get; set; } = Array.Empty(); diff --git a/src/Umbraco.Core/Manifest/ManifestParser.cs b/src/Umbraco.Core/Manifest/ManifestParser.cs index 7f2a1825b4..bf70def9dc 100644 --- a/src/Umbraco.Core/Manifest/ManifestParser.cs +++ b/src/Umbraco.Core/Manifest/ManifestParser.cs @@ -163,7 +163,7 @@ namespace Umbraco.Core.Manifest throw new ArgumentNullOrEmptyException(nameof(text)); var manifest = JsonConvert.DeserializeObject(text, - new DataEditorConverter(_logger), + new DataEditorConverter(_logger, _ioHelper), new ValueValidatorConverter(_validators), new DashboardAccessRuleConverter()); @@ -172,6 +172,19 @@ namespace Umbraco.Core.Manifest manifest.Scripts[i] = _ioHelper.ResolveVirtualUrl(manifest.Scripts[i]); for (var i = 0; i < manifest.Stylesheets.Length; i++) manifest.Stylesheets[i] = _ioHelper.ResolveVirtualUrl(manifest.Stylesheets[i]); + foreach (var contentApp in manifest.ContentApps) + { + contentApp.View = _ioHelper.ResolveVirtualUrl(contentApp.View); + } + foreach (var dashboard in manifest.Dashboards) + { + dashboard.View = _ioHelper.ResolveVirtualUrl(dashboard.View); + } + foreach (var gridEditor in manifest.GridEditors) + { + gridEditor.View = _ioHelper.ResolveVirtualUrl(gridEditor.View); + gridEditor.Render = _ioHelper.ResolveVirtualUrl(gridEditor.Render); + } // add property editors that are also parameter editors, to the parameter editors list // (the manifest format is kinda legacy) diff --git a/src/Umbraco.Core/Models/IDataValueEditor.cs b/src/Umbraco.Core/Models/IDataValueEditor.cs index cb68531cc7..5a1c6fd29d 100644 --- a/src/Umbraco.Core/Models/IDataValueEditor.cs +++ b/src/Umbraco.Core/Models/IDataValueEditor.cs @@ -59,12 +59,12 @@ namespace Umbraco.Core.PropertyEditors /// /// Converts a property value to a value for the editor. /// - object ToEditor(Property property, IDataTypeService dataTypeService, string culture = null, string segment = null); + object ToEditor(IProperty property, IDataTypeService dataTypeService, string culture = null, string segment = null); // TODO: / deal with this when unplugging the xml cache // why property vs propertyType? services should be injected! etc... - IEnumerable ConvertDbToXml(Property property, IDataTypeService dataTypeService, ILocalizationService localizationService, bool published); - XNode ConvertDbToXml(PropertyType propertyType, object value, IDataTypeService dataTypeService); - string ConvertDbToString(PropertyType propertyType, object value, IDataTypeService dataTypeService); + IEnumerable ConvertDbToXml(IProperty property, IDataTypeService dataTypeService, ILocalizationService localizationService, bool published); + XNode ConvertDbToXml(IPropertyType propertyType, object value, IDataTypeService dataTypeService); + string ConvertDbToString(IPropertyType propertyType, object value, IDataTypeService dataTypeService); } } diff --git a/src/Umbraco.Core/Models/Property.cs b/src/Umbraco.Core/Models/Property.cs index 76349823ac..9b2cda67c1 100644 --- a/src/Umbraco.Core/Models/Property.cs +++ b/src/Umbraco.Core/Models/Property.cs @@ -13,16 +13,16 @@ namespace Umbraco.Core.Models /// [Serializable] [DataContract(IsReference = true)] - public class Property : EntityBase + public class Property : EntityBase, IProperty { // _values contains all property values, including the invariant-neutral value - private List _values = new List(); + private List _values = new List(); // _pvalue contains the invariant-neutral property value - private PropertyValue _pvalue; + private IPropertyValue _pvalue; // _vvalues contains the (indexed) variant property values - private Dictionary _vvalues; + private Dictionary _vvalues; /// /// Initializes a new instance of the class. @@ -50,7 +50,7 @@ namespace Umbraco.Core.Models /// /// Represents a property value. /// - public class PropertyValue + public class PropertyValue : IPropertyValue { // TODO: Either we allow change tracking at this class level, or we add some special change tracking collections to the Property // class to deal with change tracking which variants have changed @@ -66,7 +66,7 @@ namespace Umbraco.Core.Models public string Culture { get => _culture; - internal set => _culture = value.IsNullOrWhiteSpace() ? null : value.ToLowerInvariant(); + set => _culture = value.IsNullOrWhiteSpace() ? null : value.ToLowerInvariant(); } /// @@ -77,23 +77,23 @@ namespace Umbraco.Core.Models public string Segment { get => _segment; - internal set => _segment = value?.ToLowerInvariant(); + set => _segment = value?.ToLowerInvariant(); } /// /// Gets or sets the edited value of the property. /// - public object EditedValue { get; internal set; } + public object EditedValue { get; set; } /// /// Gets or sets the published value of the property. /// - public object PublishedValue { get; internal set; } + public object PublishedValue { get; set; } /// /// Clones the property value. /// - public PropertyValue Clone() + public IPropertyValue Clone() => new PropertyValue { _culture = _culture, _segment = _segment, PublishedValue = PublishedValue, EditedValue = EditedValue }; } @@ -121,13 +121,13 @@ namespace Umbraco.Core.Models /// Returns the PropertyType, which this Property is based on /// [IgnoreDataMember] - public PropertyType PropertyType { get; private set; } + public IPropertyType PropertyType { get; private set; } /// /// Gets the list of values. /// [DataMember] - public IReadOnlyCollection Values + public IReadOnlyCollection Values { get => _values; set @@ -180,7 +180,7 @@ namespace Umbraco.Core.Models : null; } - private object GetPropertyValue(PropertyValue pvalue, bool published) + private object GetPropertyValue(IPropertyValue pvalue, bool published) { if (pvalue == null) return null; @@ -240,7 +240,7 @@ namespace Umbraco.Core.Models UnpublishValue(pvalue); } - private void PublishValue(PropertyValue pvalue) + private void PublishValue(IPropertyValue pvalue) { if (pvalue == null) return; @@ -251,7 +251,7 @@ namespace Umbraco.Core.Models DetectChanges(pvalue.EditedValue, origValue, nameof(Values), PropertyValueComparer, false); } - private void UnpublishValue(PropertyValue pvalue) + private void UnpublishValue(IPropertyValue pvalue) { if (pvalue == null) return; @@ -294,7 +294,7 @@ namespace Umbraco.Core.Models pvalue.EditedValue = value; } - private (PropertyValue, bool) GetPValue(bool create) + private (IPropertyValue, bool) GetPValue(bool create) { var change = false; if (_pvalue == null) @@ -307,7 +307,7 @@ namespace Umbraco.Core.Models return (_pvalue, change); } - private (PropertyValue, bool) GetPValue(string culture, string segment, bool create) + private (IPropertyValue, bool) GetPValue(string culture, string segment, bool create) { if (culture == null && segment == null) return GetPValue(create); @@ -316,7 +316,7 @@ namespace Umbraco.Core.Models if (_vvalues == null) { if (!create) return (null, false); - _vvalues = new Dictionary(); + _vvalues = new Dictionary(); change = true; } var k = new CompositeNStringNStringKey(culture, segment); diff --git a/src/Umbraco.Core/Models/PropertyType.cs b/src/Umbraco.Core/Models/PropertyType.cs index 40af478ab8..1448e099be 100644 --- a/src/Umbraco.Core/Models/PropertyType.cs +++ b/src/Umbraco.Core/Models/PropertyType.cs @@ -13,7 +13,7 @@ namespace Umbraco.Core.Models [Serializable] [DataContract(IsReference = true)] [DebuggerDisplay("Id: {Id}, Name: {Name}, Alias: {Alias}")] - public class PropertyType : EntityBase, IEquatable + public class PropertyType : EntityBase, IPropertyType, IEquatable { private readonly bool _forceValueStorageType; private string _name; @@ -160,7 +160,7 @@ namespace Umbraco.Core.Models /// Gets or sets the database type for storing value for this property type. /// [DataMember] - internal ValueStorageType ValueStorageType + public ValueStorageType ValueStorageType { get => _valueStorageType; set @@ -175,7 +175,7 @@ namespace Umbraco.Core.Models /// /// For generic properties, the value is null. [DataMember] - internal Lazy PropertyGroupId + public Lazy PropertyGroupId { get => _propertyGroupId; set => SetPropertyValueAndDetectChanges(value, ref _propertyGroupId, nameof(PropertyGroupId)); diff --git a/src/Umbraco.Core/PropertyEditors/ConfigurationFieldsExtensions.cs b/src/Umbraco.Core/PropertyEditors/ConfigurationFieldsExtensions.cs deleted file mode 100644 index 25fba622d5..0000000000 --- a/src/Umbraco.Core/PropertyEditors/ConfigurationFieldsExtensions.cs +++ /dev/null @@ -1,34 +0,0 @@ -using System.Collections.Generic; - -namespace Umbraco.Core.PropertyEditors -{ - public static partial class ConfigurationFieldsExtensions - { - /// - /// Adds a configuration field. - /// - /// The list of configuration fields. - /// The key (alias) of the field. - /// The name (label) of the field. - /// The description for the field. - /// The path to the editor view to be used for the field. - /// Optional configuration used for field's editor. - public static void Add( - this List fields, - string key, - string name, - string description, - string view, - IDictionary config = null) - { - fields.Add(new ConfigurationField - { - Key = key, - Name = name, - Description = description, - View = view, - Config = config, - }); - } - } -} diff --git a/src/Umbraco.Core/PropertyEditors/DataValueEditor.cs b/src/Umbraco.Core/PropertyEditors/DataValueEditor.cs index a9ce27d964..396d32c833 100644 --- a/src/Umbraco.Core/PropertyEditors/DataValueEditor.cs +++ b/src/Umbraco.Core/PropertyEditors/DataValueEditor.cs @@ -7,7 +7,6 @@ using System.Xml.Linq; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using Umbraco.Core.Composing; -using Umbraco.Core.IO; using Umbraco.Core.Logging; using Umbraco.Core.Models; using Umbraco.Core.Models.Editors; @@ -72,11 +71,7 @@ namespace Umbraco.Core.PropertyEditors /// folder, or (3) a view name which maps to views/propertyeditors/{view}/{view}.html. /// [JsonProperty("view", Required = Required.Always)] - public string View - { - get => _view; - set => _view = Current.IOHelper.ResolveVirtualUrl(value); - } + public string View { get; set; } /// /// The value type which reflects how it is validated and stored in the database @@ -237,7 +232,7 @@ namespace Umbraco.Core.PropertyEditors /// The object returned will automatically be serialized into json notation. For most property editors /// the value returned is probably just a string but in some cases a json structure will be returned. /// - public virtual object ToEditor(Property property, IDataTypeService dataTypeService, string culture = null, string segment = null) + public virtual object ToEditor(IProperty property, IDataTypeService dataTypeService, string culture = null, string segment = null) { var val = property.GetValue(culture, segment); if (val == null) return string.Empty; @@ -288,7 +283,7 @@ namespace Umbraco.Core.PropertyEditors /// /// Converts a property to Xml fragments. /// - public IEnumerable ConvertDbToXml(Property property, IDataTypeService dataTypeService, ILocalizationService localizationService, bool published) + public IEnumerable ConvertDbToXml(IProperty property, IDataTypeService dataTypeService, ILocalizationService localizationService, bool published) { published &= property.PropertyType.SupportsPublishing; @@ -322,7 +317,7 @@ namespace Umbraco.Core.PropertyEditors /// Returns an XText or XCData instance which must be wrapped in a element. /// If the value is empty we will not return as CDATA since that will just take up more space in the file. /// - public XNode ConvertDbToXml(PropertyType propertyType, object value, IDataTypeService dataTypeService) + public XNode ConvertDbToXml(IPropertyType propertyType, object value, IDataTypeService dataTypeService) { //check for null or empty value, we don't want to return CDATA if that is the case if (value == null || value.ToString().IsNullOrWhiteSpace()) @@ -348,7 +343,7 @@ namespace Umbraco.Core.PropertyEditors /// /// Converts a property value to a string. /// - public virtual string ConvertDbToString(PropertyType propertyType, object value, IDataTypeService dataTypeService) + public virtual string ConvertDbToString(IPropertyType propertyType, object value, IDataTypeService dataTypeService) { if (value == null) return string.Empty; diff --git a/src/Umbraco.Core/Services/PropertyValidationService.cs b/src/Umbraco.Core/Services/PropertyValidationService.cs index a037a83920..f619e5f47e 100644 --- a/src/Umbraco.Core/Services/PropertyValidationService.cs +++ b/src/Umbraco.Core/Services/PropertyValidationService.cs @@ -74,7 +74,7 @@ namespace Umbraco.Core.Services culture = culture.NullOrWhiteSpaceAsNull(); segment = segment.NullOrWhiteSpaceAsNull(); - Property.PropertyValue pvalue = null; + IPropertyValue pvalue = null; // if validating invariant/neutral, and it is supported, validate // (including ensuring that the value exists, if mandatory) @@ -120,7 +120,7 @@ namespace Umbraco.Core.Services /// /// /// True is property value is valid, otherwise false - private bool IsValidPropertyValue(Property property, object value) + private bool IsValidPropertyValue(IProperty property, object value) { return IsPropertyValueValid(property.PropertyType, value); } @@ -128,7 +128,7 @@ namespace Umbraco.Core.Services /// /// Determines whether a value is valid for this property type. /// - private bool IsPropertyValueValid(PropertyType propertyType, object value) + private bool IsPropertyValueValid(IPropertyType propertyType, object value) { var editor = _propertyEditors[propertyType.PropertyEditorAlias]; if (editor == null) diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index f22a29075f..45e25d9a8f 100755 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -36,7 +36,6 @@ - @@ -65,11 +64,14 @@ all - 1.3.0 + 1.4.0 1.0.0 + + 4.6.0 + 1.0.5 runtime; build; native; contentfiles; analyzers @@ -91,19 +93,19 @@ - 2.8.0 + 2.9.0 2.0.1 - 3.0.0 + 3.1.0 2.0.0 - 1.0.0 + 1.1.0 1.0.3 @@ -112,7 +114,7 @@ 2.2.2 - 4.0.0 + 4.1.0 @@ -270,7 +272,6 @@ - @@ -282,8 +283,6 @@ - - @@ -483,7 +482,6 @@ - @@ -1000,7 +998,6 @@ - diff --git a/src/Umbraco.ModelsBuilder.Embedded/Umbraco.ModelsBuilder.Embedded.csproj b/src/Umbraco.ModelsBuilder.Embedded/Umbraco.ModelsBuilder.Embedded.csproj index 67919834ac..eb61e2a2c8 100644 --- a/src/Umbraco.ModelsBuilder.Embedded/Umbraco.ModelsBuilder.Embedded.csproj +++ b/src/Umbraco.ModelsBuilder.Embedded/Umbraco.ModelsBuilder.Embedded.csproj @@ -34,7 +34,6 @@ - @@ -97,6 +96,9 @@ runtime; build; native; contentfiles; analyzers; buildtransitive all + + 4.6.0 + diff --git a/src/Umbraco.Tests/App.config b/src/Umbraco.Tests/App.config index 91047ba6a2..9eeb93384d 100644 --- a/src/Umbraco.Tests/App.config +++ b/src/Umbraco.Tests/App.config @@ -94,6 +94,10 @@ + + + + diff --git a/src/Umbraco.Tests/Models/PropertyTypeTests.cs b/src/Umbraco.Tests/Models/PropertyTypeTests.cs index 1bc99162af..b4d14e7bb5 100644 --- a/src/Umbraco.Tests/Models/PropertyTypeTests.cs +++ b/src/Umbraco.Tests/Models/PropertyTypeTests.cs @@ -54,7 +54,15 @@ namespace Umbraco.Tests.Models var allProps = clone.GetType().GetProperties(); foreach (var propertyInfo in allProps) { - Assert.AreEqual(propertyInfo.GetValue(clone, null), propertyInfo.GetValue(pt, null)); + var expected = propertyInfo.GetValue(pt, null); + var actual = propertyInfo.GetValue(clone, null); + if (propertyInfo.PropertyType == typeof(Lazy)) + { + expected = ((Lazy) expected).Value; + actual = ((Lazy) actual).Value; + } + + Assert.AreEqual(expected, actual, $"Value of propery: '{propertyInfo.Name}': {expected} != {actual}"); } } diff --git a/src/Umbraco.Tests/Testing/UmbracoTestBase.cs b/src/Umbraco.Tests/Testing/UmbracoTestBase.cs index b9fd0f6640..149d48032b 100644 --- a/src/Umbraco.Tests/Testing/UmbracoTestBase.cs +++ b/src/Umbraco.Tests/Testing/UmbracoTestBase.cs @@ -219,6 +219,7 @@ namespace Umbraco.Tests.Testing Composition.RegisterUnique(); Composition.RegisterUnique(); Composition.RegisterUnique(); + Composition.RegisterUnique(); // register back office sections in the order we want them rendered Composition.WithCollectionBuilder().Append() diff --git a/src/Umbraco.Tests/Umbraco.Tests.csproj b/src/Umbraco.Tests/Umbraco.Tests.csproj index de76b94ff1..1292d2da2e 100644 --- a/src/Umbraco.Tests/Umbraco.Tests.csproj +++ b/src/Umbraco.Tests/Umbraco.Tests.csproj @@ -56,7 +56,6 @@ - @@ -107,6 +106,7 @@ + diff --git a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj index f2976716bb..a2ce0f95f7 100644 --- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj +++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj @@ -70,7 +70,6 @@ - @@ -110,6 +109,7 @@ runtime; build; native; contentfiles; analyzers all + @@ -432,4 +432,4 @@ - + \ No newline at end of file diff --git a/src/Umbraco.Web/PropertyEditors/DateValueEditor.cs b/src/Umbraco.Web/PropertyEditors/DateValueEditor.cs index a03ad4aa00..657e2b2b49 100644 --- a/src/Umbraco.Web/PropertyEditors/DateValueEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/DateValueEditor.cs @@ -18,7 +18,7 @@ namespace Umbraco.Web.PropertyEditors Validators.Add(new DateTimeValidator()); } - public override object ToEditor(Property property, IDataTypeService dataTypeService, string culture= null, string segment = null) + public override object ToEditor(IProperty property, IDataTypeService dataTypeService, string culture= null, string segment = null) { var date = property.GetValue(culture, segment).TryConvertTo(); if (date.Success == false || date.Result == null) diff --git a/src/Umbraco.Web/PropertyEditors/GridPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/GridPropertyEditor.cs index 24e2fc29a5..5964964ab7 100644 --- a/src/Umbraco.Web/PropertyEditors/GridPropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/GridPropertyEditor.cs @@ -115,7 +115,7 @@ namespace Umbraco.Web.PropertyEditors /// /// /// - public override object ToEditor(Property property, IDataTypeService dataTypeService, string culture = null, string segment = null) + public override object ToEditor(IProperty property, IDataTypeService dataTypeService, string culture = null, string segment = null) { var val = property.GetValue(culture, segment); if (val == null) return string.Empty; diff --git a/src/Umbraco.Web/PropertyEditors/ImageCropperPropertyValueEditor.cs b/src/Umbraco.Web/PropertyEditors/ImageCropperPropertyValueEditor.cs index 4aac8f54aa..fdeb726902 100644 --- a/src/Umbraco.Web/PropertyEditors/ImageCropperPropertyValueEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/ImageCropperPropertyValueEditor.cs @@ -32,7 +32,7 @@ namespace Umbraco.Web.PropertyEditors /// This is called to merge in the prevalue crops with the value that is saved - similar to the property value converter for the front-end /// - public override object ToEditor(Property property, IDataTypeService dataTypeService, string culture = null, string segment = null) + public override object ToEditor(IProperty property, IDataTypeService dataTypeService, string culture = null, string segment = null) { var val = property.GetValue(culture, segment); if (val == null) return null; @@ -161,7 +161,7 @@ namespace Umbraco.Web.PropertyEditors } - public override string ConvertDbToString(PropertyType propertyType, object value, IDataTypeService dataTypeService) + public override string ConvertDbToString(IPropertyType propertyType, object value, IDataTypeService dataTypeService) { if (value == null || string.IsNullOrEmpty(value.ToString())) return null; diff --git a/src/Umbraco.Web/PropertyEditors/MultiUrlPickerValueEditor.cs b/src/Umbraco.Web/PropertyEditors/MultiUrlPickerValueEditor.cs index aa8fa73c7a..c2ad58a101 100644 --- a/src/Umbraco.Web/PropertyEditors/MultiUrlPickerValueEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/MultiUrlPickerValueEditor.cs @@ -28,7 +28,7 @@ namespace Umbraco.Web.PropertyEditors _logger = logger ?? throw new ArgumentNullException(nameof(logger)); } - public override object ToEditor(Property property, IDataTypeService dataTypeService, string culture = null, string segment = null) + public override object ToEditor(IProperty property, IDataTypeService dataTypeService, string culture = null, string segment = null) { var value = property.GetValue(culture, segment)?.ToString(); diff --git a/src/Umbraco.Web/PropertyEditors/MultipleTextStringPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/MultipleTextStringPropertyEditor.cs index fa82bc555c..23ceb0f22a 100644 --- a/src/Umbraco.Web/PropertyEditors/MultipleTextStringPropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/MultipleTextStringPropertyEditor.cs @@ -95,7 +95,7 @@ namespace Umbraco.Web.PropertyEditors /// /// The legacy property editor saved this data as new line delimited! strange but we have to maintain that. /// - public override object ToEditor(Property property, IDataTypeService dataTypeService, string culture = null, string segment = null) + public override object ToEditor(IProperty property, IDataTypeService dataTypeService, string culture = null, string segment = null) { var val = property.GetValue(culture, segment); return val?.ToString().Split(new[] {Environment.NewLine}, StringSplitOptions.RemoveEmptyEntries) diff --git a/src/Umbraco.Web/PropertyEditors/MultipleValueEditor.cs b/src/Umbraco.Web/PropertyEditors/MultipleValueEditor.cs index bbeaff184e..4c59a8e3c5 100644 --- a/src/Umbraco.Web/PropertyEditors/MultipleValueEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/MultipleValueEditor.cs @@ -33,7 +33,7 @@ namespace Umbraco.Web.PropertyEditors /// /// /// - public override object ToEditor(Property property, IDataTypeService dataTypeService, string culture = null, string segment = null) + public override object ToEditor(IProperty property, IDataTypeService dataTypeService, string culture = null, string segment = null) { var json = base.ToEditor(property, dataTypeService, culture, segment).ToString(); return JsonConvert.DeserializeObject(json) ?? Array.Empty(); diff --git a/src/Umbraco.Web/PropertyEditors/NestedContentPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/NestedContentPropertyEditor.cs index f511a97cac..778b69d9db 100644 --- a/src/Umbraco.Web/PropertyEditors/NestedContentPropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/NestedContentPropertyEditor.cs @@ -92,7 +92,7 @@ namespace Umbraco.Web.PropertyEditors #region DB to String - public override string ConvertDbToString(PropertyType propertyType, object propertyValue, IDataTypeService dataTypeService) + public override string ConvertDbToString(IPropertyType propertyType, object propertyValue, IDataTypeService dataTypeService) { if (propertyValue == null || string.IsNullOrWhiteSpace(propertyValue.ToString())) return string.Empty; @@ -152,7 +152,7 @@ namespace Umbraco.Web.PropertyEditors // note: there is NO variant support here - public override object ToEditor(Property property, IDataTypeService dataTypeService, string culture = null, string segment = null) + public override object ToEditor(IProperty property, IDataTypeService dataTypeService, string culture = null, string segment = null) { var val = property.GetValue(culture, segment); if (val == null || string.IsNullOrWhiteSpace(val.ToString())) diff --git a/src/Umbraco.Web/PropertyEditors/RichTextPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/RichTextPropertyEditor.cs index 5743e9c1d5..03345bee3c 100644 --- a/src/Umbraco.Web/PropertyEditors/RichTextPropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/RichTextPropertyEditor.cs @@ -92,7 +92,7 @@ namespace Umbraco.Web.PropertyEditors /// /// /// - public override object ToEditor(Property property, IDataTypeService dataTypeService, string culture = null, string segment = null) + public override object ToEditor(IProperty property, IDataTypeService dataTypeService, string culture = null, string segment = null) { var val = property.GetValue(culture, segment); if (val == null) diff --git a/src/Umbraco.Web/PropertyEditors/TextOnlyValueEditor.cs b/src/Umbraco.Web/PropertyEditors/TextOnlyValueEditor.cs index 754cef1f31..f925daba30 100644 --- a/src/Umbraco.Web/PropertyEditors/TextOnlyValueEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/TextOnlyValueEditor.cs @@ -26,7 +26,7 @@ namespace Umbraco.Web.PropertyEditors /// /// The object returned will always be a string and if the database type is not a valid string type an exception is thrown /// - public override object ToEditor(Property property, IDataTypeService dataTypeService, string culture = null, string segment = null) + public override object ToEditor(IProperty property, IDataTypeService dataTypeService, string culture = null, string segment = null) { var val = property.GetValue(culture, segment); diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index 317786b970..bede1a1a6d 100755 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -41,7 +41,6 @@ - @@ -1282,4 +1281,4 @@ - \ No newline at end of file + From c285a163932b8a2958757106b3a37ebc9f93fe27 Mon Sep 17 00:00:00 2001 From: Bjarke Berg Date: Fri, 8 Nov 2019 14:30:46 +0100 Subject: [PATCH 37/68] AB3649 - Moved more stuff --- .../PropertyEditors/ConfigurationField.cs | 28 ++++++++----------- .../IPropertyIndexValueFactory.cs | 2 +- .../ConfigurationEditorOfTConfiguration.cs | 5 ++-- .../DefaultPropertyIndexValueFactory.cs | 2 +- src/Umbraco.Core/Umbraco.Core.csproj | 1 - .../GridPropertyIndexValueFactory.cs | 2 +- .../PropertyEditors/RichTextPropertyEditor.cs | 2 +- 7 files changed, 18 insertions(+), 24 deletions(-) rename src/{Umbraco.Core => Umbraco.Abstractions}/PropertyEditors/ConfigurationField.cs (83%) rename src/{Umbraco.Core => Umbraco.Abstractions}/PropertyEditors/IPropertyIndexValueFactory.cs (92%) diff --git a/src/Umbraco.Core/PropertyEditors/ConfigurationField.cs b/src/Umbraco.Abstractions/PropertyEditors/ConfigurationField.cs similarity index 83% rename from src/Umbraco.Core/PropertyEditors/ConfigurationField.cs rename to src/Umbraco.Abstractions/PropertyEditors/ConfigurationField.cs index ee07f8dcef..52df839712 100644 --- a/src/Umbraco.Core/PropertyEditors/ConfigurationField.cs +++ b/src/Umbraco.Abstractions/PropertyEditors/ConfigurationField.cs @@ -1,15 +1,15 @@ using System; using System.Collections.Generic; using System.Linq; -using Newtonsoft.Json; -using Umbraco.Core.Composing; -using Umbraco.Core.IO; +using System.Reflection; +using System.Runtime.Serialization; namespace Umbraco.Core.PropertyEditors { /// /// Represents a datatype configuration field for editing. /// + [DataContract] public class ConfigurationField { private string _view; @@ -50,37 +50,35 @@ namespace Umbraco.Core.PropertyEditors /// /// Gets or sets the key of the field. /// - [JsonProperty("key", Required = Required.Always)] + [DataMember(Name = "key", IsRequired = true)] public string Key { get; set; } /// /// Gets or sets the name of the field. /// - [JsonProperty("label", Required = Required.Always)] + [DataMember(Name = "label", IsRequired = true)] public string Name { get; set; } /// /// Gets or sets the property name of the field. /// - [JsonIgnore] public string PropertyName { get; set; } /// /// Gets or sets the property CLR type of the field. /// - [JsonIgnore] public Type PropertyType { get; set; } /// /// Gets or sets the description of the field. /// - [JsonProperty("description")] + [DataMember(Name = "description")] public string Description { get; set; } /// /// Gets or sets a value indicating whether to hide the label of the field. /// - [JsonProperty("hideLabel")] + [DataMember(Name = "hideLabel")] public bool HideLabel { get; set; } /// @@ -90,23 +88,19 @@ namespace Umbraco.Core.PropertyEditors /// Can be the full virtual path, or the relative path to the Umbraco folder, /// or a simple view name which will map to ~/Views/PreValueEditors/{view}.html. /// - [JsonProperty("view", Required = Required.Always)] - public string View - { - get => _view; - set => _view = Current.IOHelper.ResolveVirtualUrl(value); - } + [DataMember(Name = "view", IsRequired = true)] + public string View { get; set; } /// /// Gets the validators of the field. /// - [JsonProperty("validation")] + [DataMember(Name = "validation")] public List Validators { get; } /// /// Gets or sets extra configuration properties for the editor. /// - [JsonProperty("config")] + [DataMember(Name = "config")] public IDictionary Config { get; set; } } } diff --git a/src/Umbraco.Core/PropertyEditors/IPropertyIndexValueFactory.cs b/src/Umbraco.Abstractions/PropertyEditors/IPropertyIndexValueFactory.cs similarity index 92% rename from src/Umbraco.Core/PropertyEditors/IPropertyIndexValueFactory.cs rename to src/Umbraco.Abstractions/PropertyEditors/IPropertyIndexValueFactory.cs index fd4e272f08..26552afc6f 100644 --- a/src/Umbraco.Core/PropertyEditors/IPropertyIndexValueFactory.cs +++ b/src/Umbraco.Abstractions/PropertyEditors/IPropertyIndexValueFactory.cs @@ -19,6 +19,6 @@ namespace Umbraco.Core.PropertyEditors /// values. By default, there would be only one object: the property value. But some implementations may return /// more than one value for a given field. /// - IEnumerable>> GetIndexValues(Property property, string culture, string segment, bool published); + IEnumerable>> GetIndexValues(IProperty property, string culture, string segment, bool published); } } diff --git a/src/Umbraco.Core/PropertyEditors/ConfigurationEditorOfTConfiguration.cs b/src/Umbraco.Core/PropertyEditors/ConfigurationEditorOfTConfiguration.cs index 7008c73433..bee923b50e 100644 --- a/src/Umbraco.Core/PropertyEditors/ConfigurationEditorOfTConfiguration.cs +++ b/src/Umbraco.Core/PropertyEditors/ConfigurationEditorOfTConfiguration.cs @@ -35,6 +35,7 @@ namespace Umbraco.Core.PropertyEditors ConfigurationField field; + var attributeView = Current.IOHelper.ResolveVirtualUrl(attribute.View); // if the field does not have its own type, use the base type if (attribute.Type == null) { @@ -47,7 +48,7 @@ namespace Umbraco.Core.PropertyEditors PropertyType = property.PropertyType, Description = attribute.Description, HideLabel = attribute.HideLabel, - View = attribute.View + View = attributeView }; fields.Add(field); @@ -81,7 +82,7 @@ namespace Umbraco.Core.PropertyEditors field.Name = attribute.Name; if (!string.IsNullOrWhiteSpace(attribute.View)) - field.View = attribute.View; + field.View = attributeView; if (!string.IsNullOrWhiteSpace(attribute.Description)) field.Description = attribute.Description; diff --git a/src/Umbraco.Core/PropertyEditors/DefaultPropertyIndexValueFactory.cs b/src/Umbraco.Core/PropertyEditors/DefaultPropertyIndexValueFactory.cs index 413f31d79e..0d06b59a9c 100644 --- a/src/Umbraco.Core/PropertyEditors/DefaultPropertyIndexValueFactory.cs +++ b/src/Umbraco.Core/PropertyEditors/DefaultPropertyIndexValueFactory.cs @@ -9,7 +9,7 @@ namespace Umbraco.Core.PropertyEditors public class DefaultPropertyIndexValueFactory : IPropertyIndexValueFactory { /// - public IEnumerable>> GetIndexValues(Property property, string culture, string segment, bool published) + public IEnumerable>> GetIndexValues(IProperty property, string culture, string segment, bool published) { yield return new KeyValuePair>( property.Alias, diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index 45e25d9a8f..75e79b8fe0 100755 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -287,7 +287,6 @@ - diff --git a/src/Umbraco.Web/PropertyEditors/GridPropertyIndexValueFactory.cs b/src/Umbraco.Web/PropertyEditors/GridPropertyIndexValueFactory.cs index 0cf36122d7..af72f0b819 100644 --- a/src/Umbraco.Web/PropertyEditors/GridPropertyIndexValueFactory.cs +++ b/src/Umbraco.Web/PropertyEditors/GridPropertyIndexValueFactory.cs @@ -18,7 +18,7 @@ namespace Umbraco.Web.PropertyEditors /// public class GridPropertyIndexValueFactory : IPropertyIndexValueFactory { - public IEnumerable>> GetIndexValues(Property property, string culture, string segment, bool published) + public IEnumerable>> GetIndexValues(IProperty property, string culture, string segment, bool published) { var result = new List>>(); diff --git a/src/Umbraco.Web/PropertyEditors/RichTextPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/RichTextPropertyEditor.cs index 03345bee3c..1fa2c9323b 100644 --- a/src/Umbraco.Web/PropertyEditors/RichTextPropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/RichTextPropertyEditor.cs @@ -130,7 +130,7 @@ namespace Umbraco.Web.PropertyEditors internal class RichTextPropertyIndexValueFactory : IPropertyIndexValueFactory { - public IEnumerable>> GetIndexValues(Property property, string culture, string segment, bool published) + public IEnumerable>> GetIndexValues(IProperty property, string culture, string segment, bool published) { var val = property.GetValue(culture, segment, published); From 4c963d5fb2af8156f8627512c8ff380e784d3ede Mon Sep 17 00:00:00 2001 From: Bjarke Berg Date: Fri, 8 Nov 2019 14:38:57 +0100 Subject: [PATCH 38/68] AB3649 - ILocalizationService --- src/Umbraco.Core/Umbraco.Core.csproj | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index 75e79b8fe0..3241a3852c 100755 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -299,7 +299,6 @@ - From e5c3b1f8aa02049ae0916ac1991cd171f0c32753 Mon Sep 17 00:00:00 2001 From: Bjarke Berg Date: Fri, 8 Nov 2019 15:10:05 +0100 Subject: [PATCH 39/68] AB3649 - More refactor of Property to IProperty... --- src/Umbraco.Abstractions/Models/IProperty.cs | 6 ++ .../Services/ILocalizationService.cs | 2 +- src/Umbraco.Core/ContentExtensions.cs | 6 +- src/Umbraco.Core/Models/ContentBase.cs | 6 +- .../Models/ContentTagsExtensions.cs | 2 +- src/Umbraco.Core/Models/IContentBase.cs | 2 +- .../Models/IPropertyCollection.cs | 23 ++++++ src/Umbraco.Core/Models/Property.cs | 12 +-- src/Umbraco.Core/Models/PropertyCollection.cs | 20 ++--- .../Models/PropertyTagsExtensions.cs | 18 ++--- .../Persistence/Factories/PropertyFactory.cs | 4 +- .../Services/Implement/ContentService.cs | 4 +- .../Services/Implement/EntityXmlSerializer.cs | 4 +- .../Services/PropertyValidationService.cs | 4 +- src/Umbraco.Core/Services/PublishResult.cs | 2 +- src/Umbraco.Core/Umbraco.Core.csproj | 1 + src/Umbraco.Examine/BaseValueSetBuilder.cs | 4 +- src/Umbraco.Tests/Mapping/MappingTests.cs | 4 +- .../Mapping/ContentWebModelMappingTests.cs | 6 +- src/Umbraco.Tests/Views/web.config | 74 +++++++++++++++++++ src/Umbraco.Web/Editors/ContentController.cs | 2 +- .../Editors/ContentControllerBase.cs | 4 +- .../Editors/Filters/ContentModelValidator.cs | 6 +- .../PublishedContentHashtableConverter.cs | 2 +- .../Models/Mapping/ContentMapDefinition.cs | 6 +- .../Mapping/ContentPropertyBasicMapper.cs | 2 +- .../Mapping/ContentPropertyDisplayMapper.cs | 2 +- .../Mapping/ContentPropertyDtoMapper.cs | 2 +- .../Mapping/ContentPropertyMapDefinition.cs | 12 +-- .../Models/Mapping/MediaMapDefinition.cs | 4 +- .../Models/Mapping/MemberMapDefinition.cs | 4 +- .../Mapping/MemberTabsAndPropertiesMapper.cs | 2 +- .../Models/Mapping/TabsAndPropertiesMapper.cs | 6 +- .../FileUploadPropertyEditor.cs | 4 +- .../ImageCropperPropertyEditor.cs | 4 +- .../NuCache/PublishedContent.cs | 1 + 36 files changed, 186 insertions(+), 81 deletions(-) rename src/{Umbraco.Core => Umbraco.Abstractions}/Services/ILocalizationService.cs (99%) create mode 100644 src/Umbraco.Core/Models/IPropertyCollection.cs create mode 100644 src/Umbraco.Tests/Views/web.config diff --git a/src/Umbraco.Abstractions/Models/IProperty.cs b/src/Umbraco.Abstractions/Models/IProperty.cs index 308f4ae851..cd8a07393e 100644 --- a/src/Umbraco.Abstractions/Models/IProperty.cs +++ b/src/Umbraco.Abstractions/Models/IProperty.cs @@ -6,6 +6,8 @@ namespace Umbraco.Core.Models { public interface IProperty { + + ValueStorageType ValueStorageType { get; } /// /// Returns the PropertyType, which this Property is based on /// @@ -96,5 +98,9 @@ namespace Umbraco.Core.Models /// Enables change tracking. /// void EnableChangeTracking(); + + int PropertyTypeId { get; } + void PublishValues(string culture = "*", string segment = "*"); + void UnpublishValues(string culture = "*", string segment = "*"); } } diff --git a/src/Umbraco.Core/Services/ILocalizationService.cs b/src/Umbraco.Abstractions/Services/ILocalizationService.cs similarity index 99% rename from src/Umbraco.Core/Services/ILocalizationService.cs rename to src/Umbraco.Abstractions/Services/ILocalizationService.cs index 019e07493a..6566f983df 100644 --- a/src/Umbraco.Core/Services/ILocalizationService.cs +++ b/src/Umbraco.Abstractions/Services/ILocalizationService.cs @@ -19,7 +19,7 @@ namespace Umbraco.Core.Services /// Adds or updates a translation for a dictionary item and language /// /// - /// + /// /// void AddOrUpdateDictionaryValue(IDictionaryItem item, ILanguage language, string value); diff --git a/src/Umbraco.Core/ContentExtensions.cs b/src/Umbraco.Core/ContentExtensions.cs index 8e404402d0..6732fd9394 100644 --- a/src/Umbraco.Core/ContentExtensions.cs +++ b/src/Umbraco.Core/ContentExtensions.cs @@ -108,7 +108,7 @@ namespace Umbraco.Core /// /// /// - public static IEnumerable GetNonGroupedProperties(this IContentBase content) + public static IEnumerable GetNonGroupedProperties(this IContentBase content) { return content.Properties .Where(x => x.PropertyType.PropertyGroupId == null) @@ -121,7 +121,7 @@ namespace Umbraco.Core /// /// /// - public static IEnumerable GetPropertiesForGroup(this IContentBase content, PropertyGroup propertyGroup) + public static IEnumerable GetPropertiesForGroup(this IContentBase content, PropertyGroup propertyGroup) { //get the properties for the current tab return content.Properties @@ -178,7 +178,7 @@ namespace Umbraco.Core } // gets or creates a property for a content item. - private static Property GetProperty(IContentBase content, IContentTypeBaseServiceProvider contentTypeBaseServiceProvider, string propertyTypeAlias) + private static IProperty GetProperty(IContentBase content, IContentTypeBaseServiceProvider contentTypeBaseServiceProvider, string propertyTypeAlias) { var property = content.Properties.FirstOrDefault(x => x.Alias.InvariantEquals(propertyTypeAlias)); if (property != null) return property; diff --git a/src/Umbraco.Core/Models/ContentBase.cs b/src/Umbraco.Core/Models/ContentBase.cs index fbb68194b7..c87cb0a370 100644 --- a/src/Umbraco.Core/Models/ContentBase.cs +++ b/src/Umbraco.Core/Models/ContentBase.cs @@ -20,7 +20,7 @@ namespace Umbraco.Core.Models { private int _contentTypeId; private int _writerId; - private PropertyCollection _properties; + private IPropertyCollection _properties; private ContentCultureInfosCollection _cultureInfos; internal IReadOnlyList AllPropertyTypes { get; } @@ -135,7 +135,7 @@ namespace Umbraco.Core.Models /// [DataMember] [DoNotClone] - public PropertyCollection Properties + public IPropertyCollection Properties { get => _properties; set @@ -490,7 +490,7 @@ namespace Umbraco.Core.Models if (clonedContent._properties != null) { clonedContent._properties.CollectionChanged -= PropertiesChanged; //clear this event handler if any - clonedContent._properties = (PropertyCollection)_properties.DeepClone(); //manually deep clone + clonedContent._properties = (IPropertyCollection)_properties.DeepClone(); //manually deep clone clonedContent._properties.CollectionChanged += clonedContent.PropertiesChanged; //re-assign correct event handler } diff --git a/src/Umbraco.Core/Models/ContentTagsExtensions.cs b/src/Umbraco.Core/Models/ContentTagsExtensions.cs index dd7a716520..7f9c012722 100644 --- a/src/Umbraco.Core/Models/ContentTagsExtensions.cs +++ b/src/Umbraco.Core/Models/ContentTagsExtensions.cs @@ -34,7 +34,7 @@ namespace Umbraco.Core.Models } // gets and validates the property - private static Property GetTagProperty(this IContentBase content, string propertyTypeAlias) + private static IProperty GetTagProperty(this IContentBase content, string propertyTypeAlias) { if (content == null) throw new ArgumentNullException(nameof(content)); diff --git a/src/Umbraco.Core/Models/IContentBase.cs b/src/Umbraco.Core/Models/IContentBase.cs index 0f660181fb..1864996379 100644 --- a/src/Umbraco.Core/Models/IContentBase.cs +++ b/src/Umbraco.Core/Models/IContentBase.cs @@ -98,7 +98,7 @@ namespace Umbraco.Core.Models /// List of properties, which make up all the data available for this Content object /// /// Properties are loaded as part of the Content object graph - PropertyCollection Properties { get; set; } + IPropertyCollection Properties { get; set; } /// /// Gets a value indicating whether the content entity has a property with the supplied alias. diff --git a/src/Umbraco.Core/Models/IPropertyCollection.cs b/src/Umbraco.Core/Models/IPropertyCollection.cs new file mode 100644 index 0000000000..e5bd4f60fd --- /dev/null +++ b/src/Umbraco.Core/Models/IPropertyCollection.cs @@ -0,0 +1,23 @@ +using System.Collections.Generic; +using System.Collections.Specialized; + +namespace Umbraco.Core.Models +{ + public interface IPropertyCollection : IEnumerable + { + bool TryGetValue(string propertyTypeAlias, out IProperty property); + bool Contains(string key); + + event NotifyCollectionChangedEventHandler CollectionChanged; + + void EnsurePropertyTypes(IEnumerable propertyTypes); + void EnsureCleanPropertyTypes(IEnumerable propertyTypes); + object DeepClone(); + + IProperty this[string name] { get; } + IProperty this[int index] { get; } + void Add(IProperty property); + + int Count { get; } + } +} diff --git a/src/Umbraco.Core/Models/Property.cs b/src/Umbraco.Core/Models/Property.cs index 9b2cda67c1..9aa9ab4d74 100644 --- a/src/Umbraco.Core/Models/Property.cs +++ b/src/Umbraco.Core/Models/Property.cs @@ -33,7 +33,7 @@ namespace Umbraco.Core.Models /// /// Initializes a new instance of the class. /// - public Property(PropertyType propertyType) + public Property(IPropertyType propertyType) { PropertyType = propertyType; } @@ -41,7 +41,7 @@ namespace Umbraco.Core.Models /// /// Initializes a new instance of the class. /// - public Property(int id, PropertyType propertyType) + public Property(int id, IPropertyType propertyType) { Id = id; PropertyType = propertyType; @@ -152,7 +152,7 @@ namespace Umbraco.Core.Models /// Returns the Id of the PropertyType, which this Property is based on /// [IgnoreDataMember] - internal int PropertyTypeId => PropertyType.Id; + public int PropertyTypeId => PropertyType.Id; /// /// Returns the DatabaseType that the underlaying DataType is using to store its values @@ -161,7 +161,7 @@ namespace Umbraco.Core.Models /// Only used internally when saving the property value. /// [IgnoreDataMember] - internal ValueStorageType ValueStorageType => PropertyType.ValueStorageType; + public ValueStorageType ValueStorageType => PropertyType.ValueStorageType; /// /// Gets the value. @@ -191,7 +191,7 @@ namespace Umbraco.Core.Models // internal - must be invoked by the content item // does *not* validate the value - content item must validate first - internal void PublishValues(string culture = "*", string segment = "*") + public void PublishValues(string culture = "*", string segment = "*") { culture = culture.NullOrWhiteSpaceAsNull(); segment = segment.NullOrWhiteSpaceAsNull(); @@ -216,7 +216,7 @@ namespace Umbraco.Core.Models } // internal - must be invoked by the content item - internal void UnpublishValues(string culture = "*", string segment = "*") + public void UnpublishValues(string culture = "*", string segment = "*") { culture = culture.NullOrWhiteSpaceAsNull(); segment = segment.NullOrWhiteSpaceAsNull(); diff --git a/src/Umbraco.Core/Models/PropertyCollection.cs b/src/Umbraco.Core/Models/PropertyCollection.cs index c587a45424..2415be4dce 100644 --- a/src/Umbraco.Core/Models/PropertyCollection.cs +++ b/src/Umbraco.Core/Models/PropertyCollection.cs @@ -12,10 +12,10 @@ namespace Umbraco.Core.Models /// [Serializable] [DataContract(IsReference = true)] - public class PropertyCollection : KeyedCollection, INotifyCollectionChanged, IDeepCloneable + public class PropertyCollection : KeyedCollection, INotifyCollectionChanged, IDeepCloneable, IPropertyCollection { private readonly object _addLocker = new object(); - + internal Func AdditionValidator { get; set; } /// @@ -60,7 +60,7 @@ namespace Umbraco.Core.Models /// /// Replaces the property at the specified index with the specified property. /// - protected override void SetItem(int index, Property property) + protected override void SetItem(int index, IProperty property) { var oldItem = index >= 0 ? this[index] : property; base.SetItem(index, property); @@ -80,7 +80,7 @@ namespace Umbraco.Core.Models /// /// Inserts the specified property at the specified index. /// - protected override void InsertItem(int index, Property property) + protected override void InsertItem(int index, IProperty property) { base.InsertItem(index, property); OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, property)); @@ -98,7 +98,7 @@ namespace Umbraco.Core.Models /// /// Adds or updates a property. /// - internal new void Add(Property property) + public new void Add(IProperty property) { lock (_addLocker) // TODO: why are we locking here and not everywhere else?! { @@ -141,7 +141,7 @@ namespace Umbraco.Core.Models return -1; } - protected override string GetKeyForItem(Property item) + protected override string GetKeyForItem(IProperty item) { return item.Alias; } @@ -149,7 +149,7 @@ namespace Umbraco.Core.Models /// /// Gets the property with the specified PropertyType. /// - internal Property this[PropertyType propertyType] + internal IProperty this[IPropertyType propertyType] { get { @@ -157,7 +157,7 @@ namespace Umbraco.Core.Models } } - public bool TryGetValue(string propertyTypeAlias, out Property property) + public bool TryGetValue(string propertyTypeAlias, out IProperty property) { property = this.FirstOrDefault(x => x.Alias.InvariantEquals(propertyTypeAlias)); return property != null; @@ -176,7 +176,7 @@ namespace Umbraco.Core.Models /// /// Ensures that the collection contains properties for the specified property types. /// - protected internal void EnsurePropertyTypes(IEnumerable propertyTypes) + public void EnsurePropertyTypes(IEnumerable propertyTypes) { if (propertyTypes == null) return; @@ -188,7 +188,7 @@ namespace Umbraco.Core.Models /// /// Ensures that the collection does not contain properties not in the specified property types. /// - protected internal void EnsureCleanPropertyTypes(IEnumerable propertyTypes) + public void EnsureCleanPropertyTypes(IEnumerable propertyTypes) { if (propertyTypes == null) return; diff --git a/src/Umbraco.Core/Models/PropertyTagsExtensions.cs b/src/Umbraco.Core/Models/PropertyTagsExtensions.cs index 63cf870221..1bac5c98f1 100644 --- a/src/Umbraco.Core/Models/PropertyTagsExtensions.cs +++ b/src/Umbraco.Core/Models/PropertyTagsExtensions.cs @@ -20,7 +20,7 @@ namespace Umbraco.Core.Models // gets the tag configuration for a property // from the datatype configuration, and the editor tag configuration attribute - internal static TagConfiguration GetTagConfiguration(this Property property) + internal static TagConfiguration GetTagConfiguration(this IProperty property) { if (property == null) throw new ArgumentNullException(nameof(property)); @@ -44,7 +44,7 @@ namespace Umbraco.Core.Models /// The tags. /// A value indicating whether to merge the tags with existing tags instead of replacing them. /// A culture, for multi-lingual properties. - public static void AssignTags(this Property property, IEnumerable tags, bool merge = false, string culture = null) + public static void AssignTags(this IProperty property, IEnumerable tags, bool merge = false, string culture = null) { if (property == null) throw new ArgumentNullException(nameof(property)); @@ -56,7 +56,7 @@ namespace Umbraco.Core.Models } // assumes that parameters are consistent with the datatype configuration - private static void AssignTags(this Property property, IEnumerable tags, bool merge, TagsStorageType storageType, char delimiter, string culture) + private static void AssignTags(this IProperty property, IEnumerable tags, bool merge, TagsStorageType storageType, char delimiter, string culture) { // set the property value var trimmedTags = tags.Select(x => x.Trim()).ToArray(); @@ -97,7 +97,7 @@ namespace Umbraco.Core.Models /// The property. /// The tags. /// A culture, for multi-lingual properties. - public static void RemoveTags(this Property property, IEnumerable tags, string culture = null) + public static void RemoveTags(this IProperty property, IEnumerable tags, string culture = null) { if (property == null) throw new ArgumentNullException(nameof(property)); @@ -109,7 +109,7 @@ namespace Umbraco.Core.Models } // assumes that parameters are consistent with the datatype configuration - private static void RemoveTags(this Property property, IEnumerable tags, TagsStorageType storageType, char delimiter, string culture) + private static void RemoveTags(this IProperty property, IEnumerable tags, TagsStorageType storageType, char delimiter, string culture) { // already empty = nothing to do var value = property.GetValue(culture)?.ToString(); @@ -131,7 +131,7 @@ namespace Umbraco.Core.Models } // used by ContentRepositoryBase - internal static IEnumerable GetTagsValue(this Property property, string culture = null) + internal static IEnumerable GetTagsValue(this IProperty property, string culture = null) { if (property == null) throw new ArgumentNullException(nameof(property)); @@ -142,7 +142,7 @@ namespace Umbraco.Core.Models return property.GetTagsValue(configuration.StorageType, configuration.Delimiter, culture); } - private static IEnumerable GetTagsValue(this Property property, TagsStorageType storageType, char delimiter, string culture = null) + private static IEnumerable GetTagsValue(this IProperty property, TagsStorageType storageType, char delimiter, string culture = null) { if (property == null) throw new ArgumentNullException(nameof(property)); @@ -182,7 +182,7 @@ namespace Umbraco.Core.Models /// This is used both by the content repositories to initialize a property with some tag values, and by the /// content controllers to update a property with values received from the property editor. /// - internal static void SetTagsValue(this Property property, object value, TagConfiguration tagConfiguration, string culture) + internal static void SetTagsValue(this IProperty property, object value, TagConfiguration tagConfiguration, string culture) { if (property == null) throw new ArgumentNullException(nameof(property)); if (tagConfiguration == null) throw new ArgumentNullException(nameof(tagConfiguration)); @@ -195,7 +195,7 @@ namespace Umbraco.Core.Models // assumes that parameters are consistent with the datatype configuration // value can be an enumeration of string, or a serialized value using storageType format - private static void SetTagsValue(Property property, object value, TagsStorageType storageType, char delimiter, string culture) + private static void SetTagsValue(IProperty property, object value, TagsStorageType storageType, char delimiter, string culture) { if (value == null) value = Enumerable.Empty(); diff --git a/src/Umbraco.Core/Persistence/Factories/PropertyFactory.cs b/src/Umbraco.Core/Persistence/Factories/PropertyFactory.cs index 9d9482fedb..fc31f61763 100644 --- a/src/Umbraco.Core/Persistence/Factories/PropertyFactory.cs +++ b/src/Umbraco.Core/Persistence/Factories/PropertyFactory.cs @@ -46,7 +46,7 @@ namespace Umbraco.Core.Persistence.Factories return properties; } - private static PropertyDataDto BuildDto(int versionId, Property property, int? languageId, string segment, object value) + private static PropertyDataDto BuildDto(int versionId, IProperty property, int? languageId, string segment, object value) { var dto = new PropertyDataDto { VersionId = versionId, PropertyTypeId = property.PropertyTypeId }; @@ -109,7 +109,7 @@ namespace Umbraco.Core.Persistence.Factories /// The value of this will be used to populate the edited cultures in the umbracoDocumentCultureVariation table. /// /// - public static IEnumerable BuildDtos(ContentVariation contentVariation, int currentVersionId, int publishedVersionId, IEnumerable properties, + public static IEnumerable BuildDtos(ContentVariation contentVariation, int currentVersionId, int publishedVersionId, IEnumerable properties, ILanguageRepository languageRepository, out bool edited, out HashSet editedCultures) { diff --git a/src/Umbraco.Core/Services/Implement/ContentService.cs b/src/Umbraco.Core/Services/Implement/ContentService.cs index 5a43738230..2fa75e2f3f 100644 --- a/src/Umbraco.Core/Services/Implement/ContentService.cs +++ b/src/Umbraco.Core/Services/Implement/ContentService.cs @@ -1402,7 +1402,7 @@ namespace Umbraco.Core.Services.Implement if (d.Trashed) continue; // won't publish //publish the culture values and validate the property values, if validation fails, log the invalid properties so the develeper has an idea of what has failed - Property[] invalidProperties = null; + IProperty[] invalidProperties = null; var impact = CultureImpact.Explicit(culture, IsDefaultCulture(allLangs, culture)); var tryPublish = d.PublishCulture(impact) && _propertyValidationService.Value.IsPropertyDataValid(d, out invalidProperties, impact); if (invalidProperties != null && invalidProperties.Length > 0) @@ -2602,7 +2602,7 @@ namespace Umbraco.Core.Services.Implement return new PublishResult(PublishResultType.FailedPublishContentInvalid, evtMsgs, content); //validate the property values - Property[] invalidProperties = null; + IProperty[] invalidProperties = null; if (!impactsToPublish.All(x => _propertyValidationService.Value.IsPropertyDataValid(content, out invalidProperties, x))) return new PublishResult(PublishResultType.FailedPublishContentInvalid, evtMsgs, content) { diff --git a/src/Umbraco.Core/Services/Implement/EntityXmlSerializer.cs b/src/Umbraco.Core/Services/Implement/EntityXmlSerializer.cs index bc21da15a7..f115dacc6c 100644 --- a/src/Umbraco.Core/Services/Implement/EntityXmlSerializer.cs +++ b/src/Umbraco.Core/Services/Implement/EntityXmlSerializer.cs @@ -77,7 +77,7 @@ namespace Umbraco.Core.Services.Implement var children = _contentService.GetPagedChildren(content.Id, page++, pageSize, out total); SerializeChildren(children, xml, published); } - + } return xml; @@ -552,7 +552,7 @@ namespace Umbraco.Core.Services.Implement } // exports a property as XElements. - private IEnumerable SerializeProperty(Property property, bool published) + private IEnumerable SerializeProperty(IProperty property, bool published) { var propertyType = property.PropertyType; diff --git a/src/Umbraco.Core/Services/PropertyValidationService.cs b/src/Umbraco.Core/Services/PropertyValidationService.cs index f619e5f47e..1704d52206 100644 --- a/src/Umbraco.Core/Services/PropertyValidationService.cs +++ b/src/Umbraco.Core/Services/PropertyValidationService.cs @@ -31,7 +31,7 @@ namespace Umbraco.Core.Services /// /// Validates the content item's properties pass validation rules /// - public bool IsPropertyDataValid(IContent content, out Property[] invalidProperties, CultureImpact impact) + public bool IsPropertyDataValid(IContent content, out IProperty[] invalidProperties, CultureImpact impact) { // select invalid properties invalidProperties = content.Properties.Where(x => @@ -66,7 +66,7 @@ namespace Umbraco.Core.Services /// /// Gets a value indicating whether the property has valid values. /// - public bool IsPropertyValid(Property property, string culture = "*", string segment = "*") + public bool IsPropertyValid(IProperty property, string culture = "*", string segment = "*") { //NOTE - the pvalue and vvalues logic in here is borrowed directly from the Property.Values setter so if you are wondering what that's all about, look there. // The underlying Property._pvalue and Property._vvalues are not exposed but we can re-create these values ourselves which is what it's doing. diff --git a/src/Umbraco.Core/Services/PublishResult.cs b/src/Umbraco.Core/Services/PublishResult.cs index 4f1ff776a2..fe11d77cf3 100644 --- a/src/Umbraco.Core/Services/PublishResult.cs +++ b/src/Umbraco.Core/Services/PublishResult.cs @@ -32,6 +32,6 @@ namespace Umbraco.Core.Services /// /// Gets or sets the invalid properties, if the status failed due to validation. /// - public IEnumerable InvalidProperties { get; set; } + public IEnumerable InvalidProperties { get; set; } } } diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index 3241a3852c..8df0c336db 100755 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -241,6 +241,7 @@ + diff --git a/src/Umbraco.Examine/BaseValueSetBuilder.cs b/src/Umbraco.Examine/BaseValueSetBuilder.cs index 93cee88231..4a306aa5ff 100644 --- a/src/Umbraco.Examine/BaseValueSetBuilder.cs +++ b/src/Umbraco.Examine/BaseValueSetBuilder.cs @@ -24,7 +24,7 @@ namespace Umbraco.Examine /// public abstract IEnumerable GetValueSets(params TContent[] content); - protected void AddPropertyValue(Property property, string culture, string segment, IDictionary> values) + protected void AddPropertyValue(IProperty property, string culture, string segment, IDictionary> values) { var editor = _propertyEditors[property.PropertyType.PropertyEditorAlias]; if (editor == null) return; @@ -61,7 +61,7 @@ namespace Umbraco.Examine else values.Add($"{keyVal.Key}{cultureSuffix}", val.Yield()); } - + break; } } diff --git a/src/Umbraco.Tests/Mapping/MappingTests.cs b/src/Umbraco.Tests/Mapping/MappingTests.cs index e6a382692c..ad336168c6 100644 --- a/src/Umbraco.Tests/Mapping/MappingTests.cs +++ b/src/Umbraco.Tests/Mapping/MappingTests.cs @@ -285,10 +285,10 @@ namespace Umbraco.Tests.Mapping { public void DefineMaps(UmbracoMapper mapper) { - mapper.Define((source, context) => new ContentPropertyDto(), Map); + mapper.Define((source, context) => new ContentPropertyDto(), Map); } - private static void Map(Property source, ContentPropertyDto target, MapperContext context) + private static void Map(IProperty source, ContentPropertyDto target, MapperContext context) { } } diff --git a/src/Umbraco.Tests/Models/Mapping/ContentWebModelMappingTests.cs b/src/Umbraco.Tests/Models/Mapping/ContentWebModelMappingTests.cs index 6a4054d5ae..996f02e16a 100644 --- a/src/Umbraco.Tests/Models/Mapping/ContentWebModelMappingTests.cs +++ b/src/Umbraco.Tests/Models/Mapping/ContentWebModelMappingTests.cs @@ -261,7 +261,7 @@ namespace Umbraco.Tests.Models.Mapping #region Assertions - private void AssertDisplayProperty(IContentProperties result, Property p) + private void AssertDisplayProperty(IContentProperties result, IProperty p) where T : ContentPropertyBasic { var pDto = result.Properties.SingleOrDefault(x => x.Alias == p.Alias); @@ -325,7 +325,7 @@ namespace Umbraco.Tests.Models.Mapping Assert.AreEqual(content.Properties.Count(), result.Properties.Count(x => x.Alias.StartsWith("_umb_") == false)); } - private void AssertBasicProperty(IContentProperties result, Property p) + private void AssertBasicProperty(IContentProperties result, IProperty p) where T : ContentPropertyBasic { var pDto = result.Properties.SingleOrDefault(x => x.Alias == p.Alias); @@ -341,7 +341,7 @@ namespace Umbraco.Tests.Models.Mapping Assert.AreEqual(pDto.Value, p.GetValue().ToString()); } - private void AssertProperty(IContentProperties result, Property p) + private void AssertProperty(IContentProperties result, IProperty p) { AssertBasicProperty(result, p); diff --git a/src/Umbraco.Tests/Views/web.config b/src/Umbraco.Tests/Views/web.config new file mode 100644 index 0000000000..efd80424e5 --- /dev/null +++ b/src/Umbraco.Tests/Views/web.config @@ -0,0 +1,74 @@ + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Umbraco.Web/Editors/ContentController.cs b/src/Umbraco.Web/Editors/ContentController.cs index 5c8e6fc2b5..11cc59a464 100644 --- a/src/Umbraco.Web/Editors/ContentController.cs +++ b/src/Umbraco.Web/Editors/ContentController.cs @@ -1837,7 +1837,7 @@ namespace Umbraco.Web.Editors private void MapValuesForPersistence(ContentItemSave contentSave) { // inline method to determine if a property type varies - bool Varies(Property property) => property.PropertyType.VariesByCulture(); + bool Varies(IProperty property) => property.PropertyType.VariesByCulture(); var variantIndex = 0; diff --git a/src/Umbraco.Web/Editors/ContentControllerBase.cs b/src/Umbraco.Web/Editors/ContentControllerBase.cs index 300c777b3a..83167eb9ae 100644 --- a/src/Umbraco.Web/Editors/ContentControllerBase.cs +++ b/src/Umbraco.Web/Editors/ContentControllerBase.cs @@ -50,8 +50,8 @@ namespace Umbraco.Web.Editors internal void MapPropertyValuesForPersistence( TSaved contentItem, ContentPropertyCollectionDto dto, - Func getPropertyValue, - Action savePropertyValue, + Func getPropertyValue, + Action savePropertyValue, string culture) where TPersisted : IContentBase where TSaved : IContentSave diff --git a/src/Umbraco.Web/Editors/Filters/ContentModelValidator.cs b/src/Umbraco.Web/Editors/Filters/ContentModelValidator.cs index 4acf0c948e..14531227e1 100644 --- a/src/Umbraco.Web/Editors/Filters/ContentModelValidator.cs +++ b/src/Umbraco.Web/Editors/Filters/ContentModelValidator.cs @@ -46,7 +46,7 @@ namespace Umbraco.Web.Editors.Filters protected ContentModelValidator(ILogger logger, IUmbracoContextAccessor umbracoContextAccessor) : base(logger, umbracoContextAccessor) { } - + /// /// Ensure the content exists /// @@ -85,7 +85,7 @@ namespace Umbraco.Web.Editors.Filters /// /// /// - protected bool ValidateProperties(List postedProperties, List persistedProperties, HttpActionContext actionContext) + protected bool ValidateProperties(List postedProperties, List persistedProperties, HttpActionContext actionContext) { foreach (var p in postedProperties) { @@ -142,7 +142,7 @@ namespace Umbraco.Web.Editors.Filters var postedValue = postedProp.Value; ValidatePropertyValue(model, modelWithProperties, editor, p, postedValue, modelState); - + } return modelState.IsValid; diff --git a/src/Umbraco.Web/Macros/PublishedContentHashtableConverter.cs b/src/Umbraco.Web/Macros/PublishedContentHashtableConverter.cs index 41f0e2fb65..cab20926ff 100644 --- a/src/Umbraco.Web/Macros/PublishedContentHashtableConverter.cs +++ b/src/Umbraco.Web/Macros/PublishedContentHashtableConverter.cs @@ -147,7 +147,7 @@ namespace Umbraco.Web.Macros _content = content; } - public PagePublishedProperty(IPublishedPropertyType propertyType, IPublishedContent content, Umbraco.Core.Models.Property property) + public PagePublishedProperty(IPublishedPropertyType propertyType, IPublishedContent content, IProperty property) : base(propertyType, PropertyCacheLevel.Unknown) // cache level is ignored { _sourceValue = property.GetValue(); diff --git a/src/Umbraco.Web/Models/Mapping/ContentMapDefinition.cs b/src/Umbraco.Web/Models/Mapping/ContentMapDefinition.cs index dc0df4ca96..d3b4353f2f 100644 --- a/src/Umbraco.Web/Models/Mapping/ContentMapDefinition.cs +++ b/src/Umbraco.Web/Models/Mapping/ContentMapDefinition.cs @@ -64,7 +64,7 @@ namespace Umbraco.Web.Models.Mapping // Umbraco.Code.MapAll private static void Map(IContent source, ContentPropertyCollectionDto target, MapperContext context) { - target.Properties = context.MapEnumerable(source.Properties); + target.Properties = context.MapEnumerable(source.Properties); } // Umbraco.Code.MapAll -AllowPreview -Errors -PersistedContent @@ -99,7 +99,7 @@ namespace Umbraco.Web.Models.Mapping target.Variants = _contentVariantMapper.Map(source, context); target.ContentDto = new ContentPropertyCollectionDto(); - target.ContentDto.Properties = context.MapEnumerable(source.Properties); + target.ContentDto.Properties = context.MapEnumerable(source.Properties); } // Umbraco.Code.MapAll -Segment -Language @@ -129,7 +129,7 @@ namespace Umbraco.Web.Models.Mapping target.Owner = _commonMapper.GetOwner(source, context); target.ParentId = source.ParentId; target.Path = source.Path; - target.Properties = context.MapEnumerable(source.Properties); + target.Properties = context.MapEnumerable(source.Properties); target.SortOrder = source.SortOrder; target.State = _basicStateMapper.Map(source, context); target.Trashed = source.Trashed; diff --git a/src/Umbraco.Web/Models/Mapping/ContentPropertyBasicMapper.cs b/src/Umbraco.Web/Models/Mapping/ContentPropertyBasicMapper.cs index 36c1b360b2..4e49f2ea2a 100644 --- a/src/Umbraco.Web/Models/Mapping/ContentPropertyBasicMapper.cs +++ b/src/Umbraco.Web/Models/Mapping/ContentPropertyBasicMapper.cs @@ -33,7 +33,7 @@ namespace Umbraco.Web.Models.Mapping /// Assigns the PropertyEditor, Id, Alias and Value to the property ///
/// - public virtual void Map(Property property, TDestination dest, MapperContext context) + public virtual void Map(IProperty property, TDestination dest, MapperContext context) { var editor = _propertyEditors[property.PropertyType.PropertyEditorAlias]; if (editor == null) diff --git a/src/Umbraco.Web/Models/Mapping/ContentPropertyDisplayMapper.cs b/src/Umbraco.Web/Models/Mapping/ContentPropertyDisplayMapper.cs index f68c5d8b44..12278e97ea 100644 --- a/src/Umbraco.Web/Models/Mapping/ContentPropertyDisplayMapper.cs +++ b/src/Umbraco.Web/Models/Mapping/ContentPropertyDisplayMapper.cs @@ -19,7 +19,7 @@ namespace Umbraco.Web.Models.Mapping { _textService = textService; } - public override void Map(Property originalProp, ContentPropertyDisplay dest, MapperContext context) + public override void Map(IProperty originalProp, ContentPropertyDisplay dest, MapperContext context) { base.Map(originalProp, dest, context); diff --git a/src/Umbraco.Web/Models/Mapping/ContentPropertyDtoMapper.cs b/src/Umbraco.Web/Models/Mapping/ContentPropertyDtoMapper.cs index 72107c6201..f481ad445c 100644 --- a/src/Umbraco.Web/Models/Mapping/ContentPropertyDtoMapper.cs +++ b/src/Umbraco.Web/Models/Mapping/ContentPropertyDtoMapper.cs @@ -16,7 +16,7 @@ namespace Umbraco.Web.Models.Mapping : base(dataTypeService, entityService, logger, propertyEditors) { } - public override void Map(Property property, ContentPropertyDto dest, MapperContext context) + public override void Map(IProperty property, ContentPropertyDto dest, MapperContext context) { base.Map(property, dest, context); diff --git a/src/Umbraco.Web/Models/Mapping/ContentPropertyMapDefinition.cs b/src/Umbraco.Web/Models/Mapping/ContentPropertyMapDefinition.cs index e6290cc19e..5d659fbf9e 100644 --- a/src/Umbraco.Web/Models/Mapping/ContentPropertyMapDefinition.cs +++ b/src/Umbraco.Web/Models/Mapping/ContentPropertyMapDefinition.cs @@ -27,9 +27,9 @@ namespace Umbraco.Web.Models.Mapping public void DefineMaps(UmbracoMapper mapper) { mapper.Define>((source, context) => new Tab(), Map); - mapper.Define((source, context) => new ContentPropertyBasic(), Map); - mapper.Define((source, context) => new ContentPropertyDto(), Map); - mapper.Define((source, context) => new ContentPropertyDisplay(), Map); + mapper.Define((source, context) => new ContentPropertyBasic(), Map); + mapper.Define((source, context) => new ContentPropertyDto(), Map); + mapper.Define((source, context) => new ContentPropertyDisplay(), Map); } // Umbraco.Code.MapAll -Properties -Alias -Expanded @@ -40,19 +40,19 @@ namespace Umbraco.Web.Models.Mapping target.Label = source.Name; } - private void Map(Property source, ContentPropertyBasic target, MapperContext context) + private void Map(IProperty source, ContentPropertyBasic target, MapperContext context) { // assume this is mapping everything and no MapAll is required _contentPropertyBasicConverter.Map(source, target, context); } - private void Map(Property source, ContentPropertyDto target, MapperContext context) + private void Map(IProperty source, ContentPropertyDto target, MapperContext context) { // assume this is mapping everything and no MapAll is required _contentPropertyDtoConverter.Map(source, target, context); } - private void Map(Property source, ContentPropertyDisplay target, MapperContext context) + private void Map(IProperty source, ContentPropertyDisplay target, MapperContext context) { // assume this is mapping everything and no MapAll is required _contentPropertyDisplayMapper.Map(source, target, context); diff --git a/src/Umbraco.Web/Models/Mapping/MediaMapDefinition.cs b/src/Umbraco.Web/Models/Mapping/MediaMapDefinition.cs index 05c006ec41..80bdc7ade4 100644 --- a/src/Umbraco.Web/Models/Mapping/MediaMapDefinition.cs +++ b/src/Umbraco.Web/Models/Mapping/MediaMapDefinition.cs @@ -42,7 +42,7 @@ namespace Umbraco.Web.Models.Mapping // Umbraco.Code.MapAll private static void Map(IMedia source, ContentPropertyCollectionDto target, MapperContext context) { - target.Properties = context.MapEnumerable(source.Properties); + target.Properties = context.MapEnumerable(source.Properties); } // Umbraco.Code.MapAll -Properties -Errors -Edited -Updater -Alias -IsContainer @@ -86,7 +86,7 @@ namespace Umbraco.Web.Models.Mapping target.Owner = _commonMapper.GetOwner(source, context); target.ParentId = source.ParentId; target.Path = source.Path; - target.Properties = context.MapEnumerable(source.Properties); + target.Properties = context.MapEnumerable(source.Properties); target.SortOrder = source.SortOrder; target.State = null; target.Trashed = source.Trashed; diff --git a/src/Umbraco.Web/Models/Mapping/MemberMapDefinition.cs b/src/Umbraco.Web/Models/Mapping/MemberMapDefinition.cs index 8671bfe538..fd295803c1 100644 --- a/src/Umbraco.Web/Models/Mapping/MemberMapDefinition.cs +++ b/src/Umbraco.Web/Models/Mapping/MemberMapDefinition.cs @@ -113,7 +113,7 @@ namespace Umbraco.Web.Models.Mapping target.Owner = _commonMapper.GetOwner(source, context); target.ParentId = source.ParentId; target.Path = source.Path; - target.Properties = context.MapEnumerable(source.Properties); + target.Properties = context.MapEnumerable(source.Properties); target.SortOrder = source.SortOrder; target.State = null; target.Udi = Udi.Create(Constants.UdiEntityType.Member, source.Key); @@ -151,7 +151,7 @@ namespace Umbraco.Web.Models.Mapping // Umbraco.Code.MapAll private static void Map(IMember source, ContentPropertyCollectionDto target, MapperContext context) { - target.Properties = context.MapEnumerable(source.Properties); + target.Properties = context.MapEnumerable(source.Properties); } private MembershipScenario GetMembershipScenario() diff --git a/src/Umbraco.Web/Models/Mapping/MemberTabsAndPropertiesMapper.cs b/src/Umbraco.Web/Models/Mapping/MemberTabsAndPropertiesMapper.cs index 8744b068a7..81d75de498 100644 --- a/src/Umbraco.Web/Models/Mapping/MemberTabsAndPropertiesMapper.cs +++ b/src/Umbraco.Web/Models/Mapping/MemberTabsAndPropertiesMapper.cs @@ -176,7 +176,7 @@ namespace Umbraco.Web.Models.Mapping /// /// /// - protected override List MapProperties(IContentBase content, List properties, MapperContext context) + protected override List MapProperties(IContentBase content, List properties, MapperContext context) { var result = base.MapProperties(content, properties, context); var member = (IMember)content; diff --git a/src/Umbraco.Web/Models/Mapping/TabsAndPropertiesMapper.cs b/src/Umbraco.Web/Models/Mapping/TabsAndPropertiesMapper.cs index b8d76572fb..70a001735a 100644 --- a/src/Umbraco.Web/Models/Mapping/TabsAndPropertiesMapper.cs +++ b/src/Umbraco.Web/Models/Mapping/TabsAndPropertiesMapper.cs @@ -103,9 +103,9 @@ namespace Umbraco.Web.Models.Mapping /// /// /// - protected virtual List MapProperties(IContentBase content, List properties, MapperContext context) + protected virtual List MapProperties(IContentBase content, List properties, MapperContext context) { - return context.MapEnumerable(properties.OrderBy(x => x.PropertyType.SortOrder)); + return context.MapEnumerable(properties.OrderBy(x => x.PropertyType.SortOrder)); } } @@ -132,7 +132,7 @@ namespace Umbraco.Web.Models.Mapping var groupsGroupsByName = contentType.CompositionPropertyGroups.OrderBy(x => x.SortOrder).GroupBy(x => x.Name); foreach (var groupsByName in groupsGroupsByName) { - var properties = new List(); + var properties = new List(); // merge properties for groups with the same name foreach (var group in groupsByName) diff --git a/src/Umbraco.Web/PropertyEditors/FileUploadPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/FileUploadPropertyEditor.cs index a3396a5fb3..849ad443c8 100644 --- a/src/Umbraco.Web/PropertyEditors/FileUploadPropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/FileUploadPropertyEditor.cs @@ -48,7 +48,7 @@ namespace Umbraco.Web.PropertyEditors ///
/// The property. /// A value indicating whether a property is an upload field, and (optionally) has a non-empty value. - private static bool IsUploadField(Property property) + private static bool IsUploadField(IProperty property) { return property.PropertyType.PropertyEditorAlias == Constants.PropertyEditors.Aliases.UploadField; } @@ -70,7 +70,7 @@ namespace Umbraco.Web.PropertyEditors /// /// /// - private IEnumerable GetFilePathsFromPropertyValues(Property prop) + private IEnumerable GetFilePathsFromPropertyValues(IProperty prop) { var propVals = prop.Values; foreach (var propertyValue in propVals) diff --git a/src/Umbraco.Web/PropertyEditors/ImageCropperPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/ImageCropperPropertyEditor.cs index 1d7c1eef65..d120210411 100644 --- a/src/Umbraco.Web/PropertyEditors/ImageCropperPropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/ImageCropperPropertyEditor.cs @@ -65,7 +65,7 @@ namespace Umbraco.Web.PropertyEditors /// /// The property. /// A value indicating whether a property is an image cropper field, and (optionally) has a non-empty value. - private static bool IsCropperField(Property property) + private static bool IsCropperField(IProperty property) { return property.PropertyType.PropertyEditorAlias == Constants.PropertyEditors.Aliases.ImageCropper; } @@ -111,7 +111,7 @@ namespace Umbraco.Web.PropertyEditors /// /// /// - private IEnumerable GetFilePathsFromPropertyValues(Property prop) + private IEnumerable GetFilePathsFromPropertyValues(IProperty prop) { //parses out the src from a json string diff --git a/src/Umbraco.Web/PublishedCache/NuCache/PublishedContent.cs b/src/Umbraco.Web/PublishedCache/NuCache/PublishedContent.cs index bf4975714d..6d34a2af42 100644 --- a/src/Umbraco.Web/PublishedCache/NuCache/PublishedContent.cs +++ b/src/Umbraco.Web/PublishedCache/NuCache/PublishedContent.cs @@ -4,6 +4,7 @@ using System.Linq; using Umbraco.Core; using Umbraco.Core.Cache; using Umbraco.Core.Exceptions; +using Umbraco.Core.Models; using Umbraco.Core.Models.PublishedContent; using Umbraco.Web.Composing; using Umbraco.Web.Models; From 16ff38a45661271fc9b495bd55dac6e63198c32b Mon Sep 17 00:00:00 2001 From: Bjarke Berg Date: Mon, 11 Nov 2019 08:36:27 +0100 Subject: [PATCH 40/68] AB3649 - Moved IPropertyCollection, IMedia, and IContentBase --- .../Models/IContentBase.cs | 0 .../Models/IMedia.cs | 0 .../Models/IPropertyCollection.cs | 2 +- src/Umbraco.Core/Models/PropertyCollection.cs | 2 +- src/Umbraco.Core/Umbraco.Core.csproj | 3 - src/Umbraco.Tests/Views/web.config | 74 ------------------- 6 files changed, 2 insertions(+), 79 deletions(-) rename src/{Umbraco.Core => Umbraco.Abstractions}/Models/IContentBase.cs (100%) rename src/{Umbraco.Core => Umbraco.Abstractions}/Models/IMedia.cs (100%) rename src/{Umbraco.Core => Umbraco.Abstractions}/Models/IPropertyCollection.cs (88%) delete mode 100644 src/Umbraco.Tests/Views/web.config diff --git a/src/Umbraco.Core/Models/IContentBase.cs b/src/Umbraco.Abstractions/Models/IContentBase.cs similarity index 100% rename from src/Umbraco.Core/Models/IContentBase.cs rename to src/Umbraco.Abstractions/Models/IContentBase.cs diff --git a/src/Umbraco.Core/Models/IMedia.cs b/src/Umbraco.Abstractions/Models/IMedia.cs similarity index 100% rename from src/Umbraco.Core/Models/IMedia.cs rename to src/Umbraco.Abstractions/Models/IMedia.cs diff --git a/src/Umbraco.Core/Models/IPropertyCollection.cs b/src/Umbraco.Abstractions/Models/IPropertyCollection.cs similarity index 88% rename from src/Umbraco.Core/Models/IPropertyCollection.cs rename to src/Umbraco.Abstractions/Models/IPropertyCollection.cs index e5bd4f60fd..ec2c4d90ca 100644 --- a/src/Umbraco.Core/Models/IPropertyCollection.cs +++ b/src/Umbraco.Abstractions/Models/IPropertyCollection.cs @@ -11,7 +11,7 @@ namespace Umbraco.Core.Models event NotifyCollectionChangedEventHandler CollectionChanged; void EnsurePropertyTypes(IEnumerable propertyTypes); - void EnsureCleanPropertyTypes(IEnumerable propertyTypes); + void EnsureCleanPropertyTypes(IEnumerable propertyTypes); object DeepClone(); IProperty this[string name] { get; } diff --git a/src/Umbraco.Core/Models/PropertyCollection.cs b/src/Umbraco.Core/Models/PropertyCollection.cs index 2415be4dce..4c4d083692 100644 --- a/src/Umbraco.Core/Models/PropertyCollection.cs +++ b/src/Umbraco.Core/Models/PropertyCollection.cs @@ -188,7 +188,7 @@ namespace Umbraco.Core.Models /// /// Ensures that the collection does not contain properties not in the specified property types. /// - public void EnsureCleanPropertyTypes(IEnumerable propertyTypes) + public void EnsureCleanPropertyTypes(IEnumerable propertyTypes) { if (propertyTypes == null) return; diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index 8df0c336db..7f51a855b3 100755 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -230,18 +230,15 @@ - - - diff --git a/src/Umbraco.Tests/Views/web.config b/src/Umbraco.Tests/Views/web.config deleted file mode 100644 index efd80424e5..0000000000 --- a/src/Umbraco.Tests/Views/web.config +++ /dev/null @@ -1,74 +0,0 @@ - - - - - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - From f90fc48ca8eaa3ee17640e53a394fbf39ba1d16a Mon Sep 17 00:00:00 2001 From: Bjarke Berg Date: Mon, 11 Nov 2019 15:42:14 +0100 Subject: [PATCH 41/68] AB3649 - Moved IContent and ContentSchedule --- .../Models/ContentSchedule.cs | 2 +- .../Models/ContentScheduleAction.cs | 0 .../Models/ContentScheduleCollection.cs | 0 .../Models/IContent.cs | 0 src/Umbraco.Core/Manifest/ManifestParser.cs | 10 +++++++--- src/Umbraco.Core/Umbraco.Core.csproj | 4 ---- src/Umbraco.Tests/Manifest/ManifestParserTests.cs | 3 ++- 7 files changed, 10 insertions(+), 9 deletions(-) rename src/{Umbraco.Core => Umbraco.Abstractions}/Models/ContentSchedule.cs (98%) rename src/{Umbraco.Core => Umbraco.Abstractions}/Models/ContentScheduleAction.cs (100%) rename src/{Umbraco.Core => Umbraco.Abstractions}/Models/ContentScheduleCollection.cs (100%) rename src/{Umbraco.Core => Umbraco.Abstractions}/Models/IContent.cs (100%) diff --git a/src/Umbraco.Core/Models/ContentSchedule.cs b/src/Umbraco.Abstractions/Models/ContentSchedule.cs similarity index 98% rename from src/Umbraco.Core/Models/ContentSchedule.cs rename to src/Umbraco.Abstractions/Models/ContentSchedule.cs index cac4a0fd1c..4dba0456b0 100644 --- a/src/Umbraco.Core/Models/ContentSchedule.cs +++ b/src/Umbraco.Abstractions/Models/ContentSchedule.cs @@ -36,7 +36,7 @@ namespace Umbraco.Core.Models /// Gets the unique identifier of the document targeted by the scheduled action. /// [DataMember] - public Guid Id { get; internal set; } + public Guid Id { get; set; } /// /// Gets the culture of the scheduled action. diff --git a/src/Umbraco.Core/Models/ContentScheduleAction.cs b/src/Umbraco.Abstractions/Models/ContentScheduleAction.cs similarity index 100% rename from src/Umbraco.Core/Models/ContentScheduleAction.cs rename to src/Umbraco.Abstractions/Models/ContentScheduleAction.cs diff --git a/src/Umbraco.Core/Models/ContentScheduleCollection.cs b/src/Umbraco.Abstractions/Models/ContentScheduleCollection.cs similarity index 100% rename from src/Umbraco.Core/Models/ContentScheduleCollection.cs rename to src/Umbraco.Abstractions/Models/ContentScheduleCollection.cs diff --git a/src/Umbraco.Core/Models/IContent.cs b/src/Umbraco.Abstractions/Models/IContent.cs similarity index 100% rename from src/Umbraco.Core/Models/IContent.cs rename to src/Umbraco.Abstractions/Models/IContent.cs diff --git a/src/Umbraco.Core/Manifest/ManifestParser.cs b/src/Umbraco.Core/Manifest/ManifestParser.cs index bf70def9dc..35206b3e62 100644 --- a/src/Umbraco.Core/Manifest/ManifestParser.cs +++ b/src/Umbraco.Core/Manifest/ManifestParser.cs @@ -9,6 +9,7 @@ using Umbraco.Core.Exceptions; using Umbraco.Core.IO; using Umbraco.Core.Logging; using Umbraco.Core.PropertyEditors; +using Umbraco.Core.Serialization; namespace Umbraco.Core.Manifest { @@ -17,6 +18,7 @@ namespace Umbraco.Core.Manifest /// public class ManifestParser { + private readonly IJsonSerializer _jsonSerializer; private static readonly string Utf8Preamble = Encoding.UTF8.GetString(Encoding.UTF8.GetPreamble()); private readonly IAppPolicyCache _cache; @@ -30,9 +32,11 @@ namespace Umbraco.Core.Manifest /// /// Initializes a new instance of the class. /// - public ManifestParser(AppCaches appCaches, ManifestValueValidatorCollection validators, ManifestFilterCollection filters, ILogger logger, IIOHelper ioHelper) + public ManifestParser(AppCaches appCaches, ManifestValueValidatorCollection validators, ManifestFilterCollection filters, ILogger logger, IIOHelper ioHelper, IJsonSerializer jsonSerializer) : this(appCaches, validators, filters, "~/App_Plugins", logger, ioHelper) - { } + { + _jsonSerializer = jsonSerializer; + } /// /// Initializes a new instance of the class. @@ -198,7 +202,7 @@ namespace Umbraco.Core.Manifest // purely for tests internal IEnumerable ParseGridEditors(string text) { - return JsonConvert.DeserializeObject>(text); + return _jsonSerializer.Deserialize>(text); } } } diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index 7f51a855b3..ec6c053d7f 100755 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -229,7 +229,6 @@ - @@ -425,9 +424,6 @@ - - - diff --git a/src/Umbraco.Tests/Manifest/ManifestParserTests.cs b/src/Umbraco.Tests/Manifest/ManifestParserTests.cs index 0fcb7ac9e0..fcc7ccd79b 100644 --- a/src/Umbraco.Tests/Manifest/ManifestParserTests.cs +++ b/src/Umbraco.Tests/Manifest/ManifestParserTests.cs @@ -13,6 +13,7 @@ using Umbraco.Core.PropertyEditors; using Umbraco.Core.PropertyEditors.Validators; using Umbraco.Core.Services; using Umbraco.Core.Dashboards; +using Umbraco.Core.Serialization; namespace Umbraco.Tests.Manifest { @@ -44,7 +45,7 @@ namespace Umbraco.Tests.Manifest new RequiredValidator(Mock.Of()), new RegexValidator(Mock.Of(), null) }; - _parser = new ManifestParser(AppCaches.Disabled, new ManifestValueValidatorCollection(validators), new ManifestFilterCollection(Array.Empty()), Mock.Of(), Current.IOHelper); + _parser = new ManifestParser(AppCaches.Disabled, new ManifestValueValidatorCollection(validators), new ManifestFilterCollection(Array.Empty()), Mock.Of(), Current.IOHelper, new JsonNetSerializer()); } [Test] From a2551521e45e47da4318012704d4c129e659aaa8 Mon Sep 17 00:00:00 2001 From: Jan Skovgaard Date: Mon, 11 Nov 2019 20:48:52 +0100 Subject: [PATCH 42/68] Settings dashboard: Add translations (#6880) --- .../settings/settingsdashboardintro.html | 32 ++++++++++++++----- src/Umbraco.Web.UI/Umbraco/config/lang/en.xml | 30 +++++++++++++++++ .../Umbraco/config/lang/en_us.xml | 30 +++++++++++++++++ 3 files changed, 84 insertions(+), 8 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/dashboard/settings/settingsdashboardintro.html b/src/Umbraco.Web.UI.Client/src/views/dashboard/settings/settingsdashboardintro.html index cc3e57bdc4..0ad88b9894 100644 --- a/src/Umbraco.Web.UI.Client/src/views/dashboard/settings/settingsdashboardintro.html +++ b/src/Umbraco.Web.UI.Client/src/views/dashboard/settings/settingsdashboardintro.html @@ -1,14 +1,30 @@ -

Start here

-

This section contains the building blocks for your Umbraco site. Follow the below links to find out more about working with the items in the Settings section:

-
Find out more:
+

+ Start here +

+ +

This section contains the building blocks for your Umbraco site. Follow the below links to find out more about working with the items in the Settings section:

+
: +
+ Find out more: +
diff --git a/src/Umbraco.Web.UI/Umbraco/config/lang/en.xml b/src/Umbraco.Web.UI/Umbraco/config/lang/en.xml index a8c1be1829..653974a6fe 100644 --- a/src/Umbraco.Web.UI/Umbraco/config/lang/en.xml +++ b/src/Umbraco.Web.UI/Umbraco/config/lang/en.xml @@ -2303,4 +2303,34 @@ To manage your website, simply open the Umbraco back office and start adding con To get you started + + Start here + This section contains the building blocks for your Umbraco site. Follow the below links to find out more about working with the items in the Settings section + Find out more + + in the Documentation section of Our Umbraco + ]]> + + + Community Forum + ]]> + + + tutorial videos (some are free, some require a subscription) + ]]> + + + productivity boosting tools and commercial support + ]]> + + + training and certification opportunities + ]]> + + 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 cca99b1244..ee3c7199f1 100644 --- a/src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml +++ b/src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml @@ -2319,4 +2319,34 @@ To manage your website, simply open the Umbraco back office and start adding con To get you started + + Start here + This section contains the building blocks for your Umbraco site. Follow the below links to find out more about working with the items in the Settings section + Find out more + + in the Documentation section of Our Umbraco + ]]> + + + Community Forum + ]]> + + + tutorial videos (some are free, some require a subscription) + ]]> + + + productivity boosting tools and commercial support + ]]> + + + training and certification opportunities + ]]> + + From 7eef6b40370fa4cd29a112252a49efb8bd6c25b3 Mon Sep 17 00:00:00 2001 From: Bjarke Berg Date: Tue, 12 Nov 2019 08:50:31 +0100 Subject: [PATCH 43/68] https://github.com/umbraco/Umbraco-CMS/issues/7125 - Updates the projects to use the same versions as required by our nuspec --- src/Umbraco.Examine/Umbraco.Examine.csproj | 2 +- src/Umbraco.Tests/Umbraco.Tests.csproj | 2 +- src/Umbraco.Web.UI/Umbraco.Web.UI.csproj | 8 ++++---- src/Umbraco.Web/Umbraco.Web.csproj | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/Umbraco.Examine/Umbraco.Examine.csproj b/src/Umbraco.Examine/Umbraco.Examine.csproj index e28a8e674e..da22d9e809 100644 --- a/src/Umbraco.Examine/Umbraco.Examine.csproj +++ b/src/Umbraco.Examine/Umbraco.Examine.csproj @@ -48,7 +48,7 @@ - + 1.0.0-beta2-19324-01 runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/Umbraco.Tests/Umbraco.Tests.csproj b/src/Umbraco.Tests/Umbraco.Tests.csproj index 39826fcc38..2f81623309 100644 --- a/src/Umbraco.Tests/Umbraco.Tests.csproj +++ b/src/Umbraco.Tests/Umbraco.Tests.csproj @@ -79,7 +79,7 @@ - + 1.8.14 diff --git a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj index 6c20e8c765..51258de413 100644 --- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj +++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj @@ -84,9 +84,9 @@ - - - + + + @@ -429,4 +429,4 @@ - + \ No newline at end of file diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index 166eeba352..781e023f78 100755 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -60,9 +60,9 @@ - + - + 2.7.0.100 From 6da93c6fc38e95cc736d7a42b080eecf8b030b53 Mon Sep 17 00:00:00 2001 From: Bjarke Berg Date: Tue, 12 Nov 2019 10:42:39 +0100 Subject: [PATCH 44/68] AB3649 - Refactored services injected into ctor instead of methods --- src/Umbraco.Core/Models/IDataValueEditor.cs | 8 +++---- .../PropertyEditors/DataValueEditor.cs | 24 ++++++++++++------- .../Services/Implement/EntityXmlSerializer.cs | 2 +- src/Umbraco.Core/Umbraco.Core.csproj | 3 --- src/Umbraco.Tests/Models/VariationTests.cs | 13 ++++++---- .../MultiValuePropertyEditorTests.cs | 6 ++--- .../PropertyEditorValueEditorTests.cs | 10 ++++---- .../Mapping/ContentPropertyBasicMapper.cs | 2 +- .../PropertyEditors/DateValueEditor.cs | 2 +- .../PropertyEditors/GridPropertyEditor.cs | 2 +- .../ImageCropperPropertyValueEditor.cs | 8 +++---- .../MultiUrlPickerValueEditor.cs | 4 ++-- .../MultipleTextStringPropertyEditor.cs | 2 +- .../PropertyEditors/MultipleValueEditor.cs | 4 ++-- .../NestedContentPropertyEditor.cs | 12 +++++----- .../PropertyEditors/RichTextPropertyEditor.cs | 2 +- .../PropertyEditors/TextOnlyValueEditor.cs | 2 +- 17 files changed, 56 insertions(+), 50 deletions(-) diff --git a/src/Umbraco.Core/Models/IDataValueEditor.cs b/src/Umbraco.Core/Models/IDataValueEditor.cs index 5a1c6fd29d..6158711c3c 100644 --- a/src/Umbraco.Core/Models/IDataValueEditor.cs +++ b/src/Umbraco.Core/Models/IDataValueEditor.cs @@ -59,12 +59,12 @@ namespace Umbraco.Core.PropertyEditors /// /// Converts a property value to a value for the editor. /// - object ToEditor(IProperty property, IDataTypeService dataTypeService, string culture = null, string segment = null); + object ToEditor(IProperty property, string culture = null, string segment = null); // TODO: / deal with this when unplugging the xml cache // why property vs propertyType? services should be injected! etc... - IEnumerable ConvertDbToXml(IProperty property, IDataTypeService dataTypeService, ILocalizationService localizationService, bool published); - XNode ConvertDbToXml(IPropertyType propertyType, object value, IDataTypeService dataTypeService); - string ConvertDbToString(IPropertyType propertyType, object value, IDataTypeService dataTypeService); + IEnumerable ConvertDbToXml(IProperty property, bool published); + XNode ConvertDbToXml(IPropertyType propertyType, object value); + string ConvertDbToString(IPropertyType propertyType, object value); } } diff --git a/src/Umbraco.Core/PropertyEditors/DataValueEditor.cs b/src/Umbraco.Core/PropertyEditors/DataValueEditor.cs index 396d32c833..3dde5a8949 100644 --- a/src/Umbraco.Core/PropertyEditors/DataValueEditor.cs +++ b/src/Umbraco.Core/PropertyEditors/DataValueEditor.cs @@ -20,6 +20,8 @@ namespace Umbraco.Core.PropertyEditors ///
public class DataValueEditor : IDataValueEditor { + protected readonly IDataTypeService _dataTypeService; + protected readonly ILocalizationService _localizationService; private string _view; /// @@ -29,14 +31,18 @@ namespace Umbraco.Core.PropertyEditors { ValueType = ValueTypes.String; Validators = new List(); + _dataTypeService = Current.Services.DataTypeService; + _localizationService = Current.Services.LocalizationService; } /// /// Initializes a new instance of the class. /// - public DataValueEditor(string view, params IValueValidator[] validators) // not used + public DataValueEditor(IDataTypeService dataTypeService, ILocalizationService localizationService, string view, params IValueValidator[] validators) // not used : this() { + _dataTypeService = dataTypeService; + _localizationService = localizationService; View = view; Validators.AddRange(validators); } @@ -232,7 +238,7 @@ namespace Umbraco.Core.PropertyEditors /// The object returned will automatically be serialized into json notation. For most property editors /// the value returned is probably just a string but in some cases a json structure will be returned. /// - public virtual object ToEditor(IProperty property, IDataTypeService dataTypeService, string culture = null, string segment = null) + public virtual object ToEditor(IProperty property, string culture = null, string segment = null) { var val = property.GetValue(culture, segment); if (val == null) return string.Empty; @@ -283,7 +289,7 @@ namespace Umbraco.Core.PropertyEditors /// /// Converts a property to Xml fragments. /// - public IEnumerable ConvertDbToXml(IProperty property, IDataTypeService dataTypeService, ILocalizationService localizationService, bool published) + public IEnumerable ConvertDbToXml(IProperty property, bool published) { published &= property.PropertyType.SupportsPublishing; @@ -301,7 +307,7 @@ namespace Umbraco.Core.PropertyEditors if (pvalue.Segment != null) xElement.Add(new XAttribute("segment", pvalue.Segment)); - var xValue = ConvertDbToXml(property.PropertyType, value, dataTypeService); + var xValue = ConvertDbToXml(property.PropertyType, value); xElement.Add(xValue); yield return xElement; @@ -317,12 +323,12 @@ namespace Umbraco.Core.PropertyEditors /// Returns an XText or XCData instance which must be wrapped in a element. /// If the value is empty we will not return as CDATA since that will just take up more space in the file. /// - public XNode ConvertDbToXml(IPropertyType propertyType, object value, IDataTypeService dataTypeService) + public XNode ConvertDbToXml(IPropertyType propertyType, object value) { //check for null or empty value, we don't want to return CDATA if that is the case if (value == null || value.ToString().IsNullOrWhiteSpace()) { - return new XText(ConvertDbToString(propertyType, value, dataTypeService)); + return new XText(ConvertDbToString(propertyType, value)); } switch (ValueTypes.ToStorageType(ValueType)) @@ -330,11 +336,11 @@ namespace Umbraco.Core.PropertyEditors case ValueStorageType.Date: case ValueStorageType.Integer: case ValueStorageType.Decimal: - return new XText(ConvertDbToString(propertyType, value, dataTypeService)); + return new XText(ConvertDbToString(propertyType, value)); case ValueStorageType.Nvarchar: case ValueStorageType.Ntext: //put text in cdata - return new XCData(ConvertDbToString(propertyType, value, dataTypeService)); + return new XCData(ConvertDbToString(propertyType, value)); default: throw new ArgumentOutOfRangeException(); } @@ -343,7 +349,7 @@ namespace Umbraco.Core.PropertyEditors /// /// Converts a property value to a string. /// - public virtual string ConvertDbToString(IPropertyType propertyType, object value, IDataTypeService dataTypeService) + public virtual string ConvertDbToString(IPropertyType propertyType, object value) { if (value == null) return string.Empty; diff --git a/src/Umbraco.Core/Services/Implement/EntityXmlSerializer.cs b/src/Umbraco.Core/Services/Implement/EntityXmlSerializer.cs index f115dacc6c..f488c12657 100644 --- a/src/Umbraco.Core/Services/Implement/EntityXmlSerializer.cs +++ b/src/Umbraco.Core/Services/Implement/EntityXmlSerializer.cs @@ -560,7 +560,7 @@ namespace Umbraco.Core.Services.Implement var propertyEditor = Current.PropertyEditors[propertyType.PropertyEditorAlias]; return propertyEditor == null ? Array.Empty() - : propertyEditor.GetValueEditor().ConvertDbToXml(property, _dataTypeService, _localizationService, published); + : propertyEditor.GetValueEditor().ConvertDbToXml(property, published); } // exports an IContent item descendants. diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index 0bd65f784c..4532483471 100755 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -236,7 +236,6 @@ - @@ -295,8 +294,6 @@ - - diff --git a/src/Umbraco.Tests/Models/VariationTests.cs b/src/Umbraco.Tests/Models/VariationTests.cs index ab5f726894..28663a9dbe 100644 --- a/src/Umbraco.Tests/Models/VariationTests.cs +++ b/src/Umbraco.Tests/Models/VariationTests.cs @@ -8,6 +8,7 @@ using Umbraco.Core.Logging; using Umbraco.Core.Models; using Umbraco.Core.PropertyEditors; using Umbraco.Core.Services; +using Umbraco.Core.Services.Implement; using Umbraco.Tests.TestHelpers; namespace Umbraco.Tests.Models @@ -35,9 +36,12 @@ namespace Umbraco.Tests.Models var factory = Mock.Of(); Current.Factory = factory; + var dataTypeService = Mock.Of(); + var localizationService = Mock.Of(); + var dataEditors = new DataEditorCollection(new IDataEditor[] { - new DataEditor(Mock.Of()) { Alias = "editor", ExplicitValueEditor = new DataValueEditor("view") } + new DataEditor(Mock.Of()) { Alias = "editor", ExplicitValueEditor = new DataValueEditor(dataTypeService, localizationService, "view") } }); var propertyEditors = new PropertyEditorCollection(dataEditors); @@ -46,7 +50,6 @@ namespace Umbraco.Tests.Models .Setup(x => x.Configuration) .Returns(null); - var dataTypeService = Mock.Of(); Mock.Get(dataTypeService) .Setup(x => x.GetDataType(It.IsAny())) .Returns(x => dataType); @@ -75,7 +78,7 @@ namespace Umbraco.Tests.Models // 1. if exact is set to true: culture cannot be null when the ContentVariation.Culture flag is set // 2. if wildcards is set to false: fail when "*" is passed in as either culture or segment. // 3. ContentVariation flag is ignored when wildcards are used. - // 4. Empty string is considered the same as null + // 4. Empty string is considered the same as null #region Nothing @@ -141,7 +144,7 @@ namespace Umbraco.Tests.Models #endregion #region CultureAndSegment - + Assert4B(ContentVariation.CultureAndSegment, null, null, false, true, false, true); Assert4B(ContentVariation.CultureAndSegment, null, "", false, true, false, true); Assert4B(ContentVariation.CultureAndSegment, null, "*", false, false, false, true); @@ -163,7 +166,7 @@ namespace Umbraco.Tests.Models } /// - /// Asserts the result of + /// Asserts the result of /// /// /// diff --git a/src/Umbraco.Tests/PropertyEditors/MultiValuePropertyEditorTests.cs b/src/Umbraco.Tests/PropertyEditors/MultiValuePropertyEditorTests.cs index b7037eb192..7f708b6c53 100644 --- a/src/Umbraco.Tests/PropertyEditors/MultiValuePropertyEditorTests.cs +++ b/src/Umbraco.Tests/PropertyEditors/MultiValuePropertyEditorTests.cs @@ -25,7 +25,7 @@ namespace Umbraco.Tests.PropertyEditors /// to cache. Now we always just deal with strings and we'll keep the tests that show that. /// [TestFixture] - public class MultiValuePropertyEditorTests + public class MultiValuePropertyEditorTests { [Test] public void DropDownMultipleValueEditor_Format_Data_For_Cache() @@ -51,7 +51,7 @@ namespace Umbraco.Tests.PropertyEditors var valueEditor = dataType.Editor.GetValueEditor(); ((DataValueEditor) valueEditor).Configuration = dataType.Configuration; - var result = valueEditor.ConvertDbToString(prop.PropertyType, prop.GetValue(), dataTypeService); + var result = valueEditor.ConvertDbToString(prop.PropertyType, prop.GetValue()); Assert.AreEqual("Value 1,Value 2,Value 3", result); } @@ -78,7 +78,7 @@ namespace Umbraco.Tests.PropertyEditors var prop = new Property(1, new PropertyType(dataType)); prop.SetValue("Value 2"); - var result = dataType.Editor.GetValueEditor().ConvertDbToString(prop.PropertyType, prop.GetValue(), dataTypeService); + var result = dataType.Editor.GetValueEditor().ConvertDbToString(prop.PropertyType, prop.GetValue()); Assert.AreEqual("Value 2", result); } diff --git a/src/Umbraco.Tests/PropertyEditors/PropertyEditorValueEditorTests.cs b/src/Umbraco.Tests/PropertyEditors/PropertyEditorValueEditorTests.cs index 764f6ac4a4..c7e889c84b 100644 --- a/src/Umbraco.Tests/PropertyEditors/PropertyEditorValueEditorTests.cs +++ b/src/Umbraco.Tests/PropertyEditors/PropertyEditorValueEditorTests.cs @@ -52,7 +52,7 @@ namespace Umbraco.Tests.PropertyEditors ValueType = ValueTypes.String }; - var result = valueEditor.ToEditor(prop, new Mock().Object); + var result = valueEditor.ToEditor(prop); Assert.AreEqual(isOk, !(result is string)); } @@ -142,7 +142,7 @@ namespace Umbraco.Tests.PropertyEditors ValueType = valueType }; - var result = valueEditor.ToEditor(prop, new Mock().Object); + var result = valueEditor.ToEditor(prop); Assert.AreEqual(expected, result); } @@ -158,7 +158,7 @@ namespace Umbraco.Tests.PropertyEditors var prop = new Property(1, new PropertyType("test", ValueStorageType.Decimal)); prop.SetValue(value); - var result = valueEditor.ToEditor(prop, new Mock().Object); + var result = valueEditor.ToEditor(prop); Assert.AreEqual("12.34", result); } @@ -173,7 +173,7 @@ namespace Umbraco.Tests.PropertyEditors var prop = new Property(1, new PropertyType("test", ValueStorageType.Decimal)); prop.SetValue(string.Empty); - var result = valueEditor.ToEditor(prop, new Mock().Object); + var result = valueEditor.ToEditor(prop); Assert.AreEqual(string.Empty, result); } @@ -189,7 +189,7 @@ namespace Umbraco.Tests.PropertyEditors var prop = new Property(1, new PropertyType("test", ValueStorageType.Date)); prop.SetValue(now); - var result = valueEditor.ToEditor(prop, new Mock().Object); + var result = valueEditor.ToEditor(prop); Assert.AreEqual(now.ToIsoString(), result); } } diff --git a/src/Umbraco.Web/Models/Mapping/ContentPropertyBasicMapper.cs b/src/Umbraco.Web/Models/Mapping/ContentPropertyBasicMapper.cs index 4e49f2ea2a..cddcfc6d1c 100644 --- a/src/Umbraco.Web/Models/Mapping/ContentPropertyBasicMapper.cs +++ b/src/Umbraco.Web/Models/Mapping/ContentPropertyBasicMapper.cs @@ -71,7 +71,7 @@ namespace Umbraco.Web.Models.Mapping dest.Culture = culture; // if no 'IncludeProperties' were specified or this property is set to be included - we will map the value and return. - dest.Value = editor.GetValueEditor().ToEditor(property, DataTypeService, culture); + dest.Value = editor.GetValueEditor().ToEditor(property, culture); } } } diff --git a/src/Umbraco.Web/PropertyEditors/DateValueEditor.cs b/src/Umbraco.Web/PropertyEditors/DateValueEditor.cs index 657e2b2b49..bc1c5dc5f8 100644 --- a/src/Umbraco.Web/PropertyEditors/DateValueEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/DateValueEditor.cs @@ -18,7 +18,7 @@ namespace Umbraco.Web.PropertyEditors Validators.Add(new DateTimeValidator()); } - public override object ToEditor(IProperty property, IDataTypeService dataTypeService, string culture= null, string segment = null) + public override object ToEditor(IProperty property, string culture= null, string segment = null) { var date = property.GetValue(culture, segment).TryConvertTo(); if (date.Success == false || date.Result == null) diff --git a/src/Umbraco.Web/PropertyEditors/GridPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/GridPropertyEditor.cs index 5964964ab7..bae06e09c2 100644 --- a/src/Umbraco.Web/PropertyEditors/GridPropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/GridPropertyEditor.cs @@ -115,7 +115,7 @@ namespace Umbraco.Web.PropertyEditors /// /// /// - public override object ToEditor(IProperty property, IDataTypeService dataTypeService, string culture = null, string segment = null) + public override object ToEditor(IProperty property, string culture = null, string segment = null) { var val = property.GetValue(culture, segment); if (val == null) return string.Empty; diff --git a/src/Umbraco.Web/PropertyEditors/ImageCropperPropertyValueEditor.cs b/src/Umbraco.Web/PropertyEditors/ImageCropperPropertyValueEditor.cs index fdeb726902..c9ce5a9d9d 100644 --- a/src/Umbraco.Web/PropertyEditors/ImageCropperPropertyValueEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/ImageCropperPropertyValueEditor.cs @@ -32,7 +32,7 @@ namespace Umbraco.Web.PropertyEditors /// This is called to merge in the prevalue crops with the value that is saved - similar to the property value converter for the front-end /// - public override object ToEditor(IProperty property, IDataTypeService dataTypeService, string culture = null, string segment = null) + public override object ToEditor(IProperty property, string culture = null, string segment = null) { var val = property.GetValue(culture, segment); if (val == null) return null; @@ -47,7 +47,7 @@ namespace Umbraco.Web.PropertyEditors value = new ImageCropperValue { Src = val.ToString() }; } - var dataType = dataTypeService.GetDataType(property.PropertyType.DataTypeId); + var dataType = _dataTypeService.GetDataType(property.PropertyType.DataTypeId); if (dataType?.Configuration != null) value.ApplyConfiguration(dataType.ConfigurationAs()); @@ -161,7 +161,7 @@ namespace Umbraco.Web.PropertyEditors } - public override string ConvertDbToString(IPropertyType propertyType, object value, IDataTypeService dataTypeService) + public override string ConvertDbToString(IPropertyType propertyType, object value) { if (value == null || string.IsNullOrEmpty(value.ToString())) return null; @@ -172,7 +172,7 @@ namespace Umbraco.Web.PropertyEditors return val; // more magic here ;-( - var configuration = dataTypeService.GetDataType(propertyType.DataTypeId).ConfigurationAs(); + var configuration = _dataTypeService.GetDataType(propertyType.DataTypeId).ConfigurationAs(); var crops = configuration?.Crops ?? Array.Empty(); return JsonConvert.SerializeObject(new diff --git a/src/Umbraco.Web/PropertyEditors/MultiUrlPickerValueEditor.cs b/src/Umbraco.Web/PropertyEditors/MultiUrlPickerValueEditor.cs index c2ad58a101..36d40cceb8 100644 --- a/src/Umbraco.Web/PropertyEditors/MultiUrlPickerValueEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/MultiUrlPickerValueEditor.cs @@ -28,7 +28,7 @@ namespace Umbraco.Web.PropertyEditors _logger = logger ?? throw new ArgumentNullException(nameof(logger)); } - public override object ToEditor(IProperty property, IDataTypeService dataTypeService, string culture = null, string segment = null) + public override object ToEditor(IProperty property, string culture = null, string segment = null) { var value = property.GetValue(culture, segment)?.ToString(); @@ -118,7 +118,7 @@ namespace Umbraco.Web.PropertyEditors _logger.Error("Error getting links", ex); } - return base.ToEditor(property, dataTypeService, culture, segment); + return base.ToEditor(property, culture, segment); } diff --git a/src/Umbraco.Web/PropertyEditors/MultipleTextStringPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/MultipleTextStringPropertyEditor.cs index 23ceb0f22a..279bc3618a 100644 --- a/src/Umbraco.Web/PropertyEditors/MultipleTextStringPropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/MultipleTextStringPropertyEditor.cs @@ -95,7 +95,7 @@ namespace Umbraco.Web.PropertyEditors /// /// The legacy property editor saved this data as new line delimited! strange but we have to maintain that. /// - public override object ToEditor(IProperty property, IDataTypeService dataTypeService, string culture = null, string segment = null) + public override object ToEditor(IProperty property, string culture = null, string segment = null) { var val = property.GetValue(culture, segment); return val?.ToString().Split(new[] {Environment.NewLine}, StringSplitOptions.RemoveEmptyEntries) diff --git a/src/Umbraco.Web/PropertyEditors/MultipleValueEditor.cs b/src/Umbraco.Web/PropertyEditors/MultipleValueEditor.cs index 4c59a8e3c5..b46de6d092 100644 --- a/src/Umbraco.Web/PropertyEditors/MultipleValueEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/MultipleValueEditor.cs @@ -33,9 +33,9 @@ namespace Umbraco.Web.PropertyEditors /// /// /// - public override object ToEditor(IProperty property, IDataTypeService dataTypeService, string culture = null, string segment = null) + public override object ToEditor(IProperty property, string culture = null, string segment = null) { - var json = base.ToEditor(property, dataTypeService, culture, segment).ToString(); + var json = base.ToEditor(property, culture, segment).ToString(); return JsonConvert.DeserializeObject(json) ?? Array.Empty(); } diff --git a/src/Umbraco.Web/PropertyEditors/NestedContentPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/NestedContentPropertyEditor.cs index 778b69d9db..8784a9bb49 100644 --- a/src/Umbraco.Web/PropertyEditors/NestedContentPropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/NestedContentPropertyEditor.cs @@ -92,7 +92,7 @@ namespace Umbraco.Web.PropertyEditors #region DB to String - public override string ConvertDbToString(IPropertyType propertyType, object propertyValue, IDataTypeService dataTypeService) + public override string ConvertDbToString(IPropertyType propertyType, object propertyValue) { if (propertyValue == null || string.IsNullOrWhiteSpace(propertyValue.ToString())) return string.Empty; @@ -129,9 +129,9 @@ namespace Umbraco.Web.PropertyEditors { continue; } - var tempConfig = dataTypeService.GetDataType(propType.DataTypeId).Configuration; + var tempConfig = _dataTypeService.GetDataType(propType.DataTypeId).Configuration; var valEditor = propEditor.GetValueEditor(tempConfig); - var convValue = valEditor.ConvertDbToString(propType, propValues[propAlias]?.ToString(), dataTypeService); + var convValue = valEditor.ConvertDbToString(propType, propValues[propAlias]?.ToString()); propValues[propAlias] = convValue; } catch (InvalidOperationException) @@ -152,7 +152,7 @@ namespace Umbraco.Web.PropertyEditors // note: there is NO variant support here - public override object ToEditor(IProperty property, IDataTypeService dataTypeService, string culture = null, string segment = null) + public override object ToEditor(IProperty property, string culture = null, string segment = null) { var val = property.GetValue(culture, segment); if (val == null || string.IsNullOrWhiteSpace(val.ToString())) @@ -197,9 +197,9 @@ namespace Umbraco.Web.PropertyEditors propValues[propAlias] = tempProp.GetValue()?.ToString(); continue; } - var tempConfig = dataTypeService.GetDataType(propType.DataTypeId).Configuration; + var tempConfig = _dataTypeService.GetDataType(propType.DataTypeId).Configuration; var valEditor = propEditor.GetValueEditor(tempConfig); - var convValue = valEditor.ToEditor(tempProp, dataTypeService); + var convValue = valEditor.ToEditor(tempProp); propValues[propAlias] = convValue == null ? null : JToken.FromObject(convValue); } catch (InvalidOperationException) diff --git a/src/Umbraco.Web/PropertyEditors/RichTextPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/RichTextPropertyEditor.cs index 1fa2c9323b..6932504f06 100644 --- a/src/Umbraco.Web/PropertyEditors/RichTextPropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/RichTextPropertyEditor.cs @@ -92,7 +92,7 @@ namespace Umbraco.Web.PropertyEditors /// /// /// - public override object ToEditor(IProperty property, IDataTypeService dataTypeService, string culture = null, string segment = null) + public override object ToEditor(IProperty property, string culture = null, string segment = null) { var val = property.GetValue(culture, segment); if (val == null) diff --git a/src/Umbraco.Web/PropertyEditors/TextOnlyValueEditor.cs b/src/Umbraco.Web/PropertyEditors/TextOnlyValueEditor.cs index f925daba30..826051a79b 100644 --- a/src/Umbraco.Web/PropertyEditors/TextOnlyValueEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/TextOnlyValueEditor.cs @@ -26,7 +26,7 @@ namespace Umbraco.Web.PropertyEditors /// /// The object returned will always be a string and if the database type is not a valid string type an exception is thrown /// - public override object ToEditor(IProperty property, IDataTypeService dataTypeService, string culture = null, string segment = null) + public override object ToEditor(IProperty property, string culture = null, string segment = null) { var val = property.GetValue(culture, segment); From 94f5894b7427acdb0c664ec169cd656343865aa0 Mon Sep 17 00:00:00 2001 From: Bjarke Berg Date: Tue, 12 Nov 2019 10:59:04 +0100 Subject: [PATCH 45/68] AB3649 - Moved manifest stuff --- .../Manifest/IManifestFilter.cs | 0 .../Manifest/ManifestDashboard.cs | 16 +- .../Manifest/ManifestFilterCollection.cs | 0 .../ManifestFilterCollectionBuilder.cs | 0 .../Manifest/PackageManifest.cs | 141 +++++++++--------- .../Models/IDataValueEditor.cs | 1 - .../PropertyEditors/IDataEditor.cs | 0 src/Umbraco.Core/Umbraco.Core.csproj | 7 - 8 files changed, 79 insertions(+), 86 deletions(-) rename src/{Umbraco.Core => Umbraco.Abstractions}/Manifest/IManifestFilter.cs (100%) rename src/{Umbraco.Core => Umbraco.Abstractions}/Manifest/ManifestDashboard.cs (58%) rename src/{Umbraco.Core => Umbraco.Abstractions}/Manifest/ManifestFilterCollection.cs (100%) rename src/{Umbraco.Core => Umbraco.Abstractions}/Manifest/ManifestFilterCollectionBuilder.cs (100%) rename src/{Umbraco.Core => Umbraco.Abstractions}/Manifest/PackageManifest.cs (83%) rename src/{Umbraco.Core => Umbraco.Abstractions}/Models/IDataValueEditor.cs (98%) rename src/{Umbraco.Core => Umbraco.Abstractions}/PropertyEditors/IDataEditor.cs (100%) diff --git a/src/Umbraco.Core/Manifest/IManifestFilter.cs b/src/Umbraco.Abstractions/Manifest/IManifestFilter.cs similarity index 100% rename from src/Umbraco.Core/Manifest/IManifestFilter.cs rename to src/Umbraco.Abstractions/Manifest/IManifestFilter.cs diff --git a/src/Umbraco.Core/Manifest/ManifestDashboard.cs b/src/Umbraco.Abstractions/Manifest/ManifestDashboard.cs similarity index 58% rename from src/Umbraco.Core/Manifest/ManifestDashboard.cs rename to src/Umbraco.Abstractions/Manifest/ManifestDashboard.cs index 2642ca3646..2368f07a0b 100644 --- a/src/Umbraco.Core/Manifest/ManifestDashboard.cs +++ b/src/Umbraco.Abstractions/Manifest/ManifestDashboard.cs @@ -1,28 +1,28 @@ using System; using System.ComponentModel; -using Newtonsoft.Json; -using Umbraco.Core.Composing; +using System.Runtime.Serialization; using Umbraco.Core.Dashboards; -using Umbraco.Core.IO; namespace Umbraco.Core.Manifest { + [DataContract] public class ManifestDashboard : IDashboard { - [JsonProperty("alias", Required = Required.Always)] + [DataMember(Name = "alias", IsRequired = true)] public string Alias { get; set; } - [JsonProperty("weight", DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)] + //TODO this needs to be tested manually! + //[JsonProperty("weight", DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)] [DefaultValue(100)] // must be equal to DashboardCollectionBuilder.DefaultWeight public int Weight { get; set; } - [JsonProperty("view", Required = Required.Always)] + [DataMember(Name = "view", IsRequired = true)] public string View { get; set; } - [JsonProperty("sections")] + [DataMember(Name = "sections")] public string[] Sections { get; set; } = Array.Empty(); - [JsonProperty("access")] + [DataMember(Name = "access")] public IAccessRule[] AccessRules { get; set; } = Array.Empty(); } } diff --git a/src/Umbraco.Core/Manifest/ManifestFilterCollection.cs b/src/Umbraco.Abstractions/Manifest/ManifestFilterCollection.cs similarity index 100% rename from src/Umbraco.Core/Manifest/ManifestFilterCollection.cs rename to src/Umbraco.Abstractions/Manifest/ManifestFilterCollection.cs diff --git a/src/Umbraco.Core/Manifest/ManifestFilterCollectionBuilder.cs b/src/Umbraco.Abstractions/Manifest/ManifestFilterCollectionBuilder.cs similarity index 100% rename from src/Umbraco.Core/Manifest/ManifestFilterCollectionBuilder.cs rename to src/Umbraco.Abstractions/Manifest/ManifestFilterCollectionBuilder.cs diff --git a/src/Umbraco.Core/Manifest/PackageManifest.cs b/src/Umbraco.Abstractions/Manifest/PackageManifest.cs similarity index 83% rename from src/Umbraco.Core/Manifest/PackageManifest.cs rename to src/Umbraco.Abstractions/Manifest/PackageManifest.cs index e50eb69467..5e10030693 100644 --- a/src/Umbraco.Core/Manifest/PackageManifest.cs +++ b/src/Umbraco.Abstractions/Manifest/PackageManifest.cs @@ -1,70 +1,71 @@ -using System; -using Newtonsoft.Json; -using Umbraco.Core.PropertyEditors; - -namespace Umbraco.Core.Manifest -{ - /// - /// Represents the content of a package manifest. - /// - public class PackageManifest - { - /// - /// Gets the source path of the manifest. - /// - /// - /// Gets the full absolute file path of the manifest, - /// using system directory separators. - /// - [JsonIgnore] - public string Source { get; set; } - - /// - /// Gets or sets the scripts listed in the manifest. - /// - [JsonProperty("javascript")] - public string[] Scripts { get; set; } = Array.Empty(); - - /// - /// Gets or sets the stylesheets listed in the manifest. - /// - [JsonProperty("css")] - public string[] Stylesheets { get; set; } = Array.Empty(); - - /// - /// Gets or sets the property editors listed in the manifest. - /// - [JsonProperty("propertyEditors")] - public IDataEditor[] PropertyEditors { get; set; } = Array.Empty(); - - /// - /// Gets or sets the parameter editors listed in the manifest. - /// - [JsonProperty("parameterEditors")] - public IDataEditor[] ParameterEditors { get; set; } = Array.Empty(); - - /// - /// Gets or sets the grid editors listed in the manifest. - /// - [JsonProperty("gridEditors")] - public GridEditor[] GridEditors { get; set; } = Array.Empty(); - - /// - /// Gets or sets the content apps listed in the manifest. - /// - [JsonProperty("contentApps")] - public ManifestContentAppDefinition[] ContentApps { get; set; } = Array.Empty(); - - /// - /// Gets or sets the dashboards listed in the manifest. - /// - [JsonProperty("dashboards")] - public ManifestDashboard[] Dashboards { get; set; } = Array.Empty(); - - /// - /// Gets or sets the sections listed in the manifest. - /// - [JsonProperty("sections")] - public ManifestSection[] Sections { get; set; } = Array.Empty(); - } -} +using System; +using System.Runtime.Serialization; +using Umbraco.Core.PropertyEditors; + +namespace Umbraco.Core.Manifest +{ + /// + /// Represents the content of a package manifest. + /// + [DataContract] + public class PackageManifest + { + /// + /// Gets the source path of the manifest. + /// + /// + /// Gets the full absolute file path of the manifest, + /// using system directory separators. + /// + [IgnoreDataMember] + public string Source { get; set; } + + /// + /// Gets or sets the scripts listed in the manifest. + /// + [DataMember(Name = "javascript")] + public string[] Scripts { get; set; } = Array.Empty(); + + /// + /// Gets or sets the stylesheets listed in the manifest. + /// + [DataMember(Name = "css")] + public string[] Stylesheets { get; set; } = Array.Empty(); + + /// + /// Gets or sets the property editors listed in the manifest. + /// + [DataMember(Name = "propertyEditors")] + public IDataEditor[] PropertyEditors { get; set; } = Array.Empty(); + + /// + /// Gets or sets the parameter editors listed in the manifest. + /// + [DataMember(Name = "parameterEditors")] + public IDataEditor[] ParameterEditors { get; set; } = Array.Empty(); + + /// + /// Gets or sets the grid editors listed in the manifest. + /// + [DataMember(Name = "gridEditors")] + public GridEditor[] GridEditors { get; set; } = Array.Empty(); + + /// + /// Gets or sets the content apps listed in the manifest. + /// + [DataMember(Name = "contentApps")] + public ManifestContentAppDefinition[] ContentApps { get; set; } = Array.Empty(); + + /// + /// Gets or sets the dashboards listed in the manifest. + /// + [DataMember(Name = "dashboards")] + public ManifestDashboard[] Dashboards { get; set; } = Array.Empty(); + + /// + /// Gets or sets the sections listed in the manifest. + /// + [DataMember(Name = "sections")] + public ManifestSection[] Sections { get; set; } = Array.Empty(); + } +} diff --git a/src/Umbraco.Core/Models/IDataValueEditor.cs b/src/Umbraco.Abstractions/Models/IDataValueEditor.cs similarity index 98% rename from src/Umbraco.Core/Models/IDataValueEditor.cs rename to src/Umbraco.Abstractions/Models/IDataValueEditor.cs index 6158711c3c..e095f3aa31 100644 --- a/src/Umbraco.Core/Models/IDataValueEditor.cs +++ b/src/Umbraco.Abstractions/Models/IDataValueEditor.cs @@ -3,7 +3,6 @@ using System.ComponentModel.DataAnnotations; using System.Xml.Linq; using Umbraco.Core.Models; using Umbraco.Core.Models.Editors; -using Umbraco.Core.Services; namespace Umbraco.Core.PropertyEditors { diff --git a/src/Umbraco.Core/PropertyEditors/IDataEditor.cs b/src/Umbraco.Abstractions/PropertyEditors/IDataEditor.cs similarity index 100% rename from src/Umbraco.Core/PropertyEditors/IDataEditor.cs rename to src/Umbraco.Abstractions/PropertyEditors/IDataEditor.cs diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index a356da0902..95373f4c21 100755 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -184,9 +184,6 @@ - - - @@ -225,7 +222,6 @@ - @@ -276,7 +272,6 @@ - @@ -379,7 +374,6 @@ - @@ -540,7 +534,6 @@ - From c016a48b364818fe919e58dacc5671db4ccc3f32 Mon Sep 17 00:00:00 2001 From: Bjarke Berg Date: Tue, 12 Nov 2019 11:06:50 +0100 Subject: [PATCH 46/68] AB3649 - Extracted IManifestParser --- .../Manifest/IManifestParser.cs | 23 +++++++++++++++++++ src/Umbraco.Core/Manifest/ManifestParser.cs | 6 ++--- 2 files changed, 26 insertions(+), 3 deletions(-) create mode 100644 src/Umbraco.Abstractions/Manifest/IManifestParser.cs diff --git a/src/Umbraco.Abstractions/Manifest/IManifestParser.cs b/src/Umbraco.Abstractions/Manifest/IManifestParser.cs new file mode 100644 index 0000000000..eeb0c756f6 --- /dev/null +++ b/src/Umbraco.Abstractions/Manifest/IManifestParser.cs @@ -0,0 +1,23 @@ +using System.Collections.Generic; +using Umbraco.Core.PropertyEditors; + +namespace Umbraco.Core.Manifest +{ + public interface IManifestParser + { + string Path { get; set; } + + /// + /// Gets all manifests, merged into a single manifest object. + /// + /// + PackageManifest Manifest { get; } + + /// + /// Parses a manifest. + /// + PackageManifest ParseManifest(string text); + + IEnumerable ParseGridEditors(string text); + } +} diff --git a/src/Umbraco.Core/Manifest/ManifestParser.cs b/src/Umbraco.Core/Manifest/ManifestParser.cs index 35206b3e62..6b370d2641 100644 --- a/src/Umbraco.Core/Manifest/ManifestParser.cs +++ b/src/Umbraco.Core/Manifest/ManifestParser.cs @@ -16,7 +16,7 @@ namespace Umbraco.Core.Manifest /// /// Parses the Main.js file and replaces all tokens accordingly. /// - public class ManifestParser + public class ManifestParser : IManifestParser { private readonly IJsonSerializer _jsonSerializer; private static readonly string Utf8Preamble = Encoding.UTF8.GetString(Encoding.UTF8.GetPreamble()); @@ -161,7 +161,7 @@ namespace Umbraco.Core.Manifest /// /// Parses a manifest. /// - internal PackageManifest ParseManifest(string text) + public PackageManifest ParseManifest(string text) { if (string.IsNullOrWhiteSpace(text)) throw new ArgumentNullOrEmptyException(nameof(text)); @@ -200,7 +200,7 @@ namespace Umbraco.Core.Manifest } // purely for tests - internal IEnumerable ParseGridEditors(string text) + public IEnumerable ParseGridEditors(string text) { return _jsonSerializer.Deserialize>(text); } From 10622cc430dc535beb745d9d7b9d7c24c342ae82 Mon Sep 17 00:00:00 2001 From: Jeavon Date: Tue, 12 Nov 2019 10:26:25 +0000 Subject: [PATCH 47/68] Switched to using a dummy Uri so that runtimeState isn't needed as per review --- src/Umbraco.Examine/MediaValueSetBuilder.cs | 9 ++++----- .../UmbracoExamine/IndexInitializer.cs | 13 +------------ 2 files changed, 5 insertions(+), 17 deletions(-) diff --git a/src/Umbraco.Examine/MediaValueSetBuilder.cs b/src/Umbraco.Examine/MediaValueSetBuilder.cs index 20c92eb982..3e5b9865cc 100644 --- a/src/Umbraco.Examine/MediaValueSetBuilder.cs +++ b/src/Umbraco.Examine/MediaValueSetBuilder.cs @@ -16,16 +16,14 @@ namespace Umbraco.Examine { private readonly UrlSegmentProviderCollection _urlSegmentProviders; private readonly IUserService _userService; - private readonly IRuntimeState _runtimeState; public MediaValueSetBuilder(PropertyEditorCollection propertyEditors, UrlSegmentProviderCollection urlSegmentProviders, - IUserService userService, IRuntimeState runtimeState) + IUserService userService) : base(propertyEditors, false) { _urlSegmentProviders = urlSegmentProviders; _userService = userService; - _runtimeState = runtimeState; } /// @@ -55,8 +53,9 @@ namespace Umbraco.Examine if (!string.IsNullOrEmpty(umbracoFilePath)) { - var uri = new Uri(_runtimeState.ApplicationUrl.GetLeftPart(UriPartial.Authority) + umbracoFilePath); - umbracoFile = uri.Segments.Last(); + // intentional dummy Uri + var uri = new Uri("https://localhost/" + umbracoFilePath); + umbracoFile = uri.Segments.Last(); } var values = new Dictionary> diff --git a/src/Umbraco.Tests/UmbracoExamine/IndexInitializer.cs b/src/Umbraco.Tests/UmbracoExamine/IndexInitializer.cs index 5c9c965cd1..6c65ae8345 100644 --- a/src/Umbraco.Tests/UmbracoExamine/IndexInitializer.cs +++ b/src/Umbraco.Tests/UmbracoExamine/IndexInitializer.cs @@ -45,21 +45,10 @@ namespace Umbraco.Tests.UmbracoExamine public static MediaIndexPopulator GetMediaIndexRebuilder(PropertyEditorCollection propertyEditors, IMediaService mediaService) { - var mediaValueSetBuilder = new MediaValueSetBuilder(propertyEditors, new UrlSegmentProviderCollection(new[] { new DefaultUrlSegmentProvider() }), GetMockUserService(), MockRuntimeState(RuntimeLevel.Run)); + var mediaValueSetBuilder = new MediaValueSetBuilder(propertyEditors, new UrlSegmentProviderCollection(new[] { new DefaultUrlSegmentProvider() }), GetMockUserService()); var mediaIndexDataSource = new MediaIndexPopulator(null, mediaService, mediaValueSetBuilder); return mediaIndexDataSource; } - - public static IRuntimeState MockRuntimeState(RuntimeLevel level) - { - var runtimeState = Mock.Of(); - Mock.Get(runtimeState).Setup(x => x.Level).Returns(level); - Mock.Get(runtimeState).SetupGet(m => m.ApplicationUrl).Returns(new Uri("https://localhost/umbraco")); - - return runtimeState; - } - - public static IContentService GetMockContentService() { long longTotalRecs; From 9b4c26bf7e8ab9c93f26167b72f330ac5770fadf Mon Sep 17 00:00:00 2001 From: Bjarke Berg Date: Tue, 12 Nov 2019 13:40:07 +0100 Subject: [PATCH 48/68] AB3649 - Fixed tests --- .../Manifest/ManifestDashboard.cs | 6 +-- .../Manifest/DataEditorConverter.cs | 11 ++-- src/Umbraco.Core/Manifest/ManifestParser.cs | 13 +++-- .../PropertyEditors/DataEditor.cs | 2 +- .../PropertyEditors/DataValueEditor.cs | 22 +++----- .../PropertyEditors/LabelPropertyEditor.cs | 10 ++-- .../CoreThings/ObjectExtensionsTests.cs | 6 +-- .../Manifest/ManifestParserTests.cs | 2 +- .../Models/ContentExtensionsTests.cs | 2 +- src/Umbraco.Tests/Models/ContentTests.cs | 4 +- .../Mapping/ContentTypeModelMappingTests.cs | 3 +- .../Mapping/ContentWebModelMappingTests.cs | 2 +- src/Umbraco.Tests/Models/MediaXmlTest.cs | 4 +- src/Umbraco.Tests/Models/VariationTests.cs | 2 +- .../PropertyEditors/ImageCropperTest.cs | 2 +- .../MultiValuePropertyEditorTests.cs | 4 +- .../PropertyEditorValueEditorTests.cs | 50 ++++--------------- .../Published/NestedContentTests.cs | 6 ++- .../PublishedContentTestBase.cs | 8 ++- .../PublishedContent/PublishedContentTests.cs | 5 +- .../PropertyValidationServiceTests.cs | 4 +- src/Umbraco.Tests/TestHelpers/TestHelper.cs | 16 ++++++ .../CheckBoxListPropertyEditor.cs | 8 ++- .../PropertyEditors/DateValueEditor.cs | 4 +- .../DropDownFlexiblePropertyEditor.cs | 8 ++- .../FileUploadPropertyEditor.cs | 9 +++- .../FileUploadPropertyValueEditor.cs | 7 +-- .../PropertyEditors/GridPropertyEditor.cs | 12 +++-- .../ImageCropperPropertyEditor.cs | 6 ++- .../ImageCropperPropertyValueEditor.cs | 4 +- .../MultiUrlPickerPropertyEditor.cs | 8 ++- .../MultiUrlPickerValueEditor.cs | 2 +- .../MultipleTextStringPropertyEditor.cs | 7 +-- .../PropertyEditors/MultipleValueEditor.cs | 4 +- .../NestedContentPropertyEditor.cs | 12 +++-- .../PropertyEditors/RichTextPropertyEditor.cs | 18 +++++-- .../PropertyEditors/TagsPropertyEditor.cs | 8 +-- .../PropertyEditors/TextAreaPropertyEditor.cs | 13 +++-- .../PropertyEditors/TextOnlyValueEditor.cs | 4 +- .../PropertyEditors/TextboxPropertyEditor.cs | 13 +++-- 40 files changed, 191 insertions(+), 140 deletions(-) diff --git a/src/Umbraco.Abstractions/Manifest/ManifestDashboard.cs b/src/Umbraco.Abstractions/Manifest/ManifestDashboard.cs index 2368f07a0b..2d6f96b5c2 100644 --- a/src/Umbraco.Abstractions/Manifest/ManifestDashboard.cs +++ b/src/Umbraco.Abstractions/Manifest/ManifestDashboard.cs @@ -11,10 +11,8 @@ namespace Umbraco.Core.Manifest [DataMember(Name = "alias", IsRequired = true)] public string Alias { get; set; } - //TODO this needs to be tested manually! - //[JsonProperty("weight", DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)] - [DefaultValue(100)] // must be equal to DashboardCollectionBuilder.DefaultWeight - public int Weight { get; set; } + [DataMember(Name = "weight")] + public int Weight { get; set; } = 100; [DataMember(Name = "view", IsRequired = true)] public string View { get; set; } diff --git a/src/Umbraco.Core/Manifest/DataEditorConverter.cs b/src/Umbraco.Core/Manifest/DataEditorConverter.cs index 86347d3894..437d1eb159 100644 --- a/src/Umbraco.Core/Manifest/DataEditorConverter.cs +++ b/src/Umbraco.Core/Manifest/DataEditorConverter.cs @@ -6,6 +6,7 @@ using Umbraco.Core.IO; using Umbraco.Core.Logging; using Umbraco.Core.PropertyEditors; using Umbraco.Core.Serialization; +using Umbraco.Core.Services; namespace Umbraco.Core.Manifest { @@ -16,14 +17,18 @@ namespace Umbraco.Core.Manifest { private readonly ILogger _logger; private readonly IIOHelper _ioHelper; + private readonly IDataTypeService _dataTypeService; + private readonly ILocalizationService _localizationService; /// /// Initializes a new instance of the class. /// - public DataEditorConverter(ILogger logger, IIOHelper ioHelper) + public DataEditorConverter(ILogger logger, IIOHelper ioHelper, IDataTypeService dataTypeService, ILocalizationService localizationService) { _logger = logger; _ioHelper = ioHelper; + _dataTypeService = dataTypeService; + _localizationService = localizationService; } /// @@ -78,7 +83,7 @@ namespace Umbraco.Core.Manifest // explicitly assign a value editor of type ValueEditor // (else the deserializer will try to read it before setting it) // (and besides it's an interface) - target.ExplicitValueEditor = new DataValueEditor(); + target.ExplicitValueEditor = new DataValueEditor(_dataTypeService, _localizationService); // in the manifest, validators are a simple dictionary eg // { @@ -150,7 +155,7 @@ namespace Umbraco.Core.Manifest if (jobject.Property("view") != null) { // explicitly assign a value editor of type ParameterValueEditor - target.ExplicitValueEditor = new DataValueEditor(); + target.ExplicitValueEditor = new DataValueEditor(_dataTypeService, _localizationService); // move the 'view' property jobject["editor"] = new JObject { ["view"] = jobject["view"] }; diff --git a/src/Umbraco.Core/Manifest/ManifestParser.cs b/src/Umbraco.Core/Manifest/ManifestParser.cs index 6b370d2641..75fdde487c 100644 --- a/src/Umbraco.Core/Manifest/ManifestParser.cs +++ b/src/Umbraco.Core/Manifest/ManifestParser.cs @@ -10,6 +10,7 @@ using Umbraco.Core.IO; using Umbraco.Core.Logging; using Umbraco.Core.PropertyEditors; using Umbraco.Core.Serialization; +using Umbraco.Core.Services; namespace Umbraco.Core.Manifest { @@ -24,6 +25,8 @@ namespace Umbraco.Core.Manifest private readonly IAppPolicyCache _cache; private readonly ILogger _logger; private readonly IIOHelper _ioHelper; + private readonly IDataTypeService _dataTypeService; + private readonly ILocalizationService _localizationService; private readonly ManifestValueValidatorCollection _validators; private readonly ManifestFilterCollection _filters; @@ -32,8 +35,8 @@ namespace Umbraco.Core.Manifest /// /// Initializes a new instance of the class. /// - public ManifestParser(AppCaches appCaches, ManifestValueValidatorCollection validators, ManifestFilterCollection filters, ILogger logger, IIOHelper ioHelper, IJsonSerializer jsonSerializer) - : this(appCaches, validators, filters, "~/App_Plugins", logger, ioHelper) + public ManifestParser(AppCaches appCaches, ManifestValueValidatorCollection validators, ManifestFilterCollection filters, ILogger logger, IIOHelper ioHelper, IDataTypeService dataTypeService, ILocalizationService localizationService, IJsonSerializer jsonSerializer) + : this(appCaches, validators, filters, "~/App_Plugins", logger, ioHelper, dataTypeService, localizationService) { _jsonSerializer = jsonSerializer; } @@ -41,11 +44,13 @@ namespace Umbraco.Core.Manifest /// /// Initializes a new instance of the class. /// - private ManifestParser(AppCaches appCaches, ManifestValueValidatorCollection validators, ManifestFilterCollection filters, string path, ILogger logger, IIOHelper ioHelper) + private ManifestParser(AppCaches appCaches, ManifestValueValidatorCollection validators, ManifestFilterCollection filters, string path, ILogger logger, IIOHelper ioHelper, IDataTypeService dataTypeService, ILocalizationService localizationService) { if (appCaches == null) throw new ArgumentNullException(nameof(appCaches)); _cache = appCaches.RuntimeCache; _ioHelper = ioHelper; + _dataTypeService = dataTypeService; + _localizationService = localizationService; _validators = validators ?? throw new ArgumentNullException(nameof(validators)); _filters = filters ?? throw new ArgumentNullException(nameof(filters)); if (string.IsNullOrWhiteSpace(path)) throw new ArgumentNullOrEmptyException(nameof(path)); @@ -167,7 +172,7 @@ namespace Umbraco.Core.Manifest throw new ArgumentNullOrEmptyException(nameof(text)); var manifest = JsonConvert.DeserializeObject(text, - new DataEditorConverter(_logger, _ioHelper), + new DataEditorConverter(_logger, _ioHelper, _dataTypeService, _localizationService), new ValueValidatorConverter(_validators), new DashboardAccessRuleConverter()); diff --git a/src/Umbraco.Core/PropertyEditors/DataEditor.cs b/src/Umbraco.Core/PropertyEditors/DataEditor.cs index dbb2fc467e..047c0f0683 100644 --- a/src/Umbraco.Core/PropertyEditors/DataEditor.cs +++ b/src/Umbraco.Core/PropertyEditors/DataEditor.cs @@ -165,7 +165,7 @@ namespace Umbraco.Core.PropertyEditors if (Attribute == null) throw new InvalidOperationException("The editor does not specify a view."); - return new DataValueEditor(Attribute); + return new DataValueEditor(Current.Services.DataTypeService, Current.Services.LocalizationService, Attribute); } /// diff --git a/src/Umbraco.Core/PropertyEditors/DataValueEditor.cs b/src/Umbraco.Core/PropertyEditors/DataValueEditor.cs index 3dde5a8949..d93ead5838 100644 --- a/src/Umbraco.Core/PropertyEditors/DataValueEditor.cs +++ b/src/Umbraco.Core/PropertyEditors/DataValueEditor.cs @@ -27,31 +27,18 @@ namespace Umbraco.Core.PropertyEditors /// /// Initializes a new instance of the class. /// - public DataValueEditor() // for tests, and manifest + public DataValueEditor(IDataTypeService dataTypeService, ILocalizationService localizationService) // for tests, and manifest { ValueType = ValueTypes.String; Validators = new List(); - _dataTypeService = Current.Services.DataTypeService; - _localizationService = Current.Services.LocalizationService; - } - - /// - /// Initializes a new instance of the class. - /// - public DataValueEditor(IDataTypeService dataTypeService, ILocalizationService localizationService, string view, params IValueValidator[] validators) // not used - : this() - { _dataTypeService = dataTypeService; _localizationService = localizationService; - View = view; - Validators.AddRange(validators); } /// /// Initializes a new instance of the class. /// - public DataValueEditor(DataEditorAttribute attribute) - : this() + public DataValueEditor(IDataTypeService dataTypeService, ILocalizationService localizationService, DataEditorAttribute attribute) { if (attribute == null) throw new ArgumentNullException(nameof(attribute)); @@ -62,6 +49,9 @@ namespace Umbraco.Core.PropertyEditors View = view; ValueType = attribute.ValueType; HideLabel = attribute.HideLabel; + + _dataTypeService = dataTypeService; + _localizationService = localizationService; } /// @@ -116,7 +106,7 @@ namespace Umbraco.Core.PropertyEditors /// A collection of validators for the pre value editor /// [JsonProperty("validation")] - public List Validators { get; private set; } + public List Validators { get; private set; } = new List(); /// /// Gets the validator used to validate the special property type -level "required". diff --git a/src/Umbraco.Core/PropertyEditors/LabelPropertyEditor.cs b/src/Umbraco.Core/PropertyEditors/LabelPropertyEditor.cs index 60b7d55c01..e47d35107a 100644 --- a/src/Umbraco.Core/PropertyEditors/LabelPropertyEditor.cs +++ b/src/Umbraco.Core/PropertyEditors/LabelPropertyEditor.cs @@ -1,4 +1,6 @@ -using Umbraco.Core.Logging; +using Umbraco.Core.Composing; +using Umbraco.Core.Logging; +using Umbraco.Core.Services; namespace Umbraco.Core.PropertyEditors { @@ -20,7 +22,7 @@ namespace Umbraco.Core.PropertyEditors { } /// - protected override IDataValueEditor CreateValueEditor() => new LabelPropertyValueEditor(Attribute); + protected override IDataValueEditor CreateValueEditor() => new LabelPropertyValueEditor(Current.Services.DataTypeService, Current.Services.LocalizationService, Attribute); /// protected override IConfigurationEditor CreateConfigurationEditor() => new LabelConfigurationEditor(); @@ -28,8 +30,8 @@ namespace Umbraco.Core.PropertyEditors // provides the property value editor internal class LabelPropertyValueEditor : DataValueEditor { - public LabelPropertyValueEditor(DataEditorAttribute attribute) - : base(attribute) + public LabelPropertyValueEditor(IDataTypeService dataTypeService, ILocalizationService localizationService, DataEditorAttribute attribute) + : base(dataTypeService, localizationService, attribute) { } /// diff --git a/src/Umbraco.Tests/CoreThings/ObjectExtensionsTests.cs b/src/Umbraco.Tests/CoreThings/ObjectExtensionsTests.cs index 486d35540c..544c6335e1 100644 --- a/src/Umbraco.Tests/CoreThings/ObjectExtensionsTests.cs +++ b/src/Umbraco.Tests/CoreThings/ObjectExtensionsTests.cs @@ -7,6 +7,7 @@ using System.Web.UI.WebControls; using NUnit.Framework; using Umbraco.Core; using Umbraco.Core.PropertyEditors; +using Umbraco.Tests.TestHelpers; namespace Umbraco.Tests.CoreThings { @@ -300,10 +301,7 @@ namespace Umbraco.Tests.CoreThings [Test] public void Value_Editor_Can_Convert_Decimal_To_Decimal_Clr_Type() { - var valueEditor = new DataValueEditor - { - ValueType = ValueTypes.Decimal - }; + var valueEditor = TestHelper.CreateDataValueEditor(ValueTypes.Decimal); var result = valueEditor.TryConvertValueToCrlType(12.34d); Assert.IsTrue(result.Success); diff --git a/src/Umbraco.Tests/Manifest/ManifestParserTests.cs b/src/Umbraco.Tests/Manifest/ManifestParserTests.cs index fcc7ccd79b..936138155e 100644 --- a/src/Umbraco.Tests/Manifest/ManifestParserTests.cs +++ b/src/Umbraco.Tests/Manifest/ManifestParserTests.cs @@ -45,7 +45,7 @@ namespace Umbraco.Tests.Manifest new RequiredValidator(Mock.Of()), new RegexValidator(Mock.Of(), null) }; - _parser = new ManifestParser(AppCaches.Disabled, new ManifestValueValidatorCollection(validators), new ManifestFilterCollection(Array.Empty()), Mock.Of(), Current.IOHelper, new JsonNetSerializer()); + _parser = new ManifestParser(AppCaches.Disabled, new ManifestValueValidatorCollection(validators), new ManifestFilterCollection(Array.Empty()), Mock.Of(), Current.IOHelper, Mock.Of(), Mock.Of(), new JsonNetSerializer()); } [Test] diff --git a/src/Umbraco.Tests/Models/ContentExtensionsTests.cs b/src/Umbraco.Tests/Models/ContentExtensionsTests.cs index 42d7f0e01b..52cf5ddef5 100644 --- a/src/Umbraco.Tests/Models/ContentExtensionsTests.cs +++ b/src/Umbraco.Tests/Models/ContentExtensionsTests.cs @@ -32,7 +32,7 @@ namespace Umbraco.Tests.Models Composition.Register(_ => Mock.Of()); // all this is required so we can validate properties... - var editor = new TextboxPropertyEditor(Mock.Of()) { Alias = "test" }; + var editor = new TextboxPropertyEditor(Mock.Of(), Mock.Of(), Mock.Of()) { Alias = "test" }; Composition.Register(_ => new DataEditorCollection(new[] { editor })); Composition.Register(); var dataType = Mock.Of(); diff --git a/src/Umbraco.Tests/Models/ContentTests.cs b/src/Umbraco.Tests/Models/ContentTests.cs index ffbf462b8e..ee6649dd2b 100644 --- a/src/Umbraco.Tests/Models/ContentTests.cs +++ b/src/Umbraco.Tests/Models/ContentTests.cs @@ -43,7 +43,7 @@ namespace Umbraco.Tests.Models Composition.Register(_ => Mock.Of()); // all this is required so we can validate properties... - var editor = new TextboxPropertyEditor(Mock.Of()) { Alias = "test" }; + var editor = new TextboxPropertyEditor(Mock.Of(), Mock.Of(), Mock.Of()) { Alias = "test" }; Composition.Register(_ => new DataEditorCollection(new [] { editor })); Composition.Register(); var dataType = Mock.Of(); @@ -57,7 +57,7 @@ namespace Umbraco.Tests.Models var mediaTypeService = Mock.Of(); var memberTypeService = Mock.Of(); Composition.Register(_ => ServiceContext.CreatePartial(dataTypeService: dataTypeService, contentTypeBaseServiceProvider: new ContentTypeBaseServiceProvider(_contentTypeService, mediaTypeService, memberTypeService))); - + } [Test] diff --git a/src/Umbraco.Tests/Models/Mapping/ContentTypeModelMappingTests.cs b/src/Umbraco.Tests/Models/Mapping/ContentTypeModelMappingTests.cs index 21180ce51b..968e51ab97 100644 --- a/src/Umbraco.Tests/Models/Mapping/ContentTypeModelMappingTests.cs +++ b/src/Umbraco.Tests/Models/Mapping/ContentTypeModelMappingTests.cs @@ -24,6 +24,7 @@ namespace Umbraco.Tests.Models.Mapping private readonly Mock _dataTypeService = new Mock(); private readonly Mock _entityService = new Mock(); private readonly Mock _fileService = new Mock(); + private readonly Mock _localizationService = new Mock(); private Mock _editorsMock; protected override void Compose() @@ -31,7 +32,7 @@ namespace Umbraco.Tests.Models.Mapping base.Compose(); // create and register a fake property editor collection to return fake property editors - var editors = new DataEditor[] { new TextboxPropertyEditor(Mock.Of()), }; + var editors = new DataEditor[] { new TextboxPropertyEditor(Mock.Of(), _dataTypeService.Object, _localizationService.Object), }; var dataEditors = new DataEditorCollection(editors); _editorsMock = new Mock(dataEditors); _editorsMock.Setup(x => x[It.IsAny()]).Returns(editors[0]); diff --git a/src/Umbraco.Tests/Models/Mapping/ContentWebModelMappingTests.cs b/src/Umbraco.Tests/Models/Mapping/ContentWebModelMappingTests.cs index 996f02e16a..9a47ad1b4a 100644 --- a/src/Umbraco.Tests/Models/Mapping/ContentWebModelMappingTests.cs +++ b/src/Umbraco.Tests/Models/Mapping/ContentWebModelMappingTests.cs @@ -40,7 +40,7 @@ namespace Umbraco.Tests.Models.Mapping Composition.Register(_ => Mock.Of()); // all this is required so we can validate properties... - var editor = new TextboxPropertyEditor(Mock.Of()) { Alias = "test" }; + var editor = new TextboxPropertyEditor(Mock.Of(), Mock.Of(), Mock.Of()) { Alias = "test" }; Composition.Register(_ => new DataEditorCollection(new[] { editor })); Composition.Register(); var dataType = Mock.Of(); diff --git a/src/Umbraco.Tests/Models/MediaXmlTest.cs b/src/Umbraco.Tests/Models/MediaXmlTest.cs index 3ae9414dc1..4b4b333e74 100644 --- a/src/Umbraco.Tests/Models/MediaXmlTest.cs +++ b/src/Umbraco.Tests/Models/MediaXmlTest.cs @@ -33,9 +33,11 @@ namespace Umbraco.Tests.Models var logger = Mock.Of(); var scheme = Mock.Of(); var config = Mock.Of(); + var dataTypeService = Mock.Of(); + var localizationService = Mock.Of(); var mediaFileSystem = new MediaFileSystem(Mock.Of(), config, scheme, logger); - var ignored = new FileUploadPropertyEditor(Mock.Of(), mediaFileSystem, config); + var ignored = new FileUploadPropertyEditor(Mock.Of(), mediaFileSystem, config, dataTypeService, localizationService); var media = MockedMedia.CreateMediaImage(mediaType, -1); media.WriterId = -1; // else it's zero and that's not a user and it breaks the tests diff --git a/src/Umbraco.Tests/Models/VariationTests.cs b/src/Umbraco.Tests/Models/VariationTests.cs index 28663a9dbe..c7ebb9ef71 100644 --- a/src/Umbraco.Tests/Models/VariationTests.cs +++ b/src/Umbraco.Tests/Models/VariationTests.cs @@ -41,7 +41,7 @@ namespace Umbraco.Tests.Models var dataEditors = new DataEditorCollection(new IDataEditor[] { - new DataEditor(Mock.Of()) { Alias = "editor", ExplicitValueEditor = new DataValueEditor(dataTypeService, localizationService, "view") } + new DataEditor(Mock.Of()) { Alias = "editor", ExplicitValueEditor = TestHelper.CreateDataValueEditor("view") } }); var propertyEditors = new PropertyEditorCollection(dataEditors); diff --git a/src/Umbraco.Tests/PropertyEditors/ImageCropperTest.cs b/src/Umbraco.Tests/PropertyEditors/ImageCropperTest.cs index 5bea491973..885aaeefb9 100644 --- a/src/Umbraco.Tests/PropertyEditors/ImageCropperTest.cs +++ b/src/Umbraco.Tests/PropertyEditors/ImageCropperTest.cs @@ -83,7 +83,7 @@ namespace Umbraco.Tests.PropertyEditors var mediaFileSystem = new MediaFileSystem(Mock.Of(), config, scheme, logger); var dataTypeService = new TestObjects.TestDataTypeService( - new DataType(new ImageCropperPropertyEditor(Mock.Of(), mediaFileSystem, Mock.Of(), Mock.Of())) { Id = 1 }); + new DataType(new ImageCropperPropertyEditor(Mock.Of(), mediaFileSystem, Mock.Of(), Mock.Of(), Mock.Of())) { Id = 1 }); var factory = new PublishedContentTypeFactory(Mock.Of(), new PropertyValueConverterCollection(Array.Empty()), dataTypeService); diff --git a/src/Umbraco.Tests/PropertyEditors/MultiValuePropertyEditorTests.cs b/src/Umbraco.Tests/PropertyEditors/MultiValuePropertyEditorTests.cs index 7f708b6c53..5579395b7e 100644 --- a/src/Umbraco.Tests/PropertyEditors/MultiValuePropertyEditorTests.cs +++ b/src/Umbraco.Tests/PropertyEditors/MultiValuePropertyEditorTests.cs @@ -30,7 +30,7 @@ namespace Umbraco.Tests.PropertyEditors [Test] public void DropDownMultipleValueEditor_Format_Data_For_Cache() { - var dataType = new DataType(new CheckBoxListPropertyEditor(Mock.Of(), Mock.Of())) + var dataType = new DataType(new CheckBoxListPropertyEditor(Mock.Of(), Mock.Of(), Mock.Of(), Mock.Of())) { Configuration = new ValueListConfiguration { @@ -59,7 +59,7 @@ namespace Umbraco.Tests.PropertyEditors [Test] public void DropDownValueEditor_Format_Data_For_Cache() { - var dataType = new DataType(new CheckBoxListPropertyEditor(Mock.Of(), Mock.Of())) + var dataType = new DataType(new CheckBoxListPropertyEditor(Mock.Of(), Mock.Of(), Mock.Of(), Mock.Of())) { Configuration = new ValueListConfiguration { diff --git a/src/Umbraco.Tests/PropertyEditors/PropertyEditorValueEditorTests.cs b/src/Umbraco.Tests/PropertyEditors/PropertyEditorValueEditorTests.cs index 06944c14a7..bb1b0e4b10 100644 --- a/src/Umbraco.Tests/PropertyEditors/PropertyEditorValueEditorTests.cs +++ b/src/Umbraco.Tests/PropertyEditors/PropertyEditorValueEditorTests.cs @@ -47,10 +47,7 @@ namespace Umbraco.Tests.PropertyEditors var prop = new Property(1, new PropertyType("test", ValueStorageType.Nvarchar)); prop.SetValue(value); - var valueEditor = new DataValueEditor - { - ValueType = ValueTypes.String - }; + var valueEditor = TestHelper.CreateDataValueEditor(ValueTypes.String); var result = valueEditor.ToEditor(prop); Assert.AreEqual(isOk, !(result is string)); @@ -63,10 +60,7 @@ namespace Umbraco.Tests.PropertyEditors [TestCase("DATETIME", "", null)] //test empty string for date public void Value_Editor_Can_Convert_To_Clr_Type(string valueType, string val, object expected) { - var valueEditor = new DataValueEditor - { - ValueType = valueType - }; + var valueEditor = TestHelper.CreateDataValueEditor(valueType); var result = valueEditor.TryConvertValueToCrlType(val); Assert.IsTrue(result.Success); @@ -78,10 +72,7 @@ namespace Umbraco.Tests.PropertyEditors [Test] public void Value_Editor_Can_Convert_To_Decimal_Clr_Type() { - var valueEditor = new DataValueEditor - { - ValueType = ValueTypes.Decimal - }; + var valueEditor = TestHelper.CreateDataValueEditor(ValueTypes.Decimal); var result = valueEditor.TryConvertValueToCrlType("12.34"); Assert.IsTrue(result.Success); @@ -91,10 +82,7 @@ namespace Umbraco.Tests.PropertyEditors [Test] public void Value_Editor_Can_Convert_To_Decimal_Clr_Type_With_Other_Separator() { - var valueEditor = new DataValueEditor - { - ValueType = ValueTypes.Decimal - }; + var valueEditor = TestHelper.CreateDataValueEditor(ValueTypes.Decimal); var result = valueEditor.TryConvertValueToCrlType("12,34"); Assert.IsTrue(result.Success); @@ -104,10 +92,7 @@ namespace Umbraco.Tests.PropertyEditors [Test] public void Value_Editor_Can_Convert_To_Decimal_Clr_Type_With_Empty_String() { - var valueEditor = new DataValueEditor - { - ValueType = ValueTypes.Decimal - }; + var valueEditor = TestHelper.CreateDataValueEditor(ValueTypes.Decimal); var result = valueEditor.TryConvertValueToCrlType(string.Empty); Assert.IsTrue(result.Success); @@ -117,10 +102,7 @@ namespace Umbraco.Tests.PropertyEditors [Test] public void Value_Editor_Can_Convert_To_Date_Clr_Type() { - var valueEditor = new DataValueEditor - { - ValueType = ValueTypes.Date - }; + var valueEditor = TestHelper.CreateDataValueEditor(ValueTypes.Date); var result = valueEditor.TryConvertValueToCrlType("2010-02-05"); Assert.IsTrue(result.Success); @@ -137,10 +119,7 @@ namespace Umbraco.Tests.PropertyEditors var prop = new Property(1, new PropertyType("test", ValueStorageType.Nvarchar)); prop.SetValue(val); - var valueEditor = new DataValueEditor - { - ValueType = valueType - }; + var valueEditor = TestHelper.CreateDataValueEditor(valueType); var result = valueEditor.ToEditor(prop); Assert.AreEqual(expected, result); @@ -150,10 +129,7 @@ namespace Umbraco.Tests.PropertyEditors public void Value_Editor_Can_Serialize_Decimal_Value() { var value = 12.34M; - var valueEditor = new DataValueEditor - { - ValueType = ValueTypes.Decimal - }; + var valueEditor = TestHelper.CreateDataValueEditor(ValueTypes.Decimal); var prop = new Property(1, new PropertyType("test", ValueStorageType.Decimal)); prop.SetValue(value); @@ -165,10 +141,7 @@ namespace Umbraco.Tests.PropertyEditors [Test] public void Value_Editor_Can_Serialize_Decimal_Value_With_Empty_String() { - var valueEditor = new DataValueEditor - { - ValueType = ValueTypes.Decimal - }; + var valueEditor = TestHelper.CreateDataValueEditor(ValueTypes.Decimal); var prop = new Property(1, new PropertyType("test", ValueStorageType.Decimal)); prop.SetValue(string.Empty); @@ -181,10 +154,7 @@ namespace Umbraco.Tests.PropertyEditors public void Value_Editor_Can_Serialize_Date_Value() { var now = DateTime.Now; - var valueEditor = new DataValueEditor - { - ValueType = ValueTypes.Date - }; + var valueEditor = TestHelper.CreateDataValueEditor(ValueTypes.Date); var prop = new Property(1, new PropertyType("test", ValueStorageType.Date)); prop.SetValue(now); diff --git a/src/Umbraco.Tests/Published/NestedContentTests.cs b/src/Umbraco.Tests/Published/NestedContentTests.cs index 9385b8955a..4d99aa86d8 100644 --- a/src/Umbraco.Tests/Published/NestedContentTests.cs +++ b/src/Umbraco.Tests/Published/NestedContentTests.cs @@ -11,6 +11,7 @@ using Umbraco.Core.Logging; using Umbraco.Core.Models; using Umbraco.Core.Models.PublishedContent; using Umbraco.Core.PropertyEditors; +using Umbraco.Core.Services; using Umbraco.Tests.PublishedContent; using Umbraco.Tests.TestHelpers; using Umbraco.Web; @@ -31,9 +32,10 @@ namespace Umbraco.Tests.Published var logger = Mock.Of(); var profiler = Mock.Of(); var proflog = new ProfilingLogger(logger, profiler); + var localizationService = Mock.Of(); PropertyEditorCollection editors = null; - var editor = new NestedContentPropertyEditor(logger, new Lazy(() => editors)); + var editor = new NestedContentPropertyEditor(logger, new Lazy(() => editors), Mock.Of(), localizationService); editors = new PropertyEditorCollection(new DataEditorCollection(new DataEditor[] { editor })); var dataType1 = new DataType(editor) @@ -64,7 +66,7 @@ namespace Umbraco.Tests.Published } }; - var dataType3 = new DataType(new TextboxPropertyEditor(logger)) + var dataType3 = new DataType(new TextboxPropertyEditor(logger, Mock.Of(), localizationService)) { Id = 3 }; diff --git a/src/Umbraco.Tests/PublishedContent/PublishedContentTestBase.cs b/src/Umbraco.Tests/PublishedContent/PublishedContentTestBase.cs index f1e2bf20d6..bf55f1783f 100644 --- a/src/Umbraco.Tests/PublishedContent/PublishedContentTestBase.cs +++ b/src/Umbraco.Tests/PublishedContent/PublishedContentTestBase.cs @@ -40,7 +40,13 @@ namespace Umbraco.Tests.PublishedContent var converters = Factory.GetInstance(); var dataTypeService = new TestObjects.TestDataTypeService( - new DataType(new RichTextPropertyEditor(Mock.Of(), Mock.Of(), Mock.Of(), Mock.Of())) { Id = 1 }); + new DataType(new RichTextPropertyEditor( + Mock.Of(), + Mock.Of(), + Mock.Of(), + Mock.Of(), + Mock.Of(), + Mock.Of())) { Id = 1 }); var publishedContentTypeFactory = new PublishedContentTypeFactory(Mock.Of(), converters, dataTypeService); diff --git a/src/Umbraco.Tests/PublishedContent/PublishedContentTests.cs b/src/Umbraco.Tests/PublishedContent/PublishedContentTests.cs index b42dc32b24..7c70e82047 100644 --- a/src/Umbraco.Tests/PublishedContent/PublishedContentTests.cs +++ b/src/Umbraco.Tests/PublishedContent/PublishedContentTests.cs @@ -47,13 +47,14 @@ namespace Umbraco.Tests.PublishedContent var mediaService = Mock.Of(); var contentTypeBaseServiceProvider = Mock.Of(); var umbracoContextAccessor = Mock.Of(); + var localizationService = Mock.Of(); var dataTypeService = new TestObjects.TestDataTypeService( new DataType(new VoidEditor(logger)) { Id = 1 }, new DataType(new TrueFalsePropertyEditor(logger)) { Id = 1001 }, - new DataType(new RichTextPropertyEditor(logger, mediaService, contentTypeBaseServiceProvider, umbracoContextAccessor)) { Id = 1002 }, + new DataType(new RichTextPropertyEditor(logger, mediaService, contentTypeBaseServiceProvider, umbracoContextAccessor, Mock.Of(), localizationService)) { Id = 1002 }, new DataType(new IntegerPropertyEditor(logger)) { Id = 1003 }, - new DataType(new TextboxPropertyEditor(logger)) { Id = 1004 }, + new DataType(new TextboxPropertyEditor(logger, Mock.Of(), localizationService)) { Id = 1004 }, new DataType(new MediaPickerPropertyEditor(logger)) { Id = 1005 }); Composition.RegisterUnique(f => dataTypeService); } diff --git a/src/Umbraco.Tests/Services/PropertyValidationServiceTests.cs b/src/Umbraco.Tests/Services/PropertyValidationServiceTests.cs index 425c03a9b4..746190d67f 100644 --- a/src/Umbraco.Tests/Services/PropertyValidationServiceTests.cs +++ b/src/Umbraco.Tests/Services/PropertyValidationServiceTests.cs @@ -32,7 +32,7 @@ namespace Umbraco.Tests.Services x => x.Type == EditorType.PropertyValue && x.Alias == Constants.PropertyEditors.Aliases.TextBox); Mock.Get(dataEditor).Setup(x => x.GetValueEditor(It.IsAny())) - .Returns(new CustomTextOnlyValueEditor(new DataEditorAttribute(Constants.PropertyEditors.Aliases.TextBox, "Test Textbox", "textbox"), textService.Object)); + .Returns(new CustomTextOnlyValueEditor(Mock.Of(), Mock.Of(), new DataEditorAttribute(Constants.PropertyEditors.Aliases.TextBox, "Test Textbox", "textbox"), textService.Object)); var propEditors = new PropertyEditorCollection(new DataEditorCollection(new[] { dataEditor })); @@ -164,7 +164,7 @@ namespace Umbraco.Tests.Services { private readonly ILocalizedTextService _textService; - public CustomTextOnlyValueEditor(DataEditorAttribute attribute, ILocalizedTextService textService) : base(attribute) + public CustomTextOnlyValueEditor(IDataTypeService dataTypeService, ILocalizationService localizationService, DataEditorAttribute attribute, ILocalizedTextService textService) : base(dataTypeService, localizationService, attribute) { _textService = textService; } diff --git a/src/Umbraco.Tests/TestHelpers/TestHelper.cs b/src/Umbraco.Tests/TestHelpers/TestHelper.cs index e07dbe1e5a..039a5c9b07 100644 --- a/src/Umbraco.Tests/TestHelpers/TestHelper.cs +++ b/src/Umbraco.Tests/TestHelpers/TestHelper.cs @@ -17,6 +17,7 @@ using Umbraco.Core.Logging; using Umbraco.Core.Models; using Umbraco.Core.Models.Entities; using Umbraco.Core.PropertyEditors; +using Umbraco.Core.Services; using File = System.IO.File; namespace Umbraco.Tests.TestHelpers @@ -247,5 +248,20 @@ namespace Umbraco.Tests.TestHelpers } } } + + public static DataValueEditor CreateDataValueEditor(string name) + { + var valueType = (ValueTypes.IsValue(name)) ? name : ValueTypes.String; + + return new DataValueEditor( + Mock.Of(), + Mock.Of(), + new DataEditorAttribute(name, name, name) + { + ValueType = valueType + } + + ); + } } } diff --git a/src/Umbraco.Web/PropertyEditors/CheckBoxListPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/CheckBoxListPropertyEditor.cs index d81b63f2ad..f28acd5e90 100644 --- a/src/Umbraco.Web/PropertyEditors/CheckBoxListPropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/CheckBoxListPropertyEditor.cs @@ -17,20 +17,24 @@ namespace Umbraco.Web.PropertyEditors public class CheckBoxListPropertyEditor : DataEditor { private readonly ILocalizedTextService _textService; + private readonly IDataTypeService _dataTypeService; + private readonly ILocalizationService _localizationService; /// /// The constructor will setup the property editor based on the attribute if one is found /// - public CheckBoxListPropertyEditor(ILogger logger, ILocalizedTextService textService) + public CheckBoxListPropertyEditor(ILogger logger, ILocalizedTextService textService, IDataTypeService dataTypeService, ILocalizationService localizationService) : base(logger) { _textService = textService; + _dataTypeService = dataTypeService; + _localizationService = localizationService; } /// protected override IConfigurationEditor CreateConfigurationEditor() => new ValueListConfigurationEditor(_textService); /// - protected override IDataValueEditor CreateValueEditor() => new MultipleValueEditor(Logger, Attribute); + protected override IDataValueEditor CreateValueEditor() => new MultipleValueEditor(Logger, _dataTypeService, _localizationService, Attribute); } } diff --git a/src/Umbraco.Web/PropertyEditors/DateValueEditor.cs b/src/Umbraco.Web/PropertyEditors/DateValueEditor.cs index bc1c5dc5f8..b8dada173f 100644 --- a/src/Umbraco.Web/PropertyEditors/DateValueEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/DateValueEditor.cs @@ -12,8 +12,8 @@ namespace Umbraco.Web.PropertyEditors /// internal class DateValueEditor : DataValueEditor { - public DateValueEditor(DataEditorAttribute attribute) - : base(attribute) + public DateValueEditor(IDataTypeService dataTypeService, ILocalizationService localizationService, DataEditorAttribute attribute) + : base(dataTypeService, localizationService, attribute) { Validators.Add(new DateTimeValidator()); } diff --git a/src/Umbraco.Web/PropertyEditors/DropDownFlexiblePropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/DropDownFlexiblePropertyEditor.cs index 98a19f39ad..0b0a0f6d06 100644 --- a/src/Umbraco.Web/PropertyEditors/DropDownFlexiblePropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/DropDownFlexiblePropertyEditor.cs @@ -14,16 +14,20 @@ namespace Umbraco.Web.PropertyEditors public class DropDownFlexiblePropertyEditor : DataEditor { private readonly ILocalizedTextService _textService; + private readonly IDataTypeService _dataTypeService; + private readonly ILocalizationService _localizationService; - public DropDownFlexiblePropertyEditor(ILocalizedTextService textService, ILogger logger) + public DropDownFlexiblePropertyEditor(ILocalizedTextService textService, ILogger logger, IDataTypeService dataTypeService, ILocalizationService localizationService) : base(logger) { _textService = textService; + _dataTypeService = dataTypeService; + _localizationService = localizationService; } protected override IDataValueEditor CreateValueEditor() { - return new MultipleValueEditor(Logger, Attribute); + return new MultipleValueEditor(Logger, _dataTypeService, _localizationService, Attribute); } protected override IConfigurationEditor CreateConfigurationEditor() => new DropDownFlexibleConfigurationEditor(_textService); diff --git a/src/Umbraco.Web/PropertyEditors/FileUploadPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/FileUploadPropertyEditor.cs index 849ad443c8..366f3938a6 100644 --- a/src/Umbraco.Web/PropertyEditors/FileUploadPropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/FileUploadPropertyEditor.cs @@ -8,6 +8,7 @@ using Umbraco.Core.Logging; using Umbraco.Core.Models; using Umbraco.Core.PropertyEditors; using Umbraco.Core.Services; +using Umbraco.Core.Services.Implement; using Umbraco.Web.Media; namespace Umbraco.Web.PropertyEditors @@ -23,12 +24,16 @@ namespace Umbraco.Web.PropertyEditors private readonly IMediaFileSystem _mediaFileSystem; private readonly IContentSection _contentSection; private readonly UploadAutoFillProperties _uploadAutoFillProperties; + private readonly IDataTypeService _dataTypeService; + private readonly ILocalizationService _localizationService; - public FileUploadPropertyEditor(ILogger logger, IMediaFileSystem mediaFileSystem, IContentSection contentSection) + public FileUploadPropertyEditor(ILogger logger, IMediaFileSystem mediaFileSystem, IContentSection contentSection, IDataTypeService dataTypeService, ILocalizationService localizationService) : base(logger) { _mediaFileSystem = mediaFileSystem ?? throw new ArgumentNullException(nameof(mediaFileSystem)); _contentSection = contentSection; + _dataTypeService = dataTypeService; + _localizationService = localizationService; _uploadAutoFillProperties = new UploadAutoFillProperties(_mediaFileSystem, logger, contentSection); } @@ -38,7 +43,7 @@ namespace Umbraco.Web.PropertyEditors /// The corresponding property value editor. protected override IDataValueEditor CreateValueEditor() { - var editor = new FileUploadPropertyValueEditor(Attribute, _mediaFileSystem); + var editor = new FileUploadPropertyValueEditor(Attribute, _mediaFileSystem, _dataTypeService, _localizationService); editor.Validators.Add(new UploadFileTypeValidator()); return editor; } diff --git a/src/Umbraco.Web/PropertyEditors/FileUploadPropertyValueEditor.cs b/src/Umbraco.Web/PropertyEditors/FileUploadPropertyValueEditor.cs index 942f53b561..172d8070af 100644 --- a/src/Umbraco.Web/PropertyEditors/FileUploadPropertyValueEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/FileUploadPropertyValueEditor.cs @@ -7,6 +7,7 @@ using Umbraco.Core; using Umbraco.Core.IO; using Umbraco.Core.Models.Editors; using Umbraco.Core.PropertyEditors; +using Umbraco.Core.Services; namespace Umbraco.Web.PropertyEditors { @@ -17,8 +18,8 @@ namespace Umbraco.Web.PropertyEditors { private readonly IMediaFileSystem _mediaFileSystem; - public FileUploadPropertyValueEditor(DataEditorAttribute attribute, IMediaFileSystem mediaFileSystem) - : base(attribute) + public FileUploadPropertyValueEditor(DataEditorAttribute attribute, IMediaFileSystem mediaFileSystem, IDataTypeService dataTypeService, ILocalizationService localizationService) + : base(dataTypeService, localizationService, attribute) { _mediaFileSystem = mediaFileSystem ?? throw new ArgumentNullException(nameof(mediaFileSystem)); } @@ -92,7 +93,7 @@ namespace Umbraco.Web.PropertyEditors if (editorFile == null) return null; return filepath == null ? string.Empty : _mediaFileSystem.GetUrl(filepath); - + } private string ProcessFile(ContentPropertyData editorValue, ContentPropertyFile file, string currentPath, Guid cuid, Guid puid) diff --git a/src/Umbraco.Web/PropertyEditors/GridPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/GridPropertyEditor.cs index bae06e09c2..6f6f1d911d 100644 --- a/src/Umbraco.Web/PropertyEditors/GridPropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/GridPropertyEditor.cs @@ -28,14 +28,18 @@ namespace Umbraco.Web.PropertyEditors private IMediaService _mediaService; private IContentTypeBaseServiceProvider _contentTypeBaseServiceProvider; private IUmbracoContextAccessor _umbracoContextAccessor; + private readonly IDataTypeService _dataTypeService; + private readonly ILocalizationService _localizationService; private ILogger _logger; - public GridPropertyEditor(ILogger logger, IMediaService mediaService, IContentTypeBaseServiceProvider contentTypeBaseServiceProvider, IUmbracoContextAccessor umbracoContextAccessor) + public GridPropertyEditor(ILogger logger, IMediaService mediaService, IContentTypeBaseServiceProvider contentTypeBaseServiceProvider, IUmbracoContextAccessor umbracoContextAccessor, IDataTypeService dataTypeService, ILocalizationService localizationService) : base(logger) { _mediaService = mediaService; _contentTypeBaseServiceProvider = contentTypeBaseServiceProvider; _umbracoContextAccessor = umbracoContextAccessor; + _dataTypeService = dataTypeService; + _localizationService = localizationService; _logger = logger; } @@ -45,7 +49,7 @@ namespace Umbraco.Web.PropertyEditors /// Overridden to ensure that the value is validated /// /// - protected override IDataValueEditor CreateValueEditor() => new GridPropertyValueEditor(Attribute, _mediaService, _contentTypeBaseServiceProvider, _umbracoContextAccessor, _logger); + protected override IDataValueEditor CreateValueEditor() => new GridPropertyValueEditor(Attribute, _mediaService, _contentTypeBaseServiceProvider, _umbracoContextAccessor, _logger, _dataTypeService, _localizationService); protected override IConfigurationEditor CreateConfigurationEditor() => new GridConfigurationEditor(); @@ -56,8 +60,8 @@ namespace Umbraco.Web.PropertyEditors private IUmbracoContextAccessor _umbracoContextAccessor; private ILogger _logger; - public GridPropertyValueEditor(DataEditorAttribute attribute, IMediaService mediaService, IContentTypeBaseServiceProvider contentTypeBaseServiceProvider, IUmbracoContextAccessor umbracoContextAccessor, ILogger logger) - : base(attribute) + public GridPropertyValueEditor(DataEditorAttribute attribute, IMediaService mediaService, IContentTypeBaseServiceProvider contentTypeBaseServiceProvider, IUmbracoContextAccessor umbracoContextAccessor, ILogger logger, IDataTypeService dataTypeService, ILocalizationService localizationService) + : base(dataTypeService, localizationService, attribute) { _mediaService = mediaService; _contentTypeBaseServiceProvider = contentTypeBaseServiceProvider; diff --git a/src/Umbraco.Web/PropertyEditors/ImageCropperPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/ImageCropperPropertyEditor.cs index d120210411..fe1f026417 100644 --- a/src/Umbraco.Web/PropertyEditors/ImageCropperPropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/ImageCropperPropertyEditor.cs @@ -32,17 +32,19 @@ namespace Umbraco.Web.PropertyEditors private readonly IMediaFileSystem _mediaFileSystem; private readonly IContentSection _contentSettings; private readonly IDataTypeService _dataTypeService; + private readonly ILocalizationService _localizationService; private readonly UploadAutoFillProperties _autoFillProperties; /// /// Initializes a new instance of the class. /// - public ImageCropperPropertyEditor(ILogger logger, IMediaFileSystem mediaFileSystem, IContentSection contentSettings, IDataTypeService dataTypeService) + public ImageCropperPropertyEditor(ILogger logger, IMediaFileSystem mediaFileSystem, IContentSection contentSettings, IDataTypeService dataTypeService, ILocalizationService localizationService) : base(logger) { _mediaFileSystem = mediaFileSystem ?? throw new ArgumentNullException(nameof(mediaFileSystem)); _contentSettings = contentSettings ?? throw new ArgumentNullException(nameof(contentSettings)); _dataTypeService = dataTypeService; + _localizationService = localizationService; // TODO: inject? _autoFillProperties = new UploadAutoFillProperties(_mediaFileSystem, logger, _contentSettings); @@ -52,7 +54,7 @@ namespace Umbraco.Web.PropertyEditors /// Creates the corresponding property value editor. /// /// The corresponding property value editor. - protected override IDataValueEditor CreateValueEditor() => new ImageCropperPropertyValueEditor(Attribute, Logger, _mediaFileSystem); + protected override IDataValueEditor CreateValueEditor() => new ImageCropperPropertyValueEditor(Attribute, Logger, _mediaFileSystem, _dataTypeService, _localizationService); /// /// Creates the corresponding preValue editor. diff --git a/src/Umbraco.Web/PropertyEditors/ImageCropperPropertyValueEditor.cs b/src/Umbraco.Web/PropertyEditors/ImageCropperPropertyValueEditor.cs index c9ce5a9d9d..99e2f8c727 100644 --- a/src/Umbraco.Web/PropertyEditors/ImageCropperPropertyValueEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/ImageCropperPropertyValueEditor.cs @@ -21,8 +21,8 @@ namespace Umbraco.Web.PropertyEditors private readonly ILogger _logger; private readonly IMediaFileSystem _mediaFileSystem; - public ImageCropperPropertyValueEditor(DataEditorAttribute attribute, ILogger logger, IMediaFileSystem mediaFileSystem) - : base(attribute) + public ImageCropperPropertyValueEditor(DataEditorAttribute attribute, ILogger logger, IMediaFileSystem mediaFileSystem, IDataTypeService dataTypeService, ILocalizationService localizationService) + : base(dataTypeService, localizationService, attribute) { _logger = logger ?? throw new ArgumentNullException(nameof(logger)); _mediaFileSystem = mediaFileSystem ?? throw new ArgumentNullException(nameof(mediaFileSystem)); diff --git a/src/Umbraco.Web/PropertyEditors/MultiUrlPickerPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/MultiUrlPickerPropertyEditor.cs index 95ac809576..a5da833501 100644 --- a/src/Umbraco.Web/PropertyEditors/MultiUrlPickerPropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/MultiUrlPickerPropertyEditor.cs @@ -19,15 +19,19 @@ namespace Umbraco.Web.PropertyEditors { private readonly IEntityService _entityService; private readonly IPublishedSnapshotAccessor _publishedSnapshotAccessor; + private readonly IDataTypeService _dataTypeService; + private readonly ILocalizationService _localizationService; - public MultiUrlPickerPropertyEditor(ILogger logger, IEntityService entityService, IPublishedSnapshotAccessor publishedSnapshotAccessor) : base(logger, EditorType.PropertyValue) + public MultiUrlPickerPropertyEditor(ILogger logger, IEntityService entityService, IPublishedSnapshotAccessor publishedSnapshotAccessor, IDataTypeService dataTypeService, ILocalizationService localizationService) : base(logger, EditorType.PropertyValue) { _entityService = entityService ?? throw new ArgumentNullException(nameof(entityService)); _publishedSnapshotAccessor = publishedSnapshotAccessor ?? throw new ArgumentNullException(nameof(publishedSnapshotAccessor)); + _dataTypeService = dataTypeService; + _localizationService = localizationService; } protected override IConfigurationEditor CreateConfigurationEditor() => new MultiUrlPickerConfigurationEditor(); - protected override IDataValueEditor CreateValueEditor() => new MultiUrlPickerValueEditor(_entityService, _publishedSnapshotAccessor, Logger, Attribute); + protected override IDataValueEditor CreateValueEditor() => new MultiUrlPickerValueEditor(_entityService, _publishedSnapshotAccessor, Logger, _dataTypeService, _localizationService, Attribute); } } diff --git a/src/Umbraco.Web/PropertyEditors/MultiUrlPickerValueEditor.cs b/src/Umbraco.Web/PropertyEditors/MultiUrlPickerValueEditor.cs index 36d40cceb8..97d787dbba 100644 --- a/src/Umbraco.Web/PropertyEditors/MultiUrlPickerValueEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/MultiUrlPickerValueEditor.cs @@ -21,7 +21,7 @@ namespace Umbraco.Web.PropertyEditors private readonly ILogger _logger; private readonly IPublishedSnapshotAccessor _publishedSnapshotAccessor; - public MultiUrlPickerValueEditor(IEntityService entityService, IPublishedSnapshotAccessor publishedSnapshotAccessor, ILogger logger, DataEditorAttribute attribute) : base(attribute) + public MultiUrlPickerValueEditor(IEntityService entityService, IPublishedSnapshotAccessor publishedSnapshotAccessor, ILogger logger, IDataTypeService dataTypeService, ILocalizationService localizationService, DataEditorAttribute attribute) : base(dataTypeService, localizationService, attribute) { _entityService = entityService ?? throw new ArgumentNullException(nameof(entityService)); _publishedSnapshotAccessor = publishedSnapshotAccessor ?? throw new ArgumentNullException(nameof(publishedSnapshotAccessor)); diff --git a/src/Umbraco.Web/PropertyEditors/MultipleTextStringPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/MultipleTextStringPropertyEditor.cs index 279bc3618a..29ec8530d9 100644 --- a/src/Umbraco.Web/PropertyEditors/MultipleTextStringPropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/MultipleTextStringPropertyEditor.cs @@ -4,6 +4,7 @@ using System.ComponentModel.DataAnnotations; using System.Linq; using Newtonsoft.Json.Linq; using Umbraco.Core; +using Umbraco.Core.Composing; using Umbraco.Core.Exceptions; using Umbraco.Core.Logging; using Umbraco.Core.Models; @@ -34,7 +35,7 @@ namespace Umbraco.Web.PropertyEditors { } /// - protected override IDataValueEditor CreateValueEditor() => new MultipleTextStringPropertyValueEditor(Attribute); + protected override IDataValueEditor CreateValueEditor() => new MultipleTextStringPropertyValueEditor(Current.Services.DataTypeService, Current.Services.LocalizationService,Attribute); /// protected override IConfigurationEditor CreateConfigurationEditor() => new MultipleTextStringConfigurationEditor(); @@ -44,8 +45,8 @@ namespace Umbraco.Web.PropertyEditors /// internal class MultipleTextStringPropertyValueEditor : DataValueEditor { - public MultipleTextStringPropertyValueEditor(DataEditorAttribute attribute) - : base(attribute) + public MultipleTextStringPropertyValueEditor(IDataTypeService dataTypeService, ILocalizationService localizationService, DataEditorAttribute attribute) + : base(dataTypeService, localizationService, attribute) { } /// diff --git a/src/Umbraco.Web/PropertyEditors/MultipleValueEditor.cs b/src/Umbraco.Web/PropertyEditors/MultipleValueEditor.cs index b46de6d092..f5ca6c5cfe 100644 --- a/src/Umbraco.Web/PropertyEditors/MultipleValueEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/MultipleValueEditor.cs @@ -19,8 +19,8 @@ namespace Umbraco.Web.PropertyEditors { private readonly ILogger _logger; - internal MultipleValueEditor(ILogger logger, DataEditorAttribute attribute) - : base(attribute) + internal MultipleValueEditor(ILogger logger, IDataTypeService dataTypeService, ILocalizationService localizationService, DataEditorAttribute attribute) + : base(dataTypeService, localizationService, attribute) { _logger = logger; } diff --git a/src/Umbraco.Web/PropertyEditors/NestedContentPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/NestedContentPropertyEditor.cs index 8784a9bb49..3c9dc53de7 100644 --- a/src/Umbraco.Web/PropertyEditors/NestedContentPropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/NestedContentPropertyEditor.cs @@ -28,13 +28,17 @@ namespace Umbraco.Web.PropertyEditors public class NestedContentPropertyEditor : DataEditor { private readonly Lazy _propertyEditors; + private readonly IDataTypeService _dataTypeService; + private readonly ILocalizationService _localizationService; internal const string ContentTypeAliasPropertyKey = "ncContentTypeAlias"; - public NestedContentPropertyEditor(ILogger logger, Lazy propertyEditors) + public NestedContentPropertyEditor(ILogger logger, Lazy propertyEditors, IDataTypeService dataTypeService, ILocalizationService localizationService) : base (logger) { _propertyEditors = propertyEditors; + _dataTypeService = dataTypeService; + _localizationService = localizationService; } // has to be lazy else circular dep in ctor @@ -48,7 +52,7 @@ namespace Umbraco.Web.PropertyEditors #region Value Editor - protected override IDataValueEditor CreateValueEditor() => new NestedContentPropertyValueEditor(Attribute, PropertyEditors); + protected override IDataValueEditor CreateValueEditor() => new NestedContentPropertyValueEditor(_dataTypeService, _localizationService, Attribute, PropertyEditors); internal class NestedContentPropertyValueEditor : DataValueEditor { @@ -58,8 +62,8 @@ namespace Umbraco.Web.PropertyEditors Current.Services.ContentTypeService.GetAll().ToDictionary(c => c.Alias) ); - public NestedContentPropertyValueEditor(DataEditorAttribute attribute, PropertyEditorCollection propertyEditors) - : base(attribute) + public NestedContentPropertyValueEditor(IDataTypeService dataTypeService, ILocalizationService localizationService, DataEditorAttribute attribute, PropertyEditorCollection propertyEditors) + : base(dataTypeService, localizationService, attribute) { _propertyEditors = propertyEditors; Validators.Add(new NestedContentValidator(propertyEditors, GetElementType)); diff --git a/src/Umbraco.Web/PropertyEditors/RichTextPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/RichTextPropertyEditor.cs index 6932504f06..aa6876df39 100644 --- a/src/Umbraco.Web/PropertyEditors/RichTextPropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/RichTextPropertyEditor.cs @@ -27,16 +27,26 @@ namespace Umbraco.Web.PropertyEditors private IMediaService _mediaService; private IContentTypeBaseServiceProvider _contentTypeBaseServiceProvider; private IUmbracoContextAccessor _umbracoContextAccessor; + private readonly IDataTypeService _dataTypeService; + private readonly ILocalizationService _localizationService; private ILogger _logger; /// /// The constructor will setup the property editor based on the attribute if one is found /// - public RichTextPropertyEditor(ILogger logger, IMediaService mediaService, IContentTypeBaseServiceProvider contentTypeBaseServiceProvider, IUmbracoContextAccessor umbracoContextAccessor) : base(logger) + public RichTextPropertyEditor( + ILogger logger, + IMediaService mediaService, + IContentTypeBaseServiceProvider contentTypeBaseServiceProvider, + IUmbracoContextAccessor umbracoContextAccessor, + IDataTypeService dataTypeService, + ILocalizationService localizationService) : base(logger) { _mediaService = mediaService; _contentTypeBaseServiceProvider = contentTypeBaseServiceProvider; _umbracoContextAccessor = umbracoContextAccessor; + _dataTypeService = dataTypeService; + _localizationService = localizationService; _logger = logger; } @@ -44,7 +54,7 @@ namespace Umbraco.Web.PropertyEditors /// Create a custom value editor /// /// - protected override IDataValueEditor CreateValueEditor() => new RichTextPropertyValueEditor(Attribute, _mediaService, _contentTypeBaseServiceProvider, _umbracoContextAccessor, _logger); + protected override IDataValueEditor CreateValueEditor() => new RichTextPropertyValueEditor(Attribute, _mediaService, _contentTypeBaseServiceProvider, _umbracoContextAccessor, _logger, _dataTypeService, _localizationService); protected override IConfigurationEditor CreateConfigurationEditor() => new RichTextConfigurationEditor(); @@ -60,8 +70,8 @@ namespace Umbraco.Web.PropertyEditors private IUmbracoContextAccessor _umbracoContextAccessor; private ILogger _logger; - public RichTextPropertyValueEditor(DataEditorAttribute attribute, IMediaService mediaService, IContentTypeBaseServiceProvider contentTypeBaseServiceProvider, IUmbracoContextAccessor umbracoContextAccessor, ILogger logger) - : base(attribute) + public RichTextPropertyValueEditor(DataEditorAttribute attribute, IMediaService mediaService, IContentTypeBaseServiceProvider contentTypeBaseServiceProvider, IUmbracoContextAccessor umbracoContextAccessor, ILogger logger, IDataTypeService dataTypeService, ILocalizationService localizationService) + : base(dataTypeService, localizationService, attribute) { _mediaService = mediaService; _contentTypeBaseServiceProvider = contentTypeBaseServiceProvider; diff --git a/src/Umbraco.Web/PropertyEditors/TagsPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/TagsPropertyEditor.cs index fd7e8694a3..74338ba3fa 100644 --- a/src/Umbraco.Web/PropertyEditors/TagsPropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/TagsPropertyEditor.cs @@ -4,10 +4,12 @@ using System.ComponentModel.DataAnnotations; using System.Linq; using Newtonsoft.Json.Linq; using Umbraco.Core; +using Umbraco.Core.Composing; using Umbraco.Core.Logging; using Umbraco.Core.Models; using Umbraco.Core.Models.Editors; using Umbraco.Core.PropertyEditors; +using Umbraco.Core.Services; namespace Umbraco.Web.PropertyEditors { @@ -30,14 +32,14 @@ namespace Umbraco.Web.PropertyEditors _validators = validators; } - protected override IDataValueEditor CreateValueEditor() => new TagPropertyValueEditor(Attribute); + protected override IDataValueEditor CreateValueEditor() => new TagPropertyValueEditor(Current.Services.DataTypeService, Current.Services.LocalizationService, Attribute); protected override IConfigurationEditor CreateConfigurationEditor() => new TagConfigurationEditor(_validators); internal class TagPropertyValueEditor : DataValueEditor { - public TagPropertyValueEditor(DataEditorAttribute attribute) - : base(attribute) + public TagPropertyValueEditor(IDataTypeService dataTypeService, ILocalizationService localizationService, DataEditorAttribute attribute) + : base(dataTypeService, localizationService, attribute) { } /// diff --git a/src/Umbraco.Web/PropertyEditors/TextAreaPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/TextAreaPropertyEditor.cs index c7bc2efbda..28698e2c5c 100644 --- a/src/Umbraco.Web/PropertyEditors/TextAreaPropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/TextAreaPropertyEditor.cs @@ -1,6 +1,7 @@ using Umbraco.Core; using Umbraco.Core.Logging; using Umbraco.Core.PropertyEditors; +using Umbraco.Core.Services; namespace Umbraco.Web.PropertyEditors { @@ -16,15 +17,21 @@ namespace Umbraco.Web.PropertyEditors Icon = "icon-application-window-alt")] public class TextAreaPropertyEditor : DataEditor { + private readonly IDataTypeService _dataTypeService; + private readonly ILocalizationService _localizationService; + /// /// Initializes a new instance of the class. /// - public TextAreaPropertyEditor(ILogger logger) + public TextAreaPropertyEditor(ILogger logger, IDataTypeService dataTypeService, ILocalizationService localizationService) : base(logger) - { } + { + _dataTypeService = dataTypeService; + _localizationService = localizationService; + } /// - protected override IDataValueEditor CreateValueEditor() => new TextOnlyValueEditor(Attribute); + protected override IDataValueEditor CreateValueEditor() => new TextOnlyValueEditor(_dataTypeService, _localizationService, Attribute); /// protected override IConfigurationEditor CreateConfigurationEditor() => new TextAreaConfigurationEditor(); diff --git a/src/Umbraco.Web/PropertyEditors/TextOnlyValueEditor.cs b/src/Umbraco.Web/PropertyEditors/TextOnlyValueEditor.cs index 826051a79b..782e19e42d 100644 --- a/src/Umbraco.Web/PropertyEditors/TextOnlyValueEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/TextOnlyValueEditor.cs @@ -11,8 +11,8 @@ namespace Umbraco.Web.PropertyEditors /// public class TextOnlyValueEditor : DataValueEditor { - public TextOnlyValueEditor(DataEditorAttribute attribute) - : base(attribute) + public TextOnlyValueEditor(IDataTypeService dataTypeService, ILocalizationService localizationService, DataEditorAttribute attribute) + : base(dataTypeService, localizationService, attribute) { } /// diff --git a/src/Umbraco.Web/PropertyEditors/TextboxPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/TextboxPropertyEditor.cs index 18f8155198..c7c13b4caf 100644 --- a/src/Umbraco.Web/PropertyEditors/TextboxPropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/TextboxPropertyEditor.cs @@ -1,6 +1,7 @@ using Umbraco.Core; using Umbraco.Core.Logging; using Umbraco.Core.PropertyEditors; +using Umbraco.Core.Services; namespace Umbraco.Web.PropertyEditors { @@ -15,15 +16,21 @@ namespace Umbraco.Web.PropertyEditors Group = Constants.PropertyEditors.Groups.Common)] public class TextboxPropertyEditor : DataEditor { + private readonly IDataTypeService _dataTypeService; + private readonly ILocalizationService _localizationService; + /// /// Initializes a new instance of the class. /// - public TextboxPropertyEditor(ILogger logger) + public TextboxPropertyEditor(ILogger logger, IDataTypeService dataTypeService, ILocalizationService localizationService) : base(logger) - { } + { + _dataTypeService = dataTypeService; + _localizationService = localizationService; + } /// - protected override IDataValueEditor CreateValueEditor() => new TextOnlyValueEditor(Attribute); + protected override IDataValueEditor CreateValueEditor() => new TextOnlyValueEditor(_dataTypeService, _localizationService, Attribute); /// protected override IConfigurationEditor CreateConfigurationEditor() => new TextboxConfigurationEditor(); From 0fcf8325e31634a9e8063da0335a392cde60e4d1 Mon Sep 17 00:00:00 2001 From: Bjarke Berg Date: Tue, 12 Nov 2019 15:25:21 +0100 Subject: [PATCH 49/68] Changed SystemDirectories from static to instance, Added interface in abstractions and create a static property on current. --- .../IO/ISystemDirectories.cs | 33 ++++++++++++++ .../CompositionExtensions/FileSystems.cs | 2 +- .../CompositionExtensions/Services.cs | 7 +-- src/Umbraco.Core/Composing/Current.cs | 3 +- src/Umbraco.Core/ConfigsExtensions.cs | 2 +- .../Configuration/GlobalSettings.cs | 4 +- .../Configuration/GlobalSettingsExtensions.cs | 5 ++- src/Umbraco.Core/IO/FileSystems.cs | 12 ++--- src/Umbraco.Core/IO/IOHelper.cs | 26 ++++++----- src/Umbraco.Core/IO/ShadowWrapper.cs | 2 +- src/Umbraco.Core/IO/SystemDirectories.cs | 44 +++++++++---------- src/Umbraco.Core/IO/SystemFiles.cs | 3 +- .../Migrations/Install/DatabaseBuilder.cs | 4 +- .../Packaging/CompiledPackageXmlParser.cs | 9 ++-- .../Packaging/PackageDataInstallation.cs | 3 +- .../Packaging/PackagesRepository.cs | 6 +-- .../Implement/PartialViewRepository.cs | 2 +- .../Implement/ScriptRepository.cs | 4 +- .../Implement/StylesheetRepository.cs | 2 +- .../Implement/TemplateRepository.cs | 2 +- .../Runtime/CoreInitialComponent.cs | 8 ++-- .../Services/Implement/FileService.cs | 4 +- .../Services/Implement/NotificationService.cs | 4 +- .../Services/Implement/PackagingService.cs | 2 +- src/Umbraco.Core/Sync/ApplicationUrlHelper.cs | 2 +- src/Umbraco.Examine/LuceneIndexCreator.cs | 2 +- src/Umbraco.Examine/LuceneIndexDiagnostics.cs | 2 +- .../Configurations/GlobalSettingsTests.cs | 6 +-- .../CoreThings/UriExtensionsTests.cs | 11 ++--- src/Umbraco.Tests/IO/IoHelperTests.cs | 2 + src/Umbraco.Tests/IO/ShadowFileSystemTests.cs | 8 ++-- .../LegacyXmlPublishedCache/PreviewContent.cs | 4 +- .../PartialViewRepositoryTests.cs | 3 +- .../Repositories/ScriptRepositoryTest.cs | 5 ++- .../Repositories/StylesheetRepositoryTest.cs | 5 ++- .../Repositories/TemplateRepositoryTest.cs | 9 ++-- .../Scoping/ScopeFileSystemsTests.cs | 2 +- src/Umbraco.Tests/TestHelpers/TestHelper.cs | 6 +-- src/Umbraco.Tests/TestHelpers/TestObjects.cs | 6 +-- src/Umbraco.Web/Composing/Current.cs | 1 + .../Editors/BackOfficeAssetsController.cs | 2 +- .../Editors/BackOfficeServerVariables.cs | 6 +-- .../Binders/ContentModelBinderHelper.cs | 3 +- src/Umbraco.Web/Editors/CodeFileController.cs | 28 ++++++------ .../Editors/ContentTypeController.cs | 4 +- src/Umbraco.Web/Editors/MacrosController.cs | 8 ++-- src/Umbraco.Web/Editors/MediaController.cs | 2 +- .../Editors/PackageInstallController.cs | 10 ++--- src/Umbraco.Web/Editors/TinyMceController.cs | 4 +- src/Umbraco.Web/Editors/TourController.cs | 4 +- src/Umbraco.Web/Editors/UsersController.cs | 2 +- .../FolderAndFilePermissionsCheck.cs | 24 +++++----- src/Umbraco.Web/HtmlHelperRenderExtensions.cs | 2 +- .../Install/Controllers/InstallController.cs | 6 +-- .../Install/FilePermissionHelper.cs | 6 +-- .../Install/InstallAuthorizeAttribute.cs | 2 +- .../Install/InstallStatusTracker.cs | 10 ++--- .../InstallSteps/ConfigureMachineKey.cs | 2 +- .../InstallSteps/StarterKitCleanupStep.cs | 2 +- .../ClientDependencyConfiguration.cs | 2 +- .../JavaScript/JsInitialization.cs | 2 +- .../UmbracoClientDependencyLoader.cs | 2 +- src/Umbraco.Web/Mvc/PluginViewEngine.cs | 26 +++++------ .../Mvc/UmbracoViewPageOfTModel.cs | 2 +- .../Runtime/WebInitialComponent.cs | 2 +- .../Scheduling/SchedulerComponent.cs | 2 +- src/Umbraco.Web/Security/WebSecurity.cs | 2 +- src/Umbraco.Web/UmbracoInjectedModule.cs | 6 +-- 68 files changed, 249 insertions(+), 191 deletions(-) create mode 100644 src/Umbraco.Abstractions/IO/ISystemDirectories.cs diff --git a/src/Umbraco.Abstractions/IO/ISystemDirectories.cs b/src/Umbraco.Abstractions/IO/ISystemDirectories.cs new file mode 100644 index 0000000000..4c1499760e --- /dev/null +++ b/src/Umbraco.Abstractions/IO/ISystemDirectories.cs @@ -0,0 +1,33 @@ +namespace Umbraco.Core.IO +{ + public interface ISystemDirectories + { + string Bin { get; } + string Config { get; } + string Data { get; } + string TempData { get; } + string TempFileUploads { get; } + string TempImageUploads { get; } + string Install { get; } + string AppCode { get; } + string AppPlugins { get; } + string MvcViews { get; } + string PartialViews { get; } + string MacroPartials { get; } + string Media { get; } + string Scripts { get; } + string Css { get; } + string Umbraco { get; } + string Packages { get; } + string Preview { get; } + + /// + /// Gets the root path of the application + /// + string Root + { + get; + set; //Only required for unit tests + } + } +} diff --git a/src/Umbraco.Core/Composing/CompositionExtensions/FileSystems.cs b/src/Umbraco.Core/Composing/CompositionExtensions/FileSystems.cs index 8518d907b5..27a8a03323 100644 --- a/src/Umbraco.Core/Composing/CompositionExtensions/FileSystems.cs +++ b/src/Umbraco.Core/Composing/CompositionExtensions/FileSystems.cs @@ -90,7 +90,7 @@ namespace Umbraco.Core.Composing.CompositionExtensions // register the IFileSystem supporting the IMediaFileSystem // THIS IS THE ONLY THING THAT NEEDS TO CHANGE, IN ORDER TO REPLACE THE UNDERLYING FILESYSTEM // and, SupportingFileSystem.For() returns the underlying filesystem - composition.SetMediaFileSystem(() => new PhysicalFileSystem(SystemDirectories.Media)); + composition.SetMediaFileSystem(() => new PhysicalFileSystem(Current.SystemDirectories.Media)); return composition; } diff --git a/src/Umbraco.Core/Composing/CompositionExtensions/Services.cs b/src/Umbraco.Core/Composing/CompositionExtensions/Services.cs index 9d7d0a191d..bec5640860 100644 --- a/src/Umbraco.Core/Composing/CompositionExtensions/Services.cs +++ b/src/Umbraco.Core/Composing/CompositionExtensions/Services.cs @@ -89,9 +89,10 @@ namespace Umbraco.Core.Composing.CompositionExtensions private static LocalizedTextServiceFileSources SourcesFactory(IFactory container) { - var mainLangFolder = new DirectoryInfo(Current.IOHelper.MapPath(SystemDirectories.Umbraco + "/config/lang/")); - var appPlugins = new DirectoryInfo(Current.IOHelper.MapPath(SystemDirectories.AppPlugins)); - var configLangFolder = new DirectoryInfo(Current.IOHelper.MapPath(SystemDirectories.Config + "/lang/")); + ISystemDirectories systemDirectories = new SystemDirectories(); + var mainLangFolder = new DirectoryInfo(Current.IOHelper.MapPath(systemDirectories.Umbraco + "/config/lang/")); + var appPlugins = new DirectoryInfo(Current.IOHelper.MapPath(systemDirectories.AppPlugins)); + var configLangFolder = new DirectoryInfo(Current.IOHelper.MapPath(systemDirectories.Config + "/lang/")); var pluginLangFolders = appPlugins.Exists == false ? Enumerable.Empty() diff --git a/src/Umbraco.Core/Composing/Current.cs b/src/Umbraco.Core/Composing/Current.cs index 3f9c4db288..4604590a8f 100644 --- a/src/Umbraco.Core/Composing/Current.cs +++ b/src/Umbraco.Core/Composing/Current.cs @@ -205,7 +205,8 @@ namespace Umbraco.Core.Composing public static IVariationContextAccessor VariationContextAccessor => Factory.GetInstance(); - public static readonly IIOHelper IOHelper = new IOHelper(); + public static readonly IIOHelper IOHelper = Umbraco.Core.IO.IOHelper.Default; + public static readonly ISystemDirectories SystemDirectories = new SystemDirectories(); #endregion } diff --git a/src/Umbraco.Core/ConfigsExtensions.cs b/src/Umbraco.Core/ConfigsExtensions.cs index 10293d1171..a3e60457a2 100644 --- a/src/Umbraco.Core/ConfigsExtensions.cs +++ b/src/Umbraco.Core/ConfigsExtensions.cs @@ -33,7 +33,7 @@ namespace Umbraco.Core public static void AddCoreConfigs(this Configs configs) { - var configDir = new DirectoryInfo(Current.IOHelper.MapPath(SystemDirectories.Config)); + var configDir = new DirectoryInfo(Current.IOHelper.MapPath(Current.SystemDirectories.Config)); configs.Add(() => new GlobalSettings()); configs.Add("umbracoConfiguration/settings"); diff --git a/src/Umbraco.Core/Configuration/GlobalSettings.cs b/src/Umbraco.Core/Configuration/GlobalSettings.cs index f2438065a4..0e024346af 100644 --- a/src/Umbraco.Core/Configuration/GlobalSettings.cs +++ b/src/Umbraco.Core/Configuration/GlobalSettings.cs @@ -171,7 +171,7 @@ namespace Umbraco.Core.Configuration /// Value of the setting to be saved. internal static void SaveSetting(string key, string value) { - var fileName = Current.IOHelper.MapPath(string.Format("{0}/web.config", SystemDirectories.Root)); + var fileName = Current.IOHelper.MapPath(string.Format("{0}/web.config", Current.SystemDirectories.Root)); var xml = XDocument.Load(fileName, LoadOptions.PreserveWhitespace); var appSettings = xml.Root.DescendantsAndSelf("appSettings").Single(); @@ -193,7 +193,7 @@ namespace Umbraco.Core.Configuration /// Key of the setting to be removed. internal static void RemoveSetting(string key) { - var fileName = Current.IOHelper.MapPath(string.Format("{0}/web.config", SystemDirectories.Root)); + var fileName = Current.IOHelper.MapPath(string.Format("{0}/web.config", Current.SystemDirectories.Root)); var xml = XDocument.Load(fileName, LoadOptions.PreserveWhitespace); var appSettings = xml.Root.DescendantsAndSelf("appSettings").Single(); diff --git a/src/Umbraco.Core/Configuration/GlobalSettingsExtensions.cs b/src/Umbraco.Core/Configuration/GlobalSettingsExtensions.cs index bc76caacee..2bc1e8d8c2 100644 --- a/src/Umbraco.Core/Configuration/GlobalSettingsExtensions.cs +++ b/src/Umbraco.Core/Configuration/GlobalSettingsExtensions.cs @@ -5,6 +5,7 @@ using System.Linq; using System.Threading; using System.Web; using System.Web.Routing; +using Umbraco.Core.Composing; using Umbraco.Core.IO; namespace Umbraco.Core.Configuration @@ -42,8 +43,8 @@ namespace Umbraco.Core.Configuration } var path = globalSettings.Path; - if (path.StartsWith(SystemDirectories.Root)) // beware of TrimStart, see U4-2518 - path = path.Substring(SystemDirectories.Root.Length); + if (path.StartsWith(Current.SystemDirectories.Root)) // beware of TrimStart, see U4-2518 + path = path.Substring(Current.SystemDirectories.Root.Length); return path.TrimStart('~').TrimStart('/').Replace('/', '-').Trim().ToLower(); } diff --git a/src/Umbraco.Core/IO/FileSystems.cs b/src/Umbraco.Core/IO/FileSystems.cs index 8906752dd1..88ed3b48ae 100644 --- a/src/Umbraco.Core/IO/FileSystems.cs +++ b/src/Umbraco.Core/IO/FileSystems.cs @@ -11,6 +11,7 @@ namespace Umbraco.Core.IO { private readonly IFactory _container; private readonly ILogger _logger; + private readonly ISystemDirectories _systemDirectories; private readonly ConcurrentDictionary> _filesystems = new ConcurrentDictionary>(); @@ -37,6 +38,7 @@ namespace Umbraco.Core.IO { _container = container; _logger = logger; + _systemDirectories = Current.SystemDirectories; } // for tests only, totally unsafe @@ -120,11 +122,11 @@ namespace Umbraco.Core.IO // but it does not really matter what we return - here, null private object CreateWellKnownFileSystems() { - var macroPartialFileSystem = new PhysicalFileSystem(SystemDirectories.MacroPartials); - var partialViewsFileSystem = new PhysicalFileSystem(SystemDirectories.PartialViews); - var stylesheetsFileSystem = new PhysicalFileSystem(SystemDirectories.Css); - var scriptsFileSystem = new PhysicalFileSystem(SystemDirectories.Scripts); - var mvcViewsFileSystem = new PhysicalFileSystem(SystemDirectories.MvcViews); + var macroPartialFileSystem = new PhysicalFileSystem(_systemDirectories.MacroPartials); + var partialViewsFileSystem = new PhysicalFileSystem(_systemDirectories.PartialViews); + var stylesheetsFileSystem = new PhysicalFileSystem(_systemDirectories.Css); + var scriptsFileSystem = new PhysicalFileSystem(_systemDirectories.Scripts); + var mvcViewsFileSystem = new PhysicalFileSystem(_systemDirectories.MvcViews); _macroPartialFileSystem = new ShadowWrapper(macroPartialFileSystem, "macro-partials", IsScoped); _partialViewsFileSystem = new ShadowWrapper(partialViewsFileSystem, "partials", IsScoped); diff --git a/src/Umbraco.Core/IO/IOHelper.cs b/src/Umbraco.Core/IO/IOHelper.cs index 36215b267c..3925e6d8d5 100644 --- a/src/Umbraco.Core/IO/IOHelper.cs +++ b/src/Umbraco.Core/IO/IOHelper.cs @@ -13,7 +13,13 @@ namespace Umbraco.Core.IO { public class IOHelper : IIOHelper { - internal static IIOHelper Default { get; } = new IOHelper(); + private readonly ISystemDirectories _systemDirectories; + internal static IIOHelper Default { get; } = new IOHelper(new SystemDirectories()); + + public IOHelper(ISystemDirectories systemDirectories) + { + _systemDirectories = systemDirectories; + } /// /// Gets or sets a value forcing Umbraco to consider it is non-hosted. @@ -39,10 +45,10 @@ namespace Umbraco.Core.IO string retval = virtualPath; if (virtualPath.StartsWith("~")) - retval = virtualPath.Replace("~", SystemDirectories.Root); + retval = virtualPath.Replace("~", _systemDirectories.Root); - if (virtualPath.StartsWith("/") && virtualPath.StartsWith(SystemDirectories.Root) == false) - retval = SystemDirectories.Root + "/" + virtualPath.TrimStart('/'); + if (virtualPath.StartsWith("/") && virtualPath.StartsWith(_systemDirectories.Root) == false) + retval = _systemDirectories.Root + "/" + virtualPath.TrimStart('/'); return retval; } @@ -57,11 +63,11 @@ namespace Umbraco.Core.IO public string ResolveUrl(string virtualPath) { if (virtualPath.StartsWith("~")) - return virtualPath.Replace("~", SystemDirectories.Root).Replace("//", "/"); + return virtualPath.Replace("~", _systemDirectories.Root).Replace("//", "/"); else if (Uri.IsWellFormedUriString(virtualPath, UriKind.Absolute)) return virtualPath; else - return VirtualPathUtility.ToAbsolute(virtualPath, SystemDirectories.Root); + return VirtualPathUtility.ToAbsolute(virtualPath, _systemDirectories.Root); } public Attempt TryResolveUrl(string virtualPath) @@ -69,10 +75,10 @@ namespace Umbraco.Core.IO try { if (virtualPath.StartsWith("~")) - return Attempt.Succeed(virtualPath.Replace("~", SystemDirectories.Root).Replace("//", "/")); + return Attempt.Succeed(virtualPath.Replace("~", _systemDirectories.Root).Replace("//", "/")); if (Uri.IsWellFormedUriString(virtualPath, UriKind.Absolute)) return Attempt.Succeed(virtualPath); - return Attempt.Succeed(VirtualPathUtility.ToAbsolute(virtualPath, SystemDirectories.Root)); + return Attempt.Succeed(VirtualPathUtility.ToAbsolute(virtualPath, _systemDirectories.Root)); } catch (Exception ex) { @@ -97,7 +103,7 @@ namespace Umbraco.Core.IO if (useHttpContext && HttpContext.Current != null) { //string retval; - if (String.IsNullOrEmpty(path) == false && (path.StartsWith("~") || path.StartsWith(SystemDirectories.Root))) + if (String.IsNullOrEmpty(path) == false && (path.StartsWith("~") || path.StartsWith(_systemDirectories.Root))) return HostingEnvironment.MapPath(path); else return HostingEnvironment.MapPath("~/" + path.TrimStart('/')); @@ -160,7 +166,7 @@ namespace Umbraco.Core.IO // TODO: what's below is dirty, there are too many ways to get the root dir, etc. // not going to fix everything today - var mappedRoot = MapPath(SystemDirectories.Root); + var mappedRoot = MapPath(_systemDirectories.Root); if (filePath.StartsWith(mappedRoot) == false) filePath = MapPath(filePath); diff --git a/src/Umbraco.Core/IO/ShadowWrapper.cs b/src/Umbraco.Core/IO/ShadowWrapper.cs index 44152d7c1a..aab65e0a25 100644 --- a/src/Umbraco.Core/IO/ShadowWrapper.cs +++ b/src/Umbraco.Core/IO/ShadowWrapper.cs @@ -8,7 +8,7 @@ namespace Umbraco.Core.IO { internal class ShadowWrapper : IFileSystem { - private static readonly string ShadowFsPath = SystemDirectories.TempData.EnsureEndsWith('/') + "ShadowFs"; + private static readonly string ShadowFsPath = Current.SystemDirectories.TempData.EnsureEndsWith('/') + "ShadowFs"; private readonly Func _isScoped; private readonly IFileSystem _innerFileSystem; diff --git a/src/Umbraco.Core/IO/SystemDirectories.cs b/src/Umbraco.Core/IO/SystemDirectories.cs index c5c410ff3f..4a976f5675 100644 --- a/src/Umbraco.Core/IO/SystemDirectories.cs +++ b/src/Umbraco.Core/IO/SystemDirectories.cs @@ -4,50 +4,50 @@ using Umbraco.Core.Composing; namespace Umbraco.Core.IO { //all paths has a starting but no trailing / - public class SystemDirectories + public class SystemDirectories : ISystemDirectories { - public static string Bin => "~/bin"; + public string Bin => "~/bin"; - public static string Config => "~/config"; + public string Config => "~/config"; - public static string Data => "~/App_Data"; + public string Data => "~/App_Data"; - public static string TempData => Data + "/TEMP"; + public string TempData => Data + "/TEMP"; - public static string TempFileUploads => TempData + "/FileUploads"; + public string TempFileUploads => TempData + "/FileUploads"; - public static string TempImageUploads => TempFileUploads + "/rte"; + public string TempImageUploads => TempFileUploads + "/rte"; - public static string Install => "~/install"; + public string Install => "~/install"; - public static string AppCode => "~/App_Code"; + public string AppCode => "~/App_Code"; - public static string AppPlugins => "~/App_Plugins"; + public string AppPlugins => "~/App_Plugins"; - public static string MvcViews => "~/Views"; + public string MvcViews => "~/Views"; - public static string PartialViews => MvcViews + "/Partials/"; + public string PartialViews => MvcViews + "/Partials/"; - public static string MacroPartials => MvcViews + "/MacroPartials/"; + public string MacroPartials => MvcViews + "/MacroPartials/"; - public static string Media => Current.IOHelper.ReturnPath("umbracoMediaPath", "~/media"); + public string Media => Current.IOHelper.ReturnPath("umbracoMediaPath", "~/media"); - public static string Scripts => Current.IOHelper.ReturnPath("umbracoScriptsPath", "~/scripts"); + public string Scripts => Current.IOHelper.ReturnPath("umbracoScriptsPath", "~/scripts"); - public static string Css => Current.IOHelper.ReturnPath("umbracoCssPath", "~/css"); + public string Css => Current.IOHelper.ReturnPath("umbracoCssPath", "~/css"); - public static string Umbraco => Current.IOHelper.ReturnPath("umbracoPath", "~/umbraco"); + public string Umbraco => Current.IOHelper.ReturnPath("umbracoPath", "~/umbraco"); - public static string Packages => Data + "/packages"; + public string Packages => Data + "/packages"; - public static string Preview => Data + "/preview"; + public string Preview => Data + "/preview"; - private static string _root; + private string _root; /// /// Gets the root path of the application /// - public static string Root + public string Root { get { @@ -62,7 +62,7 @@ namespace Umbraco.Core.IO return _root; } //Only required for unit tests - internal set => _root = value; + set => _root = value; } } } diff --git a/src/Umbraco.Core/IO/SystemFiles.cs b/src/Umbraco.Core/IO/SystemFiles.cs index 12e3f57d99..7df39eac6c 100644 --- a/src/Umbraco.Core/IO/SystemFiles.cs +++ b/src/Umbraco.Core/IO/SystemFiles.cs @@ -1,11 +1,12 @@ using System.IO; +using Umbraco.Core.Composing; using Umbraco.Core.Configuration; namespace Umbraco.Core.IO { public class SystemFiles { - public static string TinyMceConfig => SystemDirectories.Config + "/tinyMceConfig.config"; + public static string TinyMceConfig => Current.SystemDirectories.Config + "/tinyMceConfig.config"; // TODO: Kill this off we don't have umbraco.config XML cache we now have NuCache public static string GetContentCacheXml(IGlobalSettings globalSettings) diff --git a/src/Umbraco.Core/Migrations/Install/DatabaseBuilder.cs b/src/Umbraco.Core/Migrations/Install/DatabaseBuilder.cs index a0c87ce510..a7c6b38c1c 100644 --- a/src/Umbraco.Core/Migrations/Install/DatabaseBuilder.cs +++ b/src/Umbraco.Core/Migrations/Install/DatabaseBuilder.cs @@ -283,7 +283,7 @@ namespace Umbraco.Core.Migrations.Install if (string.IsNullOrWhiteSpace(providerName)) throw new ArgumentNullOrEmptyException(nameof(providerName)); var fileSource = "web.config"; - var fileName = Current.IOHelper.MapPath(SystemDirectories.Root +"/" + fileSource); + var fileName = Current.IOHelper.MapPath(Current.SystemDirectories.Root +"/" + fileSource); var xml = XDocument.Load(fileName, LoadOptions.PreserveWhitespace); if (xml.Root == null) throw new Exception($"Invalid {fileSource} file (no root)."); @@ -296,7 +296,7 @@ namespace Umbraco.Core.Migrations.Install if (configSourceAttribute != null) { fileSource = configSourceAttribute.Value; - fileName = Current.IOHelper.MapPath(SystemDirectories.Root + "/" + fileSource); + fileName = Current.IOHelper.MapPath(Current.SystemDirectories.Root + "/" + fileSource); if (!File.Exists(fileName)) throw new Exception($"Invalid configSource \"{fileSource}\" (no such file)."); diff --git a/src/Umbraco.Core/Packaging/CompiledPackageXmlParser.cs b/src/Umbraco.Core/Packaging/CompiledPackageXmlParser.cs index 83034a7e1b..80857ab5eb 100644 --- a/src/Umbraco.Core/Packaging/CompiledPackageXmlParser.cs +++ b/src/Umbraco.Core/Packaging/CompiledPackageXmlParser.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; using System.Xml.Linq; +using Umbraco.Core.Composing; using Umbraco.Core.IO; using Umbraco.Core.Models; using Umbraco.Core.Models.Packaging; @@ -131,15 +132,15 @@ namespace Umbraco.Core.Packaging { return pathElement.TrimStart(new[] { '\\', '/', '~' }).Replace("/", "\\"); } - + private static string UpdatePathPlaceholders(string path) { if (path.Contains("[$")) { //this is experimental and undocumented... - path = path.Replace("[$UMBRACO]", SystemDirectories.Umbraco); - path = path.Replace("[$CONFIG]", SystemDirectories.Config); - path = path.Replace("[$DATA]", SystemDirectories.Data); + path = path.Replace("[$UMBRACO]", Current.SystemDirectories.Umbraco); + path = path.Replace("[$CONFIG]", Current.SystemDirectories.Config); + path = path.Replace("[$DATA]", Current.SystemDirectories.Data); } return path; } diff --git a/src/Umbraco.Core/Packaging/PackageDataInstallation.cs b/src/Umbraco.Core/Packaging/PackageDataInstallation.cs index 281cc2c396..8cd0225327 100644 --- a/src/Umbraco.Core/Packaging/PackageDataInstallation.cs +++ b/src/Umbraco.Core/Packaging/PackageDataInstallation.cs @@ -6,6 +6,7 @@ using System.Web; using System.Xml.Linq; using System.Xml.XPath; using Umbraco.Core.Collections; +using Umbraco.Core.Composing; using Umbraco.Core.IO; using Umbraco.Core.Logging; using Umbraco.Core.Models; @@ -1317,7 +1318,7 @@ namespace Umbraco.Core.Packaging private string ViewPath(string alias) { - return SystemDirectories.MvcViews + "/" + alias.Replace(" ", "") + ".cshtml"; + return Current.SystemDirectories.MvcViews + "/" + alias.Replace(" ", "") + ".cshtml"; } #endregion diff --git a/src/Umbraco.Core/Packaging/PackagesRepository.cs b/src/Umbraco.Core/Packaging/PackagesRepository.cs index 458a239cc0..24455308c8 100644 --- a/src/Umbraco.Core/Packaging/PackagesRepository.cs +++ b/src/Umbraco.Core/Packaging/PackagesRepository.cs @@ -70,9 +70,9 @@ namespace Umbraco.Core.Packaging _logger = logger; _packageRepositoryFileName = packageRepositoryFileName; - _tempFolderPath = tempFolderPath ?? SystemDirectories.TempData.EnsureEndsWith('/') + "PackageFiles"; - _packagesFolderPath = packagesFolderPath ?? SystemDirectories.Packages; - _mediaFolderPath = mediaFolderPath ?? SystemDirectories.Media + "/created-packages"; + _tempFolderPath = tempFolderPath ?? Current.SystemDirectories.TempData.EnsureEndsWith('/') + "PackageFiles"; + _packagesFolderPath = packagesFolderPath ?? Current.SystemDirectories.Packages; + _mediaFolderPath = mediaFolderPath ?? Current.SystemDirectories.Media + "/created-packages"; _parser = new PackageDefinitionXmlParser(logger); } diff --git a/src/Umbraco.Core/Persistence/Repositories/Implement/PartialViewRepository.cs b/src/Umbraco.Core/Persistence/Repositories/Implement/PartialViewRepository.cs index d7d1be55c7..bee7260b53 100644 --- a/src/Umbraco.Core/Persistence/Repositories/Implement/PartialViewRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/Implement/PartialViewRepository.cs @@ -103,7 +103,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement } // validate path & extension - var validDir = SystemDirectories.MvcViews; + var validDir = Current.SystemDirectories.MvcViews; var isValidPath = Current.IOHelper.VerifyEditPath(fullPath, validDir); var isValidExtension = Current.IOHelper.VerifyFileExtension(fullPath, ValidExtensions); return isValidPath && isValidExtension; diff --git a/src/Umbraco.Core/Persistence/Repositories/Implement/ScriptRepository.cs b/src/Umbraco.Core/Persistence/Repositories/Implement/ScriptRepository.cs index 491dafe577..3acdb331a1 100644 --- a/src/Umbraco.Core/Persistence/Repositories/Implement/ScriptRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/Implement/ScriptRepository.cs @@ -15,11 +15,13 @@ namespace Umbraco.Core.Persistence.Repositories.Implement internal class ScriptRepository : FileRepository, IScriptRepository { private readonly IIOHelper _ioHelper; + private readonly ISystemDirectories _systemDirectories; public ScriptRepository(IFileSystems fileSystems, IIOHelper ioHelper) : base(fileSystems.ScriptsFileSystem) { _ioHelper = ioHelper ?? throw new ArgumentNullException(nameof(ioHelper)); + _systemDirectories = Current.SystemDirectories; } #region Implementation of IRepository @@ -104,7 +106,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement } // validate path & extension - var validDir = SystemDirectories.Scripts; + var validDir = _systemDirectories.Scripts; var isValidPath = _ioHelper.VerifyEditPath(fullPath, validDir); var validExts = new[] {"js"}; var isValidExtension = _ioHelper.VerifyFileExtension(script.Path, validExts); diff --git a/src/Umbraco.Core/Persistence/Repositories/Implement/StylesheetRepository.cs b/src/Umbraco.Core/Persistence/Repositories/Implement/StylesheetRepository.cs index 94737b5620..de661d1f7e 100644 --- a/src/Umbraco.Core/Persistence/Repositories/Implement/StylesheetRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/Implement/StylesheetRepository.cs @@ -121,7 +121,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement } // validate path and extension - var validDir = SystemDirectories.Css; + var validDir = Current.SystemDirectories.Css; var isValidPath = _ioHelper.VerifyEditPath(fullPath, validDir); var isValidExtension = _ioHelper.VerifyFileExtension(stylesheet.Path, ValidExtensions); return isValidPath && isValidExtension; diff --git a/src/Umbraco.Core/Persistence/Repositories/Implement/TemplateRepository.cs b/src/Umbraco.Core/Persistence/Repositories/Implement/TemplateRepository.cs index 5fd319e4d4..b45ec5048b 100644 --- a/src/Umbraco.Core/Persistence/Repositories/Implement/TemplateRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/Implement/TemplateRepository.cs @@ -585,7 +585,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement var path = template.VirtualPath; // get valid paths - var validDirs = new[] { SystemDirectories.MvcViews }; + var validDirs = new[] { Current.SystemDirectories.MvcViews }; // get valid extensions var validExts = new List(); diff --git a/src/Umbraco.Core/Runtime/CoreInitialComponent.cs b/src/Umbraco.Core/Runtime/CoreInitialComponent.cs index f88417948b..0cb7024e66 100644 --- a/src/Umbraco.Core/Runtime/CoreInitialComponent.cs +++ b/src/Umbraco.Core/Runtime/CoreInitialComponent.cs @@ -10,10 +10,10 @@ namespace Umbraco.Core.Runtime // ensure we have some essential directories // every other component can then initialize safely Current.IOHelper.EnsurePathExists("~/App_Data"); - Current.IOHelper.EnsurePathExists(SystemDirectories.Media); - Current.IOHelper.EnsurePathExists(SystemDirectories.MvcViews); - Current.IOHelper.EnsurePathExists(SystemDirectories.MvcViews + "/Partials"); - Current.IOHelper.EnsurePathExists(SystemDirectories.MvcViews + "/MacroPartials"); + Current.IOHelper.EnsurePathExists(Current.SystemDirectories.Media); + Current.IOHelper.EnsurePathExists(Current.SystemDirectories.MvcViews); + Current.IOHelper.EnsurePathExists(Current.SystemDirectories.MvcViews + "/Partials"); + Current.IOHelper.EnsurePathExists(Current.SystemDirectories.MvcViews + "/MacroPartials"); } public void Terminate() diff --git a/src/Umbraco.Core/Services/Implement/FileService.cs b/src/Umbraco.Core/Services/Implement/FileService.cs index cde8ed30fe..afc30e09ce 100644 --- a/src/Umbraco.Core/Services/Implement/FileService.cs +++ b/src/Umbraco.Core/Services/Implement/FileService.cs @@ -664,7 +664,7 @@ namespace Umbraco.Core.Services.Implement public IEnumerable GetPartialViewSnippetNames(params string[] filterNames) { - var snippetPath = Current.IOHelper.MapPath($"{SystemDirectories.Umbraco}/PartialViewMacros/Templates/"); + var snippetPath = Current.IOHelper.MapPath($"{Current.SystemDirectories.Umbraco}/PartialViewMacros/Templates/"); var files = Directory.GetFiles(snippetPath, "*.cshtml") .Select(Path.GetFileNameWithoutExtension) .Except(filterNames, StringComparer.InvariantCultureIgnoreCase) @@ -898,7 +898,7 @@ namespace Umbraco.Core.Services.Implement fileName += ".cshtml"; } - var snippetPath = Current.IOHelper.MapPath($"{SystemDirectories.Umbraco}/PartialViewMacros/Templates/{fileName}"); + var snippetPath = Current.IOHelper.MapPath($"{Current.SystemDirectories.Umbraco}/PartialViewMacros/Templates/{fileName}"); return System.IO.File.Exists(snippetPath) ? Attempt.Succeed(snippetPath) : Attempt.Fail(); diff --git a/src/Umbraco.Core/Services/Implement/NotificationService.cs b/src/Umbraco.Core/Services/Implement/NotificationService.cs index 65040f625a..fa7b14abe4 100644 --- a/src/Umbraco.Core/Services/Implement/NotificationService.cs +++ b/src/Umbraco.Core/Services/Implement/NotificationService.cs @@ -384,7 +384,7 @@ namespace Umbraco.Core.Services.Implement var protocol = _globalSettings.UseHttps ? "https" : "http"; var subjectVars = new NotificationEmailSubjectParams( - string.Concat(siteUri.Authority, Current.IOHelper.ResolveUrl(SystemDirectories.Umbraco)), + string.Concat(siteUri.Authority, Current.IOHelper.ResolveUrl(Current.SystemDirectories.Umbraco)), actionName, content.Name); @@ -400,7 +400,7 @@ namespace Umbraco.Core.Services.Implement string.Concat(content.Id, ".aspx"), protocol), performingUser.Name, - string.Concat(siteUri.Authority, Current.IOHelper.ResolveUrl(SystemDirectories.Umbraco)), + string.Concat(siteUri.Authority, Current.IOHelper.ResolveUrl(Current.SystemDirectories.Umbraco)), summary.ToString()); // create the mail message diff --git a/src/Umbraco.Core/Services/Implement/PackagingService.cs b/src/Umbraco.Core/Services/Implement/PackagingService.cs index c0946e4468..f68685ee57 100644 --- a/src/Umbraco.Core/Services/Implement/PackagingService.cs +++ b/src/Umbraco.Core/Services/Implement/PackagingService.cs @@ -64,7 +64,7 @@ namespace Umbraco.Core.Services.Implement //successful if (bytes.Length > 0) { - var packagePath = Current.IOHelper.MapPath(SystemDirectories.Packages); + var packagePath = Current.IOHelper.MapPath(Current.SystemDirectories.Packages); // Check for package directory if (Directory.Exists(packagePath) == false) diff --git a/src/Umbraco.Core/Sync/ApplicationUrlHelper.cs b/src/Umbraco.Core/Sync/ApplicationUrlHelper.cs index b7afc1048b..b58aefe5dd 100644 --- a/src/Umbraco.Core/Sync/ApplicationUrlHelper.cs +++ b/src/Umbraco.Core/Sync/ApplicationUrlHelper.cs @@ -98,7 +98,7 @@ namespace Umbraco.Core.Sync : ""; var ssl = globalSettings.UseHttps ? "s" : ""; // force, whatever the first request - var url = "http" + ssl + "://" + request.ServerVariables["SERVER_NAME"] + port + Current.IOHelper.ResolveUrl(SystemDirectories.Umbraco); + var url = "http" + ssl + "://" + request.ServerVariables["SERVER_NAME"] + port + Current.IOHelper.ResolveUrl(Current.SystemDirectories.Umbraco); return url.TrimEnd('/'); } diff --git a/src/Umbraco.Examine/LuceneIndexCreator.cs b/src/Umbraco.Examine/LuceneIndexCreator.cs index 3834c1476e..f310ca9229 100644 --- a/src/Umbraco.Examine/LuceneIndexCreator.cs +++ b/src/Umbraco.Examine/LuceneIndexCreator.cs @@ -36,7 +36,7 @@ namespace Umbraco.Examine public virtual Lucene.Net.Store.Directory CreateFileSystemLuceneDirectory(string folderName) { - var dirInfo = new DirectoryInfo(Path.Combine(Current.IOHelper.MapPath(SystemDirectories.TempData), "ExamineIndexes", folderName)); + var dirInfo = new DirectoryInfo(Path.Combine(Current.IOHelper.MapPath(Current.SystemDirectories.TempData), "ExamineIndexes", folderName)); if (!dirInfo.Exists) System.IO.Directory.CreateDirectory(dirInfo.FullName); diff --git a/src/Umbraco.Examine/LuceneIndexDiagnostics.cs b/src/Umbraco.Examine/LuceneIndexDiagnostics.cs index 7a91552c81..0ed2d88085 100644 --- a/src/Umbraco.Examine/LuceneIndexDiagnostics.cs +++ b/src/Umbraco.Examine/LuceneIndexDiagnostics.cs @@ -72,7 +72,7 @@ namespace Umbraco.Examine if (luceneDir is FSDirectory fsDir) { - d[nameof(UmbracoExamineIndex.LuceneIndexFolder)] = fsDir.Directory.ToString().ToLowerInvariant().TrimStart(Current.IOHelper.MapPath(SystemDirectories.Root).ToLowerInvariant()).Replace("\\", "/").EnsureStartsWith('/'); + d[nameof(UmbracoExamineIndex.LuceneIndexFolder)] = fsDir.Directory.ToString().ToLowerInvariant().TrimStart(Current.IOHelper.MapPath(Current.SystemDirectories.Root).ToLowerInvariant()).Replace("\\", "/").EnsureStartsWith('/'); } return d; diff --git a/src/Umbraco.Tests/Configurations/GlobalSettingsTests.cs b/src/Umbraco.Tests/Configurations/GlobalSettingsTests.cs index 69a9613a38..bab6a13dad 100644 --- a/src/Umbraco.Tests/Configurations/GlobalSettingsTests.cs +++ b/src/Umbraco.Tests/Configurations/GlobalSettingsTests.cs @@ -17,13 +17,13 @@ namespace Umbraco.Tests.Configurations public override void SetUp() { base.SetUp(); - _root = SystemDirectories.Root; + _root = Current.SystemDirectories.Root; } public override void TearDown() { base.TearDown(); - SystemDirectories.Root = _root; + Current.SystemDirectories.Root = _root; } [Test] @@ -51,7 +51,7 @@ namespace Umbraco.Tests.Configurations var globalSettingsMock = Mock.Get(globalSettings); globalSettingsMock.Setup(x => x.Path).Returns(() => Current.IOHelper.ResolveUrl(path)); - SystemDirectories.Root = rootPath; + Current.SystemDirectories.Root = rootPath; Assert.AreEqual(outcome, globalSettings.GetUmbracoMvcAreaNoCache()); } diff --git a/src/Umbraco.Tests/CoreThings/UriExtensionsTests.cs b/src/Umbraco.Tests/CoreThings/UriExtensionsTests.cs index be7aec631e..d3d5548a1d 100644 --- a/src/Umbraco.Tests/CoreThings/UriExtensionsTests.cs +++ b/src/Umbraco.Tests/CoreThings/UriExtensionsTests.cs @@ -1,6 +1,7 @@ using System; using NUnit.Framework; using Umbraco.Core; +using Umbraco.Core.Composing; using Umbraco.Core.IO; using Umbraco.Tests.TestHelpers; @@ -14,13 +15,13 @@ namespace Umbraco.Tests.CoreThings [SetUp] public void SetUp() { - _root = SystemDirectories.Root; + _root = Current.SystemDirectories.Root; } [TearDown] public void TearDown() { - SystemDirectories.Root = _root; + Current.SystemDirectories.Root = _root; } [TestCase("http://www.domain.com/umbraco", "", true)] @@ -32,7 +33,7 @@ namespace Umbraco.Tests.CoreThings [TestCase("http://www.domain.com/umbraco/test/test.js", "", true)] [TestCase("http://www.domain.com/umbrac", "", false)] [TestCase("http://www.domain.com/test", "", false)] - [TestCase("http://www.domain.com/test/umbraco", "", false)] + [TestCase("http://www.domain.com/test/umbraco", "", false)] [TestCase("http://www.domain.com/Umbraco/Backoffice/blah", "", true)] [TestCase("http://www.domain.com/Umbraco/anything", "", true)] [TestCase("http://www.domain.com/Umbraco/anything/", "", true)] @@ -44,7 +45,7 @@ namespace Umbraco.Tests.CoreThings [TestCase("http://www.domain.com/umbraco/test/legacyAjaxCalls.ashx?some=query&blah=js", "", true)] public void Is_Back_Office_Request(string input, string virtualPath, bool expected) { - SystemDirectories.Root = virtualPath; + Current.SystemDirectories.Root = virtualPath; var globalConfig = SettingsForTests.GenerateMockGlobalSettings(); var source = new Uri(input); Assert.AreEqual(expected, source.IsBackOfficeRequest(virtualPath, globalConfig)); @@ -58,7 +59,7 @@ namespace Umbraco.Tests.CoreThings [TestCase("http://www.domain.com/install/test/test.js", true)] [TestCase("http://www.domain.com/instal", false)] [TestCase("http://www.domain.com/umbraco", false)] - [TestCase("http://www.domain.com/umbraco/umbraco", false)] + [TestCase("http://www.domain.com/umbraco/umbraco", false)] public void Is_Installer_Request(string input, bool expected) { var source = new Uri(input); diff --git a/src/Umbraco.Tests/IO/IoHelperTests.cs b/src/Umbraco.Tests/IO/IoHelperTests.cs index 2a7e633e4f..5ca335db25 100644 --- a/src/Umbraco.Tests/IO/IoHelperTests.cs +++ b/src/Umbraco.Tests/IO/IoHelperTests.cs @@ -9,6 +9,8 @@ namespace Umbraco.Tests.IO [TestFixture] public class IoHelperTests { + private ISystemDirectories SystemDirectories => Current.SystemDirectories; + [TestCase("~/Scripts", "/Scripts", null)] [TestCase("/Scripts", "/Scripts", null)] [TestCase("../Scripts", "/Scripts", typeof(ArgumentException))] diff --git a/src/Umbraco.Tests/IO/ShadowFileSystemTests.cs b/src/Umbraco.Tests/IO/ShadowFileSystemTests.cs index 409fae6081..2e8c6c110f 100644 --- a/src/Umbraco.Tests/IO/ShadowFileSystemTests.cs +++ b/src/Umbraco.Tests/IO/ShadowFileSystemTests.cs @@ -41,7 +41,7 @@ namespace Umbraco.Tests.IO private static void ClearFiles() { TestHelper.DeleteDirectory(Current.IOHelper.MapPath("FileSysTests")); - TestHelper.DeleteDirectory(Current.IOHelper.MapPath(SystemDirectories.TempData.EnsureEndsWith('/') + "ShadowFs")); + TestHelper.DeleteDirectory(Current.IOHelper.MapPath(Current.SystemDirectories.TempData.EnsureEndsWith('/') + "ShadowFs")); } private static string NormPath(string path) @@ -388,7 +388,7 @@ namespace Umbraco.Tests.IO var logger = Mock.Of(); var path = Current.IOHelper.MapPath("FileSysTests"); - var shadowfs = Current.IOHelper.MapPath(SystemDirectories.TempData.EnsureEndsWith('/') + "ShadowFs"); + var shadowfs = Current.IOHelper.MapPath(Current.SystemDirectories.TempData.EnsureEndsWith('/') + "ShadowFs"); Directory.CreateDirectory(path); Directory.CreateDirectory(shadowfs); @@ -483,7 +483,7 @@ namespace Umbraco.Tests.IO var logger = Mock.Of(); var path = Current.IOHelper.MapPath("FileSysTests"); - var shadowfs = Current.IOHelper.MapPath(SystemDirectories.TempData.EnsureEndsWith('/') + "ShadowFs"); + var shadowfs = Current.IOHelper.MapPath(Current.SystemDirectories.TempData.EnsureEndsWith('/') + "ShadowFs"); Directory.CreateDirectory(path); var scopedFileSystems = false; @@ -536,7 +536,7 @@ namespace Umbraco.Tests.IO var logger = Mock.Of(); var path = Current.IOHelper.MapPath("FileSysTests"); - var shadowfs = Current.IOHelper.MapPath(SystemDirectories.TempData.EnsureEndsWith('/') + "ShadowFs"); + var shadowfs = Current.IOHelper.MapPath(Current.SystemDirectories.TempData.EnsureEndsWith('/') + "ShadowFs"); Directory.CreateDirectory(path); var scopedFileSystems = false; diff --git a/src/Umbraco.Tests/LegacyXmlPublishedCache/PreviewContent.cs b/src/Umbraco.Tests/LegacyXmlPublishedCache/PreviewContent.cs index adbd15b16a..f023eb9446 100644 --- a/src/Umbraco.Tests/LegacyXmlPublishedCache/PreviewContent.cs +++ b/src/Umbraco.Tests/LegacyXmlPublishedCache/PreviewContent.cs @@ -108,7 +108,7 @@ namespace Umbraco.Tests.LegacyXmlPublishedCache _previewXml = _xmlStore.GetPreviewXml(contentId, includeSubs); // make sure the preview folder exists - var dir = new DirectoryInfo(Current.IOHelper.MapPath(SystemDirectories.Preview)); + var dir = new DirectoryInfo(Current.IOHelper.MapPath(Current.SystemDirectories.Preview)); if (dir.Exists == false) dir.Create(); @@ -122,7 +122,7 @@ namespace Umbraco.Tests.LegacyXmlPublishedCache // get the full path to the preview set private static string GetPreviewSetPath(int userId, Guid previewSet) { - return Current.IOHelper.MapPath(Path.Combine(SystemDirectories.Preview, userId + "_" + previewSet + ".config")); + return Current.IOHelper.MapPath(Path.Combine(Current.SystemDirectories.Preview, userId + "_" + previewSet + ".config")); } // deletes files for the user, and files accessed more than one hour ago diff --git a/src/Umbraco.Tests/Persistence/Repositories/PartialViewRepositoryTests.cs b/src/Umbraco.Tests/Persistence/Repositories/PartialViewRepositoryTests.cs index 9c326b3ddc..8c47d709f2 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/PartialViewRepositoryTests.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/PartialViewRepositoryTests.cs @@ -1,6 +1,7 @@ using System.Linq; using Moq; using NUnit.Framework; +using Umbraco.Core.Composing; using Umbraco.Core.IO; using Umbraco.Core.Models; using Umbraco.Core.PropertyEditors; @@ -20,7 +21,7 @@ namespace Umbraco.Tests.Persistence.Repositories { base.SetUp(); - _fileSystem = new PhysicalFileSystem(SystemDirectories.MvcViews + "/Partials/"); + _fileSystem = new PhysicalFileSystem(Current.SystemDirectories.MvcViews + "/Partials/"); } protected override void Compose() diff --git a/src/Umbraco.Tests/Persistence/Repositories/ScriptRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/ScriptRepositoryTest.cs index ae0c71a5b3..cd3a2dae2b 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/ScriptRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/ScriptRepositoryTest.cs @@ -3,6 +3,7 @@ using System.Linq; using System.Text; using Moq; using NUnit.Framework; +using Umbraco.Core.Composing; using Umbraco.Core.Configuration.UmbracoSettings; using Umbraco.Core.IO; using Umbraco.Core.Models; @@ -26,7 +27,7 @@ namespace Umbraco.Tests.Persistence.Repositories base.SetUp(); _fileSystems = Mock.Of(); - _fileSystem = new PhysicalFileSystem(SystemDirectories.Scripts); + _fileSystem = new PhysicalFileSystem(Current.SystemDirectories.Scripts); Mock.Get(_fileSystems).Setup(x => x.ScriptsFileSystem).Returns(_fileSystem); using (var stream = CreateStream("Umbraco.Sys.registerNamespace(\"Umbraco.Utils\");")) { @@ -36,7 +37,7 @@ namespace Umbraco.Tests.Persistence.Repositories private IScriptRepository CreateRepository() { - return new ScriptRepository(_fileSystems, new IOHelper()); + return new ScriptRepository(_fileSystems, IOHelper); } protected override void Compose() diff --git a/src/Umbraco.Tests/Persistence/Repositories/StylesheetRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/StylesheetRepositoryTest.cs index 2358fb257d..a21222e4d2 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/StylesheetRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/StylesheetRepositoryTest.cs @@ -4,6 +4,7 @@ using System.Linq; using System.Text; using Moq; using NUnit.Framework; +using Umbraco.Core.Composing; using Umbraco.Core.IO; using Umbraco.Core.Models; using Umbraco.Core.Persistence.Repositories; @@ -25,7 +26,7 @@ namespace Umbraco.Tests.Persistence.Repositories base.SetUp(); _fileSystems = Mock.Of(); - _fileSystem = new PhysicalFileSystem(SystemDirectories.Css); + _fileSystem = new PhysicalFileSystem(Current.SystemDirectories.Css); Mock.Get(_fileSystems).Setup(x => x.StylesheetsFileSystem).Returns(_fileSystem); var stream = CreateStream("body {background:#EE7600; color:#FFF;}"); _fileSystem.AddFile("styles.css", stream); @@ -33,7 +34,7 @@ namespace Umbraco.Tests.Persistence.Repositories private IStylesheetRepository CreateRepository() { - return new StylesheetRepository(_fileSystems, new IOHelper()); + return new StylesheetRepository(_fileSystems, IOHelper); } [Test] diff --git a/src/Umbraco.Tests/Persistence/Repositories/TemplateRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/TemplateRepositoryTest.cs index b0f9a5335b..c7eb9ed4f6 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/TemplateRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/TemplateRepositoryTest.cs @@ -7,6 +7,7 @@ using Moq; using NUnit.Framework; using Umbraco.Core; using Umbraco.Core.Cache; +using Umbraco.Core.Composing; using Umbraco.Core.Configuration.UmbracoSettings; using Umbraco.Core.IO; using Umbraco.Core.Models; @@ -35,7 +36,7 @@ namespace Umbraco.Tests.Persistence.Repositories base.SetUp(); _fileSystems = Mock.Of(); - var viewsFileSystem = new PhysicalFileSystem(SystemDirectories.MvcViews); + var viewsFileSystem = new PhysicalFileSystem(Current.SystemDirectories.MvcViews); Mock.Get(_fileSystems).Setup(x => x.MvcViewsFileSystem).Returns(viewsFileSystem); } @@ -63,7 +64,7 @@ namespace Umbraco.Tests.Persistence.Repositories // Act var template = new Template("test", "test"); repository.Save(template); - + //Assert Assert.That(repository.Get("test"), Is.Not.Null); @@ -526,7 +527,7 @@ namespace Umbraco.Tests.Persistence.Repositories _fileSystems = null; //Delete all files - var fsViews = new PhysicalFileSystem(SystemDirectories.MvcViews); + var fsViews = new PhysicalFileSystem(Current.SystemDirectories.MvcViews); var views = fsViews.GetFiles("", "*.cshtml"); foreach (var file in views) fsViews.DeleteFile(file); @@ -615,7 +616,7 @@ namespace Umbraco.Tests.Persistence.Repositories repository.Save(toddler4); repository.Save(baby1); repository.Save(baby2); - + return new[] {parent, child1, child2, toddler1, toddler2, toddler3, toddler4, baby1, baby2}; } diff --git a/src/Umbraco.Tests/Scoping/ScopeFileSystemsTests.cs b/src/Umbraco.Tests/Scoping/ScopeFileSystemsTests.cs index 305ae70be9..1f49e83202 100644 --- a/src/Umbraco.Tests/Scoping/ScopeFileSystemsTests.cs +++ b/src/Umbraco.Tests/Scoping/ScopeFileSystemsTests.cs @@ -46,7 +46,7 @@ namespace Umbraco.Tests.Scoping { TestHelper.DeleteDirectory(Current.IOHelper.MapPath("media")); TestHelper.DeleteDirectory(Current.IOHelper.MapPath("FileSysTests")); - TestHelper.DeleteDirectory(Current.IOHelper.MapPath(SystemDirectories.TempData.EnsureEndsWith('/') + "ShadowFs")); + TestHelper.DeleteDirectory(Current.IOHelper.MapPath(Current.SystemDirectories.TempData.EnsureEndsWith('/') + "ShadowFs")); } [TestCase(true)] diff --git a/src/Umbraco.Tests/TestHelpers/TestHelper.cs b/src/Umbraco.Tests/TestHelpers/TestHelper.cs index e07dbe1e5a..abd4e0f91b 100644 --- a/src/Umbraco.Tests/TestHelpers/TestHelper.cs +++ b/src/Umbraco.Tests/TestHelpers/TestHelper.cs @@ -62,12 +62,12 @@ namespace Umbraco.Tests.TestHelpers public static void InitializeContentDirectories() { - CreateDirectories(new[] { SystemDirectories.MvcViews, SystemDirectories.Media, SystemDirectories.AppPlugins }); + CreateDirectories(new[] { Current.SystemDirectories.MvcViews, Current.SystemDirectories.Media, Current.SystemDirectories.AppPlugins }); } public static void CleanContentDirectories() { - CleanDirectories(new[] { SystemDirectories.MvcViews, SystemDirectories.Media }); + CleanDirectories(new[] { Current.SystemDirectories.MvcViews, Current.SystemDirectories.Media }); } public static void CreateDirectories(string[] directories) @@ -84,7 +84,7 @@ namespace Umbraco.Tests.TestHelpers { var preserves = new Dictionary { - { SystemDirectories.MvcViews, new[] {"dummy.txt"} } + { Current.SystemDirectories.MvcViews, new[] {"dummy.txt"} } }; foreach (var directory in directories) { diff --git a/src/Umbraco.Tests/TestHelpers/TestObjects.cs b/src/Umbraco.Tests/TestHelpers/TestObjects.cs index 280632fdae..0e838bbf24 100644 --- a/src/Umbraco.Tests/TestHelpers/TestObjects.cs +++ b/src/Umbraco.Tests/TestHelpers/TestObjects.cs @@ -118,9 +118,9 @@ namespace Umbraco.Tests.TestHelpers var localizedTextService = GetLazyService(factory, c => new LocalizedTextService( new Lazy(() => { - var mainLangFolder = new DirectoryInfo(Current.IOHelper.MapPath(SystemDirectories.Umbraco + "/config/lang/")); - var appPlugins = new DirectoryInfo(Current.IOHelper.MapPath(SystemDirectories.AppPlugins)); - var configLangFolder = new DirectoryInfo(Current.IOHelper.MapPath(SystemDirectories.Config + "/lang/")); + var mainLangFolder = new DirectoryInfo(Current.IOHelper.MapPath(Current.SystemDirectories.Umbraco + "/config/lang/")); + var appPlugins = new DirectoryInfo(Current.IOHelper.MapPath(Current.SystemDirectories.AppPlugins)); + var configLangFolder = new DirectoryInfo(Current.IOHelper.MapPath(Current.SystemDirectories.Config + "/lang/")); var pluginLangFolders = appPlugins.Exists == false ? Enumerable.Empty() diff --git a/src/Umbraco.Web/Composing/Current.cs b/src/Umbraco.Web/Composing/Current.cs index 026dedca7d..cef6065cbf 100644 --- a/src/Umbraco.Web/Composing/Current.cs +++ b/src/Umbraco.Web/Composing/Current.cs @@ -227,6 +227,7 @@ namespace Umbraco.Web.Composing public static IVariationContextAccessor VariationContextAccessor => CoreCurrent.VariationContextAccessor; public static IIOHelper IOHelper => CoreCurrent.IOHelper; + public static ISystemDirectories SystemDirectories => CoreCurrent.SystemDirectories; #endregion } diff --git a/src/Umbraco.Web/Editors/BackOfficeAssetsController.cs b/src/Umbraco.Web/Editors/BackOfficeAssetsController.cs index 6b1b12ab63..faab9fcb7f 100644 --- a/src/Umbraco.Web/Editors/BackOfficeAssetsController.cs +++ b/src/Umbraco.Web/Editors/BackOfficeAssetsController.cs @@ -11,7 +11,7 @@ namespace Umbraco.Web.Editors [PluginController("UmbracoApi")] public class BackOfficeAssetsController : UmbracoAuthorizedJsonController { - private readonly IFileSystem _jsLibFileSystem = new PhysicalFileSystem(SystemDirectories.Umbraco + Current.IOHelper.DirSepChar + "lib"); + private readonly IFileSystem _jsLibFileSystem = new PhysicalFileSystem(Current.SystemDirectories.Umbraco + Current.IOHelper.DirSepChar + "lib"); [HttpGet] public object GetSupportedLocales() diff --git a/src/Umbraco.Web/Editors/BackOfficeServerVariables.cs b/src/Umbraco.Web/Editors/BackOfficeServerVariables.cs index 45f5d52297..b706b0c229 100644 --- a/src/Umbraco.Web/Editors/BackOfficeServerVariables.cs +++ b/src/Umbraco.Web/Editors/BackOfficeServerVariables.cs @@ -320,8 +320,8 @@ namespace Umbraco.Web.Editors "umbracoSettings", new Dictionary { {"umbracoPath", _globalSettings.Path}, - {"mediaPath", Current.IOHelper.ResolveUrl(SystemDirectories.Media).TrimEnd('/')}, - {"appPluginsPath", Current.IOHelper.ResolveUrl(SystemDirectories.AppPlugins).TrimEnd('/')}, + {"mediaPath", Current.IOHelper.ResolveUrl(Current.SystemDirectories.Media).TrimEnd('/')}, + {"appPluginsPath", Current.IOHelper.ResolveUrl(Current.SystemDirectories.AppPlugins).TrimEnd('/')}, { "imageFileTypes", string.Join(",", Current.Configs.Settings().Content.ImageFileTypes) @@ -340,7 +340,7 @@ namespace Umbraco.Web.Editors }, {"keepUserLoggedIn", Current.Configs.Settings().Security.KeepUserLoggedIn}, {"usernameIsEmail", Current.Configs.Settings().Security.UsernameIsEmail}, - {"cssPath", Current.IOHelper.ResolveUrl(SystemDirectories.Css).TrimEnd('/')}, + {"cssPath", Current.IOHelper.ResolveUrl(Current.SystemDirectories.Css).TrimEnd('/')}, {"allowPasswordReset", Current.Configs.Settings().Security.AllowPasswordReset}, {"loginBackgroundImage", Current.Configs.Settings().Content.LoginBackgroundImage}, {"showUserInvite", EmailSender.CanSendRequiredEmail}, diff --git a/src/Umbraco.Web/Editors/Binders/ContentModelBinderHelper.cs b/src/Umbraco.Web/Editors/Binders/ContentModelBinderHelper.cs index 6fc0e123a5..12dab7549e 100644 --- a/src/Umbraco.Web/Editors/Binders/ContentModelBinderHelper.cs +++ b/src/Umbraco.Web/Editors/Binders/ContentModelBinderHelper.cs @@ -3,6 +3,7 @@ using System.Net.Http; using System.Web.Http; using System.Web.Http.Controllers; using Umbraco.Core; +using Umbraco.Core.Composing; using Umbraco.Core.IO; using Umbraco.Core.Models; using Umbraco.Core.Models.Editors; @@ -20,7 +21,7 @@ namespace Umbraco.Web.Editors.Binders public TModelSave BindModelFromMultipartRequest(HttpActionContext actionContext, ModelBindingContext bindingContext) where TModelSave : IHaveUploadedFiles { - var result = actionContext.ReadAsMultipart(SystemDirectories.TempFileUploads); + var result = actionContext.ReadAsMultipart(Current.SystemDirectories.TempFileUploads); var model = actionContext.GetModelFromMultipartRequest(result, "contentItem"); diff --git a/src/Umbraco.Web/Editors/CodeFileController.cs b/src/Umbraco.Web/Editors/CodeFileController.cs index a4e89c25f2..1d281e1641 100644 --- a/src/Umbraco.Web/Editors/CodeFileController.cs +++ b/src/Umbraco.Web/Editors/CodeFileController.cs @@ -110,19 +110,19 @@ namespace Umbraco.Web.Editors switch (type) { case Core.Constants.Trees.PartialViews: - virtualPath = NormalizeVirtualPath(name, SystemDirectories.PartialViews); + virtualPath = NormalizeVirtualPath(name, Current.SystemDirectories.PartialViews); Services.FileService.CreatePartialViewFolder(virtualPath); break; case Core.Constants.Trees.PartialViewMacros: - virtualPath = NormalizeVirtualPath(name, SystemDirectories.MacroPartials); + virtualPath = NormalizeVirtualPath(name, Current.SystemDirectories.MacroPartials); Services.FileService.CreatePartialViewMacroFolder(virtualPath); break; case Core.Constants.Trees.Scripts: - virtualPath = NormalizeVirtualPath(name, SystemDirectories.Scripts); + virtualPath = NormalizeVirtualPath(name, Current.SystemDirectories.Scripts); Services.FileService.CreateScriptFolder(virtualPath); break; case Core.Constants.Trees.Stylesheets: - virtualPath = NormalizeVirtualPath(name, SystemDirectories.Css); + virtualPath = NormalizeVirtualPath(name, Current.SystemDirectories.Css); Services.FileService.CreateStyleSheetFolder(virtualPath); break; @@ -250,23 +250,23 @@ namespace Umbraco.Web.Editors { case Core.Constants.Trees.PartialViews: codeFileDisplay = Mapper.Map(new PartialView(PartialViewType.PartialView, string.Empty)); - codeFileDisplay.VirtualPath = SystemDirectories.PartialViews; + codeFileDisplay.VirtualPath = Current.SystemDirectories.PartialViews; if (snippetName.IsNullOrWhiteSpace() == false) codeFileDisplay.Content = Services.FileService.GetPartialViewSnippetContent(snippetName); break; case Core.Constants.Trees.PartialViewMacros: codeFileDisplay = Mapper.Map(new PartialView(PartialViewType.PartialViewMacro, string.Empty)); - codeFileDisplay.VirtualPath = SystemDirectories.MacroPartials; + codeFileDisplay.VirtualPath = Current.SystemDirectories.MacroPartials; if (snippetName.IsNullOrWhiteSpace() == false) codeFileDisplay.Content = Services.FileService.GetPartialViewMacroSnippetContent(snippetName); break; case Core.Constants.Trees.Scripts: codeFileDisplay = Mapper.Map(new Script(string.Empty)); - codeFileDisplay.VirtualPath = SystemDirectories.Scripts; + codeFileDisplay.VirtualPath = Current.SystemDirectories.Scripts; break; case Core.Constants.Trees.Stylesheets: codeFileDisplay = Mapper.Map(new Stylesheet(string.Empty)); - codeFileDisplay.VirtualPath = SystemDirectories.Css; + codeFileDisplay.VirtualPath = Current.SystemDirectories.Css; break; default: throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.BadRequest, "Unsupported editortype")); @@ -305,7 +305,7 @@ namespace Umbraco.Web.Editors switch (type) { case Core.Constants.Trees.PartialViews: - if (IsDirectory(virtualPath, SystemDirectories.PartialViews)) + if (IsDirectory(virtualPath, Current.SystemDirectories.PartialViews)) { Services.FileService.DeletePartialViewFolder(virtualPath); return Request.CreateResponse(HttpStatusCode.OK); @@ -317,7 +317,7 @@ namespace Umbraco.Web.Editors return Request.CreateErrorResponse(HttpStatusCode.NotFound, "No Partial View or folder found with the specified path"); case Core.Constants.Trees.PartialViewMacros: - if (IsDirectory(virtualPath, SystemDirectories.MacroPartials)) + if (IsDirectory(virtualPath, Current.SystemDirectories.MacroPartials)) { Services.FileService.DeletePartialViewMacroFolder(virtualPath); return Request.CreateResponse(HttpStatusCode.OK); @@ -329,7 +329,7 @@ namespace Umbraco.Web.Editors return Request.CreateErrorResponse(HttpStatusCode.NotFound, "No Partial View Macro or folder found with the specified path"); case Core.Constants.Trees.Scripts: - if (IsDirectory(virtualPath, SystemDirectories.Scripts)) + if (IsDirectory(virtualPath, Current.SystemDirectories.Scripts)) { Services.FileService.DeleteScriptFolder(virtualPath); return Request.CreateResponse(HttpStatusCode.OK); @@ -342,7 +342,7 @@ namespace Umbraco.Web.Editors return Request.CreateErrorResponse(HttpStatusCode.NotFound, "No Script or folder found with the specified path"); case Core.Constants.Trees.Stylesheets: - if (IsDirectory(virtualPath, SystemDirectories.Css)) + if (IsDirectory(virtualPath, Current.SystemDirectories.Css)) { Services.FileService.DeleteStyleSheetFolder(virtualPath); return Request.CreateResponse(HttpStatusCode.OK); @@ -561,13 +561,13 @@ namespace Umbraco.Web.Editors private Attempt CreateOrUpdatePartialView(CodeFileDisplay display) { - return CreateOrUpdatePartialView(display, SystemDirectories.PartialViews, + return CreateOrUpdatePartialView(display, Current.SystemDirectories.PartialViews, Services.FileService.GetPartialView, Services.FileService.SavePartialView, Services.FileService.CreatePartialView); } private Attempt CreateOrUpdatePartialViewMacro(CodeFileDisplay display) { - return CreateOrUpdatePartialView(display, SystemDirectories.MacroPartials, + return CreateOrUpdatePartialView(display, Current.SystemDirectories.MacroPartials, Services.FileService.GetPartialViewMacro, Services.FileService.SavePartialViewMacro, Services.FileService.CreatePartialViewMacro); } diff --git a/src/Umbraco.Web/Editors/ContentTypeController.cs b/src/Umbraco.Web/Editors/ContentTypeController.cs index e01fe251cb..790381ab04 100644 --- a/src/Umbraco.Web/Editors/ContentTypeController.cs +++ b/src/Umbraco.Web/Editors/ContentTypeController.cs @@ -515,7 +515,7 @@ namespace Umbraco.Web.Editors [HttpPost] public HttpResponseMessage Import(string file) { - var filePath = Path.Combine(Current.IOHelper.MapPath(SystemDirectories.Data), file); + var filePath = Path.Combine(Current.IOHelper.MapPath(Current.SystemDirectories.Data), file); if (string.IsNullOrEmpty(file) || !System.IO.File.Exists(filePath)) { return Request.CreateResponse(HttpStatusCode.NotFound); @@ -553,7 +553,7 @@ namespace Umbraco.Web.Editors throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType); } - var root = Current.IOHelper.MapPath(SystemDirectories.TempData.EnsureEndsWith('/') + "FileUploads"); + var root = Current.IOHelper.MapPath(Current.SystemDirectories.TempData.EnsureEndsWith('/') + "FileUploads"); //ensure it exists Directory.CreateDirectory(root); var provider = new MultipartFormDataStreamProvider(root); diff --git a/src/Umbraco.Web/Editors/MacrosController.cs b/src/Umbraco.Web/Editors/MacrosController.cs index 0df685dea7..0f73dcea8f 100644 --- a/src/Umbraco.Web/Editors/MacrosController.cs +++ b/src/Umbraco.Web/Editors/MacrosController.cs @@ -311,12 +311,12 @@ namespace Umbraco.Web.Editors /// private IEnumerable FindPartialViewFilesInViewsFolder() { - var partialsDir = Current.IOHelper.MapPath(SystemDirectories.MacroPartials); + var partialsDir = Current.IOHelper.MapPath(Current.SystemDirectories.MacroPartials); return this.FindPartialViewFilesInFolder( partialsDir, partialsDir, - SystemDirectories.MacroPartials); + Current.SystemDirectories.MacroPartials); } /// @@ -329,7 +329,7 @@ namespace Umbraco.Web.Editors { var files = new List(); - var appPluginsFolder = new DirectoryInfo(Current.IOHelper.MapPath(SystemDirectories.AppPlugins)); + var appPluginsFolder = new DirectoryInfo(Current.IOHelper.MapPath(Current.SystemDirectories.AppPlugins)); if (!appPluginsFolder.Exists) { @@ -344,7 +344,7 @@ namespace Umbraco.Web.Editors var macroPartials = viewsFolder.First().GetDirectories("MacroPartials"); if (macroPartials.Any()) { - files.AddRange(this.FindPartialViewFilesInFolder(macroPartials.First().FullName, macroPartials.First().FullName, SystemDirectories.AppPlugins + "/" + directory.Name + "/Views/MacroPartials")); + files.AddRange(this.FindPartialViewFilesInFolder(macroPartials.First().FullName, macroPartials.First().FullName, Current.SystemDirectories.AppPlugins + "/" + directory.Name + "/Views/MacroPartials")); } } } diff --git a/src/Umbraco.Web/Editors/MediaController.cs b/src/Umbraco.Web/Editors/MediaController.cs index 2cab9f4ebc..7c53db6b17 100644 --- a/src/Umbraco.Web/Editors/MediaController.cs +++ b/src/Umbraco.Web/Editors/MediaController.cs @@ -620,7 +620,7 @@ namespace Umbraco.Web.Editors throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType); } - var root = Current.IOHelper.MapPath(SystemDirectories.TempFileUploads); + var root = Current.IOHelper.MapPath(Current.SystemDirectories.TempFileUploads); //ensure it exists Directory.CreateDirectory(root); var provider = new MultipartFormDataStreamProvider(root); diff --git a/src/Umbraco.Web/Editors/PackageInstallController.cs b/src/Umbraco.Web/Editors/PackageInstallController.cs index 51007b1970..0629adcfcf 100644 --- a/src/Umbraco.Web/Editors/PackageInstallController.cs +++ b/src/Umbraco.Web/Editors/PackageInstallController.cs @@ -90,7 +90,7 @@ namespace Umbraco.Web.Editors private void PopulateFromPackageData(LocalPackageInstallModel model) { - var zipFile = new FileInfo(Path.Combine(Current.IOHelper.MapPath(SystemDirectories.Packages), model.ZipFileName)); + var zipFile = new FileInfo(Path.Combine(Current.IOHelper.MapPath(Current.SystemDirectories.Packages), model.ZipFileName)); var ins = Services.PackagingService.GetCompiledPackageInfo(zipFile); @@ -132,7 +132,7 @@ namespace Umbraco.Web.Editors if (Request.Content.IsMimeMultipartContent() == false) throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType); - var root = Current.IOHelper.MapPath(SystemDirectories.TempFileUploads); + var root = Current.IOHelper.MapPath(Current.SystemDirectories.TempFileUploads); //ensure it exists Directory.CreateDirectory(root); var provider = new MultipartFormDataStreamProvider(root); @@ -159,7 +159,7 @@ namespace Umbraco.Web.Editors { //we always save package files to /App_Data/packages/package-guid.umb for processing as a standard so lets copy. - var packagesFolder = Current.IOHelper.MapPath(SystemDirectories.Packages); + var packagesFolder = Current.IOHelper.MapPath(Current.SystemDirectories.Packages); Directory.CreateDirectory(packagesFolder); var packageFile = Path.Combine(packagesFolder, model.PackageGuid + ".umb"); File.Copy(file.LocalFileName, packageFile); @@ -211,7 +211,7 @@ namespace Umbraco.Web.Editors { //Default path string fileName = packageGuid + ".umb"; - if (File.Exists(Path.Combine(Current.IOHelper.MapPath(SystemDirectories.Packages), fileName)) == false) + if (File.Exists(Path.Combine(Current.IOHelper.MapPath(Current.SystemDirectories.Packages), fileName)) == false) { var packageFile = await Services.PackagingService.FetchPackageFileAsync( Guid.Parse(packageGuid), @@ -251,7 +251,7 @@ namespace Umbraco.Web.Editors [HttpPost] public PackageInstallModel Import(PackageInstallModel model) { - var zipFile = new FileInfo(Path.Combine(Current.IOHelper.MapPath(SystemDirectories.Packages), model.ZipFileName)); + var zipFile = new FileInfo(Path.Combine(Current.IOHelper.MapPath(Current.SystemDirectories.Packages), model.ZipFileName)); var packageInfo = Services.PackagingService.GetCompiledPackageInfo(zipFile); diff --git a/src/Umbraco.Web/Editors/TinyMceController.cs b/src/Umbraco.Web/Editors/TinyMceController.cs index 3d03977883..b03d87ffbc 100644 --- a/src/Umbraco.Web/Editors/TinyMceController.cs +++ b/src/Umbraco.Web/Editors/TinyMceController.cs @@ -45,10 +45,10 @@ namespace Umbraco.Web.Editors } // Create an unique folder path to help with concurrent users to avoid filename clash - var imageTempPath = Current.IOHelper.MapPath(SystemDirectories.TempImageUploads + "/" + Guid.NewGuid().ToString()); + var imageTempPath = Current.IOHelper.MapPath(Current.SystemDirectories.TempImageUploads + "/" + Guid.NewGuid().ToString()); // Temp folderpath (Files come in as bodypart & will need to move/saved into imgTempPath - var folderPath = Current.IOHelper.MapPath(SystemDirectories.TempFileUploads); + var folderPath = Current.IOHelper.MapPath(Current.SystemDirectories.TempFileUploads); // Ensure image temp path exists if(Directory.Exists(imageTempPath) == false) diff --git a/src/Umbraco.Web/Editors/TourController.cs b/src/Umbraco.Web/Editors/TourController.cs index e3d42b6753..80a39ee83b 100644 --- a/src/Umbraco.Web/Editors/TourController.cs +++ b/src/Umbraco.Web/Editors/TourController.cs @@ -41,7 +41,7 @@ namespace Umbraco.Web.Editors var nonPluginFilters = _filters.Where(x => x.PluginName == null).ToList(); //add core tour files - var coreToursPath = Path.Combine(Current.IOHelper.MapPath(SystemDirectories.Config), "BackOfficeTours"); + var coreToursPath = Path.Combine(Current.IOHelper.MapPath(Current.SystemDirectories.Config), "BackOfficeTours"); if (Directory.Exists(coreToursPath)) { foreach (var tourFile in Directory.EnumerateFiles(coreToursPath, "*.json")) @@ -51,7 +51,7 @@ namespace Umbraco.Web.Editors } //collect all tour files in packages - var appPlugins = Current.IOHelper.MapPath(SystemDirectories.AppPlugins); + var appPlugins = Current.IOHelper.MapPath(Current.SystemDirectories.AppPlugins); if (Directory.Exists(appPlugins)) { foreach (var plugin in Directory.EnumerateDirectories(appPlugins)) diff --git a/src/Umbraco.Web/Editors/UsersController.cs b/src/Umbraco.Web/Editors/UsersController.cs index 3024583fba..cf81907dda 100644 --- a/src/Umbraco.Web/Editors/UsersController.cs +++ b/src/Umbraco.Web/Editors/UsersController.cs @@ -75,7 +75,7 @@ namespace Umbraco.Web.Editors throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType); } - var root = Current.IOHelper.MapPath(SystemDirectories.TempFileUploads); + var root = Current.IOHelper.MapPath(Current.SystemDirectories.TempFileUploads); //ensure it exists Directory.CreateDirectory(root); var provider = new MultipartFormDataStreamProvider(root); diff --git a/src/Umbraco.Web/HealthCheck/Checks/Permissions/FolderAndFilePermissionsCheck.cs b/src/Umbraco.Web/HealthCheck/Checks/Permissions/FolderAndFilePermissionsCheck.cs index 577d22fe67..7c263ed7a0 100644 --- a/src/Umbraco.Web/HealthCheck/Checks/Permissions/FolderAndFilePermissionsCheck.cs +++ b/src/Umbraco.Web/HealthCheck/Checks/Permissions/FolderAndFilePermissionsCheck.cs @@ -60,24 +60,24 @@ namespace Umbraco.Web.HealthCheck.Checks.Permissions // in ALL circumstances or just some var pathsToCheck = new Dictionary { - { SystemDirectories.Data, PermissionCheckRequirement.Required }, - { SystemDirectories.Packages, PermissionCheckRequirement.Required}, - { SystemDirectories.Preview, PermissionCheckRequirement.Required }, - { SystemDirectories.AppPlugins, PermissionCheckRequirement.Required }, - { SystemDirectories.Config, PermissionCheckRequirement.Optional }, - { SystemDirectories.Css, PermissionCheckRequirement.Optional }, - { SystemDirectories.Media, PermissionCheckRequirement.Optional }, - { SystemDirectories.Scripts, PermissionCheckRequirement.Optional }, - { SystemDirectories.Umbraco, PermissionCheckRequirement.Optional }, - { SystemDirectories.MvcViews, PermissionCheckRequirement.Optional } + { Current.SystemDirectories.Data, PermissionCheckRequirement.Required }, + { Current.SystemDirectories.Packages, PermissionCheckRequirement.Required}, + { Current.SystemDirectories.Preview, PermissionCheckRequirement.Required }, + { Current.SystemDirectories.AppPlugins, PermissionCheckRequirement.Required }, + { Current.SystemDirectories.Config, PermissionCheckRequirement.Optional }, + { Current.SystemDirectories.Css, PermissionCheckRequirement.Optional }, + { Current.SystemDirectories.Media, PermissionCheckRequirement.Optional }, + { Current.SystemDirectories.Scripts, PermissionCheckRequirement.Optional }, + { Current.SystemDirectories.Umbraco, PermissionCheckRequirement.Optional }, + { Current.SystemDirectories.MvcViews, PermissionCheckRequirement.Optional } }; //These are special paths to check that will restart an app domain if a file is written to them, //so these need to be tested differently var pathsToCheckWithRestarts = new Dictionary { - { SystemDirectories.AppCode, PermissionCheckRequirement.Optional }, - { SystemDirectories.Bin, PermissionCheckRequirement.Optional } + { Current.SystemDirectories.AppCode, PermissionCheckRequirement.Optional }, + { Current.SystemDirectories.Bin, PermissionCheckRequirement.Optional } }; // Run checks for required and optional paths for modify permission diff --git a/src/Umbraco.Web/HtmlHelperRenderExtensions.cs b/src/Umbraco.Web/HtmlHelperRenderExtensions.cs index a68ba96327..cd3c768b5d 100644 --- a/src/Umbraco.Web/HtmlHelperRenderExtensions.cs +++ b/src/Umbraco.Web/HtmlHelperRenderExtensions.cs @@ -67,7 +67,7 @@ namespace Umbraco.Web { var htmlBadge = String.Format(Current.Configs.Settings().Content.PreviewBadge, - Current.IOHelper.ResolveUrl(SystemDirectories.Umbraco), + Current.IOHelper.ResolveUrl(Current.SystemDirectories.Umbraco), Current.UmbracoContext.HttpContext.Server.UrlEncode(Current.UmbracoContext.HttpContext.Request.Path)); return new MvcHtmlString(htmlBadge); } diff --git a/src/Umbraco.Web/Install/Controllers/InstallController.cs b/src/Umbraco.Web/Install/Controllers/InstallController.cs index dc71125f15..8bf294ab0e 100644 --- a/src/Umbraco.Web/Install/Controllers/InstallController.cs +++ b/src/Umbraco.Web/Install/Controllers/InstallController.cs @@ -41,7 +41,7 @@ namespace Umbraco.Web.Install.Controllers public ActionResult Index() { if (_runtime.Level == RuntimeLevel.Run) - return Redirect(SystemDirectories.Umbraco.EnsureEndsWith('/')); + return Redirect(Current.SystemDirectories.Umbraco.EnsureEndsWith('/')); if (_runtime.Level == RuntimeLevel.Upgrade) { @@ -58,7 +58,7 @@ namespace Umbraco.Web.Install.Controllers { case ValidateRequestAttempt.FailedNoPrivileges: case ValidateRequestAttempt.FailedNoContextId: - return Redirect(SystemDirectories.Umbraco + "/AuthorizeUpgrade?redir=" + Server.UrlEncode(Request.RawUrl)); + return Redirect(Current.SystemDirectories.Umbraco + "/AuthorizeUpgrade?redir=" + Server.UrlEncode(Request.RawUrl)); } } @@ -66,7 +66,7 @@ namespace Umbraco.Web.Install.Controllers ViewData.SetInstallApiBaseUrl(Url.GetUmbracoApiService("GetSetup", "InstallApi", "UmbracoInstall").TrimEnd("GetSetup")); // get the base umbraco folder - ViewData.SetUmbracoBaseFolder(Current.IOHelper.ResolveUrl(SystemDirectories.Umbraco)); + ViewData.SetUmbracoBaseFolder(Current.IOHelper.ResolveUrl(Current.SystemDirectories.Umbraco)); _installHelper.InstallStatus(false, ""); diff --git a/src/Umbraco.Web/Install/FilePermissionHelper.cs b/src/Umbraco.Web/Install/FilePermissionHelper.cs index 2d48fe8974..7f90f55ae9 100644 --- a/src/Umbraco.Web/Install/FilePermissionHelper.cs +++ b/src/Umbraco.Web/Install/FilePermissionHelper.cs @@ -11,8 +11,8 @@ namespace Umbraco.Web.Install internal class FilePermissionHelper { // ensure that these directories exist and Umbraco can write to them - private static readonly string[] PermissionDirs = { SystemDirectories.Css, SystemDirectories.Config, SystemDirectories.Data, SystemDirectories.Media, SystemDirectories.Preview }; - private static readonly string[] PackagesPermissionsDirs = { SystemDirectories.Bin, SystemDirectories.Umbraco, SystemDirectories.Packages }; + private static readonly string[] PermissionDirs = { Current.SystemDirectories.Css, Current.SystemDirectories.Config, Current.SystemDirectories.Data, Current.SystemDirectories.Media, Current.SystemDirectories.Preview }; + private static readonly string[] PackagesPermissionsDirs = { Current.SystemDirectories.Bin, Current.SystemDirectories.Umbraco, Current.SystemDirectories.Packages }; // ensure Umbraco can write to these files (the directories must exist) private static readonly string[] PermissionFiles = { }; @@ -35,7 +35,7 @@ namespace Umbraco.Web.Install if (TestPublishedSnapshotService(out errors) == false) report["Published snapshot environment check failed"] = errors.ToList(); - if (EnsureCanCreateSubDirectory(SystemDirectories.Media, out errors) == false) + if (EnsureCanCreateSubDirectory(Current.SystemDirectories.Media, out errors) == false) report["Media folder creation failed"] = errors.ToList(); } diff --git a/src/Umbraco.Web/Install/InstallAuthorizeAttribute.cs b/src/Umbraco.Web/Install/InstallAuthorizeAttribute.cs index ce45ef652b..5da3179c44 100644 --- a/src/Umbraco.Web/Install/InstallAuthorizeAttribute.cs +++ b/src/Umbraco.Web/Install/InstallAuthorizeAttribute.cs @@ -66,7 +66,7 @@ namespace Umbraco.Web.Install /// protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext) { - filterContext.Result = new RedirectResult(SystemDirectories.Umbraco.EnsureEndsWith('/')); + filterContext.Result = new RedirectResult(Current.SystemDirectories.Umbraco.EnsureEndsWith('/')); } } } diff --git a/src/Umbraco.Web/Install/InstallStatusTracker.cs b/src/Umbraco.Web/Install/InstallStatusTracker.cs index 3c968ca696..874456ad3f 100644 --- a/src/Umbraco.Web/Install/InstallStatusTracker.cs +++ b/src/Umbraco.Web/Install/InstallStatusTracker.cs @@ -25,10 +25,10 @@ namespace Umbraco.Web.Install private static string GetFile(Guid installId) { - var file = Current.IOHelper.MapPath(SystemDirectories.TempData.EnsureEndsWith('/') + "Install/" - + "install_" - + installId.ToString("N") - + ".txt"); + var file = Current.IOHelper.MapPath(Current.SystemDirectories.TempData.EnsureEndsWith('/') + "Install/" + + "install_" + + installId.ToString("N") + + ".txt"); return file; } @@ -40,7 +40,7 @@ namespace Umbraco.Web.Install public static void ClearFiles() { - var dir = Current.IOHelper.MapPath(SystemDirectories.TempData.EnsureEndsWith('/') + "Install/"); + var dir = Current.IOHelper.MapPath(Current.SystemDirectories.TempData.EnsureEndsWith('/') + "Install/"); if (Directory.Exists(dir)) { var files = Directory.GetFiles(dir); diff --git a/src/Umbraco.Web/Install/InstallSteps/ConfigureMachineKey.cs b/src/Umbraco.Web/Install/InstallSteps/ConfigureMachineKey.cs index a084805a2c..d71c8d99f3 100644 --- a/src/Umbraco.Web/Install/InstallSteps/ConfigureMachineKey.cs +++ b/src/Umbraco.Web/Install/InstallSteps/ConfigureMachineKey.cs @@ -37,7 +37,7 @@ namespace Umbraco.Web.Install.InstallSteps if (model.HasValue && model.Value == false) return Task.FromResult(null); //install the machine key - var fileName = Current.IOHelper.MapPath($"{SystemDirectories.Root}/web.config"); + var fileName = Current.IOHelper.MapPath($"{Current.SystemDirectories.Root}/web.config"); var xml = XDocument.Load(fileName, LoadOptions.PreserveWhitespace); // we only want to get the element that is under the root, (there may be more under tags we don't want them) diff --git a/src/Umbraco.Web/Install/InstallSteps/StarterKitCleanupStep.cs b/src/Umbraco.Web/Install/InstallSteps/StarterKitCleanupStep.cs index 352a2cace9..89c5ba7191 100644 --- a/src/Umbraco.Web/Install/InstallSteps/StarterKitCleanupStep.cs +++ b/src/Umbraco.Web/Install/InstallSteps/StarterKitCleanupStep.cs @@ -27,7 +27,7 @@ namespace Umbraco.Web.Install.InstallSteps private void CleanupInstallation(int packageId, string packageFile) { - var zipFile = new FileInfo(Path.Combine(Current.IOHelper.MapPath(SystemDirectories.Packages), HttpUtility.UrlDecode(packageFile))); + var zipFile = new FileInfo(Path.Combine(Current.IOHelper.MapPath(Current.SystemDirectories.Packages), HttpUtility.UrlDecode(packageFile))); if (zipFile.Exists) zipFile.Delete(); diff --git a/src/Umbraco.Web/JavaScript/ClientDependencyConfiguration.cs b/src/Umbraco.Web/JavaScript/ClientDependencyConfiguration.cs index c64318a68d..b636007cfe 100644 --- a/src/Umbraco.Web/JavaScript/ClientDependencyConfiguration.cs +++ b/src/Umbraco.Web/JavaScript/ClientDependencyConfiguration.cs @@ -27,7 +27,7 @@ namespace Umbraco.Web.JavaScript { if (logger == null) throw new ArgumentNullException("logger"); _logger = logger; - _fileName = Current.IOHelper.MapPath(string.Format("{0}/ClientDependency.config", SystemDirectories.Config)); + _fileName = Current.IOHelper.MapPath(string.Format("{0}/ClientDependency.config", Current.SystemDirectories.Config)); } /// diff --git a/src/Umbraco.Web/JavaScript/JsInitialization.cs b/src/Umbraco.Web/JavaScript/JsInitialization.cs index 24c09dfd03..89b32779a5 100644 --- a/src/Umbraco.Web/JavaScript/JsInitialization.cs +++ b/src/Umbraco.Web/JavaScript/JsInitialization.cs @@ -58,7 +58,7 @@ namespace Umbraco.Web.JavaScript } jarray.Append("]"); - return WriteScript(jarray.ToString(), Current.IOHelper.ResolveUrl(SystemDirectories.Umbraco), angularModule); + return WriteScript(jarray.ToString(), Current.IOHelper.ResolveUrl(Current.SystemDirectories.Umbraco), angularModule); } /// diff --git a/src/Umbraco.Web/JavaScript/UmbracoClientDependencyLoader.cs b/src/Umbraco.Web/JavaScript/UmbracoClientDependencyLoader.cs index 82ae027c8d..c313be8a8b 100644 --- a/src/Umbraco.Web/JavaScript/UmbracoClientDependencyLoader.cs +++ b/src/Umbraco.Web/JavaScript/UmbracoClientDependencyLoader.cs @@ -18,7 +18,7 @@ namespace Umbraco.Web.JavaScript public UmbracoClientDependencyLoader() : base() { - this.AddPath("UmbracoRoot", Current.IOHelper.ResolveUrl(SystemDirectories.Umbraco)); + this.AddPath("UmbracoRoot", Current.IOHelper.ResolveUrl(Current.SystemDirectories.Umbraco)); this.ProviderName = LoaderControlProvider.DefaultName; } diff --git a/src/Umbraco.Web/Mvc/PluginViewEngine.cs b/src/Umbraco.Web/Mvc/PluginViewEngine.cs index e83980a5d8..ae07db58c5 100644 --- a/src/Umbraco.Web/Mvc/PluginViewEngine.cs +++ b/src/Umbraco.Web/Mvc/PluginViewEngine.cs @@ -35,16 +35,16 @@ namespace Umbraco.Web.Mvc var viewLocationsArray = new[] { - string.Concat(SystemDirectories.AppPlugins, "/{2}/Views/{1}/{0}.cshtml"), - string.Concat(SystemDirectories.AppPlugins, "/{2}/Views/{1}/{0}.vbhtml") + string.Concat(Current.SystemDirectories.AppPlugins, "/{2}/Views/{1}/{0}.cshtml"), + string.Concat(Current.SystemDirectories.AppPlugins, "/{2}/Views/{1}/{0}.vbhtml") }; //set all of the area view locations to the plugin folder AreaViewLocationFormats = viewLocationsArray .Concat(new[] { - string.Concat(SystemDirectories.AppPlugins, "/{2}/Views/Shared/{0}.cshtml"), - string.Concat(SystemDirectories.AppPlugins, "/{2}/Views/Shared/{0}.vbhtml") + string.Concat(Current.SystemDirectories.AppPlugins, "/{2}/Views/Shared/{0}.cshtml"), + string.Concat(Current.SystemDirectories.AppPlugins, "/{2}/Views/Shared/{0}.vbhtml") }) .ToArray(); @@ -53,15 +53,15 @@ namespace Umbraco.Web.Mvc AreaPartialViewLocationFormats = new[] { //will be used when we have partial view and child action macros - string.Concat(SystemDirectories.AppPlugins, "/{2}/Views/Partials/{0}.cshtml"), - string.Concat(SystemDirectories.AppPlugins, "/{2}/Views/Partials/{0}.vbhtml"), - string.Concat(SystemDirectories.AppPlugins, "/{2}/Views/MacroPartials/{0}.cshtml"), - string.Concat(SystemDirectories.AppPlugins, "/{2}/Views/MacroPartials/{0}.vbhtml"), - //for partials - string.Concat(SystemDirectories.AppPlugins, "/{2}/Views/{1}/{0}.cshtml"), - string.Concat(SystemDirectories.AppPlugins, "/{2}/Views/{1}/{0}.vbhtml"), - string.Concat(SystemDirectories.AppPlugins, "/{2}/Views/Shared/{0}.cshtml"), - string.Concat(SystemDirectories.AppPlugins, "/{2}/Views/Shared/{0}.vbhtml") + string.Concat(Current.SystemDirectories.AppPlugins, "/{2}/Views/Partials/{0}.cshtml"), + string.Concat(Current.SystemDirectories.AppPlugins, "/{2}/Views/Partials/{0}.vbhtml"), + string.Concat(Current.SystemDirectories.AppPlugins, "/{2}/Views/MacroPartials/{0}.cshtml"), + string.Concat(Current.SystemDirectories.AppPlugins, "/{2}/Views/MacroPartials/{0}.vbhtml"), + //for partialsCurrent. + string.Concat(Current.SystemDirectories.AppPlugins, "/{2}/Views/{1}/{0}.cshtml"), + string.Concat(Current.SystemDirectories.AppPlugins, "/{2}/Views/{1}/{0}.vbhtml"), + string.Concat(Current.SystemDirectories.AppPlugins, "/{2}/Views/Shared/{0}.cshtml"), + string.Concat(Current.SystemDirectories.AppPlugins, "/{2}/Views/Shared/{0}.vbhtml") }; } diff --git a/src/Umbraco.Web/Mvc/UmbracoViewPageOfTModel.cs b/src/Umbraco.Web/Mvc/UmbracoViewPageOfTModel.cs index 26dee405ee..f58a519393 100644 --- a/src/Umbraco.Web/Mvc/UmbracoViewPageOfTModel.cs +++ b/src/Umbraco.Web/Mvc/UmbracoViewPageOfTModel.cs @@ -214,7 +214,7 @@ namespace Umbraco.Web.Mvc // creating previewBadge markup markupToInject = string.Format(Current.Configs.Settings().Content.PreviewBadge, - Current.IOHelper.ResolveUrl(SystemDirectories.Umbraco), + Current.IOHelper.ResolveUrl(Current.SystemDirectories.Umbraco), Server.UrlEncode(Current.UmbracoContext.HttpContext.Request.Url?.PathAndQuery)); } else diff --git a/src/Umbraco.Web/Runtime/WebInitialComponent.cs b/src/Umbraco.Web/Runtime/WebInitialComponent.cs index 5210232f67..e5ad0c0665 100644 --- a/src/Umbraco.Web/Runtime/WebInitialComponent.cs +++ b/src/Umbraco.Web/Runtime/WebInitialComponent.cs @@ -112,7 +112,7 @@ namespace Umbraco.Web.Runtime private static void ConfigureClientDependency(IGlobalSettings globalSettings) { // Backwards compatibility - set the path and URL type for ClientDependency 1.5.1 [LK] - XmlFileMapper.FileMapDefaultFolder = SystemDirectories.TempData.EnsureEndsWith('/') + "ClientDependency"; + XmlFileMapper.FileMapDefaultFolder = Current.SystemDirectories.TempData.EnsureEndsWith('/') + "ClientDependency"; BaseCompositeFileProcessingProvider.UrlTypeDefault = CompositeUrlType.Base64QueryStrings; // Now we need to detect if we are running 'Umbraco.Core.LocalTempStorage' as EnvironmentTemp and in that case we want to change the CDF file diff --git a/src/Umbraco.Web/Scheduling/SchedulerComponent.cs b/src/Umbraco.Web/Scheduling/SchedulerComponent.cs index ee3fce50c8..ff1350bcde 100644 --- a/src/Umbraco.Web/Scheduling/SchedulerComponent.cs +++ b/src/Umbraco.Web/Scheduling/SchedulerComponent.cs @@ -170,7 +170,7 @@ namespace Umbraco.Web.Scheduling // temp file cleanup, will run on all servers - even though file upload should only be handled on the master, this will // ensure that in the case it happes on replicas that they are cleaned up. var task = new TempFileCleanup(_fileCleanupRunner, DefaultDelayMilliseconds, OneHourMilliseconds, - new[] { new DirectoryInfo(Current.IOHelper.MapPath(SystemDirectories.TempFileUploads)) }, + new[] { new DirectoryInfo(Current.IOHelper.MapPath(Current.SystemDirectories.TempFileUploads)) }, TimeSpan.FromDays(1), //files that are over a day old _runtime, _logger); _scrubberRunner.TryAdd(task); diff --git a/src/Umbraco.Web/Security/WebSecurity.cs b/src/Umbraco.Web/Security/WebSecurity.cs index 6b66becedb..ce799a8a2b 100644 --- a/src/Umbraco.Web/Security/WebSecurity.cs +++ b/src/Umbraco.Web/Security/WebSecurity.cs @@ -209,7 +209,7 @@ namespace Umbraco.Web.Security private static bool RequestIsInUmbracoApplication(HttpContextBase context) { - return context.Request.Path.ToLower().IndexOf(Current.IOHelper.ResolveUrl(SystemDirectories.Umbraco).ToLower(), StringComparison.Ordinal) > -1; + return context.Request.Path.ToLower().IndexOf(Current.IOHelper.ResolveUrl(Current.SystemDirectories.Umbraco).ToLower(), StringComparison.Ordinal) > -1; } /// diff --git a/src/Umbraco.Web/UmbracoInjectedModule.cs b/src/Umbraco.Web/UmbracoInjectedModule.cs index 6dc41d39ee..f43146cda5 100644 --- a/src/Umbraco.Web/UmbracoInjectedModule.cs +++ b/src/Umbraco.Web/UmbracoInjectedModule.cs @@ -180,7 +180,7 @@ namespace Umbraco.Web return Attempt.If(reason == EnsureRoutableOutcome.IsRoutable, reason); } - + private bool EnsureRuntime(HttpContextBase httpContext, Uri uri) { @@ -205,7 +205,7 @@ namespace Umbraco.Web case RuntimeLevel.Upgrade: // redirect to install ReportRuntime(level, "Umbraco must install or upgrade."); - var installPath = UriUtility.ToAbsolute(SystemDirectories.Install); + var installPath = UriUtility.ToAbsolute(Current.SystemDirectories.Install); var installUrl = $"{installPath}/?redir=true&url={HttpUtility.UrlEncode(uri.ToString())}"; httpContext.Response.Redirect(installUrl, true); return false; // cannot serve content @@ -436,6 +436,6 @@ namespace Umbraco.Web #endregion - + } } From 42904d63aa3ba91c25f7642a65b3f1fe59e58fd2 Mon Sep 17 00:00:00 2001 From: Bjarke Berg Date: Tue, 12 Nov 2019 15:32:03 +0100 Subject: [PATCH 50/68] Fixed views --- src/Umbraco.Web.UI/Umbraco/Views/AuthorizeUpgrade.cshtml | 2 +- src/Umbraco.Web.UI/Umbraco/Views/Default.cshtml | 2 +- src/Umbraco.Web.UI/Umbraco/Views/Preview/Index.cshtml | 2 +- src/Umbraco.Web.UI/config/splashes/noNodes.aspx | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Umbraco.Web.UI/Umbraco/Views/AuthorizeUpgrade.cshtml b/src/Umbraco.Web.UI/Umbraco/Views/AuthorizeUpgrade.cshtml index 59568b508e..9f7a532fe0 100644 --- a/src/Umbraco.Web.UI/Umbraco/Views/AuthorizeUpgrade.cshtml +++ b/src/Umbraco.Web.UI/Umbraco/Views/AuthorizeUpgrade.cshtml @@ -33,7 +33,7 @@ Umbraco @Html.RenderCssHere( - new BasicPath("Umbraco", Current.IOHelper.ResolveUrl(SystemDirectories.Umbraco))) + new BasicPath("Umbraco", Current.IOHelper.ResolveUrl(Current.SystemDirectories.Umbraco))) @*Because we're lazy loading angular js, the embedded cloak style will not be loaded initially, but we need it*@