Beispiel #1
0
        // 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);
        }
Beispiel #3
0
        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})");
        }
Beispiel #4
0
        // 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);
        }
Beispiel #8
0
        /// <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);
        }
Beispiel #9
0
        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);
        }
Beispiel #10
0
        // 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;
Beispiel #11
0
        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);
        }
Beispiel #12
0
        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 ?
            }
        }
Beispiel #15
0
    /// <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 + "]]";
        }
    }
Beispiel #16
0
        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]);
        }
Beispiel #17
0
        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);
        }
Beispiel #19
0
        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);
        }