diff --git a/build/NuSpecs/UmbracoCms.Core.nuspec b/build/NuSpecs/UmbracoCms.Core.nuspec index b257f8dcdd..fead7a0cce 100644 --- a/build/NuSpecs/UmbracoCms.Core.nuspec +++ b/build/NuSpecs/UmbracoCms.Core.nuspec @@ -22,7 +22,6 @@ the latter would pick anything below 3.0.0 and that includes prereleases such as 3.0.0-alpha, and we do not want this to happen as the alpha of the next major is, really, the next major already. --> - diff --git a/src/Umbraco.Core/BindingRedirects.cs b/src/Umbraco.Core/BindingRedirects.cs index 17e187b7ae..fc50b73a17 100644 --- a/src/Umbraco.Core/BindingRedirects.cs +++ b/src/Umbraco.Core/BindingRedirects.cs @@ -27,11 +27,14 @@ namespace Umbraco.Core /// private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args) { + // keep here for reference - we don't use AutoMapper + /* //AutoMapper: // ensure the assembly is indeed AutoMapper and that the PublicKeyToken is null before trying to Load again // do NOT just replace this with 'return Assembly', as it will cause an infinite loop -> stackoverflow if (args.Name.StartsWith("AutoMapper") && args.Name.EndsWith("PublicKeyToken=null")) return Assembly.Load(args.Name.Replace(", PublicKeyToken=null", ", PublicKeyToken=be96cd2c38ef1005")); + */ return null; diff --git a/src/Umbraco.Core/Mapping/Mapper.cs b/src/Umbraco.Core/Mapping/Mapper.cs index 36c7462d8b..377575fed6 100644 --- a/src/Umbraco.Core/Mapping/Mapper.cs +++ b/src/Umbraco.Core/Mapping/Mapper.cs @@ -1,19 +1,11 @@ using System; -using System.CodeDom; using System.Collections; using System.Collections.Generic; using System.Linq; namespace Umbraco.Core.Mapping { - // FIXME we should inject the mapper - // FIXME in order to transition, this should also handle AutoMapper? - // FIXME we might have to manage a 'context' for some contextual mappings? - // FIXME we have an infinite loop problem w/ logging in due to mapping issues - // FIXME refactor - // ctor: (source, context) => - // map: (source, target, context) => - // and context.Mapper is mapper + // FIXME needs documentation and cleanup! public class Mapper { @@ -31,21 +23,12 @@ namespace Umbraco.Core.Mapping #region Define - //public void Define() - // => Define((source, target) => { }); - public void Define() => Define((source, target, context) => { }); - //public void Define(Action map) - // => Define(source => throw new NotSupportedException($"Don't know how to create {typeof(TTarget)} instances."), map); - public void Define(Action map) => Define((source, context) => throw new NotSupportedException($"Don't know how to create {typeof(TTarget)} instances."), map); - //public void Define(Func ctor) - // => Define(ctor, (source, target) => { }); - public void Define(Func ctor) => Define(ctor, (source, target, context) => { }); @@ -63,42 +46,6 @@ namespace Umbraco.Core.Mapping return sourceMap; } - //public void Define(Func ctor, Action map) - //{ - // var sourceType = typeof(TSource); - // var targetType = typeof(TTarget); - - // var sourceCtors = DefineCtors(sourceType); - // sourceCtors[targetType] = (source, context) => ctor((TSource) source); - - // var sourceMaps = DefineMaps(sourceType); - // sourceMaps[targetType] = (source, target, context) => map((TSource) source, (TTarget) target); - //} - - //public void Define(Func ctor, Action map) - //{ - // var sourceType = typeof(TSource); - // var targetType = typeof(TTarget); - - // var sourceCtors = DefineCtors(sourceType); - // sourceCtors[targetType] = (source, context) => ctor((TSource)source); - - // var sourceMaps = DefineMaps(sourceType); - // sourceMaps[targetType] = (source, target, context) => map((TSource)source, (TTarget)target, context); - //} - - //public void Define(Func ctor, Action map) - //{ - // var sourceType = typeof(TSource); - // var targetType = typeof(TTarget); - - // var sourceCtors = DefineCtors(sourceType); - // sourceCtors[targetType] = (source, context) => ctor((TSource)source, context); - - // var sourceMaps = DefineMaps(sourceType); - // sourceMaps[targetType] = (source, target, context) => map((TSource)source, (TTarget)target); - //} - public void Define(Func ctor, Action map) { var sourceType = typeof(TSource); @@ -186,15 +133,10 @@ namespace Umbraco.Core.Mapping return (TTarget)targetEnumerable; } - - // fixme - temp - return AutoMapper.Mapper.Map(source); } } - // fixme this is temp - //throw new InvalidOperationException($"Don't know how to map {sourceType.FullName} to {targetType.FullName}."); - return AutoMapper.Mapper.Map(source); + throw new InvalidOperationException($"Don't know how to map {sourceType.FullName} to {targetType.FullName}."); } // TODO: when AutoMapper is completely gone these two methods can merge @@ -254,15 +196,10 @@ namespace Umbraco.Core.Mapping return (TTarget)targetEnumerable; } - - // fixme - temp - return AutoMapper.Mapper.Map(source); } } - // fixme this is temp - //throw new InvalidOperationException($"Don't know how to map {sourceType.FullName} to {targetType.FullName}."); - return AutoMapper.Mapper.Map(source); + throw new InvalidOperationException($"Don't know how to map {sourceType.FullName} to {targetType.FullName}."); } public TTarget Map(TSource source, TTarget target) @@ -275,7 +212,6 @@ namespace Umbraco.Core.Mapping return Map(source, target, context); } - public TTarget Map(TSource source, TTarget target, MapperContext context) { // fixme should we deal with enumerables? @@ -283,9 +219,7 @@ namespace Umbraco.Core.Mapping var map = GetMap(source.GetType(), typeof(TTarget)); if (map == null) { - // fixme this is temp - //throw new InvalidOperationException($"Don't know how to map {sourceType.FullName} to {targetType.FullName}."); - return AutoMapper.Mapper.Map(source, target); + throw new InvalidOperationException($"Don't know how to map {typeof(TSource).FullName} to {typeof(TTarget).FullName}."); } map(source, target, context); diff --git a/src/Umbraco.Core/Runtime/CoreInitialComponent.cs b/src/Umbraco.Core/Runtime/CoreInitialComponent.cs index 25b679b2a0..2e40bf1339 100644 --- a/src/Umbraco.Core/Runtime/CoreInitialComponent.cs +++ b/src/Umbraco.Core/Runtime/CoreInitialComponent.cs @@ -1,28 +1,12 @@ -using System.Collections.Generic; -using AutoMapper; -using Umbraco.Core.Composing; +using Umbraco.Core.Composing; using Umbraco.Core.IO; namespace Umbraco.Core.Runtime { public class CoreInitialComponent : IComponent { - private readonly IEnumerable _mapperProfiles; - - public CoreInitialComponent(IEnumerable mapperProfiles) // fixme - this is what we want to kill: mapper - { - _mapperProfiles = mapperProfiles; - } - public void Initialize() { - // mapper profiles have been registered & are created by the container - Mapper.Initialize(configuration => - { - foreach (var profile in _mapperProfiles) - configuration.AddProfile(profile); - }); - // ensure we have some essential directories // every other component can then initialize safely IOHelper.EnsurePathExists("~/App_Data"); diff --git a/src/Umbraco.Core/Runtime/CoreRuntime.cs b/src/Umbraco.Core/Runtime/CoreRuntime.cs index f00365496a..bc7b8afc3b 100644 --- a/src/Umbraco.Core/Runtime/CoreRuntime.cs +++ b/src/Umbraco.Core/Runtime/CoreRuntime.cs @@ -217,10 +217,13 @@ namespace Umbraco.Core.Runtime // This is used for loading a signed assembly of AutoMapper (v. 3.1+) without having to recompile old code. AppDomain.CurrentDomain.AssemblyResolve += (sender, args) => { + // here for reference - we don't use automapper anymore + see BindingRedirects ?? + /* // ensure the assembly is indeed AutoMapper and that the PublicKeyToken is null before trying to Load again // do NOT just replace this with 'return Assembly', as it will cause an infinite loop -> stack overflow if (args.Name.StartsWith("AutoMapper") && args.Name.EndsWith("PublicKeyToken=null")) return Assembly.Load(args.Name.Replace(", PublicKeyToken=null", ", PublicKeyToken=be96cd2c38ef1005")); + */ return null; }; } diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index e7203b3be8..c2839792bd 100755 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -60,7 +60,6 @@ runtime; build; native; contentfiles; analyzers all - diff --git a/src/Umbraco.Tests/Mapping/MappingTests.cs b/src/Umbraco.Tests/Mapping/MappingTests.cs index 07930bf027..c5f4593c6d 100644 --- a/src/Umbraco.Tests/Mapping/MappingTests.cs +++ b/src/Umbraco.Tests/Mapping/MappingTests.cs @@ -79,13 +79,12 @@ namespace Umbraco.Tests.Mapping { public void SetMaps(Mapper mapper) { - mapper.Define(source => new Thing2(), (source, target) => Map(source, target)); + mapper.Define((source, context) => new Thing2(), Map); } - private Thing2 Map(Thing1 source, Thing2 target) + private void Map(Thing1 source, Thing2 target, MapperContext context) { target.Value = source.Value; - return target; } } } diff --git a/src/Umbraco.Tests/Umbraco.Tests.csproj b/src/Umbraco.Tests/Umbraco.Tests.csproj index 706d81700b..17cb425eef 100644 --- a/src/Umbraco.Tests/Umbraco.Tests.csproj +++ b/src/Umbraco.Tests/Umbraco.Tests.csproj @@ -78,7 +78,6 @@ - diff --git a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj index 8fb0dc6cd9..6777e66456 100644 --- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj +++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj @@ -83,7 +83,6 @@ - diff --git a/src/Umbraco.Web/Composing/CompositionExtensions/WebMappingProfiles.cs b/src/Umbraco.Web/Composing/CompositionExtensions/WebMappingProfiles.cs index 88fb595440..d0c404a679 100644 --- a/src/Umbraco.Web/Composing/CompositionExtensions/WebMappingProfiles.cs +++ b/src/Umbraco.Web/Composing/CompositionExtensions/WebMappingProfiles.cs @@ -1,10 +1,7 @@ -using AutoMapper; -using Umbraco.Core; +using Umbraco.Core; using Umbraco.Core.Composing; using Umbraco.Core.Mapping; -using Umbraco.Core.Models; using Umbraco.Web.Models.Mapping; -using Umbraco.Web.Trees; namespace Umbraco.Web.Composing.CompositionExtensions { @@ -12,10 +9,10 @@ namespace Umbraco.Web.Composing.CompositionExtensions { public static Composition ComposeWebMappingProfiles(this Composition composition) { - // register the profiles composition.WithCollectionBuilder() .Append() .Append() + .Append() .Append() .Append() .Append() @@ -23,6 +20,7 @@ namespace Umbraco.Web.Composing.CompositionExtensions .Append() .Append() .Append() + .Append() .Append() .Append() .Append() @@ -31,37 +29,7 @@ namespace Umbraco.Web.Composing.CompositionExtensions .Append() .Append(); - //register the profiles - //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(); - //composition.Register(); - //composition.Register(); - //composition.Register(); - //composition.Register(); - //composition.Register(); - - //register any resolvers, etc.. that the profiles use - composition.Register(); - composition.Register>(); - composition.Register>(); - composition.Register>(); - composition.Register>(); - composition.Register(); - composition.Register(); - composition.Register(); - composition.Register(); - composition.Register(); + composition.Register(); return composition; } diff --git a/src/Umbraco.Web/Editors/Binders/ContentItemBinder.cs b/src/Umbraco.Web/Editors/Binders/ContentItemBinder.cs index ca7cb2e4e2..11a876345d 100644 --- a/src/Umbraco.Web/Editors/Binders/ContentItemBinder.cs +++ b/src/Umbraco.Web/Editors/Binders/ContentItemBinder.cs @@ -2,7 +2,6 @@ using System.Linq; using System.Web.Http.Controllers; using System.Web.Http.ModelBinding; -using AutoMapper; using Umbraco.Core; using Umbraco.Core.Logging; using Umbraco.Core.Models; diff --git a/src/Umbraco.Web/Editors/Binders/MediaItemBinder.cs b/src/Umbraco.Web/Editors/Binders/MediaItemBinder.cs index bbba9d8122..1084aa16ea 100644 --- a/src/Umbraco.Web/Editors/Binders/MediaItemBinder.cs +++ b/src/Umbraco.Web/Editors/Binders/MediaItemBinder.cs @@ -1,14 +1,10 @@ using System; using System.Web.Http.Controllers; using System.Web.Http.ModelBinding; -using AutoMapper; -using Umbraco.Core; using Umbraco.Core.Models; using Umbraco.Core.Services; using Umbraco.Web.Composing; using Umbraco.Web.Models.ContentEditing; -using Umbraco.Web.Models.Mapping; -using Umbraco.Web.WebApi; namespace Umbraco.Web.Editors.Binders { @@ -46,7 +42,7 @@ namespace Umbraco.Web.Editors.Binders //create the dto from the persisted model if (model.PersistedContent != null) { - model.PropertyCollectionDto = Mapper.Map(model.PersistedContent); + model.PropertyCollectionDto = Current.Mapper.Map(model.PersistedContent); //now map all of the saved values to the dto _modelBinderHelper.MapPropertyValuesFromSaved(model, model.PropertyCollectionDto); } diff --git a/src/Umbraco.Web/Editors/Binders/MemberBinder.cs b/src/Umbraco.Web/Editors/Binders/MemberBinder.cs index bceba2e04d..60b4f85c21 100644 --- a/src/Umbraco.Web/Editors/Binders/MemberBinder.cs +++ b/src/Umbraco.Web/Editors/Binders/MemberBinder.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using System.Web.Http.Controllers; using System.Web.Http.ModelBinding; using System.Web.Security; -using AutoMapper; using Umbraco.Core; using Umbraco.Core.Models; using Umbraco.Core.Security; @@ -50,7 +49,7 @@ namespace Umbraco.Web.Editors.Binders //create the dto from the persisted model if (model.PersistedContent != null) { - model.PropertyCollectionDto = Mapper.Map(model.PersistedContent); + model.PropertyCollectionDto = Current.Mapper.Map(model.PersistedContent); //now map all of the saved values to the dto _modelBinderHelper.MapPropertyValuesFromSaved(model, model.PropertyCollectionDto); } @@ -106,7 +105,7 @@ namespace Umbraco.Web.Editors.Binders //} //member.Key = convertResult.Result; - var member = Mapper.Map(membershipUser); + var member = Current.Mapper.Map(membershipUser); return member; } diff --git a/src/Umbraco.Web/Editors/ContentTypeControllerBase.cs b/src/Umbraco.Web/Editors/ContentTypeControllerBase.cs index 0fa3428740..e62438cc6f 100644 --- a/src/Umbraco.Web/Editors/ContentTypeControllerBase.cs +++ b/src/Umbraco.Web/Editors/ContentTypeControllerBase.cs @@ -5,7 +5,6 @@ using System.Net; using System.Net.Http; using System.Text; using System.Web.Http; -using AutoMapper; using Umbraco.Core; using Umbraco.Core.Cache; using Umbraco.Core.Configuration; @@ -501,13 +500,13 @@ namespace Umbraco.Web.Editors where TPropertyType : PropertyTypeBasic { InvalidCompositionException invalidCompositionException = null; - if (ex is AutoMapperMappingException && ex.InnerException is InvalidCompositionException) + if (ex is InvalidCompositionException) { - invalidCompositionException = (InvalidCompositionException)ex.InnerException; + invalidCompositionException = (InvalidCompositionException)ex; } else if (ex.InnerException is InvalidCompositionException) { - invalidCompositionException = (InvalidCompositionException)ex; + invalidCompositionException = (InvalidCompositionException)ex.InnerException; } if (invalidCompositionException != null) { diff --git a/src/Umbraco.Web/Editors/DataTypeValidateAttribute.cs b/src/Umbraco.Web/Editors/DataTypeValidateAttribute.cs index 738dd05c75..1337545ee0 100644 --- a/src/Umbraco.Web/Editors/DataTypeValidateAttribute.cs +++ b/src/Umbraco.Web/Editors/DataTypeValidateAttribute.cs @@ -4,7 +4,6 @@ using System.Net; using System.Net.Http; using System.Web.Http.Controllers; using System.Web.Http.Filters; -using AutoMapper; using Umbraco.Core; using Umbraco.Core.Composing; using Umbraco.Core.Models; @@ -71,12 +70,12 @@ namespace Umbraco.Web.Editors return; } // map the model to the persisted instance - Mapper.Map(dataType, persisted); + Current.Mapper.Map(dataType, persisted); break; case ContentSaveAction.SaveNew: // create the persisted model from mapping the saved model - persisted = Mapper.Map(dataType); + persisted = Current.Mapper.Map(dataType); ((DataType) persisted).ResetIdentity(); break; diff --git a/src/Umbraco.Web/Models/Mapping/ActionButtonsResolver.cs b/src/Umbraco.Web/Models/Mapping/ActionButtonsResolver.cs deleted file mode 100644 index 9c5a4a0b88..0000000000 --- a/src/Umbraco.Web/Models/Mapping/ActionButtonsResolver.cs +++ /dev/null @@ -1,45 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Umbraco.Core.Models; -using Umbraco.Core.Services; -using Umbraco.Web.Composing; - -namespace Umbraco.Web.Models.Mapping -{ - /// - /// Creates the list of action buttons allowed for this user - Publish, Send to publish, save, unpublish returned as the button's 'letter' - /// - internal class ActionButtonsResolver - { - public ActionButtonsResolver(IUserService userService, IContentService contentService) - { - UserService = userService; - ContentService = contentService; - } - - private IUserService UserService { get; } - private IContentService ContentService { get; } - - public IEnumerable Resolve(IContent source) - { - //cannot check permissions without a context - if (Current.UmbracoContext == null) - return Enumerable.Empty(); - - string path; - if (source.HasIdentity) - path = source.Path; - else - { - var parent = ContentService.GetById(source.ParentId); - path = parent == null ? "-1" : parent.Path; - } - - // TODO: This is certainly not ideal usage here - perhaps the best way to deal with this in the future is - // with the IUmbracoContextAccessor. In the meantime, if used outside of a web app this will throw a null - // reference exception :( - return UserService.GetPermissionsForPath(Current.UmbracoContext.Security.CurrentUser, path).GetAllPermissions(); - } - } -} diff --git a/src/Umbraco.Web/Models/Mapping/AuditMapperProfile.cs b/src/Umbraco.Web/Models/Mapping/AuditMapperProfile.cs index 56bd48ee17..e7756b4538 100644 --- a/src/Umbraco.Web/Models/Mapping/AuditMapperProfile.cs +++ b/src/Umbraco.Web/Models/Mapping/AuditMapperProfile.cs @@ -8,11 +8,11 @@ namespace Umbraco.Web.Models.Mapping { public void SetMaps(Mapper mapper) { - mapper.Define(source => new AuditLog(), Map); + mapper.Define((source, context) => new AuditLog(), Map); } // Umbraco.Code.MapAll -UserAvatars -UserName - private void Map(IAuditItem source, AuditLog target) + private void Map(IAuditItem source, AuditLog target, MapperContext context) { target.UserId = source.UserId; target.NodeId = source.Id; diff --git a/src/Umbraco.Web/Models/Mapping/CodeFileMapperProfile.cs b/src/Umbraco.Web/Models/Mapping/CodeFileMapperProfile.cs index 7767bcd2ee..735125d4b1 100644 --- a/src/Umbraco.Web/Models/Mapping/CodeFileMapperProfile.cs +++ b/src/Umbraco.Web/Models/Mapping/CodeFileMapperProfile.cs @@ -9,17 +9,17 @@ namespace Umbraco.Web.Models.Mapping { public void SetMaps(Mapper mapper) { - 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((source, context) => new EntityBasic(), Map); + mapper.Define((source, context) => new CodeFileDisplay(), Map); + mapper.Define((source, context) => new CodeFileDisplay(), Map); + mapper.Define((source, context) => new CodeFileDisplay(), Map); mapper.Define(Map); mapper.Define(Map); } // Umbraco.Code.MapAll -Trashed -Udi -Icon - private static void Map(Stylesheet source, EntityBasic target) + private static void Map(Stylesheet source, EntityBasic target, MapperContext context) { target.Alias = source.Alias; target.Id = source.Id; @@ -30,7 +30,7 @@ namespace Umbraco.Web.Models.Mapping } // Umbraco.Code.MapAll -FileType -Notifications -Path -Snippet - private static void Map(IPartialView source, CodeFileDisplay target) + private static void Map(IPartialView source, CodeFileDisplay target, MapperContext context) { target.Content = source.Content; target.Id = source.Id.ToString(); @@ -39,7 +39,7 @@ namespace Umbraco.Web.Models.Mapping } // Umbraco.Code.MapAll -FileType -Notifications -Path -Snippet - private static void Map(Script source, CodeFileDisplay target) + private static void Map(Script source, CodeFileDisplay target, MapperContext context) { target.Content = source.Content; target.Id = source.Id.ToString(); @@ -48,7 +48,7 @@ namespace Umbraco.Web.Models.Mapping } // Umbraco.Code.MapAll -FileType -Notifications -Path -Snippet - private static void Map(Stylesheet source, CodeFileDisplay target) + private static void Map(Stylesheet source, CodeFileDisplay target, MapperContext context) { target.Content = source.Content; target.Id = source.Id.ToString(); @@ -58,7 +58,7 @@ namespace Umbraco.Web.Models.Mapping // Umbraco.Code.MapAll -CreateDate -DeleteDate -UpdateDate // Umbraco.Code.MapAll -Id -Key -Alias -Name -OriginalPath -Path - private static void Map(CodeFileDisplay source, IPartialView target) + private static void Map(CodeFileDisplay source, IPartialView target, MapperContext context) { target.Content = source.Content; target.VirtualPath = source.VirtualPath; @@ -66,7 +66,7 @@ namespace Umbraco.Web.Models.Mapping // Umbraco.Code.MapAll -CreateDate -DeleteDate -UpdateDate -GetFileContent // Umbraco.Code.MapAll -Id -Key -Alias -Name -OriginalPath -Path - private static void Map(CodeFileDisplay source, Script target) + private static void Map(CodeFileDisplay source, Script target, MapperContext context) { target.Content = source.Content; target.VirtualPath = source.VirtualPath; diff --git a/src/Umbraco.Web/Models/Mapping/ContentAppResolver.cs b/src/Umbraco.Web/Models/Mapping/ContentAppResolver.cs deleted file mode 100644 index 6d9ae77009..0000000000 --- a/src/Umbraco.Web/Models/Mapping/ContentAppResolver.cs +++ /dev/null @@ -1,43 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using AutoMapper; -using Umbraco.Core.Models; -using Umbraco.Core.Models.ContentEditing; -using Umbraco.Core.Services; -using Umbraco.Web.ContentApps; -using Umbraco.Web.Models.ContentEditing; - -namespace Umbraco.Web.Models.Mapping -{ - // injected into ContentMapperProfile, - // maps ContentApps when mapping IContent to ContentItemDisplay - internal class ContentAppResolver : IValueResolver> - { - private readonly ContentAppFactoryCollection _contentAppDefinitions; - private readonly ILocalizedTextService _localizedTextService; - - public ContentAppResolver(ContentAppFactoryCollection contentAppDefinitions, ILocalizedTextService localizedTextService) - { - _contentAppDefinitions = contentAppDefinitions; - _localizedTextService = localizedTextService; - } - - public IEnumerable Resolve(IContent source, ContentItemDisplay destination, IEnumerable destMember, ResolutionContext context) - { - var apps = _contentAppDefinitions.GetContentAppsFor(source).ToArray(); - - // localize content app names - foreach (var app in apps) - { - var localizedAppName = _localizedTextService.Localize($"apps/{app.Alias}"); - if (localizedAppName.Equals($"[{app.Alias}]", StringComparison.OrdinalIgnoreCase) == false) - { - app.Name = localizedAppName; - } - } - - return apps; - } - } -} diff --git a/src/Umbraco.Web/Models/Mapping/ContentChildOfListViewResolver.cs b/src/Umbraco.Web/Models/Mapping/ContentChildOfListViewResolver.cs deleted file mode 100644 index a2f250d6f3..0000000000 --- a/src/Umbraco.Web/Models/Mapping/ContentChildOfListViewResolver.cs +++ /dev/null @@ -1,26 +0,0 @@ -using AutoMapper; -using Umbraco.Core.Models; -using Umbraco.Core.Services; -using Umbraco.Web.Models.ContentEditing; - -namespace Umbraco.Web.Models.Mapping -{ - internal class ContentChildOfListViewResolver : IValueResolver - { - private readonly IContentService _contentService; - private readonly IContentTypeService _contentTypeService; - - public ContentChildOfListViewResolver(IContentService contentService, IContentTypeService contentTypeService) - { - _contentService = contentService; - _contentTypeService = contentTypeService; - } - - public bool Resolve(IContent source, ContentItemDisplay destination, bool destMember, ResolutionContext context) - { - // map the IsChildOfListView (this is actually if it is a descendant of a list view!) - var parent = _contentService.GetParent(source); - return parent != null && (parent.ContentType.IsContainer || _contentTypeService.HasContainerInPath(parent.Path)); - } - } -} \ No newline at end of file diff --git a/src/Umbraco.Web/Models/Mapping/ContentMapperProfile.cs b/src/Umbraco.Web/Models/Mapping/ContentMapperProfile.cs index 0695dcf43d..05d6828cc4 100644 --- a/src/Umbraco.Web/Models/Mapping/ContentMapperProfile.cs +++ b/src/Umbraco.Web/Models/Mapping/ContentMapperProfile.cs @@ -1,11 +1,13 @@ using System; 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.Services; using Umbraco.Web.Models.ContentEditing; +using Umbraco.Web.Routing; using Umbraco.Web.Trees; namespace Umbraco.Web.Models.Mapping @@ -13,157 +15,233 @@ namespace Umbraco.Web.Models.Mapping /// /// Declares how model mappings for content /// - internal class ContentMapperProfile : Profile + internal class ContentMapperProfile : IMapperProfile { - public ContentMapperProfile( - ContentUrlResolver contentUrlResolver, - ContentTreeNodeUrlResolver contentTreeNodeUrlResolver, - TabsAndPropertiesMapper tabsAndPropertiesMapper, - ContentAppResolver contentAppResolver, - IUserService userService, - IContentService contentService, - IContentTypeService contentTypeService, - IContentTypeBaseServiceProvider contentTypeBaseServiceProvider, - ILocalizationService localizationService, - ILocalizedTextService localizedTextService) + private readonly CommonMapper _commonMapper; + private readonly ILocalizedTextService _localizedTextService; + private readonly IContentService _contentService; + private readonly IContentTypeService _contentTypeService; + private readonly IFileService _fileService; + private readonly IUmbracoContextAccessor _umbracoContextAccessor; + private readonly IPublishedRouter _publishedRouter; + private readonly ILocalizationService _localizationService; + private readonly ILogger _logger; + private readonly IUserService _userService; + private readonly TabsAndPropertiesMapper _tabsAndPropertiesMapper; + private readonly ContentSavedStateMapper _stateMapper; + private readonly ContentBasicSavedStateMapper _basicStateMapper; + private readonly ContentVariantMapper _contentVariantMapper; + + public ContentMapperProfile(CommonMapper commonMapper, ILocalizedTextService localizedTextService, IContentService contentService, IContentTypeService contentTypeService, + IFileService fileService, IUmbracoContextAccessor umbracoContextAccessor, IPublishedRouter publishedRouter, ILocalizationService localizationService, ILogger logger, + IUserService userService) { - // create, capture, cache - var contentOwnerResolver = new OwnerResolver(userService); - var creatorResolver = new CreatorResolver(userService); - var actionButtonsResolver = new ActionButtonsResolver(userService, contentService); - var childOfListViewResolver = new ContentChildOfListViewResolver(contentService, contentTypeService); - var contentTypeBasicResolver = new ContentTypeBasicResolver(contentTypeBaseServiceProvider); - var allowedTemplatesResolver = new AllowedTemplatesResolver(contentTypeService, localizedTextService); - var defaultTemplateResolver = new DefaultTemplateResolver(); - var variantResolver = new ContentVariantResolver(localizationService); - var schedPublishReleaseDateResolver = new ScheduledPublishDateResolver(ContentScheduleAction.Release); - var schedPublishExpireDateResolver = new ScheduledPublishDateResolver(ContentScheduleAction.Expire); + _commonMapper = commonMapper; + _localizedTextService = localizedTextService; + _contentService = contentService; + _contentTypeService = contentTypeService; + _fileService = fileService; + _umbracoContextAccessor = umbracoContextAccessor; + _publishedRouter = publishedRouter; + _localizationService = localizationService; + _logger = logger; + _userService = userService; - //FROM IContent TO ContentItemDisplay - CreateMap() - .ForMember(dest => dest.Udi, opt => opt.MapFrom(src => Udi.Create(src.Blueprint ? Constants.UdiEntityType.DocumentBlueprint : Constants.UdiEntityType.Document, src.Key))) - .ForMember(dest => dest.Owner, opt => opt.MapFrom(src => contentOwnerResolver.Resolve(src))) - .ForMember(dest => dest.Updater, opt => opt.MapFrom(src => creatorResolver.Resolve(src))) - .ForMember(dest => dest.Variants, opt => opt.MapFrom(variantResolver)) - .ForMember(dest => dest.ContentApps, opt => opt.MapFrom(contentAppResolver)) - .ForMember(dest => dest.Icon, opt => opt.MapFrom(src => src.ContentType.Icon)) - .ForMember(dest => dest.ContentTypeAlias, opt => opt.MapFrom(src => src.ContentType.Alias)) - .ForMember(dest => dest.ContentTypeName, opt => opt.MapFrom(src => localizedTextService.UmbracoDictionaryTranslate(src.ContentType.Name))) - .ForMember(dest => dest.IsContainer, opt => opt.MapFrom(src => src.ContentType.IsContainer)) - .ForMember(dest => dest.IsElement, opt => opt.MapFrom(src => src.ContentType.IsElement)) - .ForMember(dest => dest.IsBlueprint, opt => opt.MapFrom(src => src.Blueprint)) - .ForMember(dest => dest.IsChildOfListView, opt => opt.MapFrom(childOfListViewResolver)) - .ForMember(dest => dest.Trashed, opt => opt.MapFrom(src => src.Trashed)) - .ForMember(dest => dest.TemplateAlias, opt => opt.MapFrom(defaultTemplateResolver)) - .ForMember(dest => dest.Urls, opt => opt.MapFrom(contentUrlResolver)) - .ForMember(dest => dest.AllowPreview, opt => opt.Ignore()) - .ForMember(dest => dest.TreeNodeUrl, opt => opt.MapFrom(contentTreeNodeUrlResolver)) - .ForMember(dest => dest.Notifications, opt => opt.Ignore()) - .ForMember(dest => dest.Errors, opt => opt.Ignore()) - .ForMember(dest => dest.DocumentType, opt => opt.MapFrom(contentTypeBasicResolver)) - .ForMember(dest => dest.AllowedTemplates, opt => opt.MapFrom(allowedTemplatesResolver)) - .ForMember(dest => dest.AllowedActions, opt => opt.MapFrom(src => actionButtonsResolver.Resolve(src))) - .ForMember(dest => dest.AdditionalData, opt => opt.Ignore()); - - CreateMap() - .ForMember(dest => dest.PublishDate, opt => opt.MapFrom(src => src.PublishDate)) - .ForMember(dest => dest.ReleaseDate, opt => opt.MapFrom(schedPublishReleaseDateResolver)) - .ForMember(dest => dest.ExpireDate, opt => opt.MapFrom(schedPublishExpireDateResolver)) - .ForMember(dest => dest.Segment, opt => opt.Ignore()) - .ForMember(dest => dest.Language, opt => opt.Ignore()) - .ForMember(dest => dest.Notifications, opt => opt.Ignore()) - .ForMember(dest => dest.State, opt => opt.MapFrom>()) - .ForMember(dest => dest.Tabs, opt => opt.MapFrom(tabsAndPropertiesMapper)); - - //FROM IContent TO ContentItemBasic - CreateMap>() - .ForMember(dest => dest.Udi, opt => opt.MapFrom(src => - Udi.Create(src.Blueprint ? Constants.UdiEntityType.DocumentBlueprint : Constants.UdiEntityType.Document, src.Key))) - .ForMember(dest => dest.Owner, opt => opt.MapFrom(src => contentOwnerResolver.Resolve(src))) - .ForMember(dest => dest.Updater, opt => opt.MapFrom(src => creatorResolver.Resolve(src))) - .ForMember(dest => dest.Icon, opt => opt.MapFrom(src => src.ContentType.Icon)) - .ForMember(dest => dest.Trashed, opt => opt.MapFrom(src => src.Trashed)) - .ForMember(dest => dest.ContentTypeAlias, opt => opt.MapFrom(src => src.ContentType.Alias)) - .ForMember(dest => dest.Alias, opt => opt.Ignore()) - .ForMember(dest => dest.AdditionalData, opt => opt.Ignore()) - .ForMember(dest => dest.UpdateDate, opt => opt.MapFrom()) - .ForMember(dest => dest.Name, opt => opt.MapFrom()) - .ForMember(dest => dest.State, opt => opt.MapFrom>()) - .ForMember(dest => dest.VariesByCulture, opt => opt.MapFrom(src => src.ContentType.VariesByCulture())); - - //FROM IContent TO ContentPropertyCollectionDto - //NOTE: the property mapping for cultures relies on a culture being set in the mapping context - CreateMap(); + _tabsAndPropertiesMapper = new TabsAndPropertiesMapper(localizedTextService); + _stateMapper = new ContentSavedStateMapper(); + _basicStateMapper = new ContentBasicSavedStateMapper(); + _contentVariantMapper = new ContentVariantMapper(_localizationService); } - /// - /// Resolves the update date for a content item/content variant - /// - private class UpdateDateResolver : IValueResolver, DateTime> + public void SetMaps(Mapper mapper) { - public DateTime Resolve(IContent source, ContentItemBasic destination, DateTime destMember, ResolutionContext context) - { - // invariant = global date - if (!source.ContentType.VariesByCulture()) return source.UpdateDate; - - // variant = depends on culture - var culture = context.Options.GetCulture(); - - // if there's no culture here, the issue is somewhere else (UI, whatever) - throw! - if (culture == null) - throw new InvalidOperationException("Missing culture in mapping options."); - - // if we don't have a date for a culture, it means the culture is not available, and - // hey we should probably not be mapping it, but it's too late, return a fallback date - var date = source.GetUpdateDate(culture); - return date ?? source.UpdateDate; - } + mapper.Define((source, context) => new ContentItemDisplay(), Map); + mapper.Define((source, context) => new ContentVariantDisplay(), Map); + mapper.Define>((source, context) => new ContentItemBasic(), Map); } - /// - /// Resolves the name for a content item/content variant - /// - private class NameResolver : IValueResolver, string> + // Umbraco.Code.MapAll -AllowPreview -Errors -PersistedContent + private void Map(IContent source, ContentItemDisplay target, MapperContext context) { - public string Resolve(IContent source, ContentItemBasic destination, string destMember, ResolutionContext context) - { - // invariant = only 1 name - if (!source.ContentType.VariesByCulture()) return source.Name; + target.AllowedActions = GetActions(source); + target.AllowedTemplates = GetAllowedTemplates(source); + target.ContentApps = _commonMapper.GetContentApps(source); + target.ContentTypeAlias = source.ContentType.Alias; + target.ContentTypeName = _localizedTextService.UmbracoDictionaryTranslate(source.ContentType.Name); + target.DocumentType = _commonMapper.GetContentType(source, context.Mapper); + target.Icon = source.ContentType.Icon; + target.Id = source.Id; + target.IsBlueprint = source.Blueprint; + target.IsChildOfListView = DermineIsChildOfListView(source); + target.IsContainer = source.ContentType.IsContainer; + target.IsElement = source.ContentType.IsElement; + target.Key = source.Key; + target.Owner = _commonMapper.GetOwner(source, context.Mapper); + target.ParentId = source.ParentId; + target.Path = source.Path; + target.SortOrder = source.SortOrder; + target.TemplateAlias = GetDefaultTemplate(source); + target.TemplateId = source.TemplateId ?? default; + target.Trashed = source.Trashed; + target.TreeNodeUrl = _commonMapper.GetTreeNodeUrl(source); + target.Udi = Udi.Create(source.Blueprint ? Constants.UdiEntityType.DocumentBlueprint : Constants.UdiEntityType.Document, source.Key); + target.UpdateDate = source.UpdateDate; + target.Updater = _commonMapper.GetCreator(source, context.Mapper); + target.Urls = GetUrls(source); + target.Variants = _contentVariantMapper.Map(source, context); - // variant = depends on culture - var culture = context.Options.GetCulture(); - - // if there's no culture here, the issue is somewhere else (UI, whatever) - throw! - if (culture == null) - throw new InvalidOperationException("Missing culture in mapping options."); - - // if we don't have a name for a culture, it means the culture is not available, and - // hey we should probably not be mapping it, but it's too late, return a fallback name - return source.CultureInfos.TryGetValue(culture, out var name) && !name.Name.IsNullOrWhiteSpace() ? name.Name : $"({source.Name})"; - } + target.ContentDto = new ContentPropertyCollectionDto(); + target.ContentDto.Properties = source.Properties.Select(context.Mapper.Map); } - - private class AllowedTemplatesResolver : IValueResolver> + // Umbraco.Code.MapAll -Segment -Language + private void Map(IContent source, ContentVariantDisplay target, MapperContext context) { - private readonly IContentTypeService _contentTypeService; - private readonly ILocalizedTextService _localizedTextService; + target.CreateDate = source.CreateDate; + target.ExpireDate = GetScheduledDate(source, ContentScheduleAction.Expire, context); + target.Name = source.Name; + target.PublishDate = source.PublishDate; + target.ReleaseDate = GetScheduledDate(source, ContentScheduleAction.Release, context); + target.State = _stateMapper.Map(source, context); + target.Tabs = _tabsAndPropertiesMapper.Map(source, context); + target.UpdateDate = source.UpdateDate; + } - public AllowedTemplatesResolver(IContentTypeService contentTypeService, ILocalizedTextService localizedTextService) + // Umbraco.Code.MapAll -Alias + private void Map(IContent source, ContentItemBasic target, MapperContext context) + { + target.ContentTypeAlias = source.ContentType.Alias; + target.CreateDate = source.CreateDate; + target.Edited = source.Edited; + target.Icon = source.ContentType.Icon; + target.Id = source.Id; + target.Key = source.Key; + target.Name = GetName(source, context); + target.Owner = _commonMapper.GetOwner(source, context.Mapper); + target.ParentId = source.ParentId; + target.Path = source.Path; + target.Properties = context.Mapper.Map>(source.Properties); + target.SortOrder = source.SortOrder; + target.State = _basicStateMapper.Map(source, context); + target.Trashed = source.Trashed; + target.Udi = Udi.Create(source.Blueprint ? Constants.UdiEntityType.DocumentBlueprint : Constants.UdiEntityType.Document, source.Key); + target.UpdateDate = GetUpdateDate(source, context); + target.Updater = _commonMapper.GetCreator(source, context.Mapper); + target.VariesByCulture = source.ContentType.VariesByCulture(); + } + + private IEnumerable GetActions(IContent source) + { + var umbracoContext = _umbracoContextAccessor.UmbracoContext; + + //cannot check permissions without a context + if (umbracoContext == null) + return Enumerable.Empty(); + + string path; + if (source.HasIdentity) + path = source.Path; + else { - _contentTypeService = contentTypeService; - _localizedTextService = localizedTextService; + var parent = _contentService.GetById(source.ParentId); + path = parent == null ? "-1" : parent.Path; } - public IDictionary Resolve(IContent source, ContentItemDisplay destination, IDictionary destMember, ResolutionContext context) - { - var contentType = _contentTypeService.Get(source.ContentTypeId); + // TODO: This is certainly not ideal usage here - perhaps the best way to deal with this in the future is + // with the IUmbracoContextAccessor. In the meantime, if used outside of a web app this will throw a null + // reference exception :( + return _userService.GetPermissionsForPath(umbracoContext.Security.CurrentUser, path).GetAllPermissions(); + } - return contentType.AllowedTemplates - .Where(t => t.Alias.IsNullOrWhiteSpace() == false && t.Name.IsNullOrWhiteSpace() == false) - .ToDictionary(t => t.Alias, t => _localizedTextService.UmbracoDictionaryTranslate(t.Name)); + private UrlInfo[] GetUrls(IContent source) + { + if (source.ContentType.IsElement) + return Array.Empty(); + + var umbracoContext = _umbracoContextAccessor.UmbracoContext; + + var urls = umbracoContext == null + ? new[] { UrlInfo.Message("Cannot generate urls without a current Umbraco Context") } + : source.GetContentUrls(_publishedRouter, umbracoContext, _localizationService, _localizedTextService, _contentService, _logger).ToArray(); + + return urls; + } + + private DateTime GetUpdateDate(IContent source, MapperContext context) + { + // invariant = global date + if (!source.ContentType.VariesByCulture()) return source.UpdateDate; + + // variant = depends on culture + var culture = context.GetCulture(); + + // if there's no culture here, the issue is somewhere else (UI, whatever) - throw! + if (culture == null) + throw new InvalidOperationException("Missing culture in mapping options."); + + // if we don't have a date for a culture, it means the culture is not available, and + // hey we should probably not be mapping it, but it's too late, return a fallback date + var date = source.GetUpdateDate(culture); + return date ?? source.UpdateDate; + } + + private string GetName(IContent source, MapperContext context) + { + // invariant = only 1 name + if (!source.ContentType.VariesByCulture()) return source.Name; + + // variant = depends on culture + var culture = context.GetCulture(); + + // if there's no culture here, the issue is somewhere else (UI, whatever) - throw! + if (culture == null) + throw new InvalidOperationException("Missing culture in mapping options."); + + // if we don't have a name for a culture, it means the culture is not available, and + // hey we should probably not be mapping it, but it's too late, return a fallback name + return source.CultureInfos.TryGetValue(culture, out var name) && !name.Name.IsNullOrWhiteSpace() ? name.Name : $"({source.Name})"; + } + + private bool DermineIsChildOfListView(IContent source) + { + // map the IsChildOfListView (this is actually if it is a descendant of a list view!) + var parent = _contentService.GetParent(source); + return parent != null && (parent.ContentType.IsContainer || _contentTypeService.HasContainerInPath(parent.Path)); + } + + private DateTime? GetScheduledDate(IContent source, ContentScheduleAction action, MapperContext context) + { + var culture = context.GetCulture() ?? string.Empty; + var schedule = source.ContentSchedule.GetSchedule(culture, action); + return schedule.FirstOrDefault()?.Date; // take the first, it's ordered by date + } + + private IDictionary GetAllowedTemplates(IContent source) + { + var contentType = _contentTypeService.Get(source.ContentTypeId); + + return contentType.AllowedTemplates + .Where(t => t.Alias.IsNullOrWhiteSpace() == false && t.Name.IsNullOrWhiteSpace() == false) + .ToDictionary(t => t.Alias, t => _localizedTextService.UmbracoDictionaryTranslate(t.Name)); + } + + private string GetDefaultTemplate(IContent source) + { + if (source == null) + return null; + + // If no template id was set... + if (!source.TemplateId.HasValue) + { + // ... and no default template is set, return null... + // ... otherwise return the content type default template alias. + return string.IsNullOrWhiteSpace(source.ContentType.DefaultTemplate?.Alias) + ? null + : source.ContentType.DefaultTemplate?.Alias; } + + var template = _fileService.GetTemplate(source.TemplateId.Value); + return template.Alias; } } - } diff --git a/src/Umbraco.Web/Models/Mapping/ContentSavedStateResolver.cs b/src/Umbraco.Web/Models/Mapping/ContentSavedStateMapper.cs similarity index 75% rename from src/Umbraco.Web/Models/Mapping/ContentSavedStateResolver.cs rename to src/Umbraco.Web/Models/Mapping/ContentSavedStateMapper.cs index 2b0395b2c6..dfb334621d 100644 --- a/src/Umbraco.Web/Models/Mapping/ContentSavedStateResolver.cs +++ b/src/Umbraco.Web/Models/Mapping/ContentSavedStateMapper.cs @@ -1,24 +1,23 @@ using System; -using AutoMapper; using Umbraco.Core; +using Umbraco.Core.Mapping; using Umbraco.Core.Models; using Umbraco.Web.Models.ContentEditing; namespace Umbraco.Web.Models.Mapping { - /// /// Returns the for an item /// /// - internal class ContentBasicSavedStateResolver : IValueResolver, ContentSavedState?> + internal class ContentBasicSavedStateMapper where T : ContentPropertyBasic { - private readonly ContentSavedStateResolver _inner = new ContentSavedStateResolver(); + private readonly ContentSavedStateMapper _inner = new ContentSavedStateMapper(); - public ContentSavedState? Resolve(IContent source, IContentProperties destination, ContentSavedState? destMember, ResolutionContext context) + public ContentSavedState? Map(IContent source, MapperContext context) { - return _inner.Resolve(source, destination, default, context); + return _inner.Map(source, context); } } @@ -26,10 +25,10 @@ namespace Umbraco.Web.Models.Mapping /// Returns the for an item /// /// - internal class ContentSavedStateResolver : IValueResolver, ContentSavedState> + internal class ContentSavedStateMapper where T : ContentPropertyBasic { - public ContentSavedState Resolve(IContent source, IContentProperties destination, ContentSavedState destMember, ResolutionContext context) + public ContentSavedState Map(IContent source, MapperContext context) { PublishedState publishedState; bool isEdited; @@ -38,7 +37,7 @@ namespace Umbraco.Web.Models.Mapping if (source.ContentType.VariesByCulture()) { //Get the culture from the context which will be set during the mapping operation for each variant - var culture = context.Options.GetCulture(); + var culture = context.GetCulture(); //a culture needs to be in the context for a variant content item if (culture == null) diff --git a/src/Umbraco.Web/Models/Mapping/ContentTreeNodeUrlResolver.cs b/src/Umbraco.Web/Models/Mapping/ContentTreeNodeUrlResolver.cs deleted file mode 100644 index 91420fbe21..0000000000 --- a/src/Umbraco.Web/Models/Mapping/ContentTreeNodeUrlResolver.cs +++ /dev/null @@ -1,31 +0,0 @@ -using System.Web.Mvc; -using AutoMapper; -using Umbraco.Core.Models; -using Umbraco.Web.Trees; - -namespace Umbraco.Web.Models.Mapping -{ - /// - /// Gets the tree node url for the content or media - /// - internal class ContentTreeNodeUrlResolver : IValueResolver - where TSource : IContentBase - where TController : ContentTreeControllerBase - { - private readonly IUmbracoContextAccessor _umbracoContextAccessor; - - public ContentTreeNodeUrlResolver(IUmbracoContextAccessor umbracoContextAccessor) - { - _umbracoContextAccessor = umbracoContextAccessor ?? throw new System.ArgumentNullException(nameof(umbracoContextAccessor)); - } - - public string Resolve(TSource source, object destination, string destMember, ResolutionContext context) - { - var umbracoContext = _umbracoContextAccessor.UmbracoContext; - if (umbracoContext == null) return null; - - var urlHelper = new UrlHelper(umbracoContext.HttpContext.Request.RequestContext); - return urlHelper.GetUmbracoApiService(controller => controller.GetTreeNode(source.Key.ToString("N"), null)); - } - } -} diff --git a/src/Umbraco.Web/Models/Mapping/ContentTypeBasicResolver.cs b/src/Umbraco.Web/Models/Mapping/ContentTypeBasicResolver.cs deleted file mode 100644 index 8b5f3d4296..0000000000 --- a/src/Umbraco.Web/Models/Mapping/ContentTypeBasicResolver.cs +++ /dev/null @@ -1,43 +0,0 @@ -using System; -using System.Linq; -using System.Web; -using AutoMapper; -using Umbraco.Core; -using Umbraco.Core.Models; -using Umbraco.Core.Services; -using Umbraco.Web.Composing; -using Umbraco.Web.Models.ContentEditing; - -namespace Umbraco.Web.Models.Mapping -{ - /// - /// Resolves a from the item and checks if the current user - /// has access to see this data - /// - internal class ContentTypeBasicResolver : IValueResolver - where TSource : IContentBase - { - private readonly IContentTypeBaseServiceProvider _contentTypeBaseServiceProvider; - - public ContentTypeBasicResolver(IContentTypeBaseServiceProvider contentTypeBaseServiceProvider) - { - _contentTypeBaseServiceProvider = contentTypeBaseServiceProvider; - } - - public ContentTypeBasic Resolve(TSource source, TDestination destination, ContentTypeBasic destMember, ResolutionContext context) - { - // TODO: We can resolve the UmbracoContext from the IValueResolver options! - // OMG - if (HttpContext.Current != null && Current.UmbracoContext != null && Current.UmbracoContext.Security.CurrentUser != null - && Current.UmbracoContext.Security.CurrentUser.AllowedSections.Any(x => x.Equals(Constants.Applications.Settings))) - { - var contentType = _contentTypeBaseServiceProvider.GetContentTypeOf(source); - var contentTypeBasic = Mapper.Map(contentType); - - return contentTypeBasic; - } - //no access - return null; - } - } -} diff --git a/src/Umbraco.Web/Models/Mapping/ContentUrlResolver.cs b/src/Umbraco.Web/Models/Mapping/ContentUrlResolver.cs deleted file mode 100644 index 42c4997d86..0000000000 --- a/src/Umbraco.Web/Models/Mapping/ContentUrlResolver.cs +++ /dev/null @@ -1,52 +0,0 @@ -using System.Linq; -using AutoMapper; -using Umbraco.Core.Logging; -using Umbraco.Core.Models; -using Umbraco.Core.Services; -using Umbraco.Web.Models.ContentEditing; -using Umbraco.Web.Routing; - -namespace Umbraco.Web.Models.Mapping -{ - internal class ContentUrlResolver : IValueResolver - { - private readonly IUmbracoContextAccessor _umbracoContextAccessor; - private readonly IPublishedRouter _publishedRouter; - private readonly ILocalizationService _localizationService; - private readonly ILocalizedTextService _textService; - private readonly IContentService _contentService; - private readonly ILogger _logger; - - public ContentUrlResolver( - IUmbracoContextAccessor umbracoContextAccessor, - IPublishedRouter publishedRouter, - ILocalizationService localizationService, - ILocalizedTextService textService, - IContentService contentService, - ILogger logger) - { - _umbracoContextAccessor = umbracoContextAccessor ?? throw new System.ArgumentNullException(nameof(umbracoContextAccessor)); - _publishedRouter = publishedRouter ?? throw new System.ArgumentNullException(nameof(publishedRouter)); - _localizationService = localizationService ?? throw new System.ArgumentNullException(nameof(localizationService)); - _textService = textService ?? throw new System.ArgumentNullException(nameof(textService)); - _contentService = contentService ?? throw new System.ArgumentNullException(nameof(contentService)); - _logger = logger ?? throw new System.ArgumentNullException(nameof(logger)); - } - - public UrlInfo[] Resolve(IContent source, ContentItemDisplay destination, UrlInfo[] destMember, ResolutionContext context) - { - if (source.ContentType.IsElement) - { - return new UrlInfo[0]; - } - - var umbracoContext = _umbracoContextAccessor.UmbracoContext; - - var urls = umbracoContext == null - ? new[] { UrlInfo.Message("Cannot generate urls without a current Umbraco Context") } - : source.GetContentUrls(_publishedRouter, umbracoContext, _localizationService, _textService, _contentService, _logger).ToArray(); - - return urls; - } - } -} diff --git a/src/Umbraco.Web/Models/Mapping/ContentItemDisplayVariationResolver.cs b/src/Umbraco.Web/Models/Mapping/ContentVariantMapper.cs similarity index 84% rename from src/Umbraco.Web/Models/Mapping/ContentItemDisplayVariationResolver.cs rename to src/Umbraco.Web/Models/Mapping/ContentVariantMapper.cs index 01e57bd872..aabf1a4e60 100644 --- a/src/Umbraco.Web/Models/Mapping/ContentItemDisplayVariationResolver.cs +++ b/src/Umbraco.Web/Models/Mapping/ContentVariantMapper.cs @@ -1,8 +1,8 @@ using System; using System.Collections.Generic; using System.Linq; -using AutoMapper; using Umbraco.Core; +using Umbraco.Core.Mapping; using Umbraco.Core.Models; using Umbraco.Core.Services; using Umbraco.Web.Models.ContentEditing; @@ -10,16 +10,16 @@ using Language = Umbraco.Web.Models.ContentEditing.Language; namespace Umbraco.Web.Models.Mapping { - internal class ContentVariantResolver : IValueResolver> + internal class ContentVariantMapper { private readonly ILocalizationService _localizationService; - public ContentVariantResolver(ILocalizationService localizationService) + public ContentVariantMapper(ILocalizationService localizationService) { _localizationService = localizationService ?? throw new ArgumentNullException(nameof(localizationService)); } - public IEnumerable Resolve(IContent source, ContentItemDisplay destination, IEnumerable destMember, ResolutionContext context) + public IEnumerable Map(IContent source, MapperContext context) { var result = new List(); if (!source.ContentType.VariesByCulture()) @@ -39,7 +39,7 @@ namespace Umbraco.Web.Models.Mapping { //We need to set the culture in the mapping context since this is needed to ensure that the correct property values //are resolved during the mapping - context.Options.SetCulture(x.IsoCode); + context.SetCulture(x.IsoCode); return context.Mapper.Map(source, null, context); }).ToList(); @@ -69,5 +69,4 @@ namespace Umbraco.Web.Models.Mapping return result; } } - } diff --git a/src/Umbraco.Web/Models/Mapping/CreatorResolver.cs b/src/Umbraco.Web/Models/Mapping/CreatorResolver.cs deleted file mode 100644 index 40ebc801eb..0000000000 --- a/src/Umbraco.Web/Models/Mapping/CreatorResolver.cs +++ /dev/null @@ -1,27 +0,0 @@ -using AutoMapper; -using Umbraco.Core; -using Umbraco.Core.Models; -using Umbraco.Core.Models.Membership; -using Umbraco.Core.Services; -using UserProfile = Umbraco.Web.Models.ContentEditing.UserProfile; - -namespace Umbraco.Web.Models.Mapping -{ - /// - /// Maps the Creator for content - /// - internal class CreatorResolver - { - private readonly IUserService _userService; - - public CreatorResolver(IUserService userService) - { - _userService = userService; - } - - public UserProfile Resolve(IContent source) - { - return Mapper.Map(source.GetWriterProfile(_userService)); - } - } -} diff --git a/src/Umbraco.Web/Models/Mapping/DefaultTemplateResolver.cs b/src/Umbraco.Web/Models/Mapping/DefaultTemplateResolver.cs deleted file mode 100644 index 12caf93681..0000000000 --- a/src/Umbraco.Web/Models/Mapping/DefaultTemplateResolver.cs +++ /dev/null @@ -1,33 +0,0 @@ -using AutoMapper; -using System.Web.Mvc; -using Umbraco.Core.Models; -using Umbraco.Core.Services; -using Umbraco.Web.Models.ContentEditing; - -namespace Umbraco.Web.Models.Mapping -{ - internal class DefaultTemplateResolver : IValueResolver - { - public string Resolve(IContent source, ContentItemDisplay destination, string destMember, ResolutionContext context) - { - if (source == null) - return null; - - // If no template id was set... - if (!source.TemplateId.HasValue) - { - // ... and no default template is set, return null... - if (string.IsNullOrWhiteSpace(source.ContentType.DefaultTemplate?.Alias)) - return null; - - // ... otherwise return the content type default template alias. - return source.ContentType.DefaultTemplate?.Alias; - } - - var fileService = DependencyResolver.Current.GetService(); - var template = fileService.GetTemplate(source.TemplateId.Value); - - return template.Alias; - } - } -} diff --git a/src/Umbraco.Web/Models/Mapping/EntityProfileExtensions.cs b/src/Umbraco.Web/Models/Mapping/EntityProfileExtensions.cs deleted file mode 100644 index 46d48c2b1a..0000000000 --- a/src/Umbraco.Web/Models/Mapping/EntityProfileExtensions.cs +++ /dev/null @@ -1,26 +0,0 @@ -using AutoMapper; -using Umbraco.Core.Models.Entities; - -namespace Umbraco.Web.Models.Mapping -{ - /// - /// Mapping extension methods for re-use with other mappers (saves code duplication) - /// - internal static class EntityProfileExtensions - { - /// - /// Ignores readonly properties and the date values - /// - /// - /// - public static IMappingExpression IgnoreEntityCommonProperties(this IMappingExpression mapping) - where TDest : IEntity - { - return mapping - .IgnoreAllPropertiesWithAnInaccessibleSetter() - .ForMember(dest => dest.CreateDate, opt => opt.Ignore()) - .ForMember(dest => dest.UpdateDate, opt => opt.Ignore()) - .ForMember(dest => dest.DeleteDate, opt => opt.Ignore()); - } - } -} diff --git a/src/Umbraco.Web/Models/Mapping/LockedCompositionsResolver.cs b/src/Umbraco.Web/Models/Mapping/LockedCompositionsResolver.cs deleted file mode 100644 index f1dcd2d40f..0000000000 --- a/src/Umbraco.Web/Models/Mapping/LockedCompositionsResolver.cs +++ /dev/null @@ -1,44 +0,0 @@ -using AutoMapper; -using System.Collections.Generic; -using System.Linq; -using Umbraco.Core; -using Umbraco.Core.Models; -using Umbraco.Core.Services; - -namespace Umbraco.Web.Models.Mapping -{ - internal class LockedCompositionsResolver - { - private readonly IContentTypeService _contentTypeService; - - public LockedCompositionsResolver(IContentTypeService contentTypeService) - { - _contentTypeService = contentTypeService; - } - - public IEnumerable Resolve(IContentTypeComposition source) - { - var aliases = new List(); - // get ancestor ids from path of parent if not root - if (source.ParentId != Constants.System.Root) - { - var parent = _contentTypeService.Get(source.ParentId); - if (parent != null) - { - var ancestorIds = parent.Path.Split(',').Select(int.Parse); - // loop through all content types and return ordered aliases of ancestors - var allContentTypes = _contentTypeService.GetAll().ToArray(); - foreach (var ancestorId in ancestorIds) - { - var ancestor = allContentTypes.FirstOrDefault(x => x.Id == ancestorId); - if (ancestor != null) - { - aliases.Add(ancestor.Alias); - } - } - } - } - return aliases.OrderBy(x => x); - } - } -} diff --git a/src/Umbraco.Web/Models/Mapping/MappingOperationOptionsExtensions.cs b/src/Umbraco.Web/Models/Mapping/MappingOperationOptionsExtensions.cs deleted file mode 100644 index 10c52ff8c3..0000000000 --- a/src/Umbraco.Web/Models/Mapping/MappingOperationOptionsExtensions.cs +++ /dev/null @@ -1,38 +0,0 @@ -using AutoMapper; - -namespace Umbraco.Web.Models.Mapping -{ - // FIXME KILLE THIS CLASS - /// - /// Provides extension methods for AutoMapper's . - /// - internal static class MappingOperationOptionsExtensions - { - private const string CultureKey = "MappingOperationOptions.Culture"; - private const string IncludedPropertiesKey = "MappingOperationOptions.IncludeProperties"; - - /// - /// Gets the context culture. - /// - public static string GetCulture(this IMappingOperationOptions options) - { - return options.Items.TryGetValue(CultureKey, out var obj) && obj is string s ? s : null; - } - - /// - /// Sets a context culture. - /// - public static void SetCulture(this IMappingOperationOptions options, string culture) - { - options.Items[CultureKey] = culture; - } - - /// - /// Get included properties. - /// - public static string[] GetIncludedProperties(this IMappingOperationOptions options) - { - return options.Items.TryGetValue(IncludedPropertiesKey, out var obj) && obj is string[] s ? s : null; - } - } -} diff --git a/src/Umbraco.Web/Models/Mapping/MediaAppResolver.cs b/src/Umbraco.Web/Models/Mapping/MediaAppResolver.cs deleted file mode 100644 index 2e3afac549..0000000000 --- a/src/Umbraco.Web/Models/Mapping/MediaAppResolver.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System.Collections.Generic; -using AutoMapper; -using Umbraco.Core.Models; -using Umbraco.Core.Models.ContentEditing; -using Umbraco.Web.ContentApps; -using Umbraco.Web.Models.ContentEditing; - -namespace Umbraco.Web.Models.Mapping -{ - // injected into ContentMapperProfile, - // maps ContentApps when mapping IMedia to MediaItemDisplay - internal class MediaAppResolver : IValueResolver> - { - private readonly ContentAppFactoryCollection _contentAppDefinitions; - - public MediaAppResolver(ContentAppFactoryCollection contentAppDefinitions) - { - _contentAppDefinitions = contentAppDefinitions; - } - - public IEnumerable Resolve(IMedia source, MediaItemDisplay destination, IEnumerable destMember, ResolutionContext context) - { - return _contentAppDefinitions.GetContentAppsFor(source); - } - } -} diff --git a/src/Umbraco.Web/Models/Mapping/MediaChildOfListViewResolver.cs b/src/Umbraco.Web/Models/Mapping/MediaChildOfListViewResolver.cs deleted file mode 100644 index 997c900f84..0000000000 --- a/src/Umbraco.Web/Models/Mapping/MediaChildOfListViewResolver.cs +++ /dev/null @@ -1,26 +0,0 @@ -using AutoMapper; -using Umbraco.Core.Models; -using Umbraco.Core.Services; -using Umbraco.Web.Models.ContentEditing; - -namespace Umbraco.Web.Models.Mapping -{ - internal class MediaChildOfListViewResolver : IValueResolver - { - private readonly IMediaService _mediaService; - private readonly IMediaTypeService _mediaTypeService; - - public MediaChildOfListViewResolver(IMediaService mediaService, IMediaTypeService mediaTypeService) - { - _mediaService = mediaService; - _mediaTypeService = mediaTypeService; - } - - public bool Resolve(IMedia source, MediaItemDisplay destination, bool destMember, ResolutionContext context) - { - // map the IsChildOfListView (this is actually if it is a descendant of a list view!) - var parent = _mediaService.GetParent(source); - return parent != null && (parent.ContentType.IsContainer || _mediaTypeService.HasContainerInPath(parent.Path)); - } - } -} diff --git a/src/Umbraco.Web/Models/Mapping/MediaMapperProfile.cs b/src/Umbraco.Web/Models/Mapping/MediaMapperProfile.cs index e9c45bba9a..f2cc0b91d8 100644 --- a/src/Umbraco.Web/Models/Mapping/MediaMapperProfile.cs +++ b/src/Umbraco.Web/Models/Mapping/MediaMapperProfile.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; @@ -7,6 +8,7 @@ using Umbraco.Core.Composing; using Umbraco.Core.Logging; using Umbraco.Core.Mapping; using Umbraco.Core.Models; +using Umbraco.Core.Models.ContentEditing; using Umbraco.Core.Models.Membership; using Umbraco.Core.Services; using Umbraco.Web.ContentApps; @@ -21,26 +23,19 @@ namespace Umbraco.Web.Models.Mapping /// internal class MediaMapperProfile : IMapperProfile { + private readonly CommonMapper _commonMapper; private readonly ILogger _logger; - private readonly IUserService _userService; private readonly IMediaService _mediaService; private readonly IMediaTypeService _mediaTypeService; - private readonly IContentTypeBaseServiceProvider _contentTypeBaseServiceProvider; - private readonly ContentAppFactoryCollection _contentAppDefinitions; - private readonly IUmbracoContextAccessor _umbracoContextAccessor; private readonly TabsAndPropertiesMapper _tabsAndPropertiesMapper; - public MediaMapperProfile(ILogger logger, IUserService userService, IMediaService mediaService, IMediaTypeService mediaTypeService, - IContentTypeBaseServiceProvider contentTypeBaseServiceProvider, ContentAppFactoryCollection contentAppDefinitions, - IUmbracoContextAccessor umbracoContextAccessor, ILocalizedTextService localizedTextService) + public MediaMapperProfile(ILogger logger, CommonMapper commonMapper, IMediaService mediaService, IMediaTypeService mediaTypeService, + ILocalizedTextService localizedTextService) { _logger = logger; - _userService = userService; + _commonMapper = commonMapper; _mediaService = mediaService; _mediaTypeService = mediaTypeService; - _contentTypeBaseServiceProvider = contentTypeBaseServiceProvider; - _contentAppDefinitions = contentAppDefinitions; - _umbracoContextAccessor = umbracoContextAccessor; _tabsAndPropertiesMapper = new TabsAndPropertiesMapper(localizedTextService); } @@ -54,8 +49,8 @@ namespace Umbraco.Web.Models.Mapping // Umbraco.Code.MapAll -Properties -Errors -Edited -Updater -Alias -IsContainer private void Map(IMedia source, MediaItemDisplay target, MapperContext context) { - target.ContentApps = _contentAppDefinitions.GetContentAppsFor(source); - target.ContentType = GetContentType(source, context.Mapper); + target.ContentApps = _commonMapper.GetContentApps(source); + target.ContentType = _commonMapper.GetContentType(source, context.Mapper); target.ContentTypeAlias = source.ContentType.Alias; target.ContentTypeName = source.ContentType.Name; target.CreateDate = source.CreateDate; @@ -65,14 +60,14 @@ namespace Umbraco.Web.Models.Mapping target.Key = source.Key; target.MediaLink = string.Join(",", source.GetUrls(Current.Configs.Settings().Content, _logger)); target.Name = source.Name; - target.Owner = GetOwner(source, context.Mapper); + target.Owner = _commonMapper.GetOwner(source, context.Mapper); target.ParentId = source.ParentId; target.Path = source.Path; target.SortOrder = source.SortOrder; target.State = null; target.Tabs = _tabsAndPropertiesMapper.Map(source, context); target.Trashed = source.Trashed; - target.TreeNodeUrl = GetTreeNodeUrl(source); + target.TreeNodeUrl = _commonMapper.GetTreeNodeUrl(source); target.Udi = Udi.Create(Constants.UdiEntityType.Media, source.Key); target.UpdateDate = source.UpdateDate; target.VariesByCulture = source.ContentType.VariesByCulture(); @@ -87,7 +82,7 @@ namespace Umbraco.Web.Models.Mapping target.Id = source.Id; target.Key = source.Key; target.Name = source.Name; - target.Owner = GetOwner(source, context.Mapper); + target.Owner = _commonMapper.GetOwner(source, context.Mapper); target.ParentId = source.ParentId; target.Path = source.Path; target.Properties = context.Mapper.Map>(source.Properties); @@ -99,20 +94,46 @@ namespace Umbraco.Web.Models.Mapping target.VariesByCulture = source.ContentType.VariesByCulture(); } - private UserProfile GetOwner(IContentBase source, Mapper mapper) - { - var profile = source.GetCreatorProfile(_userService); - return profile == null ? null : mapper.Map(profile); - } - private bool DermineIsChildOfListView(IMedia source) { // map the IsChildOfListView (this is actually if it is a descendant of a list view!) var parent = _mediaService.GetParent(source); return parent != null && (parent.ContentType.IsContainer || _mediaTypeService.HasContainerInPath(parent.Path)); } + } - private ContentTypeBasic GetContentType(IContentBase source, Mapper mapper) + // fixme temp + rename + internal class CommonMapper + { + private readonly IUserService _userService; + private readonly IContentTypeBaseServiceProvider _contentTypeBaseServiceProvider; + private readonly IUmbracoContextAccessor _umbracoContextAccessor; + private readonly ContentAppFactoryCollection _contentAppDefinitions; + private readonly ILocalizedTextService _localizedTextService; + + public CommonMapper(IUserService userService, IContentTypeBaseServiceProvider contentTypeBaseServiceProvider, IUmbracoContextAccessor umbracoContextAccessor, + ContentAppFactoryCollection contentAppDefinitions, ILocalizedTextService localizedTextService) + { + _userService = userService; + _contentTypeBaseServiceProvider = contentTypeBaseServiceProvider; + _umbracoContextAccessor = umbracoContextAccessor; + _contentAppDefinitions = contentAppDefinitions; + _localizedTextService = localizedTextService; + } + + public UserProfile GetOwner(IContentBase source, Mapper mapper) + { + var profile = source.GetCreatorProfile(_userService); + return profile == null ? null : mapper.Map(profile); + } + + public UserProfile GetCreator(IContent source, Mapper mapper) + { + var profile = source.GetWriterProfile(_userService); + return profile == null ? null : mapper.Map(profile); + } + + public ContentTypeBasic GetContentType(IContentBase source, Mapper mapper) { // TODO: We can resolve the UmbracoContext from the IValueResolver options! // OMG @@ -128,7 +149,7 @@ namespace Umbraco.Web.Models.Mapping return null; } - private string GetTreeNodeUrl(IContentBase source) + public string GetTreeNodeUrl(IContentBase source) where TController : ContentTreeControllerBase { var umbracoContext = _umbracoContextAccessor.UmbracoContext; @@ -137,5 +158,31 @@ namespace Umbraco.Web.Models.Mapping var urlHelper = new UrlHelper(umbracoContext.HttpContext.Request.RequestContext); return urlHelper.GetUmbracoApiService(controller => controller.GetTreeNode(source.Key.ToString("N"), null)); } + + public string GetMemberTreeNodeUrl(IContentBase source) + { + var umbracoContext = _umbracoContextAccessor.UmbracoContext; + if (umbracoContext == null) return null; + + var urlHelper = new UrlHelper(umbracoContext.HttpContext.Request.RequestContext); + return urlHelper.GetUmbracoApiService(controller => controller.GetTreeNode(source.Key.ToString("N"), null)); + } + + public IEnumerable GetContentApps(IContentBase source) + { + var apps = _contentAppDefinitions.GetContentAppsFor(source).ToArray(); + + // localize content app names + foreach (var app in apps) + { + var localizedAppName = _localizedTextService.Localize($"apps/{app.Alias}"); + if (localizedAppName.Equals($"[{app.Alias}]", StringComparison.OrdinalIgnoreCase) == false) + { + app.Name = localizedAppName; + } + } + + return apps; + } } } diff --git a/src/Umbraco.Web/Models/Mapping/MemberBasicPropertiesResolver.cs b/src/Umbraco.Web/Models/Mapping/MemberBasicPropertiesResolver.cs deleted file mode 100644 index e1ee0631a9..0000000000 --- a/src/Umbraco.Web/Models/Mapping/MemberBasicPropertiesResolver.cs +++ /dev/null @@ -1,54 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using AutoMapper; -using Umbraco.Core.Models; -using Umbraco.Core.Services; -using Umbraco.Web.Models.ContentEditing; - -namespace Umbraco.Web.Models.Mapping -{ - /// - /// A resolver to map properties to a collection of - /// - internal class MemberBasicPropertiesResolver : IValueResolver> - { - private readonly IUmbracoContextAccessor _umbracoContextAccessor; - private readonly IMemberTypeService _memberTypeService; - - public MemberBasicPropertiesResolver(IUmbracoContextAccessor umbracoContextAccessor, IMemberTypeService memberTypeService) - { - _umbracoContextAccessor = umbracoContextAccessor ?? throw new ArgumentNullException(nameof(umbracoContextAccessor)); - _memberTypeService = memberTypeService ?? throw new ArgumentNullException(nameof(memberTypeService)); - } - - public IEnumerable Resolve(IMember source, MemberBasic destination, IEnumerable destMember, ResolutionContext context) - { - var umbracoContext = _umbracoContextAccessor.UmbracoContext; - if (umbracoContext == null) throw new InvalidOperationException("Cannot resolve value without an UmbracoContext available"); - - var result = Mapper.Map, IEnumerable>( - // Sort properties so items from different compositions appear in correct order (see U4-9298). Map sorted properties. - source.Properties.OrderBy(prop => prop.PropertyType.SortOrder)) - .ToList(); - - var memberType = _memberTypeService.Get(source.ContentTypeId); - - //now update the IsSensitive value - foreach (var prop in result) - { - //check if this property is flagged as sensitive - var isSensitiveProperty = memberType.IsSensitiveProperty(prop.Alias); - //check permissions for viewing sensitive data - if (isSensitiveProperty && umbracoContext.Security.CurrentUser.HasAccessToSensitiveData() == false) - { - //mark this property as sensitive - prop.IsSensitive = true; - //clear the value - prop.Value = null; - } - } - return result; - } - } -} diff --git a/src/Umbraco.Web/Models/Mapping/MemberDtoPropertiesResolver.cs b/src/Umbraco.Web/Models/Mapping/MemberDtoPropertiesResolver.cs deleted file mode 100644 index 0d6478d737..0000000000 --- a/src/Umbraco.Web/Models/Mapping/MemberDtoPropertiesResolver.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using AutoMapper; -using Umbraco.Core; -using Umbraco.Core.Models; -using Umbraco.Web.Models.ContentEditing; - -namespace Umbraco.Web.Models.Mapping -{ - /// - /// This ensures that the custom membership provider properties are not mapped - these property values are controller by the membership provider - /// - /// - /// Because these properties don't exist on the form, if we don't remove them for this map we'll get validation errors when posting data - /// - internal class MemberDtoPropertiesResolver - { - public IEnumerable Resolve(IMember source) - { - var defaultProps = Constants.Conventions.Member.GetStandardPropertyTypeStubs(); - - //remove all membership properties, these values are set with the membership provider. - var exclude = defaultProps.Select(x => x.Value.Alias).ToArray(); - - return source.Properties - .Where(x => exclude.Contains(x.Alias) == false) - .Select(Mapper.Map); - } - } -} diff --git a/src/Umbraco.Web/Models/Mapping/MemberMapperProfile.cs b/src/Umbraco.Web/Models/Mapping/MemberMapperProfile.cs index a2410495b9..08c7a53bd0 100644 --- a/src/Umbraco.Web/Models/Mapping/MemberMapperProfile.cs +++ b/src/Umbraco.Web/Models/Mapping/MemberMapperProfile.cs @@ -1,154 +1,185 @@ using System; +using System.Collections.Generic; using System.Web.Security; -using AutoMapper; using Umbraco.Core; +using Umbraco.Core.Mapping; using Umbraco.Core.Models; +using Umbraco.Core.Models.Membership; +using Umbraco.Core.Security; using Umbraco.Core.Services; using Umbraco.Web.Models.ContentEditing; using Umbraco.Core.Services.Implement; +using UserProfile = Umbraco.Web.Models.ContentEditing.UserProfile; namespace Umbraco.Web.Models.Mapping { /// /// Declares model mappings for members. /// - internal class MemberMapperProfile : Profile + internal class MemberMapperProfile : IMapperProfile { - public MemberMapperProfile( - MemberTabsAndPropertiesMapper tabsAndPropertiesMapper, - MemberTreeNodeUrlResolver memberTreeNodeUrlResolver, - MemberBasicPropertiesResolver memberBasicPropertiesResolver, - IUserService userService, - IMemberTypeService memberTypeService, - IMemberService memberService) + private readonly CommonMapper _commonMapper; + private readonly IMemberTypeService _memberTypeService; + private readonly TabsAndPropertiesMapper _tabsAndPropertiesMapper; + + public MemberMapperProfile(CommonMapper commonMapper, IMemberTypeService memberTypeService, ILocalizedTextService localizedTextService) { - // create, capture, cache - var memberOwnerResolver = new OwnerResolver(userService); - var memberProfiderFieldMappingResolver = new MemberProviderFieldResolver(); - var membershipScenarioMappingResolver = new MembershipScenarioResolver(memberTypeService); - var memberDtoPropertiesResolver = new MemberDtoPropertiesResolver(); + _commonMapper = commonMapper; + _memberTypeService = memberTypeService; - //FROM MembershipUser TO MediaItemDisplay - used when using a non-umbraco membership provider - CreateMap().ConvertUsing(); + _tabsAndPropertiesMapper = new TabsAndPropertiesMapper(localizedTextService); + } - //FROM MembershipUser TO IMember - used when using a non-umbraco membership provider - CreateMap() - .ConstructUsing(src => MemberService.CreateGenericMembershipProviderMember(src.UserName, src.Email, src.UserName, "")) - //we're giving this entity an ID of int.MaxValue - TODO: SD: I can't remember why this mapping is here? - .ForMember(dest => dest.Id, opt => opt.MapFrom(src => int.MaxValue)) - .ForMember(dest => dest.Comments, opt => opt.MapFrom(src => src.Comment)) - .ForMember(dest => dest.CreateDate, opt => opt.MapFrom(src => src.CreationDate)) - .ForMember(dest => dest.UpdateDate, opt => opt.MapFrom(src => src.LastActivityDate)) - .ForMember(dest => dest.LastPasswordChangeDate, opt => opt.MapFrom(src => src.LastPasswordChangedDate)) - .ForMember(dest => dest.Key, opt => opt.MapFrom(src => src.ProviderUserKey.TryConvertTo().Result.ToString("N"))) - //This is a special case for password - we don't actually care what the password is but it either needs to be something or nothing - // so we'll set it to something if the member is actually created, otherwise nothing if it is a new member. - .ForMember(dest => dest.RawPasswordValue, opt => opt.MapFrom(src => src.CreationDate > DateTime.MinValue ? Guid.NewGuid().ToString("N") : "")) - .ForMember(dest => dest.Properties, opt => opt.Ignore()) - .ForMember(dest => dest.CreatorId, opt => opt.Ignore()) - .ForMember(dest => dest.Level, opt => opt.Ignore()) - .ForMember(dest => dest.Name, opt => opt.Ignore()) - .ForMember(dest => dest.CultureInfos, opt => opt.Ignore()) - .ForMember(dest => dest.ParentId, opt => opt.Ignore()) - .ForMember(dest => dest.Path, opt => opt.Ignore()) - .ForMember(dest => dest.SortOrder, opt => opt.Ignore()) - .ForMember(dest => dest.AdditionalData, opt => opt.Ignore()) - .ForMember(dest => dest.FailedPasswordAttempts, opt => opt.Ignore()) - .ForMember(dest => dest.DeleteDate, opt => opt.Ignore()) - .ForMember(dest => dest.WriterId, opt => opt.Ignore()) - .ForMember(dest => dest.VersionId, opt => opt.Ignore()) - // TODO: Support these eventually - .ForMember(dest => dest.PasswordQuestion, opt => opt.Ignore()) - .ForMember(dest => dest.RawPasswordAnswerValue, opt => opt.Ignore()); + public void SetMaps(Mapper mapper) + { + mapper.Define((source, context) => new MemberDisplay(), Map); + mapper.Define((source, context) => MemberService.CreateGenericMembershipProviderMember(source.UserName, source.Email, source.UserName, ""), Map); + mapper.Define((source, context) => new MemberDisplay(), Map); + mapper.Define((source, context) => new MemberBasic(), Map); + mapper.Define((source, context) => new MemberBasic(), Map); + mapper.Define((source, context) => new MemberGroupDisplay(), Map); + } - //FROM IMember TO MemberDisplay - CreateMap() - .ForMember(dest => dest.Udi, opt => opt.MapFrom(content => Udi.Create(Constants.UdiEntityType.Member, content.Key))) - .ForMember(dest => dest.Owner, opt => opt.MapFrom(src => memberOwnerResolver.Resolve(src))) - .ForMember(dest => dest.Icon, opt => opt.MapFrom(src => src.ContentType.Icon)) - .ForMember(dest => dest.ContentTypeAlias, opt => opt.MapFrom(src => src.ContentType.Alias)) - .ForMember(dest => dest.ContentTypeName, opt => opt.MapFrom(src => src.ContentType.Name)) - .ForMember(dest => dest.Properties, opt => opt.Ignore()) - .ForMember(dest => dest.Tabs, opt => opt.MapFrom(tabsAndPropertiesMapper)) - .ForMember(dest => dest.MemberProviderFieldMapping, opt => opt.MapFrom(src => memberProfiderFieldMappingResolver.Resolve(src))) - .ForMember(dest => dest.MembershipScenario, opt => opt.MapFrom(src => membershipScenarioMappingResolver.Resolve(src))) - .ForMember(dest => dest.Notifications, opt => opt.Ignore()) - .ForMember(dest => dest.Errors, opt => opt.Ignore()) - .ForMember(dest => dest.State, opt => opt.MapFrom(_ => null)) - .ForMember(dest => dest.Edited, opt => opt.Ignore()) - .ForMember(dest => dest.Updater, opt => opt.Ignore()) - .ForMember(dest => dest.Alias, opt => opt.Ignore()) - .ForMember(dest => dest.IsChildOfListView, opt => opt.Ignore()) - .ForMember(dest => dest.Trashed, opt => opt.Ignore()) - .ForMember(dest => dest.IsContainer, opt => opt.Ignore()) - .ForMember(dest => dest.TreeNodeUrl, opt => opt.MapFrom(memberTreeNodeUrlResolver)) - .ForMember(dest => dest.VariesByCulture, opt => opt.Ignore()); + private void Map(MembershipUser source, MemberDisplay target, MapperContext context) + { + //first convert to IMember + var member = context.Mapper.Map(source); + //then convert to MemberDisplay + context.Mapper.Map(member); + } - //FROM IMember TO MemberBasic - CreateMap() - //we're giving this entity an ID of int.MaxValue - this is kind of a hack to force angular to use the Key instead of the Id in list views - .ForMember(dest => dest.Id, opt => opt.MapFrom(src => int.MaxValue)) - .ForMember(dest => dest.Udi, opt => opt.MapFrom(content => Udi.Create(Constants.UdiEntityType.Member, content.Key))) - .ForMember(dest => dest.Owner, opt => opt.MapFrom(src => memberOwnerResolver.Resolve(src))) - .ForMember(dest => dest.Icon, opt => opt.MapFrom(src => src.ContentType.Icon)) - .ForMember(dest => dest.ContentTypeAlias, opt => opt.MapFrom(src => src.ContentType.Alias)) - .ForMember(dest => dest.Email, opt => opt.MapFrom(src => src.Email)) - .ForMember(dest => dest.Username, opt => opt.MapFrom(src => src.Username)) - .ForMember(dest => dest.Trashed, opt => opt.Ignore()) - .ForMember(dest => dest.State, opt => opt.MapFrom(_ => null)) - .ForMember(dest => dest.Edited, opt => opt.Ignore()) - .ForMember(dest => dest.Updater, opt => opt.Ignore()) - .ForMember(dest => dest.Alias, opt => opt.Ignore()) - .ForMember(dto => dto.Properties, expression => expression.MapFrom(memberBasicPropertiesResolver)) - .ForMember(dest => dest.VariesByCulture, opt => opt.Ignore()); + // TODO: SD: I can't remember why this mapping is here? + // Umbraco.Code.MapAll -Properties -CreatorId -Level -Name -CultureInfos -ParentId + // Umbraco.Code.MapAll -Path -SortOrder -DeleteDate -WriterId -VersionId -PasswordQuestion + // Umbraco.Code.MapAll -RawPasswordAnswerValue -FailedPasswordAttempts + private void Map(MembershipUser source, IMember target, MapperContext context) + { + target.Comments = source.Comment; + target.CreateDate = source.CreationDate; + target.Email = source.Email; + target.Id = int.MaxValue; + target.IsApproved = source.IsApproved; + target.IsLockedOut = source.IsLockedOut; + target.Key = source.ProviderUserKey.TryConvertTo().Result; + target.LastLockoutDate = source.LastLockoutDate; + target.LastLoginDate = source.LastLoginDate; + target.LastPasswordChangeDate = source.LastPasswordChangedDate; + target.ProviderUserKey = source.ProviderUserKey; + target.RawPasswordValue = source.CreationDate > DateTime.MinValue ? Guid.NewGuid().ToString("N") : ""; + target.UpdateDate = source.LastActivityDate; + target.Username = source.UserName; + } - //FROM MembershipUser TO MemberBasic - CreateMap() - //we're giving this entity an ID of int.MaxValue - TODO: SD: I can't remember why this mapping is here? - .ForMember(dest => dest.Id, opt => opt.MapFrom(src => int.MaxValue)) - .ForMember(dest => dest.Udi, opt => opt.Ignore()) - .ForMember(dest => dest.CreateDate, opt => opt.MapFrom(src => src.CreationDate)) - .ForMember(dest => dest.UpdateDate, opt => opt.MapFrom(src => src.LastActivityDate)) - .ForMember(dest => dest.Key, opt => opt.MapFrom(src => src.ProviderUserKey.TryConvertTo().Result.ToString("N"))) - .ForMember(dest => dest.Owner, opt => opt.MapFrom(_ => new UserProfile {Name = "Admin", UserId = -1 })) - .ForMember(dest => dest.Icon, opt => opt.MapFrom(_ => "icon-user")) - .ForMember(dest => dest.Name, opt => opt.MapFrom(src => src.UserName)) - .ForMember(dest => dest.Email, opt => opt.MapFrom(src => src.Email)) - .ForMember(dest => dest.Username, opt => opt.MapFrom(src => src.UserName)) - .ForMember(dest => dest.Properties, opt => opt.Ignore()) - .ForMember(dest => dest.ParentId, opt => opt.Ignore()) - .ForMember(dest => dest.Path, opt => opt.Ignore()) - .ForMember(dest => dest.SortOrder, opt => opt.Ignore()) - .ForMember(dest => dest.AdditionalData, opt => opt.Ignore()) - .ForMember(dest => dest.State, opt => opt.MapFrom(_ => ContentSavedState.Draft)) - .ForMember(dest => dest.Edited, opt => opt.Ignore()) - .ForMember(dest => dest.Updater, opt => opt.Ignore()) - .ForMember(dest => dest.Trashed, opt => opt.Ignore()) - .ForMember(dest => dest.Alias, opt => opt.Ignore()) - .ForMember(dest => dest.ContentTypeAlias, opt => opt.Ignore()) - .ForMember(dest => dest.VariesByCulture, opt => opt.Ignore()); + // Umbraco.Code.MapAll -Properties -Errors -Edited -Updater -Alias -IsChildOfListView + // Umbraco.Code.MapAll -Trashed -IsContainer -VariesByCulture + private void Map(IMember source, MemberDisplay target, MapperContext context) + { + target.ContentTypeAlias = source.ContentType.Alias; + target.ContentTypeName = source.ContentType.Name; + target.CreateDate = source.CreateDate; + target.Email = source.Email; + target.Icon = source.ContentType.Icon; + target.Id = source.Id; + target.Key = source.Key; + target.MemberProviderFieldMapping = GetMemberProviderFieldMapping(); + target.MembershipScenario = GetMembershipScenario(); + target.Name = source.Name; + target.Owner = _commonMapper.GetOwner(source, context.Mapper); + target.ParentId = source.ParentId; + target.Path = source.Path; + target.SortOrder = source.SortOrder; + target.State = null; + target.Tabs = _tabsAndPropertiesMapper.Map(source, context); + target.TreeNodeUrl = _commonMapper.GetMemberTreeNodeUrl(source); + target.Udi = Udi.Create(Constants.UdiEntityType.Member, source.Key); + target.UpdateDate = source.UpdateDate; + target.Username = source.Username; + } - //FROM IMember TO ContentItemDto - CreateMap() - //.ForMember(dest => dest.Udi, opt => opt.MapFrom(content => Udi.Create(Constants.UdiEntityType.Member, content.Key))) - //.ForMember(dest => dest.Owner, opt => opt.MapFrom(src => memberOwnerResolver.Resolve(src))) - //.ForMember(dest => dest.Published, opt => opt.Ignore()) - //.ForMember(dest => dest.Edited, opt => opt.Ignore()) - //.ForMember(dest => dest.Updater, opt => opt.Ignore()) - //.ForMember(dest => dest.Icon, opt => opt.Ignore()) - //.ForMember(dest => dest.Alias, opt => opt.Ignore()) - //do no map the custom member properties (currently anyways, they were never there in 6.x) - .ForMember(dest => dest.Properties, opt => opt.MapFrom(src => memberDtoPropertiesResolver.Resolve(src))); + // Umbraco.Code.MapAll -Trashed -Edited -Updater -Alias -VariesByCulture + private void Map(IMember source, MemberBasic target, MapperContext context) + { + target.ContentTypeAlias = source.ContentType.Alias; + target.CreateDate = source.CreateDate; + target.Email = source.Email; + target.Icon = source.ContentType.Icon; + target.Id = int.MaxValue; + target.Key = source.Key; + target.Name = source.Name; + target.Owner = _commonMapper.GetOwner(source, context.Mapper); + target.ParentId = source.ParentId; + target.Path = source.Path; + target.Properties = context.Mapper.Map>(source.Properties); + target.SortOrder = source.SortOrder; + target.State = null; + target.Udi = Udi.Create(Constants.UdiEntityType.Member, source.Key); + target.UpdateDate = source.UpdateDate; + target.Username = source.Username; + } - //FROM IMemberGroup TO MemberGroupDisplay - CreateMap() - .ForMember(dest => dest.Udi, opt => opt.MapFrom(src => Udi.Create(Constants.UdiEntityType.MemberGroup, src.Key))) - .ForMember(dest => dest.Path, opt => opt.MapFrom(group => "-1," + group.Id)) - .ForMember(dest => dest.Notifications, opt => opt.Ignore()) - .ForMember(dest => dest.Icon, opt => opt.Ignore()) - .ForMember(dest => dest.Trashed, opt => opt.Ignore()) - .ForMember(dest => dest.ParentId, opt => opt.Ignore()) - .ForMember(dest => dest.Alias, opt => opt.Ignore()); + //TODO: SD: I can't remember why this mapping is here? + // Umbraco.Code.MapAll -Udi -Properties -ParentId -Path -SortOrder -Edited -Updater + // Umbraco.Code.MapAll -Trashed -Alias -ContentTypeAlias -VariesByCulture + private void Map(MembershipUser source, MemberBasic target, MapperContext context) + { + target.CreateDate = source.CreationDate; + target.Email = source.Email; + target.Icon = "icon-user"; + target.Id = int.MaxValue; + target.Key = source.ProviderUserKey.TryConvertTo().Result; + target.Name = source.UserName; + target.Owner = new UserProfile { Name = "Admin", UserId = -1 }; + target.State = ContentSavedState.Draft; + target.UpdateDate = source.LastActivityDate; + target.Username = source.UserName; +} + + // Umbraco.Code.MapAll -Icon -Trashed -ParentId -Alias + private void Map(IMemberGroup source, MemberGroupDisplay target, MapperContext context) + { + target.Id = source.Id; + target.Key = source.Key; + target.Name = source.Name; + target.Path = "-1" + source.Id; + target.Udi = Udi.Create(Constants.UdiEntityType.MemberGroup, source.Key); + } + + private MembershipScenario GetMembershipScenario() + { + var provider = Core.Security.MembershipProviderExtensions.GetMembersMembershipProvider(); + + if (provider.IsUmbracoMembershipProvider()) + { + return MembershipScenario.NativeUmbraco; + } + var memberType = _memberTypeService.Get(Constants.Conventions.MemberTypes.DefaultAlias); + return memberType != null + ? MembershipScenario.CustomProviderWithUmbracoLink + : MembershipScenario.StandaloneCustomProvider; + } + + private static IDictionary GetMemberProviderFieldMapping() + { + var provider = Core.Security.MembershipProviderExtensions.GetMembersMembershipProvider(); + + if (provider.IsUmbracoMembershipProvider() == false) + { + return new Dictionary + { + {Constants.Conventions.Member.IsLockedOut, Constants.Conventions.Member.IsLockedOut}, + {Constants.Conventions.Member.IsApproved, Constants.Conventions.Member.IsApproved}, + {Constants.Conventions.Member.Comments, Constants.Conventions.Member.Comments} + }; + } + + var umbracoProvider = (IUmbracoMemberTypeMembershipProvider)provider; + + return new Dictionary + { + {Constants.Conventions.Member.IsLockedOut, umbracoProvider.LockPropertyTypeAlias}, + {Constants.Conventions.Member.IsApproved, umbracoProvider.ApprovedPropertyTypeAlias}, + {Constants.Conventions.Member.Comments, umbracoProvider.CommentPropertyTypeAlias} + }; } } } diff --git a/src/Umbraco.Web/Models/Mapping/MemberProviderFieldResolver.cs b/src/Umbraco.Web/Models/Mapping/MemberProviderFieldResolver.cs deleted file mode 100644 index 4325ebd566..0000000000 --- a/src/Umbraco.Web/Models/Mapping/MemberProviderFieldResolver.cs +++ /dev/null @@ -1,39 +0,0 @@ -using System.Collections.Generic; -using Umbraco.Core; -using Umbraco.Core.Models; -using Umbraco.Core.Security; - -namespace Umbraco.Web.Models.Mapping -{ - /// - /// A resolver to map the provider field aliases - /// - internal class MemberProviderFieldResolver - { - public IDictionary Resolve(IMember source) - { - var provider = Core.Security.MembershipProviderExtensions.GetMembersMembershipProvider(); - - if (provider.IsUmbracoMembershipProvider() == false) - { - return new Dictionary - { - {Constants.Conventions.Member.IsLockedOut, Constants.Conventions.Member.IsLockedOut}, - {Constants.Conventions.Member.IsApproved, Constants.Conventions.Member.IsApproved}, - {Constants.Conventions.Member.Comments, Constants.Conventions.Member.Comments} - }; - } - else - { - var umbracoProvider = (IUmbracoMemberTypeMembershipProvider) provider; - - return new Dictionary - { - {Constants.Conventions.Member.IsLockedOut, umbracoProvider.LockPropertyTypeAlias}, - {Constants.Conventions.Member.IsApproved, umbracoProvider.ApprovedPropertyTypeAlias}, - {Constants.Conventions.Member.Comments, umbracoProvider.CommentPropertyTypeAlias} - }; - } - } - } -} diff --git a/src/Umbraco.Web/Models/Mapping/MemberTreeNodeUrlResolver.cs b/src/Umbraco.Web/Models/Mapping/MemberTreeNodeUrlResolver.cs deleted file mode 100644 index c4655294d7..0000000000 --- a/src/Umbraco.Web/Models/Mapping/MemberTreeNodeUrlResolver.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System.Web.Mvc; -using AutoMapper; -using Umbraco.Core.Models; -using Umbraco.Web.Models.ContentEditing; -using Umbraco.Web.Trees; - -namespace Umbraco.Web.Models.Mapping -{ - /// - /// Gets the tree node url for the IMember - /// - internal class MemberTreeNodeUrlResolver : IValueResolver - { - private readonly IUmbracoContextAccessor _umbracoContextAccessor; - - public MemberTreeNodeUrlResolver(IUmbracoContextAccessor umbracoContextAccessor) - { - _umbracoContextAccessor = umbracoContextAccessor ?? throw new System.ArgumentNullException(nameof(umbracoContextAccessor)); - } - - public string Resolve(IMember source, MemberDisplay destination, string destMember, ResolutionContext context) - { - var umbracoContext = _umbracoContextAccessor.UmbracoContext; - if (umbracoContext == null) return null; - - var urlHelper = new UrlHelper(umbracoContext.HttpContext.Request.RequestContext); - return urlHelper.GetUmbracoApiService(controller => controller.GetTreeNode(source.Key.ToString("N"), null)); - } - } -} diff --git a/src/Umbraco.Web/Models/Mapping/MembershipScenarioResolver.cs b/src/Umbraco.Web/Models/Mapping/MembershipScenarioResolver.cs deleted file mode 100644 index 3c3e0af5aa..0000000000 --- a/src/Umbraco.Web/Models/Mapping/MembershipScenarioResolver.cs +++ /dev/null @@ -1,33 +0,0 @@ -using System; -using Umbraco.Core; -using Umbraco.Core.Models; -using Umbraco.Core.Models.Membership; -using Umbraco.Core.Security; -using Umbraco.Core.Services; - -namespace Umbraco.Web.Models.Mapping -{ - internal class MembershipScenarioResolver - { - private readonly IMemberTypeService _memberTypeService; - - public MembershipScenarioResolver(IMemberTypeService memberTypeService) - { - _memberTypeService = memberTypeService; - } - - public MembershipScenario Resolve(IMember source) - { - var provider = Core.Security.MembershipProviderExtensions.GetMembersMembershipProvider(); - - if (provider.IsUmbracoMembershipProvider()) - { - return MembershipScenario.NativeUmbraco; - } - var memberType = _memberTypeService.Get(Constants.Conventions.MemberTypes.DefaultAlias); - return memberType != null - ? MembershipScenario.CustomProviderWithUmbracoLink - : MembershipScenario.StandaloneCustomProvider; - } - } -} diff --git a/src/Umbraco.Web/Models/Mapping/MembershipUserTypeConverter.cs b/src/Umbraco.Web/Models/Mapping/MembershipUserTypeConverter.cs deleted file mode 100644 index 38482cca49..0000000000 --- a/src/Umbraco.Web/Models/Mapping/MembershipUserTypeConverter.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System.Web.Security; -using AutoMapper; -using Umbraco.Core.Models; -using Umbraco.Web.Models.ContentEditing; - -namespace Umbraco.Web.Models.Mapping -{ - /// - /// A converter to go from a to a - /// - internal class MembershipUserTypeConverter : ITypeConverter - { - public MemberDisplay Convert(MembershipUser source, MemberDisplay destination, ResolutionContext context) - { - //first convert to IMember - var member = Mapper.Map(source); - //then convert to MemberDisplay - return Mapper.Map(member); - } - } -} diff --git a/src/Umbraco.Web/Models/Mapping/OwnerResolver.cs b/src/Umbraco.Web/Models/Mapping/OwnerResolver.cs deleted file mode 100644 index 76937886a9..0000000000 --- a/src/Umbraco.Web/Models/Mapping/OwnerResolver.cs +++ /dev/null @@ -1,30 +0,0 @@ -using AutoMapper; -using Umbraco.Core; -using Umbraco.Core.Models; -using Umbraco.Core.Models.Membership; -using Umbraco.Core.Services; -using UserProfile = Umbraco.Web.Models.ContentEditing.UserProfile; - -namespace Umbraco.Web.Models.Mapping -{ - /// - /// Maps the Owner for IContentBase - /// - /// - internal class OwnerResolver - where TPersisted : IContentBase - { - private readonly IUserService _userService; - - public OwnerResolver(IUserService userService) - { - _userService = userService; - } - - public UserProfile Resolve(TPersisted source) - { - var profile = source.GetCreatorProfile(_userService); - return profile == null ? null : Mapper.Map(profile); - } - } -} diff --git a/src/Umbraco.Web/Models/Mapping/PropertyGroupDisplayResolver.cs b/src/Umbraco.Web/Models/Mapping/PropertyGroupDisplayResolver.cs deleted file mode 100644 index ba165f44b4..0000000000 --- a/src/Umbraco.Web/Models/Mapping/PropertyGroupDisplayResolver.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using AutoMapper; -using Umbraco.Web.Models.ContentEditing; - -namespace Umbraco.Web.Models.Mapping -{ - internal class PropertyGroupDisplayResolver - where TSource : ContentTypeSave - where TPropertyTypeDestination : PropertyTypeDisplay - where TPropertyTypeSource : PropertyTypeBasic - { - public IEnumerable> Resolve(TSource source) - { - return source.Groups.Select(Mapper.Map>); - } - } -} diff --git a/src/Umbraco.Web/Models/Mapping/PropertyTypeVariationsResolver.cs b/src/Umbraco.Web/Models/Mapping/PropertyTypeVariationsResolver.cs deleted file mode 100644 index 00472a291c..0000000000 --- a/src/Umbraco.Web/Models/Mapping/PropertyTypeVariationsResolver.cs +++ /dev/null @@ -1,18 +0,0 @@ -using AutoMapper; -using Umbraco.Core.Models; -using Umbraco.Web.Models.ContentEditing; -using ContentVariation = Umbraco.Core.Models.ContentVariation; - -namespace Umbraco.Web.Models.Mapping -{ - /// - /// Returns the for a - /// - internal class PropertyTypeVariationsResolver: IValueResolver - { - public ContentVariation Resolve(PropertyTypeBasic source, PropertyType destination, ContentVariation destMember, ResolutionContext context) - { - return source.AllowCultureVariant ? ContentVariation.Culture : ContentVariation.Nothing; - } - } -} diff --git a/src/Umbraco.Web/Models/Mapping/ScheduledPublishDateResolver.cs b/src/Umbraco.Web/Models/Mapping/ScheduledPublishDateResolver.cs deleted file mode 100644 index 57e6ca8065..0000000000 --- a/src/Umbraco.Web/Models/Mapping/ScheduledPublishDateResolver.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System; -using AutoMapper; -using Umbraco.Core.Models; -using Umbraco.Web.Models.ContentEditing; - -namespace Umbraco.Web.Models.Mapping -{ - internal class ScheduledPublishDateResolver : IValueResolver - { - private readonly ContentScheduleAction _changeType; - - public ScheduledPublishDateResolver(ContentScheduleAction changeType) - { - _changeType = changeType; - } - - public DateTime? Resolve(IContent source, ContentVariantDisplay destination, DateTime? destMember, ResolutionContext context) - { - var culture = context.Options.GetCulture(); - var sched = source.ContentSchedule.GetSchedule(culture ?? string.Empty, _changeType); - foreach(var s in sched) - return s.Date; // take the first, it's ordered by date - - return null; - } - } -} diff --git a/src/Umbraco.Web/Security/WebAuthExtensions.cs b/src/Umbraco.Web/Security/WebAuthExtensions.cs index aa06616d90..f008dc8ba7 100644 --- a/src/Umbraco.Web/Security/WebAuthExtensions.cs +++ b/src/Umbraco.Web/Security/WebAuthExtensions.cs @@ -1,12 +1,8 @@ using System.Net.Http; -using System.Security.Claims; using System.Security.Principal; using System.ServiceModel.Channels; using System.Threading; using System.Web; -using AutoMapper; -using Umbraco.Core.Models.Membership; -using Umbraco.Core.Security; using Umbraco.Web.WebApi; namespace Umbraco.Web.Security diff --git a/src/Umbraco.Web/TagQuery.cs b/src/Umbraco.Web/TagQuery.cs index e79640bb4d..f07a122d7b 100644 --- a/src/Umbraco.Web/TagQuery.cs +++ b/src/Umbraco.Web/TagQuery.cs @@ -1,7 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; -using AutoMapper; +using Umbraco.Core.Composing; using Umbraco.Core.Models.PublishedContent; using Umbraco.Core.Services; using Umbraco.Web.Models; @@ -64,37 +64,37 @@ namespace Umbraco.Web /// public IEnumerable GetAllTags(string group = null, string culture = null) { - return Mapper.Map>(_tagService.GetAllTags(group, culture)); + return Current.Mapper.Map>(_tagService.GetAllTags(group, culture)); } /// public IEnumerable GetAllContentTags(string group = null, string culture = null) { - return Mapper.Map>(_tagService.GetAllContentTags(group, culture)); + return Current.Mapper.Map>(_tagService.GetAllContentTags(group, culture)); } /// public IEnumerable GetAllMediaTags(string group = null, string culture = null) { - return Mapper.Map>(_tagService.GetAllMediaTags(group, culture)); + return Current.Mapper.Map>(_tagService.GetAllMediaTags(group, culture)); } /// public IEnumerable GetAllMemberTags(string group = null, string culture = null) { - return Mapper.Map>(_tagService.GetAllMemberTags(group, culture)); + return Current.Mapper.Map>(_tagService.GetAllMemberTags(group, culture)); } /// public IEnumerable GetTagsForProperty(int contentId, string propertyTypeAlias, string group = null, string culture = null) { - return Mapper.Map>(_tagService.GetTagsForProperty(contentId, propertyTypeAlias, group, culture)); + return Current.Mapper.Map>(_tagService.GetTagsForProperty(contentId, propertyTypeAlias, group, culture)); } /// public IEnumerable GetTagsForEntity(int contentId, string group = null, string culture = null) { - return Mapper.Map>(_tagService.GetTagsForEntity(contentId, group, culture)); + return Current.Mapper.Map>(_tagService.GetTagsForEntity(contentId, group, culture)); } } } diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index 3956182281..9c8d64ab08 100755 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -60,7 +60,6 @@ - @@ -245,12 +244,10 @@ - - @@ -282,7 +279,7 @@ - + @@ -421,31 +418,14 @@ - - - - - - - - - - - - - - - - - - + @@ -652,8 +632,6 @@ - - @@ -967,11 +945,9 @@ - -