diff --git a/src/Umbraco.Cms.Api.Management/Mapping/ContentType/ContentTypeMapDefinition.cs b/src/Umbraco.Cms.Api.Management/Mapping/ContentType/ContentTypeMapDefinition.cs index 4b46b8f94d..d77014843c 100644 --- a/src/Umbraco.Cms.Api.Management/Mapping/ContentType/ContentTypeMapDefinition.cs +++ b/src/Umbraco.Cms.Api.Management/Mapping/ContentType/ContentTypeMapDefinition.cs @@ -78,8 +78,29 @@ public abstract class ContentTypeMapDefinition contentTypeComposition.Id == source.ParentId + protected static CompositionType CalculateCompositionType(int contentTypeParentId, IContentTypeComposition contentTypeComposition) + => contentTypeComposition.Id == contentTypeParentId ? CompositionType.Inheritance : CompositionType.Composition; + + protected static IEnumerable MapNestedCompositions(IEnumerable directCompositions, int contentTypeParentId, Func contentTypeCompositionFactory) + { + var allCompositions = new List(); + + foreach (var composition in directCompositions) + { + CompositionType compositionType = CalculateCompositionType(contentTypeParentId, composition); + T contentTypeComposition = contentTypeCompositionFactory(new ReferenceByIdModel(composition.Key), compositionType); + allCompositions.Add(contentTypeComposition); + + // When we have composition inheritance, we have to find all ancestor compositions recursively + if (compositionType == CompositionType.Inheritance && composition.ContentTypeComposition.Any()) + { + var nestedCompositions = MapNestedCompositions(composition.ContentTypeComposition, composition.ParentId, contentTypeCompositionFactory); + allCompositions.AddRange(nestedCompositions); + } + } + + return allCompositions; + } } diff --git a/src/Umbraco.Cms.Api.Management/Mapping/DocumentType/DocumentTypeMapDefinition.cs b/src/Umbraco.Cms.Api.Management/Mapping/DocumentType/DocumentTypeMapDefinition.cs index aa2bd1ac55..aa3f483819 100644 --- a/src/Umbraco.Cms.Api.Management/Mapping/DocumentType/DocumentTypeMapDefinition.cs +++ b/src/Umbraco.Cms.Api.Management/Mapping/DocumentType/DocumentTypeMapDefinition.cs @@ -1,5 +1,4 @@ -using Umbraco.Cms.Api.Management.Extensions; -using Umbraco.Cms.Api.Management.Mapping.ContentType; +using Umbraco.Cms.Api.Management.Mapping.ContentType; using Umbraco.Cms.Api.Management.ViewModels; using Umbraco.Cms.Api.Management.ViewModels.DocumentType; using Umbraco.Cms.Core.Mapping; @@ -37,11 +36,14 @@ public class DocumentTypeMapDefinition : ContentTypeMapDefinition new DocumentTypeSort { DocumentType = new ReferenceByIdModel(ct.Key), SortOrder = ct.SortOrder }) .ToArray() ?? Enumerable.Empty(); - target.Compositions = source.ContentTypeComposition.Select(contentTypeComposition => new DocumentTypeComposition - { - DocumentType = new ReferenceByIdModel(contentTypeComposition.Key), - CompositionType = CalculateCompositionType(source, contentTypeComposition) - }).ToArray(); + target.Compositions = MapNestedCompositions( + source.ContentTypeComposition, + source.ParentId, + (referenceByIdModel, compositionType) => new DocumentTypeComposition + { + DocumentType = referenceByIdModel, + CompositionType = compositionType, + }); if (source.AllowedTemplates != null) { diff --git a/src/Umbraco.Cms.Api.Management/Mapping/MediaType/MediaTypeMapDefinition.cs b/src/Umbraco.Cms.Api.Management/Mapping/MediaType/MediaTypeMapDefinition.cs index 92c7967622..c2604f7a8f 100644 --- a/src/Umbraco.Cms.Api.Management/Mapping/MediaType/MediaTypeMapDefinition.cs +++ b/src/Umbraco.Cms.Api.Management/Mapping/MediaType/MediaTypeMapDefinition.cs @@ -1,5 +1,4 @@ -using Umbraco.Cms.Api.Management.Extensions; -using Umbraco.Cms.Api.Management.Mapping.ContentType; +using Umbraco.Cms.Api.Management.Mapping.ContentType; using Umbraco.Cms.Api.Management.ViewModels; using Umbraco.Cms.Api.Management.ViewModels.MediaType; using Umbraco.Cms.Core.Mapping; @@ -38,11 +37,14 @@ public class MediaTypeMapDefinition : ContentTypeMapDefinition new MediaTypeSort { MediaType = new ReferenceByIdModel(ct.Key), SortOrder = ct.SortOrder }) .ToArray() ?? Enumerable.Empty(); - target.Compositions = source.ContentTypeComposition.Select(contentTypeComposition => new MediaTypeComposition - { - MediaType = new ReferenceByIdModel(contentTypeComposition.Key), - CompositionType = CalculateCompositionType(source, contentTypeComposition) - }).ToArray(); + target.Compositions = MapNestedCompositions( + source.ContentTypeComposition, + source.ParentId, + (referenceByIdModel, compositionType) => new MediaTypeComposition + { + MediaType = referenceByIdModel, + CompositionType = compositionType, + }); } // Umbraco.Code.MapAll diff --git a/src/Umbraco.Cms.Api.Management/Mapping/MemberType/MemberTypeMapDefinition.cs b/src/Umbraco.Cms.Api.Management/Mapping/MemberType/MemberTypeMapDefinition.cs index 9a9742a236..779fa237e5 100644 --- a/src/Umbraco.Cms.Api.Management/Mapping/MemberType/MemberTypeMapDefinition.cs +++ b/src/Umbraco.Cms.Api.Management/Mapping/MemberType/MemberTypeMapDefinition.cs @@ -1,5 +1,4 @@ using Umbraco.Cms.Api.Management.Mapping.ContentType; -using Umbraco.Cms.Api.Management.ViewModels; using Umbraco.Cms.Api.Management.ViewModels.MemberType; using Umbraco.Cms.Core.Mapping; using Umbraco.Cms.Core.Models; @@ -30,12 +29,14 @@ public class MemberTypeMapDefinition : ContentTypeMapDefinition new MemberTypeComposition - { - MemberType = new ReferenceByIdModel(contentTypeComposition.Key), - CompositionType = CalculateCompositionType(source, contentTypeComposition) - }).ToArray(); + target.Compositions = MapNestedCompositions( + source.ContentTypeComposition, + source.ParentId, + (referenceByIdModel, compositionType) => new MemberTypeComposition + { + MemberType = referenceByIdModel, + CompositionType = compositionType, + }); } // Umbraco.Code.MapAll -Collection