예제 #1
0
    public IEnumerable <ContentTypeBasic> GetAllowedChildren(int contentId)
    {
        if (contentId == Constants.System.RecycleBinContent)
        {
            return(Enumerable.Empty <ContentTypeBasic>());
        }

        IEnumerable <IContentType> types;

        if (contentId == Constants.System.Root)
        {
            types = _contentTypeService.GetAll().Where(x => x.AllowedAsRoot).ToList();
        }
        else
        {
            IContent?contentItem = _contentService.GetById(contentId);
            if (contentItem == null)
            {
                return(Enumerable.Empty <ContentTypeBasic>());
            }

            IContentTypeComposition?contentType = _contentTypeBaseServiceProvider.GetContentTypeOf(contentItem);
            var ids = contentType?.AllowedContentTypes?.OrderBy(c => c.SortOrder).Select(x => x.Id.Value).ToArray();

            if (ids is null || ids.Any() == false)
            {
                return(Enumerable.Empty <ContentTypeBasic>());
            }

            types = _contentTypeService.GetAll(ids).OrderBy(c => ids.IndexOf(c.Id)).ToList();
        }

        var basics = types.Where(type => type.IsElement == false)
                     .Select(_umbracoMapper.Map <IContentType, ContentTypeBasic>).WhereNotNull().ToList();

        ILocalizedTextService localizedTextService = _localizedTextService;

        foreach (ContentTypeBasic basic in basics)
        {
            basic.Name        = localizedTextService.UmbracoDictionaryTranslate(CultureDictionary, basic.Name);
            basic.Description = localizedTextService.UmbracoDictionaryTranslate(CultureDictionary, basic.Description);
        }

        //map the blueprints
        IContent[]? blueprints =
            _contentService.GetBlueprintsForContentTypes(types.Select(x => x.Id).ToArray())?.ToArray();
        foreach (ContentTypeBasic basic in basics)
        {
            IContent[]? docTypeBluePrints = blueprints?.Where(x => x.ContentTypeId == (int?)basic.Id).ToArray();
            if (docTypeBluePrints is not null)
            {
                foreach (IContent blueprint in docTypeBluePrints)
                {
                    basic.Blueprints[blueprint.Id] = blueprint.Name ?? string.Empty;
                }
            }
        }

        return(basics.OrderBy(c => contentId == Constants.System.Root ? c.Name : string.Empty));
    }
예제 #2
0
        // Umbraco.Code.MapAll -AllowPreview -Errors -PersistedContent
        private void Map(IContent source, ContentItemDisplay target, MapperContext context)
        {
            target.AllowedActions   = GetActions(source);
            target.AllowedTemplates = GetAllowedTemplates(source);
            target.ContentApps      = _commonMapper.GetContentApps(source);
            target.ContentTypeId    = source.ContentType.Id;
            target.ContentTypeKey   = source.ContentType.Key;
            target.ContentTypeAlias = source.ContentType.Alias;
            target.ContentTypeName  = _localizedTextService.UmbracoDictionaryTranslate(source.ContentType.Name);
            target.DocumentType     = _commonMapper.GetContentType(source, context);
            target.Icon             = source.ContentType.Icon;
            target.Id                = source.Id;
            target.IsBlueprint       = source.Blueprint;
            target.IsChildOfListView = DetermineIsChildOfListView(source, context);
            target.IsContainer       = source.ContentType.IsContainer;
            target.IsElement         = source.ContentType.IsElement;
            target.Key               = source.Key;
            target.Owner             = _commonMapper.GetOwner(source, context);
            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 <ContentTreeController>(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);
            target.Urls              = GetUrls(source);
            target.Variants          = _contentVariantMapper.Map(source, context);

            target.ContentDto            = new ContentPropertyCollectionDto();
            target.ContentDto.Properties = context.MapEnumerable <Property, ContentPropertyDto>(source.Properties);
        }
