/// <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 = Services.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); }
protected virtual IEnumerable <IEntitySlim> GetChildEntities(string id, FormDataCollection queryStrings) { // try to parse id as an integer else use GetEntityFromId // which will grok Guids, Udis, etc and let use obtain the id if (!int.TryParse(id, out var entityId)) { var entity = GetEntityFromId(id); if (entity == null) { throw new HttpResponseException(HttpStatusCode.NotFound); } entityId = entity.Id; } var ignoreUserStartNodes = IgnoreUserStartNodes(queryStrings); IEntitySlim[] result; // if a request is made for the root node but user has no access to // root node, return start nodes instead if (!ignoreUserStartNodes && entityId == Constants.System.Root && UserStartNodes.Contains(Constants.System.Root) == false) { result = UserStartNodes.Length > 0 ? Services.EntityService.GetAll(UmbracoObjectType, UserStartNodes).ToArray() : Array.Empty <IEntitySlim>(); } else { result = GetChildrenFromEntityService(entityId).ToArray(); } return(result); }
protected IEnumerable <IUmbracoEntity> GetChildEntities(string id) { // use helper method to ensure we support both integer and guid lookups int iid; // look up from GUID if it's not an integer if (int.TryParse(id, out iid) == false) { var idEntity = GetEntityFromId(id); if (idEntity == null) { throw new HttpResponseException(HttpStatusCode.NotFound); } iid = idEntity.Id; } // if a request is made for the root node but user has no access to // root node, return start nodes instead if (iid == Constants.System.Root && UserStartNodes.Contains(Constants.System.Root) == false) { return(UserStartNodes.Length > 0 ? Services.EntityService.GetAll(UmbracoObjectType, UserStartNodes) : Enumerable.Empty <IUmbracoEntity>()); } return(Services.EntityService.GetChildren(iid, UmbracoObjectType).ToArray()); }
/// <summary> /// Ensure the noAccess metadata is applied for the root node if in dialog mode and the user doesn't have path access to it /// </summary> /// <param name="queryStrings"></param> /// <returns></returns> protected override TreeNode CreateRootNode(FormDataCollection queryStrings) { var node = base.CreateRootNode(queryStrings); if (IsDialog(queryStrings) && UserStartNodes.Contains(Constants.System.Root) == false) { node.AdditionalData["noAccess"] = true; } return(node); }
/// <summary> /// Ensures the recycle bin is appended when required (i.e. user has access to the root and it's not in dialog mode) /// </summary> /// <param name="id"></param> /// <param name="queryStrings"></param> /// <returns></returns> /// <remarks> /// This method is overwritten strictly to render the recycle bin, it should serve no other purpose /// </remarks> protected sealed override ActionResult <TreeNodeCollection> GetTreeNodes(string id, FormCollection queryStrings) { //check if we're rendering the root if (id == Constants.System.RootString && UserStartNodes.Contains(Constants.System.Root)) { var altStartId = string.Empty; if (queryStrings.HasKey(TreeQueryStringParameters.StartNodeId)) { altStartId = queryStrings.GetValue <string>(TreeQueryStringParameters.StartNodeId); } //check if a request has been made to render from a specific start node if (string.IsNullOrEmpty(altStartId) == false && altStartId != "undefined" && altStartId != Constants.System.RootString) { id = altStartId; } var nodesResult = GetTreeNodesInternal(id, queryStrings); if (!(nodesResult.Result is null)) { return(nodesResult.Result); } var nodes = nodesResult.Value; //only render the recycle bin if we are not in dialog and the start id is still the root //we need to check for the "application" key in the queryString because its value is required here, //and for some reason when there are no dashboards, this parameter is missing if (IsDialog(queryStrings) == false && id == Constants.System.RootString && queryStrings.HasKey("application")) { nodes.Add(CreateTreeNode( RecycleBinId.ToInvariantString(), id, queryStrings, LocalizedTextService.Localize("general", "recycleBin"), "icon-trash", RecycleBinSmells, queryStrings.GetRequiredValue <string>("application") + TreeAlias.EnsureStartsWith('/') + "/recyclebin")); } return(nodes); } return(GetTreeNodesInternal(id, queryStrings)); }
/// <summary> /// Ensure the noAccess metadata is applied for the root node if in dialog mode and the user doesn't have path access to it /// </summary> /// <param name="queryStrings"></param> /// <returns></returns> protected override ActionResult <TreeNode> CreateRootNode(FormCollection queryStrings) { var nodeResult = base.CreateRootNode(queryStrings); if ((nodeResult.Result is null)) { return(nodeResult); } var node = nodeResult.Value; if (IsDialog(queryStrings) && UserStartNodes.Contains(Constants.System.Root) == false && IgnoreUserStartNodes(queryStrings) == false) { node.AdditionalData["noAccess"] = true; } return(node); }
/// <summary> /// Ensures the recycle bin is appended when required (i.e. user has access to the root and it's not in dialog mode) /// </summary> /// <param name="id"></param> /// <param name="queryStrings"></param> /// <returns></returns> /// <remarks> /// This method is overwritten strictly to render the recycle bin, it should serve no other purpose /// </remarks> protected sealed override TreeNodeCollection GetTreeNodes(string id, FormDataCollection queryStrings) { var ignoreUserStartNodes = queryStrings.GetValue <bool>(TreeQueryStringParameters.IgnoreUserStartNodes); //check if we're rendering the root if (id == Constants.System.RootString && UserStartNodes.Contains(Constants.System.Root) || ignoreUserStartNodes) { var altStartId = string.Empty; if (queryStrings.HasKey(TreeQueryStringParameters.StartNodeId)) { altStartId = queryStrings.GetValue <string>(TreeQueryStringParameters.StartNodeId); } //check if a request has been made to render from a specific start node if (string.IsNullOrEmpty(altStartId) == false && altStartId != "undefined" && altStartId != Constants.System.RootString) { id = altStartId; } var nodes = GetTreeNodesInternal(id, queryStrings); //only render the recycle bin if we are not in dialog and the start id id still the root if (IsDialog(queryStrings) == false && id == Constants.System.RootString) { nodes.Add(CreateTreeNode( RecycleBinId.ToInvariantString(), id, queryStrings, Services.TextService.Localize("general/recycleBin"), "icon-trash", RecycleBinSmells, queryStrings.GetRequiredValue <string>("application") + TreeAlias.EnsureStartsWith('/') + "/recyclebin")); } return(nodes); } return(GetTreeNodesInternal(id, queryStrings)); }