Beispiel #1
0
        /// <summary>
        /// Handles the SaveClick event of the modalDetails 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 mdDetails_SaveClick( object sender, EventArgs e )
        {
            int categoryId = 0;
            if ( hfIdValue.Value != string.Empty && !int.TryParse( hfIdValue.Value, out categoryId ) )
            {
                categoryId = 0;
            }

            var service = new CategoryService();
            Category category = null;

            if ( categoryId != 0 )
            {
                category = service.Get( categoryId );
            }

            if ( category == null )
            {
                category = new Category();
                category.EntityTypeId = _entityTypeId;
                var lastCategory = GetUnorderedCategories()
                    .OrderByDescending( c => c.Order ).FirstOrDefault();
                category.Order = lastCategory != null ? lastCategory.Order + 1 : 0;

                service.Add( category, CurrentPersonId );
            }

            category.Name = tbName.Text;
            category.Description = tbDescription.Text;
            category.ParentCategoryId = catpParentCategory.SelectedValueAsInt();
            category.IconCssClass = tbIconCssClass.Text;

            List<int> orphanedBinaryFileIdList = new List<int>();
           
            if ( category.IsValid )
            {
                RockTransactionScope.WrapTransaction( () =>
                {
                    service.Save( category, CurrentPersonId );

                    BinaryFileService binaryFileService = new BinaryFileService();
                    foreach ( int binaryFileId in orphanedBinaryFileIdList )
                    {
                        var binaryFile = binaryFileService.Get( binaryFileId );
                        if ( binaryFile != null )
                        {
                            // marked the old images as IsTemporary so they will get cleaned up later
                            binaryFile.IsTemporary = true;
                            binaryFileService.Save( binaryFile, CurrentPersonId );
                        }
                    }

                } );

                hfIdValue.Value = string.Empty;
                mdDetails.Hide();

                BindGrid();
            }
        }