예제 #3
0
    // Umbraco.Code.MapAll -AllowPreview -Errors -PersistedContent
    private void Map <TVariant>(IContent source, ContentItemDisplay <TVariant> target, MapperContext context)
        where TVariant : ContentVariantDisplay
    {
        // Both GetActions and DetermineIsChildOfListView use parent, so get it once here
        // Parent might already be in context, so check there before using content service
        IContent?parent;

        if (context.Items.TryGetValue("Parent", out var parentObj) &&
            parentObj is IContent typedParent)
        {
            parent = typedParent;
        }
        else
        {
            parent = _contentService.GetParent(source);
        }

        target.AllowedActions   = GetActions(source, parent, context);
        target.AllowedTemplates = GetAllowedTemplates(source);
        target.ContentApps      = _commonMapper.GetContentAppsForEntity(source);
        target.ContentTypeId    = source.ContentType.Id;
        target.ContentTypeKey   = source.ContentType.Key;
        target.ContentTypeAlias = source.ContentType.Alias;
        target.ContentTypeName  =
            _localizedTextService.UmbracoDictionaryTranslate(_cultureDictionary, source.ContentType.Name);
        target.DocumentType      = _commonMapper.GetContentType(source, context);
        target.Icon              = source.ContentType.Icon;
        target.Id                = source.Id;
        target.IsBlueprint       = source.Blueprint;
        target.IsChildOfListView = DetermineIsChildOfListView(source, parent, context);
        target.IsContainer       = source.ContentType.IsContainer;
        target.IsElement         = source.ContentType.IsElement;
        target.Key               = source.Key;
        target.Owner             = _commonMapper.GetOwner(source, context);
        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       = _commonTreeNodeMapper.GetTreeNodeUrl <ContentTreeController>(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);
        target.Urls       = GetUrls(source);
        target.Variants   = _contentVariantMapper.Map <TVariant>(source, context);

        target.ContentDto = new ContentPropertyCollectionDto
        {
            Properties = context.MapEnumerable <IProperty, ContentPropertyDto>(source.Properties).WhereNotNull()
        };
    }
        public override ContentPropertyDisplay Convert(ResolutionContext context)
        {
            var display = base.Convert(context);

            var originalProperty = context.SourceValue as Property;

            if (originalProperty == null)
            {
                throw new InvalidOperationException("Source value is not a property.");
            }

            var dataTypeService = DataTypeService;
            var preVals         = dataTypeService.GetPreValuesCollectionByDataTypeId(originalProperty.PropertyType.DataTypeDefinitionId);

            //configure the editor for display with the pre-values
            var valEditor = display.PropertyEditor.ValueEditor;

            valEditor.ConfigureForDisplay(preVals);

            //set the display properties after mapping
            display.Alias       = originalProperty.Alias;
            display.Description = originalProperty.PropertyType.Description;
            display.Label       = originalProperty.PropertyType.Name;
            display.HideLabel   = valEditor.HideLabel;

            //add the validation information
            display.Validation.Mandatory = originalProperty.PropertyType.Mandatory;
            display.Validation.Pattern   = originalProperty.PropertyType.ValidationRegExp;

            if (display.PropertyEditor == null)
            {
                //display.Config = PreValueCollection.AsDictionary(preVals);
                //if there is no property editor it means that it is a legacy data type
                // we cannot support editing with that so we'll just render the readonly value view.
                display.View = "views/propertyeditors/readonlyvalue/readonlyvalue.html";
            }
            else
            {
                //let the property editor format the pre-values
                display.Config = display.PropertyEditor.PreValueEditor.ConvertDbToEditor(display.PropertyEditor.DefaultPreValues, preVals);
                display.View   = valEditor.View;
            }

            //Translate
            display.Label       = _textService.UmbracoDictionaryTranslate(display.Label);
            display.Description = _textService.UmbracoDictionaryTranslate(display.Description);

            return(display);
        }
    public override void Map(IProperty originalProp, ContentPropertyDisplay dest, MapperContext context)
    {
        base.Map(originalProp, dest, context);

        var config = originalProp.PropertyType is null
            ? null
            : DataTypeService.GetDataType(originalProp.PropertyType.DataTypeId)?.Configuration;

        // TODO: IDataValueEditor configuration - general issue
        // GetValueEditor() returns a non-configured IDataValueEditor
        // - for richtext and nested, configuration determines HideLabel, so we need to configure the value editor
        // - could configuration also determines ValueType, everywhere?
        // - does it make any sense to use a IDataValueEditor without configuring it?

        // configure the editor for display with configuration
        IDataValueEditor?valEditor = dest.PropertyEditor?.GetValueEditor(config);

        // set the display properties after mapping
        dest.Alias       = originalProp.Alias;
        dest.Description = originalProp.PropertyType?.Description;
        dest.Label       = originalProp.PropertyType?.Name;
        dest.HideLabel   = valEditor?.HideLabel ?? false;
        dest.LabelOnTop  = originalProp.PropertyType?.LabelOnTop;

        // add the validation information
        dest.Validation.Mandatory        = originalProp.PropertyType?.Mandatory ?? false;
        dest.Validation.MandatoryMessage = originalProp.PropertyType?.MandatoryMessage;
        dest.Validation.Pattern          = originalProp.PropertyType?.ValidationRegExp;
        dest.Validation.PatternMessage   = originalProp.PropertyType?.ValidationRegExpMessage;

        if (dest.PropertyEditor == null)
        {
            // display.Config = PreValueCollection.AsDictionary(preVals);
            // if there is no property editor it means that it is a legacy data type
            // we cannot support editing with that so we'll just render the readonly value view.
            dest.View = "views/propertyeditors/readonlyvalue/readonlyvalue.html";
        }
        else
        {
            // let the property editor format the pre-values
            dest.Config = dest.PropertyEditor.GetConfigurationEditor().ToValueEditor(config);
            dest.View   = valEditor?.View;
        }

        // Translate
        dest.Label       = _textService.UmbracoDictionaryTranslate(_cultureDictionary, dest.Label);
        dest.Description = _textService.UmbracoDictionaryTranslate(_cultureDictionary, dest.Description);
    }
        protected override IEnumerable <ContentPropertyDisplay> GetCustomGenericProperties(IContentBase content)
        {
            var member = (IMember)content;

            var genericProperties = new List <ContentPropertyDisplay>
            {
                new ContentPropertyDisplay
                {
                    Alias = $"{Constants.PropertyEditors.InternalGenericPropertiesPrefix}id",
                    Label = _localizedTextService.Localize("general", "id"),
                    Value = new List <string> {
                        member.Id.ToString(), member.Key.ToString()
                    },
                    View = "idwithguid"
                },
                new ContentPropertyDisplay
                {
                    Alias = $"{Constants.PropertyEditors.InternalGenericPropertiesPrefix}doctype",
                    Label = _localizedTextService.Localize("content", "membertype"),
                    Value = _localizedTextService.UmbracoDictionaryTranslate(CultureDictionary, member.ContentType.Name),
                    View  = _propertyEditorCollection[Constants.PropertyEditors.Aliases.Label].GetValueEditor().View
                },
                GetLoginProperty(member, _localizedTextService),
                new ContentPropertyDisplay
                {
                    Alias      = $"{Constants.PropertyEditors.InternalGenericPropertiesPrefix}email",
                    Label      = _localizedTextService.Localize("general", "email"),
                    Value      = member.Email,
                    View       = "email",
                    Validation = { Mandatory = true }
                },
                new ContentPropertyDisplay
                {
                    Alias = $"{Constants.PropertyEditors.InternalGenericPropertiesPrefix}password",
                    Label = _localizedTextService.Localize(null, "password"),
                    Value = new Dictionary <string, object>
                    {
                        // TODO: why ignoreCase, what are we doing here?!
                        { "newPassword", member.GetAdditionalDataValueIgnoreCase("NewPassword", null) },
                    },
                    // TODO: Hard coding this because the changepassword doesn't necessarily need to be a resolvable (real) property editor
                    View = "changepassword",
                    // initialize the dictionary with the configuration from the default membership provider
                    Config = GetPasswordConfig(member)
                },
                new ContentPropertyDisplay
                {
                    Alias  = $"{Constants.PropertyEditors.InternalGenericPropertiesPrefix}membergroup",
                    Label  = _localizedTextService.Localize("content", "membergroup"),
                    Value  = GetMemberGroupValue(member.Username),
                    View   = "membergroups",
                    Config = new Dictionary <string, object> {
                        { "IsRequired", true }
                    }
                }
            };

            return(genericProperties);
        }
            public IDictionary <string, string> Resolve(IContent source, ContentItemDisplay destination, IDictionary <string, string> destMember, ResolutionContext context)
            {
                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)));
            }
