Refactor more mappers

This commit is contained in:
Stephan
2019-03-25 09:03:46 +01:00
parent 5bcafba34c
commit 92139dd0c9
20 changed files with 363 additions and 417 deletions

View File

@@ -25,16 +25,16 @@ namespace Umbraco.Core.Mapping
profile.SetMaps(this);
}
public void SetMap<TSource, TTarget>()
=> SetMap<TSource, TTarget>((source, target) => { });
public void Define<TSource, TTarget>()
=> Define<TSource, TTarget>((source, target) => { });
public void SetMap<TSource, TTarget>(Action<TSource, TTarget> map)
=> SetMap(source => throw new NotSupportedException($"Don't know how to create {typeof(TTarget)} instances."), map);
public void Define<TSource, TTarget>(Action<TSource, TTarget> map)
=> Define(source => throw new NotSupportedException($"Don't know how to create {typeof(TTarget)} instances."), map);
public void SetMap<TSource, TTarget>(Func<TSource, TTarget> ctor)
=> SetMap(ctor, (source, target) => { });
public void Define<TSource, TTarget>(Func<TSource, TTarget> ctor)
=> Define(ctor, (source, target) => { });
public void SetMap<TSource, TTarget>(Func<TSource, TTarget> ctor, Action<TSource, TTarget> map)
public void Define<TSource, TTarget>(Func<TSource, TTarget> ctor, Action<TSource, TTarget> map)
{
var sourceType = typeof(TSource);
var targetType = typeof(TTarget);

View File

@@ -21,7 +21,7 @@ namespace Umbraco.Core.Models.Identity
public void SetMaps(Mapper mapper)
{
mapper.SetMap<IUser, BackOfficeIdentityUser>(
mapper.Define<IUser, BackOfficeIdentityUser>(
source =>
{
var target = new BackOfficeIdentityUser(source.Id, source.Groups);

View File

@@ -79,7 +79,7 @@ namespace Umbraco.Tests.Mapping
{
public void SetMaps(Mapper mapper)
{
mapper.SetMap<Thing1, Thing2>(source => new Thing2(), (source, target) => Map(source, target));
mapper.Define<Thing1, Thing2>(source => new Thing2(), (source, target) => Map(source, target));
}
private Thing2 Map(Thing1 source, Thing2 target)

View File

@@ -17,6 +17,9 @@ namespace Umbraco.Web.Composing.CompositionExtensions
composition.WithCollectionBuilder<MapperProfileCollectionBuilder>()
.Append<AuditMapperProfile>()
.Append<CodeFileMapperProfile>()
.Append<DataTypeMapperProfile>()
.Append<DictionaryMapperProfile>()
.Append<MacroMapperProfile>()
.Append<RedirectUrlMapperProfile>()
.Append<RelationMapperProfile>()
.Append<SectionMapperProfile>()
@@ -31,10 +34,10 @@ namespace Umbraco.Web.Composing.CompositionExtensions
composition.Register<Profile, ContentMapperProfile>();
composition.Register<Profile, ContentPropertyMapperProfile>();
composition.Register<Profile, ContentTypeMapperProfile>();
composition.Register<Profile, DataTypeMapperProfile>();
//composition.Register<Profile, DataTypeMapperProfile>();
composition.Register<Profile, EntityMapperProfile>();
composition.Register<Profile, DictionaryMapperProfile>();
composition.Register<Profile, MacroMapperProfile>();
//composition.Register<Profile, DictionaryMapperProfile>();
//composition.Register<Profile, MacroMapperProfile>();
composition.Register<Profile, MediaMapperProfile>();
composition.Register<Profile, MemberMapperProfile>();
//composition.Register<Profile, RedirectUrlMapperProfile>();

View File

@@ -8,7 +8,7 @@ namespace Umbraco.Web.Models.Mapping
{
public void SetMaps(Mapper mapper)
{
mapper.SetMap<IAuditItem, AuditLog>(source => new AuditLog(), (source, target) => Map(source, target));
mapper.Define<IAuditItem, AuditLog>(source => new AuditLog(), (source, target) => Map(source, target));
}
// Umbraco.Code.MapAll -UserAvatars -UserName

View File

@@ -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<PropertyEditorBasic> Resolve(IDataType source)
{
return Current.PropertyEditors
.Where(x => !x.IsDeprecated || _contentSection.ShowDeprecatedPropertyEditors || source.EditorAlias == x.Alias)
.OrderBy(x => x.Name)
.Select(Mapper.Map<PropertyEditorBasic>);
}
}
}

View File

@@ -9,12 +9,12 @@ namespace Umbraco.Web.Models.Mapping
{
public void SetMaps(Mapper mapper)
{
mapper.SetMap<Stylesheet, EntityBasic>(source => new EntityBasic(), Map);
mapper.SetMap<IPartialView, CodeFileDisplay>(source => new CodeFileDisplay(), Map);
mapper.SetMap<Script, CodeFileDisplay>(source => new CodeFileDisplay(), Map);
mapper.SetMap<Stylesheet, CodeFileDisplay>(source => new CodeFileDisplay(), Map);
mapper.SetMap<CodeFileDisplay, IPartialView>(Map);
mapper.SetMap<CodeFileDisplay, Script>(Map);
mapper.Define<Stylesheet, EntityBasic>(source => new EntityBasic(), Map);
mapper.Define<IPartialView, CodeFileDisplay>(source => new CodeFileDisplay(), Map);
mapper.Define<Script, CodeFileDisplay>(source => new CodeFileDisplay(), Map);
mapper.Define<Stylesheet, CodeFileDisplay>(source => new CodeFileDisplay(), Map);
mapper.Define<CodeFileDisplay, IPartialView>(Map);
mapper.Define<CodeFileDisplay, Script>(Map);
}

View File

@@ -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));
}
/// <summary>
/// Maps pre-values in the dictionary to the values for the fields
/// </summary>
internal static void MapConfigurationFields(ILogger logger, DataTypeConfigurationFieldDisplay[] fields, IDictionary<string, object> 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<DataTypeConfigurationFieldDisplayResolver>("Could not find a value for configuration field '{ConfigField}'", field.Key);
}
}
}
/// <summary>
/// Creates a set of configuration fields for a data type.
/// </summary>
public IEnumerable<DataTypeConfigurationFieldDisplay> 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<DataTypeConfigurationFieldDisplay>).ToArray();
var configurationDictionary = configurationEditor.ToConfigurationEditor(dataType.Configuration);
MapConfigurationFields(_logger, fields, configurationDictionary);
return fields;
}
}
}