Beispiel #2
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 )
        {
            using ( new Rock.Data.UnitOfWorkScope() )
            {
                Rock.Data.RockTransactionScope.WrapTransaction( () =>
                {
                    var personService = new PersonService();

                    var changes = new List<string>();

                    var person = personService.Get( Person.Id );

                    int? orphanedPhotoId = null;
                    if ( person.PhotoId != imgPhoto.BinaryFileId )
                    {
                        orphanedPhotoId = person.PhotoId;
                        person.PhotoId = imgPhoto.BinaryFileId;

                        if ( orphanedPhotoId.HasValue )
                        {
                            if ( person.PhotoId.HasValue )
                            {
                                changes.Add( "Modified the photo." );
                            }
                            else
                            {
                                changes.Add( "Deleted the photo." );
                            }
                        }
                        else if ( person.PhotoId.HasValue )
                        {
                            changes.Add( "Added a photo." );
                        }
                    }

                    int? newTitleId = ddlTitle.SelectedValueAsInt();
                    History.EvaluateChange( changes, "Title", DefinedValueCache.GetName( person.TitleValueId ), DefinedValueCache.GetName( newTitleId ) );
                    person.TitleValueId = newTitleId;

                    History.EvaluateChange( changes, "First Name", person.FirstName, tbFirstName.Text );
                    person.FirstName = tbFirstName.Text;

                    string nickName = string.IsNullOrWhiteSpace( tbNickName.Text ) ? tbFirstName.Text : tbNickName.Text;
                    History.EvaluateChange( changes, "Nick Name", person.NickName, nickName );
                    person.NickName = tbNickName.Text;

                    History.EvaluateChange( changes, "Middle Name", person.MiddleName, tbMiddleName.Text );
                    person.MiddleName = tbMiddleName.Text;

                    History.EvaluateChange( changes, "Last Name", person.LastName, tbLastName.Text );
                    person.LastName = tbLastName.Text;

                    int? newSuffixId = ddlSuffix.SelectedValueAsInt();
                    History.EvaluateChange( changes, "Suffix", DefinedValueCache.GetName( person.SuffixValueId ), DefinedValueCache.GetName( newSuffixId ) );
                    person.SuffixValueId = newSuffixId;

                    var birthMonth = person.BirthMonth;
                    var birthDay = person.BirthDay;
                    var birthYear = person.BirthYear;

                    var birthday = bpBirthDay.SelectedDate;
                    if ( birthday.HasValue )
                    {
                        person.BirthMonth = birthday.Value.Month;
                        person.BirthDay = birthday.Value.Day;
                        if ( birthday.Value.Year != DateTime.MinValue.Year )
                        {
                            person.BirthYear = birthday.Value.Year;
                        }
                        else
                        {
                            person.BirthYear = null;
                        }
                    }
                    else
                    {
                        person.BirthDate = null;
                    }

                    History.EvaluateChange( changes, "Birth Month", birthMonth, person.BirthMonth );
                    History.EvaluateChange( changes, "Birth Day", birthDay, person.BirthDay );
                    History.EvaluateChange( changes, "Birth Year", birthYear, person.BirthYear );

                    History.EvaluateChange( changes, "Anniversary Date", person.AnniversaryDate, dpAnniversaryDate.SelectedDate );
                    person.AnniversaryDate = dpAnniversaryDate.SelectedDate;

                    var newGender = rblGender.SelectedValue.ConvertToEnum<Gender>();
                    History.EvaluateChange( changes, "Gender", person.Gender, newGender );
                    person.Gender = newGender;

                    int? newMaritalStatusId = rblMaritalStatus.SelectedValueAsInt();
                    History.EvaluateChange( changes, "Marital Status", DefinedValueCache.GetName( person.MaritalStatusValueId ), DefinedValueCache.GetName( newMaritalStatusId ) );
                    person.MaritalStatusValueId = newMaritalStatusId;

                    int? newConnectionStatusId = rblStatus.SelectedValueAsInt();
                    History.EvaluateChange( changes, "Connection Status", DefinedValueCache.GetName( person.ConnectionStatusValueId ), DefinedValueCache.GetName( newConnectionStatusId ) );
                    person.ConnectionStatusValueId = newConnectionStatusId;

                    var phoneNumberTypeIds = new List<int>();

                    foreach ( RepeaterItem item in rContactInfo.Items )
                    {
                        HiddenField hfPhoneType = item.FindControl( "hfPhoneType" ) as HiddenField;
                        TextBox tbPhone = item.FindControl( "tbPhone" ) as TextBox;
                        CheckBox cbUnlisted = item.FindControl( "cbUnlisted" ) as CheckBox;
                        CheckBox cbSms = item.FindControl( "cbSms" ) as CheckBox;

                        if ( hfPhoneType != null &&
                            tbPhone != null &&
                            cbSms != null &&
                            cbUnlisted != null )
                        {
                            if ( !string.IsNullOrWhiteSpace( tbPhone.Text ) )
                            {
                                int phoneNumberTypeId;
                                if ( int.TryParse( hfPhoneType.Value, out phoneNumberTypeId ) )
                                {
                                    var phoneNumber = person.PhoneNumbers.FirstOrDefault( n => n.NumberTypeValueId == phoneNumberTypeId );
                                    string oldPhoneNumber = string.Empty;
                                    if ( phoneNumber == null )
                                    {
                                        phoneNumber = new PhoneNumber { NumberTypeValueId = phoneNumberTypeId };
                                        person.PhoneNumbers.Add( phoneNumber );
                                    }
                                    else
                                    {
                                        oldPhoneNumber = phoneNumber.NumberFormatted;
                                    }

                                    phoneNumber.Number = PhoneNumber.CleanNumber( tbPhone.Text );
                                    phoneNumber.IsMessagingEnabled = cbSms.Checked;
                                    phoneNumber.IsUnlisted = cbUnlisted.Checked;
                                    phoneNumberTypeIds.Add( phoneNumberTypeId );

                                    History.EvaluateChange( changes,
                                        string.Format( "{0} Phone", DefinedValueCache.GetName( phoneNumberTypeId ) ),
                                        oldPhoneNumber, phoneNumber.NumberFormatted );
                                }
                            }
                        }
                    }

                    // Remove any blank numbers
                    var phoneNumberService = new PhoneNumberService();
                    foreach ( var phoneNumber in person.PhoneNumbers
                        .Where( n => n.NumberTypeValueId.HasValue && !phoneNumberTypeIds.Contains( n.NumberTypeValueId.Value ) )
                        .ToList() )
                    {
                        History.EvaluateChange( changes,
                            string.Format( "{0} Phone", DefinedValueCache.GetName( phoneNumber.NumberTypeValueId ) ),
                            phoneNumber.NumberFormatted, string.Empty );

                        person.PhoneNumbers.Remove( phoneNumber );
                        phoneNumberService.Delete( phoneNumber, CurrentPersonId );
                    }

                    History.EvaluateChange( changes, "Email", person.Email, tbEmail.Text );
                    person.Email = tbEmail.Text.Trim();

                    int? newGivingGroupId = ddlGivingGroup.SelectedValueAsId();
                    if ( person.GivingGroupId != newGivingGroupId )
                    {
                        string oldGivingGroupName = person.GivingGroup != null ? person.GivingGroup.Name : string.Empty;
                        string newGivingGroupName = newGivingGroupId.HasValue ? ddlGivingGroup.Items.FindByValue( newGivingGroupId.Value.ToString() ).Text : string.Empty;
                        History.EvaluateChange( changes, "Giving Group", oldGivingGroupName, newGivingGroupName );
                    }

                    int? newRecordStatusId = ddlRecordStatus.SelectedValueAsInt();
                    History.EvaluateChange( changes, "Record Status", DefinedValueCache.GetName( person.RecordStatusValueId ), DefinedValueCache.GetName( newRecordStatusId ) );
                    person.RecordStatusValueId = newRecordStatusId;

                    int? newRecordStatusReasonId = ddlReason.SelectedValueAsInt();
                    History.EvaluateChange( changes, "Record Status Reason", DefinedValueCache.GetName( person.RecordStatusReasonValueId ), DefinedValueCache.GetName( newRecordStatusReasonId ) );
                    person.RecordStatusReasonValueId = newRecordStatusReasonId;

                    if ( !person.IsValid )
                    {
                        return;
                    }

                    if ( personService.Save( person, CurrentPersonId ) )
                    {
                        if ( changes.Any() )
                        {
                            new HistoryService().SaveChanges( typeof( Person ), Rock.SystemGuid.Category.HISTORY_PERSON_DEMOGRAPHIC_CHANGES.AsGuid(),
                                Person.Id, changes, CurrentPersonId );
                        }

                        if ( orphanedPhotoId.HasValue )
                        {
                            BinaryFileService binaryFileService = new BinaryFileService( personService.RockContext );
                            var binaryFile = binaryFileService.Get( orphanedPhotoId.Value );
                            if ( binaryFile != null )
                            {
                                // marked the old images as IsTemporary so they will get cleaned up later
                                binaryFile.IsTemporary = true;
                                binaryFileService.Save( binaryFile, CurrentPersonId );
                            }
                        }
                    }
                } );
            }

            Response.Redirect( string.Format( "~/Person/{0}", Person.Id ), false );
        }
