Exemple #1
0
        /// <summary>
        /// Helper method to create a root model for a tree
        /// </summary>
        /// <returns></returns>
        protected virtual TreeNode CreateRootNode(FormCollection queryStrings)
        {
            var jsonUrl  = Url.GetTreeUrl(GetType(), RootNodeId, queryStrings);
            var isDialog = queryStrings.GetValue <bool>(TreeQueryStringParameters.DialogMode);
            var node     = new TreeNode(RootNodeId, BackOfficeRequestContext.RegisteredComponents.MenuItems, jsonUrl)
            {
                HasChildren = true,
                EditorUrl   = queryStrings.HasKey(TreeQueryStringParameters.OnNodeClick)      //has a node click handler?
                                    ? queryStrings.Get(TreeQueryStringParameters.OnNodeClick) //return node click handler
                                    : isDialog                                                //is in dialog mode without a click handler ?
                                          ? "#"                                               //return empty string, otherwise, return an editor URL:
                                          : Url.GetCurrentDashboardUrl(),
                Title = NodeDisplayName
            };

            //add the tree id to the root
            node.AdditionalData.Add("treeId", TreeId.ToString("N"));

            //add the tree-root css class
            node.Style.AddCustom("tree-root");

            //node.AdditionalData.Add("id", node.HiveId.ToString());
            //node.AdditionalData.Add("title", node.Title);

            AddQueryStringsToAdditionalData(node, queryStrings);

            //check if the tree is searchable and add that to the meta data as well
            if (this is ISearchableTree)
            {
                node.AdditionalData.Add("searchable", "true");
            }

            return(node);
        }
 /// <summary>
 /// Returns the value of a mandatory item in the FormCollection
 /// </summary>
 /// <param name="items"></param>
 /// <param name="key"></param>
 /// <returns></returns>
 public static string GetRequiredString(this FormCollection items, string key)
 {
     if (items.HasKey(key) == false)
     {
         throw new ArgumentNullException("The " + key + " query string parameter was not found but is required");
     }
     return(items.Single(x => x.Key.InvariantEquals(key)).Value);
 }
        /// <summary>
        /// Return the editor URL for the currrent node depending on the data found in the query strings
        /// </summary>
        /// <param name="id"></param>
        /// <param name="queryStrings"></param>
        /// <returns></returns>
        protected virtual string GetEditorUrl(HiveId id, FormCollection queryStrings)
        {
            var isDialog = queryStrings.GetValue <bool>(TreeQueryStringParameters.DialogMode);

            return(queryStrings.HasKey(TreeQueryStringParameters.OnNodeClick)    //has a node click handler?
                       ? queryStrings.Get(TreeQueryStringParameters.OnNodeClick) //return node click handler
                       : isDialog                                                //is in dialog mode without a click handler ?
                             ? string.Empty                                      //return empty string, otherwise, return an editor URL:
                             : Url.GetEditorUrl(id, EditorControllerId, BackOfficeRequestContext.RegisteredComponents, BackOfficeRequestContext.Application.Settings));
        }
        /// <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));
        }