예제 #8
0
            protected override IEnumerable <ContentPropertyDisplay> GetCustomGenericProperties(IContentBase content)
            {
                var member          = (IMember)content;
                var membersProvider = Core.Security.MembershipProviderExtensions.GetMembersMembershipProvider();

                var genericProperties = new List <ContentPropertyDisplay>
                {
                    new ContentPropertyDisplay
                    {
                        Alias = string.Format("{0}doctype", Constants.PropertyEditors.InternalGenericPropertiesPrefix),
                        Label = _localizedTextService.Localize("content/membertype"),
                        //Value = localizedText.UmbracoDictionaryTranslate(display.ContentTypeName),
                        Value = _localizedTextService.UmbracoDictionaryTranslate(member.ContentType.Name),
                        View  = PropertyEditorResolver.Current.GetByAlias(Constants.PropertyEditors.NoEditAlias).ValueEditor.View
                    },
                    GetLoginProperty(_memberService, member, _localizedTextService),
                    new ContentPropertyDisplay
                    {
                        Alias      = string.Format("{0}email", Constants.PropertyEditors.InternalGenericPropertiesPrefix),
                        Label      = _localizedTextService.Localize("general/email"),
                        Value      = member.Email,
                        View       = "email",
                        Validation = { Mandatory = true }
                    },
                    new ContentPropertyDisplay
                    {
                        Alias = string.Format("{0}password", Constants.PropertyEditors.InternalGenericPropertiesPrefix),
                        Label = _localizedTextService.Localize("password"),
                        //NOTE: The value here is a json value - but the only property we care about is the generatedPassword one if it exists, the newPassword exists
                        // only when creating a new member and we want to have a generated password pre-filled.
                        Value = new Dictionary <string, object>
                        {
                            { "generatedPassword", member.GetAdditionalDataValueIgnoreCase("GeneratedPassword", null) },
                            { "newPassword", member.GetAdditionalDataValueIgnoreCase("NewPassword", null) },
                        },
                        //TODO: Hard coding this because the changepassword doesn't necessarily need to be a resolvable (real) property editor
                        View = "changepassword",
                        //initialize the dictionary with the configuration from the default membership provider
                        Config = new Dictionary <string, object>(membersProvider.GetConfiguration(_userService))
                        {
                            //the password change toggle will only be displayed if there is already a password assigned.
                            { "hasPassword", member.RawPasswordValue.IsNullOrWhiteSpace() == false }
                        }
                    },
                    new ContentPropertyDisplay
                    {
                        Alias  = string.Format("{0}membergroup", Constants.PropertyEditors.InternalGenericPropertiesPrefix),
                        Label  = _localizedTextService.Localize("content/membergroup"),
                        Value  = GetMemberGroupValue(member.Username),
                        View   = "membergroups",
                        Config = new Dictionary <string, object> {
                            { "IsRequired", true }
                        }
                    }
                };

                return(genericProperties);
            }