Beispiel #3
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 )
        {
            Category category;

            using ( new UnitOfWorkScope() )
            {
                CategoryService categoryService = new CategoryService();

                int categoryId = hfCategoryId.ValueAsInt();

                if ( categoryId == 0 )
                {
                    category = new Category();
                    category.IsSystem = false;
                    category.EntityTypeId = entityTypeId;
                    category.EntityTypeQualifierColumn = entityTypeQualifierProperty;
                    category.EntityTypeQualifierValue = entityTypeQualifierValue;
                    category.Order = 0;
                }
                else
                {
                    category = categoryService.Get( categoryId );
                }

                category.Name = tbName.Text;
                category.ParentCategoryId = cpParentCategory.SelectedValueAsInt();
                category.IconCssClass = tbIconCssClass.Text;

                List<int> orphanedBinaryFileIdList = new List<int>();

                if ( !Page.IsValid )
                {
                    return;
                }

                if ( !category.IsValid )
                {
                    // Controls will render the error messages                    
                    return;
                }

                RockTransactionScope.WrapTransaction( () =>
                {
                    if ( category.Id.Equals( 0 ) )
                    {
                        categoryService.Add( category, CurrentPersonId );
                    }

                    categoryService.Save( category, CurrentPersonId );

                    BinaryFileService binaryFileService = new BinaryFileService();
                    foreach (int binaryFileId in orphanedBinaryFileIdList)
                    {
                        var binaryFile = binaryFileService.Get(binaryFileId);
                        if ( binaryFile != null )
                        {
                            // marked the old images as IsTemporary so they will get cleaned up later
                            binaryFile.IsTemporary = true;
                            binaryFileService.Save( binaryFile, CurrentPersonId );
                        }
                    }
                } );
            }

            var qryParams = new Dictionary<string, string>();
            qryParams["CategoryId"] = category.Id.ToString();
            NavigateToPage( RockPage.Guid, qryParams );
        }
