/// <summary> /// Saves SEO information. /// </summary> /// <param name="model">The SEO information model.</param> /// <returns> /// true if SEO information saved successfully; false otherwise. /// </returns> public virtual EditSeoViewModel Execute(EditSeoViewModel model) { var page = Repository.First <PageProperties>(model.PageId); bool initialHasSeo = page.HasSEO; Models.Redirect newRedirect = null; page.Version = model.Version; page.Title = model.PageTitle; model.ChangedUrlPath = urlService.FixUrl(model.ChangedUrlPath); if (!string.Equals(model.PageUrlPath, model.ChangedUrlPath)) { pageService.ValidatePageUrl(model.ChangedUrlPath, model.PageId); if (model.CreatePermanentRedirect) { var redirect = redirectService.CreateRedirectEntity(model.PageUrlPath, model.ChangedUrlPath); if (redirect != null) { Repository.Save(redirect); newRedirect = redirect; } } page.NodeCountInSitemap = model.UpdateSitemap ? sitemapService.ChangeUrl(page.PageUrl, model.ChangedUrlPath) : sitemapService.NodesWithUrl(model.ChangedUrlPath); page.PageUrl = model.ChangedUrlPath; } page.PageUrlHash = page.PageUrl.UrlHash(); page.MetaTitle = model.MetaTitle; page.MetaKeywords = model.MetaKeywords; page.MetaDescription = model.MetaDescription; page.UseCanonicalUrl = model.UseCanonicalUrl; Repository.Save(page); UnitOfWork.Commit(); // Notify about SEO change. if (page.HasSEO != initialHasSeo) { Events.PageEvents.Instance.OnPageSeoStatusChanged(page); } // Notify about new redirect creation. if (newRedirect != null) { Events.PageEvents.Instance.OnRedirectCreated(newRedirect); } return(new EditSeoViewModel { PageUrlPath = page.PageUrl }); }
/// <summary> /// Executes the specified request. /// </summary> /// <param name="options">The request.</param> /// <returns></returns> /// <exception cref="System.NotImplementedException"></exception> public SearchableGridViewModel <SiteSettingRedirectViewModel> Execute(SearchableGridOptions options) { SearchableGridViewModel <SiteSettingRedirectViewModel> model; options.SetDefaultSortingOptions("PageUrl"); Models.Redirect alias = null; SiteSettingRedirectViewModel modelAlias = null; var query = UnitOfWork.Session.QueryOver(() => alias).Where(() => !alias.IsDeleted); if (!string.IsNullOrWhiteSpace(options.SearchQuery)) { var searchQuery = string.Format("%{0}%", options.SearchQuery); query = query.Where( Restrictions.InsensitiveLike(Projections.Property(() => alias.PageUrl), searchQuery) || Restrictions.InsensitiveLike(Projections.Property(() => alias.RedirectUrl), searchQuery)); } query = query.SelectList( select => select.Select(() => alias.Id) .WithAlias(() => modelAlias.Id) .Select(() => alias.PageUrl) .WithAlias(() => modelAlias.PageUrl) .Select(() => alias.RedirectUrl) .WithAlias(() => modelAlias.RedirectUrl) .Select(() => alias.Version) .WithAlias(() => modelAlias.Version)).TransformUsing(Transformers.AliasToBean <SiteSettingRedirectViewModel>()); var count = query.ToRowCountFutureValue(); var redirects = query.AddSortingAndPaging(options).Future <SiteSettingRedirectViewModel>(); model = new SearchableGridViewModel <SiteSettingRedirectViewModel>(redirects.ToList(), options, count.Value); return(model); }
/// <summary> /// Executes the specified request. /// </summary> /// <param name="request">The request.</param> /// <returns>Save response.</returns> /// <exception cref="CmsException">Failed to save page properties.</exception> public SavePageResponse Execute(EditPagePropertiesViewModel request) { UnitOfWork.BeginTransaction(); var pageQuery = Repository .AsQueryable <PageProperties>(p => p.Id == request.Id) .FetchMany(p => p.Options) .Fetch(p => p.Layout).ThenFetchMany(l => l.LayoutOptions) .AsQueryable(); if (cmsConfiguration.Security.AccessControlEnabled) { pageQuery = pageQuery.FetchMany(f => f.AccessRules); } var page = pageQuery.ToList().FirstOne(); if (cmsConfiguration.Security.AccessControlEnabled) { AccessControlService.DemandAccess(page, Context.Principal, AccessLevel.ReadWrite, RootModuleConstants.UserRoles.EditContent, RootModuleConstants.UserRoles.PublishContent); } else { AccessControlService.DemandAccess(Context.Principal, RootModuleConstants.UserRoles.EditContent, RootModuleConstants.UserRoles.PublishContent); } Models.Redirect redirectCreated = null; bool initialSeoStatus = page.HasSEO; request.PageUrl = urlService.FixUrl(request.PageUrl); if (!string.Equals(page.PageUrl, request.PageUrl)) { pageService.ValidatePageUrl(request.PageUrl, request.Id); if (request.RedirectFromOldUrl) { var redirect = redirectService.CreateRedirectEntity(page.PageUrl, request.PageUrl); if (redirect != null) { Repository.Save(redirect); redirectCreated = redirect; } } page.NodeCountInSitemap = request.UpdateSitemap ? sitemapService.ChangeUrl(page.PageUrl, request.PageUrl) : sitemapService.NodesWithUrl(request.PageUrl); page.PageUrl = request.PageUrl; } page.PageUrlHash = page.PageUrl.UrlHash(); page.Layout = Repository.AsProxy <Root.Models.Layout>(request.TemplateId); page.Category = request.CategoryId.HasValue ? Repository.AsProxy <CategoryEntity>(request.CategoryId.Value) : null; page.Title = request.PageName; page.CustomCss = request.PageCSS; page.CustomJS = request.PageJavascript; var publishDraftContent = false; if (request.CanPublishPage) { AccessControlService.DemandAccess(Context.Principal, RootModuleConstants.UserRoles.PublishContent); if (request.IsPagePublished) { if (page.Status != PageStatus.Published) { page.Status = PageStatus.Published; page.PublishedOn = DateTime.Now; publishDraftContent = true; } } else { page.Status = PageStatus.Unpublished; } } page.UseNoFollow = request.UseNoFollow; page.UseNoIndex = request.UseNoIndex; page.UseCanonicalUrl = request.UseCanonicalUrl; page.IsArchived = request.IsArchived; page.Version = request.Version; page.Image = request.Image != null && request.Image.ImageId.HasValue ? Repository.AsProxy <MediaImage>(request.Image.ImageId.Value) : null; page.SecondaryImage = request.SecondaryImage != null && request.SecondaryImage.ImageId.HasValue ? Repository.AsProxy <MediaImage>(request.SecondaryImage.ImageId.Value) : null; page.FeaturedImage = request.FeaturedImage != null && request.FeaturedImage.ImageId.HasValue ? Repository.AsProxy <MediaImage>(request.FeaturedImage.ImageId.Value) : null; var optionValues = page.Options.Distinct(); var parentOptions = page.Layout.LayoutOptions.Distinct(); optionService.SaveOptionValues(request.OptionValues, optionValues, parentOptions, () => new PageOption { Page = page }); if (cmsConfiguration.Security.AccessControlEnabled) { page.AccessRules.RemoveDuplicateEntities(); var accessRules = request.UserAccessList != null?request.UserAccessList.Cast <IAccessRule>().ToList() : null; accessControlService.UpdateAccessControl(page, accessRules); } Repository.Save(page); // Save tags IList <Tag> newTags; tagService.SavePageTags(page, request.Tags, out newTags); if (publishDraftContent) { contentService.PublishDraftContent(page.Id); } UnitOfWork.Commit(); // Notify about page properties change. Events.PageEvents.Instance.OnPagePropertiesChanged(page); // Notify about redirect creation. if (redirectCreated != null) { Events.PageEvents.Instance.OnRedirectCreated(redirectCreated); } // Notify about SEO status change. if (initialSeoStatus != page.HasSEO) { Events.PageEvents.Instance.OnPageSeoStatusChanged(page); } // Notify about new tags. Events.RootEvents.Instance.OnTagCreated(newTags); return(new SavePageResponse(page)); }
/// <summary> /// Executes the specified request. /// </summary> /// <param name="request">The request.</param> /// <returns>Save response.</returns> /// <exception cref="CmsException">Failed to save page properties.</exception> public SavePageResponse Execute(EditPagePropertiesViewModel request) { var isMultilanguageEnabled = cmsConfiguration.EnableMultilanguage; ValidateRequest(request, isMultilanguageEnabled); var pageQuery = Repository.AsQueryable <PageProperties>(p => p.Id == request.Id) .FetchMany(p => p.Options) .Fetch(p => p.Layout) .ThenFetchMany(l => l.LayoutOptions) .FetchMany(p => p.MasterPages) .AsQueryable(); if (cmsConfiguration.Security.AccessControlEnabled) { pageQuery = pageQuery.FetchMany(f => f.AccessRules); } var page = pageQuery.ToList().FirstOne(); var beforeChange = new UpdatingPagePropertiesModel(page); var roles = page.IsMasterPage ? new[] { RootModuleConstants.UserRoles.EditContent, RootModuleConstants.UserRoles.PublishContent, RootModuleConstants.UserRoles.Administration } : new[] { RootModuleConstants.UserRoles.EditContent, RootModuleConstants.UserRoles.PublishContent }; if (cmsConfiguration.Security.AccessControlEnabled) { AccessControlService.DemandAccess(page, Context.Principal, AccessLevel.ReadWrite, roles); } else { AccessControlService.DemandAccess(Context.Principal, roles); } var canEdit = page.IsMasterPage ? SecurityService.IsAuthorized( Context.Principal, RootModuleConstants.UserRoles.MultipleRoles(RootModuleConstants.UserRoles.EditContent, RootModuleConstants.UserRoles.Administration)) : SecurityService.IsAuthorized(Context.Principal, RootModuleConstants.UserRoles.EditContent); IList <PageProperties> translations = null; if (canEdit && isMultilanguageEnabled && !page.IsMasterPage) { translations = LoadAndValidateTranslations(page, request); } // Load master pages for updating page's master path and page's children master path IList <Guid> newMasterIds; IList <Guid> oldMasterIds; IList <Guid> childrenPageIds; IList <MasterPage> existingChildrenMasterPages; masterPageService.PrepareForUpdateChildrenMasterPages(page, request.MasterPageId, out newMasterIds, out oldMasterIds, out childrenPageIds, out existingChildrenMasterPages); IList <SitemapNode> updatedNodes = null; // Start transaction, only when everything is already loaded UnitOfWork.BeginTransaction(); Models.Redirect redirectCreated = null; var initialSeoStatus = page.HasSEO; request.PageUrl = urlService.FixUrl(request.PageUrl); if (canEdit && !string.Equals(page.PageUrl, request.PageUrl)) { pageService.ValidatePageUrl(request.PageUrl, request.Id); if (request.RedirectFromOldUrl) { var redirect = redirectService.CreateRedirectEntity(page.PageUrl, request.PageUrl); if (redirect != null) { Repository.Save(redirect); redirectCreated = redirect; } } if (request.UpdateSitemap) { updatedNodes = sitemapService.ChangeUrlsInAllSitemapsNodes(page.PageUrl, request.PageUrl); } page.PageUrl = request.PageUrl; } List <PageProperties> updatePageTranslations = null; if (canEdit) { page.PageUrlHash = page.PageUrl.UrlHash(); page.ForceAccessProtocol = request.ForceAccessProtocol; categoryService.CombineEntityCategories <PageProperties, PageCategory>(page, request.Categories); page.Title = request.PageName; page.CustomCss = request.PageCSS; page.CustomJS = request.PageJavascript; masterPageService.SetMasterOrLayout(page, request.MasterPageId, request.TemplateId); if (isMultilanguageEnabled && !page.IsMasterPage) { updatePageTranslations = UpdatePageTranslations(page, translations, request); } } var publishDraftContent = false; if (request.CanPublishPage && !page.IsMasterPage) { AccessControlService.DemandAccess(Context.Principal, RootModuleConstants.UserRoles.PublishContent); if (request.IsPagePublished) { if (page.Status != PageStatus.Published) { page.Status = PageStatus.Published; page.PublishedOn = DateTime.Now; publishDraftContent = true; } } else { page.Status = PageStatus.Unpublished; } } IList <PageOption> pageOptions = page.Options.Distinct().ToList(); if (canEdit) { if (!page.IsMasterPage) { page.UseNoFollow = request.UseNoFollow; page.UseNoIndex = request.UseNoIndex; page.IsArchived = request.IsArchived; } page.UseCanonicalUrl = request.UseCanonicalUrl; page.Version = request.Version; page.Image = request.Image != null && request.Image.ImageId.HasValue ? Repository.AsProxy <MediaImage>(request.Image.ImageId.Value) : null; page.SecondaryImage = request.SecondaryImage != null && request.SecondaryImage.ImageId.HasValue ? Repository.AsProxy <MediaImage>(request.SecondaryImage.ImageId.Value) : null; page.FeaturedImage = request.FeaturedImage != null && request.FeaturedImage.ImageId.HasValue ? Repository.AsProxy <MediaImage>(request.FeaturedImage.ImageId.Value) : null; pageOptions = optionService.SaveOptionValues(request.OptionValues, pageOptions, () => new PageOption { Page = page }); if (cmsConfiguration.Security.AccessControlEnabled) { page.AccessRules.RemoveDuplicateEntities(); var accessRules = request.UserAccessList != null?request.UserAccessList.Cast <IAccessRule>().ToList() : null; accessControlService.UpdateAccessControl(page, accessRules); } } // Notify about page properties changing. var cancelEventArgs = Events.PageEvents.Instance.OnPagePropertiesChanging(beforeChange, new UpdatingPagePropertiesModel(page)); if (cancelEventArgs.Cancel) { Context.Messages.AddError(cancelEventArgs.CancellationErrorMessages.ToArray()); return(null); } Repository.Save(page); IList <Tag> newTags = null; if (canEdit) { masterPageService.UpdateChildrenMasterPages(existingChildrenMasterPages, oldMasterIds, newMasterIds, childrenPageIds); tagService.SavePageTags(page, request.Tags, out newTags); } if (publishDraftContent) { contentService.PublishDraftContent(page.Id); } UnitOfWork.Commit(); // Notify about page properties change. page.Options = pageOptions; Events.PageEvents.Instance.OnPagePropertiesChanged(page); // Notify about translation properties changed if (updatePageTranslations != null) { updatePageTranslations.ForEach(Events.PageEvents.Instance.OnPagePropertiesChanged); } // Notify about redirect creation. if (redirectCreated != null) { Events.PageEvents.Instance.OnRedirectCreated(redirectCreated); } // Notify about SEO status change. if (initialSeoStatus != page.HasSEO) { Events.PageEvents.Instance.OnPageSeoStatusChanged(page); } // Notify about new tags. Events.RootEvents.Instance.OnTagCreated(newTags); // Notify about updated sitemap nodes. if (updatedNodes != null) { var updatedSitemaps = new List <Models.Sitemap>(); foreach (var node in updatedNodes) { Events.SitemapEvents.Instance.OnSitemapNodeUpdated(node); if (!updatedSitemaps.Contains(node.Sitemap)) { updatedSitemaps.Add(node.Sitemap); } } foreach (var updatedSitemap in updatedSitemaps) { Events.SitemapEvents.Instance.OnSitemapUpdated(updatedSitemap); } } return(new SavePageResponse(page)); }
/// <summary> /// Saves SEO information. /// </summary> /// <param name="model">The SEO information model.</param> /// <returns> /// true if SEO information saved successfully; false otherwise. /// </returns> public virtual EditSeoViewModel Execute(EditSeoViewModel model) { var page = Repository.First <PageProperties>(model.PageId); bool initialHasSeo = page.HasSEO; Models.Redirect newRedirect = null; page.Version = model.Version; page.Title = model.PageTitle; model.ChangedUrlPath = urlService.FixUrl(model.ChangedUrlPath); IList <SitemapNode> updatedNodes = null; if (!string.Equals(model.PageUrlPath, model.ChangedUrlPath)) { pageService.ValidatePageUrl(model.ChangedUrlPath, model.PageId); if (model.CreatePermanentRedirect) { var redirect = redirectService.CreateRedirectEntity(model.PageUrlPath, model.ChangedUrlPath); if (redirect != null) { Repository.Save(redirect); newRedirect = redirect; } } if (model.UpdateSitemap) { updatedNodes = sitemapService.ChangeUrlsInAllSitemapsNodes(page.PageUrl, model.ChangedUrlPath); } page.PageUrl = model.ChangedUrlPath; } page.PageUrlHash = page.PageUrl.UrlHash(); page.MetaTitle = model.MetaTitle; page.MetaKeywords = model.MetaKeywords; page.MetaDescription = model.MetaDescription; page.UseCanonicalUrl = model.UseCanonicalUrl; Repository.Save(page); UnitOfWork.Commit(); // Notify about SEO change. if (page.HasSEO != initialHasSeo) { Events.PageEvents.Instance.OnPageSeoStatusChanged(page); } // Notify about new redirect creation. if (newRedirect != null) { Events.PageEvents.Instance.OnRedirectCreated(newRedirect); } // Notify about updated sitemap nodes. if (updatedNodes != null) { var updatedSitemaps = new List <Models.Sitemap>(); foreach (var node in updatedNodes) { Events.SitemapEvents.Instance.OnSitemapNodeUpdated(node); if (!updatedSitemaps.Contains(node.Sitemap)) { updatedSitemaps.Add(node.Sitemap); } } foreach (var updatedSitemap in updatedSitemaps) { Events.SitemapEvents.Instance.OnSitemapUpdated(updatedSitemap); } } return(new EditSeoViewModel { PageUrlPath = page.PageUrl }); }
/// <summary> /// Executes a command to save a redirect. /// </summary> /// <param name="request">The redirect view model.</param> /// <returns> /// Saved redirect view model. /// </returns> public SiteSettingRedirectViewModel Execute(SiteSettingRedirectViewModel request) { Models.Redirect redirect; request.PageUrl = urlService.FixUrl(request.PageUrl); request.RedirectUrl = urlService.FixUrl(request.RedirectUrl); // Validate request if (!urlService.ValidateUrl(request.PageUrl)) { var message = PagesGlobalization.SaveRedirect_InvalidPageUrl_Message; var logMessage = string.Format("Invalid page url {0}.", request.PageUrl); throw new ValidationException(() => message, logMessage); } if (!urlService.ValidateUrl(request.RedirectUrl)) { var message = PagesGlobalization.SaveRedirect_InvalidRedirectUrl_Message; var logMessage = string.Format("Invalid redirect url {0}.", request.RedirectUrl); throw new ValidationException(() => message, logMessage); } // Validate for url patterns string patternsValidationMessage; if (!urlService.ValidateUrlPatterns(request.PageUrl, out patternsValidationMessage)) { var logMessage = string.Format("{0}. URL: {1}.", patternsValidationMessage, request.PageUrl); throw new ValidationException(() => patternsValidationMessage, logMessage); } if (!urlService.ValidateUrlPatterns(request.RedirectUrl, out patternsValidationMessage, PagesGlobalization.SaveRedirect_RedirectUrl_Name)) { var logMessage = string.Format("{0}. URL: {1}.", patternsValidationMessage, request.PageUrl); throw new ValidationException(() => patternsValidationMessage, logMessage); } redirectService.ValidateRedirectExists(request.PageUrl, request.Id); redirectService.ValidateForCircularLoop(request.PageUrl, request.RedirectUrl, request.Id); if (request.Id.HasDefaultValue()) { redirect = new Models.Redirect(); } else { redirect = Repository.First <Models.Redirect>(request.Id); } redirect.Version = request.Version; redirect.PageUrl = request.PageUrl; redirect.RedirectUrl = request.RedirectUrl; Repository.Save(redirect); UnitOfWork.Commit(); // Notify. if (request.Id.HasDefaultValue()) { PagesApiContext.Events.OnRedirectCreated(redirect); } else { PagesApiContext.Events.OnRedirectUpdated(redirect); } return(new SiteSettingRedirectViewModel { Id = redirect.Id, Version = redirect.Version, PageUrl = redirect.PageUrl, RedirectUrl = redirect.RedirectUrl }); }
/// <summary> /// Executes the specified request. /// </summary> /// <param name="request">The request.</param> /// <returns>Save response.</returns> /// <exception cref="CmsException">Failed to save page properties.</exception> public SavePageResponse Execute(EditPagePropertiesViewModel request) { UnitOfWork.BeginTransaction(); var page = Repository .AsQueryable <PageProperties>(p => p.Id == request.Id) .FetchMany(p => p.Options) .Fetch(p => p.Layout).ThenFetchMany(l => l.LayoutOptions) .ToList() .FirstOrDefault(); Models.Redirect redirectCreated = null; bool initialSeoStatus = page.HasSEO; request.PageUrl = urlService.FixUrl(request.PageUrl); if (!string.Equals(page.PageUrl, request.PageUrl)) { pageService.ValidatePageUrl(request.PageUrl, request.Id); if (request.RedirectFromOldUrl) { var redirect = redirectService.CreateRedirectEntity(page.PageUrl, request.PageUrl); if (redirect != null) { Repository.Save(redirect); redirectCreated = redirect; } } page.NodeCountInSitemap = request.UpdateSitemap ? sitemapService.ChangeUrl(page.PageUrl, request.PageUrl) : sitemapService.NodesWithUrl(request.PageUrl); page.PageUrl = request.PageUrl; } page.PageUrlLowerTrimmed = page.PageUrl.LowerTrimmedUrl(); page.Layout = Repository.AsProxy <Root.Models.Layout>(request.TemplateId); page.Category = request.CategoryId.HasValue ? Repository.AsProxy <CategoryEntity>(request.CategoryId.Value) : null; page.Title = request.PageName; page.CustomCss = request.PageCSS; page.CustomJS = request.PageJavascript; if (request.IsVisibleToEveryone) { page.Status = PageStatus.Published; page.PublishedOn = DateTime.Now; } else { page.Status = PageStatus.Unpublished; } page.UseNoFollow = request.UseNoFollow; page.UseNoIndex = request.UseNoIndex; page.UseCanonicalUrl = request.UseCanonicalUrl; page.IsArchived = request.IsArchived; page.Version = request.Version; page.Image = request.Image != null && request.Image.ImageId.HasValue ? Repository.AsProxy <MediaImage>(request.Image.ImageId.Value) : null; page.SecondaryImage = request.SecondaryImage != null && request.SecondaryImage.ImageId.HasValue ? Repository.AsProxy <MediaImage>(request.SecondaryImage.ImageId.Value) : null; page.FeaturedImage = request.FeaturedImage != null && request.FeaturedImage.ImageId.HasValue ? Repository.AsProxy <MediaImage>(request.FeaturedImage.ImageId.Value) : null; var optionValues = page.Options.Distinct(); var parentOptions = page.Layout.LayoutOptions.Distinct(); optionService.SaveOptionValues(request.OptionValues, optionValues, parentOptions, () => new Root.Models.PageOption { Page = page }); if (cmsConfiguration.AccessControlEnabled) { accessControlService.UpdateAccessControl(request.UserAccessList, request.Id); } Repository.Save(page); // Save tags IList <Root.Models.Tag> newTags; tagService.SavePageTags(page, request.Tags, out newTags); UnitOfWork.Commit(); // Notify about page properties change. Events.PageEvents.Instance.OnPagePropertiesChanged(page); // Notify about redirect creation. if (redirectCreated != null) { Events.PageEvents.Instance.OnRedirectCreated(redirectCreated); } // Notify about SEO status change. if (initialSeoStatus != page.HasSEO) { Events.PageEvents.Instance.OnPageSeoStatusChanged(page); } // Notify about new tags. Events.RootEvents.Instance.OnTagCreated(newTags); return(new SavePageResponse(page)); }
/// <summary> /// Executes the specified request. /// </summary> /// <param name="request">The request.</param> /// <returns>Save response.</returns> /// <exception cref="CmsException">Failed to save page properties.</exception> public SavePageResponse Execute(EditPagePropertiesViewModel request) { UnitOfWork.BeginTransaction(); var page = Repository.First <PageProperties>(request.Id); Models.Redirect redirectCreated = null; bool initialSeoStatus = page.HasSEO; request.PageUrl = urlService.FixUrl(request.PageUrl); if (!string.Equals(page.PageUrl, request.PageUrl, StringComparison.OrdinalIgnoreCase)) { pageService.ValidatePageUrl(request.PageUrl, request.Id); if (request.RedirectFromOldUrl) { var redirect = redirectService.CreateRedirectEntity(page.PageUrl, request.PageUrl); if (redirect != null) { Repository.Save(redirect); redirectCreated = redirect; } } page.NodeCountInSitemap = request.UpdateSitemap ? sitemapService.ChangeUrl(page.PageUrl, request.PageUrl) : sitemapService.NodesWithUrl(request.PageUrl); page.PageUrl = request.PageUrl; } page.Layout = Repository.AsProxy <Root.Models.Layout>(request.TemplateId); page.Category = request.CategoryId.HasValue ? Repository.AsProxy <Category>(request.CategoryId.Value) : null; page.Title = request.PageName; page.CustomCss = request.PageCSS; page.CustomJS = request.PageJavascript; page.IsPublic = request.IsVisibleToEveryone; page.UseNoFollow = request.UseNoFollow; page.UseNoIndex = request.UseNoIndex; page.Version = request.Version; if (request.Image != null && request.Image.ImageId.HasValue) { page.Image = Repository.AsProxy <MediaImage>(request.Image.ImageId.Value); } else { page.Image = null; } Repository.Save(page); // Save tags IList <Root.Models.Tag> newTags; tagService.SavePageTags(page, request.Tags, out newTags); UnitOfWork.Commit(); // Notify about page properties change. PagesApiContext.Events.OnPagePropertiesChanged(page); // Notify about redirect creation. if (redirectCreated != null) { PagesApiContext.Events.OnRedirectCreated(redirectCreated); } // Notify about SEO status change. if (initialSeoStatus != page.HasSEO) { PagesApiContext.Events.OnPageSeoStatusChanged(page); } // Notify about new tags. PagesApiContext.Events.OnTagCreated(newTags); return(new SavePageResponse(page)); }
/// <summary> /// Saves SEO information. /// </summary> /// <param name="model">The SEO information model.</param> /// <returns> /// true if SEO information saved successfully; false otherwise. /// </returns> public virtual EditSeoViewModel Execute(EditSeoViewModel model) { var pageQuery = Repository.AsQueryable <PageProperties>(p => p.Id == model.PageId) .FetchMany(p => p.Options) .Fetch(p => p.Layout) .ThenFetchMany(l => l.LayoutOptions) .FetchMany(p => p.MasterPages) .AsQueryable(); if (cmsConfiguration.Security.AccessControlEnabled) { pageQuery = pageQuery.FetchMany(f => f.AccessRules); } var page = pageQuery.ToList().FirstOne(); var beforeChange = new UpdatingPagePropertiesModel(page); var roles = new[] { RootModuleConstants.UserRoles.EditContent }; if (cmsConfiguration.Security.AccessControlEnabled) { AccessControlService.DemandAccess(page, Context.Principal, AccessLevel.ReadWrite, roles); } else { AccessControlService.DemandAccess(Context.Principal, roles); } bool initialHasSeo = page.HasSEO; Models.Redirect newRedirect = null; page.Version = model.Version; page.Title = model.PageTitle; model.ChangedUrlPath = urlService.FixUrl(model.ChangedUrlPath); IList <SitemapNode> updatedNodes = null; if (!string.Equals(model.PageUrlPath, model.ChangedUrlPath)) { pageService.ValidatePageUrl(model.ChangedUrlPath, model.PageId); if (model.CreatePermanentRedirect) { var redirect = redirectService.CreateRedirectEntity(model.PageUrlPath, model.ChangedUrlPath); if (redirect != null) { Repository.Save(redirect); newRedirect = redirect; } } if (model.UpdateSitemap) { updatedNodes = sitemapService.ChangeUrlsInAllSitemapsNodes(page.PageUrl, model.ChangedUrlPath); } page.PageUrl = model.ChangedUrlPath; } page.PageUrlHash = page.PageUrl.UrlHash(); page.MetaTitle = model.MetaTitle; page.MetaKeywords = model.MetaKeywords; page.MetaDescription = model.MetaDescription; page.UseCanonicalUrl = model.UseCanonicalUrl; // Notify about page properties changing. var cancelEventArgs = Events.PageEvents.Instance.OnPagePropertiesChanging(beforeChange, new UpdatingPagePropertiesModel(page)); if (cancelEventArgs.Cancel) { Context.Messages.AddError(cancelEventArgs.CancellationErrorMessages.ToArray()); return(null); } Repository.Save(page); UnitOfWork.Commit(); Events.PageEvents.Instance.OnPagePropertiesChanged(page); // Notify about SEO change. if (page.HasSEO != initialHasSeo) { Events.PageEvents.Instance.OnPageSeoStatusChanged(page); } // Notify about new redirect creation. if (newRedirect != null) { Events.PageEvents.Instance.OnRedirectCreated(newRedirect); } // Notify about updated sitemap nodes. if (updatedNodes != null) { var updatedSitemaps = new List <Models.Sitemap>(); foreach (var node in updatedNodes) { Events.SitemapEvents.Instance.OnSitemapNodeUpdated(node); if (!updatedSitemaps.Contains(node.Sitemap)) { updatedSitemaps.Add(node.Sitemap); } } foreach (var updatedSitemap in updatedSitemaps) { Events.SitemapEvents.Instance.OnSitemapUpdated(updatedSitemap); } } return(new EditSeoViewModel { PageUrlPath = page.PageUrl }); }