/// <summary> /// Loads all of the configured blocks for the current page into the control tree /// </summary> /// <param name="e"></param> protected override void OnInit( EventArgs e ) { // Add the ScriptManager to each page _scriptManager = ScriptManager.GetCurrent( this.Page ); if ( _scriptManager == null ) { _scriptManager = new AjaxControlToolkit.ToolkitScriptManager { ID = "sManager" }; Page.Trace.Warn( "Adding script manager" ); Page.Form.Controls.AddAt( 0, _scriptManager ); } // enable history on the ScriptManager _scriptManager.EnableHistory = true; // TODO: Delete this line, only used for testing _scriptManager.AsyncPostBackTimeout = 180; // wire up navigation event _scriptManager.Navigate += new EventHandler<HistoryEventArgs>( scriptManager_Navigate ); // add ckeditor (doesn't like to be added during an async postback) _scriptManager.Scripts.Add( new ScriptReference( ResolveRockUrl( "~/Scripts/ckeditor/ckeditor.js", true ) ) ); // Add library and UI bundles during init, that way theme developers will only // need to worry about registering any custom scripts or script bundles they need _scriptManager.Scripts.Add( new ScriptReference( "~/Bundles/WebFormsJs" ) ); _scriptManager.Scripts.Add( new ScriptReference( "~/Scripts/Bundles/RockLibs" ) ); _scriptManager.Scripts.Add( new ScriptReference( "~/Scripts/Bundles/RockUi" ) ); _scriptManager.Scripts.Add( new ScriptReference( "~/Scripts/Bundles/RockValidation" ) ); // add Google Maps API (doesn't like to be added during an async postback ) var googleAPIKey = GlobalAttributesCache.Read().GetValue( "GoogleAPIKey" ); string keyParameter = string.IsNullOrWhiteSpace(googleAPIKey) ? "" : string.Format("key={0}&", googleAPIKey); _scriptManager.Scripts.Add( new ScriptReference( string.Format( "https://maps.googleapis.com/maps/api/js?{0}sensor=false&libraries=drawing", keyParameter ) ) ); // Recurse the page controls to find the rock page title and zone controls Page.Trace.Warn( "Recursing layout to find zones" ); Zones = new Dictionary<string, KeyValuePair<string, Zone>>(); FindRockControls( this.Controls ); // Add a Rock version meta tag Page.Trace.Warn( "Adding Rock metatag" ); string version = typeof( Rock.Web.UI.RockPage ).Assembly.GetName().Version.ToString(); HtmlMeta rockVersion = new HtmlMeta(); rockVersion.Attributes.Add( "name", "generator" ); rockVersion.Attributes.Add( "content", string.Format( "Rock v{0}", version ) ); AddMetaTag( this.Page, rockVersion ); // If the logout parameter was entered, delete the user's forms authentication cookie and redirect them // back to the same page. Page.Trace.Warn( "Checking for logout request" ); if ( PageParameter( "logout" ) != string.Empty ) { if ( CurrentUser != null ) { var transaction = new Rock.Transactions.UserLastActivityTransaction(); transaction.UserId = CurrentUser.Id; transaction.LastActivityDate = RockDateTime.Now; transaction.IsOnLine = false; Rock.Transactions.RockQueue.TransactionQueue.Enqueue( transaction ); } FormsAuthentication.SignOut(); // After logging out check to see if an anonymous user is allowed to view the current page. If so // redirect back to the current page, otherwise redirect to the site's default page if ( _pageCache != null ) { if ( _pageCache.IsAuthorized( Authorization.VIEW, null ) ) { // Remove the 'logout' queryparam before redirecting var pageReference = new PageReference( PageReference.PageId, PageReference.RouteId, PageReference.Parameters ); foreach ( string key in PageReference.QueryString ) { if ( !key.Equals( "logout", StringComparison.OrdinalIgnoreCase ) ) { pageReference.Parameters.Add( key, PageReference.QueryString[key] ); } } Response.Redirect( pageReference.BuildUrl(), false ); Context.ApplicationInstance.CompleteRequest(); } else { _pageCache.Layout.Site.RedirectToDefaultPage(); } return; } else { CurrentPerson = null; CurrentUser = null; } } var rockContext = new RockContext(); // If the impersonated query key was included then set the current person Page.Trace.Warn( "Checking for person impersanation" ); string impersonatedPersonKey = PageParameter( "rckipid" ); if ( !String.IsNullOrEmpty( impersonatedPersonKey ) ) { Rock.Model.PersonService personService = new Model.PersonService( rockContext ); Rock.Model.Person impersonatedPerson = personService.GetByEncryptedKey( impersonatedPersonKey ); if ( impersonatedPerson != null ) { Rock.Security.Authorization.SetAuthCookie( "rckipid=" + impersonatedPerson.EncryptedKey, false, true ); CurrentUser = impersonatedPerson.GetImpersonatedUser(); } } // Get current user/person info Page.Trace.Warn( "Getting CurrentUser" ); Rock.Model.UserLogin user = CurrentUser; // If there is a logged in user, see if it has an associated Person Record. If so, set the UserName to // the person's full name (which is then cached in the Session state for future page requests) if ( user != null ) { Page.Trace.Warn( "Setting CurrentPerson" ); UserName = user.UserName; int? personId = user.PersonId; if ( personId.HasValue ) { string personNameKey = "PersonName_" + personId.Value.ToString(); if ( Session[personNameKey] != null ) { UserName = Session[personNameKey].ToString(); } else { Rock.Model.PersonService personService = new Model.PersonService( rockContext ); Rock.Model.Person person = personService.Get( personId.Value ); if ( person != null ) { UserName = person.FullName; CurrentPerson = person; } Session[personNameKey] = UserName; } } } // If a PageInstance exists if ( _pageCache != null ) { BrowserTitle = _pageCache.BrowserTitle; PageTitle = _pageCache.PageTitle; PageIcon = _pageCache.IconCssClass; // If there's a master page, update it's reference to Current Page if ( this.Master is RockMasterPage ) { ( (RockMasterPage)this.Master ).SetPage( _pageCache ); } // check if page should have been loaded via ssl Page.Trace.Warn( "Checking for SSL request" ); if ( !Request.IsSecureConnection && _pageCache.RequiresEncryption ) { string redirectUrl = Request.Url.ToString().Replace( "http:", "https:" ); Response.Redirect( redirectUrl, false ); Context.ApplicationInstance.CompleteRequest(); return; } // Verify that the current user is allowed to view the page. Page.Trace.Warn( "Checking if user is authorized" ); if ( !_pageCache.IsAuthorized( Authorization.VIEW, CurrentPerson ) ) { if ( user == null ) { // If not authorized, and the user hasn't logged in yet, redirect to the login page Page.Trace.Warn( "Redirecting to login page" ); var site = _pageCache.Layout.Site; if ( site.LoginPageId.HasValue ) { site.RedirectToLoginPage( true ); } else { FormsAuthentication.RedirectToLoginPage(); } } else { // If not authorized, and the user has logged in, redirect to error page Page.Trace.Warn( "Redirecting to error page" ); Response.Redirect( "~/error.aspx?type=security", false ); Context.ApplicationInstance.CompleteRequest(); } } else { // Set current models (context) Page.Trace.Warn( "Checking for Context" ); ModelContext = new Dictionary<string, Data.KeyEntity>(); try { // first search cookies, but pageContext can replace it GetCookieContext( GetContextCookieName( false ) ); // Site GetCookieContext( GetContextCookieName( true ) ); // Page (will replace any site values) foreach ( var pageContext in _pageCache.PageContexts ) { int? contextId = PageParameter( pageContext.Value ).AsIntegerOrNull(); if ( contextId.HasValue ) { ModelContext.AddOrReplace( pageContext.Key, new Data.KeyEntity( contextId.Value ) ); } } char[] delim = new char[1] { ',' }; foreach ( string param in PageParameter( "context", true ).Split( delim, StringSplitOptions.RemoveEmptyEntries ) ) { string contextItem = Rock.Security.Encryption.DecryptString( param ); string[] parts = contextItem.Split( '|' ); if ( parts.Length == 2 ) { ModelContext.AddOrReplace( parts[0], new Data.KeyEntity( parts[1] ) ); } } } catch { // intentionally ignore exception } // set viewstate on/off this.EnableViewState = _pageCache.EnableViewState; // Cache object used for block output caching Page.Trace.Warn( "Getting memory cache" ); ObjectCache cache = MemoryCache.Default; Page.Trace.Warn( "Checking if user can administer" ); bool canAdministratePage = _pageCache.IsAuthorized( Authorization.ADMINISTRATE, CurrentPerson ); // Create a javascript object to store information about the current page for client side scripts to use Page.Trace.Warn( "Creating JS objects" ); string script = string.Format( @" Rock.settings.initialize({{ siteId: {0}, layoutId: {1}, pageId: {2}, layout: '{3}', baseUrl: '{4}' }});", _pageCache.Layout.SiteId, _pageCache.LayoutId, _pageCache.Id, _pageCache.Layout.FileName, ResolveUrl( "~" ) ); ScriptManager.RegisterStartupScript( this.Page, this.GetType(), "rock-js-object", script, true ); AddTriggerPanel(); // Add config elements if ( _pageCache.IncludeAdminFooter ) { Page.Trace.Warn( "Adding popup controls (footer elements)" ); AddPopupControls(); Page.Trace.Warn( "Adding zone elements" ); AddZoneElements( canAdministratePage ); } // Initialize the list of breadcrumbs for the current page (and blocks on the page) Page.Trace.Warn( "Setting breadcrumbs" ); PageReference.BreadCrumbs = new List<BreadCrumb>(); // If the page is configured to display in the breadcrumbs... string bcName = _pageCache.BreadCrumbText; if ( bcName != string.Empty ) { PageReference.BreadCrumbs.Add( new BreadCrumb( bcName, PageReference.BuildUrl() ) ); } // Add the Google Analytics Code script if a code was specified for the site if ( !string.IsNullOrWhiteSpace( _pageCache.Layout.Site.GoogleAnalyticsCode ) ) { AddGoogleAnalytics( _pageCache.Layout.Site.GoogleAnalyticsCode ); } // Flag indicating if user has rights to administer one or more of the blocks on page bool canAdministrateBlock = false; // Load the blocks and insert them into page zones Page.Trace.Warn( "Loading Blocks" ); foreach ( Rock.Web.Cache.BlockCache block in _pageCache.Blocks ) { Page.Trace.Warn( string.Format( "\tLoading '{0}' block", block.Name ) ); // Get current user's permissions for the block instance Page.Trace.Warn( "\tChecking permission" ); bool canAdministrate = block.IsAuthorized( Authorization.ADMINISTRATE, CurrentPerson ); bool canEdit = block.IsAuthorized( Authorization.EDIT, CurrentPerson ); bool canView = block.IsAuthorized( Authorization.VIEW, CurrentPerson ); if ( canAdministrate || canEdit ) { canAdministrateBlock = true; } // Make sure user has access to view block instance if ( canAdministrate || canEdit || canView ) { // Create block wrapper control (implements INamingContainer so child control IDs are unique for // each block instance Page.Trace.Warn( "\tAdding block wrapper html" ); HtmlGenericContainer blockWrapper = new HtmlGenericContainer( "div" ); blockWrapper.ID = string.Format( "bid_{0}", block.Id ); blockWrapper.Attributes.Add( "data-zone-location", block.BlockLocation.ToString() ); blockWrapper.ClientIDMode = ClientIDMode.Static; FindZone( block.Zone ).Controls.Add( blockWrapper ); string blockTypeCss = block.BlockType != null ? block.BlockType.Name : ""; var parts = blockTypeCss.Split( new char[] { '>' } ); if ( parts.Length > 1 ) { blockTypeCss = parts[parts.Length - 1].Trim(); } blockTypeCss = blockTypeCss.Replace( ' ', '-' ).ToLower(); blockWrapper.Attributes.Add( "class", "block-instance " + blockTypeCss + ( string.IsNullOrWhiteSpace( block.CssClass ) ? "" : " " + block.CssClass.Trim() ) + ( canAdministrate || canEdit ? " can-configure " : "" ) ); // Check to see if block is configured to use a "Cache Duration' string blockCacheKey = string.Format( "Rock:BlockOutput:{0}", block.Id ); if ( block.OutputCacheDuration > 0 && cache.Contains( blockCacheKey ) ) { // If the current block exists in our custom output cache, add the cached output instead of adding the control blockWrapper.Controls.Add( new LiteralControl( cache[blockCacheKey] as string ) ); } else { // Load the control and add to the control tree Page.Trace.Warn( "\tLoading control" ); Control control; try { control = TemplateControl.LoadControl( block.BlockType.Path ); control.ClientIDMode = ClientIDMode.AutoID; } catch ( Exception ex ) { NotificationBox nbBlockLoad = new NotificationBox(); nbBlockLoad.ID = string.Format( "nbBlockLoad_{0}", block.Id ); nbBlockLoad.CssClass = "system-error"; nbBlockLoad.NotificationBoxType = NotificationBoxType.Danger; nbBlockLoad.Text = string.Format( "Error Loading Block: {0}", block.Name ); nbBlockLoad.Details = string.Format( "{0}<pre>{1}</pre>", ex.Message, ex.StackTrace ); nbBlockLoad.Dismissable = true; control = nbBlockLoad; if ( this.IsPostBack ) { // throw an error on PostBack so that the ErrorPage gets shown (vs nothing happening) throw ex; } } RockBlock blockControl = null; // Check to see if the control was a PartialCachingControl or not Page.Trace.Warn( "\tChecking block for partial caching" ); if ( control is RockBlock ) blockControl = control as RockBlock; else { if ( control is PartialCachingControl && ( (PartialCachingControl)control ).CachedControl != null ) { blockControl = (RockBlock)( (PartialCachingControl)control ).CachedControl; } } // If the current control is a block, set it's properties if ( blockControl != null ) { Page.Trace.Warn( "\tSetting block properties" ); blockControl.SetBlock( block ); // Add any breadcrumbs to current page reference that the block creates Page.Trace.Warn( "\tAdding any breadcrumbs from block" ); if ( block.BlockLocation == BlockLocation.Page ) { blockControl.GetBreadCrumbs( PageReference ).ForEach( c => PageReference.BreadCrumbs.Add( c ) ); } // If the blocktype's security actions have not yet been loaded, load them now if ( !block.BlockType.CheckedSecurityActions ) { Page.Trace.Warn( "\tAdding additional security actions for blcok" ); block.BlockType.SecurityActions = new Dictionary<string, string>(); foreach ( var action in blockControl.GetSecurityActionAttributes() ) { if ( block.BlockType.SecurityActions.ContainsKey( action.Key ) ) { block.BlockType.SecurityActions[action.Key] = action.Value; } else { block.BlockType.SecurityActions.Add( action.Key, action.Value ); } } block.BlockType.CheckedSecurityActions = true; } // If the block's AttributeProperty values have not yet been verified verify them. // (This provides a mechanism for block developers to define the needed block // attributes in code and have them automatically added to the database) Page.Trace.Warn( "\tChecking if block attributes need refresh" ); if ( !block.BlockType.IsInstancePropertiesVerified ) { Page.Trace.Warn( "\tCreating block attributes" ); blockControl.CreateAttributes( rockContext ); block.BlockType.IsInstancePropertiesVerified = true; } // Add the block configuration scripts and icons if user is authorized if ( _pageCache.IncludeAdminFooter ) { Page.Trace.Warn( "\tAdding block configuration tools" ); AddBlockConfig( blockWrapper, blockControl, block, canAdministrate, canEdit ); } } Page.Trace.Warn( "\tAdding block to control tree" ); HtmlGenericContainer blockContent = new HtmlGenericContainer( "div" ); blockContent.Attributes.Add( "class", "block-content" ); blockWrapper.Controls.Add( blockContent ); // Add the block blockContent.Controls.Add( control ); } } } // Make the last crumb for this page the active one Page.Trace.Warn( "Setting active breadcrumb" ); if ( PageReference.BreadCrumbs.Any() ) { PageReference.BreadCrumbs.Last().Active = true; } Page.Trace.Warn( "Getting parent page references" ); var pageReferences = PageReference.GetParentPageReferences( this, _pageCache, PageReference ); pageReferences.Add( PageReference ); PageReference.SavePageReferences( pageReferences ); // Update breadcrumbs Page.Trace.Warn( "Updating breadcrumbs" ); BreadCrumbs = new List<BreadCrumb>(); foreach ( var pageReference in pageReferences ) { pageReference.BreadCrumbs.ForEach( c => BreadCrumbs.Add( c ) ); } // Add the page admin footer if the user is authorized to edit the page if ( _pageCache.IncludeAdminFooter && ( canAdministratePage || canAdministrateBlock ) ) { // Add the page admin script AddScriptLink( Page, "~/Scripts/Bundles/RockAdmin", false ); Page.Trace.Warn( "Adding admin footer to page" ); HtmlGenericControl adminFooter = new HtmlGenericControl( "div" ); adminFooter.ID = "cms-admin-footer"; adminFooter.ClientIDMode = System.Web.UI.ClientIDMode.Static; this.Form.Controls.Add( adminFooter ); phLoadTime = new PlaceHolder(); adminFooter.Controls.Add( phLoadTime ); HtmlGenericControl buttonBar = new HtmlGenericControl( "div" ); adminFooter.Controls.Add( buttonBar ); buttonBar.Attributes.Add( "class", "button-bar" ); // RockBlock Config HtmlGenericControl aBlockConfig = new HtmlGenericControl( "a" ); buttonBar.Controls.Add( aBlockConfig ); aBlockConfig.Attributes.Add( "class", "btn block-config" ); aBlockConfig.Attributes.Add( "href", "javascript: Rock.admin.pageAdmin.showBlockConfig();" ); aBlockConfig.Attributes.Add( "Title", "Block Configuration" ); HtmlGenericControl iBlockConfig = new HtmlGenericControl( "i" ); aBlockConfig.Controls.Add( iBlockConfig ); iBlockConfig.Attributes.Add( "class", "fa fa-th-large" ); if ( canAdministratePage ) { // RockPage Properties HtmlGenericControl aAttributes = new HtmlGenericControl( "a" ); buttonBar.Controls.Add( aAttributes ); aAttributes.ID = "aPageProperties"; aAttributes.ClientIDMode = System.Web.UI.ClientIDMode.Static; aAttributes.Attributes.Add( "class", "btn properties" ); aAttributes.Attributes.Add( "height", "500px" ); aAttributes.Attributes.Add( "href", "javascript: Rock.controls.modal.show($(this), '" + ResolveUrl( string.Format( "~/PageProperties/{0}?t=Page Properties", _pageCache.Id ) ) + "')" ); aAttributes.Attributes.Add( "Title", "Page Properties" ); HtmlGenericControl iAttributes = new HtmlGenericControl( "i" ); aAttributes.Controls.Add( iAttributes ); iAttributes.Attributes.Add( "class", "fa fa-cog" ); // Child Pages HtmlGenericControl aChildPages = new HtmlGenericControl( "a" ); buttonBar.Controls.Add( aChildPages ); aChildPages.ID = "aChildPages"; aChildPages.ClientIDMode = System.Web.UI.ClientIDMode.Static; aChildPages.Attributes.Add( "class", "btn page-child-pages" ); aChildPages.Attributes.Add( "height", "500px" ); aChildPages.Attributes.Add( "href", "javascript: Rock.controls.modal.show($(this), '" + ResolveUrl( string.Format( "~/pages/{0}?t=Child Pages&pb=&sb=Done", _pageCache.Id ) ) + "')" ); aChildPages.Attributes.Add( "Title", "Child Pages" ); HtmlGenericControl iChildPages = new HtmlGenericControl( "i" ); aChildPages.Controls.Add( iChildPages ); iChildPages.Attributes.Add( "class", "fa fa-sitemap" ); // RockPage Zones HtmlGenericControl aPageZones = new HtmlGenericControl( "a" ); buttonBar.Controls.Add( aPageZones ); aPageZones.Attributes.Add( "class", "btn page-zones" ); aPageZones.Attributes.Add( "href", "javascript: Rock.admin.pageAdmin.showPageZones();" ); aPageZones.Attributes.Add( "Title", "Page Zones" ); HtmlGenericControl iPageZones = new HtmlGenericControl( "i" ); aPageZones.Controls.Add( iPageZones ); iPageZones.Attributes.Add( "class", "fa fa-columns" ); // RockPage Security HtmlGenericControl aPageSecurity = new HtmlGenericControl( "a" ); buttonBar.Controls.Add( aPageSecurity ); aPageSecurity.ID = "aPageSecurity"; aPageSecurity.ClientIDMode = System.Web.UI.ClientIDMode.Static; aPageSecurity.Attributes.Add( "class", "btn page-security" ); aPageSecurity.Attributes.Add( "height", "500px" ); aPageSecurity.Attributes.Add( "href", "javascript: Rock.controls.modal.show($(this), '" + ResolveUrl( string.Format( "~/Secure/{0}/{1}?t=Page Security&pb=&sb=Done", EntityTypeCache.Read( typeof( Rock.Model.Page ) ).Id, _pageCache.Id ) ) + "')" ); aPageSecurity.Attributes.Add( "Title", "Page Security" ); HtmlGenericControl iPageSecurity = new HtmlGenericControl( "i" ); aPageSecurity.Controls.Add( iPageSecurity ); iPageSecurity.Attributes.Add( "class", "fa fa-lock" ); // System Info HtmlGenericControl aSystemInfo = new HtmlGenericControl( "a" ); buttonBar.Controls.Add( aSystemInfo ); aSystemInfo.ID = "aSystemInfo"; aSystemInfo.ClientIDMode = System.Web.UI.ClientIDMode.Static; aSystemInfo.Attributes.Add( "class", "btn system-info" ); aSystemInfo.Attributes.Add( "height", "500px" ); aSystemInfo.Attributes.Add( "href", "javascript: Rock.controls.modal.show($(this), '" + ResolveUrl( "~/SystemInfo?t=System Information&pb=&sb=Done" ) + "')" ); aSystemInfo.Attributes.Add( "Title", "Rock Information" ); HtmlGenericControl iSystemInfo = new HtmlGenericControl( "i" ); aSystemInfo.Controls.Add( iSystemInfo ); iSystemInfo.Attributes.Add( "class", "fa fa-info-circle" ); } } // Check to see if page output should be cached. The RockRouteHandler // saves the PageCacheData information for the current page to memorycache // so it should always exist if ( _pageCache.OutputCacheDuration > 0 ) { Response.Cache.SetCacheability( System.Web.HttpCacheability.Public ); Response.Cache.SetExpires( RockDateTime.Now.AddSeconds( _pageCache.OutputCacheDuration ) ); Response.Cache.SetValidUntilExpires( true ); } } string pageTitle = BrowserTitle; string siteTitle = _pageCache.Layout.Site.Name; string seperator = pageTitle.Trim() != string.Empty && siteTitle.Trim() != string.Empty ? " | " : ""; base.Title = pageTitle + seperator + siteTitle; if ( !string.IsNullOrWhiteSpace( _pageCache.Description ) ) { HtmlMeta metaTag = new HtmlMeta(); metaTag.Attributes.Add( "name", "description" ); metaTag.Attributes.Add( "content", _pageCache.Description.Trim() ); AddMetaTag( this.Page, metaTag ); } if ( !string.IsNullOrWhiteSpace( _pageCache.KeyWords ) ) { HtmlMeta metaTag = new HtmlMeta(); metaTag.Attributes.Add( "name", "keywords" ); metaTag.Attributes.Add( "content", _pageCache.KeyWords.Trim() ); AddMetaTag( this.Page, metaTag ); } if ( !string.IsNullOrWhiteSpace( _pageCache.HeaderContent ) ) { Page.Header.Controls.Add( new LiteralControl( _pageCache.HeaderContent ) ); } } }
/// <summary> /// Called by the ASP.NET page framework to notify server controls that use composition-based implementation to create any child controls they contain in preparation for posting back or rendering. /// </summary> protected override void CreateChildControls() { _hfBinaryFileId = new HiddenField(); _hfBinaryFileId.ID = this.ID + "_hfBinaryFileId"; Controls.Add( _hfBinaryFileId ); _hfCropBinaryFileId = new HiddenField(); _hfCropBinaryFileId.ID = this.ID + "_hfCropBinaryFileId"; Controls.Add( _hfCropBinaryFileId ); _hfBinaryFileTypeGuid = new HiddenField(); _hfBinaryFileTypeGuid.ID = this.ID + "_hfBinaryFileTypeGuid"; Controls.Add( _hfBinaryFileTypeGuid ); _aRemove = new HtmlAnchor(); _aRemove.ID = "rmv"; _aRemove.InnerHtml = "<i class='fa fa-times'></i>"; Controls.Add( _aRemove ); _lbShowModal = new LinkButton(); _lbShowModal.ID = this.ID + "_lbShowModal"; _lbShowModal.CssClass = this.ButtonCssClass; _lbShowModal.Text = this.ButtonText; _lbShowModal.Click += _lbShowModal_Click; Controls.Add( _lbShowModal ); // If we are not showing the delete button then // only the UploadImage button should be active. if ( !ShowDeleteButton ) { _aRemove.Visible = false; _lbShowModal.Visible = false; } _lbUploadImage = new LinkButton(); _lbUploadImage.ID = this.ID + "_lbUploadImage"; _lbUploadImage.CssClass = this.ButtonCssClass; _lbUploadImage.Text = this.ButtonText; Controls.Add( _lbUploadImage ); _fileUpload = new FileUpload(); _fileUpload.ID = this.ID + "_fu"; Controls.Add( _fileUpload ); _mdImageDialog = new ModalDialog(); _mdImageDialog.ID = this.ID + "_mdImageDialog"; _mdImageDialog.Title = "Image"; _mdImageDialog.SaveButtonText = "Crop"; _mdImageDialog.SaveClick += _mdImageDialog_SaveClick; _pnlCropContainer = new Panel(); _pnlCropContainer.CssClass = "crop-container image-editor-crop-container clearfix"; _nbImageWarning = new NotificationBox(); _nbImageWarning.ID = this.ID + "_nbImageWarning"; _nbImageWarning.NotificationBoxType = NotificationBoxType.Warning; _nbImageWarning.Text = "SVG image cropping is not supported."; _imgCropSource = new Image(); _imgCropSource.ID = this.ID + "_imgCropSource"; _imgCropSource.CssClass = "image-editor-crop-source"; _pnlCropContainer.Controls.Add( _imgCropSource ); _mdImageDialog.Content.Controls.Add( _nbImageWarning ); _mdImageDialog.Content.Controls.Add( _pnlCropContainer ); _hfCropCoords = new HiddenField(); _hfCropCoords.ID = this.ID + "_hfCropCoords"; _pnlCropContainer.Controls.Add( _hfCropCoords ); Controls.Add( _mdImageDialog ); }
/// <summary> /// Loads all of the configured blocks for the current page into the control tree /// </summary> /// <param name="e"></param> protected override void OnInit( EventArgs e ) { var slDebugTimings = new StringBuilder(); var stopwatchInitEvents = Stopwatch.StartNew(); bool showDebugTimings = this.PageParameter( "ShowDebugTimings" ).AsBoolean(); bool canAdministratePage = false; if ( showDebugTimings ) { TimeSpan tsDuration = RockDateTime.Now.Subtract( (DateTime)Context.Items["Request_Start_Time"] ); slDebugTimings.AppendFormat( "OnInit [{0}ms] @ {1} \n", stopwatchInitEvents.Elapsed.TotalMilliseconds, tsDuration.TotalMilliseconds ); stopwatchInitEvents.Restart(); } // Add the ScriptManager to each page _scriptManager = ScriptManager.GetCurrent( this.Page ); if ( _scriptManager == null ) { _scriptManager = new ScriptManager { ID = "sManager" }; Page.Trace.Warn( "Adding script manager" ); Page.Form.Controls.AddAt( 0, _scriptManager ); } // enable history on the ScriptManager _scriptManager.EnableHistory = true; // TODO: Delete this line, only used for testing _scriptManager.AsyncPostBackTimeout = 180; // wire up navigation event _scriptManager.Navigate += new EventHandler<HistoryEventArgs>( scriptManager_Navigate ); // Add library and UI bundles during init, that way theme developers will only // need to worry about registering any custom scripts or script bundles they need _scriptManager.Scripts.Add( new ScriptReference( "~/Bundles/WebFormsJs" ) ); _scriptManager.Scripts.Add( new ScriptReference( "~/Scripts/Bundles/RockLibs" ) ); _scriptManager.Scripts.Add( new ScriptReference( "~/Scripts/Bundles/RockUi" ) ); _scriptManager.Scripts.Add( new ScriptReference( "~/Scripts/Bundles/RockValidation" ) ); // Recurse the page controls to find the rock page title and zone controls Page.Trace.Warn( "Recursing layout to find zones" ); Zones = new Dictionary<string, KeyValuePair<string, Zone>>(); FindRockControls( this.Controls ); // Add a Rock version meta tag Page.Trace.Warn( "Adding Rock metatag" ); string version = typeof( Rock.Web.UI.RockPage ).Assembly.GetName().Version.ToString(); HtmlMeta rockVersion = new HtmlMeta(); rockVersion.Attributes.Add( "name", "generator" ); rockVersion.Attributes.Add( "content", string.Format( "Rock v{0}", version ) ); AddMetaTag( this.Page, rockVersion ); if ( showDebugTimings ) { slDebugTimings.AppendFormat( "CheckingForLogout [{0}ms]\n", stopwatchInitEvents.Elapsed.TotalMilliseconds ); stopwatchInitEvents.Restart(); } // If the logout parameter was entered, delete the user's forms authentication cookie and redirect them // back to the same page. Page.Trace.Warn( "Checking for logout request" ); if ( PageParameter( "logout" ) != string.Empty ) { if ( CurrentUser != null ) { var transaction = new Rock.Transactions.UserLastActivityTransaction(); transaction.UserId = CurrentUser.Id; transaction.LastActivityDate = RockDateTime.Now; transaction.IsOnLine = false; Rock.Transactions.RockQueue.TransactionQueue.Enqueue( transaction ); } FormsAuthentication.SignOut(); // After logging out check to see if an anonymous user is allowed to view the current page. If so // redirect back to the current page, otherwise redirect to the site's default page if ( _pageCache != null ) { if ( _pageCache.IsAuthorized( Authorization.VIEW, null ) ) { // Remove the 'logout' queryparam before redirecting var pageReference = new PageReference( PageReference.PageId, PageReference.RouteId, PageReference.Parameters ); foreach ( string key in PageReference.QueryString ) { if ( !key.Equals( "logout", StringComparison.OrdinalIgnoreCase ) ) { pageReference.Parameters.Add( key, PageReference.QueryString[key] ); } } Response.Redirect( pageReference.BuildUrl(), false ); Context.ApplicationInstance.CompleteRequest(); } else { _pageCache.Layout.Site.RedirectToDefaultPage(); } return; } else { CurrentPerson = null; CurrentUser = null; } } var rockContext = new RockContext(); if ( showDebugTimings ) { slDebugTimings.AppendFormat( "CreateRockContext [{0}ms]\n", stopwatchInitEvents.Elapsed.TotalMilliseconds ); stopwatchInitEvents.Restart(); } // If the impersonated query key was included then set the current person Page.Trace.Warn( "Checking for person impersanation" ); string impersonatedPersonKey = PageParameter( "rckipid" ); if ( !String.IsNullOrEmpty( impersonatedPersonKey ) ) { Rock.Model.PersonService personService = new Model.PersonService( rockContext ); Rock.Model.Person impersonatedPerson = personService.GetByEncryptedKey( impersonatedPersonKey ); if ( impersonatedPerson == null ) { impersonatedPerson = personService.GetByUrlEncodedKey( impersonatedPersonKey ); } if ( impersonatedPerson != null ) { Rock.Security.Authorization.SetAuthCookie( "rckipid=" + impersonatedPerson.EncryptedKey, false, true ); CurrentUser = impersonatedPerson.GetImpersonatedUser(); } } // Get current user/person info Page.Trace.Warn( "Getting CurrentUser" ); Rock.Model.UserLogin user = CurrentUser; if ( showDebugTimings ) { slDebugTimings.AppendFormat( "GetCurrentUser [{0}ms]\n", stopwatchInitEvents.Elapsed.TotalMilliseconds ); stopwatchInitEvents.Restart(); } // If there is a logged in user, see if it has an associated Person Record. If so, set the UserName to // the person's full name (which is then cached in the Session state for future page requests) if ( user != null ) { Page.Trace.Warn( "Setting CurrentPerson" ); UserName = user.UserName; int? personId = user.PersonId; if ( personId.HasValue ) { string personNameKey = "PersonName_" + personId.Value.ToString(); if ( Session[personNameKey] != null ) { UserName = Session[personNameKey].ToString(); } else { Rock.Model.PersonService personService = new Model.PersonService( rockContext ); Rock.Model.Person person = personService.Get( personId.Value ); if ( person != null ) { UserName = person.FullName; CurrentPerson = person; } Session[personNameKey] = UserName; } } if ( showDebugTimings ) { slDebugTimings.AppendFormat( "GetCurrentPerson [{0}ms]\n", stopwatchInitEvents.Elapsed.TotalMilliseconds ); stopwatchInitEvents.Restart(); } // check that they aren't required to change their password if ( user.IsPasswordChangeRequired == true && Site.ChangePasswordPageReference != null ) { // don't redirect if this is the change password page if ( Site.ChangePasswordPageReference.PageId != this.PageId ) { Site.RedirectToChangePasswordPage( true, true ); } } } // If a PageInstance exists if ( _pageCache != null ) { BrowserTitle = _pageCache.BrowserTitle; PageTitle = _pageCache.PageTitle; PageIcon = _pageCache.IconCssClass; BodyCssClass = _pageCache.BodyCssClass; // If there's a master page, update its reference to Current Page if ( this.Master is RockMasterPage ) { ( (RockMasterPage)this.Master ).SetPage( _pageCache ); } // Add CSS class to body if ( !string.IsNullOrWhiteSpace( this.BodyCssClass ) ) { // attempt to find the body tag var body = (HtmlGenericControl)this.Master.FindControl( "body" ); if ( body != null ) { body.Attributes.Add( "class", this.BodyCssClass ); } } // check if page should have been loaded via ssl Page.Trace.Warn( "Checking for SSL request" ); if ( !Request.IsSecureConnection && (_pageCache.RequiresEncryption || Site.RequiresEncryption) ) { string redirectUrl = Request.Url.ToString().Replace( "http:", "https:" ); Response.Redirect( redirectUrl, false ); Context.ApplicationInstance.CompleteRequest(); return; } // Verify that the current user is allowed to view the page. Page.Trace.Warn( "Checking if user is authorized" ); var isCurrentPersonAuthorized = _pageCache.IsAuthorized( Authorization.VIEW, CurrentPerson ); if ( showDebugTimings ) { slDebugTimings.AppendFormat( "isCurrentPersonAuthorized [{0}ms]\n", stopwatchInitEvents.Elapsed.TotalMilliseconds ); stopwatchInitEvents.Restart(); } if ( !isCurrentPersonAuthorized ) { if ( user == null ) { // If not authorized, and the user hasn't logged in yet, redirect to the login page Page.Trace.Warn( "Redirecting to login page" ); var site = _pageCache.Layout.Site; if ( site.LoginPageId.HasValue ) { site.RedirectToLoginPage( true ); } else { FormsAuthentication.RedirectToLoginPage(); } } else { // If not authorized, and the user has logged in, redirect to error page Page.Trace.Warn( "Redirecting to error page" ); Response.Redirect( "~/Error.aspx?type=security", false ); Context.ApplicationInstance.CompleteRequest(); } } else { // Set current models (context) Page.Trace.Warn( "Checking for Context" ); ModelContext = new Dictionary<string, Data.KeyEntity>(); try { char[] delim = new char[1] { ',' }; // Check to see if a context from query string should be saved to a cookie first foreach ( string param in PageParameter( "SetContext", true ).Split( delim, StringSplitOptions.RemoveEmptyEntries ) ) { string[] parts = param.Split( '|' ); if ( parts.Length == 2 ) { var contextModelEntityType = EntityTypeCache.Read( parts[0], false, rockContext ); int? contextId = parts[1].AsIntegerOrNull(); if ( contextModelEntityType != null && contextId.HasValue ) { var contextModelType = contextModelEntityType.GetEntityType(); var contextDbContext = Reflection.GetDbContextForEntityType( contextModelType ); if ( contextDbContext != null ) { var contextService = Reflection.GetServiceForEntityType( contextModelType, contextDbContext ); if ( contextService != null ) { MethodInfo getMethod = contextService.GetType().GetMethod( "Get", new Type[] { typeof( int ) } ); if ( getMethod != null ) { var getResult = getMethod.Invoke( contextService, new object[] { contextId.Value } ); var contextEntity = getResult as IEntity; if ( contextEntity != null ) { SetContextCookie( contextEntity, false, false ); } } } } } } } if ( showDebugTimings ) { slDebugTimings.AppendFormat( "Set Page Context(s) [{0}ms]\n", stopwatchInitEvents.Elapsed.TotalMilliseconds ); stopwatchInitEvents.Restart(); } // first search the cookies for any saved context, but pageContext can replace it GetCookieContext( GetContextCookieName( false ) ); // Site GetCookieContext( GetContextCookieName( true ) ); // Page (will replace any site values) // check for page context foreach ( var pageContext in _pageCache.PageContexts ) { int? contextId = PageParameter( pageContext.Value ).AsIntegerOrNull(); if ( contextId.HasValue ) { ModelContext.AddOrReplace( pageContext.Key, new Data.KeyEntity( contextId.Value ) ); } } // check for any encrypted contextkeys specified in query string foreach ( string param in PageParameter( "context", true ).Split( delim, StringSplitOptions.RemoveEmptyEntries ) ) { string contextItem = Rock.Security.Encryption.DecryptString( param ); string[] parts = contextItem.Split( '|' ); if ( parts.Length == 2 ) { ModelContext.AddOrReplace( parts[0], new Data.KeyEntity( parts[1] ) ); } } if ( showDebugTimings ) { slDebugTimings.AppendFormat( "Check Page Context(s) [{0}ms]\n", stopwatchInitEvents.Elapsed.TotalMilliseconds ); stopwatchInitEvents.Restart(); } } catch { // intentionally ignore exception } // set viewstate on/off this.EnableViewState = _pageCache.EnableViewState; Page.Trace.Warn( "Checking if user can administer" ); canAdministratePage = _pageCache.IsAuthorized( Authorization.ADMINISTRATE, CurrentPerson ); if ( showDebugTimings ) { slDebugTimings.AppendFormat( "canAdministratePage [{0}ms]\n", stopwatchInitEvents.Elapsed.TotalMilliseconds ); stopwatchInitEvents.Restart(); } // Create a javascript object to store information about the current page for client side scripts to use Page.Trace.Warn( "Creating JS objects" ); if ( !ClientScript.IsStartupScriptRegistered( "rock-js-object" ) ) { string script = string.Format( @" Rock.settings.initialize({{ siteId: {0}, layoutId: {1}, pageId: {2}, layout: '{3}', baseUrl: '{4}' }});", _pageCache.Layout.SiteId, _pageCache.LayoutId, _pageCache.Id, _pageCache.Layout.FileName, ResolveUrl( "~" ) ); ClientScript.RegisterStartupScript( this.Page.GetType(), "rock-js-object", script, true ); } AddTriggerPanel(); // Add config elements if ( _pageCache.IncludeAdminFooter ) { Page.Trace.Warn( "Adding popup controls (footer elements)" ); AddPopupControls(); Page.Trace.Warn( "Adding zone elements" ); AddZoneElements( canAdministratePage ); } // Initialize the list of breadcrumbs for the current page (and blocks on the page) Page.Trace.Warn( "Setting breadcrumbs" ); PageReference.BreadCrumbs = new List<BreadCrumb>(); // If the page is configured to display in the breadcrumbs... string bcName = _pageCache.BreadCrumbText; if ( bcName != string.Empty ) { PageReference.BreadCrumbs.Add( new BreadCrumb( bcName, PageReference.BuildUrl() ) ); } // Add the Google Analytics Code script if a code was specified for the site if ( !string.IsNullOrWhiteSpace( _pageCache.Layout.Site.GoogleAnalyticsCode ) ) { AddGoogleAnalytics( _pageCache.Layout.Site.GoogleAnalyticsCode ); } // Flag indicating if user has rights to administer one or more of the blocks on page bool canAdministrateBlockOnPage = false; if ( showDebugTimings ) { slDebugTimings.AppendFormat( "start loading blocks [{0}ms]\n", stopwatchInitEvents.Elapsed.TotalMilliseconds ); stopwatchInitEvents.Restart(); } // Load the blocks and insert them into page zones Page.Trace.Warn( "Loading Blocks" ); var pageBlocks = _pageCache.Blocks; foreach ( Rock.Web.Cache.BlockCache block in pageBlocks ) { var stopwatchBlockInit= Stopwatch.StartNew(); Page.Trace.Warn( string.Format( "\tLoading '{0}' block", block.Name ) ); // Get current user's permissions for the block instance Page.Trace.Warn( "\tChecking permission" ); bool canAdministrate = block.IsAuthorized( Authorization.ADMINISTRATE, CurrentPerson ); bool canEdit = block.IsAuthorized( Authorization.EDIT, CurrentPerson ); bool canView = block.IsAuthorized( Authorization.VIEW, CurrentPerson ); // Make sure user has access to view block instance if ( canAdministrate || canEdit || canView ) { // Load the control and add to the control tree Page.Trace.Warn( "\tLoading control" ); Control control = null; // Check to see if block is configured to use a "Cache Duration' if ( block.OutputCacheDuration > 0 ) { // Cache object used for block output caching Page.Trace.Warn( "Getting memory cache" ); RockMemoryCache cache = RockMemoryCache.Default; string blockCacheKey = string.Format( "Rock:BlockOutput:{0}", block.Id ); if ( cache.Contains( blockCacheKey ) ) { // If the current block exists in our custom output cache, add the cached output instead of adding the control control = new LiteralControl( cache[blockCacheKey] as string ); } } if ( control == null ) { try { control = TemplateControl.LoadControl( block.BlockType.Path ); control.ClientIDMode = ClientIDMode.AutoID; } catch ( Exception ex ) { NotificationBox nbBlockLoad = new NotificationBox(); nbBlockLoad.ID = string.Format( "nbBlockLoad_{0}", block.Id ); nbBlockLoad.CssClass = "system-error"; nbBlockLoad.NotificationBoxType = NotificationBoxType.Danger; nbBlockLoad.Text = string.Format( "Error Loading Block: {0}", block.Name ); nbBlockLoad.Details = string.Format( "{0}<pre>{1}</pre>", HttpUtility.HtmlEncode( ex.Message ), HttpUtility.HtmlEncode( ex.StackTrace ) ); nbBlockLoad.Dismissable = true; control = nbBlockLoad; if ( this.IsPostBack ) { // throw an error on PostBack so that the ErrorPage gets shown (vs nothing happening) throw; } } } if ( control != null ) { if ( canAdministrate || ( canEdit && control is RockBlockCustomSettings ) ) { canAdministrateBlockOnPage = true; } // If the current control is a block, set its properties var blockControl = control as RockBlock; if ( blockControl != null ) { Page.Trace.Warn( "\tSetting block properties" ); blockControl.SetBlock( _pageCache, block, canEdit, canAdministrate ); control = new RockBlockWrapper( blockControl ); // Add any breadcrumbs to current page reference that the block creates Page.Trace.Warn( "\tAdding any breadcrumbs from block" ); if ( block.BlockLocation == BlockLocation.Page ) { blockControl.GetBreadCrumbs( PageReference ).ForEach( c => PageReference.BreadCrumbs.Add( c ) ); } // If the blocktype's security actions have not yet been loaded, load them now block.BlockType.SetSecurityActions( blockControl ); // If the block's AttributeProperty values have not yet been verified verify them. // (This provides a mechanism for block developers to define the needed block // attributes in code and have them automatically added to the database) Page.Trace.Warn( "\tChecking if block attributes need refresh" ); if ( !block.BlockType.IsInstancePropertiesVerified ) { Page.Trace.Warn( "\tCreating block attributes" ); if ( blockControl.CreateAttributes( rockContext ) ) { // If attributes were updated, update the block attributes for all blocks in page of same type pageBlocks .Where( b => b.BlockTypeId == block.BlockTypeId ) .ToList() .ForEach( b => b.ReloadAttributeValues() ); } block.BlockType.IsInstancePropertiesVerified = true; } } } FindZone( block.Zone ).Controls.Add( control ); if ( control is RockBlockWrapper ) { ( (RockBlockWrapper)control ).EnsureBlockControls(); } if ( showDebugTimings ) { stopwatchBlockInit.Stop(); slDebugTimings.AppendFormat( "create/init block {0} <span class='label label-{2}'>[{1}ms]</span>\n", block.Name, stopwatchBlockInit.Elapsed.TotalMilliseconds, stopwatchBlockInit.Elapsed.TotalMilliseconds > 500 ? "danger" : "info"); } } } // Make the last crumb for this page the active one Page.Trace.Warn( "Setting active breadcrumb" ); if ( PageReference.BreadCrumbs.Any() ) { PageReference.BreadCrumbs.Last().Active = true; } Page.Trace.Warn( "Getting parent page references" ); var pageReferences = PageReference.GetParentPageReferences( this, _pageCache, PageReference ); pageReferences.Add( PageReference ); PageReference.SavePageReferences( pageReferences ); // Update breadcrumbs Page.Trace.Warn( "Updating breadcrumbs" ); BreadCrumbs = new List<BreadCrumb>(); foreach ( var pageReference in pageReferences ) { pageReference.BreadCrumbs.ForEach( c => BreadCrumbs.Add( c ) ); } // Add the page admin footer if the user is authorized to edit the page if ( _pageCache.IncludeAdminFooter && ( canAdministratePage || canAdministrateBlockOnPage ) ) { // Add the page admin script AddScriptLink( Page, "~/Scripts/Bundles/RockAdmin", false ); Page.Trace.Warn( "Adding admin footer to page" ); HtmlGenericControl adminFooter = new HtmlGenericControl( "div" ); adminFooter.ID = "cms-admin-footer"; adminFooter.ClientIDMode = System.Web.UI.ClientIDMode.Static; this.Form.Controls.Add( adminFooter ); phLoadStats = new PlaceHolder(); adminFooter.Controls.Add( phLoadStats ); HtmlGenericControl buttonBar = new HtmlGenericControl( "div" ); adminFooter.Controls.Add( buttonBar ); buttonBar.Attributes.Add( "class", "button-bar" ); // RockBlock Config HtmlGenericControl aBlockConfig = new HtmlGenericControl( "a" ); buttonBar.Controls.Add( aBlockConfig ); aBlockConfig.Attributes.Add( "class", "btn block-config" ); aBlockConfig.Attributes.Add( "href", "javascript: Rock.admin.pageAdmin.showBlockConfig();" ); aBlockConfig.Attributes.Add( "Title", "Block Configuration" ); HtmlGenericControl iBlockConfig = new HtmlGenericControl( "i" ); aBlockConfig.Controls.Add( iBlockConfig ); iBlockConfig.Attributes.Add( "class", "fa fa-th-large" ); if ( canAdministratePage ) { // RockPage Properties HtmlGenericControl aAttributes = new HtmlGenericControl( "a" ); buttonBar.Controls.Add( aAttributes ); aAttributes.ID = "aPageProperties"; aAttributes.ClientIDMode = System.Web.UI.ClientIDMode.Static; aAttributes.Attributes.Add( "class", "btn properties" ); aAttributes.Attributes.Add( "height", "500px" ); aAttributes.Attributes.Add( "href", "javascript: Rock.controls.modal.show($(this), '" + ResolveUrl( string.Format( "~/PageProperties/{0}?t=Page Properties", _pageCache.Id ) ) + "')" ); aAttributes.Attributes.Add( "Title", "Page Properties" ); HtmlGenericControl iAttributes = new HtmlGenericControl( "i" ); aAttributes.Controls.Add( iAttributes ); iAttributes.Attributes.Add( "class", "fa fa-cog" ); // Child Pages HtmlGenericControl aChildPages = new HtmlGenericControl( "a" ); buttonBar.Controls.Add( aChildPages ); aChildPages.ID = "aChildPages"; aChildPages.ClientIDMode = System.Web.UI.ClientIDMode.Static; aChildPages.Attributes.Add( "class", "btn page-child-pages" ); aChildPages.Attributes.Add( "height", "500px" ); aChildPages.Attributes.Add( "href", "javascript: Rock.controls.modal.show($(this), '" + ResolveUrl( string.Format( "~/pages/{0}?t=Child Pages&pb=&sb=Done", _pageCache.Id ) ) + "')" ); aChildPages.Attributes.Add( "Title", "Child Pages" ); HtmlGenericControl iChildPages = new HtmlGenericControl( "i" ); aChildPages.Controls.Add( iChildPages ); iChildPages.Attributes.Add( "class", "fa fa-sitemap" ); // RockPage Zones HtmlGenericControl aPageZones = new HtmlGenericControl( "a" ); buttonBar.Controls.Add( aPageZones ); aPageZones.Attributes.Add( "class", "btn page-zones" ); aPageZones.Attributes.Add( "href", "javascript: Rock.admin.pageAdmin.showPageZones();" ); aPageZones.Attributes.Add( "Title", "Page Zones" ); HtmlGenericControl iPageZones = new HtmlGenericControl( "i" ); aPageZones.Controls.Add( iPageZones ); iPageZones.Attributes.Add( "class", "fa fa-columns" ); // RockPage Security HtmlGenericControl aPageSecurity = new HtmlGenericControl( "a" ); buttonBar.Controls.Add( aPageSecurity ); aPageSecurity.ID = "aPageSecurity"; aPageSecurity.ClientIDMode = System.Web.UI.ClientIDMode.Static; aPageSecurity.Attributes.Add( "class", "btn page-security" ); aPageSecurity.Attributes.Add( "height", "500px" ); aPageSecurity.Attributes.Add( "href", "javascript: Rock.controls.modal.show($(this), '" + ResolveUrl( string.Format( "~/Secure/{0}/{1}?t=Page Security&pb=&sb=Done", EntityTypeCache.Read( typeof( Rock.Model.Page ) ).Id, _pageCache.Id ) ) + "')" ); aPageSecurity.Attributes.Add( "Title", "Page Security" ); HtmlGenericControl iPageSecurity = new HtmlGenericControl( "i" ); aPageSecurity.Controls.Add( iPageSecurity ); iPageSecurity.Attributes.Add( "class", "fa fa-lock" ); // System Info HtmlGenericControl aSystemInfo = new HtmlGenericControl( "a" ); buttonBar.Controls.Add( aSystemInfo ); aSystemInfo.ID = "aSystemInfo"; aSystemInfo.ClientIDMode = System.Web.UI.ClientIDMode.Static; aSystemInfo.Attributes.Add( "class", "btn system-info" ); aSystemInfo.Attributes.Add( "height", "500px" ); aSystemInfo.Attributes.Add( "href", "javascript: Rock.controls.modal.show($(this), '" + ResolveUrl( "~/SystemInfo?t=System Information&pb=&sb=Done" ) + "')" ); aSystemInfo.Attributes.Add( "Title", "Rock Information" ); HtmlGenericControl iSystemInfo = new HtmlGenericControl( "i" ); aSystemInfo.Controls.Add( iSystemInfo ); iSystemInfo.Attributes.Add( "class", "fa fa-info-circle" ); } } // Check to see if page output should be cached. The RockRouteHandler // saves the PageCacheData information for the current page to memorycache // so it should always exist if ( _pageCache.OutputCacheDuration > 0 ) { Response.Cache.SetCacheability( System.Web.HttpCacheability.Public ); Response.Cache.SetExpires( RockDateTime.Now.AddSeconds( _pageCache.OutputCacheDuration ) ); Response.Cache.SetValidUntilExpires( true ); } // create a page view transaction if enabled if ( !Page.IsPostBack && _pageCache != null ) { if ( _pageCache.Layout.Site.EnablePageViews ) { PageViewTransaction transaction = new PageViewTransaction(); transaction.DateViewed = RockDateTime.Now; transaction.PageId = _pageCache.Id; transaction.SiteId = _pageCache.Layout.Site.Id; if ( CurrentPersonAlias != null ) { transaction.PersonAliasId = CurrentPersonAlias.Id; } transaction.IPAddress = GetClientIpAddress(); transaction.UserAgent = Request.UserAgent ?? ""; transaction.Url = Request.Url.ToString(); transaction.PageTitle = _pageCache.PageTitle; var sessionId = Session["RockSessionID"]; if ( sessionId != null ) { transaction.SessionId = sessionId.ToString(); } RockQueue.TransactionQueue.Enqueue( transaction ); } } } stopwatchInitEvents.Restart(); string pageTitle = BrowserTitle ?? string.Empty; string siteTitle = _pageCache.Layout.Site.Name; string seperator = pageTitle.Trim() != string.Empty && siteTitle.Trim() != string.Empty ? " | " : ""; base.Title = pageTitle + seperator + siteTitle; if ( !string.IsNullOrWhiteSpace( _pageCache.Description ) ) { HtmlMeta metaTag = new HtmlMeta(); metaTag.Attributes.Add( "name", "description" ); metaTag.Attributes.Add( "content", _pageCache.Description.Trim() ); AddMetaTag( this.Page, metaTag ); } if ( !string.IsNullOrWhiteSpace( _pageCache.KeyWords ) ) { HtmlMeta metaTag = new HtmlMeta(); metaTag.Attributes.Add( "name", "keywords" ); metaTag.Attributes.Add( "content", _pageCache.KeyWords.Trim() ); AddMetaTag( this.Page, metaTag ); } if (!string.IsNullOrWhiteSpace( _pageCache.Layout.Site.PageHeaderContent )) { Page.Header.Controls.Add( new LiteralControl( _pageCache.Layout.Site.PageHeaderContent ) ); } if ( !string.IsNullOrWhiteSpace( _pageCache.HeaderContent ) ) { Page.Header.Controls.Add( new LiteralControl( _pageCache.HeaderContent ) ); } if ( !_pageCache.AllowIndexing || !_pageCache.Layout.Site.AllowIndexing ) { Page.Header.Controls.Add( new LiteralControl( "<meta name=\"robots\" content=\"noindex, nofollow\"/>" ) ); } if ( showDebugTimings ) { TimeSpan tsDuration = RockDateTime.Now.Subtract( (DateTime)Context.Items["Request_Start_Time"] ); slDebugTimings.AppendFormat( "done oninit [{0}ms] @ {1} \n", stopwatchInitEvents.Elapsed.TotalMilliseconds, tsDuration.TotalMilliseconds ); stopwatchInitEvents.Restart(); } if ( showDebugTimings && canAdministratePage ) { Page.Form.Controls.Add( new Label { ID="lblShowDebugTimings", Text = string.Format( "<pre>{0}</pre>", slDebugTimings.ToString() ) } ); } } }
/// <summary> /// Called by the ASP.NET page framework to notify server controls that use composition-based implementation to create any child controls they contain in preparation for posting back or rendering. /// </summary> protected override void CreateChildControls() { Controls.Clear(); ddlFilterType = new RockDropDownList(); Controls.Add(ddlFilterType); ddlFilterType.ID = this.ID + "_ddlFilter"; var component = Rock.Reporting.DataFilterContainer.GetComponent(FilterEntityTypeName); if (component != null) { if (component is Reporting.DataFilter.PropertyFilter) { (component as Reporting.DataFilter.PropertyFilter).Entity = this.Entity; } component.Options = FilterOptions; filterControls = component.CreateChildControls(FilteredEntityType, this, this.FilterMode); } else { filterControls = new Control[0]; } SetFilterControlsValidationGroup(this.ValidationGroup); ddlFilterType.AutoPostBack = true; ddlFilterType.SelectedIndexChanged += ddlFilterType_SelectedIndexChanged; ddlFilterType.Items.Clear(); if (AuthorizedComponents != null) { foreach (var section in AuthorizedComponents) { foreach (var item in section.Value) { if (!this.ExcludedFilterTypes.Any(a => a == item.Key)) { ListItem li = new ListItem(item.Value, item.Key); if (!string.IsNullOrWhiteSpace(section.Key)) { li.Attributes.Add("optiongroup", section.Key); } var filterComponent = Rock.Reporting.DataFilterContainer.GetComponent(item.Key); if (filterComponent != null) { string description = Reflection.GetDescription(filterComponent.GetType()); if (!string.IsNullOrWhiteSpace(description)) { li.Attributes.Add("title", description); } } li.Selected = item.Key == FilterEntityTypeName; ddlFilterType.Items.Add(li); } } } } hfExpanded = new HiddenField(); Controls.Add(hfExpanded); hfExpanded.ID = this.ID + "_hfExpanded"; hfExpanded.Value = "True"; lbDelete = new LinkButton(); Controls.Add(lbDelete); lbDelete.ID = this.ID + "_lbDelete"; lbDelete.CssClass = "btn btn-xs btn-square btn-danger"; lbDelete.Click += lbDelete_Click; lbDelete.CausesValidation = false; var iDelete = new HtmlGenericControl("i"); lbDelete.Controls.Add(iDelete); iDelete.AddCssClass("fa fa-times"); cbIncludeFilter = new RockCheckBox(); cbIncludeFilter.ContainerCssClass = "filterfield-checkbox"; cbIncludeFilter.TextCssClass = "control-label"; Controls.Add(cbIncludeFilter); cbIncludeFilter.ID = this.ID + "_cbIncludeFilter"; nbComponentDescription = new NotificationBox(); nbComponentDescription.NotificationBoxType = NotificationBoxType.Info; nbComponentDescription.ID = this.ID + "_nbComponentDescription"; Controls.Add(nbComponentDescription); }
/// <summary> /// Called by the ASP.NET page framework to notify server controls that use composition-based implementation to create any child controls they contain in preparation for posting back or rendering. /// </summary> protected override void CreateChildControls() { //_hfBinaryFileId = new HiddenField(); base.CreateChildControls(); Controls.Clear(); RockControlHelper.CreateChildControls(this, Controls); Controls.Add(_hfBinaryFileId); _hfBinaryFileId.ID = this.ID + "_hfBinaryFileId"; _hfBinaryFileId.Value = "0"; _hfOriginalBinaryFileId.ID = this.ID + "_hfOriginalBinaryFileId"; Controls.Add(_hfOriginalBinaryFileId); _hfCropBinaryFileId.ID = this.ID + "_hfCropBinaryFileId"; Controls.Add(_hfCropBinaryFileId); _hfBinaryFileTypeGuid.ID = this.ID + "_hfBinaryFileTypeGuid"; Controls.Add(_hfBinaryFileTypeGuid); _aRemove = new HtmlAnchor(); _aRemove.ID = "rmv"; _aRemove.InnerHtml = "<i class='fa fa-times'></i>"; Controls.Add(_aRemove); _lbShowModal = new LinkButton(); _lbShowModal.ID = this.ID + "_lbShowModal"; _lbShowModal.CssClass = this.ButtonCssClass; _lbShowModal.Text = this.ButtonText; _lbShowModal.Click += _lbShowModal_Click; _lbShowModal.CausesValidation = false; Controls.Add(_lbShowModal); // If we are not showing the delete button then // only the UploadImage button should be active. if (!ShowDeleteButton) { _aRemove.Visible = false; _lbShowModal.Visible = false; } _lbUploadImage = new LinkButton(); _lbUploadImage.ID = this.ID + "_lbUploadImage"; _lbUploadImage.CssClass = this.ButtonCssClass; _lbUploadImage.Text = this.ButtonText; _lbUploadImage.CausesValidation = false; Controls.Add(_lbUploadImage); _lSaveStatus = new Label(); _lSaveStatus.ID = this.ID + "_lSaveStatus"; _lSaveStatus.CssClass = "fa fa-2x fa-check-circle-o text-success"; _lSaveStatus.Style.Add("vertical-align", "bottom"); _lSaveStatus.Visible = false; Controls.Add(_lSaveStatus); _fileUpload = new FileUpload(); _fileUpload.ID = this.ID + "_fu"; Controls.Add(_fileUpload); _mdImageDialog = new ModalDialog(); _mdImageDialog.ValidationGroup = "vg_mdImageDialog"; _mdImageDialog.ID = this.ID + "_mdImageDialog"; _mdImageDialog.Title = "Image"; _mdImageDialog.SaveButtonText = "Crop"; _mdImageDialog.SaveClick += _mdImageDialog_SaveClick; _pnlCropContainer = new Panel(); _pnlCropContainer.CssClass = "crop-container image-editor-crop-container clearfix"; _nbImageWarning = new NotificationBox(); _nbImageWarning.ID = this.ID + "_nbImageWarning"; _nbImageWarning.NotificationBoxType = NotificationBoxType.Warning; _nbImageWarning.Text = "SVG image cropping is not supported."; _imgCropSource = new Image(); _imgCropSource.ID = this.ID + "_imgCropSource"; _imgCropSource.CssClass = "image-editor-crop-source"; _pnlCropContainer.Controls.Add(_imgCropSource); _mdImageDialog.Content.Controls.Add(_nbImageWarning); _mdImageDialog.Content.Controls.Add(_pnlCropContainer); _hfCropCoords = new HiddenField(); _hfCropCoords.ID = this.ID + "_hfCropCoords"; _pnlCropContainer.Controls.Add(_hfCropCoords); Controls.Add(_mdImageDialog); RequiredFieldValidator.InitialValue = "0"; RequiredFieldValidator.ControlToValidate = _hfBinaryFileId.ID; RequiredFieldValidator.Display = ValidatorDisplay.Dynamic; }
/// <summary> /// Outputs server control content to a provided <see cref="T:System.Web.UI.HtmlTextWriter" /> object and stores tracing information about the control if tracing is enabled. /// </summary> /// <param name="writer">The <see cref="T:System.Web.UI.HtmlTextWriter" /> object that receives the control content.</param> public override void RenderControl( System.Web.UI.HtmlTextWriter writer ) { List<string> widgetCssList = GetDivWidthCssClasses(); writer.AddAttribute( System.Web.UI.HtmlTextWriterAttribute.Class, widgetCssList.AsDelimited( " " ) ); writer.RenderBeginTag( System.Web.UI.HtmlTextWriterTag.Div ); writer.AddAttribute( System.Web.UI.HtmlTextWriterAttribute.Class, "panel-dashboard" ); writer.RenderBeginTag( System.Web.UI.HtmlTextWriterTag.Div ); writer.AddAttribute( System.Web.UI.HtmlTextWriterAttribute.Class, "panel-body" ); writer.RenderBeginTag( System.Web.UI.HtmlTextWriterTag.Div ); if ( !string.IsNullOrWhiteSpace( WidgetErrorMessage ) ) { var errorBox = new NotificationBox { ID = "nbWidgetError", NotificationBoxType = NotificationBoxType.Danger, Text = WidgetErrorMessage, Title = "Error", Dismissable = true, Details = WidgetErrorDetails }; errorBox.RenderControl( writer ); } base.RenderControl( writer ); writer.RenderEndTag(); writer.RenderEndTag(); writer.RenderEndTag(); }
/// <summary> /// Called by the ASP.NET page framework to notify server controls that use composition-based implementation to create any child controls they contain in preparation for posting back or rendering. /// </summary> protected override void CreateChildControls() { base.CreateChildControls(); // HiddenField to store which AttributeMatrix record we are editing _hfAttributeMatrixGuid = new HiddenField { ID = "_hfAttributeMatrixGuid" }; this.Controls.Add(_hfAttributeMatrixGuid); _nbWarning = new NotificationBox { ID = "_nbWarning", NotificationBoxType = NotificationBoxType.Warning, Dismissable = true }; this.Controls.Add(_nbWarning); // Grid with view of MatrixItems _gMatrixItems = new Grid { ID = "_gMatrixItems", DisplayType = GridDisplayType.Light }; this.Controls.Add(_gMatrixItems); _gMatrixItems.DataKeyNames = new string[] { "Id" }; _gMatrixItems.Actions.AddClick += gMatrixItems_AddClick; _gMatrixItems.Actions.ShowAdd = true; _gMatrixItems.IsDeleteEnabled = true; _gMatrixItems.GridReorder += gMatrixItems_GridReorder; _gMatrixItems.GridRebind += _gMatrixItems_GridRebind; _hfRowCount = new HiddenFieldWithValidationProperty { ID = "_hfRowCount" }; this.Controls.Add(_hfRowCount); _requiredRowCountRangeValidator = new HiddenFieldRangeValidator(); _requiredRowCountRangeValidator.ID = _hfRowCount.ID + "_rfv"; _requiredRowCountRangeValidator.ControlToValidate = _hfRowCount.ID; _requiredRowCountRangeValidator.Display = ValidatorDisplay.Dynamic; _requiredRowCountRangeValidator.Type = ValidationDataType.Integer; _requiredRowCountRangeValidator.CssClass = "validation-error help-inline"; _requiredRowCountRangeValidator.Enabled = false; this.Controls.Add(_requiredRowCountRangeValidator); _gMatrixItems.Columns.Add(new ReorderField()); AttributeMatrixItem tempAttributeMatrixItem = null; if (this.AttributeMatrixTemplateId.HasValue) { tempAttributeMatrixItem = new AttributeMatrixItem(); tempAttributeMatrixItem.AttributeMatrix = new AttributeMatrix { AttributeMatrixTemplateId = this.AttributeMatrixTemplateId.Value }; tempAttributeMatrixItem.LoadAttributes(); foreach (var attribute in tempAttributeMatrixItem.Attributes.Select(a => a.Value)) { _gMatrixItems.Columns.Add(new AttributeField { DataField = attribute.Key, HeaderText = attribute.Name }); } AttributeMatrixTemplateService attributeMatrixTemplateService = new AttributeMatrixTemplateService(new RockContext()); var attributeMatrixTemplateRanges = attributeMatrixTemplateService.GetSelect(this.AttributeMatrixTemplateId.Value, s => new { s.MinimumRows, s.MaximumRows }); _requiredRowCountRangeValidator.MinimumValue = (attributeMatrixTemplateRanges.MinimumRows ?? 0).ToString(); _requiredRowCountRangeValidator.Enabled = this.Required && attributeMatrixTemplateRanges.MinimumRows.HasValue; if (attributeMatrixTemplateRanges.MinimumRows == 1) { _requiredRowCountRangeValidator.ErrorMessage = $"At least {attributeMatrixTemplateRanges.MinimumRows} row is required"; } else { _requiredRowCountRangeValidator.ErrorMessage = $"At least {attributeMatrixTemplateRanges.MinimumRows} rows are required"; } } DeleteField deleteField = new DeleteField(); deleteField.Click += gMatrixItems_DeleteClick; _gMatrixItems.Columns.Add(deleteField); _gMatrixItems.RowSelected += gMatrixItems_RowSelected; // Edit Item _pnlEditMatrixItem = new Panel { ID = "_pnlEditMatrixItem", Visible = false, CssClass = "well js-validation-group" }; _hfMatrixItemId = new HiddenField { ID = "_hfMatrixItemId" }; _pnlEditMatrixItem.Controls.Add(_hfMatrixItemId); _phMatrixItemAttributes = new DynamicPlaceholder { ID = "_phMatrixItemAttributes" }; _pnlEditMatrixItem.Controls.Add(_phMatrixItemAttributes); string validationGroup = GetValidationGroupForAttributeControls(); if (tempAttributeMatrixItem != null) { Rock.Attribute.Helper.AddEditControls(tempAttributeMatrixItem, _phMatrixItemAttributes, false, validationGroup); } _pnlActions = new Panel { ID = "_pnlActions", CssClass = "actions" }; _pnlEditMatrixItem.Controls.Add(_pnlActions); _btnSaveMatrixItem = new LinkButton { ID = "_btnSaveMatrixItem", CssClass = "btn btn-primary btn-sm", Text = "Save", ValidationGroup = validationGroup, CausesValidation = true }; _btnSaveMatrixItem.Click += btnSaveMatrixItem_Click; _pnlActions.Controls.Add(_btnSaveMatrixItem); _btnCancelMatrixItem = new LinkButton { ID = "_btnCancelMatrixItem", CssClass = "btn btn-link", Text = "Cancel", CausesValidation = false }; _btnCancelMatrixItem.Click += btnCancelMatrixItem_Click; _pnlActions.Controls.Add(_btnCancelMatrixItem); this.Controls.Add(_pnlEditMatrixItem); }
/// <summary> /// Called by the ASP.NET page framework to notify server controls that use composition-based implementation to create any child controls they contain in preparation for posting back or rendering. /// </summary> protected override void CreateChildControls() { base.CreateChildControls(); // HiddenField to store which AttributeMatrix record we are editing _hfAttributeMatrixGuid = new HiddenField { ID = "_hfAttributeMatrixGuid" }; this.Controls.Add(_hfAttributeMatrixGuid); _nbWarning = new NotificationBox { ID = "_nbWarning", NotificationBoxType = NotificationBoxType.Warning, Dismissable = true }; this.Controls.Add(_nbWarning); // Grid with view of MatrixItems _gMatrixItems = new Grid { ID = "_gMatrixItems", DisplayType = GridDisplayType.Light }; this.Controls.Add(_gMatrixItems); _gMatrixItems.DataKeyNames = new string[] { "Id" }; _gMatrixItems.Actions.AddClick += gMatrixItems_AddClick; _gMatrixItems.Actions.ShowAdd = true; _gMatrixItems.IsDeleteEnabled = true; _gMatrixItems.GridReorder += gMatrixItems_GridReorder; _gMatrixItems.GridRebind += _gMatrixItems_GridRebind; _gMatrixItems.Columns.Add(new ReorderField()); AttributeMatrixItem tempAttributeMatrixItem = null; if (this.AttributeMatrixTemplateId.HasValue) { tempAttributeMatrixItem = new AttributeMatrixItem(); tempAttributeMatrixItem.AttributeMatrix = new AttributeMatrix { AttributeMatrixTemplateId = this.AttributeMatrixTemplateId.Value }; tempAttributeMatrixItem.LoadAttributes(); foreach (var attribute in tempAttributeMatrixItem.Attributes.Select(a => a.Value)) { _gMatrixItems.Columns.Add(new AttributeField { DataField = attribute.Key, HeaderText = attribute.Name }); } } DeleteField deleteField = new DeleteField(); deleteField.Click += gMatrixItems_DeleteClick; _gMatrixItems.Columns.Add(deleteField); _gMatrixItems.RowSelected += gMatrixItems_RowSelected; // Edit Item _pnlEditMatrixItem = new Panel { ID = "_pnlEditMatrixItem", Visible = false, CssClass = "well js-validation-group" }; _hfMatrixItemId = new HiddenField { ID = "_hfMatrixItemId" }; _pnlEditMatrixItem.Controls.Add(_hfMatrixItemId); _phMatrixItemAttributes = new DynamicPlaceholder { ID = "_phMatrixItemAttributes" }; _pnlEditMatrixItem.Controls.Add(_phMatrixItemAttributes); string validationGroup = GetValidationGroupForAttributeControls(); if (tempAttributeMatrixItem != null) { Rock.Attribute.Helper.AddEditControls(tempAttributeMatrixItem, _phMatrixItemAttributes, false, validationGroup); } _pnlActions = new Panel { ID = "_pnlActions", CssClass = "actions" }; _pnlEditMatrixItem.Controls.Add(_pnlActions); _btnSaveMatrixItem = new LinkButton { ID = "_btnSaveMatrixItem", CssClass = "btn btn-primary btn-sm", Text = "Save", ValidationGroup = validationGroup, CausesValidation = true }; _btnSaveMatrixItem.Click += btnSaveMatrixItem_Click; _pnlActions.Controls.Add(_btnSaveMatrixItem); _btnCancelMatrixItem = new LinkButton { ID = "_btnCancelMatrixItem", CssClass = "btn btn-link", Text = "Cancel", CausesValidation = false }; _btnCancelMatrixItem.Click += btnCancelMatrixItem_Click; _pnlActions.Controls.Add(_btnCancelMatrixItem); this.Controls.Add(_pnlEditMatrixItem); }