예제 #9
0
        public override ContentPropertyDisplay Convert(Property originalProp, ContentPropertyDisplay dest, ResolutionContext context)
        {
            var display = base.Convert(originalProp, dest, context);

            var config = DataTypeService.GetDataType(originalProp.PropertyType.DataTypeId).Configuration;

            // fixme - IDataValueEditor configuration - general issue
            // GetValueEditor() returns a non-configured IDataValueEditor
            // - for richtext and nested, configuration determines HideLabel, so we need to configure the value editor
            // - could configuration also determines ValueType, everywhere?
            // - does it make any sense to use a IDataValueEditor without configuring it?

            // configure the editor for display with configuration
            var valEditor = display.PropertyEditor.GetValueEditor(config);

            //set the display properties after mapping
            display.Alias       = originalProp.Alias;
            display.Description = originalProp.PropertyType.Description;
            display.Label       = originalProp.PropertyType.Name;
            display.HideLabel   = valEditor.HideLabel;

            //add the validation information
            display.Validation.Mandatory = originalProp.PropertyType.Mandatory;
            display.Validation.Pattern   = originalProp.PropertyType.ValidationRegExp;

            if (display.PropertyEditor == null)
            {
                //display.Config = PreValueCollection.AsDictionary(preVals);
                //if there is no property editor it means that it is a legacy data type
                // we cannot support editing with that so we'll just render the readonly value view.
                display.View = "views/propertyeditors/readonlyvalue/readonlyvalue.html";
            }
            else
            {
                //let the property editor format the pre-values
                display.Config = display.PropertyEditor.GetConfigurationEditor().ToValueEditor(config);
                display.View   = valEditor.View;
            }

            //Translate
            display.Label       = _textService.UmbracoDictionaryTranslate(display.Label);
            display.Description = _textService.UmbracoDictionaryTranslate(display.Description);

            return(display);
        }
        /// <summary>
        /// Create the list of tabs for the <see cref="IContentBase"/>
        /// </summary>
        /// <param name="umbracoContext"></param>
        /// <param name="content">Source value</param>
        /// <returns>Destination</returns>
        protected virtual List <Tab <ContentPropertyDisplay> > ResolveCore(UmbracoContext umbracoContext, TSource content)
        {
            var tabs = new List <Tab <ContentPropertyDisplay> >();

            // add the tabs, for properties that belong to a tab
            // need to aggregate the tabs, as content.PropertyGroups contains all the composition tabs,
            // and there might be duplicates (content does not work like contentType and there is no
            // content.CompositionPropertyGroups).
            var groupsGroupsByName = content.PropertyGroups.OrderBy(x => x.SortOrder).GroupBy(x => x.Name);

            foreach (var groupsByName in groupsGroupsByName)
            {
                var properties = new List <Property>();

                // merge properties for groups with the same name
                foreach (var group in groupsByName)
                {
                    var groupProperties = content.GetPropertiesForGroup(group)
                                          .Where(x => IgnoreProperties.Contains(x.Alias) == false); // skip ignored

                    properties.AddRange(groupProperties);
                }

                if (properties.Count == 0)
                {
                    continue;
                }

                //map the properties
                var mappedProperties = MapProperties(umbracoContext, content, properties);

                // add the tab
                // we need to pick an identifier... there is no "right" way...
                var g = groupsByName.FirstOrDefault(x => x.Id == content.ContentTypeId) // try local
                        ?? groupsByName.First();                                        // else pick one randomly
                var groupId   = g.Id;
                var groupName = groupsByName.Key;
                tabs.Add(new Tab <ContentPropertyDisplay>
                {
                    Id         = groupId,
                    Alias      = groupName,
                    Label      = _localizedTextService.UmbracoDictionaryTranslate(groupName),
                    Properties = mappedProperties,
                    IsActive   = false
                });
            }

            MapGenericProperties(umbracoContext, content, tabs);

            // activate the first tab
            if (tabs.Count > 0)
            {
                tabs[0].IsActive = true;
            }

            return(tabs);
        }
        private static void AfterMap(IMedia media, MediaItemDisplay display, IDataTypeService dataTypeService, ILocalizedTextService localizedText, IContentTypeService contentTypeService, ILogger logger)
        {
            // Adapted from ContentModelMapper
            //map the IsChildOfListView (this is actually if it is a descendant of a list view!)
            var parent = media.Parent();

            display.IsChildOfListView = parent != null && (parent.ContentType.IsContainer || contentTypeService.HasContainerInPath(parent.Path));

            //map the tree node url
            if (HttpContext.Current != null)
            {
                var urlHelper = new UrlHelper(HttpContext.Current.Request.RequestContext);
                var url       = urlHelper.GetUmbracoApiService <MediaTreeController>(controller => controller.GetTreeNode(display.Id.ToString(), null));
                display.TreeNodeUrl = url;
            }

            if (media.ContentType.IsContainer)
            {
                TabsAndPropertiesResolver.AddListView(display, "media", dataTypeService, localizedText);
            }

            var genericProperties = new List <ContentPropertyDisplay>
            {
                new ContentPropertyDisplay
                {
                    Alias = string.Format("{0}doctype", Constants.PropertyEditors.InternalGenericPropertiesPrefix),
                    Label = localizedText.Localize("content/mediatype"),
                    Value = localizedText.UmbracoDictionaryTranslate(display.ContentTypeName),
                    View  = PropertyEditorResolver.Current.GetByAlias(Constants.PropertyEditors.NoEditAlias).ValueEditor.View
                }
            };

            TabsAndPropertiesResolver.MapGenericProperties(media, display, localizedText, genericProperties, properties =>
            {
                if (HttpContext.Current != null && UmbracoContext.Current != null && UmbracoContext.Current.Security.CurrentUser != null &&
                    UmbracoContext.Current.Security.CurrentUser.AllowedSections.Any(x => x.Equals(Constants.Applications.Settings)))
                {
                    var mediaTypeLink = string.Format("#/settings/mediatypes/edit/{0}", media.ContentTypeId);

                    //Replace the doctype property
                    var docTypeProperty   = properties.First(x => x.Alias == string.Format("{0}doctype", Constants.PropertyEditors.InternalGenericPropertiesPrefix));
                    docTypeProperty.Value = new List <object>
                    {
                        new
                        {
                            linkText = media.ContentType.Name,
                            url      = mediaTypeLink,
                            target   = "_self",
                            icon     = "icon-item-arrangement"
                        }
                    };
                    docTypeProperty.View = "urllist";
                }

                // inject 'Link to media' as the first generic property
                var links = media.GetUrls(UmbracoConfig.For.UmbracoSettings().Content, logger);
                if (links.Any())
                {
                    var link = new ContentPropertyDisplay
                    {
                        Alias = string.Format("{0}urls", Constants.PropertyEditors.InternalGenericPropertiesPrefix),
                        Label = localizedText.Localize("media/urls"),
                        Value = string.Join(",", links),
                        View  = "urllist"
                    };
                    properties.Insert(0, link);
                }
            });
        }
