// Umbraco.Code.MapAll -Alias private static void Map(IEntitySlim source, EntityBasic target, MapperContext context) { target.Icon = MapContentTypeIcon(source); target.Id = source.Id; target.Key = source.Key; target.Name = MapName(source, context); target.ParentId = source.ParentId; target.Path = source.Path; target.Trashed = source.Trashed; target.Udi = Udi.Create(ObjectTypes.GetUdiType(source.NodeObjectType), source.Key); if (source is IContentEntitySlim contentSlim) { source.AdditionalData["ContentTypeAlias"] = contentSlim.ContentTypeAlias; } if (source is IDocumentEntitySlim documentSlim) { source.AdditionalData["IsPublished"] = documentSlim.Published; } if (source is IMediaEntitySlim mediaSlim) { source.AdditionalData["MediaPath"] = mediaSlim.MediaPath; } // NOTE: we're mapping the objects in AdditionalData by object reference here. // it works fine for now, but it's something to keep in mind in the future foreach (var kvp in source.AdditionalData) { target.AdditionalData[kvp.Key] = kvp.Value; } target.AdditionalData.Add("IsContainer", source.IsContainer); }
/// <summary> /// Check to see if we should return children of a container node /// </summary> /// <param name="e"></param> /// <returns></returns> /// <remarks> /// This is required in case a user has custom start nodes that are children of a list view since in that case we'll need to render the tree node. In normal cases we don't render /// children of a list view. /// </remarks> protected bool ShouldRenderChildrenOfContainer(IEntitySlim e) { var isContainer = e.IsContainer; var renderChildren = e.HasChildren && (isContainer == false); //Here we need to figure out if the node is a container and if so check if the user has a custom start node, then check if that start node is a child // of this container node. If that is true, the HasChildren must be true so that the tree node still renders even though this current node is a container/list view. if (isContainer && UserStartNodes.Length > 0 && UserStartNodes.Contains(Constants.System.Root) == false) { var startNodes = _entityService.GetAll(UmbracoObjectType, UserStartNodes); //if any of these start nodes' parent is current, then we need to render children normally so we need to switch some logic and tell // the UI that this node does have children and that it isn't a container if (startNodes.Any(x => { var pathParts = x.Path.Split(Constants.CharArrays.Comma); return(pathParts.Contains(e.Id.ToInvariantString())); })) { renderChildren = true; } } return(renderChildren); }
private static string MapName(IEntitySlim source, MapperContext context) { if (!(source is DocumentEntitySlim doc)) { return(source.Name); } // invariant = only 1 name if (!doc.Variations.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."); // TODO: we should throw, but this is used in various places that won't set a culture yet return(source.Name); } // 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(doc.CultureNames.TryGetValue(culture, out var name) && !name.IsNullOrWhiteSpace() ? name : $"({source.Name})"); }
// Umbraco.Code.MapAll -Alias private static void Map(IEntitySlim source, EntityBasic target, MapperContext context) { target.Icon = MapContentTypeIcon(source); target.Id = source.Id; target.Key = source.Key; target.Name = MapName(source, context); target.ParentId = source.ParentId; target.Path = source.Path; target.Trashed = source.Trashed; target.Udi = Udi.Create(ObjectTypes.GetUdiType(source.NodeObjectType), source.Key); if (source.NodeObjectType == Constants.ObjectTypes.Member && target.Icon.IsNullOrWhiteSpace()) { target.Icon = "icon-user"; } // NOTE: we're mapping the objects in AdditionalData by object reference here. // it works fine for now, but it's something to keep in mind in the future foreach (var kvp in source.AdditionalData) { target.AdditionalData[kvp.Key] = kvp.Value; } target.AdditionalData.Add("IsContainer", source.IsContainer); }
/// <summary> /// Returns a <see cref="TreeNode"/> for the <see cref="IUmbracoEntity"/> and /// attaches some meta data to the node if the user doesn't have start node access to it when in dialog mode /// </summary> /// <param name="e"></param> /// <param name="parentId"></param> /// <param name="queryStrings"></param> /// <returns></returns> internal TreeNode GetSingleTreeNodeWithAccessCheck(IEntitySlim e, string parentId, FormCollection queryStrings, int[] startNodeIds, string[] startNodePaths) { var entityIsAncestorOfStartNodes = ContentPermissions.IsInBranchOfStartNode(e.Path, startNodeIds, startNodePaths, out var hasPathAccess); var ignoreUserStartNodes = IgnoreUserStartNodes(queryStrings); if (ignoreUserStartNodes == false && entityIsAncestorOfStartNodes == false) { return(null); } var treeNode = GetSingleTreeNode(e, parentId, queryStrings); if (treeNode == null) { //this means that the user has NO access to this node via permissions! They at least need to have browse permissions to see //the node so we need to return null; return(null); } if (!ignoreUserStartNodes && !hasPathAccess) { treeNode.AdditionalData["noAccess"] = true; } return(treeNode); }
protected virtual Udi PathToUdi(string entityPath) { if (entityPath.IndexOf(':') == -1) { return(null); } var entityType = entityPath.Substring(0, entityPath.IndexOf(':')); var objectType = UdiEntityTypeHelper.ToUmbracoObjectType(entityType); var names = entityPath.Substring(entityPath.IndexOf(':') + 1).ToDelimitedList("/"); int parentId = -1; IEntitySlim next = null; foreach (var name in names) { next = FindItem(parentId, name, objectType); if (next == null) { return(null); } parentId = next.Id; } if (next != null) { return(Udi.Create(entityType, next.Key)); } return(null); }
/// <summary> /// Returns the content id based on the configured ContentErrorPage section. /// </summary> internal static int?GetContentIdFromErrorPageConfig( ContentErrorPage errorPage, IEntityService entityService, IPublishedContentQuery publishedContentQuery, int?domainContentId) { if (errorPage.HasContentId) { return(errorPage.ContentId); } if (errorPage.HasContentKey) { // need to get the Id for the GUID // TODO: When we start storing GUIDs into the IPublishedContent, then we won't have to look this up // but until then we need to look it up in the db. For now we've implemented a cached service for // converting Int -> Guid and vice versa. Attempt <int> found = entityService.GetId(errorPage.ContentKey, UmbracoObjectTypes.Document); if (found) { return(found.Result); } return(null); } if (errorPage.ContentXPath.IsNullOrWhiteSpace() == false) { try { // we have an xpath statement to execute var xpathResult = UmbracoXPathPathSyntaxParser.ParseXPathQuery( xpathExpression: errorPage.ContentXPath, nodeContextId: domainContentId, getPath: nodeid => { IEntitySlim ent = entityService.Get(nodeid); return(ent.Path.Split(',').Reverse()); }, publishedContentExists: i => publishedContentQuery.Content(i) != null); // now we'll try to execute the expression IPublishedContent nodeResult = publishedContentQuery.ContentSingleAtXPath(xpathResult); if (nodeResult != null) { return(nodeResult.Id); } } catch (Exception ex) { StaticApplicationLogging.Logger.LogError(ex, "Could not parse xpath expression: {ContentXPath}", errorPage.ContentXPath); return(null); } } return(null); }
/// <summary> /// Helper method to create tree nodes and automatically generate the json url + UDI /// </summary> /// <param name="entity"></param> /// <param name="entityObjectType"></param> /// <param name="parentId"></param> /// <param name="queryStrings"></param> /// <param name="hasChildren"></param> /// <returns></returns> public TreeNode CreateTreeNode(IEntitySlim entity, Guid entityObjectType, string parentId, FormDataCollection queryStrings, bool hasChildren) { var contentTypeIcon = entity is IContentEntitySlim contentEntity ? contentEntity.ContentTypeIcon : null; var treeNode = CreateTreeNode(entity.Id.ToInvariantString(), parentId, queryStrings, entity.Name, contentTypeIcon); treeNode.Path = entity.Path; treeNode.Udi = Udi.Create(ObjectTypes.GetUdiType(entityObjectType), entity.Key); treeNode.HasChildren = hasChildren; return(treeNode); }
private static string MapContentTypeIcon(IEntitySlim entity) { switch (entity) { case IMemberEntitySlim memberEntity: return(memberEntity.ContentTypeIcon.IfNullOrWhiteSpace(Constants.Icons.Member)); case IContentEntitySlim contentEntity: // NOTE: this case covers both content and media entities return(contentEntity.ContentTypeIcon); } return(null); }
// Umbraco.Code.MapAll -Alias private static void Map(IEntitySlim source, EntityBasic target, MapperContext context) { target.Icon = MapContentTypeIcon(source); target.Id = source.Id; target.Key = source.Key; target.Name = MapName(source, context); target.ParentId = source.ParentId; target.Path = source.Path; target.Trashed = source.Trashed; target.Udi = Udi.Create(ObjectTypes.GetUdiType(source.NodeObjectType), source.Key); if (source is IContentEntitySlim contentSlim) { source.AdditionalData !["ContentTypeAlias"] = contentSlim.ContentTypeAlias;
private string GetItemPath(IEntitySlim item) { var path = ""; if (item.ParentId != -1) { var parent = entityService.Get(item.ParentId); if (parent != null) { path += GetItemPath(parent); } } return(path += "/" + item.Name); }
protected virtual string GetItemPath(IEntitySlim item) { var path = ""; if (item.ParentId != -1) { var parent = entityService.Get(item.ParentId); if (parent != null) { path += GetItemPath(parent); } } return(path += "/" + item.Name.ToSafeAlias()); }
/// <summary> /// Returns a <see cref="TreeNode"/> for the <see cref="IUmbracoEntity"/> and /// attaches some meta data to the node if the user doesn't have start node access to it when in dialog mode /// </summary> /// <param name="e"></param> /// <param name="parentId"></param> /// <param name="queryStrings"></param> /// <returns></returns> internal TreeNode GetSingleTreeNodeWithAccessCheck(IEntitySlim e, string parentId, FormDataCollection queryStrings) { var entityIsAncestorOfStartNodes = Security.CurrentUser.IsInBranchOfStartNode(e, Services.EntityService, RecycleBinId, out var hasPathAccess); if (entityIsAncestorOfStartNodes == false) { return(null); } var treeNode = GetSingleTreeNode(e, parentId, queryStrings); if (hasPathAccess == false) { treeNode.AdditionalData["noAccess"] = true; } return(treeNode); }
public Attempt <OperationResult> DeleteContainer(int containerId, int userId = Cms.Core.Constants.Security.SuperUserId) { EventMessages eventMessages = EventMessagesFactory.Get(); using (IScope scope = ScopeProvider.CreateScope()) { scope.WriteLock(WriteLockIds); // also for containers EntityContainer container = _containerRepository.Get(containerId); if (container == null) { return(OperationResult.Attempt.NoOperation(eventMessages)); } // 'container' here does not know about its children, so we need // to get it again from the entity repository, as a light entity IEntitySlim entity = _entityRepository.Get(container.Id); if (entity.HasChildren) { scope.Complete(); return(Attempt.Fail(new OperationResult(OperationResultType.FailedCannot, eventMessages))); } var deletingNotification = new EntityContainerDeletingNotification(container, eventMessages); if (scope.Notifications.PublishCancelable(deletingNotification)) { scope.Complete(); return(Attempt.Fail(new OperationResult(OperationResultType.FailedCancelledByEvent, eventMessages))); } _containerRepository.Delete(container); scope.Complete(); var deletedNotification = new EntityContainerDeletedNotification(container, eventMessages); deletedNotification.WithStateFrom(deletingNotification); scope.Notifications.Publish(deletedNotification); return(OperationResult.Attempt.Succeed(eventMessages)); // TODO: Audit trail ? } }
/// <summary> /// set name according to variations /// </summary> /// <param name="entity"></param> /// <param name="culture"></param> private void EnsureName(IEntitySlim entity, string?culture) { if (culture == null) { if (string.IsNullOrWhiteSpace(entity.Name)) { entity.Name = "[[" + entity.Id + "]]"; } return; } if (!(entity is IDocumentEntitySlim docEntity)) { throw new InvalidOperationException( $"Cannot render a tree node for a culture when the entity isn't {typeof(IDocumentEntitySlim)}, instead it is {entity.GetType()}"); } // we are getting the tree for a given culture, // for those items that DO support cultures, we need to get the proper name, IF it exists // otherwise, invariant is fine (with brackets) if (docEntity.Variations.VariesByCulture()) { if (docEntity.CultureNames.TryGetValue(culture, out var name) && !string.IsNullOrWhiteSpace(name)) { entity.Name = name; } else { entity.Name = "(" + entity.Name + ")"; } } if (string.IsNullOrWhiteSpace(entity.Name)) { entity.Name = "[[" + entity.Id + "]]"; } }
protected virtual string GetItemPath(IEntitySlim item) { // path caching, stops us looking up the same path all the time. if (pathCache.ContainsKey(item.Path)) { return(pathCache[item.Path]); } var path = ""; if (item.ParentId != -1) { var parent = entityService.Get(item.ParentId); if (parent != null) { path += GetItemPath(parent); } } pathCache[item.Path] = path + "/" + item.Name.ToSafeAlias(); return(pathCache[item.Path]); }
public IEntitySlim GetEntity(Guid id) { if (!_cacheEnabled) { return(entityService.Get(id)); } // double cache lookup, we only store id's in the key cache, // that way we are not double storing all the entityIds in memory. IEntitySlim entity = null; var intId = keyCache.GetCacheItem(id.ToString(), () => { entity = entityService.Get(id); if (entity != null) { return(entity.Id); } return(0); }); if (intId != 0) { return(cache.GetCacheItem(intId.ToString(), () => { if (entity != null) { return entity; } return entityService.Get(intId); })); } else { keyCache.ClearByKey(id.ToString()); return(null); } }
/// <summary> /// Creates a tree node for a content item based on an UmbracoEntity /// </summary> /// <param name="e"></param> /// <param name="parentId"></param> /// <param name="queryStrings"></param> /// <returns></returns> protected override TreeNode GetSingleTreeNode(IEntitySlim entity, string parentId, FormDataCollection queryStrings) { var node = CreateTreeNode( entity, Constants.ObjectTypes.Media, parentId, queryStrings, entity.HasChildren); // entity is either a container, or a media if (entity.IsContainer) { node.SetContainerStyle(); node.AdditionalData.Add("isContainer", true); } else { var contentEntity = (IContentEntitySlim)entity; node.AdditionalData.Add("contentType", contentEntity.ContentTypeAlias); } return(node); }
public IEntitySlim GetEntity(Guid id, UmbracoObjectTypes objectType) { if (!_cacheEnabled) { return(entityService.Get(id, objectType)); } IEntitySlim entity = null; var intId = keyCache.GetCacheItem(id.ToString(), () => { entity = entityService.Get(id, objectType); if (entity != null) { return(entity.Id); } return(0); }); if (intId != 0) { return(cache.GetCacheItem(intId.ToString(), () => { if (entity != null) { return entity; } return entityService.Get(intId, objectType); })); } else { keyCache.ClearByKey(id.ToString()); return(null); } }
private static string GetContentTypeIcon(IEntitySlim entity) => entity is ContentEntitySlim contentEntity ? contentEntity.ContentTypeIcon : null;
protected abstract TreeNode GetSingleTreeNode(IEntitySlim entity, string parentId, FormDataCollection queryStrings);
/// <inheritdoc /> protected override TreeNode GetSingleTreeNode(IEntitySlim entity, string parentId, FormDataCollection queryStrings) { var culture = queryStrings?["culture"]; var allowedUserOptions = GetAllowedUserMenuItemsForNode(entity); if (CanUserAccessNode(entity, allowedUserOptions, culture)) { //Special check to see if it is a container, if so then we'll hide children. var isContainer = entity.IsContainer; // && (queryStrings.Get("isDialog") != "true"); var node = CreateTreeNode( entity, Constants.ObjectTypes.Document, parentId, queryStrings, entity.HasChildren); // set container style if it is one if (isContainer) { node.AdditionalData.Add("isContainer", true); node.SetContainerStyle(); } var documentEntity = (IDocumentEntitySlim)entity; if (!documentEntity.Variations.VariesByCulture()) { if (!documentEntity.Published) { node.SetNotPublishedStyle(); } else if (documentEntity.Edited) { node.SetHasPendingVersionStyle(); } } else { if (!culture.IsNullOrWhiteSpace()) { if (!documentEntity.Published || !documentEntity.PublishedCultures.Contains(culture)) { node.SetNotPublishedStyle(); } else if (documentEntity.EditedCultures.Contains(culture)) { node.SetHasPendingVersionStyle(); } } } node.AdditionalData.Add("variesByCulture", documentEntity.Variations.VariesByCulture()); node.AdditionalData.Add("contentType", documentEntity.ContentTypeAlias); if (Services.PublicAccessService.IsProtected(entity.Path)) { node.SetProtectedStyle(); } return(node); } return(null); }