/// <summary> /// Copies the page. /// </summary> /// <param name="pageId">The page identifier.</param> /// <param name="currentPersonAliasId">The current person alias identifier.</param> public Guid?CopyPage(int pageId, int?currentPersonAliasId = null) { var rockContext = new RockContext(); var pageService = new PageService(rockContext); Guid?newPageGuid = null; var page = pageService.Get(pageId); if (page != null) { Dictionary <Guid, Guid> pageGuidDictionary = new Dictionary <Guid, Guid>(); Dictionary <Guid, Guid> blockGuidDictionary = new Dictionary <Guid, Guid>(); var newPage = GeneratePageCopy(page, pageGuidDictionary, blockGuidDictionary, currentPersonAliasId); pageService.Add(newPage); rockContext.SaveChanges(); if (newPage.ParentPageId.HasValue) { PageCache.Flush(newPage.ParentPageId.Value); } newPageGuid = newPage.Guid; GenerateBlockAttributeValues(pageGuidDictionary, blockGuidDictionary, rockContext, currentPersonAliasId); GeneratePageBlockAuths(pageGuidDictionary, blockGuidDictionary, rockContext, currentPersonAliasId); CloneHtmlContent(blockGuidDictionary, rockContext, currentPersonAliasId); } return(newPageGuid); }
/// <summary> /// Handles the Delete event of the gPages 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 gPages_Delete(object sender, RowEventArgs e) { bool canDelete = false; var rockContext = new RockContext(); PageService pageService = new PageService(rockContext); Rock.Model.Page page = pageService.Get(new Guid(e.RowKeyValue.ToString())); if (page != null) { string errorMessage; canDelete = pageService.CanDelete(page, out errorMessage, includeSecondLvl: true); if (!canDelete) { mdGridWarning.Show(errorMessage, ModalAlertType.Alert); return; } pageService.Delete(page); rockContext.SaveChanges(); PageCache.Flush(page.Id); } BindPagesGrid(); }
/// <summary> /// Handles the Delete event of the gPages 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 gPages_Delete(object sender, RowEventArgs e) { var rockContext = new RockContext(); PageService pageService = new PageService(rockContext); var pageViewService = new PageViewService(rockContext); var siteService = new SiteService(rockContext); Rock.Model.Page page = pageService.Get(new Guid(e.RowKeyValue.ToString())); if (page != null) { string errorMessage; if (!pageService.CanDelete(page, out errorMessage, includeSecondLvl: true)) { mdGridWarning.Show(errorMessage, ModalAlertType.Alert); return; } foreach (var site in siteService.Queryable()) { if (site.DefaultPageId == page.Id) { site.DefaultPageId = null; site.DefaultPageRouteId = null; } if (site.LoginPageId == page.Id) { site.LoginPageId = null; site.LoginPageRouteId = null; } if (site.RegistrationPageId == page.Id) { site.RegistrationPageId = null; site.RegistrationPageRouteId = null; } } foreach (var pageView in pageViewService.GetByPageId(page.Id)) { pageView.Page = null; pageView.PageId = null; } pageService.Delete(page); rockContext.SaveChanges(); PageCache.Flush(page.Id); } BindPagesGrid(); }
/// <summary> /// Handles the OnSave event of the masterPage 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 masterPage_OnSave(object sender, EventArgs e) { Page.Validate(BlockValidationGroup); if (Page.IsValid && _pageId.HasValue) { var rockContext = new RockContext(); var pageService = new PageService(rockContext); var routeService = new PageRouteService(rockContext); var contextService = new PageContextService(rockContext); var page = pageService.Get(_pageId.Value); int parentPageId = ppParentPage.SelectedValueAsInt() ?? 0; if (page.ParentPageId != parentPageId) { if (page.ParentPageId.HasValue) { PageCache.Flush(page.ParentPageId.Value); } if (parentPageId != 0) { PageCache.Flush(parentPageId); } } page.InternalName = tbPageName.Text; page.PageTitle = tbPageTitle.Text; page.BrowserTitle = tbBrowserTitle.Text; if (parentPageId != 0) { page.ParentPageId = parentPageId; } else { page.ParentPageId = null; } page.LayoutId = ddlLayout.SelectedValueAsInt().Value; int?orphanedIconFileId = null; page.IconCssClass = tbIconCssClass.Text; page.PageDisplayTitle = cbPageTitle.Checked; page.PageDisplayBreadCrumb = cbPageBreadCrumb.Checked; page.PageDisplayIcon = cbPageIcon.Checked; page.PageDisplayDescription = cbPageDescription.Checked; page.DisplayInNavWhen = (DisplayInNavWhen)Enum.Parse(typeof(DisplayInNavWhen), ddlMenuWhen.SelectedValue); page.MenuDisplayDescription = cbMenuDescription.Checked; page.MenuDisplayIcon = cbMenuIcon.Checked; page.MenuDisplayChildPages = cbMenuChildPages.Checked; page.BreadCrumbDisplayName = cbBreadCrumbName.Checked; page.BreadCrumbDisplayIcon = cbBreadCrumbIcon.Checked; page.RequiresEncryption = cbRequiresEncryption.Checked; page.EnableViewState = cbEnableViewState.Checked; page.IncludeAdminFooter = cbIncludeAdminFooter.Checked; page.OutputCacheDuration = int.Parse(tbCacheDuration.Text); page.Description = tbDescription.Text; page.HeaderContent = ceHeaderContent.Text; // new or updated route foreach (var pageRoute in page.PageRoutes.ToList()) { var existingRoute = RouteTable.Routes.OfType <Route>().FirstOrDefault(a => a.RouteId() == pageRoute.Id); if (existingRoute != null) { RouteTable.Routes.Remove(existingRoute); } routeService.Delete(pageRoute); } page.PageRoutes.Clear(); foreach (string route in tbPageRoute.Text.SplitDelimitedValues()) { var pageRoute = new PageRoute(); pageRoute.Route = route.TrimStart(new char[] { '/' }); pageRoute.Guid = Guid.NewGuid(); page.PageRoutes.Add(pageRoute); } foreach (var pageContext in page.PageContexts.ToList()) { contextService.Delete(pageContext); } page.PageContexts.Clear(); foreach (var control in phContext.Controls) { if (control is RockTextBox) { var tbContext = control as RockTextBox; if (!string.IsNullOrWhiteSpace(tbContext.Text)) { var pageContext = new PageContext(); pageContext.Entity = tbContext.ID.Substring(8).Replace('_', '.'); pageContext.IdParameter = tbContext.Text; page.PageContexts.Add(pageContext); } } } if (page.IsValid) { rockContext.SaveChanges(); foreach (var pageRoute in new PageRouteService(rockContext).GetByPageId(page.Id)) { RouteTable.Routes.AddPageRoute(pageRoute); } if (orphanedIconFileId.HasValue) { BinaryFileService binaryFileService = new BinaryFileService(rockContext); var binaryFile = binaryFileService.Get(orphanedIconFileId.Value); if (binaryFile != null) { // marked the old images as IsTemporary so they will get cleaned up later binaryFile.IsTemporary = true; rockContext.SaveChanges(); } } Rock.Web.Cache.PageCache.Flush(page.Id); string script = "if (typeof window.parent.Rock.controls.modal.close === 'function') window.parent.Rock.controls.modal.close('PAGE_UPDATED');"; ScriptManager.RegisterStartupScript(this.Page, this.GetType(), "close-modal", script, true); } } }
/// <summary> /// Handles the Click event of the lbSave 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 lbSave_Click(object sender, EventArgs e) { if (Page.IsValid) { Rock.Model.Page page; var rockContext = new RockContext(); var pageService = new PageService(rockContext); int pageId = hfPageId.Value.AsInteger(); if (pageId == 0) { page = new Rock.Model.Page(); if (_page != null) { page.ParentPageId = _page.Id; page.LayoutId = _page.LayoutId; } else { page.ParentPageId = null; page.LayoutId = PageCache.Read(RockPage.PageId).LayoutId; } page.PageTitle = dtbPageName.Text; page.BrowserTitle = page.PageTitle; page.EnableViewState = true; page.IncludeAdminFooter = true; page.MenuDisplayChildPages = true; Rock.Model.Page lastPage = pageService.GetByParentPageId(_page.Id).OrderByDescending(b => b.Order).FirstOrDefault(); if (lastPage != null) { page.Order = lastPage.Order + 1; } else { page.Order = 0; } pageService.Add(page); } else { page = pageService.Get(pageId); } page.LayoutId = ddlLayout.SelectedValueAsInt().Value; page.InternalName = dtbPageName.Text; if (page.IsValid) { rockContext.SaveChanges(); PageCache.Flush(page.Id); if (_page != null) { Rock.Security.Authorization.CopyAuthorization(_page, page); _page.FlushChildPages(); } BindGrid(); } rGrid.Visible = true; pnlDetails.Visible = false; } }
/// <summary> /// Handles the OnSave event of the masterPage 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 masterPage_OnSave(object sender, EventArgs e) { Page.Validate(BlockValidationGroup); if (Page.IsValid && _pageId.HasValue) { var rockContext = new RockContext(); var pageService = new PageService(rockContext); var routeService = new PageRouteService(rockContext); var contextService = new PageContextService(rockContext); var page = pageService.Get(_pageId.Value); // validate/check for removed routes var editorRoutes = tbPageRoute.Text.SplitDelimitedValues().Distinct(); var databasePageRoutes = page.PageRoutes.ToList(); var deletedRouteIds = new List <int>(); var addedRoutes = new List <string>(); if (editorRoutes.Any()) { int?siteId = null; if (page != null && page.Layout != null) { siteId = page.Layout.SiteId; } // validate for any duplicate routes var duplicateRouteQry = routeService.Queryable() .Where(r => r.PageId != _pageId && editorRoutes.Contains(r.Route)); if (siteId.HasValue) { duplicateRouteQry = duplicateRouteQry .Where(r => r.Page != null && r.Page.Layout != null && r.Page.Layout.SiteId == siteId.Value); } var duplicateRoutes = duplicateRouteQry .Select(r => r.Route) .Distinct() .ToList(); if (duplicateRoutes.Any()) { // Duplicate routes nbPageRouteWarning.Title = "Duplicate Route(s)"; nbPageRouteWarning.Text = string.Format("<p>The page route <strong>{0}</strong>, already exists for another page in the same site. Please choose a different route name.</p>", duplicateRoutes.AsDelimited("</strong> and <strong>")); nbPageRouteWarning.Dismissable = true; nbPageRouteWarning.Visible = true; CurrentTab = "Advanced Settings"; rptProperties.DataSource = _tabs; rptProperties.DataBind(); ShowSelectedPane(); return; } } // validate if removed routes can be deleted foreach (var pageRoute in databasePageRoutes) { if (!editorRoutes.Contains(pageRoute.Route)) { // make sure the route can be deleted string errorMessage; if (!routeService.CanDelete(pageRoute, out errorMessage)) { nbPageRouteWarning.Text = string.Format("The page route <strong>{0}</strong>, cannot be removed. {1}", pageRoute.Route, errorMessage); nbPageRouteWarning.NotificationBoxType = NotificationBoxType.Warning; nbPageRouteWarning.Dismissable = true; nbPageRouteWarning.Visible = true; CurrentTab = "Advanced Settings"; rptProperties.DataSource = _tabs; rptProperties.DataBind(); ShowSelectedPane(); return; } } } // take care of deleted routes foreach (var pageRoute in databasePageRoutes) { if (!editorRoutes.Contains(pageRoute.Route)) { // if they removed the Route, remove it from the database page.PageRoutes.Remove(pageRoute); routeService.Delete(pageRoute); deletedRouteIds.Add(pageRoute.Id); } } // take care of added routes foreach (string route in editorRoutes) { // if they added the Route, add it to the database if (!databasePageRoutes.Any(a => a.Route == route)) { var pageRoute = new PageRoute(); pageRoute.Route = route.TrimStart(new char[] { '/' }); pageRoute.Guid = Guid.NewGuid(); page.PageRoutes.Add(pageRoute); addedRoutes.Add(route); } } int parentPageId = ppParentPage.SelectedValueAsInt() ?? 0; if (page.ParentPageId != parentPageId) { if (page.ParentPageId.HasValue) { PageCache.Flush(page.ParentPageId.Value); } if (parentPageId != 0) { PageCache.Flush(parentPageId); } } page.InternalName = tbPageName.Text; page.PageTitle = tbPageTitle.Text; page.BrowserTitle = tbBrowserTitle.Text; page.BodyCssClass = tbBodyCssClass.Text; if (parentPageId != 0) { page.ParentPageId = parentPageId; } else { page.ParentPageId = null; } page.LayoutId = ddlLayout.SelectedValueAsInt().Value; int?orphanedIconFileId = null; page.IconCssClass = tbIconCssClass.Text; page.PageDisplayTitle = cbPageTitle.Checked; page.PageDisplayBreadCrumb = cbPageBreadCrumb.Checked; page.PageDisplayIcon = cbPageIcon.Checked; page.PageDisplayDescription = cbPageDescription.Checked; page.DisplayInNavWhen = ddlMenuWhen.SelectedValue.ConvertToEnumOrNull <DisplayInNavWhen>() ?? DisplayInNavWhen.WhenAllowed; page.MenuDisplayDescription = cbMenuDescription.Checked; page.MenuDisplayIcon = cbMenuIcon.Checked; page.MenuDisplayChildPages = cbMenuChildPages.Checked; page.BreadCrumbDisplayName = cbBreadCrumbName.Checked; page.BreadCrumbDisplayIcon = cbBreadCrumbIcon.Checked; page.RequiresEncryption = cbRequiresEncryption.Checked; page.EnableViewState = cbEnableViewState.Checked; page.IncludeAdminFooter = cbIncludeAdminFooter.Checked; page.AllowIndexing = cbAllowIndexing.Checked; page.OutputCacheDuration = tbCacheDuration.Text.AsIntegerOrNull() ?? 0; page.Description = tbDescription.Text; page.HeaderContent = ceHeaderContent.Text; // update PageContexts foreach (var pageContext in page.PageContexts.ToList()) { contextService.Delete(pageContext); } page.PageContexts.Clear(); foreach (var control in phContext.Controls) { if (control is RockTextBox) { var tbContext = control as RockTextBox; if (!string.IsNullOrWhiteSpace(tbContext.Text)) { var pageContext = new PageContext(); pageContext.Entity = tbContext.ID.Substring(8).Replace('_', '.'); pageContext.IdParameter = tbContext.Text; page.PageContexts.Add(pageContext); } } } // save page and it's routes if (page.IsValid) { rockContext.SaveChanges(); // remove any routes for this page that are no longer configured foreach (var existingRoute in RouteTable.Routes.OfType <Route>().Where(a => a.PageIds().Contains(page.Id))) { if (!editorRoutes.Any(a => a == existingRoute.Url)) { var pageAndRouteIds = existingRoute.DataTokens["PageRoutes"] as List <Rock.Web.PageAndRouteId>; pageAndRouteIds = pageAndRouteIds.Where(p => p.PageId != page.Id).ToList(); if (pageAndRouteIds.Any()) { existingRoute.DataTokens["PageRoutes"] = pageAndRouteIds; } else { RouteTable.Routes.Remove(existingRoute); } } } // Add any routes that were added foreach (var pageRoute in new PageRouteService(rockContext).GetByPageId(page.Id)) { if (addedRoutes.Contains(pageRoute.Route)) { var pageAndRouteId = new Rock.Web.PageAndRouteId { PageId = pageRoute.PageId, RouteId = pageRoute.Id }; var existingRoute = RouteTable.Routes.OfType <Route>().FirstOrDefault(r => r.Url == pageRoute.Route); if (existingRoute != null) { var pageAndRouteIds = existingRoute.DataTokens["PageRoutes"] as List <Rock.Web.PageAndRouteId>; pageAndRouteIds.Add(pageAndRouteId); existingRoute.DataTokens["PageRoutes"] = pageAndRouteIds; } else { var pageAndRouteIds = new List <Rock.Web.PageAndRouteId>(); pageAndRouteIds.Add(pageAndRouteId); RouteTable.Routes.AddPageRoute(pageRoute.Route, pageAndRouteIds); } } } if (orphanedIconFileId.HasValue) { BinaryFileService binaryFileService = new BinaryFileService(rockContext); var binaryFile = binaryFileService.Get(orphanedIconFileId.Value); if (binaryFile != null) { // marked the old images as IsTemporary so they will get cleaned up later binaryFile.IsTemporary = true; rockContext.SaveChanges(); } } Rock.Web.Cache.PageCache.Flush(page.Id); string script = "if (typeof window.parent.Rock.controls.modal.close === 'function') window.parent.Rock.controls.modal.close('PAGE_UPDATED');"; ScriptManager.RegisterStartupScript(this.Page, this.GetType(), "close-modal", script, 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) { Site site; if (Page.IsValid) { var rockContext = new RockContext(); PageService pageService = new PageService(rockContext); SiteService siteService = new SiteService(rockContext); SiteDomainService siteDomainService = new SiteDomainService(rockContext); bool newSite = false; int siteId = hfSiteId.Value.AsInteger(); if (siteId == 0) { newSite = true; site = new Rock.Model.Site(); siteService.Add(site); } else { site = siteService.Get(siteId); } site.Name = tbSiteName.Text; site.Description = tbDescription.Text; site.Theme = ddlTheme.Text; site.DefaultPageId = ppDefaultPage.PageId; site.DefaultPageRouteId = ppDefaultPage.PageRouteId; site.LoginPageId = ppLoginPage.PageId; site.LoginPageRouteId = ppLoginPage.PageRouteId; site.ChangePasswordPageId = ppChangePasswordPage.PageId; site.ChangePasswordPageRouteId = ppChangePasswordPage.PageRouteId; site.CommunicationPageId = ppCommunicationPage.PageId; site.CommunicationPageRouteId = ppCommunicationPage.PageRouteId; site.RegistrationPageId = ppRegistrationPage.PageId; site.RegistrationPageRouteId = ppRegistrationPage.PageRouteId; site.PageNotFoundPageId = ppPageNotFoundPage.PageId; site.PageNotFoundPageRouteId = ppPageNotFoundPage.PageRouteId; site.ErrorPage = tbErrorPage.Text; site.GoogleAnalyticsCode = tbGoogleAnalytics.Text; site.RequiresEncryption = cbRequireEncryption.Checked; site.EnabledForShortening = cbEnableForShortening.Checked; site.EnableMobileRedirect = cbEnableMobileRedirect.Checked; site.MobilePageId = ppMobilePage.PageId; site.ExternalUrl = tbExternalURL.Text; site.AllowedFrameDomains = tbAllowedFrameDomains.Text; site.RedirectTablets = cbRedirectTablets.Checked; site.EnablePageViews = cbEnablePageViews.Checked; site.AllowIndexing = cbAllowIndexing.Checked; site.IsIndexEnabled = cbEnableIndexing.Checked; site.IndexStartingLocation = tbIndexStartingLocation.Text; site.PageHeaderContent = cePageHeaderContent.Text; int?existingIconId = null; if (site.FavIconBinaryFileId != imgSiteIcon.BinaryFileId) { existingIconId = site.FavIconBinaryFileId; site.FavIconBinaryFileId = imgSiteIcon.BinaryFileId; } var currentDomains = tbSiteDomains.Text.SplitDelimitedValues().ToList <string>(); site.SiteDomains = site.SiteDomains ?? new List <SiteDomain>(); // Remove any deleted domains foreach (var domain in site.SiteDomains.Where(w => !currentDomains.Contains(w.Domain)).ToList()) { site.SiteDomains.Remove(domain); siteDomainService.Delete(domain); } int order = 0; foreach (string domain in currentDomains) { SiteDomain sd = site.SiteDomains.Where(d => d.Domain == domain).FirstOrDefault(); if (sd == null) { sd = new SiteDomain(); sd.Domain = domain; sd.Guid = Guid.NewGuid(); site.SiteDomains.Add(sd); } sd.Order = order++; } if (!site.DefaultPageId.HasValue && !newSite) { ppDefaultPage.ShowErrorMessage("Default Page is required."); return; } if (!site.IsValid) { // Controls will render the error messages return; } rockContext.WrapTransaction(() => { rockContext.SaveChanges(); SaveAttributes(new Page().TypeId, "SiteId", site.Id.ToString(), PageAttributesState, rockContext); if (existingIconId.HasValue) { BinaryFileService binaryFileService = new BinaryFileService(rockContext); var binaryFile = binaryFileService.Get(existingIconId.Value); if (binaryFile != null) { // marked the old images as IsTemporary so they will get cleaned up later binaryFile.IsTemporary = true; rockContext.SaveChanges(); } } if (newSite) { Rock.Security.Authorization.CopyAuthorization(RockPage.Layout.Site, site, rockContext, Authorization.EDIT); Rock.Security.Authorization.CopyAuthorization(RockPage.Layout.Site, site, rockContext, Authorization.ADMINISTRATE); Rock.Security.Authorization.CopyAuthorization(RockPage.Layout.Site, site, rockContext, Authorization.APPROVE); } }); // add/update for the InteractionChannel for this site and set the RetentionPeriod var interactionChannelService = new InteractionChannelService(rockContext); int channelMediumWebsiteValueId = DefinedValueCache.Read(Rock.SystemGuid.DefinedValue.INTERACTIONCHANNELTYPE_WEBSITE.AsGuid()).Id; var interactionChannelForSite = interactionChannelService.Queryable() .Where(a => a.ChannelTypeMediumValueId == channelMediumWebsiteValueId && a.ChannelEntityId == site.Id).FirstOrDefault(); if (interactionChannelForSite == null) { interactionChannelForSite = new InteractionChannel(); interactionChannelForSite.ChannelTypeMediumValueId = channelMediumWebsiteValueId; interactionChannelForSite.ChannelEntityId = site.Id; interactionChannelService.Add(interactionChannelForSite); } interactionChannelForSite.Name = site.Name; interactionChannelForSite.RetentionDuration = nbPageViewRetentionPeriodDays.Text.AsIntegerOrNull(); interactionChannelForSite.ComponentEntityTypeId = EntityTypeCache.Read <Rock.Model.Page>().Id; rockContext.SaveChanges(); foreach (int pageId in pageService.GetBySiteId(site.Id) .Select(p => p.Id) .ToList()) { PageCache.Flush(pageId); } SiteCache.Flush(site.Id); AttributeCache.FlushEntityAttributes(); // Create the default page is this is a new site if (!site.DefaultPageId.HasValue && newSite) { var siteCache = SiteCache.Read(site.Id); // Create the layouts for the site, and find the first one LayoutService.RegisterLayouts(Request.MapPath("~"), siteCache); var layoutService = new LayoutService(rockContext); var layouts = layoutService.GetBySiteId(siteCache.Id); Layout layout = layouts.FirstOrDefault(l => l.FileName.Equals("FullWidth", StringComparison.OrdinalIgnoreCase)); if (layout == null) { layout = layouts.FirstOrDefault(); } if (layout != null) { var page = new Page(); page.LayoutId = layout.Id; page.PageTitle = siteCache.Name + " Home Page"; page.InternalName = page.PageTitle; page.BrowserTitle = page.PageTitle; page.EnableViewState = true; page.IncludeAdminFooter = true; page.MenuDisplayChildPages = true; var lastPage = pageService.GetByParentPageId(null).OrderByDescending(b => b.Order).FirstOrDefault(); page.Order = lastPage != null ? lastPage.Order + 1 : 0; pageService.Add(page); rockContext.SaveChanges(); site = siteService.Get(siteCache.Id); site.DefaultPageId = page.Id; rockContext.SaveChanges(); SiteCache.Flush(site.Id); } } var qryParams = new Dictionary <string, string>(); qryParams["siteId"] = site.Id.ToString(); NavigateToPage(RockPage.Guid, qryParams); } }
/// <summary> /// Handles the OnSave event of the masterPage 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 masterPage_OnSave(object sender, EventArgs e) { if (Page.IsValid) { using (new UnitOfWorkScope()) { var pageService = new PageService(); var routeService = new PageRouteService(); var contextService = new PageContextService(); var page = pageService.Get(_page.Id); int parentPageId = ppParentPage.SelectedValueAsInt() ?? 0; if (page.ParentPageId != parentPageId) { if (page.ParentPageId.HasValue) { PageCache.Flush(page.ParentPageId.Value); } if (parentPageId != 0) { PageCache.Flush(parentPageId); } } page.Name = tbPageName.Text; page.Title = tbPageTitle.Text; if (parentPageId != 0) { page.ParentPageId = parentPageId; } else { page.ParentPageId = null; } page.Layout = ddlLayout.Text; page.IconFileId = imgIcon.BinaryFileId; page.IconCssClass = tbIconCssClass.Text; page.PageDisplayTitle = cbPageTitle.Checked; page.PageDisplayBreadCrumb = cbPageBreadCrumb.Checked; page.PageDisplayIcon = cbPageIcon.Checked; page.PageDisplayDescription = cbPageDescription.Checked; page.DisplayInNavWhen = (DisplayInNavWhen)Enum.Parse(typeof(DisplayInNavWhen), ddlMenuWhen.SelectedValue); page.MenuDisplayDescription = cbMenuDescription.Checked; page.MenuDisplayIcon = cbMenuIcon.Checked; page.MenuDisplayChildPages = cbMenuChildPages.Checked; page.BreadCrumbDisplayName = cbBreadCrumbName.Checked; page.BreadCrumbDisplayIcon = cbBreadCrumbIcon.Checked; page.RequiresEncryption = cbRequiresEncryption.Checked; page.EnableViewState = cbEnableViewState.Checked; page.IncludeAdminFooter = cbIncludeAdminFooter.Checked; page.OutputCacheDuration = int.Parse(tbCacheDuration.Text); page.Description = tbDescription.Text; // new or updated route foreach (var pageRoute in page.PageRoutes.ToList()) { var existingRoute = RouteTable.Routes.OfType <Route>().FirstOrDefault(a => a.RouteId() == pageRoute.Id); if (existingRoute != null) { RouteTable.Routes.Remove(existingRoute); } routeService.Delete(pageRoute, CurrentPersonId); } page.PageRoutes.Clear(); foreach (string route in tbPageRoute.Text.SplitDelimitedValues()) { var pageRoute = new PageRoute(); pageRoute.Route = route; pageRoute.Guid = Guid.NewGuid(); page.PageRoutes.Add(pageRoute); } foreach (var pageContext in page.PageContexts.ToList()) { contextService.Delete(pageContext, CurrentPersonId); } page.PageContexts.Clear(); if (phContextPanel.Visible) { foreach (var control in phContext.Controls) { if (control is RockTextBox) { var tbContext = control as RockTextBox; var pageContext = new PageContext(); pageContext.Entity = tbContext.Label; pageContext.IdParameter = tbContext.Text; page.PageContexts.Add(pageContext); } } } pageService.Save(page, CurrentPersonId); foreach (var pageRoute in new PageRouteService().GetByPageId(page.Id)) { RouteTable.Routes.AddPageRoute(pageRoute); } Rock.Attribute.Helper.GetEditValues(phAttributes, _page); _page.SaveAttributeValues(CurrentPersonId); Rock.Web.Cache.PageCache.Flush(_page.Id); } string script = "if (typeof window.parent.Rock.controls.modal.close === 'function') window.parent.Rock.controls.modal.close();"; ScriptManager.RegisterStartupScript(this.Page, this.GetType(), "close-modal", script, true); } }