Beispiel #4
0
        /// <summary>
        /// Processes the binary file.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="uploadedFile">The uploaded file.</param>
        private void ProcessBinaryFile( HttpContext context, HttpPostedFile uploadedFile )
        {
            // get BinaryFileType info
            Guid fileTypeGuid = context.Request.QueryString["fileTypeGuid"].AsGuid();

            RockContext rockContext = new RockContext();
            BinaryFileType binaryFileType = new BinaryFileTypeService( rockContext ).Get( fileTypeGuid );

            // always create a new BinaryFile record of IsTemporary when a file is uploaded
            BinaryFile binaryFile = new BinaryFile();
            binaryFile.IsTemporary = true;
            binaryFile.BinaryFileTypeId = binaryFileType.Id;
            binaryFile.MimeType = uploadedFile.ContentType;
            binaryFile.FileName = Path.GetFileName( uploadedFile.FileName );
            binaryFile.Data = new BinaryFileData();
            binaryFile.Data.Content = GetFileBytes( context, uploadedFile );

            var binaryFileService = new BinaryFileService( rockContext );
            binaryFileService.Add( binaryFile, null );
            binaryFileService.Save( binaryFile, null );

            var response = new
            {
                Id = binaryFile.Id,
                FileName = binaryFile.FileName
            };

            context.Response.Write( response.ToJson() );
        }
Beispiel #5
0
        /// <summary>
        /// Handles the Delete event of the gBinaryFile 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 gBinaryFile_Delete( object sender, RowEventArgs e )
        {
            RockTransactionScope.WrapTransaction( () =>
            {
                BinaryFileService binaryFileService = new BinaryFileService();
                BinaryFile binaryFile = binaryFileService.Get( (int)e.RowKeyValue );

                if ( binaryFile != null )
                {
                    string errorMessage;
                    if ( !binaryFileService.CanDelete( binaryFile, out errorMessage ) )
                    {
                        mdGridWarning.Show( errorMessage, ModalAlertType.Information );
                        return;
                    }

                    binaryFileService.Delete( binaryFile, CurrentPersonId );
                    binaryFileService.Save( binaryFile, CurrentPersonId );
                }
            } );

            BindGrid();
        }
Beispiel #6
0
        /// <summary> 
        /// Job that executes routine Rock cleanup tasks
        /// 
        /// Called by the <see cref="IScheduler" /> when a
        /// <see cref="ITrigger" /> fires that is associated with
        /// the <see cref="IJob" />.
        /// </summary>
        public virtual void  Execute(IJobExecutionContext context)
        {
            
            // get the job map
            JobDataMap dataMap = context.JobDetail.JobDataMap;

            // delete accounts that have not been confirmed in X hours
            int userExpireHours = Int32.Parse( dataMap.GetString( "HoursKeepUnconfirmedAccounts" ) );
            DateTime userAccountExpireDate = DateTime.Now.Add( new TimeSpan( userExpireHours * -1,0,0 ) );

            var userLoginService = new UserLoginService();

            foreach (var user in userLoginService.Queryable().Where(u => u.IsConfirmed == false && u.CreationDateTime < userAccountExpireDate).ToList() )
            {
                userLoginService.Delete( user, null );
                userLoginService.Save( user, null );
            }

            // purge exception log
            int exceptionExpireDays = Int32.Parse( dataMap.GetString( "DaysKeepExceptions" ) );
            DateTime exceptionExpireDate = DateTime.Now.Add( new TimeSpan( exceptionExpireDays * -1, 0, 0, 0 ) );

            ExceptionLogService exceptionLogService = new ExceptionLogService();

            foreach ( var exception in exceptionLogService.Queryable().Where( e => e.ExceptionDateTime < exceptionExpireDate ).ToList() )
            {
                exceptionLogService.Delete( exception, null );
                exceptionLogService.Save( exception, null );
            }

            // purge audit log
            int auditExpireDays = Int32.Parse( dataMap.GetString( "AuditLogExpirationDays" ) );
            DateTime auditExpireDate = DateTime.Now.Add( new TimeSpan( auditExpireDays * -1, 0, 0, 0 ) );
            AuditService auditService = new AuditService();
            foreach( var audit in auditService.Queryable().Where( a => a.DateTime < auditExpireDate ).ToList() )
            {
                auditService.Delete( audit, null );
                auditService.Save( audit, null );
            }

            // clean the cached file directory

            //get the attributes
            string cacheDirectoryPath = dataMap.GetString( "BaseCacheDirectory" );
            int cacheExpirationDays = int.Parse( dataMap.GetString( "DaysKeepCachedFiles" ) );
            DateTime cacheExpirationDate = DateTime.Now.Add( new TimeSpan( cacheExpirationDays * -1, 0, 0, 0 ) );

            //if job is being run by the IIS scheduler and path is not null
            if ( context.Scheduler.SchedulerName == "RockSchedulerIIS" && !String.IsNullOrEmpty( cacheDirectoryPath ) )
            {
                //get the physical path of the cache directory
                cacheDirectoryPath = System.Web.Hosting.HostingEnvironment.MapPath( cacheDirectoryPath );
            }

            //if directory is not blank and cache expiration date not in the future
            if ( !String.IsNullOrEmpty( cacheDirectoryPath ) && cacheExpirationDate <= DateTime.Now )
            {
                //Clean cache directory
                CleanCacheDirectory( cacheDirectoryPath, cacheExpirationDate );
            }

            // clean out any temporary binary files
            BinaryFileService binaryFileService = new BinaryFileService();
            foreach( var binaryFile in binaryFileService.Queryable().Where( bf => bf.IsTemporary == true ).ToList() )
            {
                if ( binaryFile.LastModifiedDateTime < DateTime.Now.AddDays(-1) )
                {
                    binaryFileService.Delete( binaryFile, null );
                    binaryFileService.Save( binaryFile, null );
                }
            }

        }