View File

@@ -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
{
/// <summary>
/// Configures model mappings for datatypes.
/// </summary>
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<IDataEditor, PropertyEditorBasic>();
private static readonly int[] SystemIds =
{
Constants.DataTypes.DefaultContentListView,
Constants.DataTypes.DefaultMediaListView,
Constants.DataTypes.DefaultMembersListView
};
// map the standard properties, not the values
CreateMap<ConfigurationField, DataTypeConfigurationFieldDisplay>()
.ForMember(dest => dest.Value, opt => opt.Ignore());
public void SetMaps(Mapper mapper)
{
mapper.Define<IDataEditor, PropertyEditorBasic>(source => new PropertyEditorBasic(), Map);
mapper.Define<ConfigurationField, DataTypeConfigurationFieldDisplay>(source => new DataTypeConfigurationFieldDisplay(), Map);
mapper.Define<IDataEditor, DataTypeBasic>(source => new DataTypeBasic(), Map);
mapper.Define<IDataType, DataTypeBasic>(source => new DataTypeBasic(), Map);
mapper.Define<IDataType, DataTypeDisplay>(source => new DataTypeDisplay(), (source, target) => Map(source, target, mapper));
mapper.Define<IDataType, IEnumerable<DataTypeConfigurationFieldDisplay>>(source => MapPreValues(source, mapper));
mapper.Define<DataTypeSave, IDataType>(Map);
mapper.Define<IDataEditor, IEnumerable<DataTypeConfigurationFieldDisplay>>(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<PropertyEditorBasic> 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<PropertyEditorBasic>);
}
private IEnumerable<DataTypeConfigurationFieldDisplay> 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<DataTypeConfigurationFieldDisplay>).ToArray();
var configurationDictionary = configurationEditor.ToConfigurationEditor(dataType.Configuration);
MapConfigurationFields(fields, configurationDictionary);
return fields;
}
private void MapConfigurationFields(DataTypeConfigurationFieldDisplay[] fields, IDictionary<string, object> 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<IDataEditor, DataTypeBasic>()
.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<IDataType, DataTypeBasic>()
.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<IDataType, DataTypeDisplay>()
.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<DataTypeMapperProfile>("Could not find a value for configuration field '{ConfigField}'", field.Key);
}
}
}
//gets a list of PreValueFieldDisplay objects from the data type definition
CreateMap<IDataType, IEnumerable<DataTypeConfigurationFieldDisplay>>()
.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<DataTypeSave, IDataType>()
.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<IDataEditor, IEnumerable<DataTypeConfigurationFieldDisplay>>()
.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<DataTypeConfigurationFieldDisplay> 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<DataTypeConfigurationFieldDisplay>).ToArray();
var fields = configurationEditor.Fields.Select(mapper.Map<DataTypeConfigurationFieldDisplay>).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;
}
}
}

