protected ICommandContext GetMockedCommandContext(IMessagesIndicator messagesIndicator = null) { Mock <ICommandContext> commandContext = new Mock <ICommandContext>(); commandContext.Setup(f => f.Messages).Returns(() => messagesIndicator ?? GetMockedMessagesIndicator()); return(commandContext.Object); }
public static IHtmlString CustomMessagesBox(this HtmlHelper html, IMessagesIndicator messages, string id = null, IDictionary <string, string> attributes = null) { if (string.IsNullOrWhiteSpace(id)) { id = string.Format("bcms-custom-messages-{0}", Guid.NewGuid()); } return(MessagesBox(html, id, attributes, cssClassMessages + " " + cssClassCustomMessages, messages)); }
public static IHtmlString CustomMessagesBox(this HtmlHelper html, IMessagesIndicator messages, string id = null, IDictionary<string, string> attributes = null) { if (string.IsNullOrWhiteSpace(id)) { id = string.Format("bcms-custom-messages-{0}", Guid.NewGuid()); } return MessagesBox(html, id, attributes, cssClassMessages + " " + cssClassCustomMessages, messages); }
/// <summary> /// Renders messages box with given id. /// </summary> /// <param name="html">The HTML helper.</param> /// <param name="id">The messages box id.</param> /// <param name="attributes">The attributes.</param> /// <param name="cssClass">The CSS class.</param> /// <param name="messages">The messages.</param> /// <returns> /// Html string with rendered messages box. /// </returns> /// <exception cref="CmsException">Unable to generate messages box.;Controller should inherit CmsControllerBase class.</exception> /// <exception cref="System.NotSupportedException">Controller should inherit CmsControllerBase class.</exception> private static IHtmlString MessagesBox(this HtmlHelper html, string id, IDictionary<string, string> attributes, string cssClass, IMessagesIndicator messages = null) { var controller = html.ViewContext.Controller as CmsControllerBase; if (controller == null) { throw new CmsException("Unable to generate messages box.", new NotSupportedException("Controller should inherit CmsControllerBase class.")); } string customCssClass = null; if (attributes != null) { customCssClass = attributes .Where(a => a.Key == "class" && !string.IsNullOrWhiteSpace(a.Value)) .Select(a => string.Format(" {0}", a.Value)) .FirstOrDefault(); } var sb = new StringBuilder(); sb.AppendFormat("<div class=\"{0} {1}\"", cssClass, customCssClass); if (!string.IsNullOrEmpty(id)) { sb.Append(" id=\"" + id + "\""); } if (attributes != null) { foreach (var pair in attributes) { if (pair.Key != "class") { sb.AppendFormat(" {0}=\"{1}\"", pair.Key, pair.Value); } } } sb.AppendLine(">"); if (messages == null) { messages = controller.Messages; } AddMessagesBoxBlock(sb, "bcms-success-messages", messages.Success); AddMessagesBoxBlock(sb, "bcms-info-messages", messages.Info); AddMessagesBoxBlock(sb, "bcms-warning-messages", messages.Warn); AddMessagesBoxBlock(sb, "bcms-error-messages", messages.Error); sb.AppendLine("</div>"); return new MvcHtmlString(sb.ToString()); }
/// <summary> /// Renders messages box with given id. /// </summary> /// <param name="html">The HTML helper.</param> /// <param name="id">The messages box id.</param> /// <param name="attributes">The attributes.</param> /// <param name="cssClass">The CSS class.</param> /// <param name="messages">The messages.</param> /// <returns> /// Html string with rendered messages box. /// </returns> /// <exception cref="CmsException">Unable to generate messages box.;Controller should inherit CmsControllerBase class.</exception> /// <exception cref="System.NotSupportedException">Controller should inherit CmsControllerBase class.</exception> private static IHtmlString MessagesBox(this HtmlHelper html, string id, IDictionary <string, string> attributes, string cssClass, IMessagesIndicator messages = null) { var controller = html.ViewContext.Controller as CmsControllerBase; if (controller == null) { throw new CmsException("Unable to generate messages box.", new NotSupportedException("Controller should inherit CmsControllerBase class.")); } string customCssClass = null; if (attributes != null) { customCssClass = attributes .Where(a => a.Key == "class" && !string.IsNullOrWhiteSpace(a.Value)) .Select(a => string.Format(" {0}", a.Value)) .FirstOrDefault(); } var sb = new StringBuilder(); sb.AppendFormat("<div class=\"{0} {1}\"", cssClass, customCssClass); if (!string.IsNullOrEmpty(id)) { sb.Append(" id=\"" + id + "\""); } if (attributes != null) { foreach (var pair in attributes) { if (pair.Key != "class") { sb.AppendFormat(" {0}=\"{1}\"", pair.Key, pair.Value); } } } sb.AppendLine(">"); if (messages == null) { messages = controller.Messages; } AddMessagesBoxBlock(sb, "bcms-success-messages", messages.Success); AddMessagesBoxBlock(sb, "bcms-info-messages", messages.Info); AddMessagesBoxBlock(sb, "bcms-warning-messages", messages.Warn); AddMessagesBoxBlock(sb, "bcms-error-messages", messages.Error); sb.AppendLine("</div>"); return(new MvcHtmlString(sb.ToString())); }
/// <summary> /// Deletes the page. /// </summary> /// <param name="model">The model.</param> /// <param name="principal">The principal.</param> /// <param name="messages">The messages.</param> /// <returns> /// Delete result /// </returns> /// <exception cref="ConcurrentDataException"></exception> /// <exception cref="System.ComponentModel.DataAnnotations.ValidationException"> /// </exception> public bool DeletePage(DeletePageViewModel model, IPrincipal principal, IMessagesIndicator messages = null) { var languagesFuture = repository.AsQueryable<Language>().ToFuture(); var page = repository.AsQueryable<PageProperties>(p => p.Id == model.PageId) .FetchMany(p => p.PageContents) .ThenFetch(pc => pc.Content) .ToFuture() .ToList() .FirstOne(); // Unidentified problem where in some cases proxy is returned. if (page is INHibernateProxy) { page = repository.UnProxy(page); } if (model.Version > 0 && page.Version != model.Version) { throw new ConcurrentDataException(page); } if (page.IsMasterPage && repository.AsQueryable<MasterPage>(mp => mp.Master == page).Any()) { var message = PagesGlobalization.DeletePageCommand_MasterPageHasChildren_Message; var logMessage = string.Format("Failed to delete page. Page is selected as master page. Id: {0} Url: {1}", page.Id, page.PageUrl); throw new ValidationException(() => message, logMessage); } var isRedirectInternal = false; if (!string.IsNullOrWhiteSpace(model.RedirectUrl)) { isRedirectInternal = urlService.ValidateInternalUrl(model.RedirectUrl); if (!isRedirectInternal && urlService.ValidateInternalUrl(urlService.FixUrl(model.RedirectUrl))) { isRedirectInternal = true; } if (isRedirectInternal) { model.RedirectUrl = urlService.FixUrl(model.RedirectUrl); } } if (model.UpdateSitemap) { accessControlService.DemandAccess(principal, RootModuleConstants.UserRoles.EditContent); } var sitemaps = new Dictionary<Sitemap, bool>(); var sitemapNodes = sitemapService.GetNodesByPage(page); if (model.UpdateSitemap) { sitemapNodes.Select(node => node.Sitemap) .Distinct() .ToList() .ForEach( sitemap => sitemaps.Add( sitemap, !cmsConfiguration.Security.AccessControlEnabled || accessControlService.GetAccessLevel(sitemap, principal) == AccessLevel.ReadWrite)); foreach (var node in sitemapNodes) { if (sitemaps[node.Sitemap] && node.ChildNodes.Count > 0) { var logMessage = string.Format("In {0} sitemap node {1} has {2} child nodes.", node.Sitemap.Id, node.Id, node.ChildNodes.Count); throw new ValidationException(() => PagesGlobalization.DeletePageCommand_SitemapNodeHasChildNodes_Message, logMessage); } } } unitOfWork.BeginTransaction(); // Update sitemap nodes IList<SitemapNode> updatedNodes = new List<SitemapNode>(); IList<SitemapNode> deletedNodes = new List<SitemapNode>(); UpdateSitemapNodes(model, page, sitemapNodes, sitemaps, languagesFuture.ToList(), updatedNodes, deletedNodes); Redirect redirect; if (!string.IsNullOrWhiteSpace(model.RedirectUrl)) { if (string.Equals(page.PageUrl, model.RedirectUrl, StringComparison.OrdinalIgnoreCase)) { var logMessage = string.Format("Circular redirect loop from url {0} to url {0}.", model.RedirectUrl); throw new ValidationException(() => PagesGlobalization.ValidatePageUrlCommand_SameUrlPath_Message, logMessage); } // Validate url if (!urlService.ValidateExternalUrl(model.RedirectUrl)) { var logMessage = string.Format("Invalid redirect url {0}.", model.RedirectUrl); throw new ValidationException(() => PagesGlobalization.ValidatePageUrlCommand_InvalidUrlPath_Message, logMessage); } string patternsValidationMessage; if (isRedirectInternal && !urlService.ValidateUrlPatterns(model.RedirectUrl, out patternsValidationMessage, PagesGlobalization.DeletePage_RedirectUrl_Name)) { var logMessage = string.Format("{0}. URL: {1}.", patternsValidationMessage, model.RedirectUrl); throw new ValidationException(() => patternsValidationMessage, logMessage); } redirect = redirectService.GetPageRedirect(page.PageUrl); if (redirect != null) { redirect.RedirectUrl = model.RedirectUrl; } else { redirect = redirectService.CreateRedirectEntity(page.PageUrl, model.RedirectUrl); } if (redirect != null) { repository.Save(redirect); } } else { redirect = null; } // Delete child entities. if (page.PageTags != null) { foreach (var pageTag in page.PageTags) { repository.Delete(pageTag); } } var deletedPageContents = new List<PageContent>(); var htmlContentsToDelete = new List<HtmlContent>(); if (page.PageContents != null) { foreach (var pageContent in page.PageContents) { // If content is HTML content, delete HTML content var htmlContent = pageContent.Content as HtmlContent; if (htmlContent != null) { var draft = pageContent.Content.History != null ? pageContent.Content.History.FirstOrDefault(c => c.Status == ContentStatus.Draft) : null; if (draft != null) { repository.Delete(draft); } repository.Delete(htmlContent); htmlContentsToDelete.Add(htmlContent); } repository.Delete(pageContent); deletedPageContents.Add(pageContent); } } if (page.Options != null) { foreach (var option in page.Options) { repository.Delete(option); } } if (page.AccessRules != null) { var rules = page.AccessRules.ToList(); rules.ForEach(page.RemoveRule); } if (page.MasterPages != null) { foreach (var master in page.MasterPages) { repository.Delete(master); } } // Delete page repository.Delete<Root.Models.Page>(page); // Commit unitOfWork.Commit(); var updatedSitemaps = new List<Sitemap>(); foreach (var node in updatedNodes) { Events.SitemapEvents.Instance.OnSitemapNodeUpdated(node); if (!updatedSitemaps.Contains(node.Sitemap)) { updatedSitemaps.Add(node.Sitemap); } } foreach (var node in deletedNodes) { Events.SitemapEvents.Instance.OnSitemapNodeDeleted(node); if (!updatedSitemaps.Contains(node.Sitemap)) { updatedSitemaps.Add(node.Sitemap); } } foreach (var updatedSitemap in updatedSitemaps) { Events.SitemapEvents.Instance.OnSitemapUpdated(updatedSitemap); } // Notifying about redirect created if (redirect != null) { Events.PageEvents.Instance.OnRedirectCreated(redirect); } // Notify about deleted page contents foreach (var deletedPageContent in deletedPageContents) { Events.PageEvents.Instance.OnPageContentDeleted(deletedPageContent); } // Notify about deleted html contents foreach (var htmlContent in htmlContentsToDelete) { Events.PageEvents.Instance.OnHtmlContentDeleted(htmlContent); } // Notifying, that page is deleted. Events.PageEvents.Instance.OnPageDeleted(page); if (sitemaps.Any(tuple => !tuple.Value) && messages != null) { // Some sitemaps where skipped, because user has no permission to edit. messages.AddSuccess(PagesGlobalization.DeletePage_SitemapSkipped_Message); } return true; }
protected ICommandContext GetMockedCommandContext(IMessagesIndicator messagesIndicator = null) { Mock<ICommandContext> commandContext = new Mock<ICommandContext>(); commandContext.Setup(f => f.Messages).Returns(() => messagesIndicator ?? GetMockedMessagesIndicator()); return commandContext.Object; }
/// <summary> /// Deletes the page. /// </summary> /// <param name="model">The model.</param> /// <param name="principal">The principal.</param> /// <param name="messages">The messages.</param> /// <returns> /// Delete result /// </returns> /// <exception cref="ConcurrentDataException"></exception> /// <exception cref="System.ComponentModel.DataAnnotations.ValidationException"> /// </exception> public bool DeletePage(DeletePageViewModel model, IPrincipal principal, IMessagesIndicator messages = null) { var languagesFuture = repository.AsQueryable <Language>().ToFuture(); var page = repository .AsQueryable <PageProperties>(p => p.Id == model.PageId) .FetchMany(p => p.PageContents) .ThenFetch(pc => pc.Content) .ToFuture() .FirstOne(); if (model.Version > 0 && page.Version != model.Version) { throw new ConcurrentDataException(page); } if (page.IsMasterPage && repository.AsQueryable <MasterPage>(mp => mp.Master == page).Any()) { var message = PagesGlobalization.DeletePageCommand_MasterPageHasChildren_Message; var logMessage = string.Format("Failed to delete page. Page is selected as master page. Id: {0} Url: {1}", page.Id, page.PageUrl); throw new ValidationException(() => message, logMessage); } var isRedirectInternal = false; if (!string.IsNullOrWhiteSpace(model.RedirectUrl)) { isRedirectInternal = urlService.ValidateInternalUrl(model.RedirectUrl); if (!isRedirectInternal && urlService.ValidateInternalUrl(urlService.FixUrl(model.RedirectUrl))) { isRedirectInternal = true; } if (isRedirectInternal) { model.RedirectUrl = urlService.FixUrl(model.RedirectUrl); } } if (model.UpdateSitemap) { accessControlService.DemandAccess(principal, RootModuleConstants.UserRoles.EditContent); } var sitemaps = new Dictionary <Sitemap, bool>(); var sitemapNodes = sitemapService.GetNodesByPage(page); if (model.UpdateSitemap) { sitemapNodes.Select(node => node.Sitemap) .Distinct() .ToList() .ForEach( sitemap => sitemaps.Add( sitemap, !cmsConfiguration.Security.AccessControlEnabled || accessControlService.GetAccessLevel(sitemap, principal) == AccessLevel.ReadWrite)); foreach (var node in sitemapNodes) { if (sitemaps[node.Sitemap] && node.ChildNodes.Count > 0) { var logMessage = string.Format("In {0} sitemap node {1} has {2} child nodes.", node.Sitemap.Id, node.Id, node.ChildNodes.Count); throw new ValidationException(() => PagesGlobalization.DeletePageCommand_SitemapNodeHasChildNodes_Message, logMessage); } } } unitOfWork.BeginTransaction(); // Update sitemap nodes IList <SitemapNode> updatedNodes = new List <SitemapNode>(); IList <SitemapNode> deletedNodes = new List <SitemapNode>(); UpdateSitemapNodes(model, page, sitemapNodes, sitemaps, languagesFuture.ToList(), updatedNodes, deletedNodes); Redirect redirect; if (!string.IsNullOrWhiteSpace(model.RedirectUrl)) { if (string.Equals(page.PageUrl, model.RedirectUrl, StringComparison.OrdinalIgnoreCase)) { var logMessage = string.Format("Circular redirect loop from url {0} to url {0}.", model.RedirectUrl); throw new ValidationException(() => PagesGlobalization.ValidatePageUrlCommand_SameUrlPath_Message, logMessage); } // Validate url if (!urlService.ValidateExternalUrl(model.RedirectUrl)) { var logMessage = string.Format("Invalid redirect url {0}.", model.RedirectUrl); throw new ValidationException(() => PagesGlobalization.ValidatePageUrlCommand_InvalidUrlPath_Message, logMessage); } string patternsValidationMessage; if (isRedirectInternal && !urlService.ValidateUrlPatterns(model.RedirectUrl, out patternsValidationMessage, PagesGlobalization.DeletePage_RedirectUrl_Name)) { var logMessage = string.Format("{0}. URL: {1}.", patternsValidationMessage, model.RedirectUrl); throw new ValidationException(() => patternsValidationMessage, logMessage); } redirect = redirectService.GetPageRedirect(page.PageUrl); if (redirect != null) { redirect.RedirectUrl = model.RedirectUrl; } else { redirect = redirectService.CreateRedirectEntity(page.PageUrl, model.RedirectUrl); } if (redirect != null) { repository.Save(redirect); } } else { redirect = null; } // Delete child entities. if (page.PageTags != null) { foreach (var pageTag in page.PageTags) { repository.Delete(pageTag); } } var deletedPageContents = new List <PageContent>(); var htmlContentsToDelete = new List <HtmlContent>(); if (page.PageContents != null) { foreach (var pageContent in page.PageContents) { // If content is HTML content, delete HTML content var htmlContent = pageContent.Content as HtmlContent; if (htmlContent != null) { var draft = pageContent.Content.History != null?pageContent.Content.History.FirstOrDefault(c => c.Status == ContentStatus.Draft) : null; if (draft != null) { repository.Delete(draft); } repository.Delete(htmlContent); htmlContentsToDelete.Add(htmlContent); } repository.Delete(pageContent); deletedPageContents.Add(pageContent); } } if (page.Options != null) { foreach (var option in page.Options) { repository.Delete(option); } } if (page.AccessRules != null) { var rules = page.AccessRules.ToList(); rules.ForEach(page.RemoveRule); } if (page.MasterPages != null) { foreach (var master in page.MasterPages) { repository.Delete(master); } } // Delete page repository.Delete <Root.Models.Page>(page); // Commit unitOfWork.Commit(); var updatedSitemaps = new List <Sitemap>(); foreach (var node in updatedNodes) { Events.SitemapEvents.Instance.OnSitemapNodeUpdated(node); if (!updatedSitemaps.Contains(node.Sitemap)) { updatedSitemaps.Add(node.Sitemap); } } foreach (var node in deletedNodes) { Events.SitemapEvents.Instance.OnSitemapNodeDeleted(node); if (!updatedSitemaps.Contains(node.Sitemap)) { updatedSitemaps.Add(node.Sitemap); } } foreach (var updatedSitemap in updatedSitemaps) { Events.SitemapEvents.Instance.OnSitemapUpdated(updatedSitemap); } // Notifying about redirect created if (redirect != null) { Events.PageEvents.Instance.OnRedirectCreated(redirect); } // Notify about deleted page contents foreach (var deletedPageContent in deletedPageContents) { Events.PageEvents.Instance.OnPageContentDeleted(deletedPageContent); } // Notify about deleted html contents foreach (var htmlContent in htmlContentsToDelete) { Events.PageEvents.Instance.OnHtmlContentDeleted(htmlContent); } // Notifying, that page is deleted. Events.PageEvents.Instance.OnPageDeleted(page); if (sitemaps.Any(tuple => !tuple.Value) && messages != null) { // Some sitemaps where skipped, because user has no permission to edit. messages.AddSuccess(PagesGlobalization.DeletePage_SitemapSkipped_Message); } return(true); }
/// <summary> /// Deletes the page. /// </summary> /// <param name="model">The model.</param> /// <param name="principal">The principal.</param> /// <param name="messages">The messages.</param> /// <returns> /// Delete result /// </returns> /// <exception cref="ConcurrentDataException"></exception> /// <exception cref="System.ComponentModel.DataAnnotations.ValidationException"> /// </exception> public bool DeletePage(DeletePageViewModel model, IPrincipal principal, IMessagesIndicator messages = null) { var page = repository.First<PageProperties>(model.PageId); if (model.Version > 0 && page.Version != model.Version) { throw new ConcurrentDataException(page); } if (page.IsMasterPage && repository.AsQueryable<MasterPage>(mp => mp.Master == page).Any()) { var message = PagesGlobalization.DeletePageCommand_MasterPageHasChildren_Message; var logMessage = string.Format("Failed to delete page. Page is selected as master page. Id: {0} Url: {1}", page.Id, page.PageUrl); throw new ValidationException(() => message, logMessage); } var isRedirectInternal = false; if (!string.IsNullOrWhiteSpace(model.RedirectUrl)) { isRedirectInternal = urlService.ValidateInternalUrl(model.RedirectUrl); if (!isRedirectInternal && urlService.ValidateInternalUrl(urlService.FixUrl(model.RedirectUrl))) { isRedirectInternal = true; } if (isRedirectInternal) { model.RedirectUrl = urlService.FixUrl(model.RedirectUrl); } } if (model.UpdateSitemap) { accessControlService.DemandAccess(principal, RootModuleConstants.UserRoles.EditContent); } var sitemaps = new Dictionary<Sitemap, bool>(); var sitemapNodes = sitemapService.GetNodesByPage(page); if (model.UpdateSitemap) { sitemapNodes.Select(node => node.Sitemap) .Distinct() .ToList() .ForEach( sitemap => sitemaps.Add( sitemap, !cmsConfiguration.Security.AccessControlEnabled || accessControlService.GetAccessLevel(sitemap, principal) == AccessLevel.ReadWrite)); foreach (var node in sitemapNodes) { if (sitemaps[node.Sitemap] && node.ChildNodes.Count > 0) { var logMessage = string.Format("In {0} sitemap node {1} has {2} child nodes.", node.Sitemap.Id, node.Id, node.ChildNodes.Count); throw new ValidationException(() => PagesGlobalization.DeletePageCommand_SitemapNodeHasChildNodes_Message, logMessage); } } } unitOfWork.BeginTransaction(); IList<SitemapNode> updatedNodes = new List<SitemapNode>(); IList<SitemapNode> deletedNodes = new List<SitemapNode>(); if (sitemapNodes != null) { // Archive sitemaps before update. sitemaps.Select(pair => pair.Key).ToList().ForEach(sitemap => sitemapService.ArchiveSitemap(sitemap.Id)); foreach (var node in sitemapNodes) { if (!node.IsDeleted) { if (model.UpdateSitemap && sitemaps[node.Sitemap]) { // Delete sitemap node. sitemapService.DeleteNode(node, ref deletedNodes); } else { // Unlink sitemap node. if (node.Page != null && node.Page.Id == page.Id) { node.Page = null; node.Title = node.UsePageTitleAsNodeTitle ? page.Title : node.Title; node.Url = page.PageUrl; node.UrlHash = page.PageUrlHash; repository.Save(node); updatedNodes.Add(node); } } } } } Redirect redirect; if (!string.IsNullOrWhiteSpace(model.RedirectUrl)) { if (string.Equals(page.PageUrl, model.RedirectUrl, StringComparison.OrdinalIgnoreCase)) { var logMessage = string.Format("Circular redirect loop from url {0} to url {0}.", model.RedirectUrl); throw new ValidationException(() => PagesGlobalization.ValidatePageUrlCommand_SameUrlPath_Message, logMessage); } // Validate url if (!urlService.ValidateExternalUrl(model.RedirectUrl)) { var logMessage = string.Format("Invalid redirect url {0}.", model.RedirectUrl); throw new ValidationException(() => PagesGlobalization.ValidatePageUrlCommand_InvalidUrlPath_Message, logMessage); } string patternsValidationMessage; if (isRedirectInternal && !urlService.ValidateUrlPatterns(model.RedirectUrl, out patternsValidationMessage, PagesGlobalization.DeletePage_RedirectUrl_Name)) { var logMessage = string.Format("{0}. URL: {1}.", patternsValidationMessage, model.RedirectUrl); throw new ValidationException(() => patternsValidationMessage, logMessage); } redirect = redirectService.GetPageRedirect(page.PageUrl); if (redirect != null) { redirect.RedirectUrl = model.RedirectUrl; } else { redirect = redirectService.CreateRedirectEntity(page.PageUrl, model.RedirectUrl); } if (redirect != null) { repository.Save(redirect); } } else { redirect = null; } // Delete child entities. if (page.PageTags != null) { foreach (var pageTag in page.PageTags) { repository.Delete(pageTag); } } var deletedPageContents = new List<PageContent>(); if (page.PageContents != null) { foreach (var pageContent in page.PageContents) { repository.Delete(pageContent); deletedPageContents.Add(pageContent); } } if (page.Options != null) { foreach (var option in page.Options) { repository.Delete(option); } } if (page.AccessRules != null) { var rules = page.AccessRules.ToList(); rules.ForEach(page.RemoveRule); } if (page.MasterPages != null) { foreach (var master in page.MasterPages) { repository.Delete(master); } } // Delete page repository.Delete<Root.Models.Page>(page); // Commit unitOfWork.Commit(); var updatedSitemaps = new List<Sitemap>(); foreach (var node in updatedNodes) { Events.SitemapEvents.Instance.OnSitemapNodeUpdated(node); if (!updatedSitemaps.Contains(node.Sitemap)) { updatedSitemaps.Add(node.Sitemap); } } foreach (var node in deletedNodes) { Events.SitemapEvents.Instance.OnSitemapNodeDeleted(node); if (!updatedSitemaps.Contains(node.Sitemap)) { updatedSitemaps.Add(node.Sitemap); } } foreach (var updatedSitemap in updatedSitemaps) { Events.SitemapEvents.Instance.OnSitemapUpdated(updatedSitemap); } // Notifying about redirect created if (redirect != null) { Events.PageEvents.Instance.OnRedirectCreated(redirect); } // Notify about deleted page contents foreach (var deletedPageContent in deletedPageContents) { Events.PageEvents.Instance.OnPageContentDeleted(deletedPageContent); } // Notifying, that page is deleted. Events.PageEvents.Instance.OnPageDeleted(page); if (sitemaps.Any(tuple => !tuple.Value) && messages != null) { // Some sitemaps where skipped, because user has no permission to edit. messages.AddSuccess(PagesGlobalization.DeletePage_SitemapSkipped_Message); } return true; }