From 94b09a456815ae1ea7726e2d2f426487e662e5b9 Mon Sep 17 00:00:00 2001 From: Per Ploug Date: Wed, 26 Aug 2015 12:07:43 +0200 Subject: [PATCH] Fixes issues with the merged contenttype mapper Mediatype, membertype and contenttype all use the same core mapper, with small variations between each type - it is however important in what order the mappers are added. --- .../AvailableCompositeContentTypesResolver.cs | 27 +++-- .../Models/Mapping/ContentTypeModelMapper.cs | 101 +++++++++++++----- 2 files changed, 96 insertions(+), 32 deletions(-) diff --git a/src/Umbraco.Web/Models/Mapping/AvailableCompositeContentTypesResolver.cs b/src/Umbraco.Web/Models/Mapping/AvailableCompositeContentTypesResolver.cs index bdcc063591..dacd2ab0a7 100644 --- a/src/Umbraco.Web/Models/Mapping/AvailableCompositeContentTypesResolver.cs +++ b/src/Umbraco.Web/Models/Mapping/AvailableCompositeContentTypesResolver.cs @@ -10,7 +10,7 @@ using Umbraco.Web.Models.ContentEditing; namespace Umbraco.Web.Models.Mapping { - internal class AvailableCompositeContentTypesResolver : ValueResolver> + internal class AvailableCompositeContentTypesResolver : ValueResolver> { private ApplicationContext _context; private bool _mediaType; @@ -20,14 +20,29 @@ namespace Umbraco.Web.Models.Mapping _mediaType = mediaType; } - protected override IEnumerable ResolveCore(IContentType source) + protected override IEnumerable ResolveCore(IContentTypeComposition source) { + //below is all ported from the old doc type editor and comes with the same weaknesses /insanity / magic - //get all types - var allContentTypes = _mediaType - ? _context.Services.ContentTypeService.GetAllMediaTypes().Cast().ToArray() - : _context.Services.ContentTypeService.GetAllContentTypes().Cast().ToArray(); + var s = source; + var type = _context.Services.EntityService.GetObjectType(source.Id); + IContentTypeComposition[] 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 diff --git a/src/Umbraco.Web/Models/Mapping/ContentTypeModelMapper.cs b/src/Umbraco.Web/Models/Mapping/ContentTypeModelMapper.cs index f84939366b..05bb7df268 100644 --- a/src/Umbraco.Web/Models/Mapping/ContentTypeModelMapper.cs +++ b/src/Umbraco.Web/Models/Mapping/ContentTypeModelMapper.cs @@ -9,6 +9,7 @@ using Umbraco.Core.Models.Mapping; using Umbraco.Core.PropertyEditors; using Umbraco.Web.Models.ContentEditing; using System.Collections.Generic; +using AutoMapper.Internal; using Property = umbraco.NodeFactory.Property; namespace Umbraco.Web.Models.Mapping @@ -34,24 +35,11 @@ namespace Umbraco.Web.Models.Mapping public override void ConfigureMappings(IConfiguration config, ApplicationContext applicationContext) { - config.CreateMap() - .ConstructUsing((ContentTypeDisplay source) => new ContentType(source.ParentId)) - - .ForMember(dto => dto.AllowedTemplates, expression => expression.Ignore()) - .ForMember(dto => dto.DefaultTemplate, expression => expression.Ignore()) - - .AfterMap((source, dest) => - { - //sync templates - dest.AllowedTemplates = source.AllowedTemplates.Select(x => Mapper.Map(x)); - - if (source.DefaultTemplate != null) - dest.SetDefaultTemplate(Mapper.Map(source.DefaultTemplate)); - }); - - config.CreateMap() .Include() + .Include() + .Include() + //only map id if set to something higher then zero .ForMember(dto => dto.Id, expression => expression.Condition(display => (Convert.ToInt32(display.Id) > 0))) .ForMember(dto => dto.Id, expression => expression.MapFrom(display => Convert.ToInt32(display.Id))) @@ -60,9 +48,10 @@ namespace Umbraco.Web.Models.Mapping .ForMember(dto => dto.Level, expression => expression.Ignore()) .ForMember(dto => dto.SortOrder, expression => expression.Ignore()) - //mapped in aftermap - .ForMember(dto => dto.AllowedContentTypes, expression => expression.Ignore()) - + .ForMember( + dto => dto.AllowedContentTypes, + expression => expression.MapFrom(dto => dto.AllowedContentTypes.Select( (t, i) => new ContentTypeSort(t, i) ))) + //ignore, we'll do this in after map .ForMember(dto => dto.PropertyGroups, expression => expression.Ignore()) @@ -123,11 +112,24 @@ namespace Umbraco.Web.Models.Mapping { dest.RemovePropertyType(removedType.Alias); } + + }); + + config.CreateMap() + .ConstructUsing((source) => new ContentType(source.ParentId)) + + .ForMember(dto => dto.AllowedTemplates, expression => expression.Ignore()) + .ForMember(dto => dto.DefaultTemplate, expression => expression.Ignore()) + + .AfterMap((source, dest) => + { + //sync templates + dest.AllowedTemplates = source.AllowedTemplates.Select(x => Mapper.Map(x)); + + if (source.DefaultTemplate != null) + dest.SetDefaultTemplate(Mapper.Map(source.DefaultTemplate)); - //Sync allowed child types - var allowedTypes = source.AllowedContentTypes.Select((t, i) => new ContentTypeSort(t, i)); - dest.AllowedContentTypes = allowedTypes.ToArray(); //sync compositions var current = dest.CompositionAliases().ToArray(); @@ -143,23 +145,66 @@ namespace Umbraco.Web.Models.Mapping foreach (var a in add) { + //TODO: Remove N+1 lookup var addCt = applicationContext.Services.ContentTypeService.GetContentType(a); if (addCt != null) dest.AddContentType(addCt); } - }); + config.CreateMap() + .AfterMap((source, dest) => + { + + //sync compositions + var current = dest.CompositionAliases().ToArray(); + var proposed = source.CompositeContentTypes; + + var remove = current.Where(x => proposed.Contains(x) == false); + var add = proposed.Where(x => current.Contains(x) == false); + + foreach (var rem in remove) + dest.RemoveContentType(rem); + + foreach (var a in add) + { + //TODO: Remove N+1 lookup + var addCt = applicationContext.Services.MemberTypeService.Get(a); + if (addCt != null) + dest.AddContentType(addCt); + } + }); + config.CreateMap() + .AfterMap((source, dest) => + { + //sync compositions + var current = dest.CompositionAliases().ToArray(); + var proposed = source.CompositeContentTypes; - config.CreateMap().ConvertUsing(x => x.Id.Value); + var remove = current.Where(x => proposed.Contains(x) == false); + var add = proposed.Where(x => current.Contains(x) == false); + + foreach (var rem in remove) + dest.RemoveContentType(rem); + + foreach (var a in add) + { + //TODO: Remove N+1 lookup + var addCt = applicationContext.Services.ContentTypeService.GetMediaType(a); + if (addCt != null) + dest.AddContentType(addCt); + } + }); + + config.CreateMap().ConvertUsing(x => x.Alias); + config.CreateMap() .Include() - .Include() .Include() @@ -197,9 +242,9 @@ namespace Umbraco.Web.Models.Mapping })); + config.CreateMap(); config.CreateMap(); - config.CreateMap() .ForMember(dto => dto.AllowedTemplates, expression => expression.Ignore()) .ForMember(dto => dto.DefaultTemplate, expression => expression.Ignore()) @@ -213,6 +258,10 @@ namespace Umbraco.Web.Models.Mapping dest.DefaultTemplate = Mapper.Map(source.DefaultTemplate); }); + config.CreateMap(); + config.CreateMap(); + config.CreateMap(); + config.CreateMap() .ForMember(dest => dest.Id, expression => expression.Condition(source => source.Id > 0))