View File

@@ -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
{
/// <summary>
/// Gets the DataTypeDatabaseType from the selected property editor for the data type
/// </summary>
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);
}
}
}

View File

@@ -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
/// <summary>
/// The dictionary model mapper.
/// </summary>
internal class DictionaryMapperProfile : Profile
internal class DictionaryMapperProfile : IMapperProfile
{
private readonly ILocalizationService _localizationService;
public DictionaryMapperProfile(ILocalizationService localizationService)
{
CreateMap<IDictionaryItem, EntityBasic>()
.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<IDictionaryItem, DictionaryDisplay>()
.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<int> { -1 };
var parentIds = new List<int>();
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<IDictionaryItem, DictionaryOverviewDisplay>()
.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;
}
/// <summary>
/// Goes up the dictionary tree to get all parent ids
/// </summary>
/// <param name="parentId">
/// The parent id.
/// </param>
/// <param name="localizationService">
/// The localization service.
/// </param>
/// <param name="ids">
/// The ids.
/// </param>
private void GetParentId(Guid parentId, ILocalizationService localizationService, List<int> ids)
public void SetMaps(Mapper mapper)
{
mapper.Define<IDictionaryItem, EntityBasic>(source => new EntityBasic(), Map);
mapper.Define<IDictionaryItem, DictionaryDisplay>(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<int> { -1 };
var parentIds = new List<int>();
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<int> ids)
{
var dictionary = localizationService.GetDictionaryItemById(parentId);
if (dictionary == null)
return;

View File

@@ -12,9 +12,9 @@ namespace Umbraco.Web.Models.Mapping
{
public void SetMaps(Mapper mapper)
{
mapper.SetMap<ILanguage, EntityBasic>(source => new EntityBasic(), Map);
mapper.SetMap<ILanguage, Language>(source => new Language(), Map);
mapper.SetMap<IEnumerable<ILanguage>, IEnumerable<Language>>(source => new List<Language>(), (source, target) => Map(source, target, mapper));
mapper.Define<ILanguage, EntityBasic>(source => new EntityBasic(), Map);
mapper.Define<ILanguage, Language>(source => new Language(), Map);
mapper.Define<IEnumerable<ILanguage>, IEnumerable<Language>>(source => new List<Language>(), (source, target) => Map(source, target, mapper));
}
// Umbraco.Code.MapAll -Udi -Path -Trashed -AdditionalData -Icon

View File

@@ -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
{
/// <summary>
/// Declares model mappings for macros.
/// </summary>
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<IMacro, EntityBasic>()
.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<IMacro, IEnumerable<MacroParameter>>()
.ConvertUsing(macro => macro.Properties.Values.Select(Mapper.Map<MacroParameter>).ToList());
public void SetMaps(Mapper mapper)
{
mapper.Define<IMacro, EntityBasic>(source => new EntityBasic(), Map);
mapper.Define<IMacro, IEnumerable<MacroParameter>>(source => source.Properties.Values.Select(mapper.Map<MacroParameter>).ToList());
mapper.Define<IMacroProperty, MacroParameter>(source => new MacroParameter(), Map);
}
CreateMap<IMacroProperty, MacroParameter>()
.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<MacroMapperProfile>("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<MacroMapperProfile>("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);
}
}
}

View File

@@ -17,7 +17,7 @@ namespace Umbraco.Web.Models.Mapping
public void SetMaps(Mapper mapper)
{
mapper.SetMap<IRedirectUrl, ContentRedirectUrl>(source => new ContentRedirectUrl(), Map);
mapper.Define<IRedirectUrl, ContentRedirectUrl>(source => new ContentRedirectUrl(), Map);
}
// Umbraco.Code.MapAll

View File

@@ -9,9 +9,9 @@ namespace Umbraco.Web.Models.Mapping
{
public void SetMaps(Mapper mapper)
{
mapper.SetMap<IRelationType, RelationTypeDisplay>(source => new RelationTypeDisplay(), Map);
mapper.SetMap<IRelation, RelationDisplay>(source => new RelationDisplay(), Map);
mapper.SetMap<RelationTypeSave, IRelationType>(Map);
mapper.Define<IRelationType, RelationTypeDisplay>(source => new RelationTypeDisplay(), Map);
mapper.Define<IRelation, RelationDisplay>(source => new RelationDisplay(), Map);
mapper.Define<RelationTypeSave, IRelationType>(Map);
}
// Umbraco.Code.MapAll -Icon -Trashed -Alias -AdditionalData

View File

@@ -17,18 +17,18 @@ namespace Umbraco.Web.Models.Mapping
public void SetMaps(Mapper mapper)
{
mapper.SetMap<ISection, Section>(source => new Section(), Map);
mapper.Define<ISection, Section>(source => new Section(), Map);
// this is for AutoMapper ReverseMap - but really?
mapper.SetMap<Section, ContentSection>();
mapper.SetMap<Section, ContentSection>();
mapper.SetMap<Section, ManifestSection>(Map);
mapper.SetMap<Section, MediaSection>();
mapper.SetMap<Section, MembersSection>();
mapper.SetMap<Section, PackagesSection>();
mapper.SetMap<Section, SettingsSection>();
mapper.SetMap<Section, TranslationSection>();
mapper.SetMap<Section, UsersSection>();
mapper.Define<Section, ContentSection>();
mapper.Define<Section, ContentSection>();
mapper.Define<Section, ManifestSection>(Map);
mapper.Define<Section, MediaSection>();
mapper.Define<Section, MembersSection>();
mapper.Define<Section, PackagesSection>();
mapper.Define<Section, SettingsSection>();
mapper.Define<Section, TranslationSection>();
mapper.Define<Section, UsersSection>();
}
// Umbraco.Code.MapAll -RoutePath

View File

@@ -7,7 +7,7 @@ namespace Umbraco.Web.Models.Mapping
{
public void SetMaps(Mapper mapper)
{
mapper.SetMap<ITag, TagModel>(source => new TagModel(), Map);
mapper.Define<ITag, TagModel>(source => new TagModel(), Map);
}
// Umbraco.Code.MapAll

View File

@@ -8,8 +8,8 @@ namespace Umbraco.Web.Models.Mapping
{
public void SetMaps(Mapper mapper)
{
mapper.SetMap<ITemplate, TemplateDisplay>(source => new TemplateDisplay(), Map);
mapper.SetMap<TemplateDisplay, Template>(source => new Template(source.Name, source.Alias), Map);
mapper.Define<ITemplate, TemplateDisplay>(source => new TemplateDisplay(), Map);
mapper.Define<TemplateDisplay, Template>(source => new Template(source.Name, source.Alias), Map);
}
// Umbraco.Code.MapAll

View File

@@ -40,23 +40,23 @@ namespace Umbraco.Web.Models.Mapping
public void SetMaps(Mapper mapper)
{
mapper.SetMap<UserGroupSave, IUserGroup>(source => new UserGroup { CreateDate = DateTime.UtcNow }, Map);
mapper.SetMap<UserInvite, IUser>(Map);
mapper.SetMap<IProfile, ContentEditing.UserProfile>(Map);
mapper.SetMap<IReadOnlyUserGroup, UserGroupBasic>(source => new UserGroupBasic(), (source, target) => Map(source, target, mapper));
mapper.SetMap<IUserGroup, UserGroupBasic>(source => new UserGroupBasic(), (source, target) => Map(source, target, mapper));
mapper.SetMap<IUserGroup, AssignedUserGroupPermissions>(source => new AssignedUserGroupPermissions(), Map);
mapper.SetMap<EntitySlim, AssignedContentPermissions>(source => new AssignedContentPermissions(), Map);
mapper.SetMap<IUserGroup, UserGroupDisplay>(source => new UserGroupDisplay(), (source, target) => Map(source, target, mapper));
mapper.SetMap<IUser, UserBasic>(source => new UserBasic(), (source, target) => Map(source, target, mapper));
mapper.SetMap<IUser, UserDetail>(source => new UserDetail(), Map);
mapper.Define<UserGroupSave, IUserGroup>(source => new UserGroup { CreateDate = DateTime.UtcNow }, Map);
mapper.Define<UserInvite, IUser>(Map);
mapper.Define<IProfile, ContentEditing.UserProfile>(Map);
mapper.Define<IReadOnlyUserGroup, UserGroupBasic>(source => new UserGroupBasic(), (source, target) => Map(source, target, mapper));
mapper.Define<IUserGroup, UserGroupBasic>(source => new UserGroupBasic(), (source, target) => Map(source, target, mapper));
mapper.Define<IUserGroup, AssignedUserGroupPermissions>(source => new AssignedUserGroupPermissions(), Map);
mapper.Define<EntitySlim, AssignedContentPermissions>(source => new AssignedContentPermissions(), Map);
mapper.Define<IUserGroup, UserGroupDisplay>(source => new UserGroupDisplay(), (source, target) => Map(source, target, mapper));
mapper.Define<IUser, UserBasic>(source => new UserBasic(), (source, target) => Map(source, target, mapper));
mapper.Define<IUser, UserDetail>(source => new UserDetail(), Map);
// used for merging existing UserSave to an existing IUser instance - this will not create an IUser instance!
mapper.SetMap<UserSave, IUser>(Map);
mapper.Define<UserSave, IUser>(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<IUser, UserDisplay>(source => new UserDisplay(), (source, target) => Map(source, target, mapper));
mapper.Define<IUser, UserDisplay>(source => new UserDisplay(), (source, target) => Map(source, target, mapper));
}
// mappers

View File

@@ -856,11 +856,8 @@
<Compile Include="Models\ContentEditing\DataTypeConfigurationFieldDisplay.cs" />
<Compile Include="Models\ContentEditing\DataTypeConfigurationFieldSave.cs" />
<Compile Include="Models\ContentEditing\PropertyEditorBasic.cs" />
<Compile Include="Models\Mapping\AvailablePropertyEditorsResolver.cs" />
<Compile Include="Models\Mapping\DatabaseTypeResolver.cs" />
<Compile Include="Models\Mapping\DataTypeMapperProfile.cs" />
<Compile Include="Models\Mapping\EntityMapperProfile.cs" />
<Compile Include="Models\Mapping\DataTypeConfigurationFieldDisplayResolver.cs" />
<Compile Include="PropertyEditors\CheckBoxListPropertyEditor.cs" />
<Compile Include="PropertyEditors\ColorPickerPropertyEditor.cs" />
<Compile Include="PropertyEditors\DateTimePropertyEditor.cs" />