예제 #12
0
        /// <summary>
        /// TODO: We need to refactor how we work with ICultureDictionary - this is supposed to be the 'fast' way to
        /// do readonly access to the Dictionary without using the ILocalizationService. See TODO Notes in `DefaultCultureDictionary`
        /// Also NOTE that the ICultureDictionary is based on the ILocalizationService not the ILocalizedTextService (which is used
        /// only for the localization files - not the dictionary)
        /// </summary>
        /// <param name="manager"></param>
        /// <param name="text"></param>
        /// <returns></returns>
        internal static string UmbracoDictionaryTranslate(this ILocalizedTextService manager, string text)
        {
            var cultureDictionary = CultureDictionary;

            return(manager.UmbracoDictionaryTranslate(text, cultureDictionary));
        }
        public ContentMapperProfile(
            ContentUrlResolver contentUrlResolver,
            ContentTreeNodeUrlResolver <IContent, ContentTreeController> contentTreeNodeUrlResolver,
            TabsAndPropertiesResolver <IContent, ContentVariantDisplay> tabsAndPropertiesResolver,
            ContentAppResolver contentAppResolver,
            IUserService userService,
            IContentService contentService,
            IContentTypeService contentTypeService,
            IContentTypeBaseServiceProvider contentTypeBaseServiceProvider,
            ILocalizationService localizationService,
            ILocalizedTextService localizedTextService)
        {
            // create, capture, cache
            var contentOwnerResolver            = new OwnerResolver <IContent>(userService);
            var creatorResolver                 = new CreatorResolver(userService);
            var actionButtonsResolver           = new ActionButtonsResolver(userService, contentService);
            var childOfListViewResolver         = new ContentChildOfListViewResolver(contentService, contentTypeService);
            var contentTypeBasicResolver        = new ContentTypeBasicResolver <IContent, ContentItemDisplay>(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);

            //FROM IContent TO ContentItemDisplay
            CreateMap <IContent, ContentItemDisplay>()
            .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 <IContent, ContentVariantDisplay>()
            .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 <ContentSavedStateResolver <ContentPropertyDisplay> >())
            .ForMember(dest => dest.Tabs, opt => opt.MapFrom(tabsAndPropertiesResolver));

            //FROM IContent TO ContentItemBasic<ContentPropertyBasic, IContent>
            CreateMap <IContent, ContentItemBasic <ContentPropertyBasic> >()
            .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 <UpdateDateResolver>())
            .ForMember(dest => dest.Name, opt => opt.MapFrom <NameResolver>())
            .ForMember(dest => dest.State, opt => opt.MapFrom <ContentBasicSavedStateResolver <ContentPropertyBasic> >())
            .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 <IContent, ContentPropertyCollectionDto>();
        }
