From 050109edd744b1ffc5164e4ea68864e62a4263a0 Mon Sep 17 00:00:00 2001 From: Shannon Date: Tue, 15 Dec 2015 12:25:42 +0100 Subject: [PATCH] U4-6837 New content type editor: availableCompositeContentTypes could be moved to service. Allows for assigning compositions to doc types that are being created. Removes unused getAssignedListViewDataType from contentTypeResource. Removes unused getPropertyTypeScaffold from memberTypeResource. Removes unused performContainerDelete from memberTypeResource - since member types don't support folders. Ensures correct security for the ContentTypeController.GetAllPropertyTypeAliases and ContentTypeController.GetAvailableCompositeContentTypes. Removes unused ContentTypeControllerBase.GetAssignedListViewDataType, this is no longer used because the list view is configured using the DataTypeController. --- .../common/resources/contenttype.resource.js | 15 +- .../common/resources/mediatype.resource.js | 10 ++ .../common/resources/membertype.resource.js | 22 +-- .../views/documenttypes/edit.controller.js | 12 +- .../views/membertypes/delete.controller.js | 19 +-- .../src/views/membertypes/delete.html | 35 ++--- .../controls/ContentTypeControlNew.ascx.cs | 2 +- .../Editors/ContentTypeController.cs | 16 +- .../Editors/ContentTypeControllerBase.cs | 148 ++++++++++++++---- .../Editors/MediaTypeController.cs | 5 + .../Editors/MemberTypeController.cs | 5 + .../ContentTypeCompositionDisplay.cs | 9 +- .../AvailableCompositeContentTypesResolver.cs | 118 -------------- .../ContentTypeModelMapperExtensions.cs | 7 +- src/Umbraco.Web/Umbraco.Web.csproj | 1 - 15 files changed, 199 insertions(+), 225 deletions(-) delete mode 100644 src/Umbraco.Web/Models/Mapping/AvailableCompositeContentTypesResolver.cs diff --git a/src/Umbraco.Web.UI.Client/src/common/resources/contenttype.resource.js b/src/Umbraco.Web.UI.Client/src/common/resources/contenttype.resource.js index da4a736cd2..4b1ed8f9c1 100644 --- a/src/Umbraco.Web.UI.Client/src/common/resources/contenttype.resource.js +++ b/src/Umbraco.Web.UI.Client/src/common/resources/contenttype.resource.js @@ -7,15 +7,14 @@ function contentTypeResource($q, $http, umbRequestHelper, umbDataFormatter) { return { - getAssignedListViewDataType: function (contentTypeId) { - + getAvailableCompositeContentTypes: function (contentTypeId) { return umbRequestHelper.resourcePromise( $http.get( umbRequestHelper.getApiUrl( "contentTypeApiBaseUrl", - "GetAssignedListViewDataType", + "GetAvailableCompositeContentTypes", [{ contentTypeId: contentTypeId }])), - 'Failed to retrieve data for content id ' + contentTypeId); + 'Failed to retrieve data for content type id ' + contentTypeId); }, @@ -34,19 +33,19 @@ function contentTypeResource($q, $http, umbRequestHelper, umbDataFormatter) { * $scope.type = type; * }); * - * @param {Int} contentId id of the content item to retrive allowed child types for + * @param {Int} contentTypeId id of the content item to retrive allowed child types for * @returns {Promise} resourcePromise object. * */ - getAllowedTypes: function (contentId) { + getAllowedTypes: function (contentTypeId) { return umbRequestHelper.resourcePromise( $http.get( umbRequestHelper.getApiUrl( "contentTypeApiBaseUrl", "GetAllowedChildren", - [{ contentId: contentId }])), - 'Failed to retrieve data for content id ' + contentId); + [{ contentId: contentTypeId }])), + 'Failed to retrieve data for content id ' + contentTypeId); }, diff --git a/src/Umbraco.Web.UI.Client/src/common/resources/mediatype.resource.js b/src/Umbraco.Web.UI.Client/src/common/resources/mediatype.resource.js index dcdcb7de88..555889e5a3 100644 --- a/src/Umbraco.Web.UI.Client/src/common/resources/mediatype.resource.js +++ b/src/Umbraco.Web.UI.Client/src/common/resources/mediatype.resource.js @@ -7,6 +7,16 @@ function mediaTypeResource($q, $http, umbRequestHelper, umbDataFormatter) { return { + getAvailableCompositeContentTypes: function (contentTypeId) { + return umbRequestHelper.resourcePromise( + $http.get( + umbRequestHelper.getApiUrl( + "mediaTypeApiBaseUrl", + "GetAvailableCompositeMediaTypes", + [{ contentTypeId: contentTypeId }])), + 'Failed to retrieve data for content type id ' + contentTypeId); + }, + /** * @ngdoc method * @name umbraco.resources.mediaTypeResource#getAllowedTypes diff --git a/src/Umbraco.Web.UI.Client/src/common/resources/membertype.resource.js b/src/Umbraco.Web.UI.Client/src/common/resources/membertype.resource.js index b2d1e8d7ed..d949844a6c 100644 --- a/src/Umbraco.Web.UI.Client/src/common/resources/membertype.resource.js +++ b/src/Umbraco.Web.UI.Client/src/common/resources/membertype.resource.js @@ -7,6 +7,16 @@ function memberTypeResource($q, $http, umbRequestHelper, umbDataFormatter) { return { + getAvailableCompositeContentTypes: function (contentTypeId) { + return umbRequestHelper.resourcePromise( + $http.get( + umbRequestHelper.getApiUrl( + "memberTypeApiBaseUrl", + "GetAvailableCompositeMemberTypes", + [{ contentTypeId: contentTypeId }])), + 'Failed to retrieve data for content type id ' + contentTypeId); + }, + //return all member types getTypes: function () { @@ -16,17 +26,7 @@ function memberTypeResource($q, $http, umbRequestHelper, umbDataFormatter) { "memberTypeApiBaseUrl", "GetAllTypes")), 'Failed to retrieve data for member types id'); - }, - - getPropertyTypeScaffold : function (id) { - return umbRequestHelper.resourcePromise( - $http.get( - umbRequestHelper.getApiUrl( - "memberTypeApiBaseUrl", - "GetPropertyTypeScaffold", - [{ id: id }])), - 'Failed to retrieve property type scaffold'); - }, + }, getById: function (id) { diff --git a/src/Umbraco.Web.UI.Client/src/views/documenttypes/edit.controller.js b/src/Umbraco.Web.UI.Client/src/views/documenttypes/edit.controller.js index e33b592e76..1307b854f9 100644 --- a/src/Umbraco.Web.UI.Client/src/views/documenttypes/edit.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/documenttypes/edit.controller.js @@ -218,6 +218,13 @@ function init(contentType) { + //get available composite types + contentTypeResource.getAvailableCompositeContentTypes(contentType.id).then(function (result) { + contentType.availableCompositeContentTypes = result; + // convert legacy icons + convertLegacyIcons(contentType); + }); + // set all tab to inactive if (contentType.groups.length !== 0) { angular.forEach(contentType.groups, function (group) { @@ -230,8 +237,7 @@ }); } - // convert legacy icons - convertLegacyIcons(contentType); + // sort properties after sort order angular.forEach(contentType.groups, function (group) { @@ -244,6 +250,8 @@ contentType.allowedTemplates = contentTypeHelper.insertTemplatePlaceholder(contentType.allowedTemplates); } + + //set a shared state editorState.set(contentType); diff --git a/src/Umbraco.Web.UI.Client/src/views/membertypes/delete.controller.js b/src/Umbraco.Web.UI.Client/src/views/membertypes/delete.controller.js index 71a9786995..061ca7eb2c 100644 --- a/src/Umbraco.Web.UI.Client/src/views/membertypes/delete.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/membertypes/delete.controller.js @@ -6,7 +6,7 @@ * @description * The controller for deleting content */ -function MemberTypesDeleteController($scope, memberTypeResource, contentTypeResource, treeService, navigationService) { +function MemberTypesDeleteController($scope, memberTypeResource, treeService, navigationService) { $scope.performDelete = function() { @@ -25,23 +25,6 @@ function MemberTypesDeleteController($scope, memberTypeResource, contentTypeReso }; - $scope.performContainerDelete = function() { - - //mark it for deletion (used in the UI) - $scope.currentNode.loading = true; - contentTypeResource.deleteContainerById($scope.currentNode.id).then(function () { - $scope.currentNode.loading = false; - - //get the root node before we remove it - var rootNode = treeService.getTreeRoot($scope.currentNode); - - //TODO: Need to sync tree, etc... - treeService.removeNode($scope.currentNode); - navigationService.hideMenu(); - }); - - }; - $scope.cancel = function() { navigationService.hideDialog(); }; diff --git a/src/Umbraco.Web.UI.Client/src/views/membertypes/delete.html b/src/Umbraco.Web.UI.Client/src/views/membertypes/delete.html index 2b4dd8518c..bfd5e46f70 100644 --- a/src/Umbraco.Web.UI.Client/src/views/membertypes/delete.html +++ b/src/Umbraco.Web.UI.Client/src/views/membertypes/delete.html @@ -5,33 +5,20 @@ Are you sure you want to delete {{currentNode.name}} ?

