diff --git a/src/Umbraco.Core/Mapping/Mapper.cs b/src/Umbraco.Core/Mapping/Mapper.cs index a1b72807bb..f609c8c298 100644 --- a/src/Umbraco.Core/Mapping/Mapper.cs +++ b/src/Umbraco.Core/Mapping/Mapper.cs @@ -25,16 +25,16 @@ namespace Umbraco.Core.Mapping profile.SetMaps(this); } - public void SetMap() - => SetMap((source, target) => { }); + public void Define() + => Define((source, target) => { }); - public void SetMap(Action map) - => SetMap(source => throw new NotSupportedException($"Don't know how to create {typeof(TTarget)} instances."), map); + public void Define(Action map) + => Define(source => throw new NotSupportedException($"Don't know how to create {typeof(TTarget)} instances."), map); - public void SetMap(Func ctor) - => SetMap(ctor, (source, target) => { }); + public void Define(Func ctor) + => Define(ctor, (source, target) => { }); - public void SetMap(Func ctor, Action map) + public void Define(Func ctor, Action map) { var sourceType = typeof(TSource); var targetType = typeof(TTarget); diff --git a/src/Umbraco.Core/Models/Identity/IdentityMapperProfile.cs b/src/Umbraco.Core/Models/Identity/IdentityMapperProfile.cs index 64d9c6f9a1..8054c36908 100644 --- a/src/Umbraco.Core/Models/Identity/IdentityMapperProfile.cs +++ b/src/Umbraco.Core/Models/Identity/IdentityMapperProfile.cs @@ -21,7 +21,7 @@ namespace Umbraco.Core.Models.Identity public void SetMaps(Mapper mapper) { - mapper.SetMap( + mapper.Define( source => { var target = new BackOfficeIdentityUser(source.Id, source.Groups); diff --git a/src/Umbraco.Tests/Mapping/MappingTests.cs b/src/Umbraco.Tests/Mapping/MappingTests.cs index 4b2e0cfdec..07930bf027 100644 --- a/src/Umbraco.Tests/Mapping/MappingTests.cs +++ b/src/Umbraco.Tests/Mapping/MappingTests.cs @@ -79,7 +79,7 @@ namespace Umbraco.Tests.Mapping { public void SetMaps(Mapper mapper) { - mapper.SetMap(source => new Thing2(), (source, target) => Map(source, target)); + mapper.Define(source => new Thing2(), (source, target) => Map(source, target)); } private Thing2 Map(Thing1 source, Thing2 target) diff --git a/src/Umbraco.Web/Composing/CompositionExtensions/WebMappingProfiles.cs b/src/Umbraco.Web/Composing/CompositionExtensions/WebMappingProfiles.cs index a72ba41ab6..42f64938de 100644 --- a/src/Umbraco.Web/Composing/CompositionExtensions/WebMappingProfiles.cs +++ b/src/Umbraco.Web/Composing/CompositionExtensions/WebMappingProfiles.cs @@ -17,6 +17,9 @@ namespace Umbraco.Web.Composing.CompositionExtensions composition.WithCollectionBuilder() .Append() .Append() + .Append() + .Append() + .Append() .Append() .Append() .Append() @@ -31,10 +34,10 @@ namespace Umbraco.Web.Composing.CompositionExtensions composition.Register(); composition.Register(); composition.Register(); - composition.Register(); + //composition.Register(); composition.Register(); - composition.Register(); - composition.Register(); + //composition.Register(); + //composition.Register(); composition.Register(); composition.Register(); //composition.Register(); diff --git a/src/Umbraco.Web/Models/Mapping/AuditMapperProfile.cs b/src/Umbraco.Web/Models/Mapping/AuditMapperProfile.cs index ffb16b0385..6c3288afb5 100644 --- a/src/Umbraco.Web/Models/Mapping/AuditMapperProfile.cs +++ b/src/Umbraco.Web/Models/Mapping/AuditMapperProfile.cs @@ -8,7 +8,7 @@ namespace Umbraco.Web.Models.Mapping { public void SetMaps(Mapper mapper) { - mapper.SetMap(source => new AuditLog(), (source, target) => Map(source, target)); + mapper.Define(source => new AuditLog(), (source, target) => Map(source, target)); } // Umbraco.Code.MapAll -UserAvatars -UserName diff --git a/src/Umbraco.Web/Models/Mapping/AvailablePropertyEditorsResolver.cs b/src/Umbraco.Web/Models/Mapping/AvailablePropertyEditorsResolver.cs deleted file mode 100644 index d13857434f..0000000000 --- a/src/Umbraco.Web/Models/Mapping/AvailablePropertyEditorsResolver.cs +++ /dev/null @@ -1,28 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using AutoMapper; -using Umbraco.Core.Configuration.UmbracoSettings; -using Umbraco.Core.Models; -using Umbraco.Web.Composing; -using Umbraco.Web.Models.ContentEditing; - -namespace Umbraco.Web.Models.Mapping -{ - internal class AvailablePropertyEditorsResolver - { - private readonly IContentSection _contentSection; - - public AvailablePropertyEditorsResolver(IContentSection contentSection) - { - _contentSection = contentSection; - } - - public IEnumerable Resolve(IDataType source) - { - return Current.PropertyEditors - .Where(x => !x.IsDeprecated || _contentSection.ShowDeprecatedPropertyEditors || source.EditorAlias == x.Alias) - .OrderBy(x => x.Name) - .Select(Mapper.Map); - } - } -} diff --git a/src/Umbraco.Web/Models/Mapping/CodeFileMapperProfile.cs b/src/Umbraco.Web/Models/Mapping/CodeFileMapperProfile.cs index 9416123d0c..7767bcd2ee 100644 --- a/src/Umbraco.Web/Models/Mapping/CodeFileMapperProfile.cs +++ b/src/Umbraco.Web/Models/Mapping/CodeFileMapperProfile.cs @@ -9,12 +9,12 @@ namespace Umbraco.Web.Models.Mapping { public void SetMaps(Mapper mapper) { - mapper.SetMap(source => new EntityBasic(), Map); - mapper.SetMap(source => new CodeFileDisplay(), Map); - mapper.SetMap(source => new CodeFileDisplay(), Map); - mapper.SetMap(source => new CodeFileDisplay(), Map); - mapper.SetMap(Map); - mapper.SetMap(Map); + mapper.Define(source => new EntityBasic(), Map); + mapper.Define(source => new CodeFileDisplay(), Map); + mapper.Define(source => new CodeFileDisplay(), Map); + mapper.Define(source => new CodeFileDisplay(), Map); + mapper.Define(Map); + mapper.Define(Map); } diff --git a/src/Umbraco.Web/Models/Mapping/DataTypeConfigurationFieldDisplayResolver.cs b/src/Umbraco.Web/Models/Mapping/DataTypeConfigurationFieldDisplayResolver.cs deleted file mode 100644 index cca64eb164..0000000000 --- a/src/Umbraco.Web/Models/Mapping/DataTypeConfigurationFieldDisplayResolver.cs +++ /dev/null @@ -1,64 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using AutoMapper; -using Umbraco.Core.Logging; -using Umbraco.Core.Models; -using Umbraco.Web.Composing; -using Umbraco.Web.Models.ContentEditing; - -namespace Umbraco.Web.Models.Mapping -{ - internal class DataTypeConfigurationFieldDisplayResolver - { - private readonly ILogger _logger; - - public DataTypeConfigurationFieldDisplayResolver(ILogger logger) - { - _logger = logger ?? throw new ArgumentNullException(nameof(logger)); - } - - /// - /// Maps pre-values in the dictionary to the values for the fields - /// - internal static void MapConfigurationFields(ILogger logger, DataTypeConfigurationFieldDisplay[] fields, IDictionary configuration) - { - if (fields == null) throw new ArgumentNullException(nameof(fields)); - if (configuration == null) throw new ArgumentNullException(nameof(configuration)); - - // now we need to wire up the pre-values values with the actual fields defined - foreach (var field in fields) - { - if (configuration.TryGetValue(field.Key, out var value)) - field.Value = value; - else - { - // weird - just leave the field without a value - but warn - logger.Warn("Could not find a value for configuration field '{ConfigField}'", field.Key); - } - - } - } - - /// - /// Creates a set of configuration fields for a data type. - /// - public IEnumerable Resolve(IDataType dataType) - { - // in v7 it was apparently fine to have an empty .EditorAlias here, in which case we would map onto - // an empty fields list, which made no sense since there would be nothing to map to - and besides, - // a datatype without an editor alias is a serious issue - v8 wants an editor here - - if (string.IsNullOrWhiteSpace(dataType.EditorAlias) || !Current.PropertyEditors.TryGet(dataType.EditorAlias, out var editor)) - throw new InvalidOperationException($"Could not find a property editor with alias \"{dataType.EditorAlias}\"."); - - var configurationEditor = editor.GetConfigurationEditor(); - var fields = configurationEditor.Fields.Select(Mapper.Map).ToArray(); - var configurationDictionary = configurationEditor.ToConfigurationEditor(dataType.Configuration); - - MapConfigurationFields(_logger, fields, configurationDictionary); - - return fields; - } - } -} diff --git a/src/Umbraco.Web/Models/Mapping/DataTypeMapperProfile.cs b/src/Umbraco.Web/Models/Mapping/DataTypeMapperProfile.cs index f707003ffe..b13888ba9d 100644 --- a/src/Umbraco.Web/Models/Mapping/DataTypeMapperProfile.cs +++ b/src/Umbraco.Web/Models/Mapping/DataTypeMapperProfile.cs @@ -1,10 +1,9 @@ using System; using System.Collections.Generic; -using AutoMapper; using System.Linq; using Umbraco.Core; using Umbraco.Core.Logging; -using Umbraco.Core.Configuration; +using Umbraco.Core.Mapping; using Umbraco.Core.Models; using Umbraco.Core.PropertyEditors; using Umbraco.Web.Composing; @@ -12,118 +11,192 @@ using Umbraco.Web.Models.ContentEditing; namespace Umbraco.Web.Models.Mapping { - /// - /// Configures model mappings for datatypes. - /// - internal class DataTypeMapperProfile : Profile + internal class DataTypeMapperProfile : IMapperProfile { + private readonly PropertyEditorCollection _propertyEditors; + private readonly ILogger _logger; + public DataTypeMapperProfile(PropertyEditorCollection propertyEditors, ILogger logger) { - // create, capture, cache - var availablePropertyEditorsResolver = new AvailablePropertyEditorsResolver(Current.Configs.Settings().Content); - var configurationDisplayResolver = new DataTypeConfigurationFieldDisplayResolver(logger); - var databaseTypeResolver = new DatabaseTypeResolver(); + _propertyEditors = propertyEditors; + _logger = logger; + } - CreateMap(); + private static readonly int[] SystemIds = + { + Constants.DataTypes.DefaultContentListView, + Constants.DataTypes.DefaultMediaListView, + Constants.DataTypes.DefaultMembersListView + }; - // map the standard properties, not the values - CreateMap() - .ForMember(dest => dest.Value, opt => opt.Ignore()); + public void SetMaps(Mapper mapper) + { + mapper.Define(source => new PropertyEditorBasic(), Map); + mapper.Define(source => new DataTypeConfigurationFieldDisplay(), Map); + mapper.Define(source => new DataTypeBasic(), Map); + mapper.Define(source => new DataTypeBasic(), Map); + mapper.Define(source => new DataTypeDisplay(), (source, target) => Map(source, target, mapper)); + mapper.Define>(source => MapPreValues(source, mapper)); + mapper.Define(Map); + mapper.Define>(source => MapPreValues(source, mapper)); + } - var systemIds = new[] + // Umbraco.Code.MapAll + private static void Map(IDataEditor source, PropertyEditorBasic target) + { + target.Alias = source.Alias; + target.Icon = source.Icon; + target.Name = source.Name; + } + + // Umbraco.Code.MapAll -Value + private static void Map(ConfigurationField source, DataTypeConfigurationFieldDisplay target) + { + target.Config = source.Config; + target.Description = source.Description; + target.HideLabel = source.HideLabel; + target.Key = source.Key; + target.Name = source.Name; + target.View = source.View; + } + + // Umbraco.Code.MapAll -Udi -HasPrevalues -IsSystemDataType -Id -Trashed -Key + // Umbraco.Code.MapAll -ParentId -Path + private static void Map(IDataEditor source, DataTypeBasic target) + { + target.Alias = source.Alias; + target.Group = source.Group; + target.Icon = source.Icon; + target.Name = source.Name; + } + + // Umbraco.Code.MapAll -HasPrevalues + private void Map(IDataType source, DataTypeBasic target) + { + target.Id = source.Id; + target.IsSystemDataType = SystemIds.Contains(source.Id); + target.Key = source.Key; + target.Name = source.Name; + target.ParentId = source.ParentId; + target.Path = source.Path; + target.Trashed = source.Trashed; + target.Udi = Udi.Create(Constants.UdiEntityType.DataType, source.Key); + + if (!_propertyEditors.TryGet(source.EditorAlias, out var editor)) + return; + + target.Alias = editor.Alias; + target.Group = editor.Group; + target.Icon = editor.Icon; + } + + // Umbraco.Code.MapAll -HasPrevalues + private void Map(IDataType source, DataTypeDisplay target, Mapper mapper) + { + target.AvailableEditors = MapAvailableEditors(source, mapper); + target.Id = source.Id; + target.IsSystemDataType = SystemIds.Contains(source.Id); + target.Key = source.Key; + target.Name = source.Name; + target.ParentId = source.ParentId; + target.Path = source.Path; + target.PreValues = MapPreValues(source, mapper); + target.SelectedEditor = source.EditorAlias.IsNullOrWhiteSpace() ? null : source.EditorAlias; + target.Trashed = source.Trashed; + target.Udi = Udi.Create(Constants.UdiEntityType.DataType, source.Key); + + if (!_propertyEditors.TryGet(source.EditorAlias, out var editor)) + return; + + target.Alias = editor.Alias; + target.Group = editor.Group; + target.Icon = editor.Icon; + } + + // Umbraco.Code.MapAll -CreateDate -DeleteDate -UpdateDate + // Umbraco.Code.MapAll -Key -Path -CreatorId -Level -SortOrder -Configuration + private void Map(DataTypeSave source, IDataType target) + { + target.DatabaseType = MapDatabaseType(source); + target.Editor = _propertyEditors[source.EditorAlias]; + target.Id = Convert.ToInt32(source.Id); + target.Name = source.Name; + target.ParentId = source.ParentId; + } + + private IEnumerable MapAvailableEditors(IDataType source, Mapper mapper) + { + var contentSection = Current.Configs.Settings().Content; + return _propertyEditors + .Where(x => !x.IsDeprecated || contentSection.ShowDeprecatedPropertyEditors || source.EditorAlias == x.Alias) + .OrderBy(x => x.Name) + .Select(mapper.Map); + } + + private IEnumerable MapPreValues(IDataType dataType, Mapper mapper) + { + // in v7 it was apparently fine to have an empty .EditorAlias here, in which case we would map onto + // an empty fields list, which made no sense since there would be nothing to map to - and besides, + // a datatype without an editor alias is a serious issue - v8 wants an editor here + + if (string.IsNullOrWhiteSpace(dataType.EditorAlias) || !Current.PropertyEditors.TryGet(dataType.EditorAlias, out var editor)) + throw new InvalidOperationException($"Could not find a property editor with alias \"{dataType.EditorAlias}\"."); + + var configurationEditor = editor.GetConfigurationEditor(); + var fields = configurationEditor.Fields.Select(mapper.Map).ToArray(); + var configurationDictionary = configurationEditor.ToConfigurationEditor(dataType.Configuration); + + MapConfigurationFields(fields, configurationDictionary); + + return fields; + } + + private void MapConfigurationFields(DataTypeConfigurationFieldDisplay[] fields, IDictionary configuration) + { + if (fields == null) throw new ArgumentNullException(nameof(fields)); + if (configuration == null) throw new ArgumentNullException(nameof(configuration)); + + // now we need to wire up the pre-values values with the actual fields defined + foreach (var field in fields) { - Constants.DataTypes.DefaultContentListView, - Constants.DataTypes.DefaultMediaListView, - Constants.DataTypes.DefaultMembersListView - }; - - CreateMap() - .ForMember(dest => dest.Udi, opt => opt.Ignore()) - .ForMember(dest => dest.HasPrevalues, opt => opt.Ignore()) - .ForMember(dest => dest.IsSystemDataType, opt => opt.Ignore()) - .ForMember(dest => dest.Id, opt => opt.Ignore()) - .ForMember(dest => dest.Trashed, opt => opt.Ignore()) - .ForMember(dest => dest.Key, opt => opt.Ignore()) - .ForMember(dest => dest.ParentId, opt => opt.Ignore()) - .ForMember(dest => dest.Path, opt => opt.Ignore()) - .ForMember(dest => dest.AdditionalData, opt => opt.Ignore()); - - CreateMap() - .ForMember(dest => dest.Udi, opt => opt.MapFrom(src => Udi.Create(Constants.UdiEntityType.DataType, src.Key))) - .ForMember(dest => dest.HasPrevalues, opt => opt.Ignore()) - .ForMember(dest => dest.Icon, opt => opt.Ignore()) - .ForMember(dest => dest.Alias, opt => opt.Ignore()) - .ForMember(dest => dest.Group, opt => opt.Ignore()) - .ForMember(dest => dest.IsSystemDataType, opt => opt.MapFrom(src => systemIds.Contains(src.Id))) - .ForMember(dest => dest.AdditionalData, opt => opt.Ignore()) - .AfterMap((src, dest) => + if (configuration.TryGetValue(field.Key, out var value)) { - if (Current.PropertyEditors.TryGet(src.EditorAlias, out var editor)) - { - dest.Alias = editor.Alias; - dest.Group = editor.Group; - dest.Icon = editor.Icon; - } - }); - - CreateMap() - .ForMember(dest => dest.Udi, opt => opt.MapFrom(src => Udi.Create(Constants.UdiEntityType.DataType, src.Key))) - .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()) - .ForMember(dest => dest.Icon, opt => opt.Ignore()) - .ForMember(dest => dest.Alias, opt => opt.Ignore()) - .ForMember(dest => dest.Group, opt => opt.Ignore()) - .ForMember(dest => dest.IsSystemDataType, opt => opt.MapFrom(src => systemIds.Contains(src.Id))) - .ForMember(dest => dest.AdditionalData, opt => opt.Ignore()) - .AfterMap((src, dest) => + field.Value = value; + } + else { - if (Current.PropertyEditors.TryGet(src.EditorAlias, out var editor)) - { - dest.Group = editor.Group; - dest.Icon = editor.Icon; - } - }); + // weird - just leave the field without a value - but warn + _logger.Warn("Could not find a value for configuration field '{ConfigField}'", field.Key); + } + } + } - //gets a list of PreValueFieldDisplay objects from the data type definition - CreateMap>() - .ConvertUsing(src => configurationDisplayResolver.Resolve(src)); + private ValueStorageType MapDatabaseType(DataTypeSave source) + { + if (!_propertyEditors.TryGet(source.EditorAlias, out var editor)) + throw new InvalidOperationException($"Could not find property editor \"{source.EditorAlias}\"."); - CreateMap() - .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.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()) - .ForMember(dest => dest.Configuration, opt => opt.Ignore()) - .ForMember(dest => dest.Editor, opt => opt.MapFrom(src => propertyEditors[src.EditorAlias])); + // TODO: what about source.PropertyEditor? can we get the configuration here? 'cos it may change the storage type?! + var valueType = editor.GetValueEditor().ValueType; + return ValueTypes.ToStorageType(valueType); + } - //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((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 + private IEnumerable MapPreValues(IDataEditor source, Mapper mapper) + { + // 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 = dataEditor.GetConfigurationEditor(); + var configurationEditor = source.GetConfigurationEditor(); - var fields = configurationEditor.Fields.Select(Mapper.Map).ToArray(); + var fields = configurationEditor.Fields.Select(mapper.Map).ToArray(); - var defaultConfiguration = configurationEditor.DefaultConfiguration; - if (defaultConfiguration != null) - DataTypeConfigurationFieldDisplayResolver.MapConfigurationFields(logger, fields, defaultConfiguration); + var defaultConfiguration = configurationEditor.DefaultConfiguration; + if (defaultConfiguration != null) + MapConfigurationFields(fields, defaultConfiguration); - return fields; - }); + return fields; } } } diff --git a/src/Umbraco.Web/Models/Mapping/DatabaseTypeResolver.cs b/src/Umbraco.Web/Models/Mapping/DatabaseTypeResolver.cs deleted file mode 100644 index 35702719dc..0000000000 --- a/src/Umbraco.Web/Models/Mapping/DatabaseTypeResolver.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System; -using Umbraco.Core.Models; -using Umbraco.Core.PropertyEditors; -using Umbraco.Web.Composing; -using Umbraco.Web.Models.ContentEditing; - -namespace Umbraco.Web.Models.Mapping -{ - /// - /// Gets the DataTypeDatabaseType from the selected property editor for the data type - /// - internal class DatabaseTypeResolver - { - public ValueStorageType Resolve(DataTypeSave source) - { - if (!Current.PropertyEditors.TryGet(source.EditorAlias, out var editor)) - throw new InvalidOperationException($"Could not find property editor \"{source.EditorAlias}\"."); - - // TODO: what about source.PropertyEditor? can we get the configuration here? 'cos it may change the storage type?! - var valueType = editor.GetValueEditor().ValueType; - return ValueTypes.ToStorageType(valueType); - } - } -} diff --git a/src/Umbraco.Web/Models/Mapping/DictionaryMapperProfile.cs b/src/Umbraco.Web/Models/Mapping/DictionaryMapperProfile.cs index 01fcfa6f13..c9570e13e6 100644 --- a/src/Umbraco.Web/Models/Mapping/DictionaryMapperProfile.cs +++ b/src/Umbraco.Web/Models/Mapping/DictionaryMapperProfile.cs @@ -1,8 +1,8 @@ -using AutoMapper; -using System; +using System; using System.Collections.Generic; using System.Linq; using Umbraco.Core; +using Umbraco.Core.Mapping; using Umbraco.Core.Models; using Umbraco.Core.Services; using Umbraco.Web.Models.ContentEditing; @@ -13,120 +13,96 @@ namespace Umbraco.Web.Models.Mapping /// /// The dictionary model mapper. /// - internal class DictionaryMapperProfile : Profile + internal class DictionaryMapperProfile : IMapperProfile { + private readonly ILocalizationService _localizationService; + public DictionaryMapperProfile(ILocalizationService localizationService) { - CreateMap() - .ForMember(dest => dest.Id, opt => opt.MapFrom(sheet => sheet.Id)) - .ForMember(dest => dest.Alias, opt => opt.MapFrom(sheet => sheet.ItemKey)) - .ForMember(dest => dest.Key, opt => opt.MapFrom(sheet => sheet.Key)) - .ForMember(dest => dest.Name, opt => opt.MapFrom(sheet => sheet.ItemKey)) - .ForMember(dest => dest.ParentId, opt => opt.Ignore()) - .ForMember(dest => dest.Path, opt => opt.Ignore()) - .ForMember(dest => dest.Trashed, opt => opt.Ignore()) - .ForMember(dest => dest.AdditionalData, opt => opt.Ignore()) - .ForMember(dest => dest.Udi, opt => opt.Ignore()) - .ForMember(dest => dest.Icon, opt => opt.Ignore()); - - CreateMap() - .ForMember(x => x.Translations, expression => expression.Ignore()) - .ForMember(x => x.Notifications, expression => expression.Ignore()) - .ForMember(x => x.Icon, expression => expression.Ignore()) - .ForMember(x => x.Trashed, expression => expression.Ignore()) - .ForMember(x => x.Alias, expression => expression.Ignore()) - .ForMember(x => x.Path, expression => expression.Ignore()) - .ForMember(x => x.AdditionalData, expression => expression.Ignore()) - .ForMember( - x => x.Udi, - expression => expression.MapFrom( - content => Udi.Create(Constants.UdiEntityType.DictionaryItem, content.Key))).ForMember( - x => x.Name, - expression => expression.MapFrom(content => content.ItemKey)) - .AfterMap( - (src, dest) => - { - // build up the path to make it possible to set active item in tree - // TODO: check if there is a better way - if (src.ParentId.HasValue) - { - var ids = new List { -1 }; - - - var parentIds = new List(); - - this.GetParentId(src.ParentId.Value, localizationService, parentIds); - - parentIds.Reverse(); - - ids.AddRange(parentIds); - - ids.Add(src.Id); - - dest.Path = string.Join(",", ids); - } - else - { - dest.Path = "-1," + src.Id; - } - - // add all languages and the translations - foreach (var lang in localizationService.GetAllLanguages()) - { - var langId = lang.Id; - var translation = src.Translations.FirstOrDefault(x => x.LanguageId == langId); - - dest.Translations.Add(new DictionaryTranslationDisplay - { - IsoCode = lang.IsoCode, - DisplayName = lang.CultureInfo.DisplayName, - Translation = (translation != null) ? translation.Value : string.Empty, - LanguageId = lang.Id - }); - } - }); - - CreateMap() - .ForMember(dest => dest.Level, expression => expression.Ignore()) - .ForMember(dest => dest.Translations, expression => expression.Ignore()) - .ForMember( - x => x.Name, - expression => expression.MapFrom(content => content.ItemKey)) - .AfterMap( - (src, dest) => - { - // add all languages and the translations - foreach (var lang in localizationService.GetAllLanguages()) - { - var langId = lang.Id; - var translation = src.Translations.FirstOrDefault(x => x.LanguageId == langId); - - dest.Translations.Add( - new DictionaryOverviewTranslationDisplay - { - DisplayName = lang.CultureInfo.DisplayName, - HasTranslation = translation != null && string.IsNullOrEmpty(translation.Value) == false - }); - } - }); + _localizationService = localizationService; } - /// - /// Goes up the dictionary tree to get all parent ids - /// - /// - /// The parent id. - /// - /// - /// The localization service. - /// - /// - /// The ids. - /// - private void GetParentId(Guid parentId, ILocalizationService localizationService, List ids) + public void SetMaps(Mapper mapper) + { + mapper.Define(source => new EntityBasic(), Map); + mapper.Define(source => new DictionaryDisplay(), Map); + } + + // Umbraco.Code.MapAll -ParentId -Path -Trashed -Udi -Icon + private static void Map(IDictionaryItem source, EntityBasic target) + { + target.Alias = source.ItemKey; + target.Id = source.Id; + target.Key = source.Key; + target.Name = source.ItemKey; + } + + // Umbraco.Code.MapAll -Icon -Trashed -Alias + private void Map(IDictionaryItem source, DictionaryDisplay target) + { + target.Id = source.Id; + target.Key = source.Key; + target.Name = source.ItemKey; + target.ParentId = source.ParentId ?? Guid.Empty; + target.Udi = Udi.Create(Constants.UdiEntityType.DictionaryItem, source.Key); + + // build up the path to make it possible to set active item in tree + // TODO: check if there is a better way + if (source.ParentId.HasValue) + { + var ids = new List { -1 }; + var parentIds = new List(); + GetParentId(source.ParentId.Value, _localizationService, parentIds); + parentIds.Reverse(); + ids.AddRange(parentIds); + ids.Add(source.Id); + target.Path = string.Join(",", ids); + } + else + { + target.Path = "-1," + source.Id; + } + + // add all languages and the translations + foreach (var lang in _localizationService.GetAllLanguages()) + { + var langId = lang.Id; + var translation = source.Translations.FirstOrDefault(x => x.LanguageId == langId); + + target.Translations.Add(new DictionaryTranslationDisplay + { + IsoCode = lang.IsoCode, + DisplayName = lang.CultureInfo.DisplayName, + Translation = (translation != null) ? translation.Value : string.Empty, + LanguageId = lang.Id + }); + } + } + + // Umbraco.Code.MapAll -Level -Translations + private void Map(IDictionaryItem source, DictionaryOverviewDisplay target) + { + target.Id = source.Id; + target.Name = source.ItemKey; + + // add all languages and the translations + foreach (var lang in _localizationService.GetAllLanguages()) + { + var langId = lang.Id; + var translation = source.Translations.FirstOrDefault(x => x.LanguageId == langId); + + target.Translations.Add( + new DictionaryOverviewTranslationDisplay + { + DisplayName = lang.CultureInfo.DisplayName, + HasTranslation = translation != null && string.IsNullOrEmpty(translation.Value) == false + }); + } + } + + private static void GetParentId(Guid parentId, ILocalizationService localizationService, List ids) { var dictionary = localizationService.GetDictionaryItemById(parentId); - if (dictionary == null) return; diff --git a/src/Umbraco.Web/Models/Mapping/LanguageMapperProfile.cs b/src/Umbraco.Web/Models/Mapping/LanguageMapperProfile.cs index 83bf3d2491..8d45a84f32 100644 --- a/src/Umbraco.Web/Models/Mapping/LanguageMapperProfile.cs +++ b/src/Umbraco.Web/Models/Mapping/LanguageMapperProfile.cs @@ -12,9 +12,9 @@ namespace Umbraco.Web.Models.Mapping { public void SetMaps(Mapper mapper) { - mapper.SetMap(source => new EntityBasic(), Map); - mapper.SetMap(source => new Language(), Map); - mapper.SetMap, IEnumerable>(source => new List(), (source, target) => Map(source, target, mapper)); + mapper.Define(source => new EntityBasic(), Map); + mapper.Define(source => new Language(), Map); + mapper.Define, IEnumerable>(source => new List(), (source, target) => Map(source, target, mapper)); } // Umbraco.Code.MapAll -Udi -Path -Trashed -AdditionalData -Icon diff --git a/src/Umbraco.Web/Models/Mapping/MacroMapperProfile.cs b/src/Umbraco.Web/Models/Mapping/MacroMapperProfile.cs index a507cc4c03..ccb9aa3eef 100644 --- a/src/Umbraco.Web/Models/Mapping/MacroMapperProfile.cs +++ b/src/Umbraco.Web/Models/Mapping/MacroMapperProfile.cs @@ -1,60 +1,73 @@ using System.Collections.Generic; using System.Linq; -using AutoMapper; using Umbraco.Core; using Umbraco.Core.Logging; +using Umbraco.Core.Mapping; using Umbraco.Core.Models; +using Umbraco.Core.PropertyEditors; using Umbraco.Web.Composing; using Umbraco.Web.Models.ContentEditing; namespace Umbraco.Web.Models.Mapping { - /// - /// Declares model mappings for macros. - /// - internal class MacroMapperProfile : Profile + internal class MacroMapperProfile : IMapperProfile { - public MacroMapperProfile() + private readonly ParameterEditorCollection _parameterEditors; + private readonly ILogger _logger; + + public MacroMapperProfile(ParameterEditorCollection parameterEditors, ILogger logger) { - //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.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()); + _parameterEditors = parameterEditors; + _logger = logger; + } - CreateMap>() - .ConvertUsing(macro => macro.Properties.Values.Select(Mapper.Map).ToList()); + public void SetMaps(Mapper mapper) + { + mapper.Define(source => new EntityBasic(), Map); + mapper.Define>(source => source.Properties.Values.Select(mapper.Map).ToList()); + mapper.Define(source => new MacroParameter(), Map); + } - CreateMap() - .ForMember(x => x.View, expression => expression.Ignore()) - .ForMember(x => x.Configuration, expression => expression.Ignore()) - .ForMember(x => x.Value, expression => expression.Ignore()) - .AfterMap((property, parameter) => - { - //map the view and the config - // we need to show the deprecated ones for backwards compatibility - var paramEditor = Current.ParameterEditors[property.EditorAlias]; // TODO: include/filter deprecated?! - if (paramEditor == null) - { - //we'll just map this to a text box - paramEditor = Current.ParameterEditors[Constants.PropertyEditors.Aliases.TextBox]; - Current.Logger.Warn("Could not resolve a parameter editor with alias {PropertyEditorAlias}, a textbox will be rendered in it's place", property.EditorAlias); - } + // Umbraco.Code.MapAll -Trashed -AdditionalData + private static void Map(IMacro source, EntityBasic target) + { + target.Alias = source.Alias; + target.Icon = "icon-settings-alt"; + target.Id = source.Id; + target.Key = source.Key; + target.Name = source.Name; + target.ParentId = -1; + target.Path = "-1," + source.Id; + target.Udi = Udi.Create(Constants.UdiEntityType.Macro, source.Key); + } - parameter.View = paramEditor.GetValueEditor().View; + // Umbraco.Code.MapAll -Value + private void Map(IMacroProperty source, MacroParameter target) + { + target.Alias = source.Alias; + target.Name = source.Name; + target.SortOrder = source.SortOrder; - // sets the parameter configuration to be the default configuration editor's configuration, - // ie configurationEditor.DefaultConfigurationObject, prepared for the value editor, ie - // after ToValueEditor - important to use DefaultConfigurationObject here, because depending - // on editors, ToValueEditor expects the actual strongly typed configuration - not the - // dictionary thing returned by DefaultConfiguration + //map the view and the config + // we need to show the deprecated ones for backwards compatibility + var paramEditor = _parameterEditors[source.EditorAlias]; // TODO: include/filter deprecated?! + if (paramEditor == null) + { + //we'll just map this to a text box + paramEditor = _parameterEditors[Constants.PropertyEditors.Aliases.TextBox]; + _logger.Warn("Could not resolve a parameter editor with alias {PropertyEditorAlias}, a textbox will be rendered in it's place", source.EditorAlias); + } - var configurationEditor = paramEditor.GetConfigurationEditor(); - parameter.Configuration = configurationEditor.ToValueEditor(configurationEditor.DefaultConfigurationObject); - }); + target.View = paramEditor.GetValueEditor().View; + + // sets the parameter configuration to be the default configuration editor's configuration, + // ie configurationEditor.DefaultConfigurationObject, prepared for the value editor, ie + // after ToValueEditor - important to use DefaultConfigurationObject here, because depending + // on editors, ToValueEditor expects the actual strongly typed configuration - not the + // dictionary thing returned by DefaultConfiguration + + var configurationEditor = paramEditor.GetConfigurationEditor(); + target.Configuration = configurationEditor.ToValueEditor(configurationEditor.DefaultConfigurationObject); } } } diff --git a/src/Umbraco.Web/Models/Mapping/RedirectUrlMapperProfile.cs b/src/Umbraco.Web/Models/Mapping/RedirectUrlMapperProfile.cs index fabcf63163..741584a9ac 100644 --- a/src/Umbraco.Web/Models/Mapping/RedirectUrlMapperProfile.cs +++ b/src/Umbraco.Web/Models/Mapping/RedirectUrlMapperProfile.cs @@ -17,7 +17,7 @@ namespace Umbraco.Web.Models.Mapping public void SetMaps(Mapper mapper) { - mapper.SetMap(source => new ContentRedirectUrl(), Map); + mapper.Define(source => new ContentRedirectUrl(), Map); } // Umbraco.Code.MapAll diff --git a/src/Umbraco.Web/Models/Mapping/RelationMapperProfile.cs b/src/Umbraco.Web/Models/Mapping/RelationMapperProfile.cs index 3a0a19b536..3f2c2f8711 100644 --- a/src/Umbraco.Web/Models/Mapping/RelationMapperProfile.cs +++ b/src/Umbraco.Web/Models/Mapping/RelationMapperProfile.cs @@ -9,9 +9,9 @@ namespace Umbraco.Web.Models.Mapping { public void SetMaps(Mapper mapper) { - mapper.SetMap(source => new RelationTypeDisplay(), Map); - mapper.SetMap(source => new RelationDisplay(), Map); - mapper.SetMap(Map); + mapper.Define(source => new RelationTypeDisplay(), Map); + mapper.Define(source => new RelationDisplay(), Map); + mapper.Define(Map); } // Umbraco.Code.MapAll -Icon -Trashed -Alias -AdditionalData diff --git a/src/Umbraco.Web/Models/Mapping/SectionMapperProfile.cs b/src/Umbraco.Web/Models/Mapping/SectionMapperProfile.cs index 47f32b63e6..51faed3552 100644 --- a/src/Umbraco.Web/Models/Mapping/SectionMapperProfile.cs +++ b/src/Umbraco.Web/Models/Mapping/SectionMapperProfile.cs @@ -17,18 +17,18 @@ namespace Umbraco.Web.Models.Mapping public void SetMaps(Mapper mapper) { - mapper.SetMap(source => new Section(), Map); + mapper.Define(source => new Section(), Map); // this is for AutoMapper ReverseMap - but really? - mapper.SetMap(); - mapper.SetMap(); - mapper.SetMap(Map); - mapper.SetMap(); - mapper.SetMap(); - mapper.SetMap(); - mapper.SetMap(); - mapper.SetMap(); - mapper.SetMap(); + mapper.Define(); + mapper.Define(); + mapper.Define(Map); + mapper.Define(); + mapper.Define(); + mapper.Define(); + mapper.Define(); + mapper.Define(); + mapper.Define(); } // Umbraco.Code.MapAll -RoutePath diff --git a/src/Umbraco.Web/Models/Mapping/TagMapperProfile.cs b/src/Umbraco.Web/Models/Mapping/TagMapperProfile.cs index 723b0b3fc8..7099400f9a 100644 --- a/src/Umbraco.Web/Models/Mapping/TagMapperProfile.cs +++ b/src/Umbraco.Web/Models/Mapping/TagMapperProfile.cs @@ -7,7 +7,7 @@ namespace Umbraco.Web.Models.Mapping { public void SetMaps(Mapper mapper) { - mapper.SetMap(source => new TagModel(), Map); + mapper.Define(source => new TagModel(), Map); } // Umbraco.Code.MapAll diff --git a/src/Umbraco.Web/Models/Mapping/TemplateMapperProfile.cs b/src/Umbraco.Web/Models/Mapping/TemplateMapperProfile.cs index 1b4e84387c..fa6f9ceb53 100644 --- a/src/Umbraco.Web/Models/Mapping/TemplateMapperProfile.cs +++ b/src/Umbraco.Web/Models/Mapping/TemplateMapperProfile.cs @@ -8,8 +8,8 @@ namespace Umbraco.Web.Models.Mapping { public void SetMaps(Mapper mapper) { - mapper.SetMap(source => new TemplateDisplay(), Map); - mapper.SetMap(source => new Template(source.Name, source.Alias), Map); + mapper.Define(source => new TemplateDisplay(), Map); + mapper.Define(source => new Template(source.Name, source.Alias), Map); } // Umbraco.Code.MapAll diff --git a/src/Umbraco.Web/Models/Mapping/UserMapperProfile.cs b/src/Umbraco.Web/Models/Mapping/UserMapperProfile.cs index 4ec9525c19..f4e2342f90 100644 --- a/src/Umbraco.Web/Models/Mapping/UserMapperProfile.cs +++ b/src/Umbraco.Web/Models/Mapping/UserMapperProfile.cs @@ -40,23 +40,23 @@ namespace Umbraco.Web.Models.Mapping public void SetMaps(Mapper mapper) { - mapper.SetMap(source => new UserGroup { CreateDate = DateTime.UtcNow }, Map); - mapper.SetMap(Map); - mapper.SetMap(Map); - mapper.SetMap(source => new UserGroupBasic(), (source, target) => Map(source, target, mapper)); - mapper.SetMap(source => new UserGroupBasic(), (source, target) => Map(source, target, mapper)); - mapper.SetMap(source => new AssignedUserGroupPermissions(), Map); - mapper.SetMap(source => new AssignedContentPermissions(), Map); - mapper.SetMap(source => new UserGroupDisplay(), (source, target) => Map(source, target, mapper)); - mapper.SetMap(source => new UserBasic(), (source, target) => Map(source, target, mapper)); - mapper.SetMap(source => new UserDetail(), Map); + mapper.Define(source => new UserGroup { CreateDate = DateTime.UtcNow }, Map); + mapper.Define(Map); + mapper.Define(Map); + mapper.Define(source => new UserGroupBasic(), (source, target) => Map(source, target, mapper)); + mapper.Define(source => new UserGroupBasic(), (source, target) => Map(source, target, mapper)); + mapper.Define(source => new AssignedUserGroupPermissions(), Map); + mapper.Define(source => new AssignedContentPermissions(), Map); + mapper.Define(source => new UserGroupDisplay(), (source, target) => Map(source, target, mapper)); + mapper.Define(source => new UserBasic(), (source, target) => Map(source, target, mapper)); + mapper.Define(source => new UserDetail(), Map); // used for merging existing UserSave to an existing IUser instance - this will not create an IUser instance! - mapper.SetMap(Map); + mapper.Define(Map); // important! Currently we are never mapping to multiple UserDisplay objects but if we start doing that // this will cause an N+1 and we'll need to change how this works. - mapper.SetMap(source => new UserDisplay(), (source, target) => Map(source, target, mapper)); + mapper.Define(source => new UserDisplay(), (source, target) => Map(source, target, mapper)); } // mappers diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index cf1a98fefb..0ac89dfe82 100755 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -856,11 +856,8 @@ - - -