Exemplo n.º 1
0
        /// <summary>
        /// Gets the sorted list of children items from the query.
        /// </summary>
        /// <param name="options">The options that describe the current operation.</param>
        /// <param name="cachedEntityType">The cached entity type object that describes the items.</param>
        /// <param name="itemsQry">The items qry.</param>
        /// <returns>A list of child items that should be included in the results.</returns>
        private List <TreeItemViewModel> GetChildrenItems(CategoryItemTreeOptions options, EntityTypeCache cachedEntityType, IQueryable <ICategorized> itemsQry)
        {
            // Do a ToList() to load from database prior to ordering
            // by name, just in case Name is a virtual property.
            var itemsList            = itemsQry.ToList();
            var entityTypeIsSchedule = cachedEntityType.Id == EntityTypeCache.GetId <Rock.Model.Schedule>();

            List <ICategorized> sortedItemsList;

            // Sort the items by the name, unless it is a schedule.
            if (entityTypeIsSchedule && itemsList.OfType <Rock.Model.Schedule>() != null)
            {
                sortedItemsList = itemsList.OfType <Rock.Model.Schedule>().ToList().OrderByOrderAndNextScheduledDateTime().OfType <ICategorized>().ToList();
            }
            else
            {
                sortedItemsList = itemsList.OrderBy(i => i.Name).ToList();
            }

            var children = new List <TreeItemViewModel>();

            // Walk each item from the sorted list and determine if we it
            // should be added to the list of children.
            foreach (var categorizedItem in sortedItemsList)
            {
                // Ensure the person is authorized to view this item and that
                // the item is of type IEntity so we can get to the Guid.
                if (categorizedItem.IsAuthorized(Authorization.VIEW, Person) && categorizedItem is IEntity categorizedEntityItem)
                {
                    var categoryItem = new TreeItemViewModel
                    {
                        Value        = categorizedEntityItem.Guid.ToString(),
                        Text         = categorizedItem.Name,
                        IconCssClass = categorizedItem.GetPropertyValue("IconCssClass") as string ?? options.DefaultIconCssClass
                    };

                    if (categorizedItem is IHasActiveFlag activatedItem)
                    {
                        categoryItem.IsActive = activatedItem.IsActive;
                    }

                    children.Add(categoryItem);
                }
            }

            return(children);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Determines if the category has any child categories or items.
        /// </summary>
        /// <param name="options">The options that describe the current operation.</param>
        /// <param name="categoryService">The category service.</param>
        /// <param name="serviceInstance">The service instance used to access the items.</param>
        /// <param name="categoryId">The category item identifier.</param>
        /// <returns><c>true</c> if the category has children, <c>false</c> otherwise.</returns>
        private bool DoesCategoryHaveChildren(CategoryItemTreeOptions options, CategoryService categoryService, IService serviceInstance, string categoryId)
        {
            var parentGuid = categoryId.AsGuid();

            // First try a simple query on categories. This is the cheaper
            // of the two operations.
            foreach (var childCategory in categoryService.Queryable().Where(c => c.ParentCategory.Guid == parentGuid))
            {
                if (childCategory.IsAuthorized(Authorization.VIEW, Person))
                {
                    return(true);
                }
            }

            // If we didn't find any children from the above then try looking
            // for any items that reference this category.

            var itemOptions = new CategorizedItemQueryOptions
            {
                CategoryGuid              = parentGuid,
                IncludeInactiveItems      = options.IncludeInactiveItems,
                IncludeUnnamedEntityItems = options.IncludeUnnamedEntityItems,
                ItemFilterPropertyName    = options.ItemFilterPropertyName,
                ItemFilterPropertyValue   = options.ItemFilterPropertyValue
            };

            var childItems = categoryService.GetCategorizedItemQuery(serviceInstance, itemOptions);

            if (childItems != null)
            {
                foreach (var categorizedItem in childItems)
                {
                    if (categorizedItem != null && categorizedItem.IsAuthorized(Authorization.VIEW, Person))
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Gets the categorized tree items. This supports various options
        /// for filtering and determine how much data to load.
        /// </summary>
        /// <param name="options">The options that describe the request.</param>
        /// <returns>A list of view models that describe the tree of categories and items.</returns>
        public List <TreeItemViewModel> GetCategorizedTreeItems(CategoryItemTreeOptions options = null)
        {
            options = options ?? DefaultCategoryItemTreeOptions;

            // Initialize the basic query.
            var categoryService = new CategoryService(RockContext);

            var childQueryOptions = new ChildCategoryQueryOptions
            {
                ParentGuid                = options.ParentGuid,
                EntityTypeGuid            = options.EntityTypeGuid,
                IncludeCategoryGuids      = options.IncludeCategoryGuids,
                ExcludeCategoryGuids      = options.ExcludeCategoryGuids,
                EntityTypeQualifierColumn = options.EntityTypeQualifierColumn,
                EntityTypeQualifierValue  = options.EntityTypeQualifierValue
            };

            var qry = categoryService.GetChildCategoryQuery(childQueryOptions);

            // Cache the service instance for later use. If we have specified an
            // entity type then this ends up getting set.
            IService serviceInstance  = null;
            var      cachedEntityType = options.EntityTypeGuid.HasValue
                ? EntityTypeCache.Get(options.EntityTypeGuid.Value)
                : null;

            // If we have been requested to limit the results to a specific entity
            // type then apply those filters.
            if (cachedEntityType != null)
            {
                // Attempt to initialize the entity service instance. This also
                // checks if the entity supports the active flag.
                if (cachedEntityType.AssemblyName != null)
                {
                    Type entityType = cachedEntityType.GetEntityType();
                    if (entityType != null)
                    {
                        Type[] modelType          = { entityType };
                        Type   genericServiceType = typeof(Rock.Data.Service <>);
                        Type   modelServiceType   = genericServiceType.MakeGenericType(modelType);

                        serviceInstance = Activator.CreateInstance(modelServiceType, new object[] { new RockContext() }) as IService;
                    }
                }
            }

            var categoryList = qry.OrderBy(c => c.Order).ThenBy(c => c.Name).ToList();

            // Get all the categories from the query and then filter on security.
            var categoryItemList = categoryList
                                   .Where(c => c.IsAuthorized(Authorization.VIEW, Person))
                                   .Select(c => new TreeItemViewModel
            {
                Value        = c.Guid.ToString(),
                Text         = c.Name,
                IsFolder     = true,
                IconCssClass = c.IconCssClass
            })
                                   .ToList();

            if (options.GetCategorizedItems)
            {
                var itemOptions = new CategorizedItemQueryOptions
                {
                    CategoryGuid              = options.ParentGuid,
                    IncludeInactiveItems      = options.IncludeInactiveItems,
                    IncludeUnnamedEntityItems = options.IncludeUnnamedEntityItems,
                    ItemFilterPropertyName    = options.ItemFilterPropertyName,
                    ItemFilterPropertyValue   = options.ItemFilterPropertyValue
                };

                var itemsQry = categoryService.GetCategorizedItemQuery(serviceInstance, itemOptions);

                if (itemsQry != null)
                {
                    var childItems = GetChildrenItems(options, cachedEntityType, itemsQry);

                    categoryItemList.AddRange(childItems);
                }
            }

            if (options.LazyLoad)
            {
                // Try to figure out which items have viewable children in
                // the existing list and set them appropriately.
                foreach (var categoryItemListItem in categoryItemList)
                {
                    if (categoryItemListItem.IsFolder)
                    {
                        categoryItemListItem.HasChildren = DoesCategoryHaveChildren(options, categoryService, serviceInstance, categoryItemListItem.Value);
                    }
                }
            }
            else
            {
                foreach (var item in categoryItemList)
                {
                    var parentGuid = item.Value.AsGuidOrNull();

                    if (item.Children == null)
                    {
                        item.Children = new List <TreeItemViewModel>();
                    }

                    GetAllDescendants(item, Person, categoryService, serviceInstance, cachedEntityType, options);
                }
            }

            // If they don't want empty categories then filter out categories
            // that do not have child items.
            if (!options.IncludeCategoriesWithoutChildren)
            {
                categoryItemList = categoryItemList
                                   .Where(a => !a.IsFolder || (a.IsFolder && a.HasChildren))
                                   .ToList();
            }

            return(categoryItemList);
        }
Exemplo n.º 4
0
        /// <summary>
        /// Gets all both category and non-category item decendents for the provided categoryItem.
        /// This method updates the provided categoryItem.
        /// </summary>
        /// <param name="categoryItem">The category item.</param>
        /// <param name="currentPerson">The current person.</param>
        /// <param name="categoryService">The category service.</param>
        /// <param name="serviceInstance">The service instance.</param>
        /// <param name="cachedEntityType">The cached entity type of the items.</param>
        /// <param name="options">The options that describe the current operation.</param>
        /// <returns></returns>
        private TreeItemViewModel GetAllDescendants(TreeItemViewModel categoryItem, Person currentPerson, CategoryService categoryService, IService serviceInstance, EntityTypeCache cachedEntityType, CategoryItemTreeOptions options)
        {
            if (categoryItem.IsFolder)
            {
                var parentGuid      = categoryItem.Value.AsGuidOrNull();
                var childCategories = categoryService.Queryable()
                                      .AsNoTracking()
                                      .Where(c => c.ParentCategory.Guid == parentGuid)
                                      .OrderBy(c => c.Order)
                                      .ThenBy(c => c.Name);

                foreach (var childCategory in childCategories)
                {
                    if (childCategory.IsAuthorized(Authorization.VIEW, currentPerson))
                    {
                        // This category has child categories that the person can view so add them to categoryItemList
                        categoryItem.HasChildren = true;
                        var childCategoryItem = new TreeItemViewModel
                        {
                            Value        = childCategory.Guid.ToString(),
                            Text         = childCategory.Name,
                            IsFolder     = true,
                            IconCssClass = childCategory.GetPropertyValue("IconCssClass") as string ?? options.DefaultIconCssClass
                        };

                        if (childCategory is IHasActiveFlag activatedItem)
                        {
                            childCategoryItem.IsActive = activatedItem.IsActive;
                        }

                        var childCategorizedItemBranch = GetAllDescendants(childCategoryItem, currentPerson, categoryService, serviceInstance, cachedEntityType, options);
                        if (categoryItem.Children == null)
                        {
                            categoryItem.Children = new List <TreeItemViewModel>();
                        }

                        categoryItem.Children.Add(childCategorizedItemBranch);
                    }
                }

                // now that we have taken care of the child categories get the items for this category.
                if (options.GetCategorizedItems)
                {
                    var itemOptions = new CategorizedItemQueryOptions
                    {
                        CategoryGuid              = parentGuid,
                        IncludeInactiveItems      = options.IncludeInactiveItems,
                        IncludeUnnamedEntityItems = options.IncludeUnnamedEntityItems,
                        ItemFilterPropertyName    = options.ItemFilterPropertyName,
                        ItemFilterPropertyValue   = options.ItemFilterPropertyValue
                    };

                    var childQry = categoryService.GetCategorizedItemQuery(serviceInstance, itemOptions);

                    if (childQry != null)
                    {
                        var childItems = GetChildrenItems(options, cachedEntityType, childQry);

                        categoryItem.Children = new List <TreeItemViewModel>();
                        categoryItem.Children.AddRange(childItems);
                        categoryItem.HasChildren = childItems.Any();
                    }
                }
            }

            return(categoryItem);
        }