Exemple #5
0
        /// <summary>
        /// Return the editor URL for the currrent node depending on the data found in the query strings
        /// </summary>
        /// <param name="id"></param>
        /// <param name="queryStrings"></param>
        /// <returns></returns>
        /// <remarks>
        /// This checks if the tree there is a OnNodeClick handler assigned, if so, it assigns it,
        /// otherwise it checks if the tree is in DialogMode, if it is then it returns an empty handler, otherwise
        /// it sets the Url to the editor's url.
        /// </remarks>
        public string GetEditorUrl(HiveId id, FormCollection queryStrings)
        {
            Mandate.ParameterNotEmpty(id, "id");
            Mandate.ParameterNotNull(queryStrings, "queryStrings");
            Mandate.That <NullReferenceException>(Url != null);

            var isDialog = queryStrings.GetValue <bool>(TreeQueryStringParameters.DialogMode);

            return(queryStrings.HasKey(TreeQueryStringParameters.OnNodeClick)    //has a node click handler?
                       ? queryStrings.Get(TreeQueryStringParameters.OnNodeClick) //return node click handler
                       : isDialog                                                //is in dialog mode without a click handler ?
                             ? "#"                                               //return empty string, otherwise, return an editor URL:
                             : Url.GetEditorUrl(
                       id,
                       EditorControllerId,
                       BackOfficeRequestContext.RegisteredComponents,
                       BackOfficeRequestContext.Application.Settings));
        }
        protected virtual ActionResult <TreeNodeCollection> PerformGetTreeNodes(string id, FormCollection queryStrings)
        {
            var nodes = new TreeNodeCollection();

            var rootIdString    = Constants.System.RootString;
            var hasAccessToRoot = UserStartNodes.Contains(Constants.System.Root);

            var startNodeId = queryStrings.HasKey(TreeQueryStringParameters.StartNodeId)
                ? queryStrings.GetValue <string>(TreeQueryStringParameters.StartNodeId)
                : string.Empty;

            var ignoreUserStartNodes = IgnoreUserStartNodes(queryStrings);

            if (string.IsNullOrEmpty(startNodeId) == false && startNodeId != "undefined" && startNodeId != rootIdString)
            {
                // request has been made to render from a specific, non-root, start node
                id = startNodeId;

                // ensure that the user has access to that node, otherwise return the empty tree nodes collection
                // TODO: in the future we could return a validation statement so we can have some UI to notify the user they don't have access
                if (ignoreUserStartNodes == false && HasPathAccess(id, queryStrings) == false)
                {
                    _logger.LogWarning("User {Username} does not have access to node with id {Id}", _backofficeSecurityAccessor.BackOfficeSecurity.CurrentUser.Username, id);
                    return(nodes);
                }

                // if the tree is rendered...
                // - in a dialog: render only the children of the specific start node, nothing to do
                // - in a section: if the current user's start nodes do not contain the root node, we need
                //   to include these start nodes in the tree too, to provide some context - i.e. change
                //   start node back to root node, and then GetChildEntities method will take care of the rest.
                if (IsDialog(queryStrings) == false && hasAccessToRoot == false)
                {
                    id = rootIdString;
                }
            }

            // get child entities - if id is root, but user's start nodes do not contain the
            // root node, this returns the start nodes instead of root's children
            var entitiesResult = GetChildEntities(id, queryStrings);

            if (!(entitiesResult.Result is null))
            {
                return(entitiesResult.Result);
            }

            var entities = entitiesResult.Value.ToList();

            //get the current user start node/paths
            GetUserStartNodes(out var userStartNodes, out var userStartNodePaths);

            // if the user does not have access to the root node, what we have is the start nodes,
            // but to provide some context we need to add their topmost nodes when they are not
            // topmost nodes themselves (level > 1).
            if (id == rootIdString && hasAccessToRoot == false)
            {
                // first add the entities that are topmost to the nodes collection
                var topMostEntities = entities.Where(x => x.Level == 1).ToArray();
                nodes.AddRange(topMostEntities.Select(x => GetSingleTreeNodeWithAccessCheck(x, id, queryStrings, userStartNodes, userStartNodePaths)).Where(x => x != null));

                // now add the topmost nodes of the entities that aren't topmost to the nodes collection as well
                // - these will appear as "no-access" nodes in the tree, but will allow the editors to drill down through the tree
                //   until they reach their start nodes
                var topNodeIds = entities.Except(topMostEntities).Select(GetTopNodeId).Where(x => x != 0).Distinct().ToArray();
                if (topNodeIds.Length > 0)
                {
                    var topNodes = _entityService.GetAll(UmbracoObjectType, topNodeIds.ToArray());
                    nodes.AddRange(topNodes.Select(x => GetSingleTreeNodeWithAccessCheck(x, id, queryStrings, userStartNodes, userStartNodePaths)).Where(x => x != null));
                }
            }
            else
            {
                // the user has access to the root, just add the entities
                nodes.AddRange(entities.Select(x => GetSingleTreeNodeWithAccessCheck(x, id, queryStrings, userStartNodes, userStartNodePaths)).Where(x => x != null));
            }

            return(nodes);
        }