Beispiel #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 )
        {
            BinaryFile binaryFile;
            BinaryFileService binaryFileService = new BinaryFileService();
            AttributeService attributeService = new AttributeService();

            int binaryFileId = int.Parse( hfBinaryFileId.Value );

            if ( binaryFileId == 0 )
            {
                binaryFile = new BinaryFile();
                binaryFileService.Add( binaryFile, CurrentPersonId );
            }
            else
            {
                binaryFile = binaryFileService.Get( binaryFileId );
            }

            // if a new file was uploaded, copy the uploaded file to this binaryFile (uploaded files are always new temporary binaryFiles)
            if ( fsFile.BinaryFileId != binaryFile.Id)
            {
                var uploadedBinaryFile = binaryFileService.Get(fsFile.BinaryFileId ?? 0);
                if (uploadedBinaryFile != null)
                {
                    binaryFile.BinaryFileTypeId = uploadedBinaryFile.BinaryFileTypeId;
                    if ( uploadedBinaryFile.Data != null )
                    {
                        binaryFile.Data = binaryFile.Data ?? new BinaryFileData();
                        binaryFile.Data.Content = uploadedBinaryFile.Data.Content;
                    }
                }
            }

            binaryFile.IsTemporary = false;
            binaryFile.FileName = tbName.Text;
            binaryFile.Description = tbDescription.Text;
            binaryFile.MimeType = tbMimeType.Text;
            binaryFile.BinaryFileTypeId = ddlBinaryFileType.SelectedValueAsInt();

            binaryFile.LoadAttributes();
            Rock.Attribute.Helper.GetEditValues( phAttributes, binaryFile );

            if ( !Page.IsValid )
            {
                return;
            }

            if ( !binaryFile.IsValid )
            {
                // Controls will render the error messages                    
                return;
            }

            RockTransactionScope.WrapTransaction( () =>
            {
                binaryFileService.Save( binaryFile, CurrentPersonId );
                Rock.Attribute.Helper.SaveAttributeValues( binaryFile, CurrentPersonId );
            } );

            NavigateToParentPage();
        }
Beispiel #8
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 )
            {
                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.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, 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();
                    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 )
                    {
                        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 );

                        if ( orphanedIconFileId.HasValue)
                        {
                            BinaryFileService binaryFileService = new BinaryFileService();
                            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;
                                binaryFileService.Save( binaryFile, 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('PAGE_UPDATED');";
                        ScriptManager.RegisterStartupScript( this.Page, this.GetType(), "close-modal", script, true );
                    }
                }
            }
        }