- -
-

This action cannot be undone, click ok to delete.

+

+ All members + using this member type will be deleted permanently, please confirm you want to delete these as well. +

- - -
+
-
-

- All members - using this member type will be deleted permanently, please confirm you want to delete these as well. -

+ -
- - - - - -
-
+ + diff --git a/src/Umbraco.Web.UI/umbraco/controls/ContentTypeControlNew.ascx.cs b/src/Umbraco.Web.UI/umbraco/controls/ContentTypeControlNew.ascx.cs index fef17e6e2e..70b374568e 100644 --- a/src/Umbraco.Web.UI/umbraco/controls/ContentTypeControlNew.ascx.cs +++ b/src/Umbraco.Web.UI/umbraco/controls/ContentTypeControlNew.ascx.cs @@ -26,7 +26,7 @@ namespace Umbraco.Web.UI.Umbraco.Controls base.OnLoad(e); DataTypeControllerUrl = Url.GetUmbracoApiServiceBaseUrl(x => x.GetById(0)); - ContentTypeControllerUrl = Url.GetUmbracoApiServiceBaseUrl(x => x.GetAssignedListViewDataType(0)); + //ContentTypeControllerUrl = Url.GetUmbracoApiServiceBaseUrl(x => x.GetAssignedListViewDataType(0)); } protected void dgTabs_PreRender(object sender, EventArgs e) diff --git a/src/Umbraco.Web/Editors/ContentTypeController.cs b/src/Umbraco.Web/Editors/ContentTypeController.cs index 8179edce2d..aea6690bf2 100644 --- a/src/Umbraco.Web/Editors/ContentTypeController.cs +++ b/src/Umbraco.Web/Editors/ContentTypeController.cs @@ -22,7 +22,8 @@ namespace Umbraco.Web.Editors { //TODO: We'll need to be careful about the security on this controller, when we start implementing // methods to modify content types we'll need to enforce security on the individual methods, we - // cannot put security on the whole controller because things like GetAllowedChildren are required for content editing. + // cannot put security on the whole controller because things like + // GetAllowedChildren, GetPropertyTypeScaffold, GetAllPropertyTypeAliases are required for content editing. /// /// An API controller used for dealing with content types @@ -85,11 +86,24 @@ namespace Umbraco.Web.Editors /// Gets all user defined properties. /// /// + [UmbracoTreeAuthorize( + Constants.Trees.DocumentTypes, Constants.Trees.Content, + Constants.Trees.MediaTypes, Constants.Trees.Media, + Constants.Trees.MemberTypes, Constants.Trees.Members)] public IEnumerable GetAllPropertyTypeAliases() { return ApplicationContext.Services.ContentTypeService.GetAllPropertyTypeAliases(); } + public IEnumerable GetAvailableCompositeContentTypes(int contentTypeId) + { + return PerformGetAvailableCompositeContentTypes(contentTypeId, UmbracoObjectTypes.DocumentType); + } + + [UmbracoTreeAuthorize( + Constants.Trees.DocumentTypes, Constants.Trees.Content, + Constants.Trees.MediaTypes, Constants.Trees.Media, + Constants.Trees.MemberTypes, Constants.Trees.Members)] public ContentPropertyDisplay GetPropertyTypeScaffold(int id) { var dataTypeDiff = Services.DataTypeService.GetDataTypeDefinitionById(id); diff --git a/src/Umbraco.Web/Editors/ContentTypeControllerBase.cs b/src/Umbraco.Web/Editors/ContentTypeControllerBase.cs index fd229e6c47..443b1dcbff 100644 --- a/src/Umbraco.Web/Editors/ContentTypeControllerBase.cs +++ b/src/Umbraco.Web/Editors/ContentTypeControllerBase.cs @@ -46,37 +46,129 @@ namespace Umbraco.Web.Editors { } - protected internal DataTypeBasic GetAssignedListViewDataType(int contentTypeId) + /// + /// Returns the available composite content types for a given content type + /// + /// + protected IEnumerable PerformGetAvailableCompositeContentTypes(int contentTypeId, UmbracoObjectTypes type) { - var objectType = Services.EntityService.GetObjectType(contentTypeId); + IContentTypeComposition source = null; - switch (objectType) - { - case UmbracoObjectTypes.MemberType: - var memberType = Services.MemberTypeService.Get(contentTypeId); - var dtMember = Services.DataTypeService.GetDataTypeDefinitionByName(Constants.Conventions.DataTypes.ListViewPrefix + memberType.Alias); - return dtMember == null - ? Mapper.Map( - Services.DataTypeService.GetDataTypeDefinitionByName(Constants.Conventions.DataTypes.ListViewPrefix + "Member")) - : Mapper.Map(dtMember); - case UmbracoObjectTypes.MediaType: - var mediaType = Services.ContentTypeService.GetMediaType(contentTypeId); - var dtMedia = Services.DataTypeService.GetDataTypeDefinitionByName(Constants.Conventions.DataTypes.ListViewPrefix + mediaType.Alias); - return dtMedia == null - ? Mapper.Map( - Services.DataTypeService.GetDataTypeDefinitionByName(Constants.Conventions.DataTypes.ListViewPrefix + "Media")) - : Mapper.Map(dtMedia); + //below is all ported from the old doc type editor and comes with the same weaknesses /insanity / magic + + IContentTypeComposition[] allContentTypes; + + switch (type) + { case UmbracoObjectTypes.DocumentType: - var docType = Services.ContentTypeService.GetContentType(contentTypeId); - var dtDoc = Services.DataTypeService.GetDataTypeDefinitionByName(Constants.Conventions.DataTypes.ListViewPrefix + docType.Alias); - return dtDoc == null - ? Mapper.Map( - Services.DataTypeService.GetDataTypeDefinitionByName(Constants.Conventions.DataTypes.ListViewPrefix + "Content")) - : Mapper.Map(dtDoc); - default: - throw new ArgumentOutOfRangeException(); - } - } + if (contentTypeId > 0) + { + source = Services.ContentTypeService.GetContentType(contentTypeId); + if (source == null) throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotFound)); + } + allContentTypes = Services.ContentTypeService.GetAllContentTypes().Cast().ToArray(); + break; + + case UmbracoObjectTypes.MediaType: + if (contentTypeId > 0) + { + source = Services.ContentTypeService.GetMediaType(contentTypeId); + if (source == null) throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotFound)); + } + allContentTypes = Services.ContentTypeService.GetAllMediaTypes().Cast().ToArray(); + break; + + case UmbracoObjectTypes.MemberType: + if (contentTypeId > 0) + { + source = Services.MemberTypeService.Get(contentTypeId); + if (source == null) throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotFound)); + } + allContentTypes = Services.MemberTypeService.GetAll().Cast().ToArray(); + break; + + default: + throw new ArgumentOutOfRangeException("The entity type was not a content type"); + } + + // note: there are many sanity checks missing here and there ;-(( + // make sure once and for all + //if (allContentTypes.Any(x => x.ParentId > 0 && x.ContentTypeComposition.Any(y => y.Id == x.ParentId) == false)) + // throw new Exception("A parent does not belong to a composition."); + + // find out if any content type uses this content type + var isUsing = allContentTypes.Where(x => x.ContentTypeComposition.Any(y => y.Id == contentTypeId)).ToArray(); + if (isUsing.Length > 0) + { + //if already in use a composition, do not allow any composited types + return new List(); + } + + // if it is not used then composition is possible + // hashset guarantees unicity on Id + var list = new HashSet(new DelegateEqualityComparer( + (x, y) => x.Id == y.Id, + x => x.Id)); + + // usable types are those that are top-level + var usableContentTypes = allContentTypes + .Where(x => x.ContentTypeComposition.Any() == false).ToArray(); + foreach (var x in usableContentTypes) + list.Add(x); + + // indirect types are those that we use, directly or indirectly + var indirectContentTypes = GetIndirect(source).ToArray(); + foreach (var x in indirectContentTypes) + list.Add(x); + + //// directContentTypes are those we use directly + //// they are already in indirectContentTypes, no need to add to the list + //var directContentTypes = source.ContentTypeComposition.ToArray(); + + //var enabled = usableContentTypes.Select(x => x.Id) // those we can use + // .Except(indirectContentTypes.Select(x => x.Id)) // except those that are indirectly used + // .Union(directContentTypes.Select(x => x.Id)) // but those that are directly used + // .Where(x => x != source.ParentId) // but not the parent + // .Distinct() + // .ToArray(); + + return list + .Where(x => x.Id != contentTypeId) + .OrderBy(x => x.Name) + .Select(Mapper.Map) + .Select(x => + { + x.Name = TranslateItem(x.Name); + return x; + }) + .ToList(); + } + + private static IEnumerable GetIndirect(IContentTypeComposition ctype) + { + // hashset guarantees unicity on Id + var all = new HashSet(new DelegateEqualityComparer( + (x, y) => x.Id == y.Id, + x => x.Id)); + + var stack = new Stack(); + + if (ctype != null) + { + foreach (var x in ctype.ContentTypeComposition) + stack.Push(x); + } + + while (stack.Count > 0) + { + var x = stack.Pop(); + all.Add(x); + foreach (var y in x.ContentTypeComposition) + stack.Push(y); + } + + return all; + } /// /// Validates the composition and adds errors to the model state if any are found then throws an error response if there are errors diff --git a/src/Umbraco.Web/Editors/MediaTypeController.cs b/src/Umbraco.Web/Editors/MediaTypeController.cs index b212555ebe..d54981ff45 100644 --- a/src/Umbraco.Web/Editors/MediaTypeController.cs +++ b/src/Umbraco.Web/Editors/MediaTypeController.cs @@ -83,6 +83,11 @@ namespace Umbraco.Web.Editors return Request.CreateResponse(HttpStatusCode.OK); } + public IEnumerable GetAvailableCompositeMediaTypes(int contentTypeId) + { + return PerformGetAvailableCompositeContentTypes(contentTypeId, UmbracoObjectTypes.MediaType); + } + public ContentTypeCompositionDisplay GetEmpty(int parentId) { var ct = new MediaType(parentId); diff --git a/src/Umbraco.Web/Editors/MemberTypeController.cs b/src/Umbraco.Web/Editors/MemberTypeController.cs index 19a89cd963..7716f6ea00 100644 --- a/src/Umbraco.Web/Editors/MemberTypeController.cs +++ b/src/Umbraco.Web/Editors/MemberTypeController.cs @@ -79,6 +79,11 @@ namespace Umbraco.Web.Editors return Request.CreateResponse(HttpStatusCode.OK); } + public IEnumerable GetAvailableCompositeMemberTypes(int contentTypeId) + { + return PerformGetAvailableCompositeContentTypes(contentTypeId, UmbracoObjectTypes.MemberType); + } + public ContentTypeCompositionDisplay GetEmpty() { var ct = new MemberType(-1); diff --git a/src/Umbraco.Web/Models/ContentEditing/ContentTypeCompositionDisplay.cs b/src/Umbraco.Web/Models/ContentEditing/ContentTypeCompositionDisplay.cs index 7a3869d9b1..9a138dd828 100644 --- a/src/Umbraco.Web/Models/ContentEditing/ContentTypeCompositionDisplay.cs +++ b/src/Umbraco.Web/Models/ContentEditing/ContentTypeCompositionDisplay.cs @@ -18,8 +18,7 @@ namespace Umbraco.Web.Models.ContentEditing //initialize collections so at least their never null Groups = new List(); AllowedContentTypes = new List(); - CompositeContentTypes = new List(); - AvailableCompositeContentTypes = new List(); + CompositeContentTypes = new List(); Notifications = new List(); } @@ -44,11 +43,7 @@ namespace Umbraco.Web.Models.ContentEditing //Compositions [DataMember(Name = "compositeContentTypes")] public IEnumerable CompositeContentTypes { get; set; } - - [DataMember(Name = "availableCompositeContentTypes")] - [ReadOnly(true)] - public IEnumerable AvailableCompositeContentTypes { get; set; } - + [DataMember(Name = "allowAsRoot")] public bool AllowAsRoot { get; set; } diff --git a/src/Umbraco.Web/Models/Mapping/AvailableCompositeContentTypesResolver.cs b/src/Umbraco.Web/Models/Mapping/AvailableCompositeContentTypesResolver.cs deleted file mode 100644 index 9cc415d27a..0000000000 --- a/src/Umbraco.Web/Models/Mapping/AvailableCompositeContentTypesResolver.cs +++ /dev/null @@ -1,118 +0,0 @@ -using AutoMapper; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Umbraco.Core; -using Umbraco.Core.Models; -using Umbraco.Web.Models.ContentEditing; - -namespace Umbraco.Web.Models.Mapping -{ - internal class AvailableCompositeContentTypesResolver : ValueResolver> - { - private readonly ApplicationContext _context; - - internal AvailableCompositeContentTypesResolver(ApplicationContext context) - { - _context = context; - } - - protected override IEnumerable ResolveCore(IContentTypeComposition source) - { - - //below is all ported from the old doc type editor and comes with the same weaknesses /insanity / magic - - var s = source; - var type = _context.Services.EntityService.GetObjectType(source.Id); - var allContentTypes = new IContentTypeComposition[0]; - - switch (type) - { - case UmbracoObjectTypes.DocumentType: - allContentTypes = _context.Services.ContentTypeService.GetAllContentTypes().Cast().ToArray(); - break; - - case UmbracoObjectTypes.MediaType: - allContentTypes = _context.Services.ContentTypeService.GetAllMediaTypes().Cast().ToArray(); - break; - - case UmbracoObjectTypes.MemberType: - allContentTypes = _context.Services.MemberTypeService.GetAll().Cast().ToArray(); - break; - } - - // note: there are many sanity checks missing here and there ;-(( - // make sure once and for all - //if (allContentTypes.Any(x => x.ParentId > 0 && x.ContentTypeComposition.Any(y => y.Id == x.ParentId) == false)) - // throw new Exception("A parent does not belong to a composition."); - - // find out if any content type uses this content type - var isUsing = allContentTypes.Where(x => x.ContentTypeComposition.Any(y => y.Id == source.Id)).ToArray(); - if (isUsing.Length > 0) - { - //if already in use a composition, do not allow any composited types - return new List(); - } - - // if it is not used then composition is possible - // hashset guarantees unicity on Id - var list = new HashSet(new DelegateEqualityComparer( - (x, y) => x.Id == y.Id, - x => x.Id)); - - // usable types are those that are top-level - var usableContentTypes = allContentTypes - .Where(x => x.ContentTypeComposition.Any() == false).ToArray(); - foreach (var x in usableContentTypes) - list.Add(x); - - // indirect types are those that we use, directly or indirectly - var indirectContentTypes = GetIndirect(source).ToArray(); - foreach (var x in indirectContentTypes) - list.Add(x); - - //// directContentTypes are those we use directly - //// they are already in indirectContentTypes, no need to add to the list - //var directContentTypes = source.ContentTypeComposition.ToArray(); - - //var enabled = usableContentTypes.Select(x => x.Id) // those we can use - // .Except(indirectContentTypes.Select(x => x.Id)) // except those that are indirectly used - // .Union(directContentTypes.Select(x => x.Id)) // but those that are directly used - // .Where(x => x != source.ParentId) // but not the parent - // .Distinct() - // .ToArray(); - - return list - .Where(x => x.Id != source.Id) - .OrderBy(x => x.Name) - .Select(Mapper.Map) - .ToList(); - } - - - private IEnumerable GetIndirect(IContentTypeComposition ctype) - { - // hashset guarantees unicity on Id - var all = new HashSet(new DelegateEqualityComparer( - (x, y) => x.Id == y.Id, - x => x.Id)); - - var stack = new Stack(); - - foreach (var x in ctype.ContentTypeComposition) - stack.Push(x); - - while (stack.Count > 0) - { - var x = stack.Pop(); - all.Add(x); - foreach (var y in x.ContentTypeComposition) - stack.Push(y); - } - - return all; - } - } -} diff --git a/src/Umbraco.Web/Models/Mapping/ContentTypeModelMapperExtensions.cs b/src/Umbraco.Web/Models/Mapping/ContentTypeModelMapperExtensions.cs index 9178d69d8f..e59a474afb 100644 --- a/src/Umbraco.Web/Models/Mapping/ContentTypeModelMapperExtensions.cs +++ b/src/Umbraco.Web/Models/Mapping/ContentTypeModelMapperExtensions.cs @@ -56,7 +56,6 @@ namespace Umbraco.Web.Models.Mapping .ForMember(dto => dto.CreateDate, expression => expression.Ignore()) .ForMember(dto => dto.UpdateDate, expression => expression.Ignore()) .ForMember(dto => dto.ListViewEditorName, expression => expression.Ignore()) - .ForMember(dto => dto.AvailableCompositeContentTypes, expression => expression.Ignore()) .ForMember(dto => dto.Notifications, expression => expression.Ignore()) .ForMember(dto => dto.Errors, expression => expression.Ignore()); } @@ -77,11 +76,7 @@ namespace Umbraco.Web.Models.Mapping .ForMember( dto => dto.AllowedContentTypes, expression => expression.MapFrom(dto => dto.AllowedContentTypes.Select(x => x.Id.Value))) - - .ForMember( - dto => dto.AvailableCompositeContentTypes, - expression => expression.ResolveUsing(new AvailableCompositeContentTypesResolver(applicationContext))) - + .ForMember( dto => dto.CompositeContentTypes, expression => expression.MapFrom(dto => dto.ContentTypeComposition)) diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index 0ef5b3b115..12a6d47bd0 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -324,7 +324,6 @@ -