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))); }
protected override bool ResolveCore(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 || _contentTypeService.HasContainerInPath(parent.Path))); }
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))); }
/// <summary> /// Checks if the content item is a descendant of a list view /// </summary> /// <param name="source"></param> /// <param name="parent"></param> /// <param name="context"></param> /// <returns> /// Returns true if the content item is a descendant of a list view and where the content is /// not a current user's start node. /// </returns> /// <remarks> /// We must check if it's the current user's start node because in that case we will actually be /// rendering the tree node underneath the list view to visually show context. In this case we return /// false because the item is technically not being rendered as part of a list view but instead as a /// real tree node. If we didn't perform this check then tree syncing wouldn't work correctly. /// </remarks> private bool DetermineIsChildOfListView(IContent source, IContent?parent, MapperContext context) { var userStartNodes = Array.Empty <int>(); // In cases where a user's start node is below a list view, we will actually render // out the tree to that start node and in that case for that start node, we want to return // false here. if (context.HasItems && context.Items.TryGetValue("CurrentUser", out var usr) && usr is IUser currentUser) { userStartNodes = currentUser.CalculateContentStartNodeIds(_entityService, _appCaches); if (!userStartNodes?.Contains(Constants.System.Root) ?? false) { // return false if this is the user's actual start node, the node will be rendered in the tree // regardless of if it's a list view or not if (userStartNodes?.Contains(source.Id) ?? false) { return(false); } } } if (parent == null) { return(false); } var pathParts = parent.Path.Split(Constants.CharArrays.Comma).Select(x => int.TryParse(x, NumberStyles.Integer, CultureInfo.InvariantCulture, out var i) ? i : 0).ToList(); if (userStartNodes is not null) { // reduce the path parts so we exclude top level content items that // are higher up than a user's start nodes foreach (var n in userStartNodes) { var index = pathParts.IndexOf(n); if (index != -1) { // now trim all top level start nodes to the found index for (var i = 0; i < index; i++) { pathParts.RemoveAt(0); } } } } return(parent.ContentType.IsContainer || _contentTypeService.HasContainerInPath(pathParts.ToArray())); }
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); } }); }
/// <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 }); }); }