Пример #1
0
        /// <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);
        }
Пример #2
0
        /// <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();
        }
Пример #3
0
        /// <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();
        }
Пример #4
0
        /// <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);
                }
            }
        }
Пример #5
0
        /// <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;
            }
        }
Пример #6
0
        /// <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);
                }
            }
        }
Пример #7
0
        /// <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);
            }
        }