예제 #14
0
        /// <summary>
        /// Maps the generic tab with custom properties for content
        /// </summary>
        /// <param name="memberService"></param>
        /// <param name="userService"></param>
        /// <param name="member"></param>
        /// <param name="display"></param>
        /// <param name="localizedText"></param>
        /// <remarks>
        /// If this is a new entity and there is an approved field then we'll set it to true by default.
        /// </remarks>
        private static void MapGenericCustomProperties(IMemberService memberService, IUserService userService, IMember member, MemberDisplay display, ILocalizedTextService localizedText)
        {
            var membersProvider = Core.Security.MembershipProviderExtensions.GetMembersMembershipProvider();

            //map the tree node url
            if (HttpContext.Current != null)
            {
                var urlHelper = new UrlHelper(HttpContext.Current.Request.RequestContext);
                var url       = urlHelper.GetUmbracoApiService <MemberTreeController>(controller => controller.GetTreeNode(display.Key.ToString("N"), null));
                display.TreeNodeUrl = url;
            }

            var genericProperties = new List <ContentPropertyDisplay>
            {
                new ContentPropertyDisplay
                {
                    Alias = string.Format("{0}doctype", Constants.PropertyEditors.InternalGenericPropertiesPrefix),
                    Label = localizedText.Localize("content/membertype"),
                    Value = localizedText.UmbracoDictionaryTranslate(display.ContentTypeName),
                    View  = PropertyEditorResolver.Current.GetByAlias(Constants.PropertyEditors.NoEditAlias).ValueEditor.View
                },
                GetLoginProperty(memberService, member, display, localizedText),
                new ContentPropertyDisplay
                {
                    Alias      = string.Format("{0}email", Constants.PropertyEditors.InternalGenericPropertiesPrefix),
                    Label      = localizedText.Localize("general/email"),
                    Value      = display.Email,
                    View       = "email",
                    Validation = { Mandatory = true }
                },
                new ContentPropertyDisplay
                {
                    Alias = string.Format("{0}password", Constants.PropertyEditors.InternalGenericPropertiesPrefix),
                    Label = localizedText.Localize("password"),
                    //NOTE: The value here is a json value - but the only property we care about is the generatedPassword one if it exists, the newPassword exists
                    // only when creating a new member and we want to have a generated password pre-filled.
                    Value = new Dictionary <string, object>
                    {
                        { "generatedPassword", member.GetAdditionalDataValueIgnoreCase("GeneratedPassword", null) },
                        { "newPassword", member.GetAdditionalDataValueIgnoreCase("NewPassword", null) },
                    },
                    //TODO: Hard coding this because the changepassword doesn't necessarily need to be a resolvable (real) property editor
                    View = "changepassword",
                    //initialize the dictionary with the configuration from the default membership provider
                    Config = new Dictionary <string, object>(membersProvider.GetConfiguration(userService))
                    {
                        //the password change toggle will only be displayed if there is already a password assigned.
                        { "hasPassword", member.RawPasswordValue.IsNullOrWhiteSpace() == false }
                    }
                },
                new ContentPropertyDisplay
                {
                    Alias  = string.Format("{0}membergroup", Constants.PropertyEditors.InternalGenericPropertiesPrefix),
                    Label  = localizedText.Localize("content/membergroup"),
                    Value  = GetMemberGroupValue(display.Username),
                    View   = "membergroups",
                    Config = new Dictionary <string, object> {
                        { "IsRequired", true }
                    }
                }
            };

            TabsAndPropertiesResolver.MapGenericProperties(member, display, localizedText, genericProperties, properties =>
            {
                if (HttpContext.Current != null && UmbracoContext.Current != null && UmbracoContext.Current.Security.CurrentUser != null &&
                    UmbracoContext.Current.Security.CurrentUser.AllowedSections.Any(x => x.Equals(Constants.Applications.Settings)))
                {
                    var memberTypeLink = string.Format("#/member/memberTypes/edit/{0}", member.ContentTypeId);

                    //Replace the doctype property
                    var docTypeProperty   = properties.First(x => x.Alias == string.Format("{0}doctype", Constants.PropertyEditors.InternalGenericPropertiesPrefix));
                    docTypeProperty.Value = new List <object>
                    {
                        new
                        {
                            linkText = member.ContentType.Name,
                            url      = memberTypeLink,
                            target   = "_self",
                            icon     = "icon-item-arrangement"
                        }
                    };
                    docTypeProperty.View = "urllist";
                }
            });

            //check if there's an approval field
            var provider = membersProvider as global::umbraco.providers.members.UmbracoMembershipProvider;

            if (member.HasIdentity == false && provider != null)
            {
                var approvedField = provider.ApprovedPropertyTypeAlias;
                var prop          = display.Properties.FirstOrDefault(x => x.Alias == approvedField);
                if (prop != null)
                {
                    prop.Value = 1;
                }
            }
        }
        /// <summary>
        /// Maps the generic tab with custom properties for content
        /// </summary>
        /// <param name="content"></param>
        /// <param name="display"></param>
        /// <param name="dataTypeService"></param>
        /// <param name="localizedText"></param>
        /// <param name="contentTypeService"></param>
        private static void AfterMap(IContent content, ContentItemDisplay display, IDataTypeService dataTypeService,
                                     ILocalizedTextService localizedText, IContentTypeService contentTypeService)
        {
            // map the IsChildOfListView (this is actually if it is a descendant of a list view!)
            var parent = content.Parent();

            display.IsChildOfListView = parent != null && (parent.ContentType.IsContainer || contentTypeService.HasContainerInPath(parent.Path));

            //map the tree node url
            if (HttpContext.Current != null)
            {
                var urlHelper = new UrlHelper(HttpContext.Current.Request.RequestContext);
                var url       = urlHelper.GetUmbracoApiService <ContentTreeController>(controller => controller.GetTreeNode(display.Id.ToString(), null));
                display.TreeNodeUrl = url;
            }

            //fill in the template config to be passed to the template drop down.
            var templateItemConfig = new Dictionary <string, string> {
                { "", localizedText.Localize("general/choose") }
            };

            foreach (var t in content.ContentType.AllowedTemplates
                     .Where(t => t.Alias.IsNullOrWhiteSpace() == false && t.Name.IsNullOrWhiteSpace() == false))
            {
                templateItemConfig.Add(t.Alias, t.Name);
            }

            if (content.ContentType.IsContainer)
            {
                TabsAndPropertiesResolver.AddListView(display, "content", dataTypeService, localizedText);
            }

            var properties = new List <ContentPropertyDisplay>
            {
                new ContentPropertyDisplay
                {
                    Alias = string.Format("{0}doctype", Constants.PropertyEditors.InternalGenericPropertiesPrefix),
                    Label = localizedText.Localize("content/documentType"),
                    Value = localizedText.UmbracoDictionaryTranslate(display.ContentTypeName),
                    View  = PropertyEditorResolver.Current.GetByAlias(Constants.PropertyEditors.NoEditAlias).ValueEditor.View
                },
                new ContentPropertyDisplay
                {
                    Alias = string.Format("{0}releasedate", Constants.PropertyEditors.InternalGenericPropertiesPrefix),
                    Label = localizedText.Localize("content/releaseDate"),
                    Value = display.ReleaseDate.HasValue ? display.ReleaseDate.Value.ToIsoString() : null,
                    //Not editible for people without publish permission (U4-287)
                    View   = display.AllowedActions.Contains(ActionPublish.Instance.Letter) ? "datepicker" : PropertyEditorResolver.Current.GetByAlias(Constants.PropertyEditors.NoEditAlias).ValueEditor.View,
                    Config = new Dictionary <string, object>
                    {
                        { "offsetTime", "1" }
                    }
                    //TODO: Fix up hard coded datepicker
                },
                new ContentPropertyDisplay
                {
                    Alias = string.Format("{0}expiredate", Constants.PropertyEditors.InternalGenericPropertiesPrefix),
                    Label = localizedText.Localize("content/unpublishDate"),
                    Value = display.ExpireDate.HasValue ? display.ExpireDate.Value.ToIsoString() : null,
                    //Not editible for people without publish permission (U4-287)
                    View   = display.AllowedActions.Contains(ActionPublish.Instance.Letter) ? "datepicker" : PropertyEditorResolver.Current.GetByAlias(Constants.PropertyEditors.NoEditAlias).ValueEditor.View,
                    Config = new Dictionary <string, object>
                    {
                        { "offsetTime", "1" }
                    }
                    //TODO: Fix up hard coded datepicker
                },
                new ContentPropertyDisplay
                {
                    Alias  = string.Format("{0}template", Constants.PropertyEditors.InternalGenericPropertiesPrefix),
                    Label  = localizedText.Localize("template/template"),
                    Value  = display.TemplateAlias,
                    View   = "dropdown", //TODO: Hard coding until we make a real dropdown property editor to lookup
                    Config = new Dictionary <string, object>
                    {
                        { "items", templateItemConfig }
                    }
                }
            };


            TabsAndPropertiesResolver.MapGenericProperties(content, display, localizedText, properties.ToArray(),
                                                           genericProperties =>
            {
                //TODO: This would be much nicer with the IUmbracoContextAccessor so we don't use singletons
                //If this is a web request and there's a user signed in and the
                // user has access to the settings section, we will
                if (HttpContext.Current != null && UmbracoContext.Current != null && UmbracoContext.Current.Security.CurrentUser != null &&
                    UmbracoContext.Current.Security.CurrentUser.AllowedSections.Any(x => x.Equals(Constants.Applications.Settings)))
                {
                    var currentDocumentType     = contentTypeService.GetContentType(display.ContentTypeAlias);
                    var currentDocumentTypeName = currentDocumentType == null ? string.Empty : localizedText.UmbracoDictionaryTranslate(currentDocumentType.Name);

                    var currentDocumentTypeId = currentDocumentType == null ? string.Empty : currentDocumentType.Id.ToString(CultureInfo.InvariantCulture);
                    //TODO: Hard coding this is not good
                    var docTypeLink = string.Format("#/settings/documenttypes/edit/{0}", currentDocumentTypeId);

                    //Replace the doc type property
                    var docTypeProperty   = genericProperties.First(x => x.Alias == string.Format("{0}doctype", Constants.PropertyEditors.InternalGenericPropertiesPrefix));
                    docTypeProperty.Value = new List <object>
                    {
                        new
                        {
                            linkText = currentDocumentTypeName,
                            url      = docTypeLink,
                            target   = "_self",
                            icon     = "icon-item-arrangement"
                        }
                    };
                    //TODO: Hard coding this because the templatepicker doesn't necessarily need to be a resolvable (real) property editor
                    docTypeProperty.View = "urllist";
                }

                // inject 'Link to document' as the first generic property
                genericProperties.Insert(0, new ContentPropertyDisplay
                {
                    Alias = string.Format("{0}urls", Constants.PropertyEditors.InternalGenericPropertiesPrefix),
                    Label = localizedText.Localize("content/urls"),
                    Value = string.Join(",", display.Urls),
                    View  = "urllist"    //TODO: Hard coding this because the templatepicker doesn't necessarily need to be a resolvable (real) property editor
                });
            });
        }
예제 #16
0
        protected override IEnumerable <Tab <ContentPropertyDisplay> > ResolveCore(IContentBase content)
        {
            var tabs = new List <Tab <ContentPropertyDisplay> >();

            // add the tabs, for properties that belong to a tab
            // need to aggregate the tabs, as content.PropertyGroups contains all the composition tabs,
            // and there might be duplicates (content does not work like contentType and there is no
            // content.CompositionPropertyGroups).
            var groupsGroupsByName = content.PropertyGroups.OrderBy(x => x.SortOrder).GroupBy(x => x.Name);

            foreach (var groupsByName in groupsGroupsByName)
            {
                var properties = new List <Property>();

                // merge properties for groups with the same name
                foreach (var group in groupsByName)
                {
                    var groupProperties = content.GetPropertiesForGroup(group)
                                          .Where(x => IgnoreProperties.Contains(x.Alias) == false); // skip ignored

                    properties.AddRange(groupProperties);
                }

                if (properties.Count == 0)
                {
                    continue;
                }

                // Sort properties so items from different compositions appear in correct order (see U4-9298). Map sorted properties.
                var mappedProperties = Mapper.Map <IEnumerable <Property>, IEnumerable <ContentPropertyDisplay> >(properties.OrderBy(prop => prop.PropertyType.SortOrder));

                TranslateProperties(mappedProperties);

                // add the tab
                // we need to pick an identifier... there is no "right" way...
                var g = groupsByName.FirstOrDefault(x => x.Id == content.ContentTypeId) // try local
                        ?? groupsByName.First();                                        // else pick one randomly
                var groupId   = g.Id;
                var groupName = groupsByName.Key;
                tabs.Add(new Tab <ContentPropertyDisplay>
                {
                    Id         = groupId,
                    Alias      = groupName,
                    Label      = _localizedTextService.UmbracoDictionaryTranslate(groupName),
                    Properties = mappedProperties,
                    IsActive   = false
                });
            }

            // add the generic properties tab, for properties that don't belong to a tab
            // get the properties, map and translate them, then add the tab
            var noGroupProperties = content.GetNonGroupedProperties()
                                    .Where(x => IgnoreProperties.Contains(x.Alias) == false); // skip ignored
            var genericproperties = Mapper.Map <IEnumerable <Property>, IEnumerable <ContentPropertyDisplay> >(noGroupProperties).ToList();

            TranslateProperties(genericproperties);

            tabs.Add(new Tab <ContentPropertyDisplay>
            {
                Id         = 0,
                Label      = _localizedTextService.Localize("general/properties"),
                Alias      = "Generic properties",
                Properties = genericproperties
            });

            // activate the first tab
            tabs.First().IsActive = true;

            return(tabs);
        }