/// <summary> /// Handles the Click event of the btnSave control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param> protected void btnSave_Click( object sender, EventArgs e ) { BlockType blockType; BlockTypeService blockTypeService = new BlockTypeService(); int blockTypeId = int.Parse( hfBlockTypeId.Value ); if ( blockTypeId == 0 ) { blockType = new BlockType(); blockTypeService.Add( blockType, CurrentPersonId ); } else { BlockTypeCache.Flush( blockTypeId ); blockType = blockTypeService.Get( blockTypeId ); } blockType.Name = tbName.Text; blockType.Path = tbPath.Text; blockType.Description = tbDescription.Text; if ( !blockType.IsValid ) { // Controls will render the error messages return; } RockTransactionScope.WrapTransaction( () => { blockTypeService.Save( blockType, CurrentPersonId ); } ); NavigateToParentPage(); }
private void LoadBlockTypes() { using (new Rock.Data.UnitOfWorkScope()) { Rock.Model.BlockTypeService blockTypeService = new Rock.Model.BlockTypeService(); // Add any unregistered blocks foreach (Rock.Model.BlockType blockType in blockTypeService.GetUnregisteredBlocks(Request.MapPath("~"))) { try { Control control = LoadControl(blockType.Path); if (control is Rock.Web.UI.RockBlock) { blockType.Name = Path.GetFileNameWithoutExtension(blockType.Path); // Split the name on intercapped changes (ie, "HelloWorld" becomes "Hello World") blockType.Name = System.Text.RegularExpressions.Regex.Replace(blockType.Name, "([a-z](?=[A-Z])|[A-Z](?=[A-Z][a-z]))", "$1 "); blockType.Description = blockType.Path; blockTypeService.Add(blockType, CurrentPersonId); blockTypeService.Save(blockType, CurrentPersonId); } } catch { } } ddlBlockType.DataSource = blockTypeService.Queryable().OrderBy(b => b.Name).ToList(); ddlBlockType.DataTextField = "Name"; ddlBlockType.DataValueField = "Id"; ddlBlockType.DataBind(); } }
/// <summary> /// Handles the Click event of the btnSave control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param> protected void btnSave_Click( object sender, EventArgs e ) { BlockType blockType; BlockTypeService blockTypeService = new BlockTypeService(); int blockTypeId = int.Parse( hfBlockTypeId.Value ); if ( blockTypeId == 0 ) { blockType = new BlockType(); blockTypeService.Add( blockType, CurrentPersonId ); } else { BlockTypeCache.Flush( blockTypeId ); blockType = blockTypeService.Get( blockTypeId ); } blockType.Name = tbName.Text; blockType.Path = tbPath.Text; blockType.Description = tbDescription.Text; if ( !blockType.IsValid ) { // Controls will render the error messages return; } blockTypeService.Save( blockType, CurrentPersonId ); BindGrid(); pnlDetails.Visible = false; pnlList.Visible = true; }
/// <summary> /// Handles the Click event of the btnSave control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param> protected void btnSave_Click( object sender, EventArgs e ) { BlockType blockType; var rockContext = new RockContext(); BlockTypeService blockTypeService = new BlockTypeService( rockContext ); int blockTypeId = int.Parse( hfBlockTypeId.Value ); if ( blockTypeId == 0 ) { blockType = new BlockType(); blockTypeService.Add( blockType ); } else { BlockTypeCache.Flush( blockTypeId ); blockType = blockTypeService.Get( blockTypeId ); } blockType.Name = tbName.Text; blockType.Path = tbPath.Text; blockType.Description = tbDescription.Text; if ( !blockType.IsValid ) { // Controls will render the error messages return; } rockContext.SaveChanges(); NavigateToParentPage(); }
/// <summary> /// Loads the block types. /// </summary> private void LoadBlockTypes(bool registerBlockTypes) { if (registerBlockTypes) { // Add any unregistered blocks try { BlockTypeService.RegisterBlockTypes(Request.MapPath("~"), Page); } catch (Exception ex) { nbMessage.Text = "Error registering one or more block types"; nbMessage.Details = ex.Message + "<code>" + HttpUtility.HtmlEncode(ex.StackTrace) + "</code>"; nbMessage.Visible = true; } } // Load the block types using (var rockContext = new RockContext()) { Rock.Model.BlockTypeService blockTypeService = new Rock.Model.BlockTypeService(rockContext); var blockTypes = blockTypeService.Queryable().AsNoTracking() .Select(b => new { b.Id, b.Name, b.Category, b.Description }) .ToList(); ddlBlockType.Items.Clear(); // Add the categorized block types foreach (var blockType in blockTypes .Where(b => b.Category != "") .OrderBy(b => b.Category) .ThenBy(b => b.Name)) { var li = new ListItem(blockType.Name, blockType.Id.ToString()); li.Attributes.Add("optiongroup", blockType.Category); li.Attributes.Add("title", blockType.Description); ddlBlockType.Items.Add(li); } // Add the uncategorized block types foreach (var blockType in blockTypes .Where(b => b.Category == null || b.Category == "") .OrderBy(b => b.Name)) { var li = new ListItem(blockType.Name, blockType.Id.ToString()); li.Attributes.Add("optiongroup", "Other (not categorized)"); li.Attributes.Add("title", blockType.Description); ddlBlockType.Items.Add(li); } } }
/// <summary> /// Loads the block types. /// </summary> private void LoadBlockTypes() { using (new Rock.Data.UnitOfWorkScope()) { Rock.Model.BlockTypeService blockTypeService = new Rock.Model.BlockTypeService(); // Add any unregistered blocks blockTypeService.RegisterBlockTypes(Request.MapPath("~"), Page, CurrentPersonId); ddlBlockType.DataSource = blockTypeService.Queryable().OrderBy(b => b.Name).ToList(); ddlBlockType.DataTextField = "Name"; ddlBlockType.DataValueField = "Id"; ddlBlockType.DataBind(); } }
/// <summary> /// Shows the edit. /// </summary> /// <param name="location">The location.</param> /// <param name="blockId">The block id.</param> protected void ShowEdit(BlockLocation location, int blockId) { using (var rockContext = new RockContext()) { BlockService blockService = new BlockService(rockContext); Rock.Model.Block block = blockService.Get(blockId); hfBlockLocation.Value = location.ConvertToString(); if (block != null) { lAction.Text = "Edit "; hfBlockId.Value = block.Id.ToString(); ddlBlockType.SelectedValue = block.BlockType.Id.ToString(); tbBlockName.Text = block.Name; } else { lAction.Text = "Add "; hfBlockId.Value = "0"; // Select HTML Content block by default var blockType = new Rock.Model.BlockTypeService(rockContext) .GetByGuid(new Guid(Rock.SystemGuid.BlockType.HTML_CONTENT)); if (blockType != null) { ddlBlockType.SelectedValue = blockType.Id.ToString(); } else { ddlBlockType.SelectedIndex = -1; } tbBlockName.Text = string.Empty; } } lAction.Text += hfBlockLocation.Value; pnlLists.Visible = false; pnlDetails.Visible = true; }
/// <summary> /// Handles the Delete event of the gBlockTypes control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="RowEventArgs" /> instance containing the event data.</param> protected void gBlockTypes_Delete( object sender, RowEventArgs e ) { var rockContext = new RockContext(); BlockTypeService blockTypeService = new BlockTypeService( rockContext ); BlockType blockType = blockTypeService.Get( e.RowKeyId ); if ( blockType != null ) { string errorMessage; if ( !blockTypeService.CanDelete( blockType, out errorMessage ) ) { mdGridWarning.Show( errorMessage, ModalAlertType.Information ); return; } blockTypeService.Delete( blockType ); rockContext.SaveChanges(); Rock.Web.Cache.BlockTypeCache.Flush( blockType.Id ); } BindGrid(); }
/// <summary> /// Loads the block types. /// </summary> private void LoadBlockTypes() { using (new Rock.Data.UnitOfWorkScope()) { Rock.Model.BlockTypeService blockTypeService = new Rock.Model.BlockTypeService(); // Add any unregistered blocks blockTypeService.RegisterBlockTypes(Request.MapPath("~"), Page, CurrentPersonId); // Load the block types var blockTypes = blockTypeService.Queryable() .Select(b => new { b.Id, b.Name, b.Category, b.Description }) .ToList(); ddlBlockType.Items.Clear(); // Add the categorized block types foreach (var blockType in blockTypes .Where(b => b.Category != "") .OrderBy(b => b.Category) .ThenBy(b => b.Name)) { var li = new ListItem(blockType.Name, blockType.Id.ToString()); li.Attributes.Add("optiongroup", blockType.Category); li.Attributes.Add("title", blockType.Description); ddlBlockType.Items.Add(li); } // Add the uncategorized block types foreach (var blockType in blockTypes .Where(b => b.Category == null || b.Category == "") .OrderBy(b => b.Name)) { var li = new ListItem(blockType.Name, blockType.Id.ToString()); li.Attributes.Add("optiongroup", "Other (not categorized)"); li.Attributes.Add("title", blockType.Description); ddlBlockType.Items.Add(li); } } }
/// <summary> /// Shows the detail. /// </summary> /// <param name="blockTypeId">The block type identifier.</param> public void ShowDetail( int blockTypeId ) { pnlDetails.Visible = true; // Load depending on Add(0) or Edit BlockType blockType = null; if ( !blockTypeId.Equals( 0 ) ) { blockType = new BlockTypeService( new RockContext() ).Get( blockTypeId ); lActionTitle.Text = ActionTitle.Edit( BlockType.FriendlyTypeName ).FormatAsHtmlTitle(); lPages.Visible = true; lblStatus.Visible = true; pdAuditDetails.SetEntity( blockType, ResolveRockUrl( "~" ) ); } if (blockType == null) { blockType = new BlockType { Id = 0 }; lActionTitle.Text = ActionTitle.Add( BlockType.FriendlyTypeName ).FormatAsHtmlTitle(); lPages.Visible = false; lblStatus.Visible = false; // hide the panel drawer that show created and last modified dates pdAuditDetails.Visible = false; } hfBlockTypeId.Value = blockType.Id.ToString(); tbName.Text = blockType.Name; tbPath.Text = blockType.Path; tbDescription.Text = blockType.Description; StringBuilder sb = new StringBuilder(); foreach ( var fullPageName in blockType.Blocks.ToList().Where( a => a.Page != null ).Select(a => GetFullyQualifiedPageName(a.Page)).OrderBy(a => a)) { sb.Append( fullPageName ); } if ( sb.Length == 0 ) { lPages.Text = "<span class='text-muted'><em>No pages are currently using this block</em></muted>"; } else { lPages.Text = string.Format( "<ul>{0}</ul>", sb.ToString() ); } string blockPath = Request.MapPath( blockType.Path ); if ( !System.IO.File.Exists( blockPath ) ) { lblStatus.Text = string.Format( "<span class='label label-danger'>The file '{0}' [{1}] does not exist.</span>", blockType.Path, blockType.Guid ); } else { lblStatus.Text = "<span class='label label-success'>Block exists on the file system.</span>"; } // render UI based on Authorized and IsSystem bool readOnly = false; nbEditModeMessage.Text = string.Empty; if ( !IsUserAuthorized( Authorization.EDIT ) ) { readOnly = true; nbEditModeMessage.Text = EditModeMessage.ReadOnlyEditActionNotAllowed( BlockType.FriendlyTypeName ); } if ( blockType.IsSystem ) { readOnly = true; nbEditModeMessage.Text = EditModeMessage.ReadOnlySystem( BlockType.FriendlyTypeName ); } if ( readOnly ) { lActionTitle.Text = ActionTitle.View( BlockType.FriendlyTypeName ).FormatAsHtmlTitle(); btnCancel.Text = "Close"; } tbName.ReadOnly = readOnly; tbPath.ReadOnly = readOnly; tbDescription.ReadOnly = readOnly; btnSave.Visible = !readOnly; }
/// <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) List <string> registeredPaths; if (refreshAll) { FlushRegistrationCache(); registeredPaths = new List <string>(); } else { 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 the block has been previously processed or successfully registered, ignore it. if (_processedBlockPaths.Any(b => b.Equals(path, StringComparison.OrdinalIgnoreCase)) || registeredPaths.Any(b => b.Equals(path, StringComparison.OrdinalIgnoreCase))) { continue; } // Store the block path in the list of processed blocks to avoid re-processing if the registration fails. lock ( _processedBlockPathsLock ) { _processedBlockPaths.Add(path); } // 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); } } }
/// <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> /// Handles the Click event of the btnAddBlock control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param> protected void btnAddBlock_Click(object sender, EventArgs e) { tbNewBlockName.Text = string.Empty; // Load the block types using (var rockContext = new RockContext()) { try { BlockTypeService.RegisterBlockTypes(Request.MapPath("~"), Page); } catch { // ignore } Rock.Model.BlockTypeService blockTypeService = new Rock.Model.BlockTypeService(rockContext); var blockTypes = blockTypeService.Queryable().AsNoTracking() .Select(b => new { b.Id, b.Name, b.Category, b.Description }) .ToList(); ddlBlockType.Items.Clear(); // Add the categorized block types foreach (var blockType in blockTypes .Where(b => b.Category != string.Empty) .OrderBy(b => b.Category) .ThenBy(b => b.Name)) { var li = new ListItem(blockType.Name, blockType.Id.ToString()); li.Attributes.Add("optiongroup", blockType.Category); li.Attributes.Add("title", blockType.Description); ddlBlockType.Items.Add(li); } // Add the uncategorized block types foreach (var blockType in blockTypes .Where(b => b.Category == null || b.Category == string.Empty) .OrderBy(b => b.Name)) { var li = new ListItem(blockType.Name, blockType.Id.ToString()); li.Attributes.Add("optiongroup", "Other (not categorized)"); li.Attributes.Add("title", blockType.Description); ddlBlockType.Items.Add(li); } } var htmlContentBlockType = BlockTypeCache.Read(Rock.SystemGuid.BlockType.HTML_CONTENT.AsGuid()); ddlBlockType.SetValue(htmlContentBlockType.Id); rblAddBlockLocation.Items.Clear(); var page = PageCache.Read(hfPageId.Value.AsInteger()); var listItemPage = new ListItem(); listItemPage.Text = string.Format("Page ({0})", page.ToString()); listItemPage.Value = "Page"; listItemPage.Selected = true; var listItemLayout = new ListItem(); listItemLayout.Text = string.Format("Layout ({0})", page.Layout); listItemLayout.Value = "Layout"; listItemLayout.Selected = false; var listItemSite = new ListItem(); listItemSite.Text = string.Format("Site ({0})", page.Layout.Site); listItemSite.Value = "Site"; listItemSite.Selected = false; rblAddBlockLocation.Items.Add(listItemPage); rblAddBlockLocation.Items.Add(listItemLayout); rblAddBlockLocation.Items.Add(listItemSite); mdAddBlock.Title = "Add Block to " + ddlZones.SelectedValue + " Zone"; mdAddBlock.Show(); }
/// <summary> /// Shows the edit. /// </summary> /// <param name="blockTypeId">The block type id.</param> protected void ShowEdit( int blockTypeId ) { pnlDetails.Visible = true; pnlList.Visible = false; BlockTypeService blockTypeService = new BlockTypeService(); BlockType blockType = blockTypeService.Get( blockTypeId ); if ( blockType != null ) { lActionTitle.Text = ActionTitle.Edit( BlockType.FriendlyTypeName ); hfBlockTypeId.Value = blockType.Id.ToString(); tbName.Text = blockType.Name; tbPath.Text = blockType.Path; tbDescription.Text = blockType.Description; } else { lActionTitle.Text = ActionTitle.Add( BlockType.FriendlyTypeName ); hfBlockTypeId.Value = 0.ToString(); tbName.Text = string.Empty; tbPath.Text = string.Empty; tbDescription.Text = string.Empty; } }
/// <summary> /// Loads the block types. /// </summary> private void LoadBlockTypes( bool registerBlockTypes ) { if ( registerBlockTypes ) { // Add any unregistered blocks try { BlockTypeService.RegisterBlockTypes( Request.MapPath( "~" ), Page ); } catch ( Exception ex ) { nbMessage.Text = "Error registering one or more block types"; nbMessage.Details = ex.Message + "<code>" + HttpUtility.HtmlEncode( ex.StackTrace ) + "</code>"; nbMessage.Visible = true; } } // Load the block types using ( var rockContext = new RockContext() ) { Rock.Model.BlockTypeService blockTypeService = new Rock.Model.BlockTypeService( rockContext ); var blockTypes = blockTypeService.Queryable().AsNoTracking() .Select( b => new { b.Id, b.Name, b.Category, b.Description } ) .ToList(); ddlBlockType.Items.Clear(); // Add the categorized block types foreach ( var blockType in blockTypes .Where( b => b.Category != "" ) .OrderBy( b => b.Category ) .ThenBy( b => b.Name ) ) { var li = new ListItem( blockType.Name, blockType.Id.ToString() ); li.Attributes.Add( "optiongroup", blockType.Category ); li.Attributes.Add( "title", blockType.Description ); ddlBlockType.Items.Add( li ); } // Add the uncategorized block types foreach ( var blockType in blockTypes .Where( b => b.Category == null || b.Category == "" ) .OrderBy( b => b.Name ) ) { var li = new ListItem( blockType.Name, blockType.Id.ToString() ); li.Attributes.Add( "optiongroup", "Other (not categorized)" ); li.Attributes.Add( "title", blockType.Description ); ddlBlockType.Items.Add( li ); } } }
/// <summary> /// Loads the block types. /// </summary> private void LoadBlockTypes() { // Add any unregistered blocks BlockTypeService.RegisterBlockTypes( Request.MapPath( "~" ), Page ); // Load the block types Rock.Model.BlockTypeService blockTypeService = new Rock.Model.BlockTypeService( new RockContext() ); var blockTypes = blockTypeService.Queryable() .Select( b => new { b.Id, b.Name, b.Category, b.Description } ) .ToList(); ddlBlockType.Items.Clear(); // Add the categorized block types foreach ( var blockType in blockTypes .Where( b => b.Category != "" ) .OrderBy( b => b.Category ) .ThenBy( b => b.Name ) ) { var li = new ListItem( blockType.Name, blockType.Id.ToString() ); li.Attributes.Add( "optiongroup", blockType.Category ); li.Attributes.Add( "title", blockType.Description ); ddlBlockType.Items.Add( li ); } // Add the uncategorized block types foreach ( var blockType in blockTypes .Where( b => b.Category == null || b.Category == "" ) .OrderBy( b => b.Name ) ) { var li = new ListItem( blockType.Name, blockType.Id.ToString() ); li.Attributes.Add( "optiongroup", "Other (not categorized)" ); li.Attributes.Add( "title", blockType.Description ); ddlBlockType.Items.Add( li ); } }
/// <summary> /// Shows the detail. /// </summary> /// <param name="itemKey">The item key.</param> /// <param name="itemKeyValue">The item key value.</param> public void ShowDetail( string itemKey, int itemKeyValue ) { // return if unexpected itemKey if ( itemKey != "blockTypeId" ) { return; } pnlDetails.Visible = true; // Load depending on Add(0) or Edit BlockType blockType = null; if ( !itemKeyValue.Equals( 0 ) ) { blockType = new BlockTypeService( new RockContext() ).Get( itemKeyValue ); lActionTitle.Text = ActionTitle.Edit( BlockType.FriendlyTypeName ).FormatAsHtmlTitle(); lstPages.Visible = true; lblStatus.Visible = true; } else { blockType = new BlockType { Id = 0 }; lActionTitle.Text = ActionTitle.Add( BlockType.FriendlyTypeName ).FormatAsHtmlTitle(); lstPages.Visible = false; lblStatus.Visible = false; } hfBlockTypeId.Value = blockType.Id.ToString(); tbName.Text = blockType.Name; tbPath.Text = blockType.Path; tbDescription.Text = blockType.Description; foreach ( var fullPageName in blockType.Blocks.ToList().Where( a => a.Page != null ).Select(a => GetFullyQualifiedPageName(a.Page)).OrderBy(a => a)) { lstPages.Items.Add( fullPageName ); } if ( lstPages.Items.Count == 0 ) { lstPages.Items.Add( "No pages are currently using this block" ); } string blockPath = Request.MapPath( blockType.Path ); if ( !System.IO.File.Exists( blockPath ) ) { lblStatus.Text = string.Format( "<span class='label label-danger'>The file '{0}' [{1}] does not exist.</span>", blockType.Path, blockType.Guid ); } else { lblStatus.Text = "<span class='label label-success'>Block exists on the file system.</span>"; } // render UI based on Authorized and IsSystem bool readOnly = false; nbEditModeMessage.Text = string.Empty; if ( !IsUserAuthorized( Authorization.EDIT ) ) { readOnly = true; nbEditModeMessage.Text = EditModeMessage.ReadOnlyEditActionNotAllowed( BlockType.FriendlyTypeName ); } if ( blockType.IsSystem ) { readOnly = true; nbEditModeMessage.Text = EditModeMessage.ReadOnlySystem( BlockType.FriendlyTypeName ); } if ( readOnly ) { lActionTitle.Text = ActionTitle.View( BlockType.FriendlyTypeName ).FormatAsHtmlTitle(); btnCancel.Text = "Close"; } tbName.ReadOnly = readOnly; tbPath.ReadOnly = readOnly; tbDescription.ReadOnly = readOnly; btnSave.Visible = !readOnly; }
/// <summary> /// Handles the Delete event of the gBlockTypes control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="RowEventArgs" /> instance containing the event data.</param> protected void gBlockTypes_Delete( object sender, RowEventArgs e ) { BlockTypeService blockTypeService = new BlockTypeService(); BlockType blockType = blockTypeService.Get( (int)gBlockTypes.DataKeys[e.RowIndex]["id"] ); if ( CurrentBlock != null ) { blockTypeService.Delete( blockType, CurrentPersonId ); blockTypeService.Save( blockType, CurrentPersonId ); Rock.Web.Cache.BlockTypeCache.Flush( blockType.Id ); } BindGrid(); }
/// <summary> /// Binds the grid. /// </summary> private void BindGrid() { BlockTypeService blockTypeService = new BlockTypeService( new RockContext() ); SortProperty sortProperty = gBlockTypes.SortProperty; var blockTypes = blockTypeService.Queryable(); // Exclude system blocks if checked. if ( !string.IsNullOrWhiteSpace( gfSettings.GetUserPreference("Exclude System") ) ) { blockTypes = blockTypes.Where( b => b.IsSystem == false ); } // Filter by Name string nameFilter = gfSettings.GetUserPreference( "Name" ); if ( !string.IsNullOrEmpty( nameFilter.Trim() ) ) { blockTypes = blockTypes.Where( b => b.Name.Contains( nameFilter.Trim() ) ); } // Filter by Path string path = gfSettings.GetUserPreference( "Path" ); if ( !string.IsNullOrEmpty( path.Trim() ) ) { blockTypes = blockTypes.Where( b => b.Path.Contains( path.Trim() ) ); } string category = gfSettings.GetUserPreference( "Category" ); if (!string.IsNullOrWhiteSpace(category)) { blockTypes = blockTypes.Where( b => b.Category == category ); } var selectQry = blockTypes.Select( a => new { a.Id, a.Name, a.Category, a.Description, a.Path, BlocksCount = a.Blocks.Count(), a.IsSystem } ); if ( sortProperty != null ) { if ( sortProperty.Property == "Status" ) { // special case: See if the file exists and sort by that if ( sortProperty.Direction == System.Web.UI.WebControls.SortDirection.Ascending ) { gBlockTypes.DataSource = selectQry.ToList().OrderBy( a => System.IO.File.Exists( Request.MapPath( a.Path ) ) ).ToList(); } else { gBlockTypes.DataSource = selectQry.ToList().OrderBy( a => !System.IO.File.Exists( Request.MapPath( a.Path ) ) ).ToList(); } } else { gBlockTypes.DataSource = selectQry.Sort( sortProperty ).ToList(); } } else { gBlockTypes.DataSource = selectQry.OrderBy( b => b.Name ).ToList(); } gBlockTypes.DataBind(); }
/// <summary> /// Scans for unregistered blocks. /// </summary> private void ScanForUnregisteredBlocks() { BlockTypeService blockTypeService = new BlockTypeService(); foreach ( Rock.Model.BlockType blockType in blockTypeService.GetUnregisteredBlocks( Request.MapPath( "~" ) ) ) { try { Control control = LoadControl( blockType.Path ); if ( control is Rock.Web.UI.RockBlock ) { blockType.Name = Path.GetFileNameWithoutExtension( blockType.Path ).SplitCase(); blockType.Description = Rock.Reflection.GetDescription( control.GetType() ) ?? string.Empty; blockTypeService.Add( blockType, CurrentPersonId ); blockTypeService.Save( blockType, CurrentPersonId ); } } catch { // } } }
/// <summary> /// Binds the grid. /// </summary> private void BindGrid() { BlockTypeService blockTypeService = new BlockTypeService(); SortProperty sortProperty = gBlockTypes.SortProperty; if ( sortProperty != null ) { gBlockTypes.DataSource = blockTypeService.Queryable().Sort( sortProperty ).ToList(); } else { gBlockTypes.DataSource = blockTypeService.Queryable().OrderBy( b => b.Name ).ToList(); } gBlockTypes.DataBind(); }
/// <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>(); // 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 rockContext = new RockContext(); var blockTypeService = new BlockTypeService( rockContext ); var registered = blockTypeService.Queryable().ToList(); // for each BlockType foreach ( string path in list.Keys) { if ( refreshAll || !registered.Any( b => b.Path.Equals( path, StringComparison.OrdinalIgnoreCase ) ) ) { // Attempt to load the control try { System.Web.UI.Control control = page.LoadControl( path ); if ( control is Rock.Web.UI.RockBlock ) { var blockType = registered.FirstOrDefault( b => b.Path.Equals( path, StringComparison.OrdinalIgnoreCase ) ); if ( blockType == null ) { // Create new BlockType record and save it blockType = new BlockType(); blockType.Path = path; blockTypeService.Add( blockType ); } Type controlType = control.GetType(); // Update Name, Category, and Description based on block's attribute definitions blockType.Name = Rock.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; } } catch ( Exception ex ) { ExceptionLogService.LogException( new Exception( string.Format("Problem processing block with path '{0}'.", path ), ex ), null ); } } } rockContext.SaveChanges(); }
/// <summary> /// Shows the edit. /// </summary> /// <param name="location">The location.</param> /// <param name="blockId">The block id.</param> protected void ShowEdit( BlockLocation location, int blockId ) { using ( var rockContext = new RockContext() ) { BlockService blockService = new BlockService( rockContext ); Rock.Model.Block block = blockService.Get( blockId ); hfBlockLocation.Value = location.ConvertToString(); if ( block != null ) { lAction.Text = "Edit "; hfBlockId.Value = block.Id.ToString(); ddlBlockType.SelectedValue = block.BlockType.Id.ToString(); tbBlockName.Text = block.Name; } else { lAction.Text = "Add "; hfBlockId.Value = "0"; // Select HTML Content block by default var blockType = new Rock.Model.BlockTypeService( rockContext ) .GetByGuid( new Guid( Rock.SystemGuid.BlockType.HTML_CONTENT ) ); if ( blockType != null ) { ddlBlockType.SelectedValue = blockType.Id.ToString(); } else { ddlBlockType.SelectedIndex = -1; } tbBlockName.Text = string.Empty; } } lAction.Text += hfBlockLocation.Value; pnlLists.Visible = false; pnlDetails.Visible = true; }
/// <summary> /// Handles the Delete event of the gBlockTypes control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="RowEventArgs" /> instance containing the event data.</param> protected void gBlockTypes_Delete( object sender, RowEventArgs e ) { RockTransactionScope.WrapTransaction( () => { BlockTypeService blockTypeService = new BlockTypeService(); BlockType blockType = blockTypeService.Get( (int)e.RowKeyValue ); if ( blockType != null ) { string errorMessage; if ( !blockTypeService.CanDelete( blockType, out errorMessage ) ) { mdGridWarning.Show( errorMessage, ModalAlertType.Information ); return; } blockTypeService.Delete( blockType, CurrentPersonId ); blockTypeService.Save( blockType, CurrentPersonId ); Rock.Web.Cache.BlockTypeCache.Flush( blockType.Id ); } } ); BindGrid(); }
/// <summary> /// Imports the page. /// </summary> /// <param name="uploadedPackage">Byte array of the uploaded package</param> /// <param name="fileName">File name of uploaded package</param> /// <param name="personId">Id of the Person performing the import</param> /// <param name="pageId">The Id of the Page to save new data underneath</param> /// <param name="siteId">The Id of the Site tha the Page is being imported into</param> public bool ImportPage( byte[] uploadedPackage, string fileName, int personId, int pageId, int siteId ) { // Write .nupkg file to the PackageStaging folder... var path = Path.Combine( HttpContext.Current.Server.MapPath( "~/App_Data/PackageStaging" ), fileName ); using ( var file = new FileStream( path, FileMode.Create ) ) { file.Write( uploadedPackage, 0, uploadedPackage.Length ); } var package = new ZipPackage( path ); var packageFiles = package.GetFiles().ToList(); var exportFile = packageFiles.FirstOrDefault( f => f.Path.Contains( "export.json" ) ); Page page = null; // If export.json is present, deserialize data // * Are there any new BlockTypes to register? If so, save them first. // * Scrub out any `Id` and `Guid` fields that came over from export // * Save page data via PageService if ( exportFile != null ) { string json; using ( var stream = exportFile.GetStream() ) { json = stream.ReadToEnd(); } page = Page.FromJson( json ); } // Validate package... // + Does it have any executable .dll files? Should those go to the bin folder, or into a plugins directory to be loaded via MEF? // - Does it have code or asset files that need to go on the file system? (Done) // - Does it have an export.json file? Should that be a requirement? (Done) // + Does it have any corresponding SQL, migrations, seed methods to run, etc. if ( page != null ) { // Find new block types and save them prior to scrubbing data... var newBlockTypes = FindNewBlockTypes( page, new BlockTypeService().Queryable() ).ToList(); RockTransactionScope.WrapTransaction( () => { try { var blockTypeService = new BlockTypeService(); foreach ( var blockType in newBlockTypes ) { blockTypeService.Add( blockType, personId ); blockTypeService.Save( blockType, personId ); } ValidateImportData( page, newBlockTypes ); SavePages( page, newBlockTypes, personId, pageId, siteId ); ExpandFiles( packageFiles ); } catch ( Exception e ) { ErrorMessages.Add( e.Message ); } }); // Clean up PackageStaging folder on successful import. var file = new FileInfo( path ); file.Delete(); return ErrorMessages.Count <= 0; } ErrorMessages.Add( "The export package uploaded does not appear to have any data associated with it." ); return false; }
private void LoadBlockTypes() { using ( new Rock.Data.UnitOfWorkScope() ) { Rock.Model.BlockTypeService blockTypeService = new Rock.Model.BlockTypeService(); // Add any unregistered blocks foreach ( Rock.Model.BlockType blockType in blockTypeService.GetUnregisteredBlocks( Request.MapPath( "~" ) ) ) { try { Control control = LoadControl( blockType.Path ); if ( control is Rock.Web.UI.RockBlock ) { blockType.Name = Path.GetFileNameWithoutExtension( blockType.Path ); // Split the name on intercapped changes (ie, "HelloWorld" becomes "Hello World") blockType.Name = System.Text.RegularExpressions.Regex.Replace( blockType.Name, "([a-z](?=[A-Z])|[A-Z](?=[A-Z][a-z]))", "$1 " ); blockType.Description = blockType.Path; blockTypeService.Add( blockType, CurrentPersonId ); blockTypeService.Save( blockType, CurrentPersonId ); } } catch { } } ddlBlockType.DataSource = blockTypeService.Queryable().OrderBy( b => b.Name).ToList(); ddlBlockType.DataTextField = "Name"; ddlBlockType.DataValueField = "Id"; ddlBlockType.DataBind(); } }
/// <summary> /// Expands the files. /// </summary> /// <param name="packageFiles">The package files.</param> private void ExpandFiles( IEnumerable<IPackageFile> packageFiles ) { // Remove export.json file from the list of files to be unzipped var filesToUnzip = packageFiles.Where( f => !f.Path.Contains( "export.json" ) ).ToList(); var blockTypeService = new BlockTypeService(); var installedBlockTypes = blockTypeService.Queryable(); var webRoot = HttpContext.Current.Server.MapPath( "~" ); // Compare the packages files with currently installed block types, removing anything that already exists foreach ( var blockType in installedBlockTypes ) { var blockFileName = blockType.Path.Substring( blockType.Path.LastIndexOf( "/", StringComparison.InvariantCultureIgnoreCase ) ); blockFileName = blockFileName.Replace( '/', Path.DirectorySeparatorChar ); filesToUnzip.RemoveAll( f => f.Path.Contains( blockFileName ) ); } foreach ( var packageFile in filesToUnzip ) { var path = Path.Combine( webRoot, packageFile.EffectivePath ); var file = new FileInfo( path ); // Err on the side of not being destructive for now. Consider refactoring to give user a choice // on whether or not to overwrite these files. if ( file.Exists ) { WarningMessages.Add( string.Format( "Skipping '{0}', found duplicate file at '{1}'.", file.Name, path ) ); continue; } // Write each file out to disk using ( var fileStream = new FileStream( path, FileMode.Create ) ) { var stream = packageFile.GetStream(); var bytes = stream.ReadAllBytes(); fileStream.Write( bytes, 0, bytes.Length ); stream.Close(); } } }