/// <summary>
        /// Registers any entity-based block types that are not currently registered in Rock.
        /// </summary>
        /// <param name="refreshAll">if set to <c>true</c> will refresh name, category, and description for all block types (not just the new ones)</param>
        private static void RegisterEntityBlockTypes(bool refreshAll = false)
        {
            var rockBlockTypes = Reflection.FindTypes(typeof(Blocks.IRockBlockType));

            List <Type> registeredTypes;

            using (var rockContext = new RockContext())
            {
                registeredTypes = new BlockTypeService(rockContext)
                                  .Queryable().AsNoTracking()
                                  .Where(b => b.EntityTypeId.HasValue && !string.IsNullOrEmpty(b.EntityType.AssemblyName))
                                  .ToList()
                                  .Select(b => Type.GetType(b.EntityType.AssemblyName, false))
                                  .Where(b => b != null)
                                  .ToList();
            }

            // Get the Block Entity Type
            int?blockEntityTypeId = EntityTypeCache.Get(typeof(Block)).Id;

            // for each BlockType
            foreach (var type in rockBlockTypes.Values)
            {
                if (refreshAll || !registeredTypes.Any(t => t == type))
                {
                    // Attempt to load the control
                    try
                    {
                        using (var rockContext = new RockContext())
                        {
                            var entityTypeId     = EntityTypeCache.Get(type, true, rockContext).Id;
                            var blockTypeService = new BlockTypeService(rockContext);
                            var blockType        = blockTypeService.Queryable()
                                                   .FirstOrDefault(b => b.EntityTypeId == entityTypeId);

                            if (blockType == null)
                            {
                                // Create new BlockType record and save it
                                blockType = new BlockType();
                                blockType.EntityTypeId = entityTypeId;
                                blockTypeService.Add(blockType);
                            }

                            // Update Name, Category, and Description based on block's attribute definitions
                            blockType.Name = Reflection.GetDisplayName(type) ?? string.Empty;
                            if (string.IsNullOrWhiteSpace(blockType.Name))
                            {
                                blockType.Name = type.FullName;
                            }

                            if (blockType.Name.Length > 100)
                            {
                                blockType.Name = blockType.Name.Truncate(100);
                            }

                            blockType.Category    = Rock.Reflection.GetCategory(type) ?? string.Empty;
                            blockType.Description = Rock.Reflection.GetDescription(type) ?? string.Empty;

                            rockContext.SaveChanges();

                            // Update the attributes used by the block
                            Rock.Attribute.Helper.UpdateAttributes(type, blockEntityTypeId, "BlockTypeId", blockType.Id.ToString(), rockContext);
                        }
                    }
                    catch (Exception ex)
                    {
                        Debug.WriteLine($"RegisterEntityBlockTypes failed for {type.FullName} with exception: {ex.Message}");
                        ExceptionLogService.LogException(new Exception(string.Format("Problem processing block with path '{0}'.", type.FullName), ex), null);
                    }
                }
            }
        }
Exemple #2
0
        /// <summary>
        /// Registers any block types that are not currently registered in Rock.
        /// </summary>
        /// <param name="physWebAppPath">A <see cref="System.String" /> containing the physical path to Rock on the server.</param>
        /// <param name="page">The <see cref="System.Web.UI.Page" />.</param>
        /// <param name="refreshAll">if set to <c>true</c> will refresh name, category, and description for all block types (not just the new ones)</param>
        public static void RegisterBlockTypes(string physWebAppPath, System.Web.UI.Page page, bool refreshAll = false)
        {
            // Dictionary for block types.  Key is path, value is friendly name
            var list = new Dictionary <string, string>();

            RegisterEntityBlockTypes(refreshAll);

            // Find all the blocks in the Blocks folder...
            FindAllBlocksInPath(physWebAppPath, list, "Blocks");

            // Now do the exact same thing for the Plugins folder...
            FindAllBlocksInPath(physWebAppPath, list, "Plugins");

            // Get a list of the BlockTypes already registered (via the path)
            var registeredPaths = new List <string>();

            using (var rockContext = new RockContext())
            {
                registeredPaths = new BlockTypeService(rockContext)
                                  .Queryable().AsNoTracking()
                                  .Where(b => !string.IsNullOrEmpty(b.Path))
                                  .Select(b => b.Path)
                                  .ToList();
            }

            // Get the Block Entity Type
            int?blockEntityTypeId = EntityTypeCache.Get(typeof(Block)).Id;

            // for each BlockType
            foreach (string path in list.Keys)
            {
                if (refreshAll || !registeredPaths.Any(b => b.Equals(path, StringComparison.OrdinalIgnoreCase)))
                {
                    // Attempt to load the control
                    try
                    {
                        var blockCompiledType = System.Web.Compilation.BuildManager.GetCompiledType(path);
                        if (blockCompiledType != null && typeof(Web.UI.RockBlock).IsAssignableFrom(blockCompiledType))
                        {
                            using (var rockContext = new RockContext())
                            {
                                var blockTypeService = new BlockTypeService(rockContext);
                                var blockType        = blockTypeService.Queryable()
                                                       .FirstOrDefault(b => b.Path == path);
                                if (blockType == null)
                                {
                                    // Create new BlockType record and save it
                                    blockType      = new BlockType();
                                    blockType.Path = path;
                                    blockTypeService.Add(blockType);
                                }

                                Type controlType = blockCompiledType;

                                // Update Name, Category, and Description based on block's attribute definitions
                                blockType.Name = Reflection.GetDisplayName(controlType) ?? string.Empty;
                                if (string.IsNullOrWhiteSpace(blockType.Name))
                                {
                                    // Parse the relative path to get the name
                                    var nameParts = list[path].Split('/');
                                    for (int i = 0; i < nameParts.Length; i++)
                                    {
                                        if (i == nameParts.Length - 1)
                                        {
                                            nameParts[i] = Path.GetFileNameWithoutExtension(nameParts[i]);
                                        }

                                        nameParts[i] = nameParts[i].SplitCase();
                                    }

                                    blockType.Name = string.Join(" > ", nameParts);
                                }

                                if (blockType.Name.Length > 100)
                                {
                                    blockType.Name = blockType.Name.Truncate(100);
                                }

                                blockType.Category    = Rock.Reflection.GetCategory(controlType) ?? string.Empty;
                                blockType.Description = Rock.Reflection.GetDescription(controlType) ?? string.Empty;

                                rockContext.SaveChanges();

                                // Update the attributes used by the block
                                Rock.Attribute.Helper.UpdateAttributes(controlType, blockEntityTypeId, "BlockTypeId", blockType.Id.ToString(), rockContext);
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        System.Diagnostics.Debug.WriteLine($"RegisterBlockTypes failed for {path} with exception: {ex.Message}");
                        ExceptionLogService.LogException(new Exception(string.Format("Problem processing block with path '{0}'.", path), ex), null);
                    }
                }
            }
        }