/// <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); } } } }
/// <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); } } } }