From bd4b4620d4d001ac5555f9c573d0bb38dc657236 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Mon, 4 Feb 2019 13:34:26 +0100 Subject: [PATCH 01/68] First part of refactoring umb-editor-navigation --- .../editor/umbeditornavigation.directive.js | 13 +++--- .../umbeditornavigationitem.directive.js | 40 +++++++++++++++++++ .../src/less/canvas-designer.less | 1 + .../components/umb-editor-navigation.less | 22 +++++----- src/Umbraco.Web.UI.Client/src/less/navs.less | 1 + .../editor/umb-editor-navigation-item.html | 12 ++++++ .../editor/umb-editor-navigation.html | 36 ++++++----------- .../src/views/components/umb-dropdown.html | 2 +- 8 files changed, 88 insertions(+), 39 deletions(-) create mode 100644 src/Umbraco.Web.UI.Client/src/common/directives/components/editor/umbeditornavigationitem.directive.js create mode 100644 src/Umbraco.Web.UI.Client/src/views/components/editor/umb-editor-navigation-item.html diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/editor/umbeditornavigation.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/editor/umbeditornavigation.directive.js index 943d2232c2..6b269ad17e 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/editor/umbeditornavigation.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/editor/umbeditornavigation.directive.js @@ -17,14 +17,17 @@ name: "More" }; - scope.clickNavigationItem = function (selectedItem) { + scope.openNavigationItem = function (item) { + + console.log("openNavigationItem", item) + scope.showDropdown = false; - runItemAction(selectedItem); - setItemToActive(selectedItem); + runItemAction(item); + setItemToActive(item); if(scope.onSelect) { - scope.onSelect({"item": selectedItem}); + scope.onSelect({"item": item}); } - eventsService.emit("app.tabChange", selectedItem); + eventsService.emit("app.tabChange", item); }; scope.toggleDropdown = function () { diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/editor/umbeditornavigationitem.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/editor/umbeditornavigationitem.directive.js new file mode 100644 index 0000000000..60a5a54d0f --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/editor/umbeditornavigationitem.directive.js @@ -0,0 +1,40 @@ +/** +@ngdoc directive +@name umbraco.directives.directive:umbTabContent +@restrict E +@scope + +@description +Use this directive to render tab content. For an example see: {@link umbraco.directives.directive:umbTabContent umbTabContent} + +@param {string=} tab The tab. + +**/ +(function () { + 'use strict'; + + function UmbEditorNavigationItemController($scope, $element, $attrs) { + + console.log("LINKKK!") + var vm = this; + + this.callbackOpen = function(item) { + console.log("callbackOpen") + vm.open({item:vm.item}); + }; + } + + angular + .module('umbraco.directives.html') + .component('umbEditorNavigationItem', { + templateUrl: 'views/components/editor/umb-editor-navigation-item.html', + controller: UmbEditorNavigationItemController, + controllerAs: 'vm', + bindings: { + item: '=', + open: '&', + index: '@' + } + }); + +})(); diff --git a/src/Umbraco.Web.UI.Client/src/less/canvas-designer.less b/src/Umbraco.Web.UI.Client/src/less/canvas-designer.less index 7f67d5c3b2..d1492a33c6 100644 --- a/src/Umbraco.Web.UI.Client/src/less/canvas-designer.less +++ b/src/Umbraco.Web.UI.Client/src/less/canvas-designer.less @@ -176,6 +176,7 @@ a, a:hover{ .dropdown-menu { position: absolute; + display: block; top: auto; right: 0; z-index: 1000; diff --git a/src/Umbraco.Web.UI.Client/src/less/components/umb-editor-navigation.less b/src/Umbraco.Web.UI.Client/src/less/components/umb-editor-navigation.less index c1f099c2a5..f4bbeadc3f 100644 --- a/src/Umbraco.Web.UI.Client/src/less/components/umb-editor-navigation.less +++ b/src/Umbraco.Web.UI.Client/src/less/components/umb-editor-navigation.less @@ -106,29 +106,25 @@ line-height: 1em; } -.umb-sub-views-nav-item__more { +.umb-sub-views-nav-item-more__icon { margin-bottom: 10px; } -.umb-sub-views-nav-item__more i { +.umb-sub-views-nav-item-more__icon i { height: 5px; width: 5px; border-radius: 50%; - background: @gray-3; + background: @ui-active-type;// fallback if browser doesnt support currentColor + background: currentColor; display: inline-block; margin: 0 5px 0 0; } -.umb-sub-views-nav-item__more i:last-of-type { +.umb-sub-views-nav-item-more__icon i:last-of-type { margin-right: 0; } -// make dots green the an item is active -.umb-sub-views-nav-item.is-active .umb-sub-views-nav-item__more i { - background-color: @ui-active; -} - -.umb-sub-views-nav__dropdown.umb-sub-views-nav__dropdown { +.umb-sub-views-nav-item-more__dropdown { left: auto; right: 0; display: grid; @@ -136,3 +132,9 @@ min-width: auto; margin-top: 10px; } +.umb-sub-views-nav-item-more__dropdown > li { + display: flex; +} +.umb-sub-views-nav-item-more__dropdown .umb-sub-views-nav-item:first { + border-left: none; +} diff --git a/src/Umbraco.Web.UI.Client/src/less/navs.less b/src/Umbraco.Web.UI.Client/src/less/navs.less index 0101113670..a2710fab6c 100644 --- a/src/Umbraco.Web.UI.Client/src/less/navs.less +++ b/src/Umbraco.Web.UI.Client/src/less/navs.less @@ -220,6 +220,7 @@ // DROPDOWNS // --------- .dropdown-menu { + display: block; border-radius: @dropdownBorderRadius; box-shadow: 0 5px 20px rgba(0,0,0,.3); padding-top: 0; diff --git a/src/Umbraco.Web.UI.Client/src/views/components/editor/umb-editor-navigation-item.html b/src/Umbraco.Web.UI.Client/src/views/components/editor/umb-editor-navigation-item.html new file mode 100644 index 0000000000..002e9adfc0 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/views/components/editor/umb-editor-navigation-item.html @@ -0,0 +1,12 @@ + + + {{ vm.item.name }} +
{{vm.item.badge.count}}
+
diff --git a/src/Umbraco.Web.UI.Client/src/views/components/editor/umb-editor-navigation.html b/src/Umbraco.Web.UI.Client/src/views/components/editor/umb-editor-navigation.html index e278a8c401..1bc7c5ff4a 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/editor/umb-editor-navigation.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/editor/umb-editor-navigation.html @@ -3,42 +3,32 @@
  • - - - {{ item.name }} -
    {{item.badge.count}}
    -
    + +
  • -
    +
    {{ moreButton.name }}
    - + - - - {{ item.name }} - + + diff --git a/src/Umbraco.Web.UI.Client/src/views/components/umb-dropdown.html b/src/Umbraco.Web.UI.Client/src/views/components/umb-dropdown.html index 141793f6b1..2f24186597 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/umb-dropdown.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/umb-dropdown.html @@ -1 +1 @@ - \ No newline at end of file + From be881ba9ca7261d9a4a85a95338406025f5682e5 Mon Sep 17 00:00:00 2001 From: Kenn Jacobsen Date: Mon, 4 Feb 2019 20:09:17 +0100 Subject: [PATCH 02/68] Fix the redirect tracking composer --- src/Umbraco.Web/Routing/RedirectTrackingComposer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web/Routing/RedirectTrackingComposer.cs b/src/Umbraco.Web/Routing/RedirectTrackingComposer.cs index 1130f0880f..75ab4ad613 100644 --- a/src/Umbraco.Web/Routing/RedirectTrackingComposer.cs +++ b/src/Umbraco.Web/Routing/RedirectTrackingComposer.cs @@ -12,6 +12,6 @@ namespace Umbraco.Web.Routing /// recycle bin = moving to and from does nothing: to = the node is gone, where would we redirect? from = same /// [RuntimeLevel(MinLevel = RuntimeLevel.Run)] - public class RedirectTrackingComposer : ComponentComposer, ICoreComposer + public class RedirectTrackingComposer : ComponentComposer, ICoreComposer { } } From c9936058b5112ec8913e7c8746ed87ec08f7ed3d Mon Sep 17 00:00:00 2001 From: Kenn Jacobsen Date: Tue, 5 Feb 2019 07:54:42 +0100 Subject: [PATCH 03/68] Allow creating any content type at root if none are marked as "AllowAsRoot" --- src/Umbraco.Web/Editors/ContentTypeController.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Web/Editors/ContentTypeController.cs b/src/Umbraco.Web/Editors/ContentTypeController.cs index 0aa7b75143..8df753bfe7 100644 --- a/src/Umbraco.Web/Editors/ContentTypeController.cs +++ b/src/Umbraco.Web/Editors/ContentTypeController.cs @@ -393,7 +393,11 @@ namespace Umbraco.Web.Editors IEnumerable types; if (contentId == Constants.System.Root) { - types = Services.ContentTypeService.GetAll().Where(x => x.AllowedAsRoot).ToList(); + var allContentTypes = Services.ContentTypeService.GetAll().ToList(); + bool AllowedAsRoot(IContentType x) => x.AllowedAsRoot; + types = allContentTypes.Any(AllowedAsRoot) + ? allContentTypes.Where(AllowedAsRoot).ToList() + : allContentTypes; } else { From 9579b42330199621c96c472a928ad033936e1d0e Mon Sep 17 00:00:00 2001 From: Kenn Jacobsen Date: Tue, 5 Feb 2019 07:54:59 +0100 Subject: [PATCH 04/68] Allow copying/moving any content type to root if none are marked as "AllowAsRoot" --- src/Umbraco.Web/Editors/ContentController.cs | 6 ++++-- src/Umbraco.Web/Editors/MediaController.cs | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/Umbraco.Web/Editors/ContentController.cs b/src/Umbraco.Web/Editors/ContentController.cs index ee056e38f0..4e8c26b8e1 100644 --- a/src/Umbraco.Web/Editors/ContentController.cs +++ b/src/Umbraco.Web/Editors/ContentController.cs @@ -1822,8 +1822,10 @@ namespace Umbraco.Web.Editors } if (model.ParentId < 0) { - //cannot move if the content item is not allowed at the root - if (toMove.ContentType.AllowedAsRoot == false) + //cannot move if the content item is not allowed at the root unless there are + //none allowed at root (in which case all should be allowed at root) + var contentTypeService = Services.ContentTypeService; + if (toMove.ContentType.AllowedAsRoot == false && contentTypeService.GetAll().Any(ct => ct.AllowedAsRoot)) { throw new HttpResponseException( Request.CreateNotificationValidationErrorResponse( diff --git a/src/Umbraco.Web/Editors/MediaController.cs b/src/Umbraco.Web/Editors/MediaController.cs index 5662680a8a..5fab734f6c 100644 --- a/src/Umbraco.Web/Editors/MediaController.cs +++ b/src/Umbraco.Web/Editors/MediaController.cs @@ -868,8 +868,10 @@ namespace Umbraco.Web.Editors } if (model.ParentId < 0) { - //cannot move if the content item is not allowed at the root - if (toMove.ContentType.AllowedAsRoot == false) + //cannot move if the content item is not allowed at the root unless there are + //none allowed at root (in which case all should be allowed at root) + var mediaTypeService = Services.MediaTypeService; + if (toMove.ContentType.AllowedAsRoot == false && mediaTypeService.GetAll().Any(ct => ct.AllowedAsRoot)) { var notificationModel = new SimpleNotificationModel(); notificationModel.AddErrorNotification(Services.TextService.Localize("moveOrCopy/notAllowedAtRoot"), ""); From 42902497194a258cde1444c43849410225b34f5d Mon Sep 17 00:00:00 2001 From: Bjarke Berg Date: Tue, 5 Feb 2019 11:55:10 +0100 Subject: [PATCH 05/68] #4405 - Load history on init if the active tab is info --- .../content/umbcontentnodeinfo.directive.js | 26 ++++++++----------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/content/umbcontentnodeinfo.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/content/umbcontentnodeinfo.directive.js index 06a147969a..a043b292ef 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/content/umbcontentnodeinfo.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/content/umbcontentnodeinfo.directive.js @@ -3,7 +3,7 @@ function ContentNodeInfoDirective($timeout, logResource, eventsService, userService, localizationService, dateHelper, editorService, redirectUrlsResource, overlayService) { - function link(scope, umbVariantContentCtrl) { + function link(scope) { var evts = []; var isInfoTab = false; @@ -96,22 +96,17 @@ scope.previewOpenUrl = '#/settings/documenttypes/edit/' + scope.documentType.id; } - //load in the audit trail if we are currently looking at the INFO tab - if (umbVariantContentCtrl && umbVariantContentCtrl.editor) { - var activeApp = _.find(umbVariantContentCtrl.editor.content.apps, a => a.active); - if (activeApp && activeApp.alias === "umbInfo") { - isInfoTab = true; - loadAuditTrail(); - loadRedirectUrls(); - } + var activeApp = _.find(scope.node.apps, (a) => a.active); + if (activeApp.alias === "umbInfo") { + loadRedirectUrls(); + loadAuditTrail(); } } scope.auditTrailPageChange = function (pageNumber) { scope.auditTrailOptions.pageNumber = pageNumber; - auditTrailLoaded = false; - loadAuditTrail(); + loadAuditTrail(true); }; scope.openDocumentType = function (documentType) { @@ -192,10 +187,12 @@ editorService.rollback(rollback); }; - function loadAuditTrail() { + function loadAuditTrail(forceReload) { //don't load this if it's already done - if (auditTrailLoaded) { return; }; + if (auditTrailLoaded && !forceReload) { + return; + } scope.loadingAuditTrail = true; @@ -334,8 +331,7 @@ if (newValue === oldValue) { return; } if (isInfoTab) { - auditTrailLoaded = false; - loadAuditTrail(); + loadAuditTrail(true); loadRedirectUrls(); setNodePublishStatus(); updateCurrentUrls(); From 29f2f34f9b6343d772a352f9b9e3b0c56429d891 Mon Sep 17 00:00:00 2001 From: Stephan Date: Tue, 5 Feb 2019 14:06:48 +0100 Subject: [PATCH 06/68] Refactor IContent vs IContentType --- src/Umbraco.Core/ContentExtensions.cs | 9 ++-- ...ontentTypeBaseServiceProviderExtensions.cs | 17 +++++++ src/Umbraco.Core/Models/Content.cs | 41 ++++----------- src/Umbraco.Core/Models/ContentBase.cs | 51 +++++++++---------- src/Umbraco.Core/Models/ContentType.cs | 7 ++- src/Umbraco.Core/Models/ContentTypeBase.cs | 2 + src/Umbraco.Core/Models/IContent.cs | 5 -- src/Umbraco.Core/Models/IContentBase.cs | 17 ++----- src/Umbraco.Core/Models/IContentTypeBase.cs | 5 ++ src/Umbraco.Core/Models/IMedia.cs | 5 -- src/Umbraco.Core/Models/IMember.cs | 9 +--- src/Umbraco.Core/Models/Media.cs | 42 ++++----------- src/Umbraco.Core/Models/MediaExtensions.cs | 4 +- src/Umbraco.Core/Models/MediaType.cs | 3 ++ src/Umbraco.Core/Models/Member.cs | 32 +----------- src/Umbraco.Core/Models/MemberType.cs | 3 ++ src/Umbraco.Core/Models/SimpleContentType.cs | 43 +++++++++++++++- src/Umbraco.Core/Umbraco.Core.csproj | 1 + src/Umbraco.Tests/Models/ContentTests.cs | 8 --- .../Editors/Binders/MemberBinder.cs | 3 +- src/Umbraco.Web/Editors/ContentController.cs | 3 +- .../Editors/ContentTypeController.cs | 3 +- .../Editors/Filters/MemberValidationHelper.cs | 6 ++- src/Umbraco.Web/Editors/MediaController.cs | 3 +- .../Editors/MediaTypeController.cs | 3 +- src/Umbraco.Web/Editors/MemberController.cs | 5 +- .../PublishedContentHashtableConverter.cs | 4 +- .../Mapping/ContentTypeBasicResolver.cs | 3 +- .../Mapping/MemberBasicPropertiesResolver.cs | 9 ++-- .../MemberTabsAndPropertiesResolver.cs | 18 ++++--- .../Mapping/TabsAndPropertiesResolver.cs | 10 ++-- .../NuCache/PublishedSnapshotService.cs | 4 +- src/Umbraco.Web/Security/MembershipHelper.cs | 8 +-- 33 files changed, 184 insertions(+), 202 deletions(-) create mode 100644 src/Umbraco.Core/ContentTypeBaseServiceProviderExtensions.cs diff --git a/src/Umbraco.Core/ContentExtensions.cs b/src/Umbraco.Core/ContentExtensions.cs index 5db080f3f3..bf2e7f6aa8 100644 --- a/src/Umbraco.Core/ContentExtensions.cs +++ b/src/Umbraco.Core/ContentExtensions.cs @@ -137,7 +137,8 @@ namespace Umbraco.Core /// public static IEnumerable GetNonGroupedProperties(this IContentBase content) { - var propertyIdsInTabs = content.PropertyGroups.SelectMany(pg => pg.PropertyTypes); + var contentType = Current.Services.ContentTypeBaseServices.GetContentTypeOf(content); + var propertyIdsInTabs = contentType.PropertyGroups.SelectMany(pg => pg.PropertyTypes); return content.Properties .Where(property => propertyIdsInTabs.Contains(property.PropertyType) == false) .OrderBy(x => x.PropertyType.SortOrder); @@ -206,8 +207,7 @@ namespace Umbraco.Core var property = content.Properties.FirstOrDefault(x => x.Alias.InvariantEquals(propertyTypeAlias)); if (property != null) return property; - var contentTypeService = contentTypeBaseServiceProvider.For(content); - var contentType = contentTypeService.Get(content.ContentTypeId); + var contentType = contentTypeBaseServiceProvider.GetContentTypeOf(content); var propertyType = contentType.CompositionPropertyTypes .FirstOrDefault(x => x.Alias.InvariantEquals(propertyTypeAlias)); if (propertyType == null) @@ -236,8 +236,7 @@ namespace Umbraco.Core /// public static string StoreFile(this IContentBase content, IContentTypeBaseServiceProvider contentTypeBaseServiceProvider, string propertyTypeAlias, string filename, Stream filestream, string filepath) { - var contentTypeService = contentTypeBaseServiceProvider.For(content); - var contentType = contentTypeService.Get(content.ContentTypeId); + var contentType = contentTypeBaseServiceProvider.GetContentTypeOf(content); var propertyType = contentType .CompositionPropertyTypes.FirstOrDefault(x => x.Alias.InvariantEquals(propertyTypeAlias)); if (propertyType == null) throw new ArgumentException("Invalid property type alias " + propertyTypeAlias + "."); diff --git a/src/Umbraco.Core/ContentTypeBaseServiceProviderExtensions.cs b/src/Umbraco.Core/ContentTypeBaseServiceProviderExtensions.cs new file mode 100644 index 0000000000..ad4d286139 --- /dev/null +++ b/src/Umbraco.Core/ContentTypeBaseServiceProviderExtensions.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Umbraco.Core.Models; +using Umbraco.Core.Services; + +namespace Umbraco.Core +{ + // fixme + public static class ContentTypeBaseServiceProviderExtensions + { + public static IContentTypeComposition GetContentTypeOf(this IContentTypeBaseServiceProvider serviceProvider, IContentBase contentBase) + => serviceProvider.For(contentBase).Get(contentBase.ContentTypeId); + } +} diff --git a/src/Umbraco.Core/Models/Content.cs b/src/Umbraco.Core/Models/Content.cs index dd4ba13c33..d33e78d422 100644 --- a/src/Umbraco.Core/Models/Content.cs +++ b/src/Umbraco.Core/Models/Content.cs @@ -45,7 +45,6 @@ namespace Umbraco.Core.Models : base(name, parent, contentType, properties, culture) { if (contentType == null) throw new ArgumentNullException(nameof(contentType)); - ContentType = new SimpleContentType(contentType); _publishedState = PublishedState.Unpublished; PublishedVersionId = 0; } @@ -73,7 +72,6 @@ namespace Umbraco.Core.Models : base(name, parentId, contentType, properties, culture) { if (contentType == null) throw new ArgumentNullException(nameof(contentType)); - ContentType = new SimpleContentType(contentType); _publishedState = PublishedState.Unpublished; PublishedVersionId = 0; } @@ -165,12 +163,6 @@ namespace Umbraco.Core.Models [IgnoreDataMember] public bool Edited { get; internal set; } - /// - /// Gets the ContentType used by this content object - /// - [IgnoreDataMember] - public ISimpleContentType ContentType { get; private set; } - /// [IgnoreDataMember] public DateTime? PublishDate { get; internal set; } // set by persistence @@ -241,7 +233,7 @@ namespace Umbraco.Core.Models public string GetPublishName(string culture) { if (culture.IsNullOrWhiteSpace()) return PublishName; - if (!ContentTypeBase.VariesByCulture()) return null; + if (!ContentType.VariesByCulture()) return null; if (_publishInfos == null) return null; return _publishInfos.TryGetValue(culture, out var infos) ? infos.Name : null; } @@ -250,7 +242,7 @@ namespace Umbraco.Core.Models public DateTime? GetPublishDate(string culture) { if (culture.IsNullOrWhiteSpace()) return PublishDate; - if (!ContentTypeBase.VariesByCulture()) return null; + if (!ContentType.VariesByCulture()) return null; if (_publishInfos == null) return null; return _publishInfos.TryGetValue(culture, out var infos) ? infos.Date : (DateTime?) null; } @@ -410,13 +402,7 @@ namespace Umbraco.Core.Models /// Leaves PropertyTypes intact after change public void ChangeContentType(IContentType contentType) { - ContentTypeId = contentType.Id; - ContentType = new SimpleContentType(contentType); - ContentTypeBase = contentType; - Properties.EnsurePropertyTypes(PropertyTypes); - - Properties.CollectionChanged -= PropertiesChanged; // be sure not to double add - Properties.CollectionChanged += PropertiesChanged; + ChangeContentType(contentType, false); } /// @@ -427,19 +413,15 @@ namespace Umbraco.Core.Models /// Boolean indicating whether to clear PropertyTypes upon change public void ChangeContentType(IContentType contentType, bool clearProperties) { - if(clearProperties) - { - ContentTypeId = contentType.Id; - ContentType = new SimpleContentType(contentType); - ContentTypeBase = contentType; - Properties.EnsureCleanPropertyTypes(PropertyTypes); + ChangeContentType(new SimpleContentType(contentType)); - Properties.CollectionChanged -= PropertiesChanged; // be sure not to double add - Properties.CollectionChanged += PropertiesChanged; - return; - } + if (clearProperties) + Properties.EnsureCleanPropertyTypes(contentType.CompositionPropertyTypes); + else + Properties.EnsurePropertyTypes(contentType.CompositionPropertyTypes); - ChangeContentType(contentType); + Properties.CollectionChanged -= PropertiesChanged; // be sure not to double add + Properties.CollectionChanged += PropertiesChanged; } public override void ResetDirtyProperties(bool rememberDirty) @@ -484,9 +466,6 @@ namespace Umbraco.Core.Models var clonedContent = (Content)clone; - //need to manually clone this since it's not settable - clonedContent.ContentType = ContentType; - //if culture infos exist then deal with event bindings if (clonedContent._publishInfos != null) { diff --git a/src/Umbraco.Core/Models/ContentBase.cs b/src/Umbraco.Core/Models/ContentBase.cs index 51730c3b4d..908f620b11 100644 --- a/src/Umbraco.Core/Models/ContentBase.cs +++ b/src/Umbraco.Core/Models/ContentBase.cs @@ -4,6 +4,7 @@ using System.Collections.Specialized; using System.Diagnostics; using System.Linq; using System.Runtime.Serialization; +using Umbraco.Core.Composing; using Umbraco.Core.Exceptions; using Umbraco.Core.Models.Entities; @@ -20,7 +21,6 @@ namespace Umbraco.Core.Models protected static readonly ContentCultureInfosCollection NoInfos = new ContentCultureInfosCollection(); private int _contentTypeId; - protected IContentTypeComposition ContentTypeBase; private int _writerId; private PropertyCollection _properties; private ContentCultureInfosCollection _cultureInfos; @@ -47,7 +47,7 @@ namespace Umbraco.Core.Models private ContentBase(string name, IContentTypeComposition contentType, PropertyCollection properties, string culture = null) { - ContentTypeBase = contentType ?? throw new ArgumentNullException(nameof(contentType)); + ContentType = contentType?.ToSimple() ?? throw new ArgumentNullException(nameof(contentType)); // initially, all new instances have Id = 0; // no identity @@ -57,7 +57,16 @@ namespace Umbraco.Core.Models _contentTypeId = contentType.Id; _properties = properties ?? throw new ArgumentNullException(nameof(properties)); - _properties.EnsurePropertyTypes(PropertyTypes); + _properties.EnsurePropertyTypes(contentType.CompositionPropertyTypes); + } + + [IgnoreDataMember] + public ISimpleContentType ContentType { get; private set; } + + protected void ChangeContentType(ISimpleContentType contentType) + { + ContentType = contentType; + ContentTypeId = contentType.Id; } protected void PropertiesChanged(object sender, NotifyCollectionChangedEventArgs e) @@ -88,13 +97,13 @@ namespace Umbraco.Core.Models { //There will be cases where this has not been updated to reflect the true content type ID. //This will occur when inserting new content. - if (_contentTypeId == 0 && ContentTypeBase != null && ContentTypeBase.HasIdentity) + if (_contentTypeId == 0 && ContentType != null) { - _contentTypeId = ContentTypeBase.Id; + _contentTypeId = ContentType.Id; } return _contentTypeId; } - protected set => SetPropertyValueAndDetectChanges(value, ref _contentTypeId, nameof(ContentTypeId)); + private set => SetPropertyValueAndDetectChanges(value, ref _contentTypeId, nameof(ContentTypeId)); } /// @@ -115,20 +124,6 @@ namespace Umbraco.Core.Models } } - /// - /// Gets the enumeration of property groups for the entity. - /// TODO: remove this proxy method - /// - [IgnoreDataMember] - public IEnumerable PropertyGroups => ContentTypeBase.CompositionPropertyGroups; - - /// - /// Gets the numeration of property types for the entity. - /// TODO: remove this proxy method - /// - [IgnoreDataMember] - public IEnumerable PropertyTypes => ContentTypeBase.CompositionPropertyTypes; - #region Cultures // notes - common rules @@ -153,7 +148,7 @@ namespace Umbraco.Core.Models public string GetCultureName(string culture) { if (culture.IsNullOrWhiteSpace()) return Name; - if (!ContentTypeBase.VariesByCulture()) return null; + if (!ContentType.VariesByCulture()) return null; if (_cultureInfos == null) return null; return _cultureInfos.TryGetValue(culture, out var infos) ? infos.Name : null; } @@ -162,7 +157,7 @@ namespace Umbraco.Core.Models public DateTime? GetUpdateDate(string culture) { if (culture.IsNullOrWhiteSpace()) return null; - if (!ContentTypeBase.VariesByCulture()) return null; + if (!ContentType.VariesByCulture()) return null; if (_cultureInfos == null) return null; return _cultureInfos.TryGetValue(culture, out var infos) ? infos.Date : (DateTime?) null; } @@ -170,7 +165,7 @@ namespace Umbraco.Core.Models /// public void SetCultureName(string name, string culture) { - if (ContentTypeBase.VariesByCulture()) // set on variant content type + if (ContentType.VariesByCulture()) // set on variant content type { if (culture.IsNullOrWhiteSpace()) // invariant is ok { @@ -278,7 +273,8 @@ namespace Umbraco.Core.Models return; } - var propertyType = PropertyTypes.FirstOrDefault(x => x.Alias.InvariantEquals(propertyTypeAlias)); + var propertyTypes = Current.Services.ContentTypeBaseServices.GetContentTypeOf(this).CompositionPropertyTypes; + var propertyType = propertyTypes.FirstOrDefault(x => x.Alias.InvariantEquals(propertyTypeAlias)); if (propertyType == null) throw new InvalidOperationException($"No PropertyType exists with the supplied alias \"{propertyTypeAlias}\"."); @@ -302,8 +298,8 @@ namespace Umbraco.Core.Models // the variation should be supported by the content type properties // if the content type is invariant, only '*' and 'null' is ok // if the content type varies, everything is ok because some properties may be invariant - if (!ContentTypeBase.SupportsPropertyVariation(culture, "*", true)) - throw new NotSupportedException($"Culture \"{culture}\" is not supported by content type \"{ContentTypeBase.Alias}\" with variation \"{ContentTypeBase.Variations}\"."); + if (!ContentType.SupportsPropertyVariation(culture, "*", true)) + throw new NotSupportedException($"Culture \"{culture}\" is not supported by content type \"{ContentType.Alias}\" with variation \"{ContentType.Variations}\"."); // copying from the same Id and VersionPk var copyingFromSelf = Id == other.Id && VersionId == other.VersionId; @@ -490,6 +486,9 @@ namespace Umbraco.Core.Models var clonedContent = (ContentBase)clone; + //need to manually clone this since it's not settable + clonedContent.ContentType = ContentType; + //if culture infos exist then deal with event bindings if (clonedContent._cultureInfos != null) { diff --git a/src/Umbraco.Core/Models/ContentType.cs b/src/Umbraco.Core/Models/ContentType.cs index 61fabe6fb0..63c758611a 100644 --- a/src/Umbraco.Core/Models/ContentType.cs +++ b/src/Umbraco.Core/Models/ContentType.cs @@ -41,6 +41,9 @@ namespace Umbraco.Core.Models _allowedTemplates = new List(); } + /// + public override ISimpleContentType ToSimple() => new SimpleContentType(this); + /// public override bool IsPublishing => IsPublishingConst; @@ -97,8 +100,8 @@ namespace Umbraco.Core.Models /// True if AllowedTemplates contains the templateId else False public bool IsAllowedTemplate(int templateId) { - return AllowedTemplates == null - ? false + return AllowedTemplates == null + ? false : AllowedTemplates.Any(t => t.Id == templateId); } diff --git a/src/Umbraco.Core/Models/ContentTypeBase.cs b/src/Umbraco.Core/Models/ContentTypeBase.cs index 2aa114a88f..320f667e07 100644 --- a/src/Umbraco.Core/Models/ContentTypeBase.cs +++ b/src/Umbraco.Core/Models/ContentTypeBase.cs @@ -67,6 +67,8 @@ namespace Umbraco.Core.Models _variations = ContentVariation.Nothing; } + public abstract ISimpleContentType ToSimple(); + /// /// Gets a value indicating whether the content type is publishing. /// diff --git a/src/Umbraco.Core/Models/IContent.cs b/src/Umbraco.Core/Models/IContent.cs index ee38f613a3..1e1867ddc6 100644 --- a/src/Umbraco.Core/Models/IContent.cs +++ b/src/Umbraco.Core/Models/IContent.cs @@ -66,11 +66,6 @@ namespace Umbraco.Core.Models /// DateTime? PublishDate { get; } - /// - /// Gets the content type of this content. - /// - ISimpleContentType ContentType { get; } - /// /// Gets a value indicating whether a culture is published. /// diff --git a/src/Umbraco.Core/Models/IContentBase.cs b/src/Umbraco.Core/Models/IContentBase.cs index 40a1c57097..1ed042d5bd 100644 --- a/src/Umbraco.Core/Models/IContentBase.cs +++ b/src/Umbraco.Core/Models/IContentBase.cs @@ -18,6 +18,11 @@ namespace Umbraco.Core.Models /// int ContentTypeId { get; } + /// + /// Gets the content type of this content. + /// + ISimpleContentType ContentType { get; } + /// /// Gets the identifier of the writer. /// @@ -95,18 +100,6 @@ namespace Umbraco.Core.Models /// Properties are loaded as part of the Content object graph PropertyCollection Properties { get; set; } - /// - /// List of PropertyGroups available on this Content object - /// - /// PropertyGroups are kind of lazy loaded as part of the object graph - IEnumerable PropertyGroups { get; } - - /// - /// List of PropertyTypes available on this Content object - /// - /// PropertyTypes are kind of lazy loaded as part of the object graph - IEnumerable PropertyTypes { get; } - /// /// Gets a value indicating whether the content entity has a property with the supplied alias. /// diff --git a/src/Umbraco.Core/Models/IContentTypeBase.cs b/src/Umbraco.Core/Models/IContentTypeBase.cs index aea84d9767..215c8532c1 100644 --- a/src/Umbraco.Core/Models/IContentTypeBase.cs +++ b/src/Umbraco.Core/Models/IContentTypeBase.cs @@ -159,5 +159,10 @@ namespace Umbraco.Core.Models /// Name of the PropertyGroup to move the PropertyType to /// bool MovePropertyType(string propertyTypeAlias, string propertyGroupName); + + /// + /// Gets an corresponding to this content type. + /// + ISimpleContentType ToSimple(); } } diff --git a/src/Umbraco.Core/Models/IMedia.cs b/src/Umbraco.Core/Models/IMedia.cs index cfb79bbf2c..3e2d11fb71 100644 --- a/src/Umbraco.Core/Models/IMedia.cs +++ b/src/Umbraco.Core/Models/IMedia.cs @@ -4,11 +4,6 @@ namespace Umbraco.Core.Models { public interface IMedia : IContentBase { - /// - /// Gets the ContentType used by this Media object - /// - IMediaType ContentType { get; } - /// /// Changes the for the current content object /// diff --git a/src/Umbraco.Core/Models/IMember.cs b/src/Umbraco.Core/Models/IMember.cs index 15826f03f3..199d53b174 100644 --- a/src/Umbraco.Core/Models/IMember.cs +++ b/src/Umbraco.Core/Models/IMember.cs @@ -1,6 +1,4 @@ -using System; -using System.Collections.Generic; -using Umbraco.Core.Models.Entities; +using Umbraco.Core.Models.Entities; using Umbraco.Core.Models.Membership; namespace Umbraco.Core.Models @@ -11,10 +9,5 @@ namespace Umbraco.Core.Models /// String alias of the default ContentType /// string ContentTypeAlias { get; } - - /// - /// Gets the ContentType used by this content object - /// - IMemberType ContentType { get; } } } diff --git a/src/Umbraco.Core/Models/Media.cs b/src/Umbraco.Core/Models/Media.cs index a0f3aa35de..bf5f5cf948 100644 --- a/src/Umbraco.Core/Models/Media.cs +++ b/src/Umbraco.Core/Models/Media.cs @@ -10,8 +10,6 @@ namespace Umbraco.Core.Models [DataContract(IsReference = true)] public class Media : ContentBase, IMedia { - private IMediaType _contentType; - /// /// Constructor for creating a Media object /// @@ -31,9 +29,7 @@ namespace Umbraco.Core.Models /// Collection of properties public Media(string name, IMedia parent, IMediaType contentType, PropertyCollection properties) : base(name, parent, contentType, properties) - { - _contentType = contentType ?? throw new ArgumentNullException(nameof(contentType)); - } + { } /// /// Constructor for creating a Media object @@ -54,15 +50,7 @@ namespace Umbraco.Core.Models /// Collection of properties public Media(string name, int parentId, IMediaType contentType, PropertyCollection properties) : base(name, parentId, contentType, properties) - { - _contentType = contentType ?? throw new ArgumentNullException(nameof(contentType)); - } - - /// - /// Gets the ContentType used by this Media object - /// - [IgnoreDataMember] - public IMediaType ContentType => _contentType; + { } /// /// Changes the for the current Media object @@ -71,13 +59,7 @@ namespace Umbraco.Core.Models /// Leaves PropertyTypes intact after change public void ChangeContentType(IMediaType contentType) { - ContentTypeId = contentType.Id; - _contentType = contentType; - ContentTypeBase = contentType; - Properties.EnsurePropertyTypes(PropertyTypes); - - Properties.CollectionChanged -= PropertiesChanged; // be sure not to double add - Properties.CollectionChanged += PropertiesChanged; + ChangeContentType(contentType, false); } /// @@ -88,19 +70,15 @@ namespace Umbraco.Core.Models /// Boolean indicating whether to clear PropertyTypes upon change public void ChangeContentType(IMediaType contentType, bool clearProperties) { + ChangeContentType(new SimpleContentType(contentType)); + if (clearProperties) - { - ContentTypeId = contentType.Id; - _contentType = contentType; - ContentTypeBase = contentType; - Properties.EnsureCleanPropertyTypes(PropertyTypes); + Properties.EnsureCleanPropertyTypes(contentType.CompositionPropertyTypes); + else + Properties.EnsurePropertyTypes(contentType.CompositionPropertyTypes); - Properties.CollectionChanged -= PropertiesChanged; // be sure not to double add - Properties.CollectionChanged += PropertiesChanged; - return; - } - - ChangeContentType(contentType); + Properties.CollectionChanged -= PropertiesChanged; // be sure not to double add + Properties.CollectionChanged += PropertiesChanged; } /// diff --git a/src/Umbraco.Core/Models/MediaExtensions.cs b/src/Umbraco.Core/Models/MediaExtensions.cs index e281aaf5ab..b7d72f6dd3 100644 --- a/src/Umbraco.Core/Models/MediaExtensions.cs +++ b/src/Umbraco.Core/Models/MediaExtensions.cs @@ -2,6 +2,7 @@ using System.Linq; using Newtonsoft.Json; using Newtonsoft.Json.Linq; +using Umbraco.Core.Composing; using Umbraco.Core.Configuration.UmbracoSettings; using Umbraco.Core.Logging; using Umbraco.Core.PropertyEditors.ValueConverters; @@ -15,7 +16,8 @@ namespace Umbraco.Core.Models /// public static string GetUrl(this IMedia media, string propertyAlias, ILogger logger) { - var propertyType = media.PropertyTypes.FirstOrDefault(x => x.Alias.InvariantEquals(propertyAlias)); + var contentType = Current.Services.MediaTypeService.Get(media.ContentTypeId); + var propertyType = contentType.PropertyTypes.FirstOrDefault(x => x.Alias.InvariantEquals(propertyAlias)); if (propertyType == null) return string.Empty; var val = media.Properties[propertyType]; diff --git a/src/Umbraco.Core/Models/MediaType.cs b/src/Umbraco.Core/Models/MediaType.cs index 83e1acfbc0..f7598b4965 100644 --- a/src/Umbraco.Core/Models/MediaType.cs +++ b/src/Umbraco.Core/Models/MediaType.cs @@ -41,6 +41,9 @@ namespace Umbraco.Core.Models { } + /// + public override ISimpleContentType ToSimple() => new SimpleContentType(this); + /// public override bool IsPublishing => IsPublishingConst; diff --git a/src/Umbraco.Core/Models/Member.cs b/src/Umbraco.Core/Models/Member.cs index 78d1cfafd5..0e91065d56 100644 --- a/src/Umbraco.Core/Models/Member.cs +++ b/src/Umbraco.Core/Models/Member.cs @@ -15,8 +15,6 @@ namespace Umbraco.Core.Models public class Member : ContentBase, IMember { private IDictionary _additionalData; - private IMemberType _contentType; - private readonly string _contentTypeAlias; private string _username; private string _email; private string _rawPasswordValue; @@ -29,8 +27,6 @@ namespace Umbraco.Core.Models public Member(IMemberType contentType) : base("", -1, contentType, new PropertyCollection()) { - _contentType = contentType ?? throw new ArgumentNullException(nameof(contentType)); - _contentTypeAlias = contentType.Alias; IsApproved = true; //this cannot be null but can be empty @@ -49,8 +45,6 @@ namespace Umbraco.Core.Models { if (string.IsNullOrWhiteSpace(name)) throw new ArgumentNullOrEmptyException(nameof(name)); - _contentType = contentType ?? throw new ArgumentNullException(nameof(contentType)); - _contentTypeAlias = contentType.Alias; IsApproved = true; //this cannot be null but can be empty @@ -73,8 +67,6 @@ namespace Umbraco.Core.Models if (string.IsNullOrWhiteSpace(name)) throw new ArgumentNullOrEmptyException(nameof(name)); if (string.IsNullOrWhiteSpace(username)) throw new ArgumentNullOrEmptyException(nameof(username)); - _contentType = contentType ?? throw new ArgumentNullException(nameof(contentType)); - _contentTypeAlias = contentType.Alias; _email = email; _username = username; IsApproved = isApproved; @@ -96,9 +88,6 @@ namespace Umbraco.Core.Models public Member(string name, string email, string username, string rawPasswordValue, IMemberType contentType) : base(name, -1, contentType, new PropertyCollection()) { - _contentType = contentType ?? throw new ArgumentNullException(nameof(contentType)); - _contentTypeAlias = contentType.Alias; - _email = email; _username = username; _rawPasswordValue = rawPasswordValue; @@ -119,8 +108,6 @@ namespace Umbraco.Core.Models public Member(string name, string email, string username, string rawPasswordValue, IMemberType contentType, bool isApproved) : base(name, -1, contentType, new PropertyCollection()) { - _contentType = contentType ?? throw new ArgumentNullException(nameof(contentType)); - _contentTypeAlias = contentType.Alias; _email = email; _username = username; _rawPasswordValue = rawPasswordValue; @@ -473,7 +460,7 @@ namespace Umbraco.Core.Models /// String alias of the default ContentType /// [DataMember] - public virtual string ContentTypeAlias => _contentTypeAlias; + public virtual string ContentTypeAlias => ContentType.Alias; /// /// User key from the Provider. @@ -504,12 +491,6 @@ namespace Umbraco.Core.Models ProviderUserKey = Key; } - /// - /// Gets the ContentType used by this content object - /// - [IgnoreDataMember] - public IMemberType ContentType => _contentType; - /* Internal experiment - only used for mapping queries. * Adding these to have first level properties instead of the Properties collection. */ @@ -575,17 +556,6 @@ namespace Umbraco.Core.Models return true; } - protected override void PerformDeepClone(object clone) - { - base.PerformDeepClone(clone); - - var clonedEntity = (Member)clone; - - //need to manually clone this since it's not settable - clonedEntity._contentType = (IMemberType)ContentType.DeepClone(); - - } - /// [DataMember] [DoNotClone] diff --git a/src/Umbraco.Core/Models/MemberType.cs b/src/Umbraco.Core/Models/MemberType.cs index a6c1518446..e85aa0e15e 100644 --- a/src/Umbraco.Core/Models/MemberType.cs +++ b/src/Umbraco.Core/Models/MemberType.cs @@ -31,6 +31,9 @@ namespace Umbraco.Core.Models MemberTypePropertyTypes = new Dictionary(); } + /// + public override ISimpleContentType ToSimple() => new SimpleContentType(this); + /// public override bool IsPublishing => IsPublishingConst; diff --git a/src/Umbraco.Core/Models/SimpleContentType.cs b/src/Umbraco.Core/Models/SimpleContentType.cs index be1f87fcda..db7e01fade 100644 --- a/src/Umbraco.Core/Models/SimpleContentType.cs +++ b/src/Umbraco.Core/Models/SimpleContentType.cs @@ -1,4 +1,6 @@ -namespace Umbraco.Core.Models +using System; + +namespace Umbraco.Core.Models { /// /// Implements . @@ -10,6 +12,9 @@ /// public SimpleContentType(IContentType contentType) { + if (contentType == null) throw new ArgumentNullException(nameof(contentType)); + + Id = contentType.Id; Alias = contentType.Alias; DefaultTemplate = contentType.DefaultTemplate; @@ -22,6 +27,42 @@ IsElement = contentType.IsElement; } + /// + /// Initializes a new instance of the class. + /// + public SimpleContentType(IMediaType mediaType) + { + if (mediaType == null) throw new ArgumentNullException(nameof(mediaType)); + + Id = mediaType.Id; + Alias = mediaType.Alias; + Variations = mediaType.Variations; + Icon = mediaType.Icon; + IsContainer = mediaType.IsContainer; + Icon = mediaType.Icon; + Name = mediaType.Name; + AllowedAsRoot = mediaType.AllowedAsRoot; + IsElement = mediaType.IsElement; + } + + /// + /// Initializes a new instance of the class. + /// + public SimpleContentType(IMemberType memberType) + { + if (memberType == null) throw new ArgumentNullException(nameof(memberType)); + + Id = memberType.Id; + Alias = memberType.Alias; + Variations = memberType.Variations; + Icon = memberType.Icon; + IsContainer = memberType.IsContainer; + Icon = memberType.Icon; + Name = memberType.Name; + AllowedAsRoot = memberType.AllowedAsRoot; + IsElement = memberType.IsElement; + } + /// public string Alias { get; } diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index 792f1d1223..d4b26cbbc0 100755 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -291,6 +291,7 @@ + diff --git a/src/Umbraco.Tests/Models/ContentTests.cs b/src/Umbraco.Tests/Models/ContentTests.cs index 160428b5e4..844a609878 100644 --- a/src/Umbraco.Tests/Models/ContentTests.cs +++ b/src/Umbraco.Tests/Models/ContentTests.cs @@ -543,14 +543,12 @@ namespace Umbraco.Tests.Models { // Arrange var contentType = MockedContentTypes.CreateTextPageContentType(); - var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1); // Act contentType.PropertyGroups.Add(new PropertyGroup(true) { Name = "Test Group", SortOrder = 3 }); // Assert Assert.That(contentType.PropertyGroups.Count, Is.EqualTo(3)); - Assert.That(content.PropertyGroups.Count(), Is.EqualTo(3)); } [Test] @@ -573,7 +571,6 @@ namespace Umbraco.Tests.Models { // Arrange var contentType = MockedContentTypes.CreateTextPageContentType(); - var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1); // Act contentType.PropertyGroups["Content"].PropertyTypes.Add(new PropertyType("test", ValueStorageType.Ntext, "subtitle") @@ -587,7 +584,6 @@ namespace Umbraco.Tests.Models // Assert Assert.That(contentType.PropertyGroups["Content"].PropertyTypes.Count, Is.EqualTo(3)); - Assert.That(content.PropertyGroups.First(x => x.Name == "Content").PropertyTypes.Count, Is.EqualTo(3)); } [Test] @@ -637,8 +633,6 @@ namespace Umbraco.Tests.Models // Assert Assert.That(content.Properties.Count, Is.EqualTo(5)); - Assert.That(content.PropertyTypes.Count(), Is.EqualTo(5)); - Assert.That(content.PropertyGroups.Count(), Is.EqualTo(3)); Assert.That(content.Properties["subtitle"].GetValue(), Is.EqualTo("Subtitle Test")); Assert.That(content.Properties["title"].GetValue(), Is.EqualTo("Textpage textpage")); } @@ -676,8 +670,6 @@ namespace Umbraco.Tests.Models // Assert Assert.That(content.Properties.Contains("author"), Is.True); - Assert.That(content.PropertyGroups.Count(), Is.EqualTo(1)); - Assert.That(content.PropertyTypes.Count(), Is.EqualTo(3)); //Note: There was 4 properties, after changing ContentType 1 has been added (no properties are deleted) Assert.That(content.Properties.Count, Is.EqualTo(5)); } diff --git a/src/Umbraco.Web/Editors/Binders/MemberBinder.cs b/src/Umbraco.Web/Editors/Binders/MemberBinder.cs index 393fab98a9..bceba2e04d 100644 --- a/src/Umbraco.Web/Editors/Binders/MemberBinder.cs +++ b/src/Umbraco.Web/Editors/Binders/MemberBinder.cs @@ -169,7 +169,8 @@ namespace Umbraco.Web.Editors.Binders var member = MemberService.CreateGenericMembershipProviderMember(model.Name, model.Email, model.Username, Guid.NewGuid().ToString("N")); //we'll just remove all properties here otherwise we'll end up with validation errors, we don't want to persist any property data anyways // in this case. - FilterContentTypeProperties(member.ContentType, member.ContentType.PropertyTypes.Select(x => x.Alias).ToArray()); + memberType = _services.MemberTypeService.Get(member.ContentTypeId); + FilterContentTypeProperties(memberType, memberType.PropertyTypes.Select(x => x.Alias).ToArray()); return member; } } diff --git a/src/Umbraco.Web/Editors/ContentController.cs b/src/Umbraco.Web/Editors/ContentController.cs index b429c7d9bd..0c3d8dfa20 100644 --- a/src/Umbraco.Web/Editors/ContentController.cs +++ b/src/Umbraco.Web/Editors/ContentController.cs @@ -1841,8 +1841,7 @@ namespace Umbraco.Web.Editors throw new HttpResponseException(HttpStatusCode.NotFound); } - var contentTypeService = Services.ContentTypeBaseServices.For(parent); - var parentContentType = contentTypeService.Get(parent.ContentTypeId); + var parentContentType = Services.ContentTypeService.Get(parent.ContentTypeId); //check if the item is allowed under this one if (parentContentType.AllowedContentTypes.Select(x => x.Id).ToArray() .Any(x => x.Value == toMove.ContentType.Id) == false) diff --git a/src/Umbraco.Web/Editors/ContentTypeController.cs b/src/Umbraco.Web/Editors/ContentTypeController.cs index 1f5feb8ad9..756762a853 100644 --- a/src/Umbraco.Web/Editors/ContentTypeController.cs +++ b/src/Umbraco.Web/Editors/ContentTypeController.cs @@ -403,8 +403,7 @@ namespace Umbraco.Web.Editors return Enumerable.Empty(); } - var contentTypeService = Services.ContentTypeBaseServices.For(contentItem); - var contentType = contentTypeService.Get(contentItem.ContentTypeId); + var contentType = Services.ContentTypeBaseServices.GetContentTypeOf(contentItem); var ids = contentType.AllowedContentTypes.Select(x => x.Id.Value).ToArray(); if (ids.Any() == false) return Enumerable.Empty(); diff --git a/src/Umbraco.Web/Editors/Filters/MemberValidationHelper.cs b/src/Umbraco.Web/Editors/Filters/MemberValidationHelper.cs index 74fcac60ea..c97e35eb0d 100644 --- a/src/Umbraco.Web/Editors/Filters/MemberValidationHelper.cs +++ b/src/Umbraco.Web/Editors/Filters/MemberValidationHelper.cs @@ -7,6 +7,7 @@ using System.Web.Http.Controllers; using System.Web.Http.ModelBinding; using System.Web.Security; using Umbraco.Core; +using Umbraco.Core.Composing; using Umbraco.Core.Logging; using Umbraco.Core.Models; using Umbraco.Web.Models.ContentEditing; @@ -117,8 +118,9 @@ namespace Umbraco.Web.Editors.Filters //if a sensitive value is being submitted. if (UmbracoContextAccessor.UmbracoContext.Security.CurrentUser.HasAccessToSensitiveData() == false) { - var sensitiveProperties = model.PersistedContent.ContentType - .PropertyTypes.Where(x => model.PersistedContent.ContentType.IsSensitiveProperty(x.Alias)) + var contentType = Current.Services.MemberTypeService.Get(model.PersistedContent.ContentTypeId); + var sensitiveProperties = contentType + .PropertyTypes.Where(x => contentType.IsSensitiveProperty(x.Alias)) .ToList(); foreach (var sensitiveProperty in sensitiveProperties) diff --git a/src/Umbraco.Web/Editors/MediaController.cs b/src/Umbraco.Web/Editors/MediaController.cs index ee7f1cc9cd..16816aa9fc 100644 --- a/src/Umbraco.Web/Editors/MediaController.cs +++ b/src/Umbraco.Web/Editors/MediaController.cs @@ -887,7 +887,8 @@ namespace Umbraco.Web.Editors } //check if the item is allowed under this one - if (parent.ContentType.AllowedContentTypes.Select(x => x.Id).ToArray() + var parentContentType = Services.MediaTypeService.Get(parent.ContentTypeId); + if (parentContentType.AllowedContentTypes.Select(x => x.Id).ToArray() .Any(x => x.Value == toMove.ContentType.Id) == false) { var notificationModel = new SimpleNotificationModel(); diff --git a/src/Umbraco.Web/Editors/MediaTypeController.cs b/src/Umbraco.Web/Editors/MediaTypeController.cs index d041db1862..c85ef439dd 100644 --- a/src/Umbraco.Web/Editors/MediaTypeController.cs +++ b/src/Umbraco.Web/Editors/MediaTypeController.cs @@ -230,7 +230,8 @@ namespace Umbraco.Web.Editors return Enumerable.Empty(); } - var ids = contentItem.ContentType.AllowedContentTypes.Select(x => x.Id.Value).ToArray(); + var contentType = Services.MediaTypeService.Get(contentItem.ContentTypeId); + var ids = contentType.AllowedContentTypes.Select(x => x.Id.Value).ToArray(); if (ids.Any() == false) return Enumerable.Empty(); diff --git a/src/Umbraco.Web/Editors/MemberController.cs b/src/Umbraco.Web/Editors/MemberController.cs index 5a11f6cda9..cdc1fd3ce1 100644 --- a/src/Umbraco.Web/Editors/MemberController.cs +++ b/src/Umbraco.Web/Editors/MemberController.cs @@ -435,8 +435,9 @@ namespace Umbraco.Web.Editors //There's only 3 special ones we need to deal with that are part of the MemberSave instance if (Security.CurrentUser.HasAccessToSensitiveData() == false) { - var sensitiveProperties = contentItem.PersistedContent.ContentType - .PropertyTypes.Where(x => contentItem.PersistedContent.ContentType.IsSensitiveProperty(x.Alias)) + var memberType = Services.MemberTypeService.Get(contentItem.PersistedContent.ContentTypeId); + var sensitiveProperties = memberType + .PropertyTypes.Where(x => memberType.IsSensitiveProperty(x.Alias)) .ToList(); foreach (var sensitiveProperty in sensitiveProperties) diff --git a/src/Umbraco.Web/Macros/PublishedContentHashtableConverter.cs b/src/Umbraco.Web/Macros/PublishedContentHashtableConverter.cs index f40c8a7d98..2a3bca9c16 100644 --- a/src/Umbraco.Web/Macros/PublishedContentHashtableConverter.cs +++ b/src/Umbraco.Web/Macros/PublishedContentHashtableConverter.cs @@ -202,8 +202,8 @@ namespace Umbraco.Web.Macros CreatorName = _inner.GetCreatorProfile().Name; WriterName = _inner.GetWriterProfile().Name; - var contentTypeService = Current.Services.ContentTypeBaseServices.For(_inner); - ContentType = Current.PublishedContentTypeFactory.CreateContentType(contentTypeService.Get(_inner.ContentTypeId)); + var contentType = Current.Services.ContentTypeBaseServices.GetContentTypeOf(_inner); + ContentType = Current.PublishedContentTypeFactory.CreateContentType(contentType); _properties = ContentType.PropertyTypes .Select(x => diff --git a/src/Umbraco.Web/Models/Mapping/ContentTypeBasicResolver.cs b/src/Umbraco.Web/Models/Mapping/ContentTypeBasicResolver.cs index 19c150e072..aa97b25260 100644 --- a/src/Umbraco.Web/Models/Mapping/ContentTypeBasicResolver.cs +++ b/src/Umbraco.Web/Models/Mapping/ContentTypeBasicResolver.cs @@ -30,8 +30,7 @@ namespace Umbraco.Web.Models.Mapping if (HttpContext.Current != null && UmbracoContext.Current != null && UmbracoContext.Current.Security.CurrentUser != null && UmbracoContext.Current.Security.CurrentUser.AllowedSections.Any(x => x.Equals(Constants.Applications.Settings))) { - var contentTypeService = _contentTypeBaseServiceProvider.For(source); - var contentType = contentTypeService.Get(source.ContentTypeId); + var contentType = _contentTypeBaseServiceProvider.GetContentTypeOf(source); var contentTypeBasic = Mapper.Map(contentType); return contentTypeBasic; diff --git a/src/Umbraco.Web/Models/Mapping/MemberBasicPropertiesResolver.cs b/src/Umbraco.Web/Models/Mapping/MemberBasicPropertiesResolver.cs index fbd14876ea..e1ee0631a9 100644 --- a/src/Umbraco.Web/Models/Mapping/MemberBasicPropertiesResolver.cs +++ b/src/Umbraco.Web/Models/Mapping/MemberBasicPropertiesResolver.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using AutoMapper; using Umbraco.Core.Models; +using Umbraco.Core.Services; using Umbraco.Web.Models.ContentEditing; namespace Umbraco.Web.Models.Mapping @@ -13,10 +14,12 @@ namespace Umbraco.Web.Models.Mapping internal class MemberBasicPropertiesResolver : IValueResolver> { private readonly IUmbracoContextAccessor _umbracoContextAccessor; + private readonly IMemberTypeService _memberTypeService; - public MemberBasicPropertiesResolver(IUmbracoContextAccessor umbracoContextAccessor) + public MemberBasicPropertiesResolver(IUmbracoContextAccessor umbracoContextAccessor, IMemberTypeService memberTypeService) { - _umbracoContextAccessor = umbracoContextAccessor ?? throw new System.ArgumentNullException(nameof(umbracoContextAccessor)); + _umbracoContextAccessor = umbracoContextAccessor ?? throw new ArgumentNullException(nameof(umbracoContextAccessor)); + _memberTypeService = memberTypeService ?? throw new ArgumentNullException(nameof(memberTypeService)); } public IEnumerable Resolve(IMember source, MemberBasic destination, IEnumerable destMember, ResolutionContext context) @@ -29,7 +32,7 @@ namespace Umbraco.Web.Models.Mapping source.Properties.OrderBy(prop => prop.PropertyType.SortOrder)) .ToList(); - var memberType = source.ContentType; + var memberType = _memberTypeService.Get(source.ContentTypeId); //now update the IsSensitive value foreach (var prop in result) diff --git a/src/Umbraco.Web/Models/Mapping/MemberTabsAndPropertiesResolver.cs b/src/Umbraco.Web/Models/Mapping/MemberTabsAndPropertiesResolver.cs index 6134275c76..517889277c 100644 --- a/src/Umbraco.Web/Models/Mapping/MemberTabsAndPropertiesResolver.cs +++ b/src/Umbraco.Web/Models/Mapping/MemberTabsAndPropertiesResolver.cs @@ -25,16 +25,18 @@ namespace Umbraco.Web.Models.Mapping { private readonly IUmbracoContextAccessor _umbracoContextAccessor; private readonly ILocalizedTextService _localizedTextService; + private readonly IMemberTypeService _memberTypeService; private readonly IMemberService _memberService; private readonly IUserService _userService; - public MemberTabsAndPropertiesResolver(IUmbracoContextAccessor umbracoContextAccessor, ILocalizedTextService localizedTextService, IMemberService memberService, IUserService userService) + public MemberTabsAndPropertiesResolver(IUmbracoContextAccessor umbracoContextAccessor, ILocalizedTextService localizedTextService, IMemberService memberService, IUserService userService, IMemberTypeService memberTypeService) : base(localizedTextService) { - _umbracoContextAccessor = umbracoContextAccessor ?? throw new System.ArgumentNullException(nameof(umbracoContextAccessor)); - _localizedTextService = localizedTextService ?? throw new System.ArgumentNullException(nameof(localizedTextService)); - _memberService = memberService ?? throw new System.ArgumentNullException(nameof(memberService)); - _userService = userService ?? throw new System.ArgumentNullException(nameof(userService)); + _umbracoContextAccessor = umbracoContextAccessor ?? throw new ArgumentNullException(nameof(umbracoContextAccessor)); + _localizedTextService = localizedTextService ?? throw new ArgumentNullException(nameof(localizedTextService)); + _memberService = memberService ?? throw new ArgumentNullException(nameof(memberService)); + _userService = userService ?? throw new ArgumentNullException(nameof(userService)); + _memberTypeService = memberTypeService ?? throw new ArgumentNullException(nameof(memberTypeService)); } /// @@ -43,7 +45,9 @@ namespace Umbraco.Web.Models.Mapping { var provider = Core.Security.MembershipProviderExtensions.GetMembersMembershipProvider(); - IgnoreProperties = source.PropertyTypes + var memberType = _memberTypeService.Get(source.ContentTypeId); + + IgnoreProperties = memberType.CompositionPropertyTypes .Where(x => x.HasIdentity == false) .Select(x => x.Alias) .ToArray(); @@ -176,7 +180,7 @@ namespace Umbraco.Web.Models.Mapping { var result = base.MapProperties(content, properties, context); var member = (IMember)content; - var memberType = member.ContentType; + var memberType = _memberTypeService.Get(member.ContentTypeId); var umbracoContext = _umbracoContextAccessor.UmbracoContext; diff --git a/src/Umbraco.Web/Models/Mapping/TabsAndPropertiesResolver.cs b/src/Umbraco.Web/Models/Mapping/TabsAndPropertiesResolver.cs index e8d7fb38b2..4e6ae99cf2 100644 --- a/src/Umbraco.Web/Models/Mapping/TabsAndPropertiesResolver.cs +++ b/src/Umbraco.Web/Models/Mapping/TabsAndPropertiesResolver.cs @@ -26,7 +26,7 @@ namespace Umbraco.Web.Models.Mapping { IgnoreProperties = ignoreProperties ?? throw new ArgumentNullException(nameof(ignoreProperties)); } - + // TODO: This should deserialize to ListViewConfiguration private static int GetTabNumberFromConfig(IDictionary listViewConfig) { @@ -58,7 +58,7 @@ namespace Umbraco.Web.Models.Mapping /// /// /// - /// The generic properties tab is responsible for + /// The generic properties tab is responsible for /// setting up the properties such as Created date, updated date, template selected, etc... /// protected virtual void MapGenericProperties(IContentBase content, List> tabs, ResolutionContext context) @@ -98,7 +98,7 @@ namespace Umbraco.Web.Models.Mapping //re-assign genericProps.Properties = contentProps; - //Show or hide properties tab based on whether it has or not any properties + //Show or hide properties tab based on whether it has or not any properties if (genericProps.Properties.Any() == false) { //loop through the tabs, remove the one with the id of zero and exit the loop @@ -145,11 +145,13 @@ namespace Umbraco.Web.Models.Mapping { var tabs = new List>(); + var contentType = Current.Services.ContentTypeBaseServices.GetContentTypeOf(source); + // add the tabs, for properties that belong to a tab // need to aggregate the tabs, as content.PropertyGroups contains all the composition tabs, // and there might be duplicates (content does not work like contentType and there is no // content.CompositionPropertyGroups). - var groupsGroupsByName = source.PropertyGroups.OrderBy(x => x.SortOrder).GroupBy(x => x.Name); + var groupsGroupsByName = contentType.CompositionPropertyGroups.OrderBy(x => x.SortOrder).GroupBy(x => x.Name); foreach (var groupsByName in groupsGroupsByName) { var properties = new List(); diff --git a/src/Umbraco.Web/PublishedCache/NuCache/PublishedSnapshotService.cs b/src/Umbraco.Web/PublishedCache/NuCache/PublishedSnapshotService.cs index be506d99f8..18324a473d 100755 --- a/src/Umbraco.Web/PublishedCache/NuCache/PublishedSnapshotService.cs +++ b/src/Umbraco.Web/PublishedCache/NuCache/PublishedSnapshotService.cs @@ -1231,9 +1231,7 @@ namespace Umbraco.Web.PublishedCache.NuCache var cultureData = new Dictionary(); // sanitize - names should be ok but ... never knows - var contentTypeService = _contentTypeBaseServiceProvider.For(content); - var contentType = contentTypeService.Get(content.ContentTypeId); - if (contentType.VariesByCulture()) + if (content.ContentType.VariesByCulture()) { var infos = content is IContent document ? (published diff --git a/src/Umbraco.Web/Security/MembershipHelper.cs b/src/Umbraco.Web/Security/MembershipHelper.cs index 8de42fc12b..83a0b15b82 100644 --- a/src/Umbraco.Web/Security/MembershipHelper.cs +++ b/src/Umbraco.Web/Security/MembershipHelper.cs @@ -171,14 +171,16 @@ namespace Umbraco.Web.Security member.Name = model.Name; } + var memberType = _memberTypeService.Get(member.ContentTypeId); + if (model.MemberProperties != null) { foreach (var property in model.MemberProperties //ensure the property they are posting exists - .Where(p => member.ContentType.PropertyTypeExists(p.Alias)) + .Where(p => memberType.PropertyTypeExists(p.Alias)) .Where(property => member.Properties.Contains(property.Alias)) //needs to be editable - .Where(p => member.ContentType.MemberCanEditProperty(p.Alias))) + .Where(p => memberType.MemberCanEditProperty(p.Alias))) { member.Properties[property.Alias].SetValue(property.Value); } @@ -409,7 +411,7 @@ namespace Umbraco.Web.Security model.LastPasswordChangedDate = membershipUser.LastPasswordChangedDate; - var memberType = member.ContentType; + var memberType = _memberTypeService.Get(member.ContentTypeId); var builtIns = Constants.Conventions.Member.GetStandardPropertyTypeStubs().Select(x => x.Key).ToArray(); From 6f9be482be217fb506800670f6aed168fb88186e Mon Sep 17 00:00:00 2001 From: Bjarke Berg Date: Tue, 5 Feb 2019 14:52:02 +0100 Subject: [PATCH 07/68] #4398 - Added validation to the grid editor, such that columns must be at least as large as the layouts. --- .../datatypesettings.controller.js | 19 +++++-- .../grid/grid.prevalues.controller.js | 6 +-- .../GridConfigurationEditor.cs | 49 ++++++++++++++++++- 3 files changed, 66 insertions(+), 8 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/datatypesettings/datatypesettings.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/datatypesettings/datatypesettings.controller.js index 9fbbad8f09..099439fa4b 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/datatypesettings/datatypesettings.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/datatypesettings/datatypesettings.controller.js @@ -10,7 +10,7 @@ (function () { "use strict"; - function DataTypeSettingsController($scope, dataTypeResource, dataTypeHelper, localizationService) { + function DataTypeSettingsController($scope, dataTypeResource, dataTypeHelper, localizationService, notificationsService, overlayService, formHelper) { var vm = this; @@ -102,7 +102,7 @@ vm.saveButtonState = "busy"; var preValues = dataTypeHelper.createPreValueProps(vm.dataType.preValues); - + dataTypeResource.save(vm.dataType, preValues, $scope.model.create).then(function(newDataType) { $scope.model.dataType = newDataType; vm.saveButtonState = "success"; @@ -110,6 +110,19 @@ if ($scope.model && $scope.model.submit) { $scope.model.submit($scope.model); } + }, function(err) { + vm.saveButtonState = "error"; + + if(err.status === 400) { + if (err.data && (err.data.ModelState)) { + + formHelper.handleServerValidation(err.data.ModelState); + + for (var e in err.data.ModelState) { + notificationsService.error("Validation", err.data.ModelState[e][0]); + } + } + } }); } @@ -120,4 +133,4 @@ angular.module("umbraco").controller("Umbraco.Editors.DataTypeSettingsController", DataTypeSettingsController); -})(); \ No newline at end of file +})(); diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.prevalues.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.prevalues.controller.js index 2a00df32dc..19057fa842 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.prevalues.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.prevalues.controller.js @@ -96,7 +96,7 @@ angular.module("umbraco") $scope.layoutConfigOverlay.rows = $scope.model.value.layouts; $scope.layoutConfigOverlay.columns = $scope.model.value.columns; $scope.layoutConfigOverlay.show = true; - + $scope.layoutConfigOverlay.submit = function(model) { $scope.layoutConfigOverlay.show = false; $scope.layoutConfigOverlay = null; @@ -218,8 +218,8 @@ angular.module("umbraco") $scope.editConfigCollectionOverlay.show = true; $scope.editConfigCollectionOverlay.submit = function(model) { - - callback(model.config) + + callback(model.config); $scope.editConfigCollectionOverlay.show = false; $scope.editConfigCollectionOverlay = null; diff --git a/src/Umbraco.Web/PropertyEditors/GridConfigurationEditor.cs b/src/Umbraco.Web/PropertyEditors/GridConfigurationEditor.cs index fe86bb9a6e..902cd5b41b 100644 --- a/src/Umbraco.Web/PropertyEditors/GridConfigurationEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/GridConfigurationEditor.cs @@ -1,4 +1,9 @@ -using Umbraco.Core.PropertyEditors; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using Newtonsoft.Json; +using Umbraco.Core.PropertyEditors; +using Umbraco.Core.PropertyEditors.Validators; namespace Umbraco.Web.PropertyEditors { @@ -6,5 +11,45 @@ namespace Umbraco.Web.PropertyEditors /// Represents the configuration for the grid value editor. /// public class GridConfigurationEditor : ConfigurationEditor - { } + { + public GridConfigurationEditor() + { + var items = Fields.First(x => x.Key == "items"); + + items.Validators.Add(new GridValidator()); + } + } + + public class GridValidator : IValueValidator + { + public IEnumerable Validate(object rawValue, string valueType, object dataTypeConfiguration) + { + if (rawValue == null) + yield break; + + var model = JsonConvert.DeserializeObject(rawValue.ToString()); + + if (model.Templates.Any(t => t.Sections.Sum(s => s.Grid) > model.Columns)) + { + yield return new ValidationResult("Columns must be at least the same size as the largest layout", new[] { nameof(model.Columns) }); + } + + } + } + + public class GridEditorModel + { + public GridEditorTemplateModel[] Templates { get; set; } + public int Columns { get; set; } + } + + public class GridEditorTemplateModel + { + public GridEditorSectionModel[] Sections { get; set; } + } + + public class GridEditorSectionModel + { + public int Grid { get; set; } + } } From 1bbb9c2b6e939e7ba93359f448b7a49e503b1ba5 Mon Sep 17 00:00:00 2001 From: Shannon Date: Wed, 6 Feb 2019 16:43:04 +1100 Subject: [PATCH 08/68] updates to latest newtonsoft --- build/NuSpecs/UmbracoCms.Core.nuspec | 2 +- src/Umbraco.Core/Umbraco.Core.csproj | 2 +- src/Umbraco.Examine/Umbraco.Examine.csproj | 2 +- src/Umbraco.Tests/Umbraco.Tests.csproj | 2 +- src/Umbraco.Web.UI/Umbraco.Web.UI.csproj | 2 +- src/Umbraco.Web.UI/web.Template.Debug.config | 11 +++++++++++ src/Umbraco.Web.UI/web.Template.config | 2 +- src/Umbraco.Web/Umbraco.Web.csproj | 2 +- 8 files changed, 18 insertions(+), 7 deletions(-) diff --git a/build/NuSpecs/UmbracoCms.Core.nuspec b/build/NuSpecs/UmbracoCms.Core.nuspec index 9758c05dd6..8140e090c0 100644 --- a/build/NuSpecs/UmbracoCms.Core.nuspec +++ b/build/NuSpecs/UmbracoCms.Core.nuspec @@ -28,7 +28,7 @@ - + diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index 792f1d1223..274f71bc38 100755 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -69,7 +69,7 @@ 4.0.0 - + diff --git a/src/Umbraco.Examine/Umbraco.Examine.csproj b/src/Umbraco.Examine/Umbraco.Examine.csproj index 1320f3b0d2..989afd8d1c 100644 --- a/src/Umbraco.Examine/Umbraco.Examine.csproj +++ b/src/Umbraco.Examine/Umbraco.Examine.csproj @@ -49,7 +49,7 @@ - + diff --git a/src/Umbraco.Tests/Umbraco.Tests.csproj b/src/Umbraco.Tests/Umbraco.Tests.csproj index 41c9581131..b58f880522 100644 --- a/src/Umbraco.Tests/Umbraco.Tests.csproj +++ b/src/Umbraco.Tests/Umbraco.Tests.csproj @@ -105,7 +105,7 @@ - + diff --git a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj index 7c3293183d..9eee662c89 100644 --- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj +++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj @@ -103,7 +103,7 @@ - + 8.0.0-alpha.36 diff --git a/src/Umbraco.Web.UI/web.Template.Debug.config b/src/Umbraco.Web.UI/web.Template.Debug.config index 8c4b3bb299..ef9fda8964 100644 --- a/src/Umbraco.Web.UI/web.Template.Debug.config +++ b/src/Umbraco.Web.UI/web.Template.Debug.config @@ -25,4 +25,15 @@ + + + + + + + + + + diff --git a/src/Umbraco.Web.UI/web.Template.config b/src/Umbraco.Web.UI/web.Template.config index d93089fe21..703a531861 100644 --- a/src/Umbraco.Web.UI/web.Template.config +++ b/src/Umbraco.Web.UI/web.Template.config @@ -231,7 +231,7 @@ - + diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index f9fa29f7db..3e310c96b9 100755 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -82,7 +82,7 @@ - + From 50d1b9ddfdac5e7e49bb81b4c9c40e1d7c7bad5d Mon Sep 17 00:00:00 2001 From: Shannon Date: Wed, 6 Feb 2019 16:53:15 +1100 Subject: [PATCH 09/68] Latest MVC, WebApi, Owin and Signalr --- src/Umbraco.Core/Umbraco.Core.csproj | 4 +- src/Umbraco.Tests/Umbraco.Tests.csproj | 20 ++++---- src/Umbraco.Web.UI/Umbraco.Web.UI.csproj | 8 +-- src/Umbraco.Web.UI/web.Template.Debug.config | 51 ++++++++++++++++++++ src/Umbraco.Web.UI/web.Template.config | 12 ++--- src/Umbraco.Web/Umbraco.Web.csproj | 12 ++--- 6 files changed, 79 insertions(+), 28 deletions(-) diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index 274f71bc38..a235e503dd 100755 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -63,10 +63,10 @@ 2.2.2 - 5.2.6 + 5.2.7 - 4.0.0 + 4.0.1 diff --git a/src/Umbraco.Tests/Umbraco.Tests.csproj b/src/Umbraco.Tests/Umbraco.Tests.csproj index b58f880522..332e922703 100644 --- a/src/Umbraco.Tests/Umbraco.Tests.csproj +++ b/src/Umbraco.Tests/Umbraco.Tests.csproj @@ -89,16 +89,16 @@ - - - - - - - - - - + + + + + + + + + + diff --git a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj index 9eee662c89..72fe0b7e1f 100644 --- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj +++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj @@ -91,8 +91,8 @@ - - + + @@ -100,8 +100,8 @@ - - + + diff --git a/src/Umbraco.Web.UI/web.Template.Debug.config b/src/Umbraco.Web.UI/web.Template.Debug.config index ef9fda8964..cfc38814a6 100644 --- a/src/Umbraco.Web.UI/web.Template.Debug.config +++ b/src/Umbraco.Web.UI/web.Template.Debug.config @@ -27,12 +27,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Umbraco.Web.UI/web.Template.config b/src/Umbraco.Web.UI/web.Template.config index 703a531861..b977dddc6c 100644 --- a/src/Umbraco.Web.UI/web.Template.config +++ b/src/Umbraco.Web.UI/web.Template.config @@ -215,19 +215,19 @@ - + - + - + - + @@ -239,11 +239,11 @@ - + - + diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index 3e310c96b9..681713afa5 100755 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -74,13 +74,13 @@ - - - - + + + + - - + + From 33bc979cfc57a4a63d5f46171ec57dd6aa691603 Mon Sep 17 00:00:00 2001 From: Shannon Date: Wed, 6 Feb 2019 17:03:23 +1100 Subject: [PATCH 10/68] Fixes binding of FormDataCollection for GET requests which fixes the compatibility with the latest WebApi 5.2.7 version (cherry picked from https://github.com/umbraco/Umbraco-CMS/pull/3851), fixes a binding redirect --- src/Umbraco.Web.UI/web.Template.Debug.config | 7 +++ src/Umbraco.Web.UI/web.Template.config | 4 ++ src/Umbraco.Web/Editors/EntityController.cs | 4 +- .../Trees/ApplicationTreeController.cs | 4 +- .../Trees/ContentTreeControllerBase.cs | 4 +- src/Umbraco.Web/Trees/MemberTreeController.cs | 4 +- src/Umbraco.Web/Trees/TreeControllerBase.cs | 14 +++--- src/Umbraco.Web/Umbraco.Web.csproj | 2 +- .../Filters/HttpQueryStringFilterAttribute.cs | 43 ------------------- .../Filters/HttpQueryStringModelBinder.cs | 32 ++++++++++++++ 10 files changed, 57 insertions(+), 61 deletions(-) delete mode 100644 src/Umbraco.Web/WebApi/Filters/HttpQueryStringFilterAttribute.cs create mode 100644 src/Umbraco.Web/WebApi/Filters/HttpQueryStringModelBinder.cs diff --git a/src/Umbraco.Web.UI/web.Template.Debug.config b/src/Umbraco.Web.UI/web.Template.Debug.config index cfc38814a6..ff42f098f7 100644 --- a/src/Umbraco.Web.UI/web.Template.Debug.config +++ b/src/Umbraco.Web.UI/web.Template.Debug.config @@ -84,6 +84,13 @@ + + + + + + diff --git a/src/Umbraco.Web.UI/web.Template.config b/src/Umbraco.Web.UI/web.Template.config index b977dddc6c..f0abbfde52 100644 --- a/src/Umbraco.Web.UI/web.Template.config +++ b/src/Umbraco.Web.UI/web.Template.config @@ -249,6 +249,10 @@ + + + + diff --git a/src/Umbraco.Web/Editors/EntityController.cs b/src/Umbraco.Web/Editors/EntityController.cs index 55604e0eb9..d89909d793 100644 --- a/src/Umbraco.Web/Editors/EntityController.cs +++ b/src/Umbraco.Web/Editors/EntityController.cs @@ -14,6 +14,7 @@ using System.Reflection; using Umbraco.Core.Models; using Umbraco.Core.Persistence.DatabaseModelDefinitions; using System.Web.Http.Controllers; +using System.Web.Http.ModelBinding; using Umbraco.Core.Cache; using Umbraco.Core.Configuration; using Umbraco.Core.Logging; @@ -605,8 +606,7 @@ namespace Umbraco.Web.Editors } } - [HttpQueryStringFilter("queryStrings")] - public IEnumerable GetAncestors(int id, UmbracoEntityTypes type, FormDataCollection queryStrings) + public IEnumerable GetAncestors(int id, UmbracoEntityTypes type, [ModelBinder(typeof(HttpQueryStringModelBinder))]FormDataCollection queryStrings) { return GetResultForAncestors(id, type, queryStrings); } diff --git a/src/Umbraco.Web/Trees/ApplicationTreeController.cs b/src/Umbraco.Web/Trees/ApplicationTreeController.cs index 68d7fbb3fd..162d001e96 100644 --- a/src/Umbraco.Web/Trees/ApplicationTreeController.cs +++ b/src/Umbraco.Web/Trees/ApplicationTreeController.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Globalization; using System.Linq; using System.Net; using System.Net.Http; @@ -50,8 +49,7 @@ namespace Umbraco.Web.Trees /// /// Tree use. /// - [HttpQueryStringFilter("queryStrings")] - public async Task GetApplicationTrees(string application, string tree, FormDataCollection queryStrings, TreeUse use = TreeUse.Main) + public async Task GetApplicationTrees(string application, string tree, [System.Web.Http.ModelBinding.ModelBinder(typeof(HttpQueryStringModelBinder))]FormDataCollection queryStrings, TreeUse use = TreeUse.Main) { application = application.CleanForXss(); diff --git a/src/Umbraco.Web/Trees/ContentTreeControllerBase.cs b/src/Umbraco.Web/Trees/ContentTreeControllerBase.cs index ca2f2031bb..e521deca40 100644 --- a/src/Umbraco.Web/Trees/ContentTreeControllerBase.cs +++ b/src/Umbraco.Web/Trees/ContentTreeControllerBase.cs @@ -14,6 +14,7 @@ using Umbraco.Web.Models.Trees; using Umbraco.Web.WebApi.Filters; using System.Globalization; using Umbraco.Core.Models.Entities; +using System.Web.Http.ModelBinding; using Umbraco.Web.Actions; using Umbraco.Web.Composing; @@ -30,8 +31,7 @@ namespace Umbraco.Web.Trees /// /// /// - [HttpQueryStringFilter("queryStrings")] - public TreeNode GetTreeNode(string id, FormDataCollection queryStrings) + public TreeNode GetTreeNode(string id, [ModelBinder(typeof(HttpQueryStringModelBinder))]FormDataCollection queryStrings) { int asInt; Guid asGuid = Guid.Empty; diff --git a/src/Umbraco.Web/Trees/MemberTreeController.cs b/src/Umbraco.Web/Trees/MemberTreeController.cs index 430c5d2111..6107540c0c 100644 --- a/src/Umbraco.Web/Trees/MemberTreeController.cs +++ b/src/Umbraco.Web/Trees/MemberTreeController.cs @@ -5,6 +5,7 @@ using System.Net; using System.Net.Http; using System.Net.Http.Formatting; using System.Web.Http; +using System.Web.Http.ModelBinding; using System.Web.Security; using Umbraco.Core; using Umbraco.Core.Models; @@ -49,8 +50,7 @@ namespace Umbraco.Web.Trees /// /// /// - [HttpQueryStringFilter("queryStrings")] - public TreeNode GetTreeNode(string id, FormDataCollection queryStrings) + public TreeNode GetTreeNode(string id, [ModelBinder(typeof(HttpQueryStringModelBinder))]FormDataCollection queryStrings) { var node = GetSingleTreeNode(id, queryStrings); diff --git a/src/Umbraco.Web/Trees/TreeControllerBase.cs b/src/Umbraco.Web/Trees/TreeControllerBase.cs index e3946ce532..f7c2b2460e 100644 --- a/src/Umbraco.Web/Trees/TreeControllerBase.cs +++ b/src/Umbraco.Web/Trees/TreeControllerBase.cs @@ -2,6 +2,7 @@ using System.Globalization; using System.Linq; using System.Net.Http.Formatting; +using System.Web.Http.ModelBinding; using Umbraco.Core; using Umbraco.Core.Cache; using Umbraco.Core.Configuration; @@ -45,7 +46,7 @@ namespace Umbraco.Web.Trees /// We are allowing an arbitrary number of query strings to be passed in so that developers are able to persist custom data from the front-end /// to the back end to be used in the query for model data. /// - protected abstract TreeNodeCollection GetTreeNodes(string id, FormDataCollection queryStrings); + protected abstract TreeNodeCollection GetTreeNodes(string id, [ModelBinder(typeof(HttpQueryStringModelBinder))]FormDataCollection queryStrings); /// /// Returns the menu structure for the node @@ -53,7 +54,7 @@ namespace Umbraco.Web.Trees /// /// /// - protected abstract MenuItemCollection GetMenuForNode(string id, FormDataCollection queryStrings); + protected abstract MenuItemCollection GetMenuForNode(string id, [ModelBinder(typeof(HttpQueryStringModelBinder))]FormDataCollection queryStrings); /// /// The name to display on the root node @@ -86,8 +87,7 @@ namespace Umbraco.Web.Trees /// /// /// - [HttpQueryStringFilter("queryStrings")] - public TreeNode GetRootNode(FormDataCollection queryStrings) + public TreeNode GetRootNode([ModelBinder(typeof(HttpQueryStringModelBinder))]FormDataCollection queryStrings) { if (queryStrings == null) queryStrings = new FormDataCollection(""); var node = CreateRootNode(queryStrings); @@ -126,8 +126,7 @@ namespace Umbraco.Web.Trees /// We are allowing an arbitrary number of query strings to be passed in so that developers are able to persist custom data from the front-end /// to the back end to be used in the query for model data. /// - [HttpQueryStringFilter("queryStrings")] - public TreeNodeCollection GetNodes(string id, FormDataCollection queryStrings) + public TreeNodeCollection GetNodes(string id, [ModelBinder(typeof(HttpQueryStringModelBinder))]FormDataCollection queryStrings) { if (queryStrings == null) queryStrings = new FormDataCollection(""); var nodes = GetTreeNodes(id, queryStrings); @@ -158,8 +157,7 @@ namespace Umbraco.Web.Trees /// /// /// - [HttpQueryStringFilter("queryStrings")] - public MenuItemCollection GetMenu(string id, FormDataCollection queryStrings) + public MenuItemCollection GetMenu(string id, [ModelBinder(typeof(HttpQueryStringModelBinder))]FormDataCollection queryStrings) { if (queryStrings == null) queryStrings = new FormDataCollection(""); var menu = GetMenuForNode(id, queryStrings); diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index 681713afa5..0dc0845ee5 100755 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -284,6 +284,7 @@ + @@ -1058,7 +1059,6 @@ - diff --git a/src/Umbraco.Web/WebApi/Filters/HttpQueryStringFilterAttribute.cs b/src/Umbraco.Web/WebApi/Filters/HttpQueryStringFilterAttribute.cs deleted file mode 100644 index eea4ef7e67..0000000000 --- a/src/Umbraco.Web/WebApi/Filters/HttpQueryStringFilterAttribute.cs +++ /dev/null @@ -1,43 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Net.Http.Formatting; -using System.Web.Http.Controllers; -using System.Web.Http.Filters; - -namespace Umbraco.Web.WebApi.Filters -{ - /// - /// Allows an Action to execute with an arbitrary number of QueryStrings - /// - /// - /// Just like you can POST an arbitrary number of parameters to an Action, you can't GET an arbitrary number - /// but this will allow you to do it - /// - public sealed class HttpQueryStringFilterAttribute : ActionFilterAttribute - { - public string ParameterName { get; private set; } - - public HttpQueryStringFilterAttribute(string parameterName) - { - if (string.IsNullOrEmpty(parameterName)) - throw new ArgumentException("ParameterName is required."); - ParameterName = parameterName; - } - - public override void OnActionExecuting(HttpActionContext actionContext) - { - //get the query strings from the request properties - if (actionContext.Request.Properties.ContainsKey("MS_QueryNameValuePairs")) - { - var queryStrings = actionContext.Request.Properties["MS_QueryNameValuePairs"] as IEnumerable>; - if (queryStrings == null) return; - - var formData = new FormDataCollection(queryStrings); - - actionContext.ActionArguments[ParameterName] = formData; - } - - base.OnActionExecuting(actionContext); - } - } -} diff --git a/src/Umbraco.Web/WebApi/Filters/HttpQueryStringModelBinder.cs b/src/Umbraco.Web/WebApi/Filters/HttpQueryStringModelBinder.cs new file mode 100644 index 0000000000..6ffbb239f8 --- /dev/null +++ b/src/Umbraco.Web/WebApi/Filters/HttpQueryStringModelBinder.cs @@ -0,0 +1,32 @@ +using System.Collections.Generic; +using System.Net.Http.Formatting; +using System.Web.Http.Controllers; +using System.Web.Http.ModelBinding; + +namespace Umbraco.Web.WebApi.Filters +{ + /// + /// Allows an Action to execute with an arbitrary number of QueryStrings + /// + /// + /// Just like you can POST an arbitrary number of parameters to an Action, you can't GET an arbitrary number + /// but this will allow you to do it + /// + public sealed class HttpQueryStringModelBinder : IModelBinder + { + public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext) + { + //get the query strings from the request properties + if (actionContext.Request.Properties.ContainsKey("MS_QueryNameValuePairs")) + { + if (actionContext.Request.Properties["MS_QueryNameValuePairs"] is IEnumerable> queryStrings) + { + var formData = new FormDataCollection(queryStrings); + bindingContext.Model = formData; + return true; + } + } + return false; + } + } +} \ No newline at end of file From 5bf0b143d9eaa1ff169ecdfa67565553c8970f5f Mon Sep 17 00:00:00 2001 From: Shannon Date: Wed, 6 Feb 2019 17:08:47 +1100 Subject: [PATCH 11/68] another owin update and nuspec fix --- build/NuSpecs/UmbracoCms.Core.nuspec | 4 ++-- build/NuSpecs/UmbracoCms.Web.nuspec | 12 ++++++------ build/NuSpecs/UmbracoCms.nuspec | 2 +- src/Umbraco.Web.UI/Umbraco.Web.UI.csproj | 2 +- src/Umbraco.Web/Umbraco.Web.csproj | 2 +- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/build/NuSpecs/UmbracoCms.Core.nuspec b/build/NuSpecs/UmbracoCms.Core.nuspec index 8140e090c0..67d1eb86d7 100644 --- a/build/NuSpecs/UmbracoCms.Core.nuspec +++ b/build/NuSpecs/UmbracoCms.Core.nuspec @@ -25,8 +25,8 @@ - - + + diff --git a/build/NuSpecs/UmbracoCms.Web.nuspec b/build/NuSpecs/UmbracoCms.Web.nuspec index fabd1e25a8..140284e29c 100644 --- a/build/NuSpecs/UmbracoCms.Web.nuspec +++ b/build/NuSpecs/UmbracoCms.Web.nuspec @@ -32,12 +32,12 @@ - - - - - - + + + + + + diff --git a/build/NuSpecs/UmbracoCms.nuspec b/build/NuSpecs/UmbracoCms.nuspec index b0f30b9779..238dfd3c31 100644 --- a/build/NuSpecs/UmbracoCms.nuspec +++ b/build/NuSpecs/UmbracoCms.nuspec @@ -21,7 +21,7 @@ the latter would pick anything below 3.0.0 and that includes prereleases such as 3.0.0-alpha, and we do not want this to happen as the alpha of the next major is, really, the next major already. --> - + diff --git a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj index 72fe0b7e1f..a72434db42 100644 --- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj +++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj @@ -99,7 +99,7 @@ all - + diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index 0dc0845ee5..af6c012c69 100755 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -78,7 +78,7 @@ - + From b82dde240be8030eacefc95563185a9ab3777ea7 Mon Sep 17 00:00:00 2001 From: Bjarke Berg Date: Wed, 6 Feb 2019 08:07:04 +0100 Subject: [PATCH 12/68] #4302 - Bugfixes for media validation. --- .../src/views/media/media.edit.controller.js | 2 +- .../Editors/Filters/MediaItemSaveValidationAttribute.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/media/media.edit.controller.js b/src/Umbraco.Web.UI.Client/src/views/media/media.edit.controller.js index 175007e9ad..1f898230ac 100644 --- a/src/Umbraco.Web.UI.Client/src/views/media/media.edit.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/media/media.edit.controller.js @@ -194,7 +194,7 @@ function mediaEditController($scope, $routeParams, $q, appState, mediaResource, contentEditingHelper.handleSaveError({ err: err, - redirectOnError: !infiniteMode, + redirectOnFailure: !infiniteMode, rebindCallback: contentEditingHelper.reBindChangedProperties($scope.content, err.data) }); diff --git a/src/Umbraco.Web/Editors/Filters/MediaItemSaveValidationAttribute.cs b/src/Umbraco.Web/Editors/Filters/MediaItemSaveValidationAttribute.cs index 36bab16ed1..eda2bb8d53 100644 --- a/src/Umbraco.Web/Editors/Filters/MediaItemSaveValidationAttribute.cs +++ b/src/Umbraco.Web/Editors/Filters/MediaItemSaveValidationAttribute.cs @@ -45,7 +45,7 @@ namespace Umbraco.Web.Editors.Filters { //now do each validation step if (contentItemValidator.ValidateExistingContent(model, actionContext)) - if (!contentItemValidator.ValidateProperties(model, model, actionContext)) + if (contentItemValidator.ValidateProperties(model, model, actionContext)) contentItemValidator.ValidatePropertyData(model, model, model.PropertyCollectionDto, actionContext.ModelState); } } From 48531c6193bec465033e045662c2d71dc42c094f Mon Sep 17 00:00:00 2001 From: Bjarke Berg Date: Wed, 6 Feb 2019 08:07:50 +0100 Subject: [PATCH 13/68] #4302 - Sets the default values for Media File and Image File as mandatory --- src/Umbraco.Core/Migrations/Install/DatabaseDataCreator.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Umbraco.Core/Migrations/Install/DatabaseDataCreator.cs b/src/Umbraco.Core/Migrations/Install/DatabaseDataCreator.cs index ef55048122..7f7229ccd6 100644 --- a/src/Umbraco.Core/Migrations/Install/DatabaseDataCreator.cs +++ b/src/Umbraco.Core/Migrations/Install/DatabaseDataCreator.cs @@ -69,7 +69,7 @@ namespace Umbraco.Core.Migrations.Install if (tableName.Equals(Constants.DatabaseSchema.Tables.RelationType)) CreateRelationTypeData(); - + if (tableName.Equals(Constants.DatabaseSchema.Tables.KeyValue)) CreateKeyValueData(); @@ -210,12 +210,12 @@ namespace Umbraco.Core.Migrations.Install private void CreatePropertyTypeData() { - _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 6, UniqueId = 6.ToGuid(), DataTypeId = 1043, ContentTypeId = 1032, PropertyTypeGroupId = 3, Alias = Constants.Conventions.Media.File, Name = "Upload image", SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing }); + _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 6, UniqueId = 6.ToGuid(), DataTypeId = 1043, ContentTypeId = 1032, PropertyTypeGroupId = 3, Alias = Constants.Conventions.Media.File, Name = "Upload image", SortOrder = 0, Mandatory = true, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing }); _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 7, UniqueId = 7.ToGuid(), DataTypeId = Constants.DataTypes.LabelInt, ContentTypeId = 1032, PropertyTypeGroupId = 3, Alias = Constants.Conventions.Media.Width, Name = "Width", SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = "in pixels", Variations = (byte) ContentVariation.Nothing }); _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 8, UniqueId = 8.ToGuid(), DataTypeId = Constants.DataTypes.LabelInt, ContentTypeId = 1032, PropertyTypeGroupId = 3, Alias = Constants.Conventions.Media.Height, Name = "Height", SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = "in pixels", Variations = (byte) ContentVariation.Nothing }); _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 9, UniqueId = 9.ToGuid(), DataTypeId = Constants.DataTypes.LabelBigint, ContentTypeId = 1032, PropertyTypeGroupId = 3, Alias = Constants.Conventions.Media.Bytes, Name = "Size", SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = "in bytes", Variations = (byte) ContentVariation.Nothing }); _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 10, UniqueId = 10.ToGuid(), DataTypeId = -92, ContentTypeId = 1032, PropertyTypeGroupId = 3, Alias = Constants.Conventions.Media.Extension, Name = "Type", SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing }); - _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 24, UniqueId = 24.ToGuid(), DataTypeId = -90, ContentTypeId = 1033, PropertyTypeGroupId = 4, Alias = Constants.Conventions.Media.File, Name = "Upload file", SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing }); + _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 24, UniqueId = 24.ToGuid(), DataTypeId = -90, ContentTypeId = 1033, PropertyTypeGroupId = 4, Alias = Constants.Conventions.Media.File, Name = "Upload file", SortOrder = 0, Mandatory = true, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing }); _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 25, UniqueId = 25.ToGuid(), DataTypeId = -92, ContentTypeId = 1033, PropertyTypeGroupId = 4, Alias = Constants.Conventions.Media.Extension, Name = "Type", SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing }); _database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 26, UniqueId = 26.ToGuid(), DataTypeId = Constants.DataTypes.LabelBigint, ContentTypeId = 1033, PropertyTypeGroupId = 4, Alias = Constants.Conventions.Media.Bytes, Name = "Size", SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = "in bytes", Variations = (byte) ContentVariation.Nothing }); //membership property types From 4b9a13c3a1a65f8e86f2994298e9902b067318d1 Mon Sep 17 00:00:00 2001 From: Shannon Date: Wed, 6 Feb 2019 19:04:52 +1100 Subject: [PATCH 14/68] Updates mini profiler --- build/NuSpecs/UmbracoCms.Core.nuspec | 2 +- .../Configuration/GlobalSettings.cs | 2 +- .../Persistence/DbConnectionExtensions.cs | 2 +- .../Persistence/NPocoDatabaseExtensions.cs | 2 +- src/Umbraco.Core/Umbraco.Core.csproj | 2 +- .../TestHelpers/Stubs/TestProfiler.cs | 13 +++-- src/Umbraco.Tests/Umbraco.Tests.csproj | 2 +- src/Umbraco.Web.UI/Umbraco.Web.UI.csproj | 2 +- src/Umbraco.Web/Logging/WebProfiler.cs | 25 +++++++--- .../Logging/WebProfilerProvider.cs | 50 +++++++++---------- src/Umbraco.Web/Umbraco.Web.csproj | 2 +- 11 files changed, 58 insertions(+), 46 deletions(-) diff --git a/build/NuSpecs/UmbracoCms.Core.nuspec b/build/NuSpecs/UmbracoCms.Core.nuspec index 67d1eb86d7..c5e891bd01 100644 --- a/build/NuSpecs/UmbracoCms.Core.nuspec +++ b/build/NuSpecs/UmbracoCms.Core.nuspec @@ -27,7 +27,7 @@ - + diff --git a/src/Umbraco.Core/Configuration/GlobalSettings.cs b/src/Umbraco.Core/Configuration/GlobalSettings.cs index e30bf85fd0..1c8188e99f 100644 --- a/src/Umbraco.Core/Configuration/GlobalSettings.cs +++ b/src/Umbraco.Core/Configuration/GlobalSettings.cs @@ -31,7 +31,7 @@ namespace Umbraco.Core.Configuration private static string _reservedPaths; private static string _reservedUrls; //ensure the built on (non-changeable) reserved paths are there at all times - internal const string StaticReservedPaths = "~/app_plugins/,~/install/,"; //must end with a comma! + internal const string StaticReservedPaths = "~/app_plugins/,~/install/,~/mini-profiler-resources/"; //must end with a comma! internal const string StaticReservedUrls = "~/config/splashes/noNodes.aspx,~/.well-known,"; //must end with a comma! #endregion diff --git a/src/Umbraco.Core/Persistence/DbConnectionExtensions.cs b/src/Umbraco.Core/Persistence/DbConnectionExtensions.cs index 20586cb6f4..835f76f9f9 100644 --- a/src/Umbraco.Core/Persistence/DbConnectionExtensions.cs +++ b/src/Umbraco.Core/Persistence/DbConnectionExtensions.cs @@ -76,7 +76,7 @@ namespace Umbraco.Core.Persistence do { c = unwrapped; - if (unwrapped is ProfiledDbConnection profiled) unwrapped = profiled.InnerConnection; + if (unwrapped is ProfiledDbConnection profiled) unwrapped = profiled.WrappedConnection; if (unwrapped is RetryDbConnection retrying) unwrapped = retrying.Inner; } while (c != unwrapped); diff --git a/src/Umbraco.Core/Persistence/NPocoDatabaseExtensions.cs b/src/Umbraco.Core/Persistence/NPocoDatabaseExtensions.cs index 248f91284f..bb4c60a0df 100644 --- a/src/Umbraco.Core/Persistence/NPocoDatabaseExtensions.cs +++ b/src/Umbraco.Core/Persistence/NPocoDatabaseExtensions.cs @@ -148,7 +148,7 @@ namespace Umbraco.Core.Persistence where TConnection : class, IDbConnection { var profiled = connection as ProfiledDbConnection; - return profiled == null ? connection as TConnection : profiled.InnerConnection as TConnection; + return profiled == null ? connection as TConnection : profiled.WrappedConnection as TConnection; } /// diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index a235e503dd..e77cacbba2 100755 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -68,7 +68,7 @@ 4.0.1 - + diff --git a/src/Umbraco.Tests/TestHelpers/Stubs/TestProfiler.cs b/src/Umbraco.Tests/TestHelpers/Stubs/TestProfiler.cs index 0ffcfb7a3f..39cac6e24f 100644 --- a/src/Umbraco.Tests/TestHelpers/Stubs/TestProfiler.cs +++ b/src/Umbraco.Tests/TestHelpers/Stubs/TestProfiler.cs @@ -33,15 +33,20 @@ namespace Umbraco.Tests.TestHelpers.Stubs { if (_enabled == false) return; - MiniProfiler.Settings.SqlFormatter = new SqlServerFormatter(); - MiniProfiler.Settings.StackMaxLength = 5000; - MiniProfiler.Start(); + //see https://miniprofiler.com/dotnet/AspDotNet + MiniProfiler.Configure(new MiniProfilerOptions + { + SqlFormatter = new SqlServerFormatter(), + StackMaxLength = 5000, + }); + + MiniProfiler.StartNew(); } public void Stop(bool discardResults = false) { if (_enabled) - MiniProfiler.Stop(discardResults); + MiniProfiler.Current.Stop(discardResults); } } } diff --git a/src/Umbraco.Tests/Umbraco.Tests.csproj b/src/Umbraco.Tests/Umbraco.Tests.csproj index 332e922703..5d056ee0f8 100644 --- a/src/Umbraco.Tests/Umbraco.Tests.csproj +++ b/src/Umbraco.Tests/Umbraco.Tests.csproj @@ -100,7 +100,7 @@ - + diff --git a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj index a72434db42..0ce5e97c0a 100644 --- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj +++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj @@ -102,7 +102,7 @@ - + 8.0.0-alpha.36 diff --git a/src/Umbraco.Web/Logging/WebProfiler.cs b/src/Umbraco.Web/Logging/WebProfiler.cs index e31ef75209..a98b712038 100755 --- a/src/Umbraco.Web/Logging/WebProfiler.cs +++ b/src/Umbraco.Web/Logging/WebProfiler.cs @@ -11,6 +11,9 @@ namespace Umbraco.Web.Logging /// /// Implements by using the MiniProfiler framework. /// + /// + /// Profiling only runs when the app is in debug mode, see WebRuntime for how this gets created + /// internal class WebProfiler : IProfiler { private const string BootRequestItemKey = "Umbraco.Core.Logging.WebProfiler__isBootRequest"; @@ -22,10 +25,13 @@ namespace Umbraco.Web.Logging // create our own provider, which can provide a profiler even during boot _provider = new WebProfilerProvider(); - // settings - MiniProfiler.Settings.SqlFormatter = new SqlServerFormatter(); - MiniProfiler.Settings.StackMaxLength = 5000; - MiniProfiler.Settings.ProfilerProvider = _provider; + //see https://miniprofiler.com/dotnet/AspDotNet + MiniProfiler.Configure(new MiniProfilerOptions + { + SqlFormatter = new SqlServerFormatter(), + StackMaxLength = 5000, + ProfilerProvider = _provider + }); } public void UmbracoApplicationBeginRequest(object sender, EventArgs e) @@ -68,29 +74,32 @@ namespace Umbraco.Web.Logging /// public string Render() { - return MiniProfiler.RenderIncludes(RenderPosition.Right).ToString(); + return MiniProfiler.Current.RenderIncludes(RenderPosition.Left).ToString(); } /// public IDisposable Step(string name) { - return MiniProfiler.Current.Step(name); + return MiniProfiler.Current?.Step(name); } /// public void Start() { - MiniProfiler.Start(); + MiniProfiler.StartNew(); } /// public void Stop(bool discardResults = false) { - MiniProfiler.Stop(discardResults); + MiniProfiler.Current?.Stop(discardResults); } private static Attempt TryGetRequest(object sender) { + if (sender is HttpRequest httpRequest) + return Attempt.Succeed(new HttpRequestWrapper(httpRequest)); + var app = sender as HttpApplication; if (app == null) return Attempt.Fail(); diff --git a/src/Umbraco.Web/Logging/WebProfilerProvider.cs b/src/Umbraco.Web/Logging/WebProfilerProvider.cs index 7b12c2f5bd..dbb81cf232 100755 --- a/src/Umbraco.Web/Logging/WebProfilerProvider.cs +++ b/src/Umbraco.Web/Logging/WebProfilerProvider.cs @@ -2,6 +2,7 @@ using System.Threading; using System.Web; using StackExchange.Profiling; +using StackExchange.Profiling.Internal; namespace Umbraco.Web.Logging { @@ -13,7 +14,7 @@ namespace Umbraco.Web.Logging /// Once the boot phase is changed to BootPhase.BootRequest then the base class (default) provider will handle all /// profiling data and this sub class no longer performs any logic. /// - internal class WebProfilerProvider : WebRequestProfilerProvider + internal class WebProfilerProvider : AspNetRequestProvider { private readonly ReaderWriterLockSlim _locker = new ReaderWriterLockSlim(); private MiniProfiler _startupProfiler; @@ -81,23 +82,16 @@ namespace Umbraco.Web.Logging /// - assuming profiling is enabled, on every BeginRequest that should be profiled, /// - except for the very first one which is the boot request. /// - public override MiniProfiler Start(string sessionName = null) + public override MiniProfiler Start(string profilerName, MiniProfilerBaseOptions options) { var first = Interlocked.Exchange(ref _first, 1) == 0; - if (first == false) return base.Start(sessionName); + if (first == false) return base.Start(profilerName, options); - _startupProfiler = new MiniProfiler("http://localhost/umbraco-startup") { Name = "StartupProfiler" }; - SetProfilerActive(_startupProfiler); + _startupProfiler = new MiniProfiler("StartupProfiler", options); + CurrentProfiler = _startupProfiler; return _startupProfiler; } - // obsolete but that's the one that's called ;-( - [Obsolete] - public override MiniProfiler Start(ProfileLevel level, string sessionName = null) - { - return Start(sessionName); - } - /// /// Gets the current profiler. /// @@ -105,23 +99,27 @@ namespace Umbraco.Web.Logging /// If the boot phase is not Booted, then this will return the startup profiler (this), otherwise /// returns the base class /// - public override MiniProfiler GetCurrentProfiler() + public override MiniProfiler CurrentProfiler { - // if not booting then just use base (fast) - // no lock, _bootPhase is volatile - if (_bootPhase == BootPhase.Booted) - return base.GetCurrentProfiler(); + get + { + // if not booting then just use base (fast) + // no lock, _bootPhase is volatile + if (_bootPhase == BootPhase.Booted) + return base.CurrentProfiler; - // else - try - { - var current = base.GetCurrentProfiler(); - return current ?? _startupProfiler; - } - catch - { - return _startupProfiler; + // else + try + { + var current = base.CurrentProfiler; + return current ?? _startupProfiler; + } + catch + { + return _startupProfiler; + } } + } } } diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index af6c012c69..8e13d33433 100755 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -81,7 +81,7 @@ - + From b4bf1cb01ce1a93d23af831eee30c7993856a8d4 Mon Sep 17 00:00:00 2001 From: Shannon Date: Wed, 6 Feb 2019 19:58:56 +1100 Subject: [PATCH 15/68] puts the profiler back to the right --- src/Umbraco.Web/Logging/WebProfiler.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web/Logging/WebProfiler.cs b/src/Umbraco.Web/Logging/WebProfiler.cs index a98b712038..14c1bb065f 100755 --- a/src/Umbraco.Web/Logging/WebProfiler.cs +++ b/src/Umbraco.Web/Logging/WebProfiler.cs @@ -74,7 +74,7 @@ namespace Umbraco.Web.Logging /// public string Render() { - return MiniProfiler.Current.RenderIncludes(RenderPosition.Left).ToString(); + return MiniProfiler.Current.RenderIncludes(RenderPosition.Right).ToString(); } /// From 0947a1a109aca25a624bf3ac5a07b0afa6eea351 Mon Sep 17 00:00:00 2001 From: Shannon Date: Wed, 6 Feb 2019 21:14:50 +1100 Subject: [PATCH 16/68] Automapper upgraded --- build/NuSpecs/UmbracoCms.Core.nuspec | 2 +- build/NuSpecs/UmbracoCms.Web.nuspec | 1 - src/Umbraco.Core/Umbraco.Core.csproj | 2 +- .../Models/Mapping/AutoMapper6Tests.cs | 6 +-- src/Umbraco.Tests/Umbraco.Tests.csproj | 2 +- src/Umbraco.Web.UI/Umbraco.Web.UI.csproj | 2 +- .../Models/Mapping/CodeFileMapperProfile.cs | 2 +- .../Models/Mapping/ContentMapperProfile.cs | 40 +++++++++---------- .../Mapping/ContentPropertyMapperProfile.cs | 2 +- .../Mapping/ContentTypeMapperProfile.cs | 4 +- .../Mapping/ContentTypeProfileExtensions.cs | 10 ++--- .../Models/Mapping/DataTypeMapperProfile.cs | 12 +++--- .../Models/Mapping/EntityMapperProfile.cs | 26 ++++++------ .../Models/Mapping/LanguageMapperProfile.cs | 2 +- .../Models/Mapping/MacroMapperProfile.cs | 6 +-- .../Models/Mapping/MediaMapperProfile.cs | 22 +++++----- .../Models/Mapping/MemberMapperProfile.cs | 28 ++++++------- .../Models/Mapping/UserMapperProfile.cs | 18 ++++----- src/Umbraco.Web/Umbraco.Web.csproj | 2 +- 19 files changed, 94 insertions(+), 95 deletions(-) diff --git a/build/NuSpecs/UmbracoCms.Core.nuspec b/build/NuSpecs/UmbracoCms.Core.nuspec index c5e891bd01..60b91af7e6 100644 --- a/build/NuSpecs/UmbracoCms.Core.nuspec +++ b/build/NuSpecs/UmbracoCms.Core.nuspec @@ -20,7 +20,7 @@ the latter would pick anything below 3.0.0 and that includes prereleases such as 3.0.0-alpha, and we do not want this to happen as the alpha of the next major is, really, the next major already. --> - + diff --git a/build/NuSpecs/UmbracoCms.Web.nuspec b/build/NuSpecs/UmbracoCms.Web.nuspec index 140284e29c..4ea0b7b07d 100644 --- a/build/NuSpecs/UmbracoCms.Web.nuspec +++ b/build/NuSpecs/UmbracoCms.Web.nuspec @@ -21,7 +21,6 @@ not want this to happen as the alpha of the next major is, really, the next major already. --> - diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index e77cacbba2..9135c6bf98 100755 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -55,7 +55,7 @@ - + diff --git a/src/Umbraco.Tests/Models/Mapping/AutoMapper6Tests.cs b/src/Umbraco.Tests/Models/Mapping/AutoMapper6Tests.cs index 59c514f654..18bceaae49 100644 --- a/src/Umbraco.Tests/Models/Mapping/AutoMapper6Tests.cs +++ b/src/Umbraco.Tests/Models/Mapping/AutoMapper6Tests.cs @@ -121,16 +121,16 @@ namespace Umbraco.Tests.Models.Mapping break; case 1: map - .ForMember(dest => dest.ValueString, opt => opt.ResolveUsing(src => src.ValueString)); + .ForMember(dest => dest.ValueString, opt => opt.MapFrom(src => src.ValueString)); break; case 2: map - .ForMember(dest => dest.ValueString, opt => opt.ResolveUsing()); + .ForMember(dest => dest.ValueString, opt => opt.MapFrom()); break; case 3: // in most cases that should be perfectly enough? map - .ForMember(dest => dest.ValueString, opt => opt.ResolveUsing(source => "!!" + source.ValueString + "!!")); + .ForMember(dest => dest.ValueString, opt => opt.MapFrom(source => "!!" + source.ValueString + "!!")); break; default: throw new ArgumentOutOfRangeException(nameof(ver)); diff --git a/src/Umbraco.Tests/Umbraco.Tests.csproj b/src/Umbraco.Tests/Umbraco.Tests.csproj index 5d056ee0f8..8dfad73b8a 100644 --- a/src/Umbraco.Tests/Umbraco.Tests.csproj +++ b/src/Umbraco.Tests/Umbraco.Tests.csproj @@ -78,7 +78,7 @@ - + diff --git a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj index 0ce5e97c0a..1a4eeb3bbd 100644 --- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj +++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj @@ -83,7 +83,7 @@ - + diff --git a/src/Umbraco.Web/Models/Mapping/CodeFileMapperProfile.cs b/src/Umbraco.Web/Models/Mapping/CodeFileMapperProfile.cs index b3f5f0374c..563935676f 100644 --- a/src/Umbraco.Web/Models/Mapping/CodeFileMapperProfile.cs +++ b/src/Umbraco.Web/Models/Mapping/CodeFileMapperProfile.cs @@ -14,7 +14,7 @@ namespace Umbraco.Web.Models.Mapping .ForMember(dest => dest.Alias, opt => opt.MapFrom(sheet => sheet.Alias)) .ForMember(dest => dest.Key, opt => opt.MapFrom(sheet => sheet.Key)) .ForMember(dest => dest.Name, opt => opt.MapFrom(sheet => sheet.Name)) - .ForMember(dest => dest.ParentId, opt => opt.UseValue(-1)) + .ForMember(dest => dest.ParentId, opt => opt.MapFrom(_ => -1)) .ForMember(dest => dest.Path, opt => opt.MapFrom(sheet => sheet.Path)) .ForMember(dest => dest.Trashed, opt => opt.Ignore()) .ForMember(dest => dest.AdditionalData, opt => opt.Ignore()) diff --git a/src/Umbraco.Web/Models/Mapping/ContentMapperProfile.cs b/src/Umbraco.Web/Models/Mapping/ContentMapperProfile.cs index 55b1672b2b..652ac12014 100644 --- a/src/Umbraco.Web/Models/Mapping/ContentMapperProfile.cs +++ b/src/Umbraco.Web/Models/Mapping/ContentMapperProfile.cs @@ -41,53 +41,53 @@ namespace Umbraco.Web.Models.Mapping //FROM IContent TO ContentItemDisplay CreateMap() .ForMember(dest => dest.Udi, opt => opt.MapFrom(src => Udi.Create(src.Blueprint ? Constants.UdiEntityType.DocumentBlueprint : Constants.UdiEntityType.Document, src.Key))) - .ForMember(dest => dest.Owner, opt => opt.ResolveUsing(src => contentOwnerResolver.Resolve(src))) - .ForMember(dest => dest.Updater, opt => opt.ResolveUsing(src => creatorResolver.Resolve(src))) - .ForMember(dest => dest.Variants, opt => opt.ResolveUsing(variantResolver)) - .ForMember(dest => dest.ContentApps, opt => opt.ResolveUsing(contentAppResolver)) + .ForMember(dest => dest.Owner, opt => opt.MapFrom(src => contentOwnerResolver.Resolve(src))) + .ForMember(dest => dest.Updater, opt => opt.MapFrom(src => creatorResolver.Resolve(src))) + .ForMember(dest => dest.Variants, opt => opt.MapFrom(variantResolver)) + .ForMember(dest => dest.ContentApps, opt => opt.MapFrom(contentAppResolver)) .ForMember(dest => dest.Icon, opt => opt.MapFrom(src => src.ContentType.Icon)) .ForMember(dest => dest.ContentTypeAlias, opt => opt.MapFrom(src => src.ContentType.Alias)) .ForMember(dest => dest.ContentTypeName, opt => opt.MapFrom(src => src.ContentType.Name)) .ForMember(dest => dest.IsContainer, opt => opt.MapFrom(src => src.ContentType.IsContainer)) .ForMember(dest => dest.IsElement, opt => opt.MapFrom(src => src.ContentType.IsElement)) .ForMember(dest => dest.IsBlueprint, opt => opt.MapFrom(src => src.Blueprint)) - .ForMember(dest => dest.IsChildOfListView, opt => opt.ResolveUsing(childOfListViewResolver)) + .ForMember(dest => dest.IsChildOfListView, opt => opt.MapFrom(childOfListViewResolver)) .ForMember(dest => dest.Trashed, opt => opt.MapFrom(src => src.Trashed)) - .ForMember(dest => dest.TemplateAlias, opt => opt.ResolveUsing(defaultTemplateResolver)) - .ForMember(dest => dest.Urls, opt => opt.ResolveUsing(contentUrlResolver)) + .ForMember(dest => dest.TemplateAlias, opt => opt.MapFrom(defaultTemplateResolver)) + .ForMember(dest => dest.Urls, opt => opt.MapFrom(contentUrlResolver)) .ForMember(dest => dest.AllowPreview, opt => opt.Ignore()) - .ForMember(dest => dest.TreeNodeUrl, opt => opt.ResolveUsing(contentTreeNodeUrlResolver)) + .ForMember(dest => dest.TreeNodeUrl, opt => opt.MapFrom(contentTreeNodeUrlResolver)) .ForMember(dest => dest.Notifications, opt => opt.Ignore()) .ForMember(dest => dest.Errors, opt => opt.Ignore()) - .ForMember(dest => dest.DocumentType, opt => opt.ResolveUsing(contentTypeBasicResolver)) - .ForMember(dest => dest.AllowedTemplates, opt => opt.ResolveUsing(allowedTemplatesResolver)) - .ForMember(dest => dest.AllowedActions, opt => opt.ResolveUsing(src => actionButtonsResolver.Resolve(src))) + .ForMember(dest => dest.DocumentType, opt => opt.MapFrom(contentTypeBasicResolver)) + .ForMember(dest => dest.AllowedTemplates, opt => opt.MapFrom(allowedTemplatesResolver)) + .ForMember(dest => dest.AllowedActions, opt => opt.MapFrom(src => actionButtonsResolver.Resolve(src))) .ForMember(dest => dest.AdditionalData, opt => opt.Ignore()); CreateMap() .ForMember(dest => dest.PublishDate, opt => opt.MapFrom(src => src.PublishDate)) - .ForMember(dest => dest.ReleaseDate, opt => opt.ResolveUsing(schedPublishReleaseDateResolver)) - .ForMember(dest => dest.ExpireDate, opt => opt.ResolveUsing(schedPublishExpireDateResolver)) + .ForMember(dest => dest.ReleaseDate, opt => opt.MapFrom(schedPublishReleaseDateResolver)) + .ForMember(dest => dest.ExpireDate, opt => opt.MapFrom(schedPublishExpireDateResolver)) .ForMember(dest => dest.Segment, opt => opt.Ignore()) .ForMember(dest => dest.Language, opt => opt.Ignore()) .ForMember(dest => dest.Notifications, opt => opt.Ignore()) - .ForMember(dest => dest.State, opt => opt.ResolveUsing>()) - .ForMember(dest => dest.Tabs, opt => opt.ResolveUsing(tabsAndPropertiesResolver)); + .ForMember(dest => dest.State, opt => opt.MapFrom>()) + .ForMember(dest => dest.Tabs, opt => opt.MapFrom(tabsAndPropertiesResolver)); //FROM IContent TO ContentItemBasic CreateMap>() .ForMember(dest => dest.Udi, opt => opt.MapFrom(src => Udi.Create(src.Blueprint ? Constants.UdiEntityType.DocumentBlueprint : Constants.UdiEntityType.Document, src.Key))) - .ForMember(dest => dest.Owner, opt => opt.ResolveUsing(src => contentOwnerResolver.Resolve(src))) - .ForMember(dest => dest.Updater, opt => opt.ResolveUsing(src => creatorResolver.Resolve(src))) + .ForMember(dest => dest.Owner, opt => opt.MapFrom(src => contentOwnerResolver.Resolve(src))) + .ForMember(dest => dest.Updater, opt => opt.MapFrom(src => creatorResolver.Resolve(src))) .ForMember(dest => dest.Icon, opt => opt.MapFrom(src => src.ContentType.Icon)) .ForMember(dest => dest.Trashed, opt => opt.MapFrom(src => src.Trashed)) .ForMember(dest => dest.ContentTypeAlias, opt => opt.MapFrom(src => src.ContentType.Alias)) .ForMember(dest => dest.Alias, opt => opt.Ignore()) .ForMember(dest => dest.AdditionalData, opt => opt.Ignore()) - .ForMember(dest => dest.UpdateDate, opt => opt.ResolveUsing()) - .ForMember(dest => dest.Name, opt => opt.ResolveUsing()) - .ForMember(dest => dest.State, opt => opt.ResolveUsing>()) + .ForMember(dest => dest.UpdateDate, opt => opt.MapFrom()) + .ForMember(dest => dest.Name, opt => opt.MapFrom()) + .ForMember(dest => dest.State, opt => opt.MapFrom>()) .ForMember(dest => dest.VariesByCulture, opt => opt.MapFrom(src => src.ContentType.VariesByCulture())); //FROM IContent TO ContentPropertyCollectionDto diff --git a/src/Umbraco.Web/Models/Mapping/ContentPropertyMapperProfile.cs b/src/Umbraco.Web/Models/Mapping/ContentPropertyMapperProfile.cs index 0b086afb2d..f9ed72fc11 100644 --- a/src/Umbraco.Web/Models/Mapping/ContentPropertyMapperProfile.cs +++ b/src/Umbraco.Web/Models/Mapping/ContentPropertyMapperProfile.cs @@ -22,7 +22,7 @@ namespace Umbraco.Web.Models.Mapping //FROM Property TO ContentPropertyBasic CreateMap>() .ForMember(tab => tab.Label, expression => expression.MapFrom(@group => @group.Name)) - .ForMember(tab => tab.IsActive, expression => expression.UseValue(true)) + .ForMember(tab => tab.IsActive, expression => expression.MapFrom(_ => true)) .ForMember(tab => tab.Properties, expression => expression.Ignore()) .ForMember(tab => tab.Alias, expression => expression.Ignore()) .ForMember(tab => tab.Expanded, expression => expression.Ignore()); diff --git a/src/Umbraco.Web/Models/Mapping/ContentTypeMapperProfile.cs b/src/Umbraco.Web/Models/Mapping/ContentTypeMapperProfile.cs index 88bf409737..ee78c692ff 100644 --- a/src/Umbraco.Web/Models/Mapping/ContentTypeMapperProfile.cs +++ b/src/Umbraco.Web/Models/Mapping/ContentTypeMapperProfile.cs @@ -153,7 +153,7 @@ namespace Umbraco.Web.Models.Mapping CreateMap() - .ConstructUsing(propertyTypeBasic => + .ConstructUsing((propertyTypeBasic, context) => { var dataType = dataTypeService.GetDataType(propertyTypeBasic.DataTypeId); if (dataType == null) throw new NullReferenceException("No data type found with id " + propertyTypeBasic.DataTypeId); @@ -168,7 +168,7 @@ namespace Umbraco.Web.Models.Mapping .ForMember(dest => dest.PropertyEditorAlias, opt => opt.Ignore()) .ForMember(dest => dest.DeleteDate, opt => opt.Ignore()) - .ForMember(dto => dto.Variations, opt => opt.ResolveUsing()) + .ForMember(dto => dto.Variations, opt => opt.MapFrom()) //only map if it is actually set .ForMember(dest => dest.Id, opt => opt.Condition(source => source.Id > 0)) diff --git a/src/Umbraco.Web/Models/Mapping/ContentTypeProfileExtensions.cs b/src/Umbraco.Web/Models/Mapping/ContentTypeProfileExtensions.cs index 0181fc25be..b44cafa280 100644 --- a/src/Umbraco.Web/Models/Mapping/ContentTypeProfileExtensions.cs +++ b/src/Umbraco.Web/Models/Mapping/ContentTypeProfileExtensions.cs @@ -114,7 +114,7 @@ namespace Umbraco.Web.Models.Mapping .ForMember(dest => dest.Notifications, opt => opt.Ignore()) .ForMember(dest => dest.Errors, opt => opt.Ignore()) .ForMember(dest => dest.LockedCompositeContentTypes, opt => opt.Ignore()) - .ForMember(dest => dest.Groups, opt => opt.ResolveUsing(src => propertyGroupDisplayResolver.Resolve(src))); + .ForMember(dest => dest.Groups, opt => opt.MapFrom(src => propertyGroupDisplayResolver.Resolve(src))); } public static IMappingExpression MapBaseContentTypeEntityToDisplay( @@ -129,7 +129,7 @@ namespace Umbraco.Web.Models.Mapping var propertyTypeGroupResolver = new PropertyTypeGroupResolver(propertyEditors, dataTypeService); return mapping - .ForMember(dest => dest.Udi, opt => opt.ResolveUsing(src => contentTypeUdiResolver.Resolve(src))) + .ForMember(dest => dest.Udi, opt => opt.MapFrom(src => contentTypeUdiResolver.Resolve(src))) .ForMember(dest => dest.Notifications, opt => opt.Ignore()) .ForMember(dest => dest.Blueprints, opt => opt.Ignore()) .ForMember(dest => dest.Errors, opt => opt.Ignore()) @@ -140,8 +140,8 @@ namespace Umbraco.Web.Models.Mapping .ForMember(dest => dest.AllowedContentTypes, opt => opt.MapFrom(src => src.AllowedContentTypes.Select(x => x.Id.Value))) .ForMember(dest => dest.CompositeContentTypes, opt => opt.MapFrom(src => src.ContentTypeComposition)) - .ForMember(dest => dest.LockedCompositeContentTypes, opt => opt.ResolveUsing(src => lockedCompositionsResolver.Resolve(src))) - .ForMember(dest => dest.Groups, opt => opt.ResolveUsing(src => propertyTypeGroupResolver.Resolve(src))) + .ForMember(dest => dest.LockedCompositeContentTypes, opt => opt.MapFrom(src => lockedCompositionsResolver.Resolve(src))) + .ForMember(dest => dest.Groups, opt => opt.MapFrom(src => propertyTypeGroupResolver.Resolve(src))) .ForMember(dest => dest.AdditionalData, opt => opt.Ignore()); } @@ -184,7 +184,7 @@ namespace Umbraco.Web.Models.Mapping // ignore for members mapping = typeof(TDestination) == typeof(IMemberType) ? mapping.ForMember(dto => dto.Variations, opt => opt.Ignore()) - : mapping.ForMember(dto => dto.Variations, opt => opt.ResolveUsing>()); + : mapping.ForMember(dto => dto.Variations, opt => opt.MapFrom>()); mapping = mapping .ForMember( diff --git a/src/Umbraco.Web/Models/Mapping/DataTypeMapperProfile.cs b/src/Umbraco.Web/Models/Mapping/DataTypeMapperProfile.cs index 425e447c9c..f707003ffe 100644 --- a/src/Umbraco.Web/Models/Mapping/DataTypeMapperProfile.cs +++ b/src/Umbraco.Web/Models/Mapping/DataTypeMapperProfile.cs @@ -68,8 +68,8 @@ namespace Umbraco.Web.Models.Mapping CreateMap() .ForMember(dest => dest.Udi, opt => opt.MapFrom(src => Udi.Create(Constants.UdiEntityType.DataType, src.Key))) - .ForMember(dest => dest.AvailableEditors, opt => opt.ResolveUsing(src => availablePropertyEditorsResolver.Resolve(src))) - .ForMember(dest => dest.PreValues, opt => opt.ResolveUsing(src => configurationDisplayResolver.Resolve(src))) + .ForMember(dest => dest.AvailableEditors, opt => opt.MapFrom(src => availablePropertyEditorsResolver.Resolve(src))) + .ForMember(dest => dest.PreValues, opt => opt.MapFrom(src => configurationDisplayResolver.Resolve(src))) .ForMember(dest => dest.SelectedEditor, opt => opt.MapFrom(src => src.EditorAlias.IsNullOrWhiteSpace() ? null : src.EditorAlias)) .ForMember(dest => dest.HasPrevalues, opt => opt.Ignore()) .ForMember(dest => dest.Notifications, opt => opt.Ignore()) @@ -92,13 +92,13 @@ namespace Umbraco.Web.Models.Mapping .ConvertUsing(src => configurationDisplayResolver.Resolve(src)); CreateMap() - .ConstructUsing(src => new DataType(propertyEditors[src.EditorAlias]) {CreateDate = DateTime.Now}) + .ConstructUsing(src => new DataType(propertyEditors[src.EditorAlias], -1) {CreateDate = DateTime.Now}) .IgnoreEntityCommonProperties() .ForMember(dest => dest.Id, opt => opt.MapFrom(src => Convert.ToInt32(src.Id))) .ForMember(dest => dest.Key, opt => opt.Ignore()) // ignore key, else resets UniqueId - U4-3911 .ForMember(dest => dest.Path, opt => opt.Ignore()) .ForMember(dest => dest.EditorAlias, opt => opt.MapFrom(src => src.EditorAlias)) - .ForMember(dest => dest.DatabaseType, opt => opt.ResolveUsing(src => databaseTypeResolver.Resolve(src))) + .ForMember(dest => dest.DatabaseType, opt => opt.MapFrom(src => databaseTypeResolver.Resolve(src))) .ForMember(dest => dest.CreatorId, opt => opt.Ignore()) .ForMember(dest => dest.Level, opt => opt.Ignore()) .ForMember(dest => dest.SortOrder, opt => opt.Ignore()) @@ -107,14 +107,14 @@ namespace Umbraco.Web.Models.Mapping //Converts a property editor to a new list of pre-value fields - used when creating a new data type or changing a data type with new pre-vals CreateMap>() - .ConvertUsing(src => + .ConvertUsing((dataEditor, configurationFieldDisplays) => { // this is a new data type, initialize default configuration // get the configuration editor, // get the configuration fields and map to UI, // get the configuration default values and map to UI - var configurationEditor = src.GetConfigurationEditor(); + var configurationEditor = dataEditor.GetConfigurationEditor(); var fields = configurationEditor.Fields.Select(Mapper.Map).ToArray(); diff --git a/src/Umbraco.Web/Models/Mapping/EntityMapperProfile.cs b/src/Umbraco.Web/Models/Mapping/EntityMapperProfile.cs index 90e98822b1..ab3929166f 100644 --- a/src/Umbraco.Web/Models/Mapping/EntityMapperProfile.cs +++ b/src/Umbraco.Web/Models/Mapping/EntityMapperProfile.cs @@ -25,7 +25,7 @@ namespace Umbraco.Web.Models.Mapping var contentTypeUdiResolver = new ContentTypeUdiResolver(); CreateMap() - .ForMember(dest => dest.Name, opt => opt.ResolveUsing()) + .ForMember(dest => dest.Name, opt => opt.MapFrom()) .ForMember(dest => dest.Udi, opt => opt.MapFrom(src => Udi.Create(ObjectTypes.GetUdiType(src.NodeObjectType), src.Key))) .ForMember(dest => dest.Icon, opt => opt.MapFrom(src => GetContentTypeIcon(src))) .ForMember(dest => dest.Trashed, opt => opt.MapFrom(src => src.Trashed)) @@ -42,17 +42,17 @@ namespace Umbraco.Web.Models.Mapping CreateMap() .ForMember(dest => dest.Udi, opt => opt.Ignore()) - .ForMember(dest => dest.Icon, opt => opt.UseValue("icon-box")) - .ForMember(dest => dest.Path, opt => opt.UseValue("")) - .ForMember(dest => dest.ParentId, opt => opt.UseValue(-1)) + .ForMember(dest => dest.Icon, opt => opt.MapFrom(_ => "icon-box")) + .ForMember(dest => dest.Path, opt => opt.MapFrom(_ => "")) + .ForMember(dest => dest.ParentId, opt => opt.MapFrom(_ => -1)) .ForMember(dest => dest.Trashed, opt => opt.Ignore()) .ForMember(dest => dest.AdditionalData, opt => opt.Ignore()); CreateMap() .ForMember(dest => dest.Udi, opt => opt.Ignore()) - .ForMember(dest => dest.Icon, opt => opt.UseValue("icon-tab")) - .ForMember(dest => dest.Path, opt => opt.UseValue("")) - .ForMember(dest => dest.ParentId, opt => opt.UseValue(-1)) + .ForMember(dest => dest.Icon, opt => opt.MapFrom(_ => "icon-tab")) + .ForMember(dest => dest.Path, opt => opt.MapFrom(_ => "")) + .ForMember(dest => dest.ParentId, opt => opt.MapFrom(_ => -1)) //in v6 the 'alias' is it's lower cased name so we'll stick to that. .ForMember(dest => dest.Alias, opt => opt.MapFrom(src => src.Name.ToLowerInvariant())) .ForMember(dest => dest.Trashed, opt => opt.Ignore()) @@ -60,18 +60,18 @@ namespace Umbraco.Web.Models.Mapping CreateMap() .ForMember(dest => dest.Udi, opt => opt.Ignore()) - .ForMember(dest => dest.Icon, opt => opt.UseValue("icon-user")) - .ForMember(dest => dest.Path, opt => opt.UseValue("")) - .ForMember(dest => dest.ParentId, opt => opt.UseValue(-1)) + .ForMember(dest => dest.Icon, opt => opt.MapFrom(_ => "icon-user")) + .ForMember(dest => dest.Path, opt => opt.MapFrom(_ => "")) + .ForMember(dest => dest.ParentId, opt => opt.MapFrom(_ => -1)) .ForMember(dest => dest.Alias, opt => opt.MapFrom(src => src.Username)) .ForMember(dest => dest.Trashed, opt => opt.Ignore()) .ForMember(dest => dest.AdditionalData, opt => opt.Ignore()); CreateMap() .ForMember(dest => dest.Udi, opt => opt.MapFrom(src => Udi.Create(Constants.UdiEntityType.Template, src.Key))) - .ForMember(dest => dest.Icon, opt => opt.UseValue("icon-layout")) + .ForMember(dest => dest.Icon, opt => opt.MapFrom(_ => "icon-layout")) .ForMember(dest => dest.Path, opt => opt.MapFrom(src => src.Path)) - .ForMember(dest => dest.ParentId, opt => opt.UseValue(-1)) + .ForMember(dest => dest.ParentId, opt => opt.MapFrom(_ => -1)) .ForMember(dest => dest.Trashed, opt => opt.Ignore()) .ForMember(dest => dest.AdditionalData, opt => opt.Ignore()); @@ -80,7 +80,7 @@ namespace Umbraco.Web.Models.Mapping .ForMember(dest => dest.SortOrder, opt => opt.Ignore()); CreateMap() - .ForMember(dest => dest.Udi, opt => opt.ResolveUsing(src => contentTypeUdiResolver.Resolve(src))) + .ForMember(dest => dest.Udi, opt => opt.MapFrom(src => contentTypeUdiResolver.Resolve(src))) .ForMember(dest => dest.Path, opt => opt.MapFrom(src => src.Path)) .ForMember(dest => dest.ParentId, opt => opt.MapFrom(src => src.ParentId)) .ForMember(dest => dest.Trashed, opt => opt.Ignore()) diff --git a/src/Umbraco.Web/Models/Mapping/LanguageMapperProfile.cs b/src/Umbraco.Web/Models/Mapping/LanguageMapperProfile.cs index 13c6af2fda..a838180622 100644 --- a/src/Umbraco.Web/Models/Mapping/LanguageMapperProfile.cs +++ b/src/Umbraco.Web/Models/Mapping/LanguageMapperProfile.cs @@ -17,7 +17,7 @@ namespace Umbraco.Web.Models.Mapping .ForMember(dest => dest.Name, opt => opt.MapFrom(x => x.CultureName)) .ForMember(dest => dest.Key, opt => opt.MapFrom(x => x.Key)) .ForMember(dest => dest.Alias, opt => opt.MapFrom(x => x.IsoCode)) - .ForMember(dest => dest.ParentId, opt => opt.UseValue(-1)) + .ForMember(dest => dest.ParentId, opt => opt.MapFrom(_ => -1)) .ForMember(dest => dest.Path, opt => opt.Ignore()) .ForMember(dest => dest.Trashed, opt => opt.Ignore()) .ForMember(dest => dest.AdditionalData, opt => opt.Ignore()) diff --git a/src/Umbraco.Web/Models/Mapping/MacroMapperProfile.cs b/src/Umbraco.Web/Models/Mapping/MacroMapperProfile.cs index be1bcdefdc..3e0f6c7337 100644 --- a/src/Umbraco.Web/Models/Mapping/MacroMapperProfile.cs +++ b/src/Umbraco.Web/Models/Mapping/MacroMapperProfile.cs @@ -19,9 +19,9 @@ namespace Umbraco.Web.Models.Mapping //FROM IMacro TO EntityBasic CreateMap() .ForMember(x => x.Udi, expression => expression.MapFrom(content => Udi.Create(Constants.UdiEntityType.Macro, content.Key))) - .ForMember(entityBasic => entityBasic.Icon, expression => expression.UseValue("icon-settings-alt")) - .ForMember(dto => dto.ParentId, expression => expression.UseValue(-1)) - .ForMember(dto => dto.Path, expression => expression.ResolveUsing(macro => "-1," + macro.Id)) + .ForMember(entityBasic => entityBasic.Icon, expression => expression.MapFrom(_ => "icon-settings-alt")) + .ForMember(dto => dto.ParentId, expression => expression.MapFrom(_ => -1)) + .ForMember(dto => dto.Path, expression => expression.MapFrom(macro => "-1," + macro.Id)) .ForMember(dto => dto.Trashed, expression => expression.Ignore()) .ForMember(dto => dto.AdditionalData, expression => expression.Ignore()); diff --git a/src/Umbraco.Web/Models/Mapping/MediaMapperProfile.cs b/src/Umbraco.Web/Models/Mapping/MediaMapperProfile.cs index 7a8706edf2..f5182f0b3b 100644 --- a/src/Umbraco.Web/Models/Mapping/MediaMapperProfile.cs +++ b/src/Umbraco.Web/Models/Mapping/MediaMapperProfile.cs @@ -35,37 +35,37 @@ namespace Umbraco.Web.Models.Mapping //FROM IMedia TO MediaItemDisplay CreateMap() .ForMember(dest => dest.Udi, opt => opt.MapFrom(content => Udi.Create(Constants.UdiEntityType.Media, content.Key))) - .ForMember(dest => dest.Owner, opt => opt.ResolveUsing(src => mediaOwnerResolver.Resolve(src))) + .ForMember(dest => dest.Owner, opt => opt.MapFrom(src => mediaOwnerResolver.Resolve(src))) .ForMember(dest => dest.Icon, opt => opt.MapFrom(content => content.ContentType.Icon)) .ForMember(dest => dest.ContentTypeAlias, opt => opt.MapFrom(content => content.ContentType.Alias)) - .ForMember(dest => dest.IsChildOfListView, opt => opt.ResolveUsing(childOfListViewResolver)) + .ForMember(dest => dest.IsChildOfListView, opt => opt.MapFrom(childOfListViewResolver)) .ForMember(dest => dest.Trashed, opt => opt.MapFrom(content => content.Trashed)) .ForMember(dest => dest.ContentTypeName, opt => opt.MapFrom(content => content.ContentType.Name)) .ForMember(dest => dest.Properties, opt => opt.Ignore()) - .ForMember(dest => dest.TreeNodeUrl, opt => opt.ResolveUsing(contentTreeNodeUrlResolver)) + .ForMember(dest => dest.TreeNodeUrl, opt => opt.MapFrom(contentTreeNodeUrlResolver)) .ForMember(dest => dest.Notifications, opt => opt.Ignore()) .ForMember(dest => dest.Errors, opt => opt.Ignore()) - .ForMember(dest => dest.State, opt => opt.UseValue(null)) + .ForMember(dest => dest.State, opt => opt.MapFrom(_ => null)) .ForMember(dest => dest.Edited, opt => opt.Ignore()) .ForMember(dest => dest.Updater, opt => opt.Ignore()) .ForMember(dest => dest.Alias, opt => opt.Ignore()) .ForMember(dest => dest.IsContainer, opt => opt.Ignore()) - .ForMember(dest => dest.Tabs, opt => opt.ResolveUsing(tabsAndPropertiesResolver)) + .ForMember(dest => dest.Tabs, opt => opt.MapFrom(tabsAndPropertiesResolver)) .ForMember(dest => dest.AdditionalData, opt => opt.Ignore()) - .ForMember(dest => dest.ContentType, opt => opt.ResolveUsing(mediaTypeBasicResolver)) - .ForMember(dest => dest.MediaLink, opt => opt.ResolveUsing(content => string.Join(",", content.GetUrls(Current.Configs.Settings().Content, logger)))) - .ForMember(dest => dest.ContentApps, opt => opt.ResolveUsing(mediaAppResolver)) + .ForMember(dest => dest.ContentType, opt => opt.MapFrom(mediaTypeBasicResolver)) + .ForMember(dest => dest.MediaLink, opt => opt.MapFrom(content => string.Join(",", content.GetUrls(Current.Configs.Settings().Content, logger)))) + .ForMember(dest => dest.ContentApps, opt => opt.MapFrom(mediaAppResolver)) .ForMember(dest => dest.VariesByCulture, opt => opt.MapFrom(src => src.ContentType.VariesByCulture())); //FROM IMedia TO ContentItemBasic CreateMap>() .ForMember(dest => dest.Udi, opt => opt.MapFrom(src => Udi.Create(Constants.UdiEntityType.Media, src.Key))) - .ForMember(dest => dest.Owner, opt => opt.ResolveUsing(src => mediaOwnerResolver.Resolve(src))) + .ForMember(dest => dest.Owner, opt => opt.MapFrom(src => mediaOwnerResolver.Resolve(src))) .ForMember(dest => dest.Icon, opt => opt.MapFrom(src => src.ContentType.Icon)) .ForMember(dest => dest.Trashed, opt => opt.MapFrom(src => src.Trashed)) .ForMember(dest => dest.ContentTypeAlias, opt => opt.MapFrom(src => src.ContentType.Alias)) - .ForMember(dest => dest.State, opt => opt.UseValue(null)) + .ForMember(dest => dest.State, opt => opt.MapFrom(_ => null)) .ForMember(dest => dest.Edited, opt => opt.Ignore()) .ForMember(dest => dest.Updater, opt => opt.Ignore()) .ForMember(dest => dest.Alias, opt => opt.Ignore()) @@ -76,7 +76,7 @@ namespace Umbraco.Web.Models.Mapping //FROM IMedia TO ContentItemDto CreateMap(); //.ForMember(dest => dest.Udi, opt => opt.MapFrom(src => Udi.Create(Constants.UdiEntityType.Media, src.Key))) - //.ForMember(dest => dest.Owner, opt => opt.ResolveUsing(src => mediaOwnerResolver.Resolve(src))) + //.ForMember(dest => dest.Owner, opt => opt.MapFrom(src => mediaOwnerResolver.Resolve(src))) //.ForMember(dest => dest.Published, opt => opt.Ignore()) //.ForMember(dest => dest.Edited, opt => opt.Ignore()) //.ForMember(dest => dest.Updater, opt => opt.Ignore()) diff --git a/src/Umbraco.Web/Models/Mapping/MemberMapperProfile.cs b/src/Umbraco.Web/Models/Mapping/MemberMapperProfile.cs index dbdac1f91f..a651ba33af 100644 --- a/src/Umbraco.Web/Models/Mapping/MemberMapperProfile.cs +++ b/src/Umbraco.Web/Models/Mapping/MemberMapperProfile.cs @@ -63,24 +63,24 @@ namespace Umbraco.Web.Models.Mapping //FROM IMember TO MemberDisplay CreateMap() .ForMember(dest => dest.Udi, opt => opt.MapFrom(content => Udi.Create(Constants.UdiEntityType.Member, content.Key))) - .ForMember(dest => dest.Owner, opt => opt.ResolveUsing(src => memberOwnerResolver.Resolve(src))) + .ForMember(dest => dest.Owner, opt => opt.MapFrom(src => memberOwnerResolver.Resolve(src))) .ForMember(dest => dest.Icon, opt => opt.MapFrom(src => src.ContentType.Icon)) .ForMember(dest => dest.ContentTypeAlias, opt => opt.MapFrom(src => src.ContentType.Alias)) .ForMember(dest => dest.ContentTypeName, opt => opt.MapFrom(src => src.ContentType.Name)) .ForMember(dest => dest.Properties, opt => opt.Ignore()) - .ForMember(dest => dest.Tabs, opt => opt.ResolveUsing(tabsAndPropertiesResolver)) - .ForMember(dest => dest.MemberProviderFieldMapping, opt => opt.ResolveUsing(src => memberProfiderFieldMappingResolver.Resolve(src))) - .ForMember(dest => dest.MembershipScenario, opt => opt.ResolveUsing(src => membershipScenarioMappingResolver.Resolve(src))) + .ForMember(dest => dest.Tabs, opt => opt.MapFrom(tabsAndPropertiesResolver)) + .ForMember(dest => dest.MemberProviderFieldMapping, opt => opt.MapFrom(src => memberProfiderFieldMappingResolver.Resolve(src))) + .ForMember(dest => dest.MembershipScenario, opt => opt.MapFrom(src => membershipScenarioMappingResolver.Resolve(src))) .ForMember(dest => dest.Notifications, opt => opt.Ignore()) .ForMember(dest => dest.Errors, opt => opt.Ignore()) - .ForMember(dest => dest.State, opt => opt.UseValue(null)) + .ForMember(dest => dest.State, opt => opt.MapFrom(_ => null)) .ForMember(dest => dest.Edited, opt => opt.Ignore()) .ForMember(dest => dest.Updater, opt => opt.Ignore()) .ForMember(dest => dest.Alias, opt => opt.Ignore()) .ForMember(dest => dest.IsChildOfListView, opt => opt.Ignore()) .ForMember(dest => dest.Trashed, opt => opt.Ignore()) .ForMember(dest => dest.IsContainer, opt => opt.Ignore()) - .ForMember(dest => dest.TreeNodeUrl, opt => opt.ResolveUsing(memberTreeNodeUrlResolver)) + .ForMember(dest => dest.TreeNodeUrl, opt => opt.MapFrom(memberTreeNodeUrlResolver)) .ForMember(dest => dest.VariesByCulture, opt => opt.Ignore()); //FROM IMember TO MemberBasic @@ -88,17 +88,17 @@ namespace Umbraco.Web.Models.Mapping //we're giving this entity an ID of int.MaxValue - this is kind of a hack to force angular to use the Key instead of the Id in list views .ForMember(dest => dest.Id, opt => opt.MapFrom(src => int.MaxValue)) .ForMember(dest => dest.Udi, opt => opt.MapFrom(content => Udi.Create(Constants.UdiEntityType.Member, content.Key))) - .ForMember(dest => dest.Owner, opt => opt.ResolveUsing(src => memberOwnerResolver.Resolve(src))) + .ForMember(dest => dest.Owner, opt => opt.MapFrom(src => memberOwnerResolver.Resolve(src))) .ForMember(dest => dest.Icon, opt => opt.MapFrom(src => src.ContentType.Icon)) .ForMember(dest => dest.ContentTypeAlias, opt => opt.MapFrom(src => src.ContentType.Alias)) .ForMember(dest => dest.Email, opt => opt.MapFrom(src => src.Email)) .ForMember(dest => dest.Username, opt => opt.MapFrom(src => src.Username)) .ForMember(dest => dest.Trashed, opt => opt.Ignore()) - .ForMember(dest => dest.State, opt => opt.UseValue(null)) + .ForMember(dest => dest.State, opt => opt.MapFrom(_ => null)) .ForMember(dest => dest.Edited, opt => opt.Ignore()) .ForMember(dest => dest.Updater, opt => opt.Ignore()) .ForMember(dest => dest.Alias, opt => opt.Ignore()) - .ForMember(dto => dto.Properties, expression => expression.ResolveUsing(memberBasicPropertiesResolver)) + .ForMember(dto => dto.Properties, expression => expression.MapFrom(memberBasicPropertiesResolver)) .ForMember(dest => dest.VariesByCulture, opt => opt.Ignore()); //FROM MembershipUser TO MemberBasic @@ -109,8 +109,8 @@ namespace Umbraco.Web.Models.Mapping .ForMember(dest => dest.CreateDate, opt => opt.MapFrom(src => src.CreationDate)) .ForMember(dest => dest.UpdateDate, opt => opt.MapFrom(src => src.LastActivityDate)) .ForMember(dest => dest.Key, opt => opt.MapFrom(src => src.ProviderUserKey.TryConvertTo().Result.ToString("N"))) - .ForMember(dest => dest.Owner, opt => opt.UseValue(new UserProfile {Name = "Admin", UserId = -1 })) - .ForMember(dest => dest.Icon, opt => opt.UseValue("icon-user")) + .ForMember(dest => dest.Owner, opt => opt.MapFrom(_ => new UserProfile {Name = "Admin", UserId = -1 })) + .ForMember(dest => dest.Icon, opt => opt.MapFrom(_ => "icon-user")) .ForMember(dest => dest.Name, opt => opt.MapFrom(src => src.UserName)) .ForMember(dest => dest.Email, opt => opt.MapFrom(src => src.Email)) .ForMember(dest => dest.Username, opt => opt.MapFrom(src => src.UserName)) @@ -119,7 +119,7 @@ namespace Umbraco.Web.Models.Mapping .ForMember(dest => dest.Path, opt => opt.Ignore()) .ForMember(dest => dest.SortOrder, opt => opt.Ignore()) .ForMember(dest => dest.AdditionalData, opt => opt.Ignore()) - .ForMember(dest => dest.State, opt => opt.UseValue(ContentSavedState.Draft)) + .ForMember(dest => dest.State, opt => opt.MapFrom(_ => ContentSavedState.Draft)) .ForMember(dest => dest.Edited, opt => opt.Ignore()) .ForMember(dest => dest.Updater, opt => opt.Ignore()) .ForMember(dest => dest.Trashed, opt => opt.Ignore()) @@ -130,14 +130,14 @@ namespace Umbraco.Web.Models.Mapping //FROM IMember TO ContentItemDto CreateMap() //.ForMember(dest => dest.Udi, opt => opt.MapFrom(content => Udi.Create(Constants.UdiEntityType.Member, content.Key))) - //.ForMember(dest => dest.Owner, opt => opt.ResolveUsing(src => memberOwnerResolver.Resolve(src))) + //.ForMember(dest => dest.Owner, opt => opt.MapFrom(src => memberOwnerResolver.Resolve(src))) //.ForMember(dest => dest.Published, opt => opt.Ignore()) //.ForMember(dest => dest.Edited, opt => opt.Ignore()) //.ForMember(dest => dest.Updater, opt => opt.Ignore()) //.ForMember(dest => dest.Icon, opt => opt.Ignore()) //.ForMember(dest => dest.Alias, opt => opt.Ignore()) //do no map the custom member properties (currently anyways, they were never there in 6.x) - .ForMember(dest => dest.Properties, opt => opt.ResolveUsing(src => memberDtoPropertiesResolver.Resolve(src))); + .ForMember(dest => dest.Properties, opt => opt.MapFrom(src => memberDtoPropertiesResolver.Resolve(src))); //FROM IMemberGroup TO MemberGroupDisplay CreateMap() diff --git a/src/Umbraco.Web/Models/Mapping/UserMapperProfile.cs b/src/Umbraco.Web/Models/Mapping/UserMapperProfile.cs index 6f3af3b812..84660d2602 100644 --- a/src/Umbraco.Web/Models/Mapping/UserMapperProfile.cs +++ b/src/Umbraco.Web/Models/Mapping/UserMapperProfile.cs @@ -99,7 +99,7 @@ namespace Umbraco.Web.Models.Mapping .ForMember(dest => dest.LastLockoutDate, opt => opt.Ignore()) .ForMember(dest => dest.FailedPasswordAttempts, opt => opt.Ignore()) //all invited users will not be approved, completing the invite will approve the user - .ForMember(user => user.IsApproved, opt => opt.UseValue(false)) + .ForMember(user => user.IsApproved, opt => opt.MapFrom(_ => false)) .AfterMap((invite, user) => { user.ClearGroups(); @@ -119,7 +119,7 @@ namespace Umbraco.Web.Models.Mapping .ForMember(dest => dest.Notifications, opt => opt.Ignore()) .ForMember(dest => dest.Udi, opt => opt.Ignore()) .ForMember(dest => dest.Trashed, opt => opt.Ignore()) - .ForMember(dest => dest.ParentId, opt => opt.UseValue(-1)) + .ForMember(dest => dest.ParentId, opt => opt.MapFrom(_ => -1)) .ForMember(dest => dest.Path, opt => opt.MapFrom(userGroup => "-1," + userGroup.Id)) .ForMember(dest => dest.AdditionalData, opt => opt.Ignore()) .AfterMap((group, display) => @@ -134,7 +134,7 @@ namespace Umbraco.Web.Models.Mapping .ForMember(dest => dest.Notifications, opt => opt.Ignore()) .ForMember(dest => dest.Udi, opt => opt.Ignore()) .ForMember(dest => dest.Trashed, opt => opt.Ignore()) - .ForMember(dest => dest.ParentId, opt => opt.UseValue(-1)) + .ForMember(dest => dest.ParentId, opt => opt.MapFrom(_ => -1)) .ForMember(dest => dest.Path, opt => opt.MapFrom(userGroup => "-1," + userGroup.Id)) .ForMember(dest => dest.AdditionalData, opt => opt.Ignore()) .AfterMap((group, display) => @@ -148,9 +148,9 @@ namespace Umbraco.Web.Models.Mapping .ForMember(dest => dest.Trashed, opt => opt.Ignore()) .ForMember(dest => dest.AdditionalData, opt => opt.Ignore()) .ForMember(dest => dest.Id, opt => opt.MapFrom(group => group.Id)) - .ForMember(dest => dest.ParentId, opt => opt.UseValue(-1)) + .ForMember(dest => dest.ParentId, opt => opt.MapFrom(_ => -1)) .ForMember(dest => dest.Path, opt => opt.MapFrom(userGroup => "-1," + userGroup.Id)) - .ForMember(dest => dest.DefaultPermissions, opt => opt.ResolveUsing(src => userGroupDefaultPermissionsResolver.Resolve(src))) + .ForMember(dest => dest.DefaultPermissions, opt => opt.MapFrom(src => userGroupDefaultPermissionsResolver.Resolve(src))) //these will be manually mapped and by default they are null .ForMember(dest => dest.AssignedPermissions, opt => opt.Ignore()) .AfterMap((group, display) => @@ -182,11 +182,11 @@ namespace Umbraco.Web.Models.Mapping .ForMember(dest => dest.Notifications, opt => opt.Ignore()) .ForMember(dest => dest.Udi, opt => opt.Ignore()) .ForMember(dest => dest.Trashed, opt => opt.Ignore()) - .ForMember(dest => dest.ParentId, opt => opt.UseValue(-1)) + .ForMember(dest => dest.ParentId, opt => opt.MapFrom(_ => -1)) .ForMember(dest => dest.Path, opt => opt.MapFrom(userGroup => "-1," + userGroup.Id)) .ForMember(dest => dest.AdditionalData, opt => opt.Ignore()) .ForMember(dest => dest.Users, opt => opt.Ignore()) - .ForMember(dest => dest.DefaultPermissions, opt => opt.ResolveUsing(src => userGroupDefaultPermissionsResolver.Resolve(src))) + .ForMember(dest => dest.DefaultPermissions, opt => opt.MapFrom(src => userGroupDefaultPermissionsResolver.Resolve(src))) .ForMember(dest => dest.AssignedPermissions, opt => opt.Ignore()) .AfterMap((group, display) => { @@ -276,7 +276,7 @@ namespace Umbraco.Web.Models.Mapping .ForMember( dest => dest.EmailHash, opt => opt.MapFrom(user => user.Email.ToLowerInvariant().Trim().GenerateHash())) - .ForMember(dest => dest.ParentId, opt => opt.UseValue(-1)) + .ForMember(dest => dest.ParentId, opt => opt.MapFrom(_ => -1)) .ForMember(dest => dest.Path, opt => opt.MapFrom(user => "-1," + user.Id)) .ForMember(dest => dest.Notifications, opt => opt.Ignore()) .ForMember(dest => dest.Udi, opt => opt.Ignore()) @@ -302,7 +302,7 @@ namespace Umbraco.Web.Models.Mapping .ForMember( dest => dest.EmailHash, opt => opt.MapFrom(user => user.Email.ToLowerInvariant().Trim().ToMd5())) - .ForMember(dest => dest.ParentId, opt => opt.UseValue(-1)) + .ForMember(dest => dest.ParentId, opt => opt.MapFrom(_ => -1)) .ForMember(dest => dest.Path, opt => opt.MapFrom(user => "-1," + user.Id)) .ForMember(dest => dest.Notifications, opt => opt.Ignore()) .ForMember(dest => dest.IsCurrentUser, opt => opt.Ignore()) diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index 8e13d33433..a40f5d20f9 100755 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -60,7 +60,7 @@ - + From 64d2940c3b510a3c218237f6d4d791f042f5cc64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Wed, 6 Feb 2019 11:26:39 +0100 Subject: [PATCH 17/68] refactoring of umb-editor-navigation --- .../umbeditorcontentheader.directive.js | 23 ++- .../editor/umbeditornavigation.directive.js | 4 +- .../umbeditornavigationitem.directive.js | 10 +- src/Umbraco.Web.UI.Client/src/less/belle.less | 1 + .../umb-editor-navigation-item.less | 132 +++++++++++++++++ .../components/umb-editor-navigation.less | 134 ------------------ .../content/umb-variant-content.html | 7 +- .../editor/umb-editor-content-header.html | 8 +- .../editor/umb-editor-navigation-item.html | 3 +- .../editor/umb-editor-navigation.html | 47 +++--- 10 files changed, 188 insertions(+), 181 deletions(-) create mode 100644 src/Umbraco.Web.UI.Client/src/less/components/umb-editor-navigation-item.less diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/editor/umbeditorcontentheader.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/editor/umbeditorcontentheader.directive.js index 0d78aab0eb..0f1aae940d 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/editor/umbeditorcontentheader.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/editor/umbeditorcontentheader.directive.js @@ -11,17 +11,27 @@ if (!scope.serverValidationAliasField) { scope.serverValidationAliasField = "Alias"; } - + scope.vm = {}; scope.vm.dropdownOpen = false; scope.vm.currentVariant = ""; function onInit() { + setCurrentVariant(); + /* + angular.forEach(scope.content.apps, (app) => { + if (app.alias === "umbContent") { + console.log("content app", app) + app.type = "dropdown"; + app.groups = scope.content.tabs; + } + }); + */ } function setCurrentVariant() { - angular.forEach(scope.variants, function (variant) { + angular.forEach(scope.content.variants, function (variant) { if (variant.active) { scope.vm.currentVariant = variant; } @@ -72,10 +82,10 @@ onInit(); //watch for the active culture changing, if it changes, update the current variant - if (scope.variants) { + if (scope.content.variants) { scope.$watch(function () { - for (var i = 0; i < scope.variants.length; i++) { - var v = scope.variants[i]; + for (var i = 0; i < scope.content.variants.length; i++) { + var v = scope.content.variants[i]; if (v.active) { return v.language.culture; } @@ -100,10 +110,9 @@ nameDisabled: " li { + display: flex; +} +.umb-sub-views-nav-item-more__dropdown .umb-sub-views-nav-item:first { + border-left: none; +} diff --git a/src/Umbraco.Web.UI.Client/src/less/components/umb-editor-navigation.less b/src/Umbraco.Web.UI.Client/src/less/components/umb-editor-navigation.less index f4bbeadc3f..985765e53a 100644 --- a/src/Umbraco.Web.UI.Client/src/less/components/umb-editor-navigation.less +++ b/src/Umbraco.Web.UI.Client/src/less/components/umb-editor-navigation.less @@ -4,137 +4,3 @@ margin: 0; border-left: 1px solid @gray-9; } - -.umb-sub-views-nav-item { - text-align: center; - cursor: pointer; - display: block; - padding: 4px 10px 0 10px; - //border-bottom: 4px solid transparent; - min-width: 70px; - border-right: 1px solid @gray-9; - box-sizing: border-box; - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - height: @editorHeaderHeight; - position: relative; - - color: @ui-active-type; - - &:hover { - color: @ui-active-type-hover !important; - } - - &::after { - content: ""; - height: 0px; - left: 8px; - right: 8px; - background-color: @ui-light-active-border; - position: absolute; - bottom: 0; - border-radius: 3px 3px 0 0; - opacity: 0; - transition: all .2s linear; - } -} - -.umb-sub-views-nav-item:focus { - outline: none; -} - -.umb-sub-views-nav-item:hover, -.umb-sub-views-nav-item:focus { - text-decoration: none; -} - -.umb-sub-views-nav-item.is-active { - //color: @ui-active; - //border-bottom-color: @ui-active; - - //background-color: rgba(@ui-active, 0.25); - color: @ui-light-active-type; - //border-bottom-color: @ui-active; - &::after { - opacity: 1; - height: 4px; - } -} - -.show-validation .umb-sub-views-nav-item.-has-error { - color: @red; -} - -.umb-sub-views-nav-item .icon { - font-size: 24px; - display: block; - text-align: center; - margin-bottom: 7px; -} - -.umb-sub-views-nav-item .badge { - position: absolute; - top: 6px; - right: 6px; - min-width: 16px; - color: @white; - background-color: @ui-active-type; - border: 2px solid @white; - border-radius: 50%; - font-size: 10px; - font-weight: bold; - padding: 2px; - line-height: 16px; - display: block; - - &.-type-alert { - background-color: @red; - } - &.-type-warning { - background-color: @yellow-d2; - } - &:empty { - height: 12px; - min-width: 12px; - } -} - -.umb-sub-views-nav-item-text { - font-size: 12px; - line-height: 1em; -} - -.umb-sub-views-nav-item-more__icon { - margin-bottom: 10px; -} - -.umb-sub-views-nav-item-more__icon i { - height: 5px; - width: 5px; - border-radius: 50%; - background: @ui-active-type;// fallback if browser doesnt support currentColor - background: currentColor; - display: inline-block; - margin: 0 5px 0 0; -} - -.umb-sub-views-nav-item-more__icon i:last-of-type { - margin-right: 0; -} - -.umb-sub-views-nav-item-more__dropdown { - left: auto; - right: 0; - display: grid; - grid-template-columns: 1fr 1fr 1fr; - min-width: auto; - margin-top: 10px; -} -.umb-sub-views-nav-item-more__dropdown > li { - display: flex; -} -.umb-sub-views-nav-item-more__dropdown .umb-sub-views-nav-item:first { - border-left: none; -} diff --git a/src/Umbraco.Web.UI.Client/src/views/components/content/umb-variant-content.html b/src/Umbraco.Web.UI.Client/src/views/components/content/umb-variant-content.html index c03b017a82..84928a00bb 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/content/umb-variant-content.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/content/umb-variant-content.html @@ -1,19 +1,18 @@ 
    - -
    +
    diff --git a/src/Umbraco.Web.UI.Client/src/views/components/editor/umb-editor-navigation-item.html b/src/Umbraco.Web.UI.Client/src/views/components/editor/umb-editor-navigation-item.html index 002e9adfc0..329e96242b 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/editor/umb-editor-navigation-item.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/editor/umb-editor-navigation-item.html @@ -1,8 +1,7 @@ diff --git a/src/Umbraco.Web.UI.Client/src/views/components/editor/umb-editor-navigation.html b/src/Umbraco.Web.UI.Client/src/views/components/editor/umb-editor-navigation.html index 1bc7c5ff4a..31388a54f8 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/editor/umb-editor-navigation.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/editor/umb-editor-navigation.html @@ -1,11 +1,11 @@
      -
    • -
      +
    • +
      @@ -13,24 +13,27 @@
    • - -
      - {{ moreButton.name }} -
      +
      - - - - - - + +
      + {{ moreButton.name }} +
      + + + + + + + + +
    • From e556e39cd1f716420d893f4b3fb86d542b48d2bd Mon Sep 17 00:00:00 2001 From: Shannon Date: Wed, 6 Feb 2019 21:31:50 +1100 Subject: [PATCH 18/68] latest HtmlAgility --- build/NuSpecs/UmbracoCms.Web.nuspec | 2 +- src/Umbraco.Tests/Umbraco.Tests.csproj | 2 +- src/Umbraco.Web/Umbraco.Web.csproj | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build/NuSpecs/UmbracoCms.Web.nuspec b/build/NuSpecs/UmbracoCms.Web.nuspec index 4ea0b7b07d..b79b909191 100644 --- a/build/NuSpecs/UmbracoCms.Web.nuspec +++ b/build/NuSpecs/UmbracoCms.Web.nuspec @@ -25,7 +25,7 @@ - + diff --git a/src/Umbraco.Tests/Umbraco.Tests.csproj b/src/Umbraco.Tests/Umbraco.Tests.csproj index 8dfad73b8a..7116a95b31 100644 --- a/src/Umbraco.Tests/Umbraco.Tests.csproj +++ b/src/Umbraco.Tests/Umbraco.Tests.csproj @@ -82,7 +82,7 @@ - 1.8.9 + 1.8.14 diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index a40f5d20f9..edbb5130b9 100755 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -64,7 +64,7 @@ - + 2.6.2.25 From 7c21a42804fdb372df71e743589aab1e9730bf0e Mon Sep 17 00:00:00 2001 From: Shannon Date: Wed, 6 Feb 2019 21:39:09 +1100 Subject: [PATCH 19/68] Update serilog --- build/NuSpecs/UmbracoCms.Core.nuspec | 4 ++-- src/Umbraco.Core/Umbraco.Core.csproj | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/NuSpecs/UmbracoCms.Core.nuspec b/build/NuSpecs/UmbracoCms.Core.nuspec index 60b91af7e6..e4fc5f3013 100644 --- a/build/NuSpecs/UmbracoCms.Core.nuspec +++ b/build/NuSpecs/UmbracoCms.Core.nuspec @@ -30,12 +30,12 @@ - + - + diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index 9135c6bf98..f66b55eab2 100755 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -73,7 +73,7 @@ - 2.7.1 + 2.8.0 2.0.1 @@ -88,7 +88,7 @@ 1.0.0 - 1.0.2 + 1.0.3 2.2.2 From 4c2ea81c535e2fd5d5ecfc6fbdea310820e358dc Mon Sep 17 00:00:00 2001 From: Shannon Date: Wed, 6 Feb 2019 21:41:46 +1100 Subject: [PATCH 20/68] updates Light Inject --- build/NuSpecs/UmbracoCms.Core.nuspec | 2 +- src/Umbraco.Core/Umbraco.Core.csproj | 2 +- src/Umbraco.Tests/Umbraco.Tests.csproj | 2 +- src/Umbraco.Web/Umbraco.Web.csproj | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/NuSpecs/UmbracoCms.Core.nuspec b/build/NuSpecs/UmbracoCms.Core.nuspec index e4fc5f3013..6fdc11f2f1 100644 --- a/build/NuSpecs/UmbracoCms.Core.nuspec +++ b/build/NuSpecs/UmbracoCms.Core.nuspec @@ -21,7 +21,7 @@ not want this to happen as the alpha of the next major is, really, the next major already. --> - + diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index f66b55eab2..5a8fbe6295 100755 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -56,7 +56,7 @@ - + diff --git a/src/Umbraco.Tests/Umbraco.Tests.csproj b/src/Umbraco.Tests/Umbraco.Tests.csproj index 7116a95b31..251718a3b7 100644 --- a/src/Umbraco.Tests/Umbraco.Tests.csproj +++ b/src/Umbraco.Tests/Umbraco.Tests.csproj @@ -84,7 +84,7 @@ 1.8.14 - + diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index edbb5130b9..89432d4d25 100755 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -68,7 +68,7 @@ 2.6.2.25 - + From 817ce71e832c1e4fa9cf8c8187e0c78e2069c077 Mon Sep 17 00:00:00 2001 From: Shannon Date: Wed, 6 Feb 2019 21:44:12 +1100 Subject: [PATCH 21/68] updates threading libs --- build/NuSpecs/UmbracoCms.Web.nuspec | 2 +- src/Umbraco.Tests/Umbraco.Tests.csproj | 2 +- src/Umbraco.Web/Umbraco.Web.csproj | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build/NuSpecs/UmbracoCms.Web.nuspec b/build/NuSpecs/UmbracoCms.Web.nuspec index b79b909191..5a7a44e80f 100644 --- a/build/NuSpecs/UmbracoCms.Web.nuspec +++ b/build/NuSpecs/UmbracoCms.Web.nuspec @@ -37,7 +37,7 @@ - + diff --git a/src/Umbraco.Tests/Umbraco.Tests.csproj b/src/Umbraco.Tests/Umbraco.Tests.csproj index 251718a3b7..8c26e3d532 100644 --- a/src/Umbraco.Tests/Umbraco.Tests.csproj +++ b/src/Umbraco.Tests/Umbraco.Tests.csproj @@ -111,7 +111,7 @@ - + diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index 89432d4d25..8a29df96ff 100755 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -85,7 +85,7 @@ - + From 47d660041e08a25364accef777b9672371660ad7 Mon Sep 17 00:00:00 2001 From: Shannon Date: Wed, 6 Feb 2019 21:47:21 +1100 Subject: [PATCH 22/68] updates test proj dependencies --- src/Umbraco.Tests/Umbraco.Tests.csproj | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Umbraco.Tests/Umbraco.Tests.csproj b/src/Umbraco.Tests/Umbraco.Tests.csproj index 8c26e3d532..5148ca150d 100644 --- a/src/Umbraco.Tests/Umbraco.Tests.csproj +++ b/src/Umbraco.Tests/Umbraco.Tests.csproj @@ -79,7 +79,7 @@ - + 1.8.14 @@ -101,13 +101,13 @@ - + - - + + - + From 68cdbf50b234e87295128a164aed7232625ccfd5 Mon Sep 17 00:00:00 2001 From: Shannon Date: Wed, 6 Feb 2019 21:48:33 +1100 Subject: [PATCH 23/68] removes old unused dependency from tests --- src/Umbraco.Tests/Umbraco.Tests.csproj | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Umbraco.Tests/Umbraco.Tests.csproj b/src/Umbraco.Tests/Umbraco.Tests.csproj index 5148ca150d..bff8d63a3f 100644 --- a/src/Umbraco.Tests/Umbraco.Tests.csproj +++ b/src/Umbraco.Tests/Umbraco.Tests.csproj @@ -109,7 +109,6 @@ - From 3f8efed392fb4d6b4f88ebeb26ae852811097924 Mon Sep 17 00:00:00 2001 From: Shannon Date: Wed, 6 Feb 2019 21:55:59 +1100 Subject: [PATCH 24/68] updates nuspecs to have the correct target framework --- build/NuSpecs/UmbracoCms.Core.nuspec | 54 +++++++++++++++------------- build/NuSpecs/UmbracoCms.Web.nuspec | 52 +++++++++++++++------------ build/NuSpecs/UmbracoCms.nuspec | 31 +++++++++------- 3 files changed, 77 insertions(+), 60 deletions(-) diff --git a/build/NuSpecs/UmbracoCms.Core.nuspec b/build/NuSpecs/UmbracoCms.Core.nuspec index 6fdc11f2f1..88281cb84b 100644 --- a/build/NuSpecs/UmbracoCms.Core.nuspec +++ b/build/NuSpecs/UmbracoCms.Core.nuspec @@ -15,31 +15,35 @@ en-US umbraco - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/NuSpecs/UmbracoCms.Web.nuspec b/build/NuSpecs/UmbracoCms.Web.nuspec index 5a7a44e80f..c52c8831e0 100644 --- a/build/NuSpecs/UmbracoCms.Web.nuspec +++ b/build/NuSpecs/UmbracoCms.Web.nuspec @@ -15,29 +15,35 @@ en-US umbraco - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/NuSpecs/UmbracoCms.nuspec b/build/NuSpecs/UmbracoCms.nuspec index 238dfd3c31..5e6dccfcd8 100644 --- a/build/NuSpecs/UmbracoCms.nuspec +++ b/build/NuSpecs/UmbracoCms.nuspec @@ -15,18 +15,25 @@ en-US umbraco - - - - - - - - + + + + + + + + + + + + + + + From 5b3f21c541384f0fa43ecfcf057bc6c4af14a192 Mon Sep 17 00:00:00 2001 From: Shannon Date: Wed, 6 Feb 2019 22:12:00 +1100 Subject: [PATCH 25/68] fixes tests --- src/Umbraco.Core/Configuration/GlobalSettings.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Core/Configuration/GlobalSettings.cs b/src/Umbraco.Core/Configuration/GlobalSettings.cs index 1c8188e99f..02b26aec86 100644 --- a/src/Umbraco.Core/Configuration/GlobalSettings.cs +++ b/src/Umbraco.Core/Configuration/GlobalSettings.cs @@ -31,7 +31,7 @@ namespace Umbraco.Core.Configuration private static string _reservedPaths; private static string _reservedUrls; //ensure the built on (non-changeable) reserved paths are there at all times - internal const string StaticReservedPaths = "~/app_plugins/,~/install/,~/mini-profiler-resources/"; //must end with a comma! + internal const string StaticReservedPaths = "~/app_plugins/,~/install/,~/mini-profiler-resources/,"; //must end with a comma! internal const string StaticReservedUrls = "~/config/splashes/noNodes.aspx,~/.well-known,"; //must end with a comma! #endregion From b260c18056414fbc27ce3965a225b9ea8086b6dc Mon Sep 17 00:00:00 2001 From: Stephan Date: Tue, 5 Feb 2019 19:58:33 +0100 Subject: [PATCH 26/68] Refactor IContent vs IContentType --- src/Umbraco.Core/Models/ContentBase.cs | 2 +- src/Umbraco.Core/Models/ISimpleContentType.cs | 16 +-- src/Umbraco.Core/Models/SimpleContentType.cs | 100 +++++++++++------- .../Mappers/MapperCollectionBuilder.cs | 1 + .../Mappers/SimpleContentTypeMapper.cs | 38 +++++++ src/Umbraco.Core/Umbraco.Core.csproj | 1 + .../Composing/TypeLoaderTests.cs | 2 +- .../Models/ContentExtensionsTests.cs | 54 +++++++++- src/Umbraco.Tests/Models/ContentTests.cs | 53 +++++++++- .../Mapping/ContentWebModelMappingTests.cs | 61 ++++++++--- src/Umbraco.Tests/Models/MemberTests.cs | 16 +-- src/Umbraco.Tests/Models/VariationTests.cs | 3 + .../Repositories/DocumentRepositoryTest.cs | 9 +- .../Repositories/MediaRepositoryTest.cs | 7 +- .../Repositories/MemberRepositoryTest.cs | 10 +- .../Repositories/UserRepositoryTest.cs | 25 +++-- .../Services/ContentTypeServiceTests.cs | 2 - .../Services/MemberTypeServiceTests.cs | 2 - .../Testing/ContentBaseExtensions.cs | 8 +- .../UmbracoExamine/IndexInitializer.cs | 2 +- .../Web/Controllers/ContentControllerTests.cs | 58 +++++----- 21 files changed, 330 insertions(+), 140 deletions(-) create mode 100644 src/Umbraco.Core/Persistence/Mappers/SimpleContentTypeMapper.cs diff --git a/src/Umbraco.Core/Models/ContentBase.cs b/src/Umbraco.Core/Models/ContentBase.cs index 908f620b11..765275cf51 100644 --- a/src/Umbraco.Core/Models/ContentBase.cs +++ b/src/Umbraco.Core/Models/ContentBase.cs @@ -15,7 +15,7 @@ namespace Umbraco.Core.Models ///
    [Serializable] [DataContract(IsReference = true)] - [DebuggerDisplay("Id: {Id}, Name: {Name}, ContentType: {ContentTypeBase.Alias}")] + [DebuggerDisplay("Id: {Id}, Name: {Name}, ContentType: {ContentType.Alias}")] public abstract class ContentBase : TreeEntityBase, IContentBase { protected static readonly ContentCultureInfosCollection NoInfos = new ContentCultureInfosCollection(); diff --git a/src/Umbraco.Core/Models/ISimpleContentType.cs b/src/Umbraco.Core/Models/ISimpleContentType.cs index 8c9413f934..40862afd9e 100644 --- a/src/Umbraco.Core/Models/ISimpleContentType.cs +++ b/src/Umbraco.Core/Models/ISimpleContentType.cs @@ -1,20 +1,17 @@ -namespace Umbraco.Core.Models +using Umbraco.Core.Models.Entities; + +namespace Umbraco.Core.Models { /// /// Represents a simplified view of a content type. /// - public interface ISimpleContentType + public interface ISimpleContentType : IUmbracoEntity { /// /// Gets the alias of the content type. /// string Alias { get; } - /// - /// Gets the identifier of the content type. - /// - int Id { get; } - /// /// Gets the default template of the content type. /// @@ -35,11 +32,6 @@ ///
    bool IsContainer { get; } - /// - /// Gets the name of the content type. - /// - string Name { get; } - /// /// Gets a value indicating whether content of that type can be created at the root of the tree. /// diff --git a/src/Umbraco.Core/Models/SimpleContentType.cs b/src/Umbraco.Core/Models/SimpleContentType.cs index db7e01fade..c0e235e92d 100644 --- a/src/Umbraco.Core/Models/SimpleContentType.cs +++ b/src/Umbraco.Core/Models/SimpleContentType.cs @@ -1,4 +1,6 @@ using System; +using System.Collections.Generic; +using Umbraco.Core.Models.Entities; namespace Umbraco.Core.Models { @@ -7,67 +9,56 @@ namespace Umbraco.Core.Models ///
    public class SimpleContentType : ISimpleContentType { + private readonly int _id; + private readonly string _name; + /// /// Initializes a new instance of the class. /// public SimpleContentType(IContentType contentType) + : this((IContentTypeBase)contentType) { - if (contentType == null) throw new ArgumentNullException(nameof(contentType)); - - - Id = contentType.Id; - Alias = contentType.Alias; DefaultTemplate = contentType.DefaultTemplate; - Variations = contentType.Variations; - Icon = contentType.Icon; - IsContainer = contentType.IsContainer; - Icon = contentType.Icon; - Name = contentType.Name; - AllowedAsRoot = contentType.AllowedAsRoot; - IsElement = contentType.IsElement; } /// /// Initializes a new instance of the class. /// public SimpleContentType(IMediaType mediaType) - { - if (mediaType == null) throw new ArgumentNullException(nameof(mediaType)); - - Id = mediaType.Id; - Alias = mediaType.Alias; - Variations = mediaType.Variations; - Icon = mediaType.Icon; - IsContainer = mediaType.IsContainer; - Icon = mediaType.Icon; - Name = mediaType.Name; - AllowedAsRoot = mediaType.AllowedAsRoot; - IsElement = mediaType.IsElement; - } + : this((IContentTypeBase)mediaType) + { } /// /// Initializes a new instance of the class. /// public SimpleContentType(IMemberType memberType) - { - if (memberType == null) throw new ArgumentNullException(nameof(memberType)); + : this((IContentTypeBase)memberType) + { } - Id = memberType.Id; - Alias = memberType.Alias; - Variations = memberType.Variations; - Icon = memberType.Icon; - IsContainer = memberType.IsContainer; - Icon = memberType.Icon; - Name = memberType.Name; - AllowedAsRoot = memberType.AllowedAsRoot; - IsElement = memberType.IsElement; + private SimpleContentType(IContentTypeBase contentType) + { + if (contentType == null) throw new ArgumentNullException(nameof(contentType)); + + _id = contentType.Id; + Alias = contentType.Alias; + Variations = contentType.Variations; + Icon = contentType.Icon; + IsContainer = contentType.IsContainer; + Icon = contentType.Icon; + _name = contentType.Name; + AllowedAsRoot = contentType.AllowedAsRoot; + IsElement = contentType.IsElement; } /// public string Alias { get; } /// - public int Id { get; } + public int Id + { + get => _id; + set => throw new NotSupportedException(); + } /// public ITemplate DefaultTemplate { get; } @@ -82,7 +73,11 @@ namespace Umbraco.Core.Models public bool IsContainer { get; } /// - public string Name { get; } + public string Name + { + get => _name; + set => throw new NotSupportedException(); + } /// public bool AllowedAsRoot { get; } @@ -121,5 +116,34 @@ namespace Umbraco.Core.Models return ((Alias != null ? Alias.GetHashCode() : 0) * 397) ^ Id; } } + + // we have to have all this, because we're an IUmbracoEntity, because that is + // required by the query expression visitor / SimpleContentTypeMapper + + public object DeepClone() => throw new NotImplementedException(); + + public Guid Key { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + public DateTime CreateDate { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + public DateTime UpdateDate { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + public DateTime? DeleteDate { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + public bool HasIdentity => throw new NotImplementedException(); + + public int CreatorId { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + public int ParentId { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + public void SetParent(ITreeEntity parent) => throw new NotImplementedException(); + + public int Level { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + public string Path { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + public int SortOrder { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + public bool Trashed => throw new NotImplementedException(); + public bool IsDirty() => throw new NotImplementedException(); + public bool IsPropertyDirty(string propName) => throw new NotImplementedException(); + public IEnumerable GetDirtyProperties() => throw new NotImplementedException(); + public void ResetDirtyProperties() => throw new NotImplementedException(); + public bool WasDirty() => throw new NotImplementedException(); + public bool WasPropertyDirty(string propertyName) => throw new NotImplementedException(); + public void ResetWereDirtyProperties() => throw new NotImplementedException(); + public void ResetDirtyProperties(bool rememberDirty) => throw new NotImplementedException(); + public IEnumerable GetWereDirtyProperties() => throw new NotImplementedException(); } } diff --git a/src/Umbraco.Core/Persistence/Mappers/MapperCollectionBuilder.cs b/src/Umbraco.Core/Persistence/Mappers/MapperCollectionBuilder.cs index 80819933f5..e20f7c1911 100644 --- a/src/Umbraco.Core/Persistence/Mappers/MapperCollectionBuilder.cs +++ b/src/Umbraco.Core/Persistence/Mappers/MapperCollectionBuilder.cs @@ -25,6 +25,7 @@ namespace Umbraco.Core.Persistence.Mappers Add(); Add(); Add(); + Add(); Add(); Add(); Add(); diff --git a/src/Umbraco.Core/Persistence/Mappers/SimpleContentTypeMapper.cs b/src/Umbraco.Core/Persistence/Mappers/SimpleContentTypeMapper.cs new file mode 100644 index 0000000000..3ad975defb --- /dev/null +++ b/src/Umbraco.Core/Persistence/Mappers/SimpleContentTypeMapper.cs @@ -0,0 +1,38 @@ +using System.Collections.Concurrent; +using Umbraco.Core.Models; +using Umbraco.Core.Persistence.Dtos; + +namespace Umbraco.Core.Persistence.Mappers +{ + [MapperFor(typeof(ISimpleContentType))] + [MapperFor(typeof(SimpleContentType))] + public sealed class SimpleContentTypeMapper : BaseMapper + { + private static readonly ConcurrentDictionary PropertyInfoCacheInstance = new ConcurrentDictionary(); + + internal override ConcurrentDictionary PropertyInfoCache => PropertyInfoCacheInstance; + + protected override void BuildMap() + { + if (PropertyInfoCache.IsEmpty == false) return; + + CacheMap(src => src.Id, dto => dto.NodeId); + CacheMap(src => src.CreateDate, dto => dto.CreateDate); + CacheMap(src => src.Level, dto => dto.Level); + CacheMap(src => src.ParentId, dto => dto.ParentId); + CacheMap(src => src.Path, dto => dto.Path); + CacheMap(src => src.SortOrder, dto => dto.SortOrder); + CacheMap(src => src.Name, dto => dto.Text); + CacheMap(src => src.Trashed, dto => dto.Trashed); + CacheMap(src => src.Key, dto => dto.UniqueId); + CacheMap(src => src.CreatorId, dto => dto.UserId); + CacheMap(src => src.Alias, dto => dto.Alias); + CacheMap(src => src.AllowedAsRoot, dto => dto.AllowAtRoot); + CacheMap(src => src.Description, dto => dto.Description); + CacheMap(src => src.Icon, dto => dto.Icon); + CacheMap(src => src.IsContainer, dto => dto.IsContainer); + CacheMap(src => src.IsElement, dto => dto.IsElement); + CacheMap(src => src.Thumbnail, dto => dto.Thumbnail); + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index d4b26cbbc0..eda02148fe 100755 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -467,6 +467,7 @@ + diff --git a/src/Umbraco.Tests/Composing/TypeLoaderTests.cs b/src/Umbraco.Tests/Composing/TypeLoaderTests.cs index 2354dc8147..2dbd3055cb 100644 --- a/src/Umbraco.Tests/Composing/TypeLoaderTests.cs +++ b/src/Umbraco.Tests/Composing/TypeLoaderTests.cs @@ -264,7 +264,7 @@ AnotherContentFinder public void Resolves_Assigned_Mappers() { var foundTypes1 = _typeLoader.GetAssignedMapperTypes(); - Assert.AreEqual(29, foundTypes1.Count()); + Assert.AreEqual(30, foundTypes1.Count()); } [Test] diff --git a/src/Umbraco.Tests/Models/ContentExtensionsTests.cs b/src/Umbraco.Tests/Models/ContentExtensionsTests.cs index 5c95f1ead5..efa464a46c 100644 --- a/src/Umbraco.Tests/Models/ContentExtensionsTests.cs +++ b/src/Umbraco.Tests/Models/ContentExtensionsTests.cs @@ -1,22 +1,60 @@ using System; using System.Linq; +using Moq; using NUnit.Framework; using Umbraco.Core; +using Umbraco.Core.Composing; +using Umbraco.Core.Composing.Composers; +using Umbraco.Core.Configuration.UmbracoSettings; +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.Entities; using Umbraco.Tests.Testing; +using Umbraco.Web.PropertyEditors; namespace Umbraco.Tests.Models { [TestFixture] public class ContentExtensionsTests : UmbracoTestBase { - #region Others + private IContentTypeService _contentTypeService; + + protected override void Compose() + { + base.Compose(); + + Composition.Register(_ => Mock.Of()); + Composition.ComposeFileSystems(); + + Composition.Register(_ => Mock.Of()); + Composition.Register(_ => Mock.Of()); + + // all this is required so we can validate properties... + var editor = new TextboxPropertyEditor(Mock.Of()) { Alias = "test" }; + Composition.Register(_ => new DataEditorCollection(new[] { editor })); + Composition.Register(); + var dataType = Mock.Of(); + Mock.Get(dataType).Setup(x => x.Configuration).Returns(() => new object()); + var dataTypeService = Mock.Of(); + Mock.Get(dataTypeService) + .Setup(x => x.GetDataType(It.IsAny())) + .Returns(() => dataType); + + _contentTypeService = Mock.Of(); + var mediaTypeService = Mock.Of(); + var memberTypeService = Mock.Of(); + Composition.Register(_ => ServiceContext.CreatePartial(dataTypeService: dataTypeService, contentTypeBaseServiceProvider: new ContentTypeBaseServiceProvider(_contentTypeService, mediaTypeService, memberTypeService))); + } [Test] public void DirtyProperty_Reset_Clears_SavedPublishedState() { var contentType = MockedContentTypes.CreateTextPageContentType(); + Mock.Get(_contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); + var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1); content.PublishedState = PublishedState.Publishing; @@ -30,6 +68,8 @@ namespace Umbraco.Tests.Models public void DirtyProperty_OnlyIfActuallyChanged_Content() { var contentType = MockedContentTypes.CreateTextPageContentType(); + Mock.Get(_contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); + var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1); // if you assign a content property with its value it is not dirty @@ -52,6 +92,8 @@ namespace Umbraco.Tests.Models public void DirtyProperty_OnlyIfActuallyChanged_User() { var contentType = MockedContentTypes.CreateTextPageContentType(); + Mock.Get(_contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); + var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1); var prop = content.Properties.First(); @@ -76,6 +118,8 @@ namespace Umbraco.Tests.Models public void DirtyProperty_UpdateDate() { var contentType = MockedContentTypes.CreateTextPageContentType(); + Mock.Get(_contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); + var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1); var prop = content.Properties.First(); @@ -99,6 +143,8 @@ namespace Umbraco.Tests.Models public void DirtyProperty_WasDirty_ContentProperty() { var contentType = MockedContentTypes.CreateTextPageContentType(); + Mock.Get(_contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); + var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1); content.ResetDirtyProperties(false); Assert.IsFalse(content.IsDirty()); @@ -126,6 +172,8 @@ namespace Umbraco.Tests.Models public void DirtyProperty_WasDirty_ContentSortOrder() { var contentType = MockedContentTypes.CreateTextPageContentType(); + Mock.Get(_contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); + var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1); content.ResetDirtyProperties(false); Assert.IsFalse(content.IsDirty()); @@ -153,6 +201,8 @@ namespace Umbraco.Tests.Models public void DirtyProperty_WasDirty_UserProperty() { var contentType = MockedContentTypes.CreateTextPageContentType(); + Mock.Get(_contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); + var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1); var prop = content.Properties.First(); content.ResetDirtyProperties(false); @@ -178,7 +228,5 @@ namespace Umbraco.Tests.Models //Assert.IsFalse(content.WasDirty()); // not impacted by user properties Assert.IsTrue(content.WasDirty()); // now it is! } - - #endregion } } diff --git a/src/Umbraco.Tests/Models/ContentTests.cs b/src/Umbraco.Tests/Models/ContentTests.cs index 844a609878..ad49fb226b 100644 --- a/src/Umbraco.Tests/Models/ContentTests.cs +++ b/src/Umbraco.Tests/Models/ContentTests.cs @@ -17,6 +17,7 @@ using Umbraco.Core.Models.Entities; using Umbraco.Core.PropertyEditors; using Umbraco.Core.Serialization; using Umbraco.Core.Services; +using Umbraco.Core.Services.Implement; using Umbraco.Tests.TestHelpers.Entities; using Umbraco.Tests.TestHelpers.Stubs; using Umbraco.Tests.Testing; @@ -28,6 +29,8 @@ namespace Umbraco.Tests.Models [TestFixture] public class ContentTests : UmbracoTestBase { + private IContentTypeService _contentTypeService; + protected override void Compose() { base.Compose(); @@ -48,19 +51,24 @@ namespace Umbraco.Tests.Models Mock.Get(dataTypeService) .Setup(x => x.GetDataType(It.IsAny())) .Returns(() => dataType); - Composition.Register(_ => ServiceContext.CreatePartial(dataTypeService: dataTypeService)); + + _contentTypeService = Mock.Of(); + var mediaTypeService = Mock.Of(); + var memberTypeService = Mock.Of(); + Composition.Register(_ => ServiceContext.CreatePartial(dataTypeService: dataTypeService, contentTypeBaseServiceProvider: new ContentTypeBaseServiceProvider(_contentTypeService, mediaTypeService, memberTypeService))); } [Test] public void Variant_Culture_Names_Track_Dirty_Changes() { var contentType = new ContentType(-1) { Alias = "contentType" }; + contentType.Variations = ContentVariation.Culture; + Mock.Get(_contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); + var content = new Content("content", -1, contentType) { Id = 1, VersionId = 1 }; const string langFr = "fr-FR"; - contentType.Variations = ContentVariation.Culture; - Assert.IsFalse(content.IsPropertyDirty("CultureInfos")); //hasn't been changed Thread.Sleep(500); //The "Date" wont be dirty if the test runs too fast since it will be the same date @@ -123,6 +131,7 @@ namespace Umbraco.Tests.Models //ensure that nothing is marked as dirty contentType.ResetDirtyProperties(false); + Mock.Get(_contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); var content = MockedContent.CreateSimpleContent(contentType); @@ -138,6 +147,8 @@ namespace Umbraco.Tests.Models public void All_Dirty_Properties_Get_Reset() { var contentType = MockedContentTypes.CreateTextPageContentType(); + Mock.Get(_contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); + var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1); content.ResetDirtyProperties(false); @@ -154,6 +165,8 @@ namespace Umbraco.Tests.Models { // Arrange var contentType = MockedContentTypes.CreateTextPageContentType(); + Mock.Get(_contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); + var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1); // Act @@ -167,6 +180,8 @@ namespace Umbraco.Tests.Models { // Arrange var contentType = MockedContentTypes.CreateTextPageContentType(); + Mock.Get(_contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); + var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1); // Act @@ -183,6 +198,8 @@ namespace Umbraco.Tests.Models { // Arrange var contentType = MockedContentTypes.CreateTextPageContentType(); + Mock.Get(_contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); + var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1); // Act @@ -199,6 +216,8 @@ namespace Umbraco.Tests.Models { // Arrange var contentType = MockedContentTypes.CreateTextPageContentType(); + Mock.Get(_contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); + var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1); content.Id = 10; content.Key = new Guid("29181B97-CB8F-403F-86DE-5FEB497F4800"); @@ -278,6 +297,8 @@ namespace Umbraco.Tests.Models var contentType = MockedContentTypes.CreateTextPageContentType(); contentType.Id = 99; contentType.Variations = ContentVariation.Culture; + Mock.Get(_contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); + var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1); content.SetCultureName("Hello", "en-US"); @@ -387,6 +408,8 @@ namespace Umbraco.Tests.Models var contentType = MockedContentTypes.CreateTextPageContentType(); contentType.Id = 99; contentType.Variations = ContentVariation.Culture; + Mock.Get(_contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); + var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1); content.SetCultureName("Hello", "en-US"); @@ -458,6 +481,8 @@ namespace Umbraco.Tests.Models // Arrange var contentType = MockedContentTypes.CreateTextPageContentType(); contentType.Id = 99; + Mock.Get(_contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); + var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1); var i = 200; foreach (var property in content.Properties) @@ -509,6 +534,8 @@ namespace Umbraco.Tests.Models { // Arrange var contentType = MockedContentTypes.CreateTextPageContentType(); + Mock.Get(_contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); + var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1); // Act @@ -527,6 +554,8 @@ namespace Umbraco.Tests.Models { // Arrange var contentType = MockedContentTypes.CreateTextPageContentType(); + Mock.Get(_contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); + var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1); // Act @@ -591,6 +620,8 @@ namespace Umbraco.Tests.Models { // Arrange var contentType = MockedContentTypes.CreateTextPageContentType(); + Mock.Get(_contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); + var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1); // Act @@ -613,6 +644,8 @@ namespace Umbraco.Tests.Models { // Arrange var contentType = MockedContentTypes.CreateTextPageContentType(); + Mock.Get(_contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); + var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1); // Act @@ -642,6 +675,8 @@ namespace Umbraco.Tests.Models { // Arrange var contentType = MockedContentTypes.CreateTextPageContentType(); + Mock.Get(_contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); + var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1); // Act - note that the PropertyType's properties like SortOrder is not updated through the Content object @@ -663,6 +698,8 @@ namespace Umbraco.Tests.Models // Arrange var contentType = MockedContentTypes.CreateTextPageContentType(); var simpleContentType = MockedContentTypes.CreateSimpleContentType(); + Mock.Get(_contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); + var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1); // Act @@ -680,6 +717,8 @@ namespace Umbraco.Tests.Models // Arrange var contentType = MockedContentTypes.CreateTextPageContentType(); var simpleContentType = MockedContentTypes.CreateSimpleContentType(); + Mock.Get(_contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); + var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1); // Act @@ -697,6 +736,8 @@ namespace Umbraco.Tests.Models // Arrange var contentType = MockedContentTypes.CreateTextPageContentType(); var simpleContentType = MockedContentTypes.CreateSimpleContentType(); + Mock.Get(_contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); + var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1); // Act @@ -716,6 +757,8 @@ namespace Umbraco.Tests.Models // Arrange var contentType = MockedContentTypes.CreateTextPageContentType(); var simpleContentType = MockedContentTypes.CreateSimpleContentType(); + Mock.Get(_contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); + var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1); // Act @@ -731,6 +774,8 @@ namespace Umbraco.Tests.Models public void Can_Verify_Content_Is_Published() { var contentType = MockedContentTypes.CreateTextPageContentType(); + Mock.Get(_contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); + var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1); content.ResetDirtyProperties(); @@ -800,6 +845,8 @@ namespace Umbraco.Tests.Models // Arrange var contentType = MockedContentTypes.CreateTextPageContentType(); contentType.ResetDirtyProperties(); //reset + Mock.Get(_contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); + var content = MockedContent.CreateTextpageContent(contentType, "test", -1); content.ResetDirtyProperties(); diff --git a/src/Umbraco.Tests/Models/Mapping/ContentWebModelMappingTests.cs b/src/Umbraco.Tests/Models/Mapping/ContentWebModelMappingTests.cs index e3551921d8..1817414f69 100644 --- a/src/Umbraco.Tests/Models/Mapping/ContentWebModelMappingTests.cs +++ b/src/Umbraco.Tests/Models/Mapping/ContentWebModelMappingTests.cs @@ -4,15 +4,20 @@ using AutoMapper; using Moq; using NUnit.Framework; using Umbraco.Core; +using Umbraco.Core.Composing; +using Umbraco.Core.Composing.Composers; +using Umbraco.Core.Configuration.UmbracoSettings; using Umbraco.Core.Services; using Umbraco.Core.Dictionary; using Umbraco.Core.Logging; using Umbraco.Core.Models; using Umbraco.Core.PropertyEditors; +using Umbraco.Core.Services.Implement; using Umbraco.Tests.TestHelpers; using Umbraco.Tests.TestHelpers.Entities; using Umbraco.Web.Models.ContentEditing; using Umbraco.Tests.Testing; +using Umbraco.Web.PropertyEditors; using Current = Umbraco.Web.Composing.Current; namespace Umbraco.Tests.Models.Mapping @@ -21,12 +26,37 @@ namespace Umbraco.Tests.Models.Mapping [UmbracoTest(AutoMapper = true, Database = UmbracoTestOptions.Database.NewSchemaPerFixture)] public class ContentWebModelMappingTests : TestWithDatabaseBase { + private IContentTypeService _contentTypeService; + + protected override void Compose() { base.Compose(); Composition.RegisterUnique(f => Mock.Of()); - Composition.RegisterUnique(f => Mock.Of()); + + Composition.Register(_ => Mock.Of()); + Composition.ComposeFileSystems(); + + Composition.Register(_ => Mock.Of()); + Composition.Register(_ => Mock.Of()); + + // all this is required so we can validate properties... + var editor = new TextboxPropertyEditor(Mock.Of()) { Alias = "test" }; + Composition.Register(_ => new DataEditorCollection(new[] { editor })); + Composition.Register(); + var dataType = Mock.Of(); + Mock.Get(dataType).Setup(x => x.Configuration).Returns(() => new object()); + var dataTypeService = Mock.Of(); + Mock.Get(dataTypeService) + .Setup(x => x.GetDataType(It.IsAny())) + .Returns(() => dataType); + + _contentTypeService = Mock.Of(); + var mediaTypeService = Mock.Of(); + var memberTypeService = Mock.Of(); + Composition.RegisterUnique(_ => _contentTypeService); + Composition.Register(_ => ServiceContext.CreatePartial(dataTypeService: dataTypeService, contentTypeBaseServiceProvider: new ContentTypeBaseServiceProvider(_contentTypeService, mediaTypeService, memberTypeService))); } [DataEditor("Test.Test", "Test", "~/Test.html")] @@ -53,6 +83,8 @@ namespace Umbraco.Tests.Models.Mapping public void To_Media_Item_Simple() { var contentType = MockedContentTypes.CreateImageMediaType(); + Mock.Get(_contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); + var content = MockedMedia.CreateMediaImage(contentType, -1); FixUsers(content); @@ -70,6 +102,8 @@ namespace Umbraco.Tests.Models.Mapping public void To_Content_Item_Simple() { var contentType = MockedContentTypes.CreateSimpleContentType(); + Mock.Get(_contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); + var content = MockedContent.CreateSimpleContent(contentType); FixUsers(content); @@ -87,6 +121,8 @@ namespace Umbraco.Tests.Models.Mapping public void To_Content_Item_Dto() { var contentType = MockedContentTypes.CreateSimpleContentType(); + Mock.Get(_contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); + var content = MockedContent.CreateSimpleContent(contentType); FixUsers(content); @@ -117,8 +153,8 @@ namespace Umbraco.Tests.Models.Mapping public void To_Display_Model() { var contentType = MockedContentTypes.CreateSimpleContentType(); - var contentTypeServiceMock = Mock.Get(Current.Services.ContentTypeService); - contentTypeServiceMock.Setup(x => x.Get(contentType.Id)).Returns(() => contentType); + Mock.Get(_contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); + Mock.Get(_contentTypeService).Setup(x => x.Get(It.IsAny())).Returns(contentType); var content = MockedContent.CreateSimpleContent(contentType); @@ -127,7 +163,7 @@ namespace Umbraco.Tests.Models.Mapping // need ids for tabs var id = 1; - foreach (var g in content.PropertyGroups) + foreach (var g in contentType.CompositionPropertyGroups) g.Id = id++; var result = Mapper.Map(content); @@ -141,7 +177,7 @@ namespace Umbraco.Tests.Models.Mapping AssertDisplayProperty(invariantContent, p); } - Assert.AreEqual(content.PropertyGroups.Count(), invariantContent.Tabs.Count()); + Assert.AreEqual(contentType.CompositionPropertyGroups.Count(), invariantContent.Tabs.Count()); Assert.IsTrue(invariantContent.Tabs.First().IsActive); Assert.IsTrue(invariantContent.Tabs.Except(new[] { invariantContent.Tabs.First() }).All(x => x.IsActive == false)); } @@ -151,9 +187,8 @@ namespace Umbraco.Tests.Models.Mapping { var contentType = MockedContentTypes.CreateSimpleContentType(); contentType.PropertyGroups.Clear(); - var contentTypeServiceMock = Mock.Get(Current.Services.ContentTypeService); - contentTypeServiceMock.Setup(x => x.Get(contentType.Id)).Returns(() => contentType); - + Mock.Get(_contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); + Mock.Get(_contentTypeService).Setup(x => x.Get(It.IsAny())).Returns(contentType); var content = new Content("Home", -1, contentType) { Level = 1, SortOrder = 1, CreatorId = 0, WriterId = 0 }; @@ -168,7 +203,7 @@ namespace Umbraco.Tests.Models.Mapping AssertDisplayProperty(invariantContent, p); } - Assert.AreEqual(content.PropertyGroups.Count(), invariantContent.Tabs.Count()); + Assert.AreEqual(contentType.CompositionPropertyGroups.Count(), invariantContent.Tabs.Count()); } [Test] @@ -186,8 +221,8 @@ namespace Umbraco.Tests.Models.Mapping p.Id = idSeed; idSeed++; } - var contentTypeServiceMock = Mock.Get(Current.Services.ContentTypeService); - contentTypeServiceMock.Setup(x => x.Get(contentType.Id)).Returns(() => contentType); + Mock.Get(_contentTypeService).As().Setup(x => x.Get(It.IsAny())).Returns(contentType); + Mock.Get(_contentTypeService).Setup(x => x.Get(It.IsAny())).Returns(contentType); var content = MockedContent.CreateSimpleContent(contentType); @@ -200,7 +235,7 @@ namespace Umbraco.Tests.Models.Mapping } //need ids for tabs var id = 1; - foreach (var g in content.PropertyGroups) + foreach (var g in contentType.CompositionPropertyGroups) { g.Id = id; id++; @@ -221,7 +256,7 @@ namespace Umbraco.Tests.Models.Mapping AssertDisplayProperty(invariantContent, p); } - Assert.AreEqual(content.PropertyGroups.Count(), invariantContent.Tabs.Count() - 1); + Assert.AreEqual(contentType.CompositionPropertyGroups.Count(), invariantContent.Tabs.Count() - 1); Assert.IsTrue(invariantContent.Tabs.Any(x => x.Label == Current.Services.TextService.Localize("general/properties"))); Assert.AreEqual(2, invariantContent.Tabs.Where(x => x.Label == Current.Services.TextService.Localize("general/properties")).SelectMany(x => x.Properties.Where(p => p.Alias.StartsWith("_umb_") == false)).Count()); } diff --git a/src/Umbraco.Tests/Models/MemberTests.cs b/src/Umbraco.Tests/Models/MemberTests.cs index c09f2e9460..5e92ad7ccf 100644 --- a/src/Umbraco.Tests/Models/MemberTests.cs +++ b/src/Umbraco.Tests/Models/MemberTests.cs @@ -67,20 +67,7 @@ namespace Umbraco.Tests.Models Assert.AreEqual(clone.Id, member.Id); Assert.AreEqual(clone.VersionId, member.VersionId); Assert.AreEqual(clone.AdditionalData, member.AdditionalData); - Assert.AreNotSame(clone.ContentType, member.ContentType); Assert.AreEqual(clone.ContentType, member.ContentType); - Assert.AreEqual(clone.ContentType.PropertyGroups.Count, member.ContentType.PropertyGroups.Count); - for (var index = 0; index < member.ContentType.PropertyGroups.Count; index++) - { - Assert.AreNotSame(clone.ContentType.PropertyGroups[index], member.ContentType.PropertyGroups[index]); - Assert.AreEqual(clone.ContentType.PropertyGroups[index], member.ContentType.PropertyGroups[index]); - } - Assert.AreEqual(clone.ContentType.PropertyTypes.Count(), member.ContentType.PropertyTypes.Count()); - for (var index = 0; index < member.ContentType.PropertyTypes.Count(); index++) - { - Assert.AreNotSame(clone.ContentType.PropertyTypes.ElementAt(index), member.ContentType.PropertyTypes.ElementAt(index)); - Assert.AreEqual(clone.ContentType.PropertyTypes.ElementAt(index), member.ContentType.PropertyTypes.ElementAt(index)); - } Assert.AreEqual(clone.ContentTypeId, member.ContentTypeId); Assert.AreEqual(clone.CreateDate, member.CreateDate); Assert.AreEqual(clone.CreatorId, member.CreatorId); @@ -112,6 +99,9 @@ namespace Umbraco.Tests.Models Assert.AreEqual(clone.Properties[index], member.Properties[index]); } + // this can be the same, it is immutable + Assert.AreSame(clone.ContentType, member.ContentType); + //This double verifies by reflection var allProps = clone.GetType().GetProperties(); foreach (var propertyInfo in allProps) diff --git a/src/Umbraco.Tests/Models/VariationTests.cs b/src/Umbraco.Tests/Models/VariationTests.cs index 0ccdabe928..36fb399fa7 100644 --- a/src/Umbraco.Tests/Models/VariationTests.cs +++ b/src/Umbraco.Tests/Models/VariationTests.cs @@ -227,6 +227,9 @@ namespace Umbraco.Tests.Models // now it will work contentType.Variations = ContentVariation.Culture; + // recreate content to re-capture content type variations + content = new Content("content", -1, contentType) { Id = 1, VersionId = 1 }; + // invariant name works content.Name = "name"; Assert.AreEqual("name", content.GetCultureName(null)); diff --git a/src/Umbraco.Tests/Persistence/Repositories/DocumentRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/DocumentRepositoryTest.cs index 459dbeb587..2c4f3f1908 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/DocumentRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/DocumentRepositoryTest.cs @@ -130,10 +130,11 @@ namespace Umbraco.Tests.Persistence.Repositories var hasPropertiesContentType = MockedContentTypes.CreateSimpleContentType("umbTextpage1", "Textpage"); ServiceContext.FileService.SaveTemplate(hasPropertiesContentType.DefaultTemplate); // else, FK violation on contentType! + contentTypeRepository.Save(hasPropertiesContentType); + IContent content1 = MockedContent.CreateSimpleContent(hasPropertiesContentType); // save = create the initial version - contentTypeRepository.Save(hasPropertiesContentType); repository.Save(content1); versions.Add(content1.VersionId); // the first version @@ -399,9 +400,10 @@ namespace Umbraco.Tests.Persistence.Repositories var repository = CreateRepository((IScopeAccessor)provider, out var contentTypeRepository); var contentType = MockedContentTypes.CreateSimpleContentType("umbTextpage2", "Textpage"); ServiceContext.FileService.SaveTemplate(contentType.DefaultTemplate); // else, FK violation on contentType! + contentTypeRepository.Save(contentType); + IContent textpage = MockedContent.CreateSimpleContent(contentType); - contentTypeRepository.Save(contentType); repository.Save(textpage); scope.Complete(); @@ -487,9 +489,10 @@ namespace Umbraco.Tests.Persistence.Repositories var repository = CreateRepository((IScopeAccessor)provider, out var contentTypeRepository); var contentType = MockedContentTypes.CreateSimpleContentType("umbTextpage1", "Textpage"); ServiceContext.FileService.SaveTemplate(contentType.DefaultTemplate); // else, FK violation on contentType! + contentTypeRepository.Save(contentType); + var textpage = MockedContent.CreateSimpleContent(contentType); - contentTypeRepository.Save(contentType); repository.Save(textpage); diff --git a/src/Umbraco.Tests/Persistence/Repositories/MediaRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/MediaRepositoryTest.cs index cbd591950a..1c1b5e60f4 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/MediaRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/MediaRepositoryTest.cs @@ -61,8 +61,9 @@ namespace Umbraco.Tests.Persistence.Repositories udb.EnableSqlCount = false; var mediaType = MockedContentTypes.CreateSimpleMediaType("umbTextpage1", "Textpage"); - var media = MockedMedia.CreateSimpleMedia(mediaType, "hello", -1); mediaTypeRepository.Save(mediaType); + + var media = MockedMedia.CreateSimpleMedia(mediaType, "hello", -1); repository.Save(media); udb.EnableSqlCount = true; @@ -271,7 +272,7 @@ namespace Umbraco.Tests.Persistence.Repositories var folder = MockedMedia.CreateMediaFolder(folderMediaType, -1); repository.Save(folder); } - + var types = new[] { 1031 }; var query = scope.SqlContext.Query().Where(x => types.Contains(x.ContentTypeId)); @@ -302,7 +303,7 @@ namespace Umbraco.Tests.Persistence.Repositories var folder = MockedMedia.CreateMediaFolder(folderMediaType, -1); repository.Save(folder); } - + var types = new[] { "Folder" }; var query = scope.SqlContext.Query().Where(x => types.Contains(x.ContentType.Alias)); diff --git a/src/Umbraco.Tests/Persistence/Repositories/MemberRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/MemberRepositoryTest.cs index dea15cd4ad..c46a090685 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/MemberRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/MemberRepositoryTest.cs @@ -164,21 +164,19 @@ namespace Umbraco.Tests.Persistence.Repositories var memberType = MockedContentTypes.CreateSimpleMemberType(); memberTypeRepository.Save(memberType); - var member = MockedMember.CreateSimpleMember(memberType, "Johnny Hefty", "johnny@example.com", "123", "hefty"); repository.Save(member); - var sut = repository.Get(member.Id); - Assert.That(sut.ContentType.PropertyGroups.Count(), Is.EqualTo(2)); - Assert.That(sut.ContentType.PropertyTypes.Count(), Is.EqualTo(3 + Constants.Conventions.Member.GetStandardPropertyTypeStubs().Count)); + Assert.That(memberType.CompositionPropertyGroups.Count(), Is.EqualTo(2)); + Assert.That(memberType.CompositionPropertyTypes.Count(), Is.EqualTo(3 + Constants.Conventions.Member.GetStandardPropertyTypeStubs().Count)); Assert.That(sut.Properties.Count(), Is.EqualTo(3 + Constants.Conventions.Member.GetStandardPropertyTypeStubs().Count)); - var grp = sut.PropertyGroups.FirstOrDefault(x => x.Name == Constants.Conventions.Member.StandardPropertiesGroupName); + var grp = memberType.CompositionPropertyGroups.FirstOrDefault(x => x.Name == Constants.Conventions.Member.StandardPropertiesGroupName); Assert.IsNotNull(grp); var aliases = Constants.Conventions.Member.GetStandardPropertyTypeStubs().Select(x => x.Key).ToArray(); - foreach (var p in sut.PropertyTypes.Where(x => aliases.Contains(x.Alias))) + foreach (var p in memberType.CompositionPropertyTypes.Where(x => aliases.Contains(x.Alias))) { Assert.AreEqual(grp.Id, p.PropertyGroupId.Value); } diff --git a/src/Umbraco.Tests/Persistence/Repositories/UserRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/UserRepositoryTest.cs index 8f750f9238..1d50fcac9e 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/UserRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/UserRepositoryTest.cs @@ -75,7 +75,7 @@ namespace Umbraco.Tests.Persistence.Repositories // Act repository.Save(user); - + // Assert Assert.That(user.HasIdentity, Is.True); @@ -96,9 +96,9 @@ namespace Umbraco.Tests.Persistence.Repositories // Act repository.Save(user1); - + repository.Save(use2); - + // Assert Assert.That(user1.HasIdentity, Is.True); @@ -117,7 +117,7 @@ namespace Umbraco.Tests.Persistence.Repositories var user = MockedUser.CreateUser(); repository.Save(user); - + // Act var resolved = repository.Get((int)user.Id); @@ -132,9 +132,7 @@ namespace Umbraco.Tests.Persistence.Repositories public void Can_Perform_Update_On_UserRepository() { var ct = MockedContentTypes.CreateBasicContentType("test"); - var content = MockedContent.CreateBasicContent(ct); var mt = MockedContentTypes.CreateSimpleMediaType("testmedia", "TestMedia"); - var media = MockedMedia.CreateSimpleMedia(mt, "asdf", -1); // Arrange var provider = TestObjects.GetScopeProvider(Logger); @@ -147,11 +145,12 @@ namespace Umbraco.Tests.Persistence.Repositories contentTypeRepo.Save(ct); mediaTypeRepo.Save(mt); - + + var content = MockedContent.CreateBasicContent(ct); + var media = MockedMedia.CreateSimpleMedia(mt, "asdf", -1); contentRepository.Save(content); mediaRepository.Save(media); - var user = CreateAndCommitUserWithGroup(userRepository, userGroupRepository); @@ -171,7 +170,7 @@ namespace Umbraco.Tests.Persistence.Repositories resolved.Username = "newName"; userRepository.Save(resolved); - + var updatedItem = (User) userRepository.Get(user.Id); // Assert @@ -204,13 +203,13 @@ namespace Umbraco.Tests.Persistence.Repositories // Act repository.Save(user); - + var id = user.Id; var repository2 = new UserRepository((IScopeAccessor) provider, AppCaches.Disabled, Logger, Mock.Of(),TestObjects.GetGlobalSettings()); repository2.Delete(user); - + var resolved = repository2.Get((int) id); @@ -373,7 +372,7 @@ namespace Umbraco.Tests.Persistence.Repositories scope.Database.AsUmbracoDatabase().EnableSqlCount = false; } } - + } [Test] @@ -429,7 +428,7 @@ namespace Umbraco.Tests.Persistence.Repositories { var user = MockedUser.CreateUser(); repository.Save(user); - + var group = MockedUserGroup.CreateUserGroup(); userGroupRepository.AddOrUpdateGroupWithUsers(@group, new[] { user.Id }); diff --git a/src/Umbraco.Tests/Services/ContentTypeServiceTests.cs b/src/Umbraco.Tests/Services/ContentTypeServiceTests.cs index 1319d00c48..7a7aad6905 100644 --- a/src/Umbraco.Tests/Services/ContentTypeServiceTests.cs +++ b/src/Umbraco.Tests/Services/ContentTypeServiceTests.cs @@ -554,7 +554,6 @@ namespace Umbraco.Tests.Services IContent contentItem = MockedContent.CreateTextpageContent(contentType1, "Testing", -1); ServiceContext.ContentService.SaveAndPublish(contentItem); var initProps = contentItem.Properties.Count; - var initPropTypes = contentItem.PropertyTypes.Count(); //remove a property contentType1.RemovePropertyType(contentType1.PropertyTypes.First().Alias); @@ -563,7 +562,6 @@ namespace Umbraco.Tests.Services //re-load it from the db contentItem = ServiceContext.ContentService.GetById(contentItem.Id); - Assert.AreEqual(initPropTypes - 1, contentItem.PropertyTypes.Count()); Assert.AreEqual(initProps - 1, contentItem.Properties.Count); } diff --git a/src/Umbraco.Tests/Services/MemberTypeServiceTests.cs b/src/Umbraco.Tests/Services/MemberTypeServiceTests.cs index 459daa3da6..5f4a87c3eb 100644 --- a/src/Umbraco.Tests/Services/MemberTypeServiceTests.cs +++ b/src/Umbraco.Tests/Services/MemberTypeServiceTests.cs @@ -83,7 +83,6 @@ namespace Umbraco.Tests.Services IMember member = MockedMember.CreateSimpleMember(memberType, "test", "test@test.com", "pass", "test"); ServiceContext.MemberService.Save(member); var initProps = member.Properties.Count; - var initPropTypes = member.PropertyTypes.Count(); //remove a property (NOT ONE OF THE DEFAULTS) var standardProps = Constants.Conventions.Member.GetStandardPropertyTypeStubs(); @@ -93,7 +92,6 @@ namespace Umbraco.Tests.Services //re-load it from the db member = ServiceContext.MemberService.GetById(member.Id); - Assert.AreEqual(initPropTypes - 1, member.PropertyTypes.Count()); Assert.AreEqual(initProps - 1, member.Properties.Count); } diff --git a/src/Umbraco.Tests/Testing/ContentBaseExtensions.cs b/src/Umbraco.Tests/Testing/ContentBaseExtensions.cs index 58d4dfbd7f..85ecf03dee 100644 --- a/src/Umbraco.Tests/Testing/ContentBaseExtensions.cs +++ b/src/Umbraco.Tests/Testing/ContentBaseExtensions.cs @@ -1,5 +1,7 @@ using System; using System.Linq; +using Umbraco.Core; +using Umbraco.Core.Composing; using Umbraco.Core.Models; namespace Umbraco.Tests.Testing @@ -7,7 +9,7 @@ namespace Umbraco.Tests.Testing public static class ContentBaseExtensions { /// - /// Set property values by alias with an annonymous object. + /// Set property values by alias with an anonymous object. /// /// Does not support variants. public static void PropertyValues(this IContentBase content, object value, string culture = null, string segment = null) @@ -15,11 +17,13 @@ namespace Umbraco.Tests.Testing if (value == null) throw new Exception("No properties has been passed in"); + var contentType = Current.Services.ContentTypeBaseServices.GetContentTypeOf(content); + var propertyInfos = value.GetType().GetProperties(); foreach (var propertyInfo in propertyInfos) { //Check if a PropertyType with alias exists thus being a valid property - var propertyType = content.PropertyTypes.FirstOrDefault(x => x.Alias == propertyInfo.Name); + var propertyType = contentType.CompositionPropertyTypes.FirstOrDefault(x => x.Alias == propertyInfo.Name); if (propertyType == null) throw new Exception($"The property alias {propertyInfo.Name} is not valid, because no PropertyType with this alias exists"); diff --git a/src/Umbraco.Tests/UmbracoExamine/IndexInitializer.cs b/src/Umbraco.Tests/UmbracoExamine/IndexInitializer.cs index 6fe921e13f..f7b1799d63 100644 --- a/src/Umbraco.Tests/UmbracoExamine/IndexInitializer.cs +++ b/src/Umbraco.Tests/UmbracoExamine/IndexInitializer.cs @@ -110,7 +110,7 @@ namespace Umbraco.Tests.UmbracoExamine m.GetCultureName(It.IsAny()) == (string)x.Attribute("nodeName") && m.Path == (string)x.Attribute("path") && m.Properties == new PropertyCollection() && - m.ContentType == Mock.Of(mt => + m.ContentType == Mock.Of(mt => mt.Alias == (string)x.Attribute("nodeTypeAlias") && mt.Id == (int)x.Attribute("nodeType")))) .ToArray(); diff --git a/src/Umbraco.Tests/Web/Controllers/ContentControllerTests.cs b/src/Umbraco.Tests/Web/Controllers/ContentControllerTests.cs index 37600e2f89..d0c09d3340 100644 --- a/src/Umbraco.Tests/Web/Controllers/ContentControllerTests.cs +++ b/src/Umbraco.Tests/Web/Controllers/ContentControllerTests.cs @@ -43,6 +43,14 @@ namespace Umbraco.Tests.Web.Controllers [UmbracoTest(Database = UmbracoTestOptions.Database.None)] public class ContentControllerTests : TestWithDatabaseBase { + private IContentType _contentTypeForMockedContent; + + public override void SetUp() + { + base.SetUp(); + _contentTypeForMockedContent = null; + } + protected override void ComposeApplication(bool withApplication) { base.ComposeApplication(withApplication); @@ -115,23 +123,42 @@ namespace Umbraco.Tests.Web.Controllers }; } - private IContent GetMockedContent() + private IContentType GetMockedContentType() { - var content = MockedContent.CreateSimpleContent(MockedContentTypes.CreateSimpleContentType()); - content.Id = 123; - content.Path = "-1,123"; + var contentType = MockedContentTypes.CreateSimpleContentType(); //ensure things have ids var ids = 888; - foreach (var g in content.PropertyGroups) + foreach (var g in contentType.CompositionPropertyGroups) { g.Id = ids; ids++; } - foreach (var p in content.PropertyTypes) + foreach (var p in contentType.CompositionPropertyGroups) { p.Id = ids; ids++; } + + return contentType; + } + + private IContent GetMockedContent() + { + if (_contentTypeForMockedContent == null) + { + _contentTypeForMockedContent = GetMockedContentType(); + Mock.Get(Current.Services.ContentTypeService) + .Setup(x => x.Get(_contentTypeForMockedContent.Id)) + .Returns(_contentTypeForMockedContent); + Mock.Get(Current.Services.ContentTypeService) + .As() + .Setup(x => x.Get(_contentTypeForMockedContent.Id)) + .Returns(_contentTypeForMockedContent); + } + + var content = MockedContent.CreateSimpleContent(_contentTypeForMockedContent); + content.Id = 123; + content.Path = "-1,123"; return content; } @@ -229,7 +256,7 @@ namespace Umbraco.Tests.Web.Controllers Factory.GetInstance(), Factory.GetInstance(), helper); - + return controller; } @@ -251,9 +278,6 @@ namespace Umbraco.Tests.Web.Controllers { ApiController CtrlFactory(HttpRequestMessage message, UmbracoContext umbracoContext, UmbracoHelper helper) { - var contentServiceMock = Mock.Get(Current.Services.ContentService); - contentServiceMock.Setup(x => x.GetById(123)).Returns(() => GetMockedContent()); - var propertyEditorCollection = new PropertyEditorCollection(new DataEditorCollection(Enumerable.Empty())); var controller = new ContentController( propertyEditorCollection, @@ -336,15 +360,11 @@ namespace Umbraco.Tests.Web.Controllers ApiController CtrlFactory(HttpRequestMessage message, UmbracoContext umbracoContext, UmbracoHelper helper) { - var contentServiceMock = Mock.Get(Current.Services.ContentService); contentServiceMock.Setup(x => x.GetById(123)).Returns(() => content); contentServiceMock.Setup(x => x.Save(It.IsAny(), It.IsAny(), It.IsAny())) .Returns(new OperationResult(OperationResultType.Success, new Core.Events.EventMessages())); //success - var contentTypeServiceMock = Mock.Get(Current.Services.ContentTypeService); - contentTypeServiceMock.Setup(x => x.Get(content.ContentTypeId)).Returns(() => MockedContentTypes.CreateSimpleContentType()); - var propertyEditorCollection = new PropertyEditorCollection(new DataEditorCollection(Enumerable.Empty())); var controller = new ContentController( propertyEditorCollection, @@ -369,8 +389,6 @@ namespace Umbraco.Tests.Web.Controllers Assert.AreEqual(HttpStatusCode.OK, response.Item1.StatusCode); var display = JsonConvert.DeserializeObject(response.Item2); Assert.AreEqual(1, display.Variants.Count()); - Assert.AreEqual(content.PropertyGroups.Count(), display.Variants.ElementAt(0).Tabs.Count()); - Assert.AreEqual(content.PropertyTypes.Count(), display.Variants.ElementAt(0).Tabs.ElementAt(0).Properties.Count()); } [Test] @@ -380,15 +398,11 @@ namespace Umbraco.Tests.Web.Controllers ApiController CtrlFactory(HttpRequestMessage message, UmbracoContext umbracoContext, UmbracoHelper helper) { - var contentServiceMock = Mock.Get(Current.Services.ContentService); contentServiceMock.Setup(x => x.GetById(123)).Returns(() => content); contentServiceMock.Setup(x => x.Save(It.IsAny(), It.IsAny(), It.IsAny())) .Returns(new OperationResult(OperationResultType.Success, new Core.Events.EventMessages())); //success - var contentTypeServiceMock = Mock.Get(Current.Services.ContentTypeService); - contentTypeServiceMock.Setup(x => x.Get(content.ContentTypeId)).Returns(() => MockedContentTypes.CreateSimpleContentType()); - var propertyEditorCollection = new PropertyEditorCollection(new DataEditorCollection(Enumerable.Empty())); var controller = new ContentController( propertyEditorCollection, @@ -428,15 +442,11 @@ namespace Umbraco.Tests.Web.Controllers ApiController CtrlFactory(HttpRequestMessage message, UmbracoContext umbracoContext, UmbracoHelper helper) { - var contentServiceMock = Mock.Get(Current.Services.ContentService); contentServiceMock.Setup(x => x.GetById(123)).Returns(() => content); contentServiceMock.Setup(x => x.Save(It.IsAny(), It.IsAny(), It.IsAny())) .Returns(new OperationResult(OperationResultType.Success, new Core.Events.EventMessages())); //success - var contentTypeServiceMock = Mock.Get(Current.Services.ContentTypeService); - contentTypeServiceMock.Setup(x => x.Get(content.ContentTypeId)).Returns(() => MockedContentTypes.CreateSimpleContentType()); - var propertyEditorCollection = new PropertyEditorCollection(new DataEditorCollection(Enumerable.Empty())); var controller = new ContentController( propertyEditorCollection, From bcfbab2add6558331ba74aa3b751abe3e0a4bcc9 Mon Sep 17 00:00:00 2001 From: Shannon Date: Wed, 6 Feb 2019 23:12:01 +1100 Subject: [PATCH 27/68] fixing tests --- src/Umbraco.Tests/App.config | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/Umbraco.Tests/App.config b/src/Umbraco.Tests/App.config index 5e366eef33..49de625450 100644 --- a/src/Umbraco.Tests/App.config +++ b/src/Umbraco.Tests/App.config @@ -64,23 +64,23 @@ - + - + - + - + - - + + @@ -88,7 +88,7 @@ - + @@ -100,11 +100,11 @@ - + - + From 8b4315cd46229531a8dfbe79023eda72b59d76c4 Mon Sep 17 00:00:00 2001 From: Warren Buckley Date: Wed, 6 Feb 2019 14:01:14 +0000 Subject: [PATCH 28/68] =?UTF-8?q?=F0=9F=A6=B8=F0=9F=A6=B8=20Is=20it=20a=20?= =?UTF-8?q?bird,=20is=20it=20a=20plane,=20no=20it's=20SuperUser=20?= =?UTF-8?q?=F0=9F=A6=B8=F0=9F=A6=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Services/ContentServiceExtensions.cs | 2 +- src/Umbraco.Core/Services/IContentService.cs | 62 +++++++++---------- .../Services/IContentTypeServiceBase.cs | 16 ++--- src/Umbraco.Core/Services/IDataTypeService.cs | 14 ++--- src/Umbraco.Core/Services/IFileService.cs | 30 ++++----- .../Services/ILocalizationService.cs | 8 +-- src/Umbraco.Core/Services/IMacroService.cs | 4 +- src/Umbraco.Core/Services/IMediaService.cs | 30 ++++----- .../Services/IPackagingService.cs | 10 +-- .../Services/Implement/ContentService.cs | 60 +++++++++--------- ...peServiceBaseOfTRepositoryTItemTService.cs | 16 ++--- .../Services/Implement/DataTypeService.cs | 14 ++--- .../Services/Implement/FileService.cs | 36 +++++------ .../Services/Implement/LocalizationService.cs | 8 +-- .../Services/Implement/MacroService.cs | 4 +- .../Services/Implement/MediaService.cs | 34 +++++----- .../Services/Implement/PackagingService.cs | 10 +-- 17 files changed, 179 insertions(+), 179 deletions(-) diff --git a/src/Umbraco.Core/Services/ContentServiceExtensions.cs b/src/Umbraco.Core/Services/ContentServiceExtensions.cs index 03a790d4b8..4d673fc902 100644 --- a/src/Umbraco.Core/Services/ContentServiceExtensions.cs +++ b/src/Umbraco.Core/Services/ContentServiceExtensions.cs @@ -34,7 +34,7 @@ namespace Umbraco.Core.Services /// /// /// - public static IContent CreateContent(this IContentService contentService, string name, Udi parentId, string mediaTypeAlias, int userId = 0) + public static IContent CreateContent(this IContentService contentService, string name, Udi parentId, string mediaTypeAlias, int userId = Constants.Security.SuperUserId) { var guidUdi = parentId as GuidUdi; if (guidUdi == null) diff --git a/src/Umbraco.Core/Services/IContentService.cs b/src/Umbraco.Core/Services/IContentService.cs index 7fb7450b46..24462cdbf4 100644 --- a/src/Umbraco.Core/Services/IContentService.cs +++ b/src/Umbraco.Core/Services/IContentService.cs @@ -32,27 +32,27 @@ namespace Umbraco.Core.Services /// /// Saves a blueprint. /// - void SaveBlueprint(IContent content, int userId = 0); + void SaveBlueprint(IContent content, int userId = Constants.Security.SuperUserId); /// /// Deletes a blueprint. /// - void DeleteBlueprint(IContent content, int userId = 0); + void DeleteBlueprint(IContent content, int userId = Constants.Security.SuperUserId); /// /// Creates a new content item from a blueprint. /// - IContent CreateContentFromBlueprint(IContent blueprint, string name, int userId = 0); + IContent CreateContentFromBlueprint(IContent blueprint, string name, int userId = Constants.Security.SuperUserId); /// /// Deletes blueprints for a content type. /// - void DeleteBlueprintsOfType(int contentTypeId, int userId = 0); + void DeleteBlueprintsOfType(int contentTypeId, int userId = Constants.Security.SuperUserId); /// /// Deletes blueprints for content types. /// - void DeleteBlueprintsOfTypes(IEnumerable contentTypeIds, int userId = 0); + void DeleteBlueprintsOfTypes(IEnumerable contentTypeIds, int userId = Constants.Security.SuperUserId); #endregion @@ -237,13 +237,13 @@ namespace Umbraco.Core.Services /// /// Saves a document. /// - OperationResult Save(IContent content, int userId = 0, bool raiseEvents = true); + OperationResult Save(IContent content, int userId = Constants.Security.SuperUserId, bool raiseEvents = true); /// /// Saves documents. /// // TODO: why only 1 result not 1 per content?! - OperationResult Save(IEnumerable contents, int userId = 0, bool raiseEvents = true); + OperationResult Save(IEnumerable contents, int userId = Constants.Security.SuperUserId, bool raiseEvents = true); /// /// Deletes a document. @@ -252,7 +252,7 @@ namespace Umbraco.Core.Services /// This method will also delete associated media files, child content and possibly associated domains. /// This method entirely clears the content from the database. /// - OperationResult Delete(IContent content, int userId = 0); + OperationResult Delete(IContent content, int userId = Constants.Security.SuperUserId); /// /// Deletes all documents of a given document type. @@ -261,7 +261,7 @@ namespace Umbraco.Core.Services /// All non-deleted descendants of the deleted documents are moved to the recycle bin. /// This operation is potentially dangerous and expensive. /// - void DeleteOfType(int documentTypeId, int userId = 0); + void DeleteOfType(int documentTypeId, int userId = Constants.Security.SuperUserId); /// /// Deletes all documents of given document types. @@ -270,17 +270,17 @@ namespace Umbraco.Core.Services /// All non-deleted descendants of the deleted documents are moved to the recycle bin. /// This operation is potentially dangerous and expensive. /// - void DeleteOfTypes(IEnumerable contentTypeIds, int userId = 0); + void DeleteOfTypes(IEnumerable contentTypeIds, int userId = Constants.Security.SuperUserId); /// /// Deletes versions of a document prior to a given date. /// - void DeleteVersions(int id, DateTime date, int userId = 0); + void DeleteVersions(int id, DateTime date, int userId = Constants.Security.SuperUserId); /// /// Deletes a version of a document. /// - void DeleteVersion(int id, int versionId, bool deletePriorVersions, int userId = 0); + void DeleteVersion(int id, int versionId, bool deletePriorVersions, int userId = Constants.Security.SuperUserId); #endregion @@ -289,7 +289,7 @@ namespace Umbraco.Core.Services /// /// Moves a document under a new parent. /// - void Move(IContent content, int parentId, int userId = 0); + void Move(IContent content, int parentId, int userId = Constants.Security.SuperUserId); /// /// Copies a document. @@ -297,7 +297,7 @@ namespace Umbraco.Core.Services /// /// Recursively copies all children. /// - IContent Copy(IContent content, int parentId, bool relateToOriginal, int userId = 0); + IContent Copy(IContent content, int parentId, bool relateToOriginal, int userId = Constants.Security.SuperUserId); /// /// Copies a document. @@ -305,12 +305,12 @@ namespace Umbraco.Core.Services /// /// Optionally recursively copies all children. /// - IContent Copy(IContent content, int parentId, bool relateToOriginal, bool recursive, int userId = 0); + IContent Copy(IContent content, int parentId, bool relateToOriginal, bool recursive, int userId = Constants.Security.SuperUserId); /// /// Moves a document to the recycle bin. /// - OperationResult MoveToRecycleBin(IContent content, int userId = 0); + OperationResult MoveToRecycleBin(IContent content, int userId = Constants.Security.SuperUserId); /// /// Empties the recycle bin. @@ -320,12 +320,12 @@ namespace Umbraco.Core.Services /// /// Sorts documents. /// - OperationResult Sort(IEnumerable items, int userId = 0, bool raiseEvents = true); + OperationResult Sort(IEnumerable items, int userId = Constants.Security.SuperUserId, bool raiseEvents = true); /// /// Sorts documents. /// - OperationResult Sort(IEnumerable ids, int userId = 0, bool raiseEvents = true); + OperationResult Sort(IEnumerable ids, int userId = Constants.Security.SuperUserId, bool raiseEvents = true); #endregion @@ -342,7 +342,7 @@ namespace Umbraco.Core.Services /// If the content type is variant, then culture can be either '*' or an actual culture, but neither 'null' nor /// 'empty'. If the content type is invariant, then culture can be either '*' or null or empty. /// - PublishResult SaveAndPublish(IContent content, string culture = "*", int userId = 0, bool raiseEvents = true); + PublishResult SaveAndPublish(IContent content, string culture = "*", int userId = Constants.Security.SuperUserId, bool raiseEvents = true); /// /// Saves and publishes a publishing document. @@ -358,7 +358,7 @@ namespace Umbraco.Core.Services /// to actually commit the changes to the database. /// The document is *always* saved, even when publishing fails. /// - PublishResult SavePublishing(IContent content, int userId = 0, bool raiseEvents = true); + PublishResult SavePublishing(IContent content, int userId = Constants.Security.SuperUserId, bool raiseEvents = true); /// /// Saves and publishes a document branch. @@ -374,7 +374,7 @@ namespace Umbraco.Core.Services /// only those documents that are already published, are republished. When true, all documents are /// published. The root of the branch is always published, regardless of . /// - IEnumerable SaveAndPublishBranch(IContent content, bool force, string culture = "*", int userId = 0); + IEnumerable SaveAndPublishBranch(IContent content, bool force, string culture = "*", int userId = Constants.Security.SuperUserId); /// /// Saves and publishes a document branch. @@ -388,7 +388,7 @@ namespace Umbraco.Core.Services /// only those documents that are already published, are republished. When true, all documents are /// published. The root of the branch is always published, regardless of . /// - IEnumerable SaveAndPublishBranch(IContent content, bool force, string[] cultures, int userId = 0); + IEnumerable SaveAndPublishBranch(IContent content, bool force, string[] cultures, int userId = Constants.Security.SuperUserId); /// /// Saves and publishes a document branch. @@ -413,7 +413,7 @@ namespace Umbraco.Core.Services IEnumerable SaveAndPublishBranch(IContent content, bool force, Func> shouldPublish, Func, bool> publishCultures, - int userId = 0); + int userId = Constants.Security.SuperUserId); /// /// Unpublishes a document. @@ -425,7 +425,7 @@ namespace Umbraco.Core.Services /// If the content type is variant, then culture can be either '*' or an actual culture, but neither null nor /// empty. If the content type is invariant, then culture can be either '*' or null or empty. /// - PublishResult Unpublish(IContent content, string culture = "*", int userId = 0); + PublishResult Unpublish(IContent content, string culture = "*", int userId = Constants.Security.SuperUserId); /// /// Gets a value indicating whether a document is path-publishable. @@ -442,7 +442,7 @@ namespace Umbraco.Core.Services /// /// Saves a document and raises the "sent to publication" events. /// - bool SendToPublication(IContent content, int userId = 0); + bool SendToPublication(IContent content, int userId = Constants.Security.SuperUserId); /// /// Publishes and unpublishes scheduled documents. @@ -477,27 +477,27 @@ namespace Umbraco.Core.Services /// /// Creates a document. /// - IContent Create(string name, Guid parentId, string documentTypeAlias, int userId = 0); + IContent Create(string name, Guid parentId, string documentTypeAlias, int userId = Constants.Security.SuperUserId); /// /// Creates a document. /// - IContent Create(string name, int parentId, string documentTypeAlias, int userId = 0); + IContent Create(string name, int parentId, string documentTypeAlias, int userId = Constants.Security.SuperUserId); /// /// Creates a document. /// - IContent Create(string name, IContent parent, string documentTypeAlias, int userId = 0); + IContent Create(string name, IContent parent, string documentTypeAlias, int userId = Constants.Security.SuperUserId); /// /// Creates and saves a document. /// - IContent CreateAndSave(string name, int parentId, string contentTypeAlias, int userId = 0); + IContent CreateAndSave(string name, int parentId, string contentTypeAlias, int userId = Constants.Security.SuperUserId); /// /// Creates and saves a document. /// - IContent CreateAndSave(string name, IContent parent, string contentTypeAlias, int userId = 0); + IContent CreateAndSave(string name, IContent parent, string contentTypeAlias, int userId = Constants.Security.SuperUserId); #endregion @@ -513,7 +513,7 @@ namespace Umbraco.Core.Services /// /// When no culture is specified, all cultures are rolled back. /// - OperationResult Rollback(int id, int versionId, string culture = "*", int userId = 0); + OperationResult Rollback(int id, int versionId, string culture = "*", int userId = Constants.Security.SuperUserId); #endregion } diff --git a/src/Umbraco.Core/Services/IContentTypeServiceBase.cs b/src/Umbraco.Core/Services/IContentTypeServiceBase.cs index 8fa77e4836..b86494adb5 100644 --- a/src/Umbraco.Core/Services/IContentTypeServiceBase.cs +++ b/src/Umbraco.Core/Services/IContentTypeServiceBase.cs @@ -47,11 +47,11 @@ namespace Umbraco.Core.Services IEnumerable GetChildren(int id); bool HasChildren(int id); - void Save(TItem item, int userId = 0); - void Save(IEnumerable items, int userId = 0); + void Save(TItem item, int userId = Constants.Security.SuperUserId); + void Save(IEnumerable items, int userId = Constants.Security.SuperUserId); - void Delete(TItem item, int userId = 0); - void Delete(IEnumerable item, int userId = 0); + void Delete(TItem item, int userId = Constants.Security.SuperUserId); + void Delete(IEnumerable item, int userId = Constants.Security.SuperUserId); Attempt ValidateComposition(TItem compo); @@ -63,15 +63,15 @@ namespace Umbraco.Core.Services /// bool HasContainerInPath(string contentPath); - Attempt> CreateContainer(int parentContainerId, string name, int userId = 0); - Attempt SaveContainer(EntityContainer container, int userId = 0); + Attempt> CreateContainer(int parentContainerId, string name, int userId = Constants.Security.SuperUserId); + Attempt SaveContainer(EntityContainer container, int userId = Constants.Security.SuperUserId); EntityContainer GetContainer(int containerId); EntityContainer GetContainer(Guid containerId); IEnumerable GetContainers(int[] containerIds); IEnumerable GetContainers(TItem contentType); IEnumerable GetContainers(string folderName, int level); - Attempt DeleteContainer(int containerId, int userId = 0); - Attempt> RenameContainer(int id, string name, int userId = 0); + Attempt DeleteContainer(int containerId, int userId = Constants.Security.SuperUserId); + Attempt> RenameContainer(int id, string name, int userId = Constants.Security.SuperUserId); Attempt> Move(TItem moving, int containerId); Attempt> Copy(TItem copying, int containerId); diff --git a/src/Umbraco.Core/Services/IDataTypeService.cs b/src/Umbraco.Core/Services/IDataTypeService.cs index 537c0e629f..3dc530e250 100644 --- a/src/Umbraco.Core/Services/IDataTypeService.cs +++ b/src/Umbraco.Core/Services/IDataTypeService.cs @@ -9,15 +9,15 @@ namespace Umbraco.Core.Services /// public interface IDataTypeService : IService { - Attempt> CreateContainer(int parentId, string name, int userId = 0); - Attempt SaveContainer(EntityContainer container, int userId = 0); + Attempt> CreateContainer(int parentId, string name, int userId = Constants.Security.SuperUserId); + Attempt SaveContainer(EntityContainer container, int userId = Constants.Security.SuperUserId); EntityContainer GetContainer(int containerId); EntityContainer GetContainer(Guid containerId); IEnumerable GetContainers(string folderName, int level); IEnumerable GetContainers(IDataType dataType); IEnumerable GetContainers(int[] containerIds); - Attempt DeleteContainer(int containerId, int userId = 0); - Attempt> RenameContainer(int id, string name, int userId = 0); + Attempt DeleteContainer(int containerId, int userId = Constants.Security.SuperUserId); + Attempt> RenameContainer(int id, string name, int userId = Constants.Security.SuperUserId); /// /// Gets a by its Name @@ -52,14 +52,14 @@ namespace Umbraco.Core.Services /// /// to save /// Id of the user issuing the save - void Save(IDataType dataType, int userId = 0); + void Save(IDataType dataType, int userId = Constants.Security.SuperUserId); /// /// Saves a collection of /// /// to save /// Id of the user issuing the save - void Save(IEnumerable dataTypeDefinitions, int userId = 0); + void Save(IEnumerable dataTypeDefinitions, int userId = Constants.Security.SuperUserId); /// /// Saves a collection of @@ -78,7 +78,7 @@ namespace Umbraco.Core.Services /// /// to delete /// Id of the user issuing the deletion - void Delete(IDataType dataType, int userId = 0); + void Delete(IDataType dataType, int userId = Constants.Security.SuperUserId); /// /// Gets a by its control Id diff --git a/src/Umbraco.Core/Services/IFileService.cs b/src/Umbraco.Core/Services/IFileService.cs index 8596424b03..5fe52559ee 100644 --- a/src/Umbraco.Core/Services/IFileService.cs +++ b/src/Umbraco.Core/Services/IFileService.cs @@ -18,12 +18,12 @@ namespace Umbraco.Core.Services IPartialView GetPartialView(string path); IPartialView GetPartialViewMacro(string path); IEnumerable GetPartialViewMacros(params string[] names); - Attempt CreatePartialView(IPartialView partialView, string snippetName = null, int userId = 0); - Attempt CreatePartialViewMacro(IPartialView partialView, string snippetName = null, int userId = 0); - bool DeletePartialView(string path, int userId = 0); - bool DeletePartialViewMacro(string path, int userId = 0); - Attempt SavePartialView(IPartialView partialView, int userId = 0); - Attempt SavePartialViewMacro(IPartialView partialView, int userId = 0); + Attempt CreatePartialView(IPartialView partialView, string snippetName = null, int userId = Constants.Security.SuperUserId); + Attempt CreatePartialViewMacro(IPartialView partialView, string snippetName = null, int userId = Constants.Security.SuperUserId); + bool DeletePartialView(string path, int userId = Constants.Security.SuperUserId); + bool DeletePartialViewMacro(string path, int userId = Constants.Security.SuperUserId); + Attempt SavePartialView(IPartialView partialView, int userId = Constants.Security.SuperUserId); + Attempt SavePartialViewMacro(IPartialView partialView, int userId = Constants.Security.SuperUserId); bool ValidatePartialView(PartialView partialView); bool ValidatePartialViewMacro(PartialView partialView); @@ -45,14 +45,14 @@ namespace Umbraco.Core.Services /// /// to save /// Optional id of the user saving the stylesheet - void SaveStylesheet(Stylesheet stylesheet, int userId = 0); + void SaveStylesheet(Stylesheet stylesheet, int userId = Constants.Security.SuperUserId); /// /// Deletes a stylesheet by its name /// /// Name incl. extension of the Stylesheet to delete /// Optional id of the user deleting the stylesheet - void DeleteStylesheet(string path, int userId = 0); + void DeleteStylesheet(string path, int userId = Constants.Security.SuperUserId); /// /// Validates a @@ -79,14 +79,14 @@ namespace Umbraco.Core.Services /// /// to save /// Optional id of the user saving the script - void SaveScript(Script script, int userId = 0); + void SaveScript(Script script, int userId = Constants.Security.SuperUserId); /// /// Deletes a script by its name /// /// Name incl. extension of the Script to delete /// Optional id of the user deleting the script - void DeleteScript(string path, int userId = 0); + void DeleteScript(string path, int userId = Constants.Security.SuperUserId); /// /// Validates a @@ -187,7 +187,7 @@ namespace Umbraco.Core.Services /// /// to save /// Optional id of the user saving the template - void SaveTemplate(ITemplate template, int userId = 0); + void SaveTemplate(ITemplate template, int userId = Constants.Security.SuperUserId); /// /// Creates a template for a content type @@ -198,16 +198,16 @@ namespace Umbraco.Core.Services /// /// The template created /// - Attempt> CreateTemplateForContentType(string contentTypeAlias, string contentTypeName, int userId = 0); + Attempt> CreateTemplateForContentType(string contentTypeAlias, string contentTypeName, int userId = Constants.Security.SuperUserId); - ITemplate CreateTemplateWithIdentity(string name, string alias, string content, ITemplate masterTemplate = null, int userId = 0); + ITemplate CreateTemplateWithIdentity(string name, string alias, string content, ITemplate masterTemplate = null, int userId = Constants.Security.SuperUserId); /// /// Deletes a template by its alias /// /// Alias of the to delete /// Optional id of the user deleting the template - void DeleteTemplate(string alias, int userId = 0); + void DeleteTemplate(string alias, int userId = Constants.Security.SuperUserId); /// /// Validates a @@ -221,7 +221,7 @@ namespace Umbraco.Core.Services /// /// List of to save /// Optional id of the user - void SaveTemplate(IEnumerable templates, int userId = 0); + void SaveTemplate(IEnumerable templates, int userId = Constants.Security.SuperUserId); /// /// Gets the content of a template as a stream. diff --git a/src/Umbraco.Core/Services/ILocalizationService.cs b/src/Umbraco.Core/Services/ILocalizationService.cs index 4882c7e829..54022d37bb 100644 --- a/src/Umbraco.Core/Services/ILocalizationService.cs +++ b/src/Umbraco.Core/Services/ILocalizationService.cs @@ -86,7 +86,7 @@ namespace Umbraco.Core.Services /// /// to save /// Optional id of the user saving the dictionary item - void Save(IDictionaryItem dictionaryItem, int userId = 0); + void Save(IDictionaryItem dictionaryItem, int userId = Constants.Security.SuperUserId); /// /// Deletes a object and its related translations @@ -94,7 +94,7 @@ namespace Umbraco.Core.Services /// /// to delete /// Optional id of the user deleting the dictionary item - void Delete(IDictionaryItem dictionaryItem, int userId = 0); + void Delete(IDictionaryItem dictionaryItem, int userId = Constants.Security.SuperUserId); /// /// Gets a by its id @@ -153,14 +153,14 @@ namespace Umbraco.Core.Services /// /// to save /// Optional id of the user saving the language - void Save(ILanguage language, int userId = 0); + void Save(ILanguage language, int userId = Constants.Security.SuperUserId); /// /// Deletes a by removing it and its usages from the db /// /// to delete /// Optional id of the user deleting the language - void Delete(ILanguage language, int userId = 0); + void Delete(ILanguage language, int userId = Constants.Security.SuperUserId); /// /// Gets the full dictionary key map. diff --git a/src/Umbraco.Core/Services/IMacroService.cs b/src/Umbraco.Core/Services/IMacroService.cs index 8c3acfd619..597c986f37 100644 --- a/src/Umbraco.Core/Services/IMacroService.cs +++ b/src/Umbraco.Core/Services/IMacroService.cs @@ -39,14 +39,14 @@ namespace Umbraco.Core.Services /// /// to delete /// Optional id of the user deleting the macro - void Delete(IMacro macro, int userId = 0); + void Delete(IMacro macro, int userId = Constants.Security.SuperUserId); /// /// Saves an /// /// to save /// Optional id of the user saving the macro - void Save(IMacro macro, int userId = 0); + void Save(IMacro macro, int userId = Constants.Security.SuperUserId); ///// ///// Gets a list all available plugins diff --git a/src/Umbraco.Core/Services/IMediaService.cs b/src/Umbraco.Core/Services/IMediaService.cs index ce2062d08d..02398c3634 100644 --- a/src/Umbraco.Core/Services/IMediaService.cs +++ b/src/Umbraco.Core/Services/IMediaService.cs @@ -37,7 +37,7 @@ namespace Umbraco.Core.Services /// Alias of the /// Optional id of the user creating the media item /// - IMedia CreateMedia(string name, Guid parentId, string mediaTypeAlias, int userId = 0); + IMedia CreateMedia(string name, Guid parentId, string mediaTypeAlias, int userId = Constants.Security.SuperUserId); /// /// Creates an object using the alias of the @@ -53,7 +53,7 @@ namespace Umbraco.Core.Services /// Alias of the /// Optional id of the user creating the media item /// - IMedia CreateMedia(string name, int parentId, string mediaTypeAlias, int userId = 0); + IMedia CreateMedia(string name, int parentId, string mediaTypeAlias, int userId = Constants.Security.SuperUserId); /// /// Creates an object using the alias of the @@ -69,7 +69,7 @@ namespace Umbraco.Core.Services /// Alias of the /// Optional id of the user creating the media item /// - IMedia CreateMedia(string name, IMedia parent, string mediaTypeAlias, int userId = 0); + IMedia CreateMedia(string name, IMedia parent, string mediaTypeAlias, int userId = Constants.Security.SuperUserId); /// /// Gets an object by Id @@ -152,14 +152,14 @@ namespace Umbraco.Core.Services /// Id of the Media's new Parent /// Id of the User moving the Media /// True if moving succeeded, otherwise False - Attempt Move(IMedia media, int parentId, int userId = 0); + Attempt Move(IMedia media, int parentId, int userId = Constants.Security.SuperUserId); /// /// Deletes an object by moving it to the Recycle Bin /// /// The to delete /// Id of the User deleting the Media - Attempt MoveToRecycleBin(IMedia media, int userId = 0); + Attempt MoveToRecycleBin(IMedia media, int userId = Constants.Security.SuperUserId); /// /// Empties the Recycle Bin by deleting all that resides in the bin @@ -172,7 +172,7 @@ namespace Umbraco.Core.Services /// This needs extra care and attention as its potentially a dangerous and extensive operation /// Id of the /// Optional Id of the user deleting Media - void DeleteMediaOfType(int mediaTypeId, int userId = 0); + void DeleteMediaOfType(int mediaTypeId, int userId = Constants.Security.SuperUserId); /// /// Deletes all media of the specified types. All Descendants of deleted media that is not of these types is moved to Recycle Bin. @@ -180,7 +180,7 @@ namespace Umbraco.Core.Services /// This needs extra care and attention as its potentially a dangerous and extensive operation /// Ids of the s /// Optional Id of the user issuing the delete operation - void DeleteMediaOfTypes(IEnumerable mediaTypeIds, int userId = 0); + void DeleteMediaOfTypes(IEnumerable mediaTypeIds, int userId = Constants.Security.SuperUserId); /// /// Permanently deletes an object @@ -191,7 +191,7 @@ namespace Umbraco.Core.Services /// /// The to delete /// Id of the User deleting the Media - Attempt Delete(IMedia media, int userId = 0); + Attempt Delete(IMedia media, int userId = Constants.Security.SuperUserId); /// /// Saves a single object @@ -199,7 +199,7 @@ namespace Umbraco.Core.Services /// The to save /// Id of the User saving the Media /// Optional boolean indicating whether or not to raise events. - Attempt Save(IMedia media, int userId = 0, bool raiseEvents = true); + Attempt Save(IMedia media, int userId = Constants.Security.SuperUserId, bool raiseEvents = true); /// /// Saves a collection of objects @@ -207,7 +207,7 @@ namespace Umbraco.Core.Services /// Collection of to save /// Id of the User saving the Media /// Optional boolean indicating whether or not to raise events. - Attempt Save(IEnumerable medias, int userId = 0, bool raiseEvents = true); + Attempt Save(IEnumerable medias, int userId = Constants.Security.SuperUserId, bool raiseEvents = true); /// /// Gets an object by its 'UniqueId' @@ -250,7 +250,7 @@ namespace Umbraco.Core.Services /// Id of the object to delete versions from /// Latest version date /// Optional Id of the User deleting versions of a Content object - void DeleteVersions(int id, DateTime versionDate, int userId = 0); + void DeleteVersions(int id, DateTime versionDate, int userId = Constants.Security.SuperUserId); /// /// Permanently deletes specific version(s) from an object. @@ -259,7 +259,7 @@ namespace Umbraco.Core.Services /// Id of the version to delete /// Boolean indicating whether to delete versions prior to the versionId /// Optional Id of the User deleting versions of a Content object - void DeleteVersion(int id, int versionId, bool deletePriorVersions, int userId = 0); + void DeleteVersion(int id, int versionId, bool deletePriorVersions, int userId = Constants.Security.SuperUserId); /// /// Gets an object from the path stored in the 'umbracoFile' property. @@ -304,7 +304,7 @@ namespace Umbraco.Core.Services /// /// /// True if sorting succeeded, otherwise False - bool Sort(IEnumerable items, int userId = 0, bool raiseEvents = true); + bool Sort(IEnumerable items, int userId = Constants.Security.SuperUserId, bool raiseEvents = true); /// /// Creates an object using the alias of the @@ -319,7 +319,7 @@ namespace Umbraco.Core.Services /// Alias of the /// Optional id of the user creating the media item /// - IMedia CreateMediaWithIdentity(string name, IMedia parent, string mediaTypeAlias, int userId = 0); + IMedia CreateMediaWithIdentity(string name, IMedia parent, string mediaTypeAlias, int userId = Constants.Security.SuperUserId); /// /// Creates an object using the alias of the @@ -334,7 +334,7 @@ namespace Umbraco.Core.Services /// Alias of the /// Optional id of the user creating the media item /// - IMedia CreateMediaWithIdentity(string name, int parentId, string mediaTypeAlias, int userId = 0); + IMedia CreateMediaWithIdentity(string name, int parentId, string mediaTypeAlias, int userId = Constants.Security.SuperUserId); /// /// Gets the content of a media as a stream. diff --git a/src/Umbraco.Core/Services/IPackagingService.cs b/src/Umbraco.Core/Services/IPackagingService.cs index c14882fe7a..b38b5a426b 100644 --- a/src/Umbraco.Core/Services/IPackagingService.cs +++ b/src/Umbraco.Core/Services/IPackagingService.cs @@ -27,7 +27,7 @@ namespace Umbraco.Core.Services /// /// /// - IEnumerable InstallCompiledPackageFiles(PackageDefinition packageDefinition, FileInfo packageFile, int userId = 0); + IEnumerable InstallCompiledPackageFiles(PackageDefinition packageDefinition, FileInfo packageFile, int userId = Constants.Security.SuperUserId); /// /// Installs the data, entities, objects contained in an umbraco package file (zip) @@ -35,7 +35,7 @@ namespace Umbraco.Core.Services /// /// /// - InstallationSummary InstallCompiledPackageData(PackageDefinition packageDefinition, FileInfo packageFile, int userId = 0); + InstallationSummary InstallCompiledPackageData(PackageDefinition packageDefinition, FileInfo packageFile, int userId = Constants.Security.SuperUserId); /// /// Uninstalls all versions of the package by name @@ -43,7 +43,7 @@ namespace Umbraco.Core.Services /// /// /// - UninstallationSummary UninstallPackage(string packageName, int userId = 0); + UninstallationSummary UninstallPackage(string packageName, int userId = Constants.Security.SuperUserId); #endregion @@ -75,7 +75,7 @@ namespace Umbraco.Core.Services /// If the package is an upgrade, the original/current PackageDefinition is returned /// PackageInstallType GetPackageInstallType(string packageName, SemVersion packageVersion, out PackageDefinition alreadyInstalled); - void DeleteInstalledPackage(int packageId, int userId = 0); + void DeleteInstalledPackage(int packageId, int userId = Constants.Security.SuperUserId); /// /// Persists a package definition to storage @@ -89,7 +89,7 @@ namespace Umbraco.Core.Services IEnumerable GetAllCreatedPackages(); PackageDefinition GetCreatedPackageById(int id); - void DeleteCreatedPackage(int id, int userId = 0); + void DeleteCreatedPackage(int id, int userId = Constants.Security.SuperUserId); /// /// Persists a package definition to storage diff --git a/src/Umbraco.Core/Services/Implement/ContentService.cs b/src/Umbraco.Core/Services/Implement/ContentService.cs index c5745090f9..9e78f902e1 100644 --- a/src/Umbraco.Core/Services/Implement/ContentService.cs +++ b/src/Umbraco.Core/Services/Implement/ContentService.cs @@ -162,7 +162,7 @@ namespace Umbraco.Core.Services.Implement /// Alias of the /// Optional id of the user creating the content /// - public IContent Create(string name, Guid parentId, string contentTypeAlias, int userId = 0) + public IContent Create(string name, Guid parentId, string contentTypeAlias, int userId = Constants.Security.SuperUserId) { // TODO: what about culture? @@ -182,7 +182,7 @@ namespace Umbraco.Core.Services.Implement /// The alias of the content type. /// The optional id of the user creating the content. /// The content object. - public IContent Create(string name, int parentId, string contentTypeAlias, int userId = 0) + public IContent Create(string name, int parentId, string contentTypeAlias, int userId = Constants.Security.SuperUserId) { // TODO: what about culture? @@ -215,7 +215,7 @@ namespace Umbraco.Core.Services.Implement /// The alias of the content type. /// The optional id of the user creating the content. /// The content object. - public IContent Create(string name, IContent parent, string contentTypeAlias, int userId = 0) + public IContent Create(string name, IContent parent, string contentTypeAlias, int userId = Constants.Security.SuperUserId) { // TODO: what about culture? @@ -246,7 +246,7 @@ namespace Umbraco.Core.Services.Implement /// The alias of the content type. /// The optional id of the user creating the content. /// The content object. - public IContent CreateAndSave(string name, int parentId, string contentTypeAlias, int userId = 0) + public IContent CreateAndSave(string name, int parentId, string contentTypeAlias, int userId = Constants.Security.SuperUserId) { // TODO: what about culture? @@ -280,7 +280,7 @@ namespace Umbraco.Core.Services.Implement /// The alias of the content type. /// The optional id of the user creating the content. /// The content object. - public IContent CreateAndSave(string name, IContent parent, string contentTypeAlias, int userId = 0) + public IContent CreateAndSave(string name, IContent parent, string contentTypeAlias, int userId = Constants.Security.SuperUserId) { // TODO: what about culture? @@ -751,7 +751,7 @@ namespace Umbraco.Core.Services.Implement #region Save, Publish, Unpublish /// - public OperationResult Save(IContent content, int userId = 0, bool raiseEvents = true) + public OperationResult Save(IContent content, int userId = Constants.Security.SuperUserId, bool raiseEvents = true) { var publishedState = content.PublishedState; if (publishedState != PublishedState.Published && publishedState != PublishedState.Unpublished) @@ -810,7 +810,7 @@ namespace Umbraco.Core.Services.Implement } /// - public OperationResult Save(IEnumerable contents, int userId = 0, bool raiseEvents = true) + public OperationResult Save(IEnumerable contents, int userId = Constants.Security.SuperUserId, bool raiseEvents = true) { var evtMsgs = EventMessagesFactory.Get(); var contentsA = contents.ToArray(); @@ -851,7 +851,7 @@ namespace Umbraco.Core.Services.Implement } /// - public PublishResult SaveAndPublish(IContent content, string culture = "*", int userId = 0, bool raiseEvents = true) + public PublishResult SaveAndPublish(IContent content, string culture = "*", int userId = Constants.Security.SuperUserId, bool raiseEvents = true) { var evtMsgs = EventMessagesFactory.Get(); @@ -895,7 +895,7 @@ namespace Umbraco.Core.Services.Implement } /// - public PublishResult Unpublish(IContent content, string culture = "*", int userId = 0) + public PublishResult Unpublish(IContent content, string culture = "*", int userId = Constants.Security.SuperUserId) { var evtMsgs = EventMessagesFactory.Get(); @@ -942,7 +942,7 @@ namespace Umbraco.Core.Services.Implement } /// - public PublishResult SavePublishing(IContent content, int userId = 0, bool raiseEvents = true) + public PublishResult SavePublishing(IContent content, int userId = Constants.Security.SuperUserId, bool raiseEvents = true) { using (var scope = ScopeProvider.CreateScope()) { @@ -953,7 +953,7 @@ namespace Umbraco.Core.Services.Implement } } - private PublishResult SavePublishingInternal(IScope scope, IContent content, int userId = 0, bool raiseEvents = true, bool branchOne = false, bool branchRoot = false) + private PublishResult SavePublishingInternal(IScope scope, IContent content, int userId = Constants.Security.SuperUserId, bool raiseEvents = true, bool branchOne = false, bool branchRoot = false) { var evtMsgs = EventMessagesFactory.Get(); PublishResult publishResult = null; @@ -1315,7 +1315,7 @@ namespace Umbraco.Core.Services.Implement /// - public IEnumerable SaveAndPublishBranch(IContent content, bool force, string culture = "*", int userId = 0) + public IEnumerable SaveAndPublishBranch(IContent content, bool force, string culture = "*", int userId = Constants.Security.SuperUserId) { // note: EditedValue and PublishedValue are objects here, so it is important to .Equals() // and not to == them, else we would be comparing references, and that is a bad thing @@ -1357,7 +1357,7 @@ namespace Umbraco.Core.Services.Implement } /// - public IEnumerable SaveAndPublishBranch(IContent content, bool force, string[] cultures, int userId = 0) + public IEnumerable SaveAndPublishBranch(IContent content, bool force, string[] cultures, int userId = Constants.Security.SuperUserId) { // note: EditedValue and PublishedValue are objects here, so it is important to .Equals() // and not to == them, else we would be comparing references, and that is a bad thing @@ -1397,7 +1397,7 @@ namespace Umbraco.Core.Services.Implement public IEnumerable SaveAndPublishBranch(IContent document, bool force, Func> shouldPublish, Func, bool> publishCultures, - int userId = 0) + int userId = Constants.Security.SuperUserId) { if (shouldPublish == null) throw new ArgumentNullException(nameof(shouldPublish)); if (publishCultures == null) throw new ArgumentNullException(nameof(publishCultures)); @@ -1574,7 +1574,7 @@ namespace Umbraco.Core.Services.Implement /// Id of the object to delete versions from /// Latest version date /// Optional Id of the User deleting versions of a Content object - public void DeleteVersions(int id, DateTime versionDate, int userId = 0) + public void DeleteVersions(int id, DateTime versionDate, int userId = Constants.Security.SuperUserId) { using (var scope = ScopeProvider.CreateScope()) { @@ -1604,7 +1604,7 @@ namespace Umbraco.Core.Services.Implement /// Id of the version to delete /// Boolean indicating whether to delete versions prior to the versionId /// Optional Id of the User deleting versions of a Content object - public void DeleteVersion(int id, int versionId, bool deletePriorVersions, int userId = 0) + public void DeleteVersion(int id, int versionId, bool deletePriorVersions, int userId = Constants.Security.SuperUserId) { using (var scope = ScopeProvider.CreateScope()) { @@ -1690,7 +1690,7 @@ namespace Umbraco.Core.Services.Implement /// The to move /// Id of the Content's new Parent /// Optional Id of the User moving the Content - public void Move(IContent content, int parentId, int userId = 0) + public void Move(IContent content, int parentId, int userId = Constants.Security.SuperUserId) { // if moving to the recycle bin then use the proper method if (parentId == Constants.System.RecycleBinContent) @@ -1866,7 +1866,7 @@ namespace Umbraco.Core.Services.Implement /// Boolean indicating whether the copy should be related to the original /// Optional Id of the User copying the Content /// The newly created object - public IContent Copy(IContent content, int parentId, bool relateToOriginal, int userId = 0) + public IContent Copy(IContent content, int parentId, bool relateToOriginal, int userId = Constants.Security.SuperUserId) { return Copy(content, parentId, relateToOriginal, true, userId); } @@ -1881,7 +1881,7 @@ namespace Umbraco.Core.Services.Implement /// A value indicating whether to recursively copy children. /// Optional Id of the User copying the Content /// The newly created object - public IContent Copy(IContent content, int parentId, bool relateToOriginal, bool recursive, int userId = 0) + public IContent Copy(IContent content, int parentId, bool relateToOriginal, bool recursive, int userId = Constants.Security.SuperUserId) { var copy = content.DeepCloneWithResetIdentities(); copy.ParentId = parentId; @@ -1984,7 +1984,7 @@ namespace Umbraco.Core.Services.Implement /// The to send to publication /// Optional Id of the User issuing the send to publication /// True if sending publication was successful otherwise false - public bool SendToPublication(IContent content, int userId = 0) + public bool SendToPublication(IContent content, int userId = Constants.Security.SuperUserId) { using (var scope = ScopeProvider.CreateScope()) { @@ -2038,7 +2038,7 @@ namespace Umbraco.Core.Services.Implement /// /// /// Result indicating what action was taken when handling the command. - public OperationResult Sort(IEnumerable items, int userId = 0, bool raiseEvents = true) + public OperationResult Sort(IEnumerable items, int userId = Constants.Security.SuperUserId, bool raiseEvents = true) { var evtMsgs = EventMessagesFactory.Get(); @@ -2067,7 +2067,7 @@ namespace Umbraco.Core.Services.Implement /// /// /// Result indicating what action was taken when handling the command. - public OperationResult Sort(IEnumerable ids, int userId = 0, bool raiseEvents = true) + public OperationResult Sort(IEnumerable ids, int userId = Constants.Security.SuperUserId, bool raiseEvents = true) { var evtMsgs = EventMessagesFactory.Get(); @@ -2550,7 +2550,7 @@ namespace Umbraco.Core.Services.Implement /// /// Id of the /// Optional Id of the user issuing the delete operation - public void DeleteOfTypes(IEnumerable contentTypeIds, int userId = 0) + public void DeleteOfTypes(IEnumerable contentTypeIds, int userId = Constants.Security.SuperUserId) { // TODO: This currently this is called from the ContentTypeService but that needs to change, // if we are deleting a content type, we should just delete the data and do this operation slightly differently. @@ -2626,7 +2626,7 @@ namespace Umbraco.Core.Services.Implement /// This needs extra care and attention as its potentially a dangerous and extensive operation /// Id of the /// Optional id of the user deleting the media - public void DeleteOfType(int contentTypeId, int userId = 0) + public void DeleteOfType(int contentTypeId, int userId = Constants.Security.SuperUserId) { DeleteOfTypes(new[] { contentTypeId }, userId); } @@ -2684,7 +2684,7 @@ namespace Umbraco.Core.Services.Implement } } - public void SaveBlueprint(IContent content, int userId = 0) + public void SaveBlueprint(IContent content, int userId = Constants.Security.SuperUserId) { //always ensure the blueprint is at the root if (content.ParentId != -1) @@ -2710,7 +2710,7 @@ namespace Umbraco.Core.Services.Implement } } - public void DeleteBlueprint(IContent content, int userId = 0) + public void DeleteBlueprint(IContent content, int userId = Constants.Security.SuperUserId) { using (var scope = ScopeProvider.CreateScope()) { @@ -2723,7 +2723,7 @@ namespace Umbraco.Core.Services.Implement private static readonly string[] ArrayOfOneNullString = { null }; - public IContent CreateContentFromBlueprint(IContent blueprint, string name, int userId = 0) + public IContent CreateContentFromBlueprint(IContent blueprint, string name, int userId = Constants.Security.SuperUserId) { if (blueprint == null) throw new ArgumentNullException(nameof(blueprint)); @@ -2772,7 +2772,7 @@ namespace Umbraco.Core.Services.Implement } } - public void DeleteBlueprintsOfTypes(IEnumerable contentTypeIds, int userId = 0) + public void DeleteBlueprintsOfTypes(IEnumerable contentTypeIds, int userId = Constants.Security.SuperUserId) { using (var scope = ScopeProvider.CreateScope()) { @@ -2799,7 +2799,7 @@ namespace Umbraco.Core.Services.Implement } } - public void DeleteBlueprintsOfType(int contentTypeId, int userId = 0) + public void DeleteBlueprintsOfType(int contentTypeId, int userId = Constants.Security.SuperUserId) { DeleteBlueprintsOfTypes(new[] { contentTypeId }, userId); } @@ -2808,7 +2808,7 @@ namespace Umbraco.Core.Services.Implement #region Rollback - public OperationResult Rollback(int id, int versionId, string culture = "*", int userId = 0) + public OperationResult Rollback(int id, int versionId, string culture = "*", int userId = Constants.Security.SuperUserId) { var evtMsgs = EventMessagesFactory.Get(); diff --git a/src/Umbraco.Core/Services/Implement/ContentTypeServiceBaseOfTRepositoryTItemTService.cs b/src/Umbraco.Core/Services/Implement/ContentTypeServiceBaseOfTRepositoryTItemTService.cs index d4cb890953..1f1f0d9ac3 100644 --- a/src/Umbraco.Core/Services/Implement/ContentTypeServiceBaseOfTRepositoryTItemTService.cs +++ b/src/Umbraco.Core/Services/Implement/ContentTypeServiceBaseOfTRepositoryTItemTService.cs @@ -376,7 +376,7 @@ namespace Umbraco.Core.Services.Implement #region Save - public void Save(TItem item, int userId = 0) + public void Save(TItem item, int userId = Constants.Security.SuperUserId) { using (var scope = ScopeProvider.CreateScope()) { @@ -414,7 +414,7 @@ namespace Umbraco.Core.Services.Implement } } - public void Save(IEnumerable items, int userId = 0) + public void Save(IEnumerable items, int userId = Constants.Security.SuperUserId) { var itemsA = items.ToArray(); @@ -460,7 +460,7 @@ namespace Umbraco.Core.Services.Implement #region Delete - public void Delete(TItem item, int userId = 0) + public void Delete(TItem item, int userId = Constants.Security.SuperUserId) { using (var scope = ScopeProvider.CreateScope()) { @@ -514,7 +514,7 @@ namespace Umbraco.Core.Services.Implement } } - public void Delete(IEnumerable items, int userId = 0) + public void Delete(IEnumerable items, int userId = Constants.Security.SuperUserId) { var itemsA = items.ToArray(); @@ -735,7 +735,7 @@ namespace Umbraco.Core.Services.Implement protected Guid ContainerObjectType => EntityContainer.GetContainerObjectType(ContainedObjectType); - public Attempt> CreateContainer(int parentId, string name, int userId = 0) + public Attempt> CreateContainer(int parentId, string name, int userId = Constants.Security.SuperUserId) { var evtMsgs = EventMessagesFactory.Get(); using (var scope = ScopeProvider.CreateScope()) @@ -775,7 +775,7 @@ namespace Umbraco.Core.Services.Implement } } - public Attempt SaveContainer(EntityContainer container, int userId = 0) + public Attempt SaveContainer(EntityContainer container, int userId = Constants.Security.SuperUserId) { var evtMsgs = EventMessagesFactory.Get(); @@ -869,7 +869,7 @@ namespace Umbraco.Core.Services.Implement } } - public Attempt DeleteContainer(int containerId, int userId = 0) + public Attempt DeleteContainer(int containerId, int userId = Constants.Security.SuperUserId) { var evtMsgs = EventMessagesFactory.Get(); using (var scope = ScopeProvider.CreateScope()) @@ -906,7 +906,7 @@ namespace Umbraco.Core.Services.Implement } } - public Attempt> RenameContainer(int id, string name, int userId = 0) + public Attempt> RenameContainer(int id, string name, int userId = Constants.Security.SuperUserId) { var evtMsgs = EventMessagesFactory.Get(); using (var scope = ScopeProvider.CreateScope()) diff --git a/src/Umbraco.Core/Services/Implement/DataTypeService.cs b/src/Umbraco.Core/Services/Implement/DataTypeService.cs index 97368e9047..445daddff4 100644 --- a/src/Umbraco.Core/Services/Implement/DataTypeService.cs +++ b/src/Umbraco.Core/Services/Implement/DataTypeService.cs @@ -38,7 +38,7 @@ namespace Umbraco.Core.Services.Implement #region Containers - public Attempt> CreateContainer(int parentId, string name, int userId = 0) + public Attempt> CreateContainer(int parentId, string name, int userId = Constants.Security.SuperUserId) { var evtMsgs = EventMessagesFactory.Get(); using (var scope = ScopeProvider.CreateScope()) @@ -119,7 +119,7 @@ namespace Umbraco.Core.Services.Implement } } - public Attempt SaveContainer(EntityContainer container, int userId = 0) + public Attempt SaveContainer(EntityContainer container, int userId = Constants.Security.SuperUserId) { var evtMsgs = EventMessagesFactory.Get(); @@ -153,7 +153,7 @@ namespace Umbraco.Core.Services.Implement return OperationResult.Attempt.Succeed(evtMsgs); } - public Attempt DeleteContainer(int containerId, int userId = 0) + public Attempt DeleteContainer(int containerId, int userId = Constants.Security.SuperUserId) { var evtMsgs = EventMessagesFactory.Get(); using (var scope = ScopeProvider.CreateScope()) @@ -186,7 +186,7 @@ namespace Umbraco.Core.Services.Implement return OperationResult.Attempt.Succeed(evtMsgs); } - public Attempt> RenameContainer(int id, string name, int userId = 0) + public Attempt> RenameContainer(int id, string name, int userId = Constants.Security.SuperUserId) { var evtMsgs = EventMessagesFactory.Get(); using (var scope = ScopeProvider.CreateScope()) @@ -331,7 +331,7 @@ namespace Umbraco.Core.Services.Implement /// /// to save /// Id of the user issuing the save - public void Save(IDataType dataType, int userId = 0) + public void Save(IDataType dataType, int userId = Constants.Security.SuperUserId) { dataType.CreatorId = userId; @@ -363,7 +363,7 @@ namespace Umbraco.Core.Services.Implement /// /// to save /// Id of the user issuing the save - public void Save(IEnumerable dataTypeDefinitions, int userId = 0) + public void Save(IEnumerable dataTypeDefinitions, int userId = Constants.Security.SuperUserId) { Save(dataTypeDefinitions, userId, true); } @@ -413,7 +413,7 @@ namespace Umbraco.Core.Services.Implement /// /// to delete /// Optional Id of the user issuing the deletion - public void Delete(IDataType dataType, int userId = 0) + public void Delete(IDataType dataType, int userId = Constants.Security.SuperUserId) { using (var scope = ScopeProvider.CreateScope()) { diff --git a/src/Umbraco.Core/Services/Implement/FileService.cs b/src/Umbraco.Core/Services/Implement/FileService.cs index d85b0ca1ba..596d033ae8 100644 --- a/src/Umbraco.Core/Services/Implement/FileService.cs +++ b/src/Umbraco.Core/Services/Implement/FileService.cs @@ -74,7 +74,7 @@ namespace Umbraco.Core.Services.Implement /// /// to save /// - public void SaveStylesheet(Stylesheet stylesheet, int userId = 0) + public void SaveStylesheet(Stylesheet stylesheet, int userId = Constants.Security.SuperUserId) { using (var scope = ScopeProvider.CreateScope()) { @@ -100,7 +100,7 @@ namespace Umbraco.Core.Services.Implement /// /// Name incl. extension of the Stylesheet to delete /// - public void DeleteStylesheet(string path, int userId = 0) + public void DeleteStylesheet(string path, int userId = Constants.Security.SuperUserId) { using (var scope = ScopeProvider.CreateScope()) { @@ -217,7 +217,7 @@ namespace Umbraco.Core.Services.Implement /// /// to save /// - public void SaveScript(Script script, int userId = 0) + public void SaveScript(Script script, int userId = Constants.Security.SuperUserId) { using (var scope = ScopeProvider.CreateScope()) { @@ -242,7 +242,7 @@ namespace Umbraco.Core.Services.Implement /// /// Name incl. extension of the Script to delete /// - public void DeleteScript(string path, int userId = 0) + public void DeleteScript(string path, int userId = Constants.Security.SuperUserId) { using (var scope = ScopeProvider.CreateScope()) { @@ -338,7 +338,7 @@ namespace Umbraco.Core.Services.Implement /// /// The template created /// - public Attempt> CreateTemplateForContentType(string contentTypeAlias, string contentTypeName, int userId = 0) + public Attempt> CreateTemplateForContentType(string contentTypeAlias, string contentTypeName, int userId = Constants.Security.SuperUserId) { var template = new Template(contentTypeName, //NOTE: We are NOT passing in the content type alias here, we want to use it's name since we don't @@ -395,7 +395,7 @@ namespace Umbraco.Core.Services.Implement /// /// /// - public ITemplate CreateTemplateWithIdentity(string name, string alias, string content, ITemplate masterTemplate = null, int userId = 0) + public ITemplate CreateTemplateWithIdentity(string name, string alias, string content, ITemplate masterTemplate = null, int userId = Constants.Security.SuperUserId) { // file might already be on disk, if so grab the content to avoid overwriting var template = new Template(name, alias) @@ -529,7 +529,7 @@ namespace Umbraco.Core.Services.Implement /// /// to save /// - public void SaveTemplate(ITemplate template, int userId = 0) + public void SaveTemplate(ITemplate template, int userId = Constants.Security.SuperUserId) { using (var scope = ScopeProvider.CreateScope()) { @@ -553,7 +553,7 @@ namespace Umbraco.Core.Services.Implement /// /// List of to save /// Optional id of the user - public void SaveTemplate(IEnumerable templates, int userId = 0) + public void SaveTemplate(IEnumerable templates, int userId = Constants.Security.SuperUserId) { var templatesA = templates.ToArray(); using (var scope = ScopeProvider.CreateScope()) @@ -579,7 +579,7 @@ namespace Umbraco.Core.Services.Implement /// /// Alias of the to delete /// - public void DeleteTemplate(string alias, int userId = 0) + public void DeleteTemplate(string alias, int userId = Constants.Security.SuperUserId) { using (var scope = ScopeProvider.CreateScope()) { @@ -723,17 +723,17 @@ namespace Umbraco.Core.Services.Implement } } - public Attempt CreatePartialView(IPartialView partialView, string snippetName = null, int userId = 0) + public Attempt CreatePartialView(IPartialView partialView, string snippetName = null, int userId = Constants.Security.SuperUserId) { return CreatePartialViewMacro(partialView, PartialViewType.PartialView, snippetName, userId); } - public Attempt CreatePartialViewMacro(IPartialView partialView, string snippetName = null, int userId = 0) + public Attempt CreatePartialViewMacro(IPartialView partialView, string snippetName = null, int userId = Constants.Security.SuperUserId) { return CreatePartialViewMacro(partialView, PartialViewType.PartialViewMacro, snippetName, userId); } - private Attempt CreatePartialViewMacro(IPartialView partialView, PartialViewType partialViewType, string snippetName = null, int userId = 0) + private Attempt CreatePartialViewMacro(IPartialView partialView, PartialViewType partialViewType, string snippetName = null, int userId = Constants.Security.SuperUserId) { string partialViewHeader; switch (partialViewType) @@ -799,17 +799,17 @@ namespace Umbraco.Core.Services.Implement return Attempt.Succeed(partialView); } - public bool DeletePartialView(string path, int userId = 0) + public bool DeletePartialView(string path, int userId = Constants.Security.SuperUserId) { return DeletePartialViewMacro(path, PartialViewType.PartialView, userId); } - public bool DeletePartialViewMacro(string path, int userId = 0) + public bool DeletePartialViewMacro(string path, int userId = Constants.Security.SuperUserId) { return DeletePartialViewMacro(path, PartialViewType.PartialViewMacro, userId); } - private bool DeletePartialViewMacro(string path, PartialViewType partialViewType, int userId = 0) + private bool DeletePartialViewMacro(string path, PartialViewType partialViewType, int userId = Constants.Security.SuperUserId) { using (var scope = ScopeProvider.CreateScope()) { @@ -839,17 +839,17 @@ namespace Umbraco.Core.Services.Implement return true; } - public Attempt SavePartialView(IPartialView partialView, int userId = 0) + public Attempt SavePartialView(IPartialView partialView, int userId = Constants.Security.SuperUserId) { return SavePartialView(partialView, PartialViewType.PartialView, userId); } - public Attempt SavePartialViewMacro(IPartialView partialView, int userId = 0) + public Attempt SavePartialViewMacro(IPartialView partialView, int userId = Constants.Security.SuperUserId) { return SavePartialView(partialView, PartialViewType.PartialViewMacro, userId); } - private Attempt SavePartialView(IPartialView partialView, PartialViewType partialViewType, int userId = 0) + private Attempt SavePartialView(IPartialView partialView, PartialViewType partialViewType, int userId = Constants.Security.SuperUserId) { using (var scope = ScopeProvider.CreateScope()) { diff --git a/src/Umbraco.Core/Services/Implement/LocalizationService.cs b/src/Umbraco.Core/Services/Implement/LocalizationService.cs index 678ea10da2..251261cfc8 100644 --- a/src/Umbraco.Core/Services/Implement/LocalizationService.cs +++ b/src/Umbraco.Core/Services/Implement/LocalizationService.cs @@ -227,7 +227,7 @@ namespace Umbraco.Core.Services.Implement /// /// to save /// Optional id of the user saving the dictionary item - public void Save(IDictionaryItem dictionaryItem, int userId = 0) + public void Save(IDictionaryItem dictionaryItem, int userId = Constants.Security.SuperUserId) { using (var scope = ScopeProvider.CreateScope()) { @@ -256,7 +256,7 @@ namespace Umbraco.Core.Services.Implement /// /// to delete /// Optional id of the user deleting the dictionary item - public void Delete(IDictionaryItem dictionaryItem, int userId = 0) + public void Delete(IDictionaryItem dictionaryItem, int userId = Constants.Security.SuperUserId) { using (var scope = ScopeProvider.CreateScope()) { @@ -356,7 +356,7 @@ namespace Umbraco.Core.Services.Implement /// /// to save /// Optional id of the user saving the language - public void Save(ILanguage language, int userId = 0) + public void Save(ILanguage language, int userId = Constants.Security.SuperUserId) { using (var scope = ScopeProvider.CreateScope()) { @@ -409,7 +409,7 @@ namespace Umbraco.Core.Services.Implement /// /// to delete /// Optional id of the user deleting the language - public void Delete(ILanguage language, int userId = 0) + public void Delete(ILanguage language, int userId = Constants.Security.SuperUserId) { using (var scope = ScopeProvider.CreateScope()) { diff --git a/src/Umbraco.Core/Services/Implement/MacroService.cs b/src/Umbraco.Core/Services/Implement/MacroService.cs index d4f2d95bbb..a6631aae4c 100644 --- a/src/Umbraco.Core/Services/Implement/MacroService.cs +++ b/src/Umbraco.Core/Services/Implement/MacroService.cs @@ -81,7 +81,7 @@ namespace Umbraco.Core.Services.Implement /// /// to delete /// Optional id of the user deleting the macro - public void Delete(IMacro macro, int userId = 0) + public void Delete(IMacro macro, int userId = Constants.Security.SuperUserId) { using (var scope = ScopeProvider.CreateScope()) { @@ -106,7 +106,7 @@ namespace Umbraco.Core.Services.Implement /// /// to save /// Optional Id of the user deleting the macro - public void Save(IMacro macro, int userId = 0) + public void Save(IMacro macro, int userId = Constants.Security.SuperUserId) { using (var scope = ScopeProvider.CreateScope()) { diff --git a/src/Umbraco.Core/Services/Implement/MediaService.cs b/src/Umbraco.Core/Services/Implement/MediaService.cs index e7a42e28e4..1fa9b9fdb4 100644 --- a/src/Umbraco.Core/Services/Implement/MediaService.cs +++ b/src/Umbraco.Core/Services/Implement/MediaService.cs @@ -112,7 +112,7 @@ namespace Umbraco.Core.Services.Implement /// Alias of the /// Optional id of the user creating the media item /// - public IMedia CreateMedia(string name, Guid parentId, string mediaTypeAlias, int userId = 0) + public IMedia CreateMedia(string name, Guid parentId, string mediaTypeAlias, int userId = Constants.Security.SuperUserId) { var parent = GetById(parentId); return CreateMedia(name, parent, mediaTypeAlias, userId); @@ -130,7 +130,7 @@ namespace Umbraco.Core.Services.Implement /// The alias of the media type. /// The optional id of the user creating the media. /// The media object. - public IMedia CreateMedia(string name, int parentId, string mediaTypeAlias, int userId = 0) + public IMedia CreateMedia(string name, int parentId, string mediaTypeAlias, int userId = Constants.Security.SuperUserId) { var mediaType = GetMediaType(mediaTypeAlias); if (mediaType == null) @@ -160,7 +160,7 @@ namespace Umbraco.Core.Services.Implement /// The alias of the media type. /// The optional id of the user creating the media. /// The media object. - public IMedia CreateMedia(string name, string mediaTypeAlias, int userId = 0) + public IMedia CreateMedia(string name, string mediaTypeAlias, int userId = Constants.Security.SuperUserId) { // not locking since not saving anything @@ -190,7 +190,7 @@ namespace Umbraco.Core.Services.Implement /// The alias of the media type. /// The optional id of the user creating the media. /// The media object. - public IMedia CreateMedia(string name, IMedia parent, string mediaTypeAlias, int userId = 0) + public IMedia CreateMedia(string name, IMedia parent, string mediaTypeAlias, int userId = Constants.Security.SuperUserId) { if (parent == null) throw new ArgumentNullException(nameof(parent)); @@ -219,7 +219,7 @@ namespace Umbraco.Core.Services.Implement /// The alias of the media type. /// The optional id of the user creating the media. /// The media object. - public IMedia CreateMediaWithIdentity(string name, int parentId, string mediaTypeAlias, int userId = 0) + public IMedia CreateMediaWithIdentity(string name, int parentId, string mediaTypeAlias, int userId = Constants.Security.SuperUserId) { using (var scope = ScopeProvider.CreateScope()) { @@ -251,7 +251,7 @@ namespace Umbraco.Core.Services.Implement /// The alias of the media type. /// The optional id of the user creating the media. /// The media object. - public IMedia CreateMediaWithIdentity(string name, IMedia parent, string mediaTypeAlias, int userId = 0) + public IMedia CreateMediaWithIdentity(string name, IMedia parent, string mediaTypeAlias, int userId = Constants.Security.SuperUserId) { if (parent == null) throw new ArgumentNullException(nameof(parent)); @@ -632,7 +632,7 @@ namespace Umbraco.Core.Services.Implement /// The to save /// Id of the User saving the Media /// Optional boolean indicating whether or not to raise events. - public Attempt Save(IMedia media, int userId = 0, bool raiseEvents = true) + public Attempt Save(IMedia media, int userId = Constants.Security.SuperUserId, bool raiseEvents = true) { var evtMsgs = EventMessagesFactory.Get(); @@ -677,7 +677,7 @@ namespace Umbraco.Core.Services.Implement /// Collection of to save /// Id of the User saving the Media /// Optional boolean indicating whether or not to raise events. - public Attempt Save(IEnumerable medias, int userId = 0, bool raiseEvents = true) + public Attempt Save(IEnumerable medias, int userId = Constants.Security.SuperUserId, bool raiseEvents = true) { var evtMsgs = EventMessagesFactory.Get(); var mediasA = medias.ToArray(); @@ -724,7 +724,7 @@ namespace Umbraco.Core.Services.Implement /// /// The to delete /// Id of the User deleting the Media - public Attempt Delete(IMedia media, int userId = 0) + public Attempt Delete(IMedia media, int userId = Constants.Security.SuperUserId) { var evtMsgs = EventMessagesFactory.Get(); @@ -785,7 +785,7 @@ namespace Umbraco.Core.Services.Implement /// Id of the object to delete versions from /// Latest version date /// Optional Id of the User deleting versions of a Media object - public void DeleteVersions(int id, DateTime versionDate, int userId = 0) + public void DeleteVersions(int id, DateTime versionDate, int userId = Constants.Security.SuperUserId) { using (var scope = ScopeProvider.CreateScope()) { @@ -809,7 +809,7 @@ namespace Umbraco.Core.Services.Implement } } - private void DeleteVersions(IScope scope, bool wlock, int id, DateTime versionDate, int userId = 0) + private void DeleteVersions(IScope scope, bool wlock, int id, DateTime versionDate, int userId = Constants.Security.SuperUserId) { var args = new DeleteRevisionsEventArgs(id, dateToRetain: versionDate); if (scope.Events.DispatchCancelable(DeletingVersions, this, args)) @@ -832,7 +832,7 @@ namespace Umbraco.Core.Services.Implement /// Id of the version to delete /// Boolean indicating whether to delete versions prior to the versionId /// Optional Id of the User deleting versions of a Media object - public void DeleteVersion(int id, int versionId, bool deletePriorVersions, int userId = 0) + public void DeleteVersion(int id, int versionId, bool deletePriorVersions, int userId = Constants.Security.SuperUserId) { using (var scope = ScopeProvider.CreateScope()) { @@ -872,7 +872,7 @@ namespace Umbraco.Core.Services.Implement /// /// The to delete /// Id of the User deleting the Media - public Attempt MoveToRecycleBin(IMedia media, int userId = 0) + public Attempt MoveToRecycleBin(IMedia media, int userId = Constants.Security.SuperUserId) { var evtMsgs = EventMessagesFactory.Get(); var moves = new List>(); @@ -916,7 +916,7 @@ namespace Umbraco.Core.Services.Implement /// The to move /// Id of the Media's new Parent /// Id of the User moving the Media - public Attempt Move(IMedia media, int parentId, int userId = 0) + public Attempt Move(IMedia media, int parentId, int userId = Constants.Security.SuperUserId) { var evtMsgs = EventMessagesFactory.Get(); @@ -1084,7 +1084,7 @@ namespace Umbraco.Core.Services.Implement /// /// /// True if sorting succeeded, otherwise False - public bool Sort(IEnumerable items, int userId = 0, bool raiseEvents = true) + public bool Sort(IEnumerable items, int userId = Constants.Security.SuperUserId, bool raiseEvents = true) { var itemsA = items.ToArray(); if (itemsA.Length == 0) return true; @@ -1273,7 +1273,7 @@ namespace Umbraco.Core.Services.Implement /// /// Id of the /// Optional id of the user deleting the media - public void DeleteMediaOfTypes(IEnumerable mediaTypeIds, int userId = 0) + public void DeleteMediaOfTypes(IEnumerable mediaTypeIds, int userId = Constants.Security.SuperUserId) { // TODO: This currently this is called from the ContentTypeService but that needs to change, // if we are deleting a content type, we should just delete the data and do this operation slightly differently. @@ -1338,7 +1338,7 @@ namespace Umbraco.Core.Services.Implement /// This needs extra care and attention as its potentially a dangerous and extensive operation /// Id of the /// Optional id of the user deleting the media - public void DeleteMediaOfType(int mediaTypeId, int userId = 0) + public void DeleteMediaOfType(int mediaTypeId, int userId = Constants.Security.SuperUserId) { DeleteMediaOfTypes(new[] { mediaTypeId }, userId); } diff --git a/src/Umbraco.Core/Services/Implement/PackagingService.cs b/src/Umbraco.Core/Services/Implement/PackagingService.cs index 9c4c6290a9..5194a26eb5 100644 --- a/src/Umbraco.Core/Services/Implement/PackagingService.cs +++ b/src/Umbraco.Core/Services/Implement/PackagingService.cs @@ -100,7 +100,7 @@ namespace Umbraco.Core.Services.Implement public CompiledPackage GetCompiledPackageInfo(FileInfo packageFile) => _packageInstallation.ReadPackage(packageFile); - public IEnumerable InstallCompiledPackageFiles(PackageDefinition packageDefinition, FileInfo packageFile, int userId = 0) + public IEnumerable InstallCompiledPackageFiles(PackageDefinition packageDefinition, FileInfo packageFile, int userId = Constants.Security.SuperUserId) { if (packageDefinition == null) throw new ArgumentNullException(nameof(packageDefinition)); if (packageDefinition.Id == default) throw new ArgumentException("The package definition has not been persisted"); @@ -118,7 +118,7 @@ namespace Umbraco.Core.Services.Implement return files; } - public InstallationSummary InstallCompiledPackageData(PackageDefinition packageDefinition, FileInfo packageFile, int userId = 0) + public InstallationSummary InstallCompiledPackageData(PackageDefinition packageDefinition, FileInfo packageFile, int userId = Constants.Security.SuperUserId) { if (packageDefinition == null) throw new ArgumentNullException(nameof(packageDefinition)); if (packageDefinition.Id == default) throw new ArgumentException("The package definition has not been persisted"); @@ -141,7 +141,7 @@ namespace Umbraco.Core.Services.Implement return summary; } - public UninstallationSummary UninstallPackage(string packageName, int userId = 0) + public UninstallationSummary UninstallPackage(string packageName, int userId = Constants.Security.SuperUserId) { //this is ordered by descending version var allPackageVersions = GetInstalledPackageByName(packageName)?.ToList(); @@ -187,7 +187,7 @@ namespace Umbraco.Core.Services.Implement #region Created/Installed Package Repositories - public void DeleteCreatedPackage(int id, int userId = 0) + public void DeleteCreatedPackage(int id, int userId = Constants.Security.SuperUserId) { var package = GetCreatedPackageById(id); if (package == null) return; @@ -236,7 +236,7 @@ namespace Umbraco.Core.Services.Implement public bool SaveInstalledPackage(PackageDefinition definition) => _installedPackages.SavePackage(definition); - public void DeleteInstalledPackage(int packageId, int userId = 0) + public void DeleteInstalledPackage(int packageId, int userId = Constants.Security.SuperUserId) { var package = GetInstalledPackageById(packageId); if (package == null) return; From 51ad0f75d1c95808f05096b1cc89557fe3cf2bdc Mon Sep 17 00:00:00 2001 From: Warren Buckley Date: Wed, 6 Feb 2019 15:16:11 +0000 Subject: [PATCH 29/68] Fix up unit test but also uses constant for -1 as the parent id aka System Root Node Id --- .../Services/ContentServiceTests.cs | 90 +++++++++---------- 1 file changed, 45 insertions(+), 45 deletions(-) diff --git a/src/Umbraco.Tests/Services/ContentServiceTests.cs b/src/Umbraco.Tests/Services/ContentServiceTests.cs index 017f1f50ec..e75ed3f52c 100644 --- a/src/Umbraco.Tests/Services/ContentServiceTests.cs +++ b/src/Umbraco.Tests/Services/ContentServiceTests.cs @@ -96,7 +96,7 @@ namespace Umbraco.Tests.Services ServiceContext.FileService.SaveTemplate(contentType.DefaultTemplate); contentTypeService.Save(contentType); - var blueprint = MockedContent.CreateTextpageContent(contentType, "hello", -1); + var blueprint = MockedContent.CreateTextpageContent(contentType, "hello", Constants.System.Root); blueprint.SetValue("title", "blueprint 1"); blueprint.SetValue("bodyText", "blueprint 2"); blueprint.SetValue("keywords", "blueprint 3"); @@ -122,7 +122,7 @@ namespace Umbraco.Tests.Services ServiceContext.FileService.SaveTemplate(contentType.DefaultTemplate); contentTypeService.Save(contentType); - var blueprint = MockedContent.CreateTextpageContent(contentType, "hello", -1); + var blueprint = MockedContent.CreateTextpageContent(contentType, "hello", Constants.System.Root); blueprint.SetValue("title", "blueprint 1"); blueprint.SetValue("bodyText", "blueprint 2"); blueprint.SetValue("keywords", "blueprint 3"); @@ -148,7 +148,7 @@ namespace Umbraco.Tests.Services ServiceContext.FileService.SaveTemplate(contentType.DefaultTemplate); contentTypeService.Save(contentType); - var blueprint = MockedContent.CreateTextpageContent(contentType, "hello", -1); + var blueprint = MockedContent.CreateTextpageContent(contentType, "hello", Constants.System.Root); blueprint.SetValue("title", "blueprint 1"); blueprint.SetValue("bodyText", "blueprint 2"); blueprint.SetValue("keywords", "blueprint 3"); @@ -183,7 +183,7 @@ namespace Umbraco.Tests.Services for (int i = 0; i < 10; i++) { - var blueprint = MockedContent.CreateTextpageContent(i % 2 == 0 ? ct1 : ct2, "hello" + i, -1); + var blueprint = MockedContent.CreateTextpageContent(i % 2 == 0 ? ct1 : ct2, "hello" + i, Constants.System.Root); contentService.SaveBlueprint(blueprint); } @@ -294,7 +294,7 @@ namespace Umbraco.Tests.Services var contentService = ServiceContext.ContentService; // Act - var content = contentService.CreateAndSave("Test", -1, "umbTextpage", Constants.Security.SuperUserId); + var content = contentService.CreateAndSave("Test", Constants.System.Root, "umbTextpage", Constants.Security.SuperUserId); content.ContentSchedule.Add(null, DateTime.Now.AddHours(2)); contentService.Save(content, Constants.Security.SuperUserId); @@ -322,7 +322,7 @@ namespace Umbraco.Tests.Services var contentService = ServiceContext.ContentService; // Act - var content = contentService.CreateAndSave("Test", -1, "umbTextpage", Constants.Security.SuperUserId); + var content = contentService.CreateAndSave("Test", Constants.System.Root, "umbTextpage", Constants.Security.SuperUserId); for (var i = 0; i < 20; i++) { content.SetValue("bodyText", "hello world " + Guid.NewGuid()); @@ -347,7 +347,7 @@ namespace Umbraco.Tests.Services var results = new List(); for (var i = 0; i < 20; i++) { - results.Add(contentService.CreateAndSave("Test", -1, "umbTextpage", 0)); + results.Add(contentService.CreateAndSave("Test", Constants.System.Root, "umbTextpage", 0)); } var sortedGet = contentService.GetByIds(new[] {results[10].Id, results[5].Id, results[12].Id}).ToArray(); @@ -367,7 +367,7 @@ namespace Umbraco.Tests.Services // Act for (int i = 0; i < 20; i++) { - contentService.CreateAndSave("Test", -1, "umbTextpage", Constants.Security.SuperUserId); + contentService.CreateAndSave("Test", Constants.System.Root, "umbTextpage", Constants.Security.SuperUserId); } // Assert @@ -386,7 +386,7 @@ namespace Umbraco.Tests.Services // Act for (int i = 0; i < 20; i++) { - contentService.CreateAndSave("Test", -1, "umbBlah", Constants.Security.SuperUserId); + contentService.CreateAndSave("Test", Constants.System.Root, "umbBlah", Constants.Security.SuperUserId); } // Assert @@ -401,7 +401,7 @@ namespace Umbraco.Tests.Services var contentTypeService = ServiceContext.ContentTypeService; var contentType = MockedContentTypes.CreateSimpleContentType("umbBlah", "test Doc Type"); contentTypeService.Save(contentType); - var parent = contentService.CreateAndSave("Test", -1, "umbBlah", Constants.Security.SuperUserId); + var parent = contentService.CreateAndSave("Test", Constants.System.Root, "umbBlah", Constants.Security.SuperUserId); // Act for (int i = 0; i < 20; i++) @@ -421,7 +421,7 @@ namespace Umbraco.Tests.Services var contentTypeService = ServiceContext.ContentTypeService; var contentType = MockedContentTypes.CreateSimpleContentType("umbBlah", "test Doc Type"); contentTypeService.Save(contentType); - var parent = contentService.CreateAndSave("Test", -1, "umbBlah", Constants.Security.SuperUserId); + var parent = contentService.CreateAndSave("Test", Constants.System.Root, "umbBlah", Constants.Security.SuperUserId); // Act IContent current = parent; @@ -455,7 +455,7 @@ namespace Umbraco.Tests.Services var contentService = ServiceContext.ContentService; // Act - var content = contentService.Create("Test", -1, "umbTextpage", Constants.Security.SuperUserId); + var content = contentService.Create("Test", Constants.System.Root, "umbTextpage", Constants.Security.SuperUserId); // Assert Assert.That(content, Is.Not.Null); @@ -469,7 +469,7 @@ namespace Umbraco.Tests.Services var contentService = ServiceContext.ContentService; // Act - var content = contentService.Create("Test", -1, "umbTextpage", Constants.Security.SuperUserId); + var content = contentService.Create("Test", Constants.System.Root, "umbTextpage", Constants.Security.SuperUserId); // Assert Assert.That(content, Is.Not.Null); @@ -483,12 +483,12 @@ namespace Umbraco.Tests.Services var contentService = ServiceContext.ContentService; // Act - var content = contentService.Create("Test", -1, "umbTextpage"); + var content = contentService.Create("Test", Constants.System.Root, "umbTextpage"); // Assert Assert.That(content, Is.Not.Null); Assert.That(content.HasIdentity, Is.False); - Assert.That(content.CreatorId, Is.EqualTo(0)); //Default to 0 (unknown) since we didn't explicitly set this in the Create call + Assert.That(content.CreatorId, Is.EqualTo(Constants.Security.SuperUserId)); //Default to -1 aka SuperUser (unknown) since we didn't explicitly set this in the Create call } [Test] @@ -502,7 +502,7 @@ namespace Umbraco.Tests.Services RawPasswordValue = "test" }; ServiceContext.UserService.Save(user); - var content = new Content("Test", -1, ServiceContext.ContentTypeService.Get("umbTextpage")); + var content = new Content("Test", Constants.System.Root, ServiceContext.ContentTypeService.Get("umbTextpage")); // Act ServiceContext.ContentService.Save(content, (int)user.Id); @@ -519,7 +519,7 @@ namespace Umbraco.Tests.Services var contentService = ServiceContext.ContentService; // Act & Assert - Assert.Throws(() => contentService.Create("Test", -1, "umbAliasDoesntExist")); + Assert.Throws(() => contentService.Create("Test", Constants.System.Root, "umbAliasDoesntExist")); } [Test] @@ -527,7 +527,7 @@ namespace Umbraco.Tests.Services { // Arrange var contentService = ServiceContext.ContentService; - var content = new Content(string.Empty, -1, ServiceContext.ContentTypeService.Get("umbTextpage")); + var content = new Content(string.Empty, Constants.System.Root, ServiceContext.ContentTypeService.Get("umbTextpage")); // Act & Assert Assert.Throws(() => contentService.Save(content)); @@ -757,7 +757,7 @@ namespace Umbraco.Tests.Services contentType.Variations = ContentVariation.Culture; ServiceContext.ContentTypeService.Save(contentType); - IContent content = new Content("content", -1, contentType); + IContent content = new Content("content", Constants.System.Root, contentType); content.SetCultureName("content-fr", langFr.IsoCode); content.SetCultureName("content-en", langUk.IsoCode); content.PublishCulture(langFr.IsoCode); @@ -816,7 +816,7 @@ namespace Umbraco.Tests.Services ServiceContext.ContentTypeService.Save(contentType); - IContent content = new Content("content", -1, contentType); + IContent content = new Content("content", Constants.System.Root, contentType); content.SetCultureName("content-en", langGB.IsoCode); content.SetCultureName("content-fr", langFr.IsoCode); content.PublishCulture(langGB.IsoCode); @@ -859,7 +859,7 @@ namespace Umbraco.Tests.Services contentType.Variations = ContentVariation.Culture; ServiceContext.ContentTypeService.Save(contentType); - IContent content = new Content("content", -1, contentType); + IContent content = new Content("content", Constants.System.Root, contentType); content.SetCultureName("content-fr", langFr.IsoCode); content.PublishCulture(langFr.IsoCode); var published = ServiceContext.ContentService.SavePublishing(content); @@ -892,7 +892,7 @@ namespace Umbraco.Tests.Services contentType.Variations = ContentVariation.Culture; ServiceContext.ContentTypeService.Save(contentType); - IContent content = new Content("content", -1, contentType); + IContent content = new Content("content", Constants.System.Root, contentType); content.SetCultureName("content-fr", langFr.IsoCode); content.SetCultureName("content-gb", langGB.IsoCode); content.PublishCulture(langGB.IsoCode); @@ -955,7 +955,7 @@ namespace Umbraco.Tests.Services { // Arrange var contentService = ServiceContext.ContentService; - var parent = contentService.Create("parent", -1, "umbTextpage"); + var parent = contentService.Create("parent", Constants.System.Root, "umbTextpage"); contentService.SaveAndPublish(parent); var content = contentService.Create("child", parent, "umbTextpage"); @@ -1288,7 +1288,7 @@ namespace Umbraco.Tests.Services { // Arrange var contentService = ServiceContext.ContentService; - var content = contentService.Create("Home US", -1, "umbTextpage", Constants.Security.SuperUserId); + var content = contentService.Create("Home US", Constants.System.Root, "umbTextpage", Constants.Security.SuperUserId); content.SetValue("author", "Barack Obama"); // Act @@ -1787,7 +1787,7 @@ namespace Umbraco.Tests.Services ServiceContext.FileService.SaveTemplate(contentType.DefaultTemplate); // else, FK violation on contentType! ServiceContext.ContentTypeService.Save(contentType); - var content = MockedContent.CreateSimpleContent(contentType, "Simple Tags Page", -1); + var content = MockedContent.CreateSimpleContent(contentType, "Simple Tags Page", Constants.System.Root); content.AssignTags(propAlias, new[] {"hello", "world"}); contentService.Save(content); @@ -1963,7 +1963,7 @@ namespace Umbraco.Tests.Services ServiceContext.FileService.SaveTemplate(contentType.DefaultTemplate); // else, FK violation on contentType! ServiceContext.ContentTypeService.Save(contentType); - var page = new Content("Page", -1, contentType) + var page = new Content("Page", Constants.System.Root, contentType) { Level = 1, SortOrder = 1, @@ -2190,7 +2190,7 @@ namespace Umbraco.Tests.Services var contentType = MockedContentTypes.CreateAllTypesContentType("allDataTypes", "All DataTypes"); contentTypeService.Save(contentType); var contentService = ServiceContext.ContentService; - var content = MockedContent.CreateAllTypesContent(contentType, "Random Content", -1); + var content = MockedContent.CreateAllTypesContent(contentType, "Random Content", Constants.System.Root); contentService.Save(content); var id = content.Id; @@ -2243,7 +2243,7 @@ namespace Umbraco.Tests.Services public void Ensure_Content_Xml_Created() { var contentService = ServiceContext.ContentService; - var content = contentService.Create("Home US", -1, "umbTextpage", Constants.Security.SuperUserId); + var content = contentService.Create("Home US", Constants.System.Root, "umbTextpage", Constants.Security.SuperUserId); content.SetValue("author", "Barack Obama"); contentService.Save(content); @@ -2265,7 +2265,7 @@ namespace Umbraco.Tests.Services public void Ensure_Preview_Xml_Created() { var contentService = ServiceContext.ContentService; - var content = contentService.Create("Home US", -1, "umbTextpage", Constants.Security.SuperUserId); + var content = contentService.Create("Home US", Constants.System.Root, "umbTextpage", Constants.Security.SuperUserId); content.SetValue("author", "Barack Obama"); contentService.Save(content); @@ -2293,10 +2293,10 @@ namespace Umbraco.Tests.Services } long total; - var entities = service.GetPagedChildren(-1, 0, 6, out total).ToArray(); + var entities = service.GetPagedChildren(Constants.System.Root, 0, 6, out total).ToArray(); Assert.That(entities.Length, Is.EqualTo(6)); Assert.That(total, Is.EqualTo(10)); - entities = service.GetPagedChildren(-1, 1, 6, out total).ToArray(); + entities = service.GetPagedChildren(Constants.System.Root, 1, 6, out total).ToArray(); Assert.That(entities.Length, Is.EqualTo(4)); Assert.That(total, Is.EqualTo(10)); } @@ -2328,10 +2328,10 @@ namespace Umbraco.Tests.Services long total; // children in root including the folder - not the descendants in the folder - var entities = service.GetPagedChildren(-1, 0, 6, out total).ToArray(); + var entities = service.GetPagedChildren(Constants.System.Root, 0, 6, out total).ToArray(); Assert.That(entities.Length, Is.EqualTo(6)); Assert.That(total, Is.EqualTo(10)); - entities = service.GetPagedChildren(-1, 1, 6, out total).ToArray(); + entities = service.GetPagedChildren(Constants.System.Root, 1, 6, out total).ToArray(); Assert.That(entities.Length, Is.EqualTo(4)); Assert.That(total, Is.EqualTo(10)); @@ -2347,7 +2347,7 @@ namespace Umbraco.Tests.Services [Test] public void PublishingTest() { - var contentType = new ContentType(-1) + var contentType = new ContentType(Constants.System.Root) { Alias = "foo", Name = "Foo" @@ -2365,7 +2365,7 @@ namespace Umbraco.Tests.Services ServiceContext.ContentTypeService.Save(contentType); var contentService = ServiceContext.ContentService; - var content = contentService.Create("foo", -1, "foo"); + var content = contentService.Create("foo", Constants.System.Root, "foo"); contentService.Save(content); Assert.IsFalse(content.Published); @@ -2493,7 +2493,7 @@ namespace Umbraco.Tests.Services contentTypeService.Save(contentType); var contentService = ServiceContext.ContentService; - var content = new Content(null, -1, contentType); + var content = new Content(null, Constants.System.Root, contentType); content.SetCultureName("name-us", langUk.IsoCode); content.SetCultureName("name-fr", langFr.IsoCode); @@ -2528,7 +2528,7 @@ namespace Umbraco.Tests.Services var contentService = ServiceContext.ContentService; - var content = new Content(null, -1, contentType); + var content = new Content(null, Constants.System.Root, contentType); content.SetCultureName("root", langUk.IsoCode); contentService.Save(content); @@ -2570,13 +2570,13 @@ namespace Umbraco.Tests.Services var o = new[] { 2, 1, 3, 0, 4 }; // randomly different for (var i = 0; i < 5; i++) { - var contentA = new Content(null, -1, contentType); + var contentA = new Content(null, Constants.System.Root, contentType); contentA.SetCultureName("contentA" + i + "uk", langUk.IsoCode); contentA.SetCultureName("contentA" + o[i] + "fr", langFr.IsoCode); contentA.SetCultureName("contentX" + i + "da", langDa.IsoCode); contentService.Save(contentA); - var contentB = new Content(null, -1, contentType); + var contentB = new Content(null, Constants.System.Root, contentType); contentB.SetCultureName("contentB" + i + "uk", langUk.IsoCode); contentB.SetCultureName("contentB" + o[i] + "fr", langFr.IsoCode); contentB.SetCultureName("contentX" + i + "da", langDa.IsoCode); @@ -2584,7 +2584,7 @@ namespace Umbraco.Tests.Services } // get all - var list = contentService.GetPagedChildren(-1, 0, 100, out var total).ToList(); + var list = contentService.GetPagedChildren(Constants.System.Root, 0, 100, out var total).ToList(); Console.WriteLine("ALL"); WriteList(list); @@ -2594,7 +2594,7 @@ namespace Umbraco.Tests.Services Assert.AreEqual(11, list.Count); // filter - list = contentService.GetPagedChildren(-1, 0, 100, out total, + list = contentService.GetPagedChildren(Constants.System.Root, 0, 100, out total, SqlContext.Query().Where(x => x.Name.Contains("contentX")), Ordering.By("name", culture: langFr.IsoCode)).ToList(); @@ -2602,7 +2602,7 @@ namespace Umbraco.Tests.Services Assert.AreEqual(0, list.Count); // filter - list = contentService.GetPagedChildren(-1, 0, 100, out total, + list = contentService.GetPagedChildren(Constants.System.Root, 0, 100, out total, SqlContext.Query().Where(x => x.Name.Contains("contentX")), Ordering.By("name", culture: langDa.IsoCode)).ToList(); @@ -2613,7 +2613,7 @@ namespace Umbraco.Tests.Services Assert.AreEqual(10, list.Count); // filter - list = contentService.GetPagedChildren(-1, 0, 100, out total, + list = contentService.GetPagedChildren(Constants.System.Root, 0, 100, out total, SqlContext.Query().Where(x => x.Name.Contains("contentA")), Ordering.By("name", culture: langFr.IsoCode)).ToList(); @@ -2626,7 +2626,7 @@ namespace Umbraco.Tests.Services for (var i = 0; i < 5; i++) Assert.AreEqual("contentA" + i + "fr", list[i].GetCultureName(langFr.IsoCode)); - list = contentService.GetPagedChildren(-1, 0, 100, out total, + list = contentService.GetPagedChildren(Constants.System.Root, 0, 100, out total, SqlContext.Query().Where(x => x.Name.Contains("contentA")), Ordering.By("name", direction: Direction.Descending, culture: langFr.IsoCode)).ToList(); @@ -2671,7 +2671,7 @@ namespace Umbraco.Tests.Services contentTypeService.Save(contentType); var contentService = ServiceContext.ContentService; - var content = contentService.Create("Home US", -1, "umbTextpage"); + var content = contentService.Create("Home US", Constants.System.Root, "umbTextpage"); // creating content with a name but no culture - will set the invariant name // but, because that content is variant, as soon as we save, we'll need to From 78849bb7ff5e8c2c379d8310458db37341fc2985 Mon Sep 17 00:00:00 2001 From: Shannon Date: Thu, 7 Feb 2019 11:42:16 +1100 Subject: [PATCH 30/68] removes unused methods and internalizes methods we can't expose yet --- src/Umbraco.Core/Models/ContentBase.cs | 2 +- src/Umbraco.Core/Models/IMedia.cs | 15 +-------------- src/Umbraco.Core/Models/Media.cs | 15 ++------------- 3 files changed, 4 insertions(+), 28 deletions(-) diff --git a/src/Umbraco.Core/Models/ContentBase.cs b/src/Umbraco.Core/Models/ContentBase.cs index 3a372296f0..c6f5f39e23 100644 --- a/src/Umbraco.Core/Models/ContentBase.cs +++ b/src/Umbraco.Core/Models/ContentBase.cs @@ -69,7 +69,7 @@ namespace Umbraco.Core.Models [IgnoreDataMember] public ISimpleContentType ContentType { get; private set; } - protected void ChangeContentType(ISimpleContentType contentType) + internal void ChangeContentType(ISimpleContentType contentType) { ContentType = contentType; ContentTypeId = contentType.Id; diff --git a/src/Umbraco.Core/Models/IMedia.cs b/src/Umbraco.Core/Models/IMedia.cs index 3e2d11fb71..3ad4f87aa8 100644 --- a/src/Umbraco.Core/Models/IMedia.cs +++ b/src/Umbraco.Core/Models/IMedia.cs @@ -4,19 +4,6 @@ namespace Umbraco.Core.Models { public interface IMedia : IContentBase { - /// - /// Changes the for the current content object - /// - /// New ContentType for this content - /// Leaves PropertyTypes intact after change - void ChangeContentType(IMediaType contentType); - - /// - /// Changes the for the current content object and removes PropertyTypes, - /// which are not part of the new ContentType. - /// - /// New ContentType for this content - /// Boolean indicating whether to clear PropertyTypes upon change - void ChangeContentType(IMediaType contentType, bool clearProperties); + } } diff --git a/src/Umbraco.Core/Models/Media.cs b/src/Umbraco.Core/Models/Media.cs index bf5f5cf948..d281f8f267 100644 --- a/src/Umbraco.Core/Models/Media.cs +++ b/src/Umbraco.Core/Models/Media.cs @@ -57,7 +57,7 @@ namespace Umbraco.Core.Models /// /// New MediaType for this Media /// Leaves PropertyTypes intact after change - public void ChangeContentType(IMediaType contentType) + internal void ChangeContentType(IMediaType contentType) { ChangeContentType(contentType, false); } @@ -68,7 +68,7 @@ namespace Umbraco.Core.Models /// /// New MediaType for this Media /// Boolean indicating whether to clear PropertyTypes upon change - public void ChangeContentType(IMediaType contentType, bool clearProperties) + internal void ChangeContentType(IMediaType contentType, bool clearProperties) { ChangeContentType(new SimpleContentType(contentType)); @@ -81,16 +81,5 @@ namespace Umbraco.Core.Models Properties.CollectionChanged += PropertiesChanged; } - /// - /// Changes the Trashed state of the content object - /// - /// Boolean indicating whether content is trashed (true) or not trashed (false) - /// - public void ChangeTrashedState(bool isTrashed, int parentId = -20) - { - Trashed = isTrashed; - //The Media Recycle Bin Id is -21 so we correct that here - ParentId = parentId == -20 ? -21 : parentId; - } } } From 030b6263504387c57b84a6821e31621f2e5613b4 Mon Sep 17 00:00:00 2001 From: Shannon Date: Thu, 7 Feb 2019 11:49:30 +1100 Subject: [PATCH 31/68] Removes the need for a .Current, removes an unused method --- src/Umbraco.Core/ContentExtensions.cs | 5 +-- src/Umbraco.Tests/Models/ContentTests.cs | 4 ++- .../MemberTabsAndPropertiesResolver.cs | 4 +-- .../Mapping/TabsAndPropertiesResolver.cs | 31 ++++++------------- 4 files changed, 17 insertions(+), 27 deletions(-) diff --git a/src/Umbraco.Core/ContentExtensions.cs b/src/Umbraco.Core/ContentExtensions.cs index d82f181e5d..d552b3f960 100644 --- a/src/Umbraco.Core/ContentExtensions.cs +++ b/src/Umbraco.Core/ContentExtensions.cs @@ -106,10 +106,11 @@ namespace Umbraco.Core /// Returns properties that do not belong to a group /// /// + /// /// - public static IEnumerable GetNonGroupedProperties(this IContentBase content) + public static IEnumerable GetNonGroupedProperties(this IContentBase content, IContentTypeBaseServiceProvider contentTypeBaseService) { - var contentType = Current.Services.ContentTypeBaseServices.GetContentTypeOf(content); + var contentType = contentTypeBaseService.GetContentTypeOf(content); var propertyIdsInTabs = contentType.PropertyGroups.SelectMany(pg => pg.PropertyTypes); return content.Properties .Where(property => propertyIdsInTabs.Contains(property.PropertyType) == false) diff --git a/src/Umbraco.Tests/Models/ContentTests.cs b/src/Umbraco.Tests/Models/ContentTests.cs index 7fc1bd3ce4..a54b9c4e48 100644 --- a/src/Umbraco.Tests/Models/ContentTests.cs +++ b/src/Umbraco.Tests/Models/ContentTests.cs @@ -137,7 +137,9 @@ namespace Umbraco.Tests.Models var content = MockedContent.CreateSimpleContent(contentType); //need to id the p - var nonGrouped = content.GetNonGroupedProperties(); + var serviceProvider = new ContentTypeBaseServiceProvider(_contentTypeService, Mock.Of(), Mock.Of()); + + var nonGrouped = content.GetNonGroupedProperties(serviceProvider); Assert.AreEqual(2, nonGrouped.Count()); Assert.AreEqual(5, content.Properties.Count()); diff --git a/src/Umbraco.Web/Models/Mapping/MemberTabsAndPropertiesResolver.cs b/src/Umbraco.Web/Models/Mapping/MemberTabsAndPropertiesResolver.cs index 517889277c..288b835318 100644 --- a/src/Umbraco.Web/Models/Mapping/MemberTabsAndPropertiesResolver.cs +++ b/src/Umbraco.Web/Models/Mapping/MemberTabsAndPropertiesResolver.cs @@ -29,8 +29,8 @@ namespace Umbraco.Web.Models.Mapping private readonly IMemberService _memberService; private readonly IUserService _userService; - public MemberTabsAndPropertiesResolver(IUmbracoContextAccessor umbracoContextAccessor, ILocalizedTextService localizedTextService, IMemberService memberService, IUserService userService, IMemberTypeService memberTypeService) - : base(localizedTextService) + public MemberTabsAndPropertiesResolver(IUmbracoContextAccessor umbracoContextAccessor, ILocalizedTextService localizedTextService, IMemberService memberService, IUserService userService, IMemberTypeService memberTypeService, IContentTypeBaseServiceProvider contentTypeServiceProvider) + : base(localizedTextService, contentTypeServiceProvider) { _umbracoContextAccessor = umbracoContextAccessor ?? throw new ArgumentNullException(nameof(umbracoContextAccessor)); _localizedTextService = localizedTextService ?? throw new ArgumentNullException(nameof(localizedTextService)); diff --git a/src/Umbraco.Web/Models/Mapping/TabsAndPropertiesResolver.cs b/src/Umbraco.Web/Models/Mapping/TabsAndPropertiesResolver.cs index 4e6ae99cf2..6f3815f678 100644 --- a/src/Umbraco.Web/Models/Mapping/TabsAndPropertiesResolver.cs +++ b/src/Umbraco.Web/Models/Mapping/TabsAndPropertiesResolver.cs @@ -12,36 +12,23 @@ namespace Umbraco.Web.Models.Mapping { internal abstract class TabsAndPropertiesResolver { + private readonly IContentTypeBaseServiceProvider _contentTypeServiceProvider; protected ILocalizedTextService LocalizedTextService { get; } protected IEnumerable IgnoreProperties { get; set; } - protected TabsAndPropertiesResolver(ILocalizedTextService localizedTextService) + protected TabsAndPropertiesResolver(ILocalizedTextService localizedTextService, IContentTypeBaseServiceProvider contentTypeServiceProvider) { + _contentTypeServiceProvider = contentTypeServiceProvider; LocalizedTextService = localizedTextService ?? throw new ArgumentNullException(nameof(localizedTextService)); IgnoreProperties = new List(); } - protected TabsAndPropertiesResolver(ILocalizedTextService localizedTextService, IEnumerable ignoreProperties) - : this(localizedTextService) + protected TabsAndPropertiesResolver(ILocalizedTextService localizedTextService, IContentTypeBaseServiceProvider contentTypeServiceProvider, IEnumerable ignoreProperties) + : this(localizedTextService, contentTypeServiceProvider) { IgnoreProperties = ignoreProperties ?? throw new ArgumentNullException(nameof(ignoreProperties)); } - - // TODO: This should deserialize to ListViewConfiguration - private static int GetTabNumberFromConfig(IDictionary listViewConfig) - { - if (!listViewConfig.TryGetValue("displayAtTabNumber", out var displayTabNum)) - return -1; - switch (displayTabNum) - { - case int i: - return i; - case string s when int.TryParse(s, out var parsed): - return parsed; - } - return -1; - } - + /// /// Returns a collection of custom generic properties that exist on the generic properties tab /// @@ -65,7 +52,7 @@ namespace Umbraco.Web.Models.Mapping { // add the generic properties tab, for properties that don't belong to a tab // get the properties, map and translate them, then add the tab - var noGroupProperties = content.GetNonGroupedProperties() + var noGroupProperties = content.GetNonGroupedProperties(_contentTypeServiceProvider) .Where(x => IgnoreProperties.Contains(x.Alias) == false) // skip ignored .ToList(); var genericproperties = MapProperties(content, noGroupProperties, context); @@ -137,8 +124,8 @@ namespace Umbraco.Web.Models.Mapping internal class TabsAndPropertiesResolver : TabsAndPropertiesResolver, IValueResolver>> where TSource : IContentBase { - public TabsAndPropertiesResolver(ILocalizedTextService localizedTextService) - : base(localizedTextService) + public TabsAndPropertiesResolver(ILocalizedTextService localizedTextService, IContentTypeBaseServiceProvider contentTypeServiceProvider) + : base(localizedTextService, contentTypeServiceProvider) { } public virtual IEnumerable> Resolve(TSource source, TDestination destination, IEnumerable> destMember, ResolutionContext context) From 562855a687cce19272a0ed8ea8aaab771c82afbd Mon Sep 17 00:00:00 2001 From: Shannon Date: Thu, 7 Feb 2019 11:53:43 +1100 Subject: [PATCH 32/68] removes fixme, adds comments and null checks --- .../ContentTypeBaseServiceProviderExtensions.cs | 13 ++++++------- .../Implement/ContentTypeBaseServiceProvider.cs | 1 + .../Macros/PublishedContentHashtableConverter.cs | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/Umbraco.Core/ContentTypeBaseServiceProviderExtensions.cs b/src/Umbraco.Core/ContentTypeBaseServiceProviderExtensions.cs index ad4d286139..f962d9aefb 100644 --- a/src/Umbraco.Core/ContentTypeBaseServiceProviderExtensions.cs +++ b/src/Umbraco.Core/ContentTypeBaseServiceProviderExtensions.cs @@ -1,17 +1,16 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; using Umbraco.Core.Models; using Umbraco.Core.Services; namespace Umbraco.Core { - // fixme - public static class ContentTypeBaseServiceProviderExtensions + internal static class ContentTypeBaseServiceProviderExtensions { + //TODO: Maybe this should just be on the IContentTypeBaseServiceProvider interface? public static IContentTypeComposition GetContentTypeOf(this IContentTypeBaseServiceProvider serviceProvider, IContentBase contentBase) - => serviceProvider.For(contentBase).Get(contentBase.ContentTypeId); + { + if (contentBase == null) throw new ArgumentNullException(nameof(contentBase)); + return serviceProvider.For(contentBase)?.Get(contentBase.ContentTypeId); + } } } diff --git a/src/Umbraco.Core/Services/Implement/ContentTypeBaseServiceProvider.cs b/src/Umbraco.Core/Services/Implement/ContentTypeBaseServiceProvider.cs index d867224b90..e20ff28ab3 100644 --- a/src/Umbraco.Core/Services/Implement/ContentTypeBaseServiceProvider.cs +++ b/src/Umbraco.Core/Services/Implement/ContentTypeBaseServiceProvider.cs @@ -18,6 +18,7 @@ namespace Umbraco.Core.Services.Implement public IContentTypeBaseService For(IContentBase contentBase) { + if (contentBase == null) throw new ArgumentNullException(nameof(contentBase)); switch (contentBase) { case IContent _: diff --git a/src/Umbraco.Web/Macros/PublishedContentHashtableConverter.cs b/src/Umbraco.Web/Macros/PublishedContentHashtableConverter.cs index 0ce317ac65..cc88d183b6 100644 --- a/src/Umbraco.Web/Macros/PublishedContentHashtableConverter.cs +++ b/src/Umbraco.Web/Macros/PublishedContentHashtableConverter.cs @@ -199,8 +199,8 @@ namespace Umbraco.Web.Macros Key = _inner.Key; // TODO: ARGH! need to fix this - this is not good because it uses ApplicationContext.Current - CreatorName = _inner.GetCreatorProfile().Name; - WriterName = _inner.GetWriterProfile().Name; + CreatorName = _inner.GetCreatorProfile()?.Name; + WriterName = _inner.GetWriterProfile()?.Name; var contentType = Current.Services.ContentTypeBaseServices.GetContentTypeOf(_inner); ContentType = Current.PublishedContentTypeFactory.CreateContentType(contentType); From 9df0f384afe2f06978c181972b6e58a8ccd8362b Mon Sep 17 00:00:00 2001 From: Shannon Date: Thu, 7 Feb 2019 12:02:47 +1100 Subject: [PATCH 33/68] Removes the need for another .Current and a lookup, simplifies the whole GetUrl for media --- src/Umbraco.Core/Models/MediaExtensions.cs | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/src/Umbraco.Core/Models/MediaExtensions.cs b/src/Umbraco.Core/Models/MediaExtensions.cs index b7d72f6dd3..ff5e47394f 100644 --- a/src/Umbraco.Core/Models/MediaExtensions.cs +++ b/src/Umbraco.Core/Models/MediaExtensions.cs @@ -16,21 +16,17 @@ namespace Umbraco.Core.Models /// public static string GetUrl(this IMedia media, string propertyAlias, ILogger logger) { - var contentType = Current.Services.MediaTypeService.Get(media.ContentTypeId); - var propertyType = contentType.PropertyTypes.FirstOrDefault(x => x.Alias.InvariantEquals(propertyAlias)); - if (propertyType == null) return string.Empty; - - var val = media.Properties[propertyType]; - if (val == null) return string.Empty; + if (!media.Properties.TryGetValue(propertyAlias, out var property)) + return string.Empty; // TODO: would need to be adjusted to variations, when media become variants - var jsonString = val.GetValue() as string; + var jsonString = property?.GetValue() as string; if (jsonString == null) return string.Empty; - if (propertyType.PropertyEditorAlias == Constants.PropertyEditors.Aliases.UploadField) + if (property.PropertyType.PropertyEditorAlias == Constants.PropertyEditors.Aliases.UploadField) return jsonString; - if (propertyType.PropertyEditorAlias == Constants.PropertyEditors.Aliases.ImageCropper) + if (property.PropertyType.PropertyEditorAlias == Constants.PropertyEditors.Aliases.ImageCropper) { if (jsonString.DetectIsJson() == false) return jsonString; From 123daed990445885343eca8b017ae6d6358bb472 Mon Sep 17 00:00:00 2001 From: Shannon Date: Thu, 7 Feb 2019 12:43:11 +1100 Subject: [PATCH 34/68] Removes the need for .Current in some places, adds TODO notes to test a theory, removes IUmbracoEntity from ISimpleContentType since all tests seem to pass without it and because the SimpleContentTypeMapper doesn't actually use ISimpleContentType i don't think it's needed, we'll see what the tests say. --- src/Umbraco.Core/Models/ISimpleContentType.cs | 5 +- src/Umbraco.Core/Models/PropertyCollection.cs | 2 +- src/Umbraco.Core/Models/SimpleContentType.cs | 73 ++++++++----------- .../Querying/ModelToSqlExpressionVisitor.cs | 2 +- src/Umbraco.Tests/Models/ContentTests.cs | 5 +- .../Services/ContentServiceTests.cs | 6 +- .../Testing/ContentBaseExtensions.cs | 34 +++++---- .../Filters/MemberSaveValidationAttribute.cs | 9 ++- .../Editors/Filters/MemberValidationHelper.cs | 33 ++------- 9 files changed, 74 insertions(+), 95 deletions(-) diff --git a/src/Umbraco.Core/Models/ISimpleContentType.cs b/src/Umbraco.Core/Models/ISimpleContentType.cs index 40862afd9e..7f6b2e68ea 100644 --- a/src/Umbraco.Core/Models/ISimpleContentType.cs +++ b/src/Umbraco.Core/Models/ISimpleContentType.cs @@ -5,8 +5,11 @@ namespace Umbraco.Core.Models /// /// Represents a simplified view of a content type. /// - public interface ISimpleContentType : IUmbracoEntity + public interface ISimpleContentType { + int Id { get; } + string Name { get; } + /// /// Gets the alias of the content type. /// diff --git a/src/Umbraco.Core/Models/PropertyCollection.cs b/src/Umbraco.Core/Models/PropertyCollection.cs index 5e71fe9f65..ed641080ea 100644 --- a/src/Umbraco.Core/Models/PropertyCollection.cs +++ b/src/Umbraco.Core/Models/PropertyCollection.cs @@ -93,7 +93,7 @@ namespace Umbraco.Core.Models } /// - /// Adds a property. + /// Adds or update a property. /// internal new void Add(Property property) { diff --git a/src/Umbraco.Core/Models/SimpleContentType.cs b/src/Umbraco.Core/Models/SimpleContentType.cs index c0e235e92d..86a1e56723 100644 --- a/src/Umbraco.Core/Models/SimpleContentType.cs +++ b/src/Umbraco.Core/Models/SimpleContentType.cs @@ -9,9 +9,6 @@ namespace Umbraco.Core.Models /// public class SimpleContentType : ISimpleContentType { - private readonly int _id; - private readonly string _name; - /// /// Initializes a new instance of the class. /// @@ -39,13 +36,12 @@ namespace Umbraco.Core.Models { if (contentType == null) throw new ArgumentNullException(nameof(contentType)); - _id = contentType.Id; + Id = contentType.Id; Alias = contentType.Alias; Variations = contentType.Variations; Icon = contentType.Icon; IsContainer = contentType.IsContainer; - Icon = contentType.Icon; - _name = contentType.Name; + Name = contentType.Name; AllowedAsRoot = contentType.AllowedAsRoot; IsElement = contentType.IsElement; } @@ -53,12 +49,7 @@ namespace Umbraco.Core.Models /// public string Alias { get; } - /// - public int Id - { - get => _id; - set => throw new NotSupportedException(); - } + public int Id { get; } /// public ITemplate DefaultTemplate { get; } @@ -71,13 +62,8 @@ namespace Umbraco.Core.Models /// public bool IsContainer { get; } - - /// - public string Name - { - get => _name; - set => throw new NotSupportedException(); - } + + public string Name { get; } /// public bool AllowedAsRoot { get; } @@ -120,30 +106,29 @@ namespace Umbraco.Core.Models // we have to have all this, because we're an IUmbracoEntity, because that is // required by the query expression visitor / SimpleContentTypeMapper - public object DeepClone() => throw new NotImplementedException(); - - public Guid Key { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - public DateTime CreateDate { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - public DateTime UpdateDate { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - public DateTime? DeleteDate { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - public bool HasIdentity => throw new NotImplementedException(); - - public int CreatorId { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - public int ParentId { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - public void SetParent(ITreeEntity parent) => throw new NotImplementedException(); - - public int Level { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - public string Path { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - public int SortOrder { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - public bool Trashed => throw new NotImplementedException(); - public bool IsDirty() => throw new NotImplementedException(); - public bool IsPropertyDirty(string propName) => throw new NotImplementedException(); - public IEnumerable GetDirtyProperties() => throw new NotImplementedException(); - public void ResetDirtyProperties() => throw new NotImplementedException(); - public bool WasDirty() => throw new NotImplementedException(); - public bool WasPropertyDirty(string propertyName) => throw new NotImplementedException(); - public void ResetWereDirtyProperties() => throw new NotImplementedException(); - public void ResetDirtyProperties(bool rememberDirty) => throw new NotImplementedException(); - public IEnumerable GetWereDirtyProperties() => throw new NotImplementedException(); + //string ITreeEntity.Name { get => this.Name; set => throw new NotImplementedException(); } + //int IEntity.Id { get => this.Id; set => throw new NotImplementedException(); } + //bool IEntity.HasIdentity => this.Id != default; + //int ITreeEntity.CreatorId { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + //int ITreeEntity.ParentId { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + //int ITreeEntity.Level { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + //string ITreeEntity.Path { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + //int ITreeEntity.SortOrder { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + //bool ITreeEntity.Trashed => throw new NotImplementedException(); + //Guid IEntity.Key { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + //DateTime IEntity.CreateDate { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + //DateTime IEntity.UpdateDate { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + //DateTime? IEntity.DeleteDate { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + //void ITreeEntity.SetParent(ITreeEntity parent) => throw new NotImplementedException(); + //object IDeepCloneable.DeepClone() => throw new NotImplementedException(); + //bool IRememberBeingDirty.WasDirty() => throw new NotImplementedException(); + //bool IRememberBeingDirty.WasPropertyDirty(string propertyName) => throw new NotImplementedException(); + //void IRememberBeingDirty.ResetWereDirtyProperties() => throw new NotImplementedException(); + //void IRememberBeingDirty.ResetDirtyProperties(bool rememberDirty) => throw new NotImplementedException(); + //IEnumerable IRememberBeingDirty.GetWereDirtyProperties() => throw new NotImplementedException(); + //bool ICanBeDirty.IsDirty() => throw new NotImplementedException(); + //bool ICanBeDirty.IsPropertyDirty(string propName) => throw new NotImplementedException(); + //IEnumerable ICanBeDirty.GetDirtyProperties() => throw new NotImplementedException(); + //void ICanBeDirty.ResetDirtyProperties() => throw new NotImplementedException(); } } diff --git a/src/Umbraco.Core/Persistence/Querying/ModelToSqlExpressionVisitor.cs b/src/Umbraco.Core/Persistence/Querying/ModelToSqlExpressionVisitor.cs index a353f01f5b..bf26523d9e 100644 --- a/src/Umbraco.Core/Persistence/Querying/ModelToSqlExpressionVisitor.cs +++ b/src/Umbraco.Core/Persistence/Querying/ModelToSqlExpressionVisitor.cs @@ -60,7 +60,7 @@ namespace Umbraco.Core.Persistence.Querying if (m.Expression != null && m.Expression.Type != typeof(T) - && TypeHelper.IsTypeAssignableFrom(m.Expression.Type) + && TypeHelper.IsTypeAssignableFrom(m.Expression.Type) //TODO: Could this just be `IEntity` ? why does it need to be IUmbracoEntity, we aren't even using the reference to that below && EndsWithConstant(m) == false) { //if this is the case, it means we have a sub expression / nested property access, such as: x.ContentType.Alias == "Test"; diff --git a/src/Umbraco.Tests/Models/ContentTests.cs b/src/Umbraco.Tests/Models/ContentTests.cs index a54b9c4e48..7d19c34167 100644 --- a/src/Umbraco.Tests/Models/ContentTests.cs +++ b/src/Umbraco.Tests/Models/ContentTests.cs @@ -30,6 +30,7 @@ namespace Umbraco.Tests.Models public class ContentTests : UmbracoTestBase { private IContentTypeService _contentTypeService; + private IContentTypeBaseServiceProvider _contentTypeServiceProvider; protected override void Compose() { @@ -56,6 +57,8 @@ namespace Umbraco.Tests.Models var mediaTypeService = Mock.Of(); var memberTypeService = Mock.Of(); Composition.Register(_ => ServiceContext.CreatePartial(dataTypeService: dataTypeService, contentTypeBaseServiceProvider: new ContentTypeBaseServiceProvider(_contentTypeService, mediaTypeService, memberTypeService))); + + _contentTypeServiceProvider = new ContentTypeBaseServiceProvider(_contentTypeService, Mock.Of(), Mock.Of()); } [Test] @@ -541,7 +544,7 @@ namespace Umbraco.Tests.Models var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1); // Act - content.PropertyValues(new {title = "This is the new title"}); + content.PropertyValues(_contentTypeServiceProvider, new { title = "This is the new title"}); // Assert Assert.That(content.Properties.Any(), Is.True); diff --git a/src/Umbraco.Tests/Services/ContentServiceTests.cs b/src/Umbraco.Tests/Services/ContentServiceTests.cs index 94cbf69b63..b5069e040b 100644 --- a/src/Umbraco.Tests/Services/ContentServiceTests.cs +++ b/src/Umbraco.Tests/Services/ContentServiceTests.cs @@ -1574,19 +1574,19 @@ namespace Umbraco.Tests.Services var contentType = MockedContentTypes.CreateAllTypesContentType("test", "test"); ServiceContext.ContentTypeService.Save(contentType, Constants.Security.SuperUserId); - + object obj = new { tags = "[\"Hello\",\"World\"]" }; var content1 = MockedContent.CreateBasicContent(contentType); - content1.PropertyValues(obj); + content1.PropertyValues(ServiceContext.ContentTypeBaseServices, obj); content1.ResetDirtyProperties(false); ServiceContext.ContentService.Save(content1, Constants.Security.SuperUserId); Assert.IsTrue(ServiceContext.ContentService.SaveAndPublish(content1, userId: 0).Success); var content2 = MockedContent.CreateBasicContent(contentType); - content2.PropertyValues(obj); + content2.PropertyValues(ServiceContext.ContentTypeBaseServices, obj); content2.ResetDirtyProperties(false); ServiceContext.ContentService.Save(content2, Constants.Security.SuperUserId); Assert.IsTrue(ServiceContext.ContentService.SaveAndPublish(content2, userId: 0).Success); diff --git a/src/Umbraco.Tests/Testing/ContentBaseExtensions.cs b/src/Umbraco.Tests/Testing/ContentBaseExtensions.cs index 85ecf03dee..883c7682f4 100644 --- a/src/Umbraco.Tests/Testing/ContentBaseExtensions.cs +++ b/src/Umbraco.Tests/Testing/ContentBaseExtensions.cs @@ -3,42 +3,48 @@ using System.Linq; using Umbraco.Core; using Umbraco.Core.Composing; using Umbraco.Core.Models; +using Umbraco.Core.Services; namespace Umbraco.Tests.Testing { public static class ContentBaseExtensions { + public static void PropertyValues(this IContentBase content, object value, string culture = null, string segment = null) + { + content.PropertyValues(Current.Services.ContentTypeBaseServices, value, culture, segment); + } + /// /// Set property values by alias with an anonymous object. /// /// Does not support variants. - public static void PropertyValues(this IContentBase content, object value, string culture = null, string segment = null) + public static void PropertyValues(this IContentBase content, IContentTypeBaseServiceProvider contentTypeServiceProvider, object value, string culture = null, string segment = null) { if (value == null) throw new Exception("No properties has been passed in"); - var contentType = Current.Services.ContentTypeBaseServices.GetContentTypeOf(content); - var propertyInfos = value.GetType().GetProperties(); foreach (var propertyInfo in propertyInfos) { - //Check if a PropertyType with alias exists thus being a valid property - var propertyType = contentType.CompositionPropertyTypes.FirstOrDefault(x => x.Alias == propertyInfo.Name); - if (propertyType == null) - throw new Exception($"The property alias {propertyInfo.Name} is not valid, because no PropertyType with this alias exists"); - - //Check if a Property with the alias already exists in the collection thus being updated or inserted - var item = content.Properties.FirstOrDefault(x => x.Alias == propertyInfo.Name); - if (item != null) + if (content.Properties.TryGetValue(propertyInfo.Name, out var property)) { - item.SetValue(propertyInfo.GetValue(value, null), culture, segment); + property.SetValue(propertyInfo.GetValue(value, null), culture, segment); //Update item with newly added value - content.Properties.Add(item); + content.Properties.Add(property); } else { + + //TODO: Will this ever happen?? In theory we don't need to lookup the content type here since we can just check if the content contains properties with the correct name, + // however, i think this may be needed in the case where the content type contains property types that do not exist yet as properties on the + // content item? But can that happen? AFAIK it can't/shouldn't because of how we create content items in ContentBase we do _properties.EnsurePropertyTypes! + + var contentType = contentTypeServiceProvider.GetContentTypeOf(content); + var propertyType = contentType.CompositionPropertyTypes.FirstOrDefault(x => x.Alias == propertyInfo.Name); + if (propertyType == null) + throw new Exception($"The property alias {propertyInfo.Name} is not valid, because no PropertyType with this alias exists"); //Create new Property to add to collection - var property = propertyType.CreateProperty(); + property = propertyType.CreateProperty(); property.SetValue(propertyInfo.GetValue(value, null), culture, segment); content.Properties.Add(property); } diff --git a/src/Umbraco.Web/Editors/Filters/MemberSaveValidationAttribute.cs b/src/Umbraco.Web/Editors/Filters/MemberSaveValidationAttribute.cs index 619bd76333..80d5f684fe 100644 --- a/src/Umbraco.Web/Editors/Filters/MemberSaveValidationAttribute.cs +++ b/src/Umbraco.Web/Editors/Filters/MemberSaveValidationAttribute.cs @@ -5,6 +5,7 @@ using System.Web.Http.Controllers; using System.Web.Http.Filters; using Umbraco.Core.Logging; using Umbraco.Core.Models; +using Umbraco.Core.Services; using Umbraco.Web.Composing; using Umbraco.Web.Models.ContentEditing; @@ -17,21 +18,23 @@ namespace Umbraco.Web.Editors.Filters { private readonly ILogger _logger; private readonly IUmbracoContextAccessor _umbracoContextAccessor; + private readonly IMemberTypeService _memberTypeService; - public MemberSaveValidationAttribute() : this(Current.Logger, Current.UmbracoContextAccessor) + public MemberSaveValidationAttribute() : this(Current.Logger, Current.UmbracoContextAccessor, Current.Services.MemberTypeService) { } - public MemberSaveValidationAttribute(ILogger logger, IUmbracoContextAccessor umbracoContextAccessor) + public MemberSaveValidationAttribute(ILogger logger, IUmbracoContextAccessor umbracoContextAccessor, IMemberTypeService memberTypeService) { _logger = logger; _umbracoContextAccessor = umbracoContextAccessor; + _memberTypeService = memberTypeService; } public override void OnActionExecuting(HttpActionContext actionContext) { var model = (MemberSave)actionContext.ActionArguments["contentItem"]; - var contentItemValidator = new MemberValidationHelper(_logger, _umbracoContextAccessor); + var contentItemValidator = new MemberValidationHelper(_logger, _umbracoContextAccessor, _memberTypeService); //now do each validation step if (contentItemValidator.ValidateExistingContent(model, actionContext)) if (contentItemValidator.ValidateProperties(model, model, actionContext)) diff --git a/src/Umbraco.Web/Editors/Filters/MemberValidationHelper.cs b/src/Umbraco.Web/Editors/Filters/MemberValidationHelper.cs index c97e35eb0d..8f98765c34 100644 --- a/src/Umbraco.Web/Editors/Filters/MemberValidationHelper.cs +++ b/src/Umbraco.Web/Editors/Filters/MemberValidationHelper.cs @@ -10,43 +10,22 @@ using Umbraco.Core; using Umbraco.Core.Composing; using Umbraco.Core.Logging; using Umbraco.Core.Models; +using Umbraco.Core.Services; using Umbraco.Web.Models.ContentEditing; namespace Umbraco.Web.Editors.Filters { - //internal class ContentValidationHelper : ContentItemValidationHelper - //{ - // public ContentValidationHelper(ILogger logger, IUmbracoContextAccessor umbracoContextAccessor) : base(logger, umbracoContextAccessor) - // { - // } - - // /// - // /// Validates that the correct information is in the request for saving a culture variant - // /// - // /// - // /// - // /// - // protected override bool ValidateCultureVariant(ContentItemSave postedItem, HttpActionContext actionContext) - // { - // var contentType = postedItem.PersistedContent.GetContentType(); - // if (contentType.VariesByCulture() && postedItem.Culture.IsNullOrWhiteSpace()) - // { - // //we cannot save a content item that is culture variant if no culture was specified in the request! - // actionContext.Response = actionContext.Request.CreateValidationErrorResponse($"No culture found in request. Cannot save a content item that varies by culture, without a specified culture."); - // return false; - // } - // return true; - // } - //} - /// /// Custom validation helper so that we can exclude the Member.StandardPropertyTypeStubs from being validating for existence /// internal class MemberValidationHelper : ContentItemValidationHelper { - public MemberValidationHelper(ILogger logger, IUmbracoContextAccessor umbracoContextAccessor) : base(logger, umbracoContextAccessor) + private readonly IMemberTypeService _memberTypeService; + + public MemberValidationHelper(ILogger logger, IUmbracoContextAccessor umbracoContextAccessor, IMemberTypeService memberTypeService) : base(logger, umbracoContextAccessor) { + _memberTypeService = memberTypeService; } /// @@ -118,7 +97,7 @@ namespace Umbraco.Web.Editors.Filters //if a sensitive value is being submitted. if (UmbracoContextAccessor.UmbracoContext.Security.CurrentUser.HasAccessToSensitiveData() == false) { - var contentType = Current.Services.MemberTypeService.Get(model.PersistedContent.ContentTypeId); + var contentType = _memberTypeService.Get(model.PersistedContent.ContentTypeId); var sensitiveProperties = contentType .PropertyTypes.Where(x => contentType.IsSensitiveProperty(x.Alias)) .ToList(); From 3b12e0b72a040967d22a268478ca018d754b13ae Mon Sep 17 00:00:00 2001 From: Shannon Date: Thu, 7 Feb 2019 13:28:23 +1100 Subject: [PATCH 35/68] Updates ContentBase to track the original PropertyType's which means we don't ever need to look them up again, adds notes about this too since it seems it is probably unnecessary to begin with. --- src/Umbraco.Core/Models/ContentBase.cs | 34 ++++++++++++------- src/Umbraco.Tests/Models/ContentTests.cs | 6 ++-- .../Services/ContentServiceTests.cs | 4 +-- .../Testing/ContentBaseExtensions.cs | 21 +++++------- 4 files changed, 35 insertions(+), 30 deletions(-) diff --git a/src/Umbraco.Core/Models/ContentBase.cs b/src/Umbraco.Core/Models/ContentBase.cs index c6f5f39e23..03eb5a4c9e 100644 --- a/src/Umbraco.Core/Models/ContentBase.cs +++ b/src/Umbraco.Core/Models/ContentBase.cs @@ -23,6 +23,7 @@ namespace Umbraco.Core.Models private int _writerId; private PropertyCollection _properties; private ContentCultureInfosCollection _cultureInfos; + internal IReadOnlyList AllPropertyTypes { get; } #region Used for change tracking @@ -64,6 +65,11 @@ namespace Umbraco.Core.Models _contentTypeId = contentType.Id; _properties = properties ?? throw new ArgumentNullException(nameof(properties)); _properties.EnsurePropertyTypes(contentType.CompositionPropertyTypes); + + //track all property types on this content type, these can never change during the lifetime of this single instance + //there is no real extra memory overhead of doing this since these property types are already cached on this object via the + //properties already. + AllPropertyTypes = new List(contentType.CompositionPropertyTypes); } [IgnoreDataMember] @@ -294,22 +300,26 @@ namespace Umbraco.Core.Models /// public void SetValue(string propertyTypeAlias, object value, string culture = null, string segment = null) { - if (Properties.Contains(propertyTypeAlias)) + if (Properties.TryGetValue(propertyTypeAlias, out var property)) { - Properties[propertyTypeAlias].SetValue(value, culture, segment); - //bump the culture to be flagged for updating - this.TouchCulture(culture); - return; + property.SetValue(value, culture, segment); } + else + { + //fixme: Can this ever happen? According to the ctor in ContentBase (EnsurePropertyTypes), all properties will be created based on the content type's property types + // so how can a property not be resolved by the alias on the content.Properties but it can on the content type? + // This maybe can happen if a developer has removed a property with the api and is trying to then set the value of that property again... + // BUT, as it turns out the content.Properties.Remove(...) method is NEVER used, because why and how could it? you never remove a property from + // a content item directly. - var propertyTypes = Current.Services.ContentTypeBaseServices.GetContentTypeOf(this).CompositionPropertyTypes; - var propertyType = propertyTypes.FirstOrDefault(x => x.Alias.InvariantEquals(propertyTypeAlias)); - if (propertyType == null) - throw new InvalidOperationException($"No PropertyType exists with the supplied alias \"{propertyTypeAlias}\"."); + var propertyType = AllPropertyTypes.FirstOrDefault(x => x.Alias.InvariantEquals(propertyTypeAlias)); + if (propertyType == null) + throw new InvalidOperationException($"No PropertyType exists with the supplied alias \"{propertyTypeAlias}\"."); - var property = propertyType.CreateProperty(); - property.SetValue(value, culture, segment); - Properties.Add(property); + property = propertyType.CreateProperty(); + property.SetValue(value, culture, segment); + Properties.Add(property); + } //bump the culture to be flagged for updating this.TouchCulture(culture); diff --git a/src/Umbraco.Tests/Models/ContentTests.cs b/src/Umbraco.Tests/Models/ContentTests.cs index 7d19c34167..f211e570e9 100644 --- a/src/Umbraco.Tests/Models/ContentTests.cs +++ b/src/Umbraco.Tests/Models/ContentTests.cs @@ -30,7 +30,6 @@ namespace Umbraco.Tests.Models public class ContentTests : UmbracoTestBase { private IContentTypeService _contentTypeService; - private IContentTypeBaseServiceProvider _contentTypeServiceProvider; protected override void Compose() { @@ -57,8 +56,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))); - - _contentTypeServiceProvider = new ContentTypeBaseServiceProvider(_contentTypeService, Mock.Of(), Mock.Of()); + } [Test] @@ -544,7 +542,7 @@ namespace Umbraco.Tests.Models var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1); // Act - content.PropertyValues(_contentTypeServiceProvider, new { title = "This is the new title"}); + content.PropertyValues(new { title = "This is the new title"}); // Assert Assert.That(content.Properties.Any(), Is.True); diff --git a/src/Umbraco.Tests/Services/ContentServiceTests.cs b/src/Umbraco.Tests/Services/ContentServiceTests.cs index b5069e040b..78f0d739fb 100644 --- a/src/Umbraco.Tests/Services/ContentServiceTests.cs +++ b/src/Umbraco.Tests/Services/ContentServiceTests.cs @@ -1581,12 +1581,12 @@ namespace Umbraco.Tests.Services tags = "[\"Hello\",\"World\"]" }; var content1 = MockedContent.CreateBasicContent(contentType); - content1.PropertyValues(ServiceContext.ContentTypeBaseServices, obj); + content1.PropertyValues(obj); content1.ResetDirtyProperties(false); ServiceContext.ContentService.Save(content1, Constants.Security.SuperUserId); Assert.IsTrue(ServiceContext.ContentService.SaveAndPublish(content1, userId: 0).Success); var content2 = MockedContent.CreateBasicContent(contentType); - content2.PropertyValues(ServiceContext.ContentTypeBaseServices, obj); + content2.PropertyValues(obj); content2.ResetDirtyProperties(false); ServiceContext.ContentService.Save(content2, Constants.Security.SuperUserId); Assert.IsTrue(ServiceContext.ContentService.SaveAndPublish(content2, userId: 0).Success); diff --git a/src/Umbraco.Tests/Testing/ContentBaseExtensions.cs b/src/Umbraco.Tests/Testing/ContentBaseExtensions.cs index 883c7682f4..6d3d2c7683 100644 --- a/src/Umbraco.Tests/Testing/ContentBaseExtensions.cs +++ b/src/Umbraco.Tests/Testing/ContentBaseExtensions.cs @@ -9,16 +9,12 @@ namespace Umbraco.Tests.Testing { public static class ContentBaseExtensions { - public static void PropertyValues(this IContentBase content, object value, string culture = null, string segment = null) - { - content.PropertyValues(Current.Services.ContentTypeBaseServices, value, culture, segment); - } - + /// /// Set property values by alias with an anonymous object. /// /// Does not support variants. - public static void PropertyValues(this IContentBase content, IContentTypeBaseServiceProvider contentTypeServiceProvider, object value, string culture = null, string segment = null) + public static void PropertyValues(this IContentBase content, object value, string culture = null, string segment = null) { if (value == null) throw new Exception("No properties has been passed in"); @@ -35,12 +31,13 @@ namespace Umbraco.Tests.Testing else { - //TODO: Will this ever happen?? In theory we don't need to lookup the content type here since we can just check if the content contains properties with the correct name, - // however, i think this may be needed in the case where the content type contains property types that do not exist yet as properties on the - // content item? But can that happen? AFAIK it can't/shouldn't because of how we create content items in ContentBase we do _properties.EnsurePropertyTypes! - - var contentType = contentTypeServiceProvider.GetContentTypeOf(content); - var propertyType = contentType.CompositionPropertyTypes.FirstOrDefault(x => x.Alias == propertyInfo.Name); + //fixme: Can this ever happen? According to the ctor in ContentBase (EnsurePropertyTypes), all properties will be created based on the content type's property types + // so how can a property not be resolved by the alias on the content.Properties but it can on the content type? + // This maybe can happen if a developer has removed a property with the api and is trying to then set the value of that property again... + // BUT, as it turns out the content.Properties.Remove(...) method is NEVER used, because why and how could it? you never remove a property from + // a content item directly. + + var propertyType = ((ContentBase)content).AllPropertyTypes.FirstOrDefault(x => x.Alias == propertyInfo.Name); if (propertyType == null) throw new Exception($"The property alias {propertyInfo.Name} is not valid, because no PropertyType with this alias exists"); //Create new Property to add to collection From 03eaf3aa3dc034930621545e5562c4fb287b09e0 Mon Sep 17 00:00:00 2001 From: Shannon Date: Thu, 7 Feb 2019 13:29:01 +1100 Subject: [PATCH 36/68] So yup ISimpleContentType needs the IUmbracoEntity, so we'll explicitly implement essentially hiding the implementation from the API unless it's explicitly cast --- src/Umbraco.Core/Models/ISimpleContentType.cs | 6 +-- src/Umbraco.Core/Models/SimpleContentType.cs | 48 +++++++++---------- 2 files changed, 27 insertions(+), 27 deletions(-) diff --git a/src/Umbraco.Core/Models/ISimpleContentType.cs b/src/Umbraco.Core/Models/ISimpleContentType.cs index 7f6b2e68ea..740db8e73f 100644 --- a/src/Umbraco.Core/Models/ISimpleContentType.cs +++ b/src/Umbraco.Core/Models/ISimpleContentType.cs @@ -5,10 +5,10 @@ namespace Umbraco.Core.Models /// /// Represents a simplified view of a content type. /// - public interface ISimpleContentType + public interface ISimpleContentType : IUmbracoEntity { - int Id { get; } - string Name { get; } + new int Id { get; } + new string Name { get; } /// /// Gets the alias of the content type. diff --git a/src/Umbraco.Core/Models/SimpleContentType.cs b/src/Umbraco.Core/Models/SimpleContentType.cs index 86a1e56723..5c81017ec8 100644 --- a/src/Umbraco.Core/Models/SimpleContentType.cs +++ b/src/Umbraco.Core/Models/SimpleContentType.cs @@ -106,29 +106,29 @@ namespace Umbraco.Core.Models // we have to have all this, because we're an IUmbracoEntity, because that is // required by the query expression visitor / SimpleContentTypeMapper - //string ITreeEntity.Name { get => this.Name; set => throw new NotImplementedException(); } - //int IEntity.Id { get => this.Id; set => throw new NotImplementedException(); } - //bool IEntity.HasIdentity => this.Id != default; - //int ITreeEntity.CreatorId { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - //int ITreeEntity.ParentId { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - //int ITreeEntity.Level { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - //string ITreeEntity.Path { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - //int ITreeEntity.SortOrder { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - //bool ITreeEntity.Trashed => throw new NotImplementedException(); - //Guid IEntity.Key { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - //DateTime IEntity.CreateDate { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - //DateTime IEntity.UpdateDate { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - //DateTime? IEntity.DeleteDate { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - //void ITreeEntity.SetParent(ITreeEntity parent) => throw new NotImplementedException(); - //object IDeepCloneable.DeepClone() => throw new NotImplementedException(); - //bool IRememberBeingDirty.WasDirty() => throw new NotImplementedException(); - //bool IRememberBeingDirty.WasPropertyDirty(string propertyName) => throw new NotImplementedException(); - //void IRememberBeingDirty.ResetWereDirtyProperties() => throw new NotImplementedException(); - //void IRememberBeingDirty.ResetDirtyProperties(bool rememberDirty) => throw new NotImplementedException(); - //IEnumerable IRememberBeingDirty.GetWereDirtyProperties() => throw new NotImplementedException(); - //bool ICanBeDirty.IsDirty() => throw new NotImplementedException(); - //bool ICanBeDirty.IsPropertyDirty(string propName) => throw new NotImplementedException(); - //IEnumerable ICanBeDirty.GetDirtyProperties() => throw new NotImplementedException(); - //void ICanBeDirty.ResetDirtyProperties() => throw new NotImplementedException(); + string ITreeEntity.Name { get => this.Name; set => throw new NotImplementedException(); } + int IEntity.Id { get => this.Id; set => throw new NotImplementedException(); } + bool IEntity.HasIdentity => this.Id != default; + int ITreeEntity.CreatorId { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + int ITreeEntity.ParentId { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + int ITreeEntity.Level { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + string ITreeEntity.Path { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + int ITreeEntity.SortOrder { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + bool ITreeEntity.Trashed => throw new NotImplementedException(); + Guid IEntity.Key { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + DateTime IEntity.CreateDate { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + DateTime IEntity.UpdateDate { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + DateTime? IEntity.DeleteDate { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + void ITreeEntity.SetParent(ITreeEntity parent) => throw new NotImplementedException(); + object IDeepCloneable.DeepClone() => throw new NotImplementedException(); + bool IRememberBeingDirty.WasDirty() => throw new NotImplementedException(); + bool IRememberBeingDirty.WasPropertyDirty(string propertyName) => throw new NotImplementedException(); + void IRememberBeingDirty.ResetWereDirtyProperties() => throw new NotImplementedException(); + void IRememberBeingDirty.ResetDirtyProperties(bool rememberDirty) => throw new NotImplementedException(); + IEnumerable IRememberBeingDirty.GetWereDirtyProperties() => throw new NotImplementedException(); + bool ICanBeDirty.IsDirty() => throw new NotImplementedException(); + bool ICanBeDirty.IsPropertyDirty(string propName) => throw new NotImplementedException(); + IEnumerable ICanBeDirty.GetDirtyProperties() => throw new NotImplementedException(); + void ICanBeDirty.ResetDirtyProperties() => throw new NotImplementedException(); } } From a9045c254eda37a296f29e1c834cf1f703385b58 Mon Sep 17 00:00:00 2001 From: Shannon Date: Thu, 7 Feb 2019 14:01:00 +1100 Subject: [PATCH 37/68] Removes the need to do any lookup for GetNonGroupedProperties, we already know if they belong to a non-group based on the ID --- src/Umbraco.Core/ContentExtensions.cs | 9 +++------ src/Umbraco.Tests/Models/ContentTests.cs | 4 +--- .../Mapping/MemberTabsAndPropertiesResolver.cs | 4 ++-- .../Models/Mapping/TabsAndPropertiesResolver.cs | 14 ++++++-------- 4 files changed, 12 insertions(+), 19 deletions(-) diff --git a/src/Umbraco.Core/ContentExtensions.cs b/src/Umbraco.Core/ContentExtensions.cs index d552b3f960..f802c2d0d9 100644 --- a/src/Umbraco.Core/ContentExtensions.cs +++ b/src/Umbraco.Core/ContentExtensions.cs @@ -106,15 +106,12 @@ namespace Umbraco.Core /// Returns properties that do not belong to a group /// /// - /// /// - public static IEnumerable GetNonGroupedProperties(this IContentBase content, IContentTypeBaseServiceProvider contentTypeBaseService) + public static IEnumerable GetNonGroupedProperties(this IContentBase content) { - var contentType = contentTypeBaseService.GetContentTypeOf(content); - var propertyIdsInTabs = contentType.PropertyGroups.SelectMany(pg => pg.PropertyTypes); return content.Properties - .Where(property => propertyIdsInTabs.Contains(property.PropertyType) == false) - .OrderBy(x => x.PropertyType.SortOrder); + .Where(x => x.PropertyType.PropertyGroupId == null) + .OrderBy(x => x.PropertyType.SortOrder); } /// diff --git a/src/Umbraco.Tests/Models/ContentTests.cs b/src/Umbraco.Tests/Models/ContentTests.cs index f211e570e9..693f919b7a 100644 --- a/src/Umbraco.Tests/Models/ContentTests.cs +++ b/src/Umbraco.Tests/Models/ContentTests.cs @@ -138,9 +138,7 @@ namespace Umbraco.Tests.Models var content = MockedContent.CreateSimpleContent(contentType); //need to id the p - var serviceProvider = new ContentTypeBaseServiceProvider(_contentTypeService, Mock.Of(), Mock.Of()); - - var nonGrouped = content.GetNonGroupedProperties(serviceProvider); + var nonGrouped = content.GetNonGroupedProperties(); Assert.AreEqual(2, nonGrouped.Count()); Assert.AreEqual(5, content.Properties.Count()); diff --git a/src/Umbraco.Web/Models/Mapping/MemberTabsAndPropertiesResolver.cs b/src/Umbraco.Web/Models/Mapping/MemberTabsAndPropertiesResolver.cs index 288b835318..517889277c 100644 --- a/src/Umbraco.Web/Models/Mapping/MemberTabsAndPropertiesResolver.cs +++ b/src/Umbraco.Web/Models/Mapping/MemberTabsAndPropertiesResolver.cs @@ -29,8 +29,8 @@ namespace Umbraco.Web.Models.Mapping private readonly IMemberService _memberService; private readonly IUserService _userService; - public MemberTabsAndPropertiesResolver(IUmbracoContextAccessor umbracoContextAccessor, ILocalizedTextService localizedTextService, IMemberService memberService, IUserService userService, IMemberTypeService memberTypeService, IContentTypeBaseServiceProvider contentTypeServiceProvider) - : base(localizedTextService, contentTypeServiceProvider) + public MemberTabsAndPropertiesResolver(IUmbracoContextAccessor umbracoContextAccessor, ILocalizedTextService localizedTextService, IMemberService memberService, IUserService userService, IMemberTypeService memberTypeService) + : base(localizedTextService) { _umbracoContextAccessor = umbracoContextAccessor ?? throw new ArgumentNullException(nameof(umbracoContextAccessor)); _localizedTextService = localizedTextService ?? throw new ArgumentNullException(nameof(localizedTextService)); diff --git a/src/Umbraco.Web/Models/Mapping/TabsAndPropertiesResolver.cs b/src/Umbraco.Web/Models/Mapping/TabsAndPropertiesResolver.cs index 6f3815f678..dc3cc9e74f 100644 --- a/src/Umbraco.Web/Models/Mapping/TabsAndPropertiesResolver.cs +++ b/src/Umbraco.Web/Models/Mapping/TabsAndPropertiesResolver.cs @@ -12,19 +12,17 @@ namespace Umbraco.Web.Models.Mapping { internal abstract class TabsAndPropertiesResolver { - private readonly IContentTypeBaseServiceProvider _contentTypeServiceProvider; protected ILocalizedTextService LocalizedTextService { get; } protected IEnumerable IgnoreProperties { get; set; } - protected TabsAndPropertiesResolver(ILocalizedTextService localizedTextService, IContentTypeBaseServiceProvider contentTypeServiceProvider) + protected TabsAndPropertiesResolver(ILocalizedTextService localizedTextService) { - _contentTypeServiceProvider = contentTypeServiceProvider; LocalizedTextService = localizedTextService ?? throw new ArgumentNullException(nameof(localizedTextService)); IgnoreProperties = new List(); } - protected TabsAndPropertiesResolver(ILocalizedTextService localizedTextService, IContentTypeBaseServiceProvider contentTypeServiceProvider, IEnumerable ignoreProperties) - : this(localizedTextService, contentTypeServiceProvider) + protected TabsAndPropertiesResolver(ILocalizedTextService localizedTextService, IEnumerable ignoreProperties) + : this(localizedTextService) { IgnoreProperties = ignoreProperties ?? throw new ArgumentNullException(nameof(ignoreProperties)); } @@ -52,7 +50,7 @@ namespace Umbraco.Web.Models.Mapping { // add the generic properties tab, for properties that don't belong to a tab // get the properties, map and translate them, then add the tab - var noGroupProperties = content.GetNonGroupedProperties(_contentTypeServiceProvider) + var noGroupProperties = content.GetNonGroupedProperties() .Where(x => IgnoreProperties.Contains(x.Alias) == false) // skip ignored .ToList(); var genericproperties = MapProperties(content, noGroupProperties, context); @@ -124,8 +122,8 @@ namespace Umbraco.Web.Models.Mapping internal class TabsAndPropertiesResolver : TabsAndPropertiesResolver, IValueResolver>> where TSource : IContentBase { - public TabsAndPropertiesResolver(ILocalizedTextService localizedTextService, IContentTypeBaseServiceProvider contentTypeServiceProvider) - : base(localizedTextService, contentTypeServiceProvider) + public TabsAndPropertiesResolver(ILocalizedTextService localizedTextService) + : base(localizedTextService) { } public virtual IEnumerable> Resolve(TSource source, TDestination destination, IEnumerable> destMember, ResolutionContext context) From 977250dcddfdc50564e8affb4beb69c6d047ee0c Mon Sep 17 00:00:00 2001 From: Shannon Date: Thu, 7 Feb 2019 17:15:49 +1100 Subject: [PATCH 38/68] tests as part of build --- src/Umbraco.Web.UI.Client/gulp/tasks/build.js | 2 +- src/Umbraco.Web.UI.Client/gulp/tasks/test.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/gulp/tasks/build.js b/src/Umbraco.Web.UI.Client/gulp/tasks/build.js index 4e519c58e9..32bf71f5f7 100644 --- a/src/Umbraco.Web.UI.Client/gulp/tasks/build.js +++ b/src/Umbraco.Web.UI.Client/gulp/tasks/build.js @@ -6,5 +6,5 @@ var runSequence = require('run-sequence'); // Build - build the files ready for production gulp.task('build', function(cb) { - runSequence(["dependencies", "js", "less", "views"], cb); + runSequence(["js", "dependencies", "less", "views"], "test:unit", cb); }); diff --git a/src/Umbraco.Web.UI.Client/gulp/tasks/test.js b/src/Umbraco.Web.UI.Client/gulp/tasks/test.js index 76712f1454..eae65613c4 100644 --- a/src/Umbraco.Web.UI.Client/gulp/tasks/test.js +++ b/src/Umbraco.Web.UI.Client/gulp/tasks/test.js @@ -11,7 +11,7 @@ var runSequence = require('run-sequence'); // Karma test gulp.task('runTests', function(cb) { - runSequence(["js"], "test:unit", cb); + runSequence("js", "test:unit", cb); }); gulp.task('test:unit', function () { From d11fd67a093827e577cab4c685528ea56d1316fb Mon Sep 17 00:00:00 2001 From: Stephan Date: Wed, 6 Feb 2019 19:04:58 +0100 Subject: [PATCH 39/68] Bugfix PublishedContentTypeFactory --- .../PublishedContentTypeFactory.cs | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Core/Models/PublishedContent/PublishedContentTypeFactory.cs b/src/Umbraco.Core/Models/PublishedContent/PublishedContentTypeFactory.cs index 8a44a7a9b4..2ca3593b55 100644 --- a/src/Umbraco.Core/Models/PublishedContent/PublishedContentTypeFactory.cs +++ b/src/Umbraco.Core/Models/PublishedContent/PublishedContentTypeFactory.cs @@ -87,8 +87,20 @@ namespace Umbraco.Core.Models.PublishedContent { lock (_publishedDataTypesLocker) { - var dataTypes = _dataTypeService.GetAll(ids); - _publishedDataTypes = dataTypes.ToDictionary(x => x.Id, CreatePublishedDataType); + if (_publishedDataTypes == null) + { + var dataTypes = _dataTypeService.GetAll(); + _publishedDataTypes = dataTypes.ToDictionary(x => x.Id, CreatePublishedDataType); + } + else + { + foreach (var id in ids) + _publishedDataTypes.Remove(id); + + var dataTypes = _dataTypeService.GetAll(ids); + foreach (var dataType in dataTypes) + _publishedDataTypes[dataType.Id] = CreatePublishedDataType(dataType); + } } } From f6da7e4444d45f420c50e7a533b89eb66d067201 Mon Sep 17 00:00:00 2001 From: Bjarke Berg Date: Thu, 7 Feb 2019 08:19:44 +0100 Subject: [PATCH 40/68] JS error, handle user dialog in the same way as help dialog. Don't close on change of section. Before was a js error with missing method --- .../components/application/umbsections.directive.js | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/application/umbsections.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/application/umbsections.directive.js index 5006087ca5..14c9878839 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/application/umbsections.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/application/umbsections.directive.js @@ -105,11 +105,6 @@ function sectionsDirective($timeout, $window, navigationService, treeService, se return; } - if (scope.userDialog) { - closeUserDialog(); - } - - navigationService.hideSearch(); navigationService.showTree(section.alias); From 8329097974b56da85d16549e09b9b92ba85539db Mon Sep 17 00:00:00 2001 From: Stephan Date: Wed, 6 Feb 2019 17:28:48 +0100 Subject: [PATCH 41/68] Review PR, adjustments --- .../CancellableEnumerableObjectEventArgs.cs | 24 ++--- .../Events/CancellableEventArgs.cs | 4 +- .../Events/CancellableObjectEventArgs.cs | 90 +------------------ ...ancellableObjectEventArgsOfTEventObject.cs | 82 +++++++++++++++++ .../Events/ContentPublishedEventArgs.cs | 19 ++-- .../Events/ContentPublishingEventArgs.cs | 17 ++-- .../Events/ContentSavedEventArgs.cs | 20 ++--- .../Events/ContentSavingEventArgs.cs | 31 ++++--- src/Umbraco.Core/Models/Content.cs | 24 ++--- src/Umbraco.Core/Models/ContentBase.cs | 37 ++++---- .../Models/ContentRepositoryExtensions.cs | 8 +- src/Umbraco.Core/Models/IContentBase.cs | 2 +- .../Repositories/IDocumentRepository.cs | 2 - .../Implement/DocumentRepository.cs | 22 +++-- src/Umbraco.Core/Services/IContentService.cs | 16 ++-- .../Services/Implement/ContentService.cs | 20 +++-- src/Umbraco.Core/Umbraco.Core.csproj | 1 + 17 files changed, 212 insertions(+), 207 deletions(-) create mode 100644 src/Umbraco.Core/Events/CancellableObjectEventArgsOfTEventObject.cs diff --git a/src/Umbraco.Core/Events/CancellableEnumerableObjectEventArgs.cs b/src/Umbraco.Core/Events/CancellableEnumerableObjectEventArgs.cs index 1a651ef348..1d52d0d847 100644 --- a/src/Umbraco.Core/Events/CancellableEnumerableObjectEventArgs.cs +++ b/src/Umbraco.Core/Events/CancellableEnumerableObjectEventArgs.cs @@ -1,34 +1,36 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Security.Permissions; namespace Umbraco.Core.Events { - [HostProtection(SecurityAction.LinkDemand, SharedState = true)] - public class CancellableEnumerableObjectEventArgs : CancellableObjectEventArgs>, IEquatable> + /// + /// Represents event data, for events that support cancellation, and expose impacted objects. + /// + /// The type of the exposed, impacted objects. + public class CancellableEnumerableObjectEventArgs : CancellableObjectEventArgs>, IEquatable> { - public CancellableEnumerableObjectEventArgs(IEnumerable eventObject, bool canCancel, EventMessages messages, IDictionary additionalData) + public CancellableEnumerableObjectEventArgs(IEnumerable eventObject, bool canCancel, EventMessages messages, IDictionary additionalData) : base(eventObject, canCancel, messages, additionalData) { } - public CancellableEnumerableObjectEventArgs(IEnumerable eventObject, bool canCancel, EventMessages eventMessages) + public CancellableEnumerableObjectEventArgs(IEnumerable eventObject, bool canCancel, EventMessages eventMessages) : base(eventObject, canCancel, eventMessages) { } - public CancellableEnumerableObjectEventArgs(IEnumerable eventObject, EventMessages eventMessages) + public CancellableEnumerableObjectEventArgs(IEnumerable eventObject, EventMessages eventMessages) : base(eventObject, eventMessages) { } - public CancellableEnumerableObjectEventArgs(IEnumerable eventObject, bool canCancel) + public CancellableEnumerableObjectEventArgs(IEnumerable eventObject, bool canCancel) : base(eventObject, canCancel) { } - public CancellableEnumerableObjectEventArgs(IEnumerable eventObject) + public CancellableEnumerableObjectEventArgs(IEnumerable eventObject) : base(eventObject) { } - public bool Equals(CancellableEnumerableObjectEventArgs other) + public bool Equals(CancellableEnumerableObjectEventArgs other) { if (other is null) return false; if (ReferenceEquals(this, other)) return true; @@ -41,7 +43,7 @@ namespace Umbraco.Core.Events if (obj is null) return false; if (ReferenceEquals(this, obj)) return true; if (obj.GetType() != this.GetType()) return false; - return Equals((CancellableEnumerableObjectEventArgs)obj); + return Equals((CancellableEnumerableObjectEventArgs)obj); } public override int GetHashCode() @@ -49,4 +51,4 @@ namespace Umbraco.Core.Events return HashCodeHelper.GetHashCode(EventObject); } } -} \ No newline at end of file +} diff --git a/src/Umbraco.Core/Events/CancellableEventArgs.cs b/src/Umbraco.Core/Events/CancellableEventArgs.cs index 19f576478f..d9d670ea59 100644 --- a/src/Umbraco.Core/Events/CancellableEventArgs.cs +++ b/src/Umbraco.Core/Events/CancellableEventArgs.cs @@ -1,14 +1,12 @@ using System; using System.Collections.Generic; using System.Collections.ObjectModel; -using System.Security.Permissions; namespace Umbraco.Core.Events { /// - /// Event args for that can support cancellation + /// Represents event data for events that support cancellation. /// - [HostProtection(SecurityAction.LinkDemand, SharedState = true)] public class CancellableEventArgs : EventArgs, IEquatable { private bool _cancel; diff --git a/src/Umbraco.Core/Events/CancellableObjectEventArgs.cs b/src/Umbraco.Core/Events/CancellableObjectEventArgs.cs index 27ffb1b75d..daf36fd6c8 100644 --- a/src/Umbraco.Core/Events/CancellableObjectEventArgs.cs +++ b/src/Umbraco.Core/Events/CancellableObjectEventArgs.cs @@ -1,15 +1,10 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Security.Permissions; -using Umbraco.Core.Models; +using System.Collections.Generic; namespace Umbraco.Core.Events { /// - /// Used as a base class for the generic type CancellableObjectEventArgs{T} so that we can get direct 'object' access to the underlying EventObject + /// Provides a base class for classes representing event data, for events that support cancellation, and expose an impacted object. /// - [HostProtection(SecurityAction.LinkDemand, SharedState = true)] public abstract class CancellableObjectEventArgs : CancellableEventArgs { protected CancellableObjectEventArgs(object eventObject, bool canCancel, EventMessages messages, IDictionary additionalData) @@ -41,90 +36,11 @@ namespace Umbraco.Core.Events } /// - /// Returns the object relating to the event + /// Gets or sets the impacted object. /// /// /// This is protected so that inheritors can expose it with their own name /// internal object EventObject { get; set; } - - } - - /// - /// Event args for a strongly typed object that can support cancellation - /// - /// - [HostProtection(SecurityAction.LinkDemand, SharedState = true)] - public class CancellableObjectEventArgs : CancellableObjectEventArgs, IEquatable> - { - public CancellableObjectEventArgs(T eventObject, bool canCancel, EventMessages messages, IDictionary additionalData) - : base(eventObject, canCancel, messages, additionalData) - { - } - - public CancellableObjectEventArgs(T eventObject, bool canCancel, EventMessages eventMessages) - : base(eventObject, canCancel, eventMessages) - { - } - - public CancellableObjectEventArgs(T eventObject, EventMessages eventMessages) - : base(eventObject, eventMessages) - { - } - - public CancellableObjectEventArgs(T eventObject, bool canCancel) - : base(eventObject, canCancel) - { - } - - public CancellableObjectEventArgs(T eventObject) - : base(eventObject) - { - } - - /// - /// Returns the object relating to the event - /// - /// - /// This is protected so that inheritors can expose it with their own name - /// - protected new T EventObject - { - get { return (T) base.EventObject; } - set { base.EventObject = value; } - } - - public bool Equals(CancellableObjectEventArgs other) - { - if (other is null) return false; - if (ReferenceEquals(this, other)) return true; - return base.Equals(other) && EqualityComparer.Default.Equals(EventObject, other.EventObject); - } - - public override bool Equals(object obj) - { - if (obj is null) return false; - if (ReferenceEquals(this, obj)) return true; - if (obj.GetType() != this.GetType()) return false; - return Equals((CancellableObjectEventArgs)obj); - } - - public override int GetHashCode() - { - unchecked - { - return (base.GetHashCode() * 397) ^ EqualityComparer.Default.GetHashCode(EventObject); - } - } - - public static bool operator ==(CancellableObjectEventArgs left, CancellableObjectEventArgs right) - { - return Equals(left, right); - } - - public static bool operator !=(CancellableObjectEventArgs left, CancellableObjectEventArgs right) - { - return !Equals(left, right); - } } } diff --git a/src/Umbraco.Core/Events/CancellableObjectEventArgsOfTEventObject.cs b/src/Umbraco.Core/Events/CancellableObjectEventArgsOfTEventObject.cs new file mode 100644 index 0000000000..ace2ce0a4f --- /dev/null +++ b/src/Umbraco.Core/Events/CancellableObjectEventArgsOfTEventObject.cs @@ -0,0 +1,82 @@ +using System; +using System.Collections.Generic; + +namespace Umbraco.Core.Events +{ + /// + /// Represent event data, for events that support cancellation, and expose an impacted object. + /// + /// The type of the exposed, impacted object. + public class CancellableObjectEventArgs : CancellableObjectEventArgs, IEquatable> + { + public CancellableObjectEventArgs(TEventObject eventObject, bool canCancel, EventMessages messages, IDictionary additionalData) + : base(eventObject, canCancel, messages, additionalData) + { + } + + public CancellableObjectEventArgs(TEventObject eventObject, bool canCancel, EventMessages eventMessages) + : base(eventObject, canCancel, eventMessages) + { + } + + public CancellableObjectEventArgs(TEventObject eventObject, EventMessages eventMessages) + : base(eventObject, eventMessages) + { + } + + public CancellableObjectEventArgs(TEventObject eventObject, bool canCancel) + : base(eventObject, canCancel) + { + } + + public CancellableObjectEventArgs(TEventObject eventObject) + : base(eventObject) + { + } + + /// + /// Gets or sets the impacted object. + /// + /// + /// This is protected so that inheritors can expose it with their own name + /// + protected new TEventObject EventObject + { + get => (TEventObject) base.EventObject; + set => base.EventObject = value; + } + + public bool Equals(CancellableObjectEventArgs other) + { + if (other is null) return false; + if (ReferenceEquals(this, other)) return true; + return base.Equals(other) && EqualityComparer.Default.Equals(EventObject, other.EventObject); + } + + public override bool Equals(object obj) + { + if (obj is null) return false; + if (ReferenceEquals(this, obj)) return true; + if (obj.GetType() != this.GetType()) return false; + return Equals((CancellableObjectEventArgs)obj); + } + + public override int GetHashCode() + { + unchecked + { + return (base.GetHashCode() * 397) ^ EqualityComparer.Default.GetHashCode(EventObject); + } + } + + public static bool operator ==(CancellableObjectEventArgs left, CancellableObjectEventArgs right) + { + return Equals(left, right); + } + + public static bool operator !=(CancellableObjectEventArgs left, CancellableObjectEventArgs right) + { + return !Equals(left, right); + } + } +} diff --git a/src/Umbraco.Core/Events/ContentPublishedEventArgs.cs b/src/Umbraco.Core/Events/ContentPublishedEventArgs.cs index 589e447ba7..8c0690d591 100644 --- a/src/Umbraco.Core/Events/ContentPublishedEventArgs.cs +++ b/src/Umbraco.Core/Events/ContentPublishedEventArgs.cs @@ -1,29 +1,30 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using Umbraco.Core.Models; namespace Umbraco.Core.Events { + /// + /// Represents event data for the Published event. + /// public class ContentPublishedEventArgs : PublishEventArgs { + /// + /// Initializes a new instance of the class. + /// public ContentPublishedEventArgs(IEnumerable eventObject, bool canCancel, EventMessages eventMessages) : base(eventObject, canCancel, eventMessages) - { - } + { } /// /// Determines whether a culture has been published, during a Published event. /// public bool HasPublishedCulture(IContent content, string culture) - => content.WasPropertyDirty("_changedCulture_" + culture); + => content.WasPropertyDirty(ContentBase.ChangeTrackingPrefix.ChangedCulture + culture); /// /// Determines whether a culture has been unpublished, during a Published event. /// public bool HasUnpublishedCulture(IContent content, string culture) - => content.WasPropertyDirty("_unpublishedCulture_" + culture); - - - + => content.WasPropertyDirty(ContentBase.ChangeTrackingPrefix.UnpublishedCulture + culture); } } diff --git a/src/Umbraco.Core/Events/ContentPublishingEventArgs.cs b/src/Umbraco.Core/Events/ContentPublishingEventArgs.cs index 35cbf63441..b64bb19def 100644 --- a/src/Umbraco.Core/Events/ContentPublishingEventArgs.cs +++ b/src/Umbraco.Core/Events/ContentPublishingEventArgs.cs @@ -1,21 +1,19 @@ -using System; -using System.Linq; -using System.Collections.Generic; +using System.Collections.Generic; using Umbraco.Core.Models; namespace Umbraco.Core.Events { + /// + /// Represents event data for the Publishing event. + /// public class ContentPublishingEventArgs : PublishEventArgs { /// - /// Creates a new + /// Initializes a new instance of the class. /// - /// - /// public ContentPublishingEventArgs(IEnumerable eventObject, EventMessages eventMessages) : base(eventObject, eventMessages) - { - } + { } /// /// Determines whether a culture is being published, during a Publishing event. @@ -27,7 +25,6 @@ namespace Umbraco.Core.Events /// Determines whether a culture is being unpublished, during a Publishing event. /// public bool IsUnpublishingCulture(IContent content, string culture) - => content.IsPropertyDirty("_unpublishedCulture_" + culture); //bit of a hack since we know that the content implementation tracks changes this way - + => content.IsPropertyDirty(ContentBase.ChangeTrackingPrefix.UnpublishedCulture + culture); //bit of a hack since we know that the content implementation tracks changes this way } } diff --git a/src/Umbraco.Core/Events/ContentSavedEventArgs.cs b/src/Umbraco.Core/Events/ContentSavedEventArgs.cs index 4d4085b064..e2d8c25dd1 100644 --- a/src/Umbraco.Core/Events/ContentSavedEventArgs.cs +++ b/src/Umbraco.Core/Events/ContentSavedEventArgs.cs @@ -1,30 +1,24 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using Umbraco.Core.Models; namespace Umbraco.Core.Events { + /// + /// Represents event data for the Saved event. + /// public class ContentSavedEventArgs : SaveEventArgs { - #region Constructors - /// - /// Creates a new + /// Initializes a new instance of the class. /// - /// - /// - /// public ContentSavedEventArgs(IEnumerable eventObject, EventMessages messages, IDictionary additionalData) : base(eventObject, false, messages, additionalData) - { - } - - #endregion + { } /// /// Determines whether a culture has been saved, during a Saved event. /// public bool HasSavedCulture(IContent content, string culture) - => content.WasPropertyDirty("_updatedCulture_" + culture); + => content.WasPropertyDirty(ContentBase.ChangeTrackingPrefix.UpdatedCulture + culture); } } diff --git a/src/Umbraco.Core/Events/ContentSavingEventArgs.cs b/src/Umbraco.Core/Events/ContentSavingEventArgs.cs index aa62f64349..384353ee2e 100644 --- a/src/Umbraco.Core/Events/ContentSavingEventArgs.cs +++ b/src/Umbraco.Core/Events/ContentSavingEventArgs.cs @@ -1,12 +1,15 @@ -using System.Linq; -using System.Collections.Generic; +using System.Collections.Generic; using Umbraco.Core.Models; namespace Umbraco.Core.Events { + /// + /// Represent event data for the Saving event. + /// public class ContentSavingEventArgs : SaveEventArgs { #region Factory Methods + /// /// Converts to while preserving all args state /// @@ -43,24 +46,32 @@ namespace Umbraco.Core.Events EventState = EventState, AdditionalData = AdditionalData }; - } + } + #endregion #region Constructors - public ContentSavingEventArgs(IEnumerable eventObject, EventMessages eventMessages) : base(eventObject, eventMessages) - { - } + /// + /// Initializes a new instance of the class. + /// + public ContentSavingEventArgs(IEnumerable eventObject, EventMessages eventMessages) + : base(eventObject, eventMessages) + { } - public ContentSavingEventArgs(IContent eventObject, EventMessages eventMessages) : base(eventObject, eventMessages) - { - } + /// + /// Initializes a new instance of the class. + /// + public ContentSavingEventArgs(IContent eventObject, EventMessages eventMessages) + : base(eventObject, eventMessages) + { } #endregion /// /// Determines whether a culture is being saved, during a Saving event. /// - public bool IsSavingCulture(IContent content, string culture) => content.CultureInfos.TryGetValue(culture, out var cultureInfo) && cultureInfo.IsDirty(); + public bool IsSavingCulture(IContent content, string culture) + => content.CultureInfos.TryGetValue(culture, out var cultureInfo) && cultureInfo.IsDirty(); } } diff --git a/src/Umbraco.Core/Models/Content.cs b/src/Umbraco.Core/Models/Content.cs index 483ba8b0d2..f0c1915f75 100644 --- a/src/Umbraco.Core/Models/Content.cs +++ b/src/Umbraco.Core/Models/Content.cs @@ -385,19 +385,19 @@ namespace Umbraco.Core.Models public override bool IsPropertyDirty(string propertyName) { //Special check here since we want to check if the request is for changed cultures - if (propertyName.StartsWith("_publishedCulture_")) + if (propertyName.StartsWith(ChangeTrackingPrefix.PublishedCulture)) { - var culture = propertyName.TrimStart("_publishedCulture_"); + var culture = propertyName.TrimStart(ChangeTrackingPrefix.PublishedCulture); return _currentPublishCultureChanges.addedCultures?.Contains(culture) ?? false; } - if (propertyName.StartsWith("_unpublishedCulture_")) + if (propertyName.StartsWith(ChangeTrackingPrefix.UnpublishedCulture)) { - var culture = propertyName.TrimStart("_unpublishedCulture_"); + var culture = propertyName.TrimStart(ChangeTrackingPrefix.UnpublishedCulture); return _currentPublishCultureChanges.removedCultures?.Contains(culture) ?? false; } - if (propertyName.StartsWith("_changedCulture_")) + if (propertyName.StartsWith(ChangeTrackingPrefix.ChangedCulture)) { - var culture = propertyName.TrimStart("_changedCulture_"); + var culture = propertyName.TrimStart(ChangeTrackingPrefix.ChangedCulture); return _currentPublishCultureChanges.updatedCultures?.Contains(culture) ?? false; } @@ -409,19 +409,19 @@ namespace Umbraco.Core.Models public override bool WasPropertyDirty(string propertyName) { //Special check here since we want to check if the request is for changed cultures - if (propertyName.StartsWith("_publishedCulture_")) + if (propertyName.StartsWith(ChangeTrackingPrefix.PublishedCulture)) { - var culture = propertyName.TrimStart("_publishedCulture_"); + var culture = propertyName.TrimStart(ChangeTrackingPrefix.PublishedCulture); return _previousPublishCultureChanges.addedCultures?.Contains(culture) ?? false; } - if (propertyName.StartsWith("_unpublishedCulture_")) + if (propertyName.StartsWith(ChangeTrackingPrefix.UnpublishedCulture)) { - var culture = propertyName.TrimStart("_unpublishedCulture_"); + var culture = propertyName.TrimStart(ChangeTrackingPrefix.UnpublishedCulture); return _previousPublishCultureChanges.removedCultures?.Contains(culture) ?? false; } - if (propertyName.StartsWith("_changedCulture_")) + if (propertyName.StartsWith(ChangeTrackingPrefix.ChangedCulture)) { - var culture = propertyName.TrimStart("_changedCulture_"); + var culture = propertyName.TrimStart(ChangeTrackingPrefix.ChangedCulture); return _previousPublishCultureChanges.updatedCultures?.Contains(culture) ?? false; } diff --git a/src/Umbraco.Core/Models/ContentBase.cs b/src/Umbraco.Core/Models/ContentBase.cs index 50de59931c..55922b485a 100644 --- a/src/Umbraco.Core/Models/ContentBase.cs +++ b/src/Umbraco.Core/Models/ContentBase.cs @@ -17,7 +17,6 @@ namespace Umbraco.Core.Models [DebuggerDisplay("Id: {Id}, Name: {Name}, ContentType: {ContentTypeBase.Alias}")] public abstract class ContentBase : TreeEntityBase, IContentBase { - private int _contentTypeId; protected IContentTypeComposition ContentTypeBase; private int _writerId; @@ -29,6 +28,16 @@ namespace Umbraco.Core.Models private (HashSet addedCultures, HashSet removedCultures, HashSet updatedCultures) _currentCultureChanges; private (HashSet addedCultures, HashSet removedCultures, HashSet updatedCultures) _previousCultureChanges; + public static class ChangeTrackingPrefix + { + public const string UpdatedCulture = "_updatedCulture_"; + public const string ChangedCulture = "_changedCulture_"; + public const string PublishedCulture = "_publishedCulture_"; + public const string UnpublishedCulture = "_unpublishedCulture_"; + public const string AddedCulture = "_addedCulture_"; + public const string RemovedCulture = "_removedCulture_"; + } + #endregion /// @@ -71,8 +80,6 @@ namespace Umbraco.Core.Models OnPropertyChanged(nameof(Properties)); } - - /// /// Id of the user who wrote/updated this entity /// @@ -402,19 +409,19 @@ namespace Umbraco.Core.Models return true; //Special check here since we want to check if the request is for changed cultures - if (propertyName.StartsWith("_addedCulture_")) + if (propertyName.StartsWith(ChangeTrackingPrefix.AddedCulture)) { - var culture = propertyName.TrimStart("_addedCulture_"); + var culture = propertyName.TrimStart(ChangeTrackingPrefix.AddedCulture); return _currentCultureChanges.addedCultures?.Contains(culture) ?? false; } - if (propertyName.StartsWith("_removedCulture_")) + if (propertyName.StartsWith(ChangeTrackingPrefix.RemovedCulture)) { - var culture = propertyName.TrimStart("_removedCulture_"); + var culture = propertyName.TrimStart(ChangeTrackingPrefix.RemovedCulture); return _currentCultureChanges.removedCultures?.Contains(culture) ?? false; } - if (propertyName.StartsWith("_updatedCulture_")) + if (propertyName.StartsWith(ChangeTrackingPrefix.UpdatedCulture)) { - var culture = propertyName.TrimStart("_updatedCulture_"); + var culture = propertyName.TrimStart(ChangeTrackingPrefix.UpdatedCulture); return _currentCultureChanges.updatedCultures?.Contains(culture) ?? false; } @@ -429,19 +436,19 @@ namespace Umbraco.Core.Models return true; //Special check here since we want to check if the request is for changed cultures - if (propertyName.StartsWith("_addedCulture_")) + if (propertyName.StartsWith(ChangeTrackingPrefix.AddedCulture)) { - var culture = propertyName.TrimStart("_addedCulture_"); + var culture = propertyName.TrimStart(ChangeTrackingPrefix.AddedCulture); return _previousCultureChanges.addedCultures?.Contains(culture) ?? false; } - if (propertyName.StartsWith("_removedCulture_")) + if (propertyName.StartsWith(ChangeTrackingPrefix.RemovedCulture)) { - var culture = propertyName.TrimStart("_removedCulture_"); + var culture = propertyName.TrimStart(ChangeTrackingPrefix.RemovedCulture); return _previousCultureChanges.removedCultures?.Contains(culture) ?? false; } - if (propertyName.StartsWith("_updatedCulture_")) + if (propertyName.StartsWith(ChangeTrackingPrefix.UpdatedCulture)) { - var culture = propertyName.TrimStart("_updatedCulture_"); + var culture = propertyName.TrimStart(ChangeTrackingPrefix.UpdatedCulture); return _previousCultureChanges.updatedCultures?.Contains(culture) ?? false; } diff --git a/src/Umbraco.Core/Models/ContentRepositoryExtensions.cs b/src/Umbraco.Core/Models/ContentRepositoryExtensions.cs index ca9bf57902..27678c047c 100644 --- a/src/Umbraco.Core/Models/ContentRepositoryExtensions.cs +++ b/src/Umbraco.Core/Models/ContentRepositoryExtensions.cs @@ -20,7 +20,7 @@ namespace Umbraco.Core.Models return Array.Empty(); var culturesUnpublishing = content.CultureInfos.Values - .Where(x => content.IsPropertyDirty("_unpublishedCulture_" + x.Culture)) + .Where(x => content.IsPropertyDirty(ContentBase.ChangeTrackingPrefix.UnpublishedCulture + x.Culture)) .Select(x => x.Culture); return culturesUnpublishing.ToList(); @@ -88,8 +88,7 @@ namespace Umbraco.Core.Models { content.CultureInfos.Clear(); content.CultureInfos = null; - } - + } if (culture == null || culture == "*") content.Name = other.Name; @@ -158,8 +157,9 @@ namespace Umbraco.Core.Models if (!content.PublishCultureInfos.TryGetValue(culture, out var publishInfos)) continue; + // if it's not dirty, it means it hasn't changed so there's nothing to adjust if (!publishInfos.IsDirty()) - continue; //if it's not dirty, it means it hasn't changed so there's nothing to adjust + continue; content.PublishCultureInfos.AddOrUpdate(culture, publishInfos.Name, date); diff --git a/src/Umbraco.Core/Models/IContentBase.cs b/src/Umbraco.Core/Models/IContentBase.cs index 1ebbfa1d49..1a6a6843f9 100644 --- a/src/Umbraco.Core/Models/IContentBase.cs +++ b/src/Umbraco.Core/Models/IContentBase.cs @@ -58,7 +58,7 @@ namespace Umbraco.Core.Models /// culture name, which must be get or set via the property. /// ContentCultureInfosCollection CultureInfos { get; set; } - + /// /// Gets the available cultures. /// diff --git a/src/Umbraco.Core/Persistence/Repositories/IDocumentRepository.cs b/src/Umbraco.Core/Persistence/Repositories/IDocumentRepository.cs index d49c92f1bf..fc5382499f 100644 --- a/src/Umbraco.Core/Persistence/Repositories/IDocumentRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/IDocumentRepository.cs @@ -7,8 +7,6 @@ namespace Umbraco.Core.Persistence.Repositories { public interface IDocumentRepository : IContentRepository, IReadRepository { - - /// /// Clears the publishing schedule for all entries having an a date before (lower than, or equal to) a specified date. /// diff --git a/src/Umbraco.Core/Persistence/Repositories/Implement/DocumentRepository.cs b/src/Umbraco.Core/Persistence/Repositories/Implement/DocumentRepository.cs index 04af52047c..d8e6fd2c0e 100644 --- a/src/Umbraco.Core/Persistence/Repositories/Implement/DocumentRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/Implement/DocumentRepository.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using System.Linq; using NPoco; using Umbraco.Core.Cache; -using Umbraco.Core.Configuration.UmbracoSettings; using Umbraco.Core.Exceptions; using Umbraco.Core.Logging; using Umbraco.Core.Models; @@ -120,15 +119,15 @@ namespace Umbraco.Core.Persistence.Repositories.Implement break; case QueryType.Single: case QueryType.Many: + // R# may flag this ambiguous and red-squiggle it, but it is not + sql = sql.Select(r => + r.Select(documentDto => documentDto.ContentDto, r1 => + r1.Select(contentDto => contentDto.NodeDto)) + .Select(documentDto => documentDto.DocumentVersionDto, r1 => + r1.Select(documentVersionDto => documentVersionDto.ContentVersionDto)) + .Select(documentDto => documentDto.PublishedVersionDto, "pdv", r1 => + r1.Select(documentVersionDto => documentVersionDto.ContentVersionDto, "pcv"))) - //we've put this in a local function so that the below sql.Select statement doesn't have a problem - //thinking that the call is ambiguous - NPocoSqlExtensions.SqlRef SelectStatement(NPocoSqlExtensions.SqlRef r) => - r.Select(documentDto => documentDto.ContentDto, r1 => r1.Select(contentDto => contentDto.NodeDto)) - .Select(documentDto => documentDto.DocumentVersionDto, r1 => r1.Select(documentVersionDto => documentVersionDto.ContentVersionDto)) - .Select(documentDto => documentDto.PublishedVersionDto, "pdv", r1 => r1.Select(documentVersionDto => documentVersionDto.ContentVersionDto, "pcv")); - - sql = sql.Select(SelectStatement) // select the variant name, coalesce to the invariant name, as "variantName" .AndSelect(VariantNameSqlExpression + " AS variantName"); break; @@ -954,8 +953,6 @@ namespace Umbraco.Core.Persistence.Repositories.Implement #endregion - - protected override string ApplySystemOrdering(ref Sql sql, Ordering ordering) { // note: 'updater' is the user who created the latest draft version, @@ -1187,17 +1184,18 @@ namespace Umbraco.Core.Persistence.Repositories.Implement return result; } - private void SetVariations(Content content, IDictionary> contentVariations, IDictionary> documentVariations) { if (contentVariations.TryGetValue(content.VersionId, out var contentVariation)) foreach (var v in contentVariation) content.SetCultureInfo(v.Culture, v.Name, v.Date); + if (content.PublishedVersionId > 0 && contentVariations.TryGetValue(content.PublishedVersionId, out contentVariation)) { foreach (var v in contentVariation) content.SetPublishInfo(v.Culture, v.Name, v.Date); } + if (documentVariations.TryGetValue(content.Id, out var documentVariation)) content.SetCultureEdited(documentVariation.Where(x => x.Edited).Select(x => x.Culture)); } diff --git a/src/Umbraco.Core/Services/IContentService.cs b/src/Umbraco.Core/Services/IContentService.cs index 600921ee78..942206ccc2 100644 --- a/src/Umbraco.Core/Services/IContentService.cs +++ b/src/Umbraco.Core/Services/IContentService.cs @@ -341,11 +341,10 @@ namespace Umbraco.Core.Services /// If the content type is variant, then culture can be either '*' or an actual culture, but neither 'null' nor /// 'empty'. If the content type is invariant, then culture can be either '*' or null or empty. /// - /// - /// - /// - /// - /// + /// The document to publish. + /// The culture to publish. + /// The identifier of the user performing the action. + /// A value indicating whether to raise events. PublishResult SaveAndPublish(IContent content, string culture = "*", int userId = 0, bool raiseEvents = true); /// @@ -356,11 +355,10 @@ namespace Umbraco.Core.Services /// When a culture is being published, it includes all varying values along with all invariant values. /// The document is *always* saved, even when publishing fails. /// - /// + /// The document to publish. /// The cultures to publish. - /// - /// - /// + /// The identifier of the user performing the action. + /// A value indicating whether to raise events. PublishResult SaveAndPublish(IContent content, string[] cultures, int userId = 0, bool raiseEvents = true); /// diff --git a/src/Umbraco.Core/Services/Implement/ContentService.cs b/src/Umbraco.Core/Services/Implement/ContentService.cs index ce7417722d..d034dad22d 100644 --- a/src/Umbraco.Core/Services/Implement/ContentService.cs +++ b/src/Umbraco.Core/Services/Implement/ContentService.cs @@ -908,8 +908,9 @@ namespace Umbraco.Core.Services.Implement : new PublishResult(PublishResultType.FailedPublishNothingToPublish, evtMsgs, content); } + // TODO: currently, no way to know which one failed if (cultures.Select(content.PublishCulture).Any(isValid => !isValid)) - return new PublishResult(PublishResultType.FailedPublishContentInvalid, evtMsgs, content); //fixme: no way to know which one failed? + return new PublishResult(PublishResultType.FailedPublishContentInvalid, evtMsgs, content); return CommitDocumentChanges(content, userId, raiseEvents); } @@ -1055,9 +1056,10 @@ namespace Umbraco.Core.Services.Implement } // reset published state from temp values (publishing, unpublishing) to original value - // (published, unpublished) in order to save the document, unchanged - //TODO: why? this seems odd, were just setting the exact same value that it already has - // instead do we want to just set the PublishState? + // (published, unpublished) in order to save the document, unchanged - yes, this is odd, + // but: (a) it means we don't reproduce the PublishState logic here and (b) setting the + // PublishState to anything other than Publishing or Unpublishing - which is precisely + // what we want to do here - throws content.Published = content.Published; } } @@ -1080,9 +1082,10 @@ namespace Umbraco.Core.Services.Implement else { // reset published state from temp values (publishing, unpublishing) to original value - // (published, unpublished) in order to save the document, unchanged - //TODO: why? this seems odd, were just setting the exact same value that it already has - // instead do we want to just set the PublishState? + // (published, unpublished) in order to save the document, unchanged - yes, this is odd, + // but: (a) it means we don't reproduce the PublishState logic here and (b) setting the + // PublishState to anything other than Publishing or Unpublishing - which is precisely + // what we want to do here - throws content.Published = content.Published; } } @@ -1507,9 +1510,8 @@ namespace Umbraco.Core.Services.Implement Audit(AuditType.Publish, userId, document.Id, "Branch published"); // trigger events for the entire branch + // (SaveAndPublishBranchOne does *not* do it) scope.Events.Dispatch(TreeChanged, this, new TreeChange(document, TreeChangeTypes.RefreshBranch).ToEventArgs()); - - //fixme - in the SaveAndPublishBranchOne -> CommitDocumentChangesInternal publishing/published is going to be raised there, so are we raising it 2x for the same thing? scope.Events.Dispatch(Published, this, new ContentPublishedEventArgs(publishedDocuments, false, evtMsgs), nameof(Published)); scope.Complete(); diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index ab663b5a24..f6705f6619 100755 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -302,6 +302,7 @@ + From fb070928f743301c01cf6ca7b744f725132c9c89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Thu, 7 Feb 2019 08:57:20 +0100 Subject: [PATCH 42/68] V8: umb-editor-navigation-anchor-dropdown first version --- .../components/content/edit.controller.js | 17 +++ .../content/umbtabbedcontent.directive.js | 113 +++++++++++++----- .../content/umbvariantcontent.directive.js | 15 ++- .../umbvariantcontenteditors.directive.js | 10 +- .../umbeditorcontentheader.directive.js | 16 ++- .../editor/umbeditornavigation.directive.js | 9 +- .../umbeditornavigationitem.directive.js | 45 ++++++- .../util/getDomElement.directive.js | 17 +++ .../umb-editor-navigation-item.less | 36 ++++-- .../src/views/components/content/edit.html | 3 +- .../content/umb-tabbed-content.html | 13 +- .../content/umb-variant-content-editors.html | 3 +- .../content/umb-variant-content.html | 1 + .../editor/umb-editor-content-header.html | 3 +- .../editor/umb-editor-navigation-item.html | 10 +- .../editor/umb-editor-navigation.html | 2 + 16 files changed, 256 insertions(+), 57 deletions(-) create mode 100644 src/Umbraco.Web.UI.Client/src/common/directives/util/getDomElement.directive.js diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/content/edit.controller.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/content/edit.controller.js index 16db974df9..c91683be83 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/content/edit.controller.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/content/edit.controller.js @@ -878,6 +878,23 @@ } }; + /** + * Call back when a content app changes + * @param {any} app + */ + $scope.appAnchorChanged = function (app, anchor) { + + if ($scope.app !== app) { + console.log("Change app") + // TODO: Not working..!!!!!!!! + $scope.appChanged(app); + } + + //send an event downwards + $scope.$broadcast("editors.apps.appAnchorChanged", { app: app, anchor: anchor }); + + }; + // methods for infinite editing $scope.close = function () { if ($scope.infiniteModel.close) { diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/content/umbtabbedcontent.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/content/umbtabbedcontent.directive.js index 5ebb40fac6..f288d8681d 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/content/umbtabbedcontent.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/content/umbtabbedcontent.directive.js @@ -4,38 +4,95 @@ /** This directive is used to render out the current variant tabs and properties and exposes an API for other directives to consume */ function tabbedContentDirective() { + function link($scope, $element, $attrs) { + + var appRootNode = $element[0]; + + // Directive for cached property groups. + var propertyGroupNodesDictionary = {}; + + var scrollableNode = appRootNode.closest(".umb-scrollable"); + scrollableNode.addEventListener("scroll", onScroll); + + function onScroll(event) { + + var viewFocusY = scrollableNode.scrollTop + scrollableNode.clientHeight * .5; + + for(var i in $scope.content.tabs) { + var group = $scope.content.tabs[i]; + var node = propertyGroupNodesDictionary[group.id]; + //console.log(node.offsetTop, node.offsetTop + node.clientHeight) + if (viewFocusY >= node.offsetTop && viewFocusY <= node.offsetTop + node.clientHeight) { + setActiveAnchor(group); + return; + } + } + + } + function setActiveAnchor(tab) { + var i = $scope.content.tabs.length; + while(i--) { + $scope.content.tabs[i].active = false; + } + tab.active = true; + } + function scrollTo(id) { + console.log("scrollTo", id); + + if (propertyGroupNodesDictionary[id]) { + let y = propertyGroupNodesDictionary[id].offsetTop - 20;// currently only relative to closest relatively positioned parent + + scrollableNode.scrollTo(0, y); + } + } + + $scope.registerPropertyGroup = function(element, appAnchor) { + propertyGroupNodesDictionary[appAnchor] = element; + } + + $scope.$on("editors.apps.appAnchorChanged", function($event, $args) { + if($args.app.alias === "umbContent") { + setActiveAnchor($args.anchor); + scrollTo($args.anchor.id); + } + }); + + + } + + function controller($scope, $element, $attrs) { + + + //expose the property/methods for other directives to use + this.content = $scope.content; + this.activeVariant = _.find(this.content.variants, variant => { + return variant.active; + }); + + $scope.activeVariant = this.activeVariant; + + $scope.defaultVariant = _.find(this.content.variants, variant => { + return variant.language.isDefault; + }); + + $scope.unlockInvariantValue = function(property) { + property.unlockInvariantValue = !property.unlockInvariantValue; + }; + + $scope.$watch("tabbedContentForm.$dirty", + function (newValue, oldValue) { + if (newValue === true) { + $scope.content.isDirty = true; + } + }); + } + var directive = { restrict: 'E', replace: true, templateUrl: 'views/components/content/umb-tabbed-content.html', - controller: function ($scope) { - - //expose the property/methods for other directives to use - this.content = $scope.content; - this.activeVariant = _.find(this.content.variants, variant => { - return variant.active; - }); - - $scope.activeVariant = this.activeVariant; - - $scope.defaultVariant = _.find(this.content.variants, variant => { - return variant.language.isDefault; - }); - - $scope.unlockInvariantValue = function(property) { - property.unlockInvariantValue = !property.unlockInvariantValue; - }; - - $scope.$watch("tabbedContentForm.$dirty", - function (newValue, oldValue) { - if (newValue === true) { - $scope.content.isDirty = true; - } - }); - }, - link: function(scope) { - - }, + controller: controller, + link: link, scope: { content: "=" } diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/content/umbvariantcontent.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/content/umbvariantcontent.directive.js index 8545854992..9eb4ddee15 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/content/umbvariantcontent.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/content/umbvariantcontent.directive.js @@ -16,7 +16,8 @@ onCloseSplitView: "&", onSelectVariant: "&", onOpenSplitView: "&", - onSelectApp: "&" + onSelectApp: "&", + onSelectAppAnchor: "&" }, controllerAs: 'vm', controller: umbVariantContentController @@ -35,6 +36,7 @@ vm.selectVariant = selectVariant; vm.openSplitView = openSplitView; vm.selectApp = selectApp; + vm.selectAppAnchor = selectAppAnchor; function onInit() { // disable the name field if the active content app is not "Content" @@ -89,6 +91,17 @@ } } + /** + * Used to proxy a callback + * @param {any} item + */ + function selectAppAnchor(item, anchor) { + // call the callback if any is registered + if(vm.onSelectAppAnchor) { + vm.onSelectAppAnchor({"app": item, "anchor": anchor}); + } + } + /** * Used to proxy a callback * @param {any} variant diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/content/umbvariantcontenteditors.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/content/umbvariantcontenteditors.directive.js index addbb3b11b..0995a13707 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/content/umbvariantcontenteditors.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/content/umbvariantcontenteditors.directive.js @@ -10,7 +10,8 @@ page: "<", content: "<", // TODO: Not sure if this should be = since we are changing the 'active' property of a variant culture: "<", - onSelectApp: "&?" + onSelectApp: "&?", + onSelectAppAnchor: "&?" }, controllerAs: 'vm', controller: umbVariantContentEditorsController @@ -32,6 +33,7 @@ vm.closeSplitView = closeSplitView; vm.selectVariant = selectVariant; vm.selectApp = selectApp; + vm.selectAppAnchor = selectAppAnchor; //Used to track how many content views there are (for split view there will be 2, it could support more in theory) vm.editors = []; @@ -323,6 +325,12 @@ vm.onSelectApp({"app": app}); } } + + function selectAppAnchor(app, anchor) { + if(vm.onSelectAppAnchor) { + vm.onSelectAppAnchor({"app": app, "anchor": anchor}); + } + } } diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/editor/umbeditorcontentheader.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/editor/umbeditorcontentheader.directive.js index 0f1aae940d..ad20c6bbae 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/editor/umbeditorcontentheader.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/editor/umbeditorcontentheader.directive.js @@ -19,15 +19,14 @@ function onInit() { setCurrentVariant(); - /* + angular.forEach(scope.content.apps, (app) => { if (app.alias === "umbContent") { - console.log("content app", app) - app.type = "dropdown"; - app.groups = scope.content.tabs; + console.log("app: ", app) + app.anchors = scope.content.tabs; } }); - */ + } function setCurrentVariant() { @@ -56,6 +55,12 @@ } } + scope.selectAnchorItem = function(item, anchor) { + if(scope.onSelectAnchorItem) { + scope.onSelectAnchorItem({"item": item, "anchor": anchor}); + } + } + scope.closeSplitView = function () { if (scope.onCloseSplitView) { scope.onCloseSplitView(); @@ -114,6 +119,7 @@ openVariants: "<", hideChangeVariant: " a { text-align: center; cursor: pointer; display: block; @@ -36,16 +36,16 @@ } } -.umb-sub-views-nav-item a:focus { +.umb-sub-views-nav-item > a:focus { outline: none; } -.umb-sub-views-nav-item a:hover, -.umb-sub-views-nav-item a:focus { +.umb-sub-views-nav-item > a:hover, +.umb-sub-views-nav-item > a:focus { text-decoration: none; } -.umb-sub-views-nav-item a.is-active { +.umb-sub-views-nav-item > a.is-active { color: @ui-light-active-type; @@ -55,7 +55,7 @@ } } -.show-validation .umb-sub-views-nav-item a.-has-error { +.show-validation .umb-sub-views-nav-item > a.-has-error { color: @red; } @@ -98,6 +98,28 @@ line-height: 1em; } + +.umb-sub-views-nav-item__anchor_dropdown {// inherits from .dropdown-menu + display: none; + &.show { + display: block; + } +} +.umb-sub-views-nav-item__anchor_dropdown li a { + border-left: 4px solid transparent; +} +.umb-sub-views-nav-item__anchor_dropdown li.is-active a { + border-left-color: @ui-selected-border; +} +.umb-sub-views-nav-item__anchor_dropdown li:hover.is-active a { + border-left-color: @ui-selected-border-hover; +} + + +// -------------------------------- +// item__more, appears when there is not enough room for the visible items. +// -------------------------------- + .umb-sub-views-nav-item-more__icon { margin-bottom: 10px; } diff --git a/src/Umbraco.Web.UI.Client/src/views/components/content/edit.html b/src/Umbraco.Web.UI.Client/src/views/components/content/edit.html index e97eabf17f..dda9334e05 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/content/edit.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/content/edit.html @@ -10,7 +10,8 @@ page="page" content="content" culture="culture" - on-select-app="appChanged(app)"> + on-select-app="appChanged(app)" + on-select-app-anchor="appAnchorChanged(app, anchor)"> diff --git a/src/Umbraco.Web.UI.Client/src/views/components/content/umb-tabbed-content.html b/src/Umbraco.Web.UI.Client/src/views/components/content/umb-tabbed-content.html index cdacea7cf1..be768db497 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/content/umb-tabbed-content.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/content/umb-tabbed-content.html @@ -1,16 +1,15 @@ 
    -
    +
    -
    +
    {{ group.label }}
    -  
    -
    - + diff --git a/src/Umbraco.Web.UI.Client/src/views/components/content/umb-variant-content-editors.html b/src/Umbraco.Web.UI.Client/src/views/components/content/umb-variant-content-editors.html index 9d879fac22..76bca6fce2 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/content/umb-variant-content-editors.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/content/umb-variant-content-editors.html @@ -13,7 +13,8 @@ on-open-split-view="vm.openSplitView(variant)" on-close-split-view="vm.closeSplitView($index)" on-select-variant="vm.selectVariant(variant, $index)" - on-select-app="vm.selectApp(app)"> + on-select-app="vm.selectApp(app)" + on-select-app-anchor="vm.selectAppAnchor(app, anchor)">
    diff --git a/src/Umbraco.Web.UI.Client/src/views/components/content/umb-variant-content.html b/src/Umbraco.Web.UI.Client/src/views/components/content/umb-variant-content.html index 84928a00bb..34c7792055 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/content/umb-variant-content.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/content/umb-variant-content.html @@ -13,6 +13,7 @@ name-disabled="vm.nameDisabled" content="vm.editor.content" on-select-navigation-item="vm.selectApp(item)" + on-select-anchor-item="vm.selectAppAnchor(item, anchor)" open-variants="vm.openVariants" hide-change-variant="vm.page.hideChangeVariant" show-back-button="vm.page.listViewPath !== null" diff --git a/src/Umbraco.Web.UI.Client/src/views/components/editor/umb-editor-content-header.html b/src/Umbraco.Web.UI.Client/src/views/components/editor/umb-editor-content-header.html index 8e308e89b2..98ecfd4d28 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/editor/umb-editor-content-header.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/editor/umb-editor-content-header.html @@ -64,7 +64,8 @@ + on-select="selectNavigationItem(item)" + on-anchor-select="selectAnchorItem(item, anchor)">
    diff --git a/src/Umbraco.Web.UI.Client/src/views/components/editor/umb-editor-navigation-item.html b/src/Umbraco.Web.UI.Client/src/views/components/editor/umb-editor-navigation-item.html index 329e96242b..848985239c 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/editor/umb-editor-navigation-item.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/editor/umb-editor-navigation-item.html @@ -1,7 +1,7 @@ @@ -9,3 +9,11 @@ {{ vm.item.name }}
    {{vm.item.badge.count}}
    + + diff --git a/src/Umbraco.Web.UI.Client/src/views/components/editor/umb-editor-navigation.html b/src/Umbraco.Web.UI.Client/src/views/components/editor/umb-editor-navigation.html index 31388a54f8..0c8f0be7a2 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/editor/umb-editor-navigation.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/editor/umb-editor-navigation.html @@ -6,6 +6,7 @@
    @@ -28,6 +29,7 @@ From fc6548d87bb740c60dd2d3fe1b7dc7cba9ad3507 Mon Sep 17 00:00:00 2001 From: Bjarke Berg Date: Thu, 7 Feb 2019 09:56:14 +0100 Subject: [PATCH 43/68] Fix issue where Id was not set when loading all entity paths --- src/Umbraco.Core/Models/Entities/TreeEntityPath.cs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/Umbraco.Core/Models/Entities/TreeEntityPath.cs b/src/Umbraco.Core/Models/Entities/TreeEntityPath.cs index 54142a7527..adbb0d9a39 100644 --- a/src/Umbraco.Core/Models/Entities/TreeEntityPath.cs +++ b/src/Umbraco.Core/Models/Entities/TreeEntityPath.cs @@ -14,5 +14,14 @@ /// Gets or sets the path of the entity. ///
    public string Path { get; set; } + + /// + /// Proxy of the Id + /// + public int NodeId + { + get => Id; + set => Id = value; + } } } From 8ed2dcb8bfaf5cffc515aaea174a8016b6a06e9b Mon Sep 17 00:00:00 2001 From: Stephan Date: Thu, 7 Feb 2019 09:59:16 +0100 Subject: [PATCH 44/68] Don't capture content caches! --- .../PublishedContentMoreTests.cs | 2 +- src/Umbraco.Web/PublishedContentQuery.cs | 52 ++++++++----------- .../Routing/ContentFinderByConfigured404.cs | 3 +- src/Umbraco.Web/Runtime/WebRuntimeComposer.cs | 2 +- src/Umbraco.Web/UmbracoHelper.cs | 2 +- 5 files changed, 25 insertions(+), 36 deletions(-) diff --git a/src/Umbraco.Tests/PublishedContent/PublishedContentMoreTests.cs b/src/Umbraco.Tests/PublishedContent/PublishedContentMoreTests.cs index 5f3a51f4f6..0dcc4bea99 100644 --- a/src/Umbraco.Tests/PublishedContent/PublishedContentMoreTests.cs +++ b/src/Umbraco.Tests/PublishedContent/PublishedContentMoreTests.cs @@ -195,7 +195,7 @@ namespace Umbraco.Tests.PublishedContent [Test] public void PublishedContentQueryTypedContentList() { - var query = new PublishedContentQuery(UmbracoContext.Current.ContentCache, UmbracoContext.Current.MediaCache, UmbracoContext.Current.VariationContextAccessor); + var query = new PublishedContentQuery(UmbracoContext.Current.PublishedSnapshot, UmbracoContext.Current.VariationContextAccessor); var result = query.Content(new[] { 1, 2, 4 }).ToArray(); Assert.AreEqual(2, result.Length); Assert.AreEqual(1, result[0].Id); diff --git a/src/Umbraco.Web/PublishedContentQuery.cs b/src/Umbraco.Web/PublishedContentQuery.cs index 2c4d08502e..61180580cb 100644 --- a/src/Umbraco.Web/PublishedContentQuery.cs +++ b/src/Umbraco.Web/PublishedContentQuery.cs @@ -2,41 +2,31 @@ using System.Collections; using System.Collections.Generic; using System.Linq; -using System.Reflection; -using System.Text.RegularExpressions; using System.Xml.XPath; using Examine; using Examine.Search; using Umbraco.Core; using Umbraco.Core.Models.PublishedContent; -using Umbraco.Core.Services; using Umbraco.Core.Xml; using Umbraco.Examine; using Umbraco.Web.PublishedCache; namespace Umbraco.Web { - using Examine = global::Examine; - /// /// A class used to query for published content, media items /// public class PublishedContentQuery : IPublishedContentQuery { - private readonly IPublishedContentCache _contentCache; - private readonly IPublishedMediaCache _mediaCache; + private readonly IPublishedSnapshot _publishedSnapshot; private readonly IVariationContextAccessor _variationContextAccessor; /// - /// Constructor used to return results from the caches + /// Initializes a new instance of the class. /// - /// - /// - /// - public PublishedContentQuery(IPublishedContentCache contentCache, IPublishedMediaCache mediaCache, IVariationContextAccessor variationContextAccessor) + public PublishedContentQuery(IPublishedSnapshot publishedSnapshot, IVariationContextAccessor variationContextAccessor) { - _contentCache = contentCache ?? throw new ArgumentNullException(nameof(contentCache)); - _mediaCache = mediaCache ?? throw new ArgumentNullException(nameof(mediaCache)); + _publishedSnapshot = publishedSnapshot ?? throw new ArgumentNullException(nameof(publishedSnapshot)); _variationContextAccessor = variationContextAccessor ?? throw new ArgumentNullException(nameof(variationContextAccessor)); } @@ -44,48 +34,48 @@ namespace Umbraco.Web public IPublishedContent Content(int id) { - return ItemById(id, _contentCache); + return ItemById(id, _publishedSnapshot.Content); } public IPublishedContent Content(Guid id) { - return ItemById(id, _contentCache); + return ItemById(id, _publishedSnapshot.Content); } public IPublishedContent Content(Udi id) { if (!(id is GuidUdi udi)) return null; - return ItemById(udi.Guid, _contentCache); + return ItemById(udi.Guid, _publishedSnapshot.Content); } public IPublishedContent ContentSingleAtXPath(string xpath, params XPathVariable[] vars) { - return ItemByXPath(xpath, vars, _contentCache); + return ItemByXPath(xpath, vars, _publishedSnapshot.Content); } public IEnumerable Content(IEnumerable ids) { - return ItemsByIds(_contentCache, ids); + return ItemsByIds(_publishedSnapshot.Content, ids); } public IEnumerable Content(IEnumerable ids) { - return ItemsByIds(_contentCache, ids); + return ItemsByIds(_publishedSnapshot.Content, ids); } public IEnumerable ContentAtXPath(string xpath, params XPathVariable[] vars) { - return ItemsByXPath(xpath, vars, _contentCache); + return ItemsByXPath(xpath, vars, _publishedSnapshot.Content); } public IEnumerable ContentAtXPath(XPathExpression xpath, params XPathVariable[] vars) { - return ItemsByXPath(xpath, vars, _contentCache); + return ItemsByXPath(xpath, vars, _publishedSnapshot.Content); } public IEnumerable ContentAtRoot() { - return ItemsAtRoot(_contentCache); + return ItemsAtRoot(_publishedSnapshot.Content); } #endregion @@ -94,33 +84,33 @@ namespace Umbraco.Web public IPublishedContent Media(int id) { - return ItemById(id, _mediaCache); + return ItemById(id, _publishedSnapshot.Media); } public IPublishedContent Media(Guid id) { - return ItemById(id, _mediaCache); + return ItemById(id, _publishedSnapshot.Media); } public IPublishedContent Media(Udi id) { if (!(id is GuidUdi udi)) return null; - return ItemById(udi.Guid, _mediaCache); + return ItemById(udi.Guid, _publishedSnapshot.Media); } public IEnumerable Media(IEnumerable ids) { - return ItemsByIds(_mediaCache, ids); + return ItemsByIds(_publishedSnapshot.Media, ids); } public IEnumerable Media(IEnumerable ids) { - return ItemsByIds(_mediaCache, ids); + return ItemsByIds(_publishedSnapshot.Media, ids); } public IEnumerable MediaAtRoot() { - return ItemsAtRoot(_mediaCache); + return ItemsAtRoot(_publishedSnapshot.Media); } @@ -224,7 +214,7 @@ namespace Umbraco.Web totalRecords = results.TotalItemCount; - return new CultureContextualSearchResults(results.ToPublishedSearchResults(_contentCache), _variationContextAccessor, culture); + return new CultureContextualSearchResults(results.ToPublishedSearchResults(_publishedSnapshot.Content), _variationContextAccessor, culture); } /// @@ -241,7 +231,7 @@ namespace Umbraco.Web : query.Execute(maxResults: skip + take); totalRecords = results.TotalItemCount; - return results.ToPublishedSearchResults(_contentCache); + return results.ToPublishedSearchResults(_publishedSnapshot.Content); } /// diff --git a/src/Umbraco.Web/Routing/ContentFinderByConfigured404.cs b/src/Umbraco.Web/Routing/ContentFinderByConfigured404.cs index 382ee6fe12..e3cad25c6f 100644 --- a/src/Umbraco.Web/Routing/ContentFinderByConfigured404.cs +++ b/src/Umbraco.Web/Routing/ContentFinderByConfigured404.cs @@ -13,7 +13,6 @@ namespace Umbraco.Web.Routing /// public class ContentFinderByConfigured404 : IContentLastChanceFinder { - private readonly ILogger _logger; private readonly IEntityService _entityService; private readonly IContentSection _contentConfigSection; @@ -63,7 +62,7 @@ namespace Umbraco.Web.Routing var error404 = NotFoundHandlerHelper.GetCurrentNotFoundPageId( _contentConfigSection.Error404Collection.ToArray(), _entityService, - new PublishedContentQuery(frequest.UmbracoContext.ContentCache, frequest.UmbracoContext.MediaCache, frequest.UmbracoContext.VariationContextAccessor), + new PublishedContentQuery(frequest.UmbracoContext.PublishedSnapshot, frequest.UmbracoContext.VariationContextAccessor), errorCulture); IPublishedContent content = null; diff --git a/src/Umbraco.Web/Runtime/WebRuntimeComposer.cs b/src/Umbraco.Web/Runtime/WebRuntimeComposer.cs index 0f17c19bdb..3afe6aa397 100644 --- a/src/Umbraco.Web/Runtime/WebRuntimeComposer.cs +++ b/src/Umbraco.Web/Runtime/WebRuntimeComposer.cs @@ -91,7 +91,7 @@ namespace Umbraco.Web.Runtime composition.Register(factory => { var umbCtx = factory.GetInstance(); - return new PublishedContentQuery(umbCtx.UmbracoContext.ContentCache, umbCtx.UmbracoContext.MediaCache, factory.GetInstance()); + return new PublishedContentQuery(umbCtx.UmbracoContext.PublishedSnapshot, factory.GetInstance()); }, Lifetime.Request); composition.Register(Lifetime.Request); diff --git a/src/Umbraco.Web/UmbracoHelper.cs b/src/Umbraco.Web/UmbracoHelper.cs index 962d181d7b..d2da4d1646 100644 --- a/src/Umbraco.Web/UmbracoHelper.cs +++ b/src/Umbraco.Web/UmbracoHelper.cs @@ -73,7 +73,7 @@ namespace Umbraco.Web #endregion // ensures that we can return the specified value - T Ensure(T o) where T : class => o ?? throw new InvalidOperationException(""); // fixme + T Ensure(T o) where T : class => o ?? throw new InvalidOperationException("This UmbracoHelper instance has not been initialized."); private IUmbracoComponentRenderer ComponentRenderer => Ensure(_componentRenderer); private ICultureDictionaryFactory CultureDictionaryFactory => Ensure(_cultureDictionaryFactory); From 2092156db34d3d6a8393934f2c1295502984bb6c Mon Sep 17 00:00:00 2001 From: Stephan Date: Thu, 7 Feb 2019 12:27:19 +0100 Subject: [PATCH 45/68] Cleanup --- ...ontentTypeBaseServiceProviderExtensions.cs | 16 ---------- src/Umbraco.Core/Models/ContentBase.cs | 22 ++------------ src/Umbraco.Core/Models/IMedia.cs | 8 ++--- src/Umbraco.Core/Models/Media.cs | 1 - src/Umbraco.Core/Models/MediaExtensions.cs | 5 ++-- src/Umbraco.Core/Models/PropertyCollection.cs | 2 +- .../IContentTypeBaseServiceProvider.cs | 5 ++++ .../ContentTypeBaseServiceProvider.cs | 7 +++++ src/Umbraco.Core/Umbraco.Core.csproj | 1 - .../Testing/ContentBaseExtensions.cs | 29 ++++--------------- .../Filters/MemberSaveValidationAttribute.cs | 12 +++----- .../Editors/Filters/MemberValidationHelper.cs | 4 +-- 12 files changed, 32 insertions(+), 80 deletions(-) delete mode 100644 src/Umbraco.Core/ContentTypeBaseServiceProviderExtensions.cs diff --git a/src/Umbraco.Core/ContentTypeBaseServiceProviderExtensions.cs b/src/Umbraco.Core/ContentTypeBaseServiceProviderExtensions.cs deleted file mode 100644 index f962d9aefb..0000000000 --- a/src/Umbraco.Core/ContentTypeBaseServiceProviderExtensions.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System; -using Umbraco.Core.Models; -using Umbraco.Core.Services; - -namespace Umbraco.Core -{ - internal static class ContentTypeBaseServiceProviderExtensions - { - //TODO: Maybe this should just be on the IContentTypeBaseServiceProvider interface? - public static IContentTypeComposition GetContentTypeOf(this IContentTypeBaseServiceProvider serviceProvider, IContentBase contentBase) - { - if (contentBase == null) throw new ArgumentNullException(nameof(contentBase)); - return serviceProvider.For(contentBase)?.Get(contentBase.ContentTypeId); - } - } -} diff --git a/src/Umbraco.Core/Models/ContentBase.cs b/src/Umbraco.Core/Models/ContentBase.cs index e6e893d905..fbb68194b7 100644 --- a/src/Umbraco.Core/Models/ContentBase.cs +++ b/src/Umbraco.Core/Models/ContentBase.cs @@ -307,26 +307,10 @@ namespace Umbraco.Core.Models /// public void SetValue(string propertyTypeAlias, object value, string culture = null, string segment = null) { - if (Properties.TryGetValue(propertyTypeAlias, out var property)) - { - property.SetValue(value, culture, segment); - } - else - { - //fixme: Can this ever happen? According to the ctor in ContentBase (EnsurePropertyTypes), all properties will be created based on the content type's property types - // so how can a property not be resolved by the alias on the content.Properties but it can on the content type? - // This maybe can happen if a developer has removed a property with the api and is trying to then set the value of that property again... - // BUT, as it turns out the content.Properties.Remove(...) method is NEVER used, because why and how could it? you never remove a property from - // a content item directly. + if (!Properties.TryGetValue(propertyTypeAlias, out var property)) + throw new InvalidOperationException($"No PropertyType exists with the supplied alias \"{propertyTypeAlias}\"."); - var propertyType = AllPropertyTypes.FirstOrDefault(x => x.Alias.InvariantEquals(propertyTypeAlias)); - if (propertyType == null) - throw new InvalidOperationException($"No PropertyType exists with the supplied alias \"{propertyTypeAlias}\"."); - - property = propertyType.CreateProperty(); - property.SetValue(value, culture, segment); - Properties.Add(property); - } + property.SetValue(value, culture, segment); //bump the culture to be flagged for updating this.TouchCulture(culture); diff --git a/src/Umbraco.Core/Models/IMedia.cs b/src/Umbraco.Core/Models/IMedia.cs index 3ad4f87aa8..75e94d66e7 100644 --- a/src/Umbraco.Core/Models/IMedia.cs +++ b/src/Umbraco.Core/Models/IMedia.cs @@ -1,9 +1,5 @@ -using Umbraco.Core.Persistence.Mappers; - -namespace Umbraco.Core.Models +namespace Umbraco.Core.Models { public interface IMedia : IContentBase - { - - } + { } } diff --git a/src/Umbraco.Core/Models/Media.cs b/src/Umbraco.Core/Models/Media.cs index d281f8f267..002611c09c 100644 --- a/src/Umbraco.Core/Models/Media.cs +++ b/src/Umbraco.Core/Models/Media.cs @@ -80,6 +80,5 @@ namespace Umbraco.Core.Models Properties.CollectionChanged -= PropertiesChanged; // be sure not to double add Properties.CollectionChanged += PropertiesChanged; } - } } diff --git a/src/Umbraco.Core/Models/MediaExtensions.cs b/src/Umbraco.Core/Models/MediaExtensions.cs index ff5e47394f..1166698adb 100644 --- a/src/Umbraco.Core/Models/MediaExtensions.cs +++ b/src/Umbraco.Core/Models/MediaExtensions.cs @@ -2,7 +2,6 @@ using System.Linq; using Newtonsoft.Json; using Newtonsoft.Json.Linq; -using Umbraco.Core.Composing; using Umbraco.Core.Configuration.UmbracoSettings; using Umbraco.Core.Logging; using Umbraco.Core.PropertyEditors.ValueConverters; @@ -20,8 +19,8 @@ namespace Umbraco.Core.Models return string.Empty; // TODO: would need to be adjusted to variations, when media become variants - var jsonString = property?.GetValue() as string; - if (jsonString == null) return string.Empty; + if (!(property.GetValue() is string jsonString)) + return string.Empty; if (property.PropertyType.PropertyEditorAlias == Constants.PropertyEditors.Aliases.UploadField) return jsonString; diff --git a/src/Umbraco.Core/Models/PropertyCollection.cs b/src/Umbraco.Core/Models/PropertyCollection.cs index ed641080ea..977600a2f7 100644 --- a/src/Umbraco.Core/Models/PropertyCollection.cs +++ b/src/Umbraco.Core/Models/PropertyCollection.cs @@ -93,7 +93,7 @@ namespace Umbraco.Core.Models } /// - /// Adds or update a property. + /// Adds or updates a property. /// internal new void Add(Property property) { diff --git a/src/Umbraco.Core/Services/IContentTypeBaseServiceProvider.cs b/src/Umbraco.Core/Services/IContentTypeBaseServiceProvider.cs index 70327e7baf..d0146ce043 100644 --- a/src/Umbraco.Core/Services/IContentTypeBaseServiceProvider.cs +++ b/src/Umbraco.Core/Services/IContentTypeBaseServiceProvider.cs @@ -18,5 +18,10 @@ namespace Umbraco.Core.Services /// to retrieve the content / media / whatever type as . /// IContentTypeBaseService For(IContentBase contentBase); + + /// + /// Gets the content type of an object. + /// + IContentTypeComposition GetContentTypeOf(IContentBase contentBase); } } diff --git a/src/Umbraco.Core/Services/Implement/ContentTypeBaseServiceProvider.cs b/src/Umbraco.Core/Services/Implement/ContentTypeBaseServiceProvider.cs index e20ff28ab3..5a56dfe3bc 100644 --- a/src/Umbraco.Core/Services/Implement/ContentTypeBaseServiceProvider.cs +++ b/src/Umbraco.Core/Services/Implement/ContentTypeBaseServiceProvider.cs @@ -31,5 +31,12 @@ namespace Umbraco.Core.Services.Implement throw new ArgumentException($"Invalid contentBase type: {contentBase.GetType().FullName}" , nameof(contentBase)); } } + + // note: this should be a default interface method with C# 8 + public IContentTypeComposition GetContentTypeOf(IContentBase contentBase) + { + if (contentBase == null) throw new ArgumentNullException(nameof(contentBase)); + return For(contentBase)?.Get(contentBase.ContentTypeId); + } } } diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index b29977697a..f773d5d152 100755 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -291,7 +291,6 @@ - diff --git a/src/Umbraco.Tests/Testing/ContentBaseExtensions.cs b/src/Umbraco.Tests/Testing/ContentBaseExtensions.cs index 6d3d2c7683..d33818a31b 100644 --- a/src/Umbraco.Tests/Testing/ContentBaseExtensions.cs +++ b/src/Umbraco.Tests/Testing/ContentBaseExtensions.cs @@ -9,7 +9,7 @@ namespace Umbraco.Tests.Testing { public static class ContentBaseExtensions { - + /// /// Set property values by alias with an anonymous object. /// @@ -22,29 +22,12 @@ namespace Umbraco.Tests.Testing var propertyInfos = value.GetType().GetProperties(); foreach (var propertyInfo in propertyInfos) { - if (content.Properties.TryGetValue(propertyInfo.Name, out var property)) - { - property.SetValue(propertyInfo.GetValue(value, null), culture, segment); - //Update item with newly added value - content.Properties.Add(property); - } - else - { + if (!content.Properties.TryGetValue(propertyInfo.Name, out var property)) + throw new Exception($"The property alias {propertyInfo.Name} is not valid, because no PropertyType with this alias exists"); - //fixme: Can this ever happen? According to the ctor in ContentBase (EnsurePropertyTypes), all properties will be created based on the content type's property types - // so how can a property not be resolved by the alias on the content.Properties but it can on the content type? - // This maybe can happen if a developer has removed a property with the api and is trying to then set the value of that property again... - // BUT, as it turns out the content.Properties.Remove(...) method is NEVER used, because why and how could it? you never remove a property from - // a content item directly. - - var propertyType = ((ContentBase)content).AllPropertyTypes.FirstOrDefault(x => x.Alias == propertyInfo.Name); - if (propertyType == null) - throw new Exception($"The property alias {propertyInfo.Name} is not valid, because no PropertyType with this alias exists"); - //Create new Property to add to collection - property = propertyType.CreateProperty(); - property.SetValue(propertyInfo.GetValue(value, null), culture, segment); - content.Properties.Add(property); - } + property.SetValue(propertyInfo.GetValue(value, null), culture, segment); + //Update item with newly added value + content.Properties.Add(property); } } } diff --git a/src/Umbraco.Web/Editors/Filters/MemberSaveValidationAttribute.cs b/src/Umbraco.Web/Editors/Filters/MemberSaveValidationAttribute.cs index 80d5f684fe..c99bc64e23 100644 --- a/src/Umbraco.Web/Editors/Filters/MemberSaveValidationAttribute.cs +++ b/src/Umbraco.Web/Editors/Filters/MemberSaveValidationAttribute.cs @@ -1,10 +1,6 @@ -using System.Linq; -using System.Net; -using System.Net.Http; -using System.Web.Http.Controllers; +using System.Web.Http.Controllers; using System.Web.Http.Filters; using Umbraco.Core.Logging; -using Umbraco.Core.Models; using Umbraco.Core.Services; using Umbraco.Web.Composing; using Umbraco.Web.Models.ContentEditing; @@ -20,9 +16,9 @@ namespace Umbraco.Web.Editors.Filters private readonly IUmbracoContextAccessor _umbracoContextAccessor; private readonly IMemberTypeService _memberTypeService; - public MemberSaveValidationAttribute() : this(Current.Logger, Current.UmbracoContextAccessor, Current.Services.MemberTypeService) - { - } + public MemberSaveValidationAttribute() + : this(Current.Logger, Current.UmbracoContextAccessor, Current.Services.MemberTypeService) + { } public MemberSaveValidationAttribute(ILogger logger, IUmbracoContextAccessor umbracoContextAccessor, IMemberTypeService memberTypeService) { diff --git a/src/Umbraco.Web/Editors/Filters/MemberValidationHelper.cs b/src/Umbraco.Web/Editors/Filters/MemberValidationHelper.cs index 8f98765c34..ac72019cdf 100644 --- a/src/Umbraco.Web/Editors/Filters/MemberValidationHelper.cs +++ b/src/Umbraco.Web/Editors/Filters/MemberValidationHelper.cs @@ -7,7 +7,6 @@ using System.Web.Http.Controllers; using System.Web.Http.ModelBinding; using System.Web.Security; using Umbraco.Core; -using Umbraco.Core.Composing; using Umbraco.Core.Logging; using Umbraco.Core.Models; using Umbraco.Core.Services; @@ -23,7 +22,8 @@ namespace Umbraco.Web.Editors.Filters { private readonly IMemberTypeService _memberTypeService; - public MemberValidationHelper(ILogger logger, IUmbracoContextAccessor umbracoContextAccessor, IMemberTypeService memberTypeService) : base(logger, umbracoContextAccessor) + public MemberValidationHelper(ILogger logger, IUmbracoContextAccessor umbracoContextAccessor, IMemberTypeService memberTypeService) + : base(logger, umbracoContextAccessor) { _memberTypeService = memberTypeService; } From 990e82d183897b6bc36735133305e58d0cd167d1 Mon Sep 17 00:00:00 2001 From: Stephan Date: Thu, 7 Feb 2019 12:36:53 +0100 Subject: [PATCH 46/68] Upgrade ModelsBuilder, cleanup dashboard --- .../ModelsBuilder/modelsbuilder.controller.js | 35 +++++++++------ .../ModelsBuilder/modelsbuilder.htm | 41 ----------------- .../ModelsBuilder/modelsbuilder.html | 44 +++++++++++++++++++ .../ModelsBuilder/package.manifest | 19 ++++++-- src/Umbraco.Web.UI/Umbraco.Web.UI.csproj | 2 +- .../Dashboards/ModelsBuilderDashboard.cs | 20 --------- src/Umbraco.Web/Umbraco.Web.csproj | 1 - 7 files changed, 81 insertions(+), 81 deletions(-) delete mode 100644 src/Umbraco.Web.UI/App_Plugins/ModelsBuilder/modelsbuilder.htm create mode 100644 src/Umbraco.Web.UI/App_Plugins/ModelsBuilder/modelsbuilder.html delete mode 100644 src/Umbraco.Web/Dashboards/ModelsBuilderDashboard.cs diff --git a/src/Umbraco.Web.UI/App_Plugins/ModelsBuilder/modelsbuilder.controller.js b/src/Umbraco.Web.UI/App_Plugins/ModelsBuilder/modelsbuilder.controller.js index 942b79eabd..b0e0c303cf 100644 --- a/src/Umbraco.Web.UI/App_Plugins/ModelsBuilder/modelsbuilder.controller.js +++ b/src/Umbraco.Web.UI/App_Plugins/ModelsBuilder/modelsbuilder.controller.js @@ -1,28 +1,35 @@ -function modelsBuilderController($scope, umbRequestHelper, $log, $http, modelsBuilderResource) { +function modelsBuilderController($scope, $http, umbRequestHelper, modelsBuilderResource) { - $scope.generate = function() { - $scope.generating = true; + var vm = this; + + vm.reload = reload; + vm.generate = generate; + vm.dashboard = null; + + function generate() { + vm.generating = true; umbRequestHelper.resourcePromise( $http.post(umbRequestHelper.getApiUrl("modelsBuilderBaseUrl", "BuildModels")), 'Failed to generate.') .then(function (result) { - $scope.generating = false; - $scope.dashboard = result; + vm.generating = false; + vm.dashboard = result; }); - }; + } - $scope.reload = function () { - $scope.ready = false; + function reload() { + vm.loading = true; modelsBuilderResource.getDashboard().then(function (result) { - $scope.dashboard = result; - $scope.ready = true; + vm.dashboard = result; + vm.loading = false; }); - }; + } function init() { - modelsBuilderResource.getDashboard().then(function(result) { - $scope.dashboard = result; - $scope.ready = true; + vm.loading = true; + modelsBuilderResource.getDashboard().then(function (result) { + vm.dashboard = result; + vm.loading = false; }); } diff --git a/src/Umbraco.Web.UI/App_Plugins/ModelsBuilder/modelsbuilder.htm b/src/Umbraco.Web.UI/App_Plugins/ModelsBuilder/modelsbuilder.htm deleted file mode 100644 index eeca93bf3a..0000000000 --- a/src/Umbraco.Web.UI/App_Plugins/ModelsBuilder/modelsbuilder.htm +++ /dev/null @@ -1,41 +0,0 @@ -
    - -
    - -
    - -

    Models Builder

    - -
    - Loading... -
    - -
    -
    - -
    -

    Models are out-of-date. -

    -
    - -
    -
    -

    Generating models will restart the application.

    -
    -
    - -
    -
    -
    -
    -
    - -
    - Last generation failed with the following error: -
    {{dashboard.lastError}}
    -
    -
    - -
    diff --git a/src/Umbraco.Web.UI/App_Plugins/ModelsBuilder/modelsbuilder.html b/src/Umbraco.Web.UI/App_Plugins/ModelsBuilder/modelsbuilder.html new file mode 100644 index 0000000000..0c10c33e39 --- /dev/null +++ b/src/Umbraco.Web.UI/App_Plugins/ModelsBuilder/modelsbuilder.html @@ -0,0 +1,44 @@ +
    + + + + +
    + +
    + +

    Models Builder

    + + + +
    +
    + +
    +

    Models are out-of-date.

    +
    + +
    +
    +

    Generating models will restart the application.

    +
    +
    + +
    +
    +
    +
    +
    + +
    + Last generation failed with the following error: +
    {{vm.dashboard.lastError}}
    +
    +
    + +
    +
    + +
    diff --git a/src/Umbraco.Web.UI/App_Plugins/ModelsBuilder/package.manifest b/src/Umbraco.Web.UI/App_Plugins/ModelsBuilder/package.manifest index d83523517a..5e64177046 100644 --- a/src/Umbraco.Web.UI/App_Plugins/ModelsBuilder/package.manifest +++ b/src/Umbraco.Web.UI/App_Plugins/ModelsBuilder/package.manifest @@ -1,7 +1,18 @@ { - //array of files we want to inject into the application on app_start - javascript: [ - '~/App_Plugins/ModelsBuilder/modelsbuilder.controller.js', - '~/App_Plugins/ModelsBuilder/modelsbuilder.resource.js' + // array of files we want to inject into the application + "javascript": [ + "~/App_Plugins/ModelsBuilder/modelsbuilder.controller.js", + "~/App_Plugins/ModelsBuilder/modelsbuilder.resource.js" + ], + + // models builder dashboard + "dashboards": [ + { + "alias": "settingsModelsBuilder", + "name": "Models Builder", + "view": "/App_Plugins/ModelsBuilder/modelsbuilder.html", + "sections": [ "settings" ], + "weight": 40 + } ] } \ No newline at end of file diff --git a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj index 7c3293183d..245ae7ca94 100644 --- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj +++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj @@ -105,7 +105,7 @@ - 8.0.0-alpha.36 + 8.0.0-alpha.37 diff --git a/src/Umbraco.Web/Dashboards/ModelsBuilderDashboard.cs b/src/Umbraco.Web/Dashboards/ModelsBuilderDashboard.cs deleted file mode 100644 index 44bc00cb6f..0000000000 --- a/src/Umbraco.Web/Dashboards/ModelsBuilderDashboard.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System; -using Umbraco.Core.Composing; -using Umbraco.Core.Dashboards; - -namespace Umbraco.Web.Dashboards -{ - [Weight(40)] - public class ModelsBuilderDashboard : IDashboard - { - public string Alias => "settingsModelsBuilder"; - - public string[] Sections => new [] { "settings" }; - - public string View => "/App_Plugins/ModelsBuilder/modelsbuilder.htm"; - - public IAccessRule[] AccessRules => Array.Empty(); - } - - -} diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index f9fa29f7db..1cb2e9a53e 100755 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -130,7 +130,6 @@ - From 29334ed2d56f6ad4099b3f103627f74d9c9536c3 Mon Sep 17 00:00:00 2001 From: Stephan Date: Thu, 7 Feb 2019 12:57:10 +0100 Subject: [PATCH 47/68] Fix ModelsBuilder changes --- src/Umbraco.Web.UI/Umbraco.Web.UI.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj index 245ae7ca94..f12ccfcf99 100644 --- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj +++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj @@ -141,7 +141,7 @@ Settings.settings - + From 42803ff006d45167ac4e259d53691dd00f4958d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Thu, 7 Feb 2019 13:26:23 +0100 Subject: [PATCH 48/68] V8: umb-editor-navigation anchor-dropdown refined, remembers last active anchor, --- .../components/content/edit.controller.js | 10 +++-- .../content/umbtabbedcontent.directive.js | 39 ++++++++++++++++--- .../content/umbvariantcontent.directive.js | 14 ++++--- .../umbvariantcontenteditors.directive.js | 11 ++++-- .../editor/umbeditornavigation.directive.js | 3 ++ .../umbeditornavigationitem.directive.js | 2 +- .../umb-editor-navigation-item.less | 15 +++++-- .../editor/umb-editor-navigation-item.html | 2 +- 8 files changed, 74 insertions(+), 22 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/content/edit.controller.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/content/edit.controller.js index c91683be83..6b7b129809 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/content/edit.controller.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/content/edit.controller.js @@ -871,6 +871,8 @@ $scope.app = app; + $scope.$broadcast("editors.apps.appChanged", { app: app }); + if (infiniteMode) { createInfiniteModeButtons($scope.content); } else { @@ -883,13 +885,15 @@ * @param {any} app */ $scope.appAnchorChanged = function (app, anchor) { - + /* + // This is how it should be done — but because of the current architecture, i had to give the responsibilty to 'activate' the content-app to the menu, cause thats the only place you currently can change the active content-app. + // proposal. Make sure that the content-app-menu dosnt do anything. Just make it callback when menu-item are clicked, then make the controller of the view handle what to be done. Then the controller should broadcast a local event, notifying that the current content-app has been changed. + // read more on this issue: https://github.com/umbraco/Umbraco-CMS/issues/4467 if ($scope.app !== app) { - console.log("Change app") // TODO: Not working..!!!!!!!! $scope.appChanged(app); } - + */ //send an event downwards $scope.$broadcast("editors.apps.appAnchorChanged", { app: app, anchor: anchor }); diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/content/umbtabbedcontent.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/content/umbtabbedcontent.directive.js index f288d8681d..c2d2ce5fa9 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/content/umbtabbedcontent.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/content/umbtabbedcontent.directive.js @@ -2,7 +2,7 @@ 'use strict'; /** This directive is used to render out the current variant tabs and properties and exposes an API for other directives to consume */ - function tabbedContentDirective() { + function tabbedContentDirective($timeout) { function link($scope, $element, $attrs) { @@ -36,12 +36,30 @@ } tab.active = true; } + function getActiveAnchor() { + var i = $scope.content.tabs.length; + while(i--) { + if ($scope.content.tabs[i].active === true) + return $scope.content.tabs[i]; + } + return false; + } + function getScrollPositionFor(id) { + if (propertyGroupNodesDictionary[id]) { + return propertyGroupNodesDictionary[id].offsetTop - 20;// currently only relative to closest relatively positioned parent + } + return null; + } function scrollTo(id) { console.log("scrollTo", id); - - if (propertyGroupNodesDictionary[id]) { - let y = propertyGroupNodesDictionary[id].offsetTop - 20;// currently only relative to closest relatively positioned parent - + var y = getScrollPositionFor(id); + if (getScrollPositionFor !== null) { + scrollableNode.scrollTo(0, y); + } + } + function jumpTo(id) { + var y = getScrollPositionFor(id); + if (getScrollPositionFor !== null) { scrollableNode.scrollTo(0, y); } } @@ -50,6 +68,14 @@ propertyGroupNodesDictionary[appAnchor] = element; } + $scope.$on("editors.apps.appChanged", function($event, $args) { + // if app changed to this app, then we want to scroll to the current anchor + if($args.app.alias === "umbContent") { + var activeAnchor = getActiveAnchor(); + $timeout(jumpTo.bind(null, [activeAnchor.id])); + } + }); + $scope.$on("editors.apps.appAnchorChanged", function($event, $args) { if($args.app.alias === "umbContent") { setActiveAnchor($args.anchor); @@ -84,7 +110,8 @@ if (newValue === true) { $scope.content.isDirty = true; } - }); + } + ); } var directive = { diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/content/umbvariantcontent.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/content/umbvariantcontent.directive.js index 9eb4ddee15..5556308e06 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/content/umbvariantcontent.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/content/umbvariantcontent.directive.js @@ -80,16 +80,20 @@ * @param {any} item */ function selectApp(item) { - // disable the name field if the active content app is not "Content" or "Info" - vm.nameDisabled = false; - if(item && item.alias !== "umbContent" && item.alias !== "umbInfo") { - vm.nameDisabled = true; - } // call the callback if any is registered if(vm.onSelectApp) { vm.onSelectApp({"app": item}); } } + + $scope.$on("editors.apps.appChanged", function($event, $args) { + var app = $args.app; + // disable the name field if the active content app is not "Content" or "Info" + vm.nameDisabled = false; + if(app && app.alias !== "umbContent" && app.alias !== "umbInfo") { + vm.nameDisabled = true; + } + }); /** * Used to proxy a callback diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/content/umbvariantcontenteditors.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/content/umbvariantcontenteditors.directive.js index 0995a13707..bd21cca541 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/content/umbvariantcontenteditors.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/content/umbvariantcontenteditors.directive.js @@ -318,9 +318,6 @@ * @param {any} app This is the model of the selected app */ function selectApp(app) { - if(app && app.alias) { - activeAppAlias = app.alias; - } if(vm.onSelectApp) { vm.onSelectApp({"app": app}); } @@ -331,6 +328,14 @@ vm.onSelectAppAnchor({"app": app, "anchor": anchor}); } } + + + $scope.$on("editors.apps.appChanged", function($event, $args) { + var app = $args.app; + if(app && app.alias) { + activeAppAlias = app.alias; + } + }); } diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/editor/umbeditornavigation.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/editor/umbeditornavigation.directive.js index 34810f17dd..31976118fd 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/editor/umbeditornavigation.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/editor/umbeditornavigation.directive.js @@ -32,6 +32,9 @@ if(scope.onAnchorSelect) { scope.onAnchorSelect({"item": item, "anchor": anchor}); } + if (item.active !== true) { + scope.openNavigationItem(item); + } }; scope.toggleDropdown = function () { diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/editor/umbeditornavigationitem.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/editor/umbeditornavigationitem.directive.js index abb685807b..8ebee7d15c 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/editor/umbeditornavigationitem.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/editor/umbeditornavigationitem.directive.js @@ -48,7 +48,7 @@ Use this directive to render tab content. For an example see: {@link umbraco.dir vm.mouseOut = function() { clearTimeout(vm.mouseOutDelay); - vm.mouseOutDelay = setTimeout(hideDropdownBind, 1000); + vm.mouseOutDelay = setTimeout(hideDropdownBind, 500); } diff --git a/src/Umbraco.Web.UI.Client/src/less/components/umb-editor-navigation-item.less b/src/Umbraco.Web.UI.Client/src/less/components/umb-editor-navigation-item.less index faa4ff40b0..673de62b36 100644 --- a/src/Umbraco.Web.UI.Client/src/less/components/umb-editor-navigation-item.less +++ b/src/Umbraco.Web.UI.Client/src/less/components/umb-editor-navigation-item.less @@ -1,5 +1,6 @@ .umb-sub-views-nav-item { position: relative; + display: block; } .umb-sub-views-nav-item > a { text-align: center; @@ -36,6 +37,9 @@ } } +.umb-sub-views-nav-item > a:active { + .box-shadow(~"inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05)"); +} .umb-sub-views-nav-item > a:focus { outline: none; } @@ -101,6 +105,12 @@ .umb-sub-views-nav-item__anchor_dropdown {// inherits from .dropdown-menu display: none; + margin: 0; + + // center align horizontal + left: 50%; + transform: translateX(-50%); + &.show { display: block; } @@ -111,9 +121,8 @@ .umb-sub-views-nav-item__anchor_dropdown li.is-active a { border-left-color: @ui-selected-border; } -.umb-sub-views-nav-item__anchor_dropdown li:hover.is-active a { - border-left-color: @ui-selected-border-hover; -} + +.umb-sub-views-nav-item // -------------------------------- diff --git a/src/Umbraco.Web.UI.Client/src/views/components/editor/umb-editor-navigation-item.html b/src/Umbraco.Web.UI.Client/src/views/components/editor/umb-editor-navigation-item.html index 848985239c..90408e00cc 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/editor/umb-editor-navigation-item.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/editor/umb-editor-navigation-item.html @@ -11,7 +11,7 @@
    public class DateConfigurationEditor : ConfigurationEditor { + public override IDictionary DefaultConfiguration => new Dictionary + { + ["pickTime"] = false, + }; + public override IDictionary ToValueEditor(object configuration) { var d = base.ToValueEditor(configuration); diff --git a/src/Umbraco.Web/PropertyEditors/DateTimeConfigurationEditor.cs b/src/Umbraco.Web/PropertyEditors/DateTimeConfigurationEditor.cs index 494d8814f4..882400a25e 100644 --- a/src/Umbraco.Web/PropertyEditors/DateTimeConfigurationEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/DateTimeConfigurationEditor.cs @@ -8,6 +8,11 @@ namespace Umbraco.Web.PropertyEditors ///
    public class DateTimeConfigurationEditor : ConfigurationEditor { + public override IDictionary DefaultConfiguration => new Dictionary + { + ["pickTime"] = true, + }; + public override IDictionary ToValueEditor(object configuration) { var d = base.ToValueEditor(configuration); diff --git a/src/Umbraco.Web/PropertyEditors/MediaPickerConfigurationEditor.cs b/src/Umbraco.Web/PropertyEditors/MediaPickerConfigurationEditor.cs index e810a65fb6..c7c3b1087c 100644 --- a/src/Umbraco.Web/PropertyEditors/MediaPickerConfigurationEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/MediaPickerConfigurationEditor.cs @@ -20,6 +20,11 @@ namespace Umbraco.Web.PropertyEditors }; } + public override IDictionary DefaultConfiguration => new Dictionary + { + ["idType"] = "udi" + }; + public override IDictionary ToValueEditor(object configuration) { var d = base.ToValueEditor(configuration); @@ -27,4 +32,4 @@ namespace Umbraco.Web.PropertyEditors return d; } } -} \ No newline at end of file +} diff --git a/src/Umbraco.Web/PropertyEditors/MultiNodePickerConfigurationEditor.cs b/src/Umbraco.Web/PropertyEditors/MultiNodePickerConfigurationEditor.cs index 75fe581d5b..96cdbe5dc1 100644 --- a/src/Umbraco.Web/PropertyEditors/MultiNodePickerConfigurationEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/MultiNodePickerConfigurationEditor.cs @@ -28,6 +28,14 @@ namespace Umbraco.Web.PropertyEditors return output; } + public override IDictionary DefaultConfiguration => new Dictionary + { + ["multiPicker"] = true, + ["showEditButton"] = false, + ["showPathOnHover"] = false, + ["idType"] = "udi" + }; + /// public override IDictionary ToValueEditor(object configuration) { From 40097c441a200b9edadf42e2c87fca19af6189f1 Mon Sep 17 00:00:00 2001 From: Shannon Date: Fri, 8 Feb 2019 16:07:03 +1100 Subject: [PATCH 56/68] Ensure the same logic for property editors is executed for parameter editors to get the final configuration object --- src/Umbraco.Web/Models/Mapping/MacroMapperProfile.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Web/Models/Mapping/MacroMapperProfile.cs b/src/Umbraco.Web/Models/Mapping/MacroMapperProfile.cs index 3e0f6c7337..de649a09d8 100644 --- a/src/Umbraco.Web/Models/Mapping/MacroMapperProfile.cs +++ b/src/Umbraco.Web/Models/Mapping/MacroMapperProfile.cs @@ -45,8 +45,9 @@ namespace Umbraco.Web.Models.Mapping } parameter.View = paramEditor.GetValueEditor().View; + var paramConfig = paramEditor.GetConfigurationEditor().ToValueEditor(paramEditor.DefaultConfiguration); //set the config - parameter.Configuration = paramEditor.DefaultConfiguration; + parameter.Configuration = paramConfig; }); } } From 964447d54673adced8c8447eac5e81263abe99a2 Mon Sep 17 00:00:00 2001 From: Shannon Date: Fri, 8 Feb 2019 16:08:29 +1100 Subject: [PATCH 57/68] fixes up the web.config view file with the right mvc version --- src/Umbraco.Web.UI/Views/Web.config | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Web.UI/Views/Web.config b/src/Umbraco.Web.UI/Views/Web.config index c137c3705e..efd80424e5 100644 --- a/src/Umbraco.Web.UI/Views/Web.config +++ b/src/Umbraco.Web.UI/Views/Web.config @@ -9,7 +9,7 @@ - + @@ -41,7 +41,7 @@ - +