using System.Collections.Generic; using System.Web.Security; using AutoMapper; using Umbraco.Core; using Umbraco.Core.Models; using Umbraco.Core.Models.Mapping; using Umbraco.Web.Models.ContentEditing; using umbraco; using System.Linq; namespace Umbraco.Web.Models.Mapping { /// /// Declares model mappings for members. /// internal class MemberModelMapper : MapperConfiguration { public override void ConfigureMappings(IConfiguration config, ApplicationContext applicationContext) { //FROM IMember TO MediaItemDisplay config.CreateMap() .ForMember( dto => dto.Owner, expression => expression.ResolveUsing>()) .ForMember( dto => dto.Icon, expression => expression.MapFrom(content => content.ContentType.Icon)) .ForMember( dto => dto.ContentTypeAlias, expression => expression.MapFrom(content => content.ContentType.Alias)) .ForMember( dto => dto.ContentTypeName, expression => expression.MapFrom(content => content.ContentType.Name)) .ForMember(display => display.Properties, expression => expression.Ignore()) .ForMember(display => display.Tabs, expression => expression.ResolveUsing( new TabsAndPropertiesResolver( //do no map this properties (currently anyways, they were never there in 6.x) Constants.Conventions.Member.StandardPropertyTypeStubs.Select(x => x.Value.Alias)))) .AfterMap(MapGenericCustomProperties); //FROM IMember TO ContentItemBasic config.CreateMap>() .ForMember( dto => dto.Owner, expression => expression.ResolveUsing>()) .ForMember( dto => dto.Icon, expression => expression.MapFrom(content => content.ContentType.Icon)) .ForMember( dto => dto.ContentTypeAlias, expression => expression.MapFrom(content => content.ContentType.Alias)); //FROM IMember TO ContentItemDto config.CreateMap>() .ForMember( dto => dto.Owner, expression => expression.ResolveUsing>()) //do no map the custom member properties (currently anyways, they were never there in 6.x) .ForMember(dto => dto.Properties, expression => expression.ResolveUsing()); } /// /// Maps the generic tab with custom properties for content /// /// /// private static void MapGenericCustomProperties(IMember member, MemberDisplay display) { var membershipProvider = Membership.Provider; TabsAndPropertiesResolver.MapGenericProperties( member, display, new ContentPropertyDisplay { Alias = string.Format("{0}login", Constants.PropertyEditors.InternalGenericPropertiesPrefix), Label = ui.Text("login"), Value = display.Username, View = "textbox", Config = new Dictionary {{"IsRequired", true}} }, new ContentPropertyDisplay { Alias = string.Format("{0}password", Constants.PropertyEditors.InternalGenericPropertiesPrefix), Label = ui.Text("password"), //NOTE: The value here is a json value - but the only property we care about is the generatedPassword one if it exists - this is the only value we'll ever supply to the front-end Value = new Dictionary { {"generatedPassword", member.AdditionalData.ContainsKey("GeneratedPassword") ? member.AdditionalData["GeneratedPassword"] : null} }, //TODO: Hard coding this because the changepassword doesn't necessarily need to be a resolvable (real) property editor View = "changepassword", Config = new Dictionary { //the password change toggle will only be displayed if there is already a password assigned. {"hasPassword", member.Password.IsNullOrWhiteSpace() == false}, {"minPasswordLength", membershipProvider.MinRequiredPasswordLength}, {"enableReset", membershipProvider.EnablePasswordReset}, {"enablePasswordRetrieval", membershipProvider.EnablePasswordRetrieval}, {"requiresQuestionAnswer", membershipProvider.RequiresQuestionAndAnswer} //TODO: Inject the other parameters in here to change the behavior of this control - based on the membership provider settings. } }, new ContentPropertyDisplay { Alias = string.Format("{0}email", Constants.PropertyEditors.InternalGenericPropertiesPrefix), Label = ui.Text("general", "email"), Value = display.Email, View = "email", Config = new Dictionary {{"IsRequired", true}} }); } /// /// This ensures that the custom membership provider properties are not mapped (currently since they weren't there in v6) /// /// /// 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 MemberDtoPropertiesValueResolver : ValueResolver> { protected override IEnumerable ResolveCore(IMember source) { var exclude = Constants.Conventions.Member.StandardPropertyTypeStubs.Select(x => x.Value.Alias).ToArray(); return source.Properties .Where(x => exclude.Contains(x.Alias) == false) .Select(Mapper.Map); } } } }