private void UrlSlug_Update_Before(object sender, ObjectEventArgs e) { UrlSlugInfo UrlSlug = (UrlSlugInfo)e.Object; // save previous Url to 301 redirects // Get DocumentID var Document = DocumentHelper.GetDocuments() .WhereEquals("NodeID", UrlSlug.UrlSlugNodeID) .CombineWithDefaultCulture() .CombineWithAnyCulture() .Culture(UrlSlug.UrlSlugCultureCode) .FirstOrDefault(); var AlternativeUrl = AlternativeUrlInfoProvider.GetAlternativeUrls() .WhereEquals("AlternativeUrlUrl", UrlSlug.UrlSlug) .FirstOrDefault(); if (AlternativeUrl != null) { if (AlternativeUrl.AlternativeUrlDocumentID != Document.DocumentID) { // If Same NodeID, then replace the DocumentID with the current one as now the document has the culture code. var AlternativeUrlDocument = DocumentHelper.GetDocument(AlternativeUrl.AlternativeUrlDocumentID, new TreeProvider()); if (AlternativeUrlDocument.NodeID == UrlSlug.UrlSlugNodeID) { AlternativeUrl.AlternativeUrlDocumentID = Document.DocumentID; AlternativeUrlInfoProvider.SetAlternativeUrlInfo(AlternativeUrl); } else { // Log EventLogProvider.LogEvent("W", "DynamicRouting", "AlternativeUrlConflict", eventDescription: string.Format("Could not create Alternative Url '{0}' for Document {1} [{2}] because it already exists as an Alternative Url for Document {3} [{4}]", AlternativeUrl.AlternativeUrlUrl, Document.NodeAliasPath, Document.DocumentCulture, AlternativeUrlDocument.NodeAliasPath, AlternativeUrlDocument.DocumentCulture )); } } } else { // Create new one AlternativeUrl = new AlternativeUrlInfo() { AlternativeUrlDocumentID = Document.DocumentID, AlternativeUrlSiteID = Document.NodeSiteID, }; AlternativeUrl.SetValue("AlternativeUrlUrl", UrlSlug.UrlSlug); AlternativeUrlInfoProvider.SetAlternativeUrlInfo(AlternativeUrl); } }
private void UrlSlug_Update_Before_301Redirect(object sender, ObjectEventArgs e) { UrlSlugInfo UrlSlug = (UrlSlugInfo)e.Object; #region "Create Alternative Url of Previous Url" try { // Alternative Urls don't have the slash at the beginning string OriginalUrlSlugNoTrim = ValidationHelper.GetString(UrlSlug.GetOriginalValue("UrlSlug"), UrlSlug.UrlSlug); string OriginalUrlSlug = OriginalUrlSlugNoTrim.Trim('/'); // save previous Url to 301 redirects // Get DocumentID var Document = DocumentHelper.GetDocuments() .WhereEquals("NodeID", UrlSlug.UrlSlugNodeID) .CombineWithDefaultCulture() .CombineWithAnyCulture() .Culture(UrlSlug.UrlSlugCultureCode) .FirstOrDefault(); var AlternativeUrl = AlternativeUrlInfoProvider.GetAlternativeUrls() .WhereEquals("AlternativeUrlUrl", OriginalUrlSlug) .FirstOrDefault(); SiteInfo Site = SiteInfoProvider.GetSiteInfo(Document.NodeSiteID); string DefaultCulture = SettingsKeyInfoProvider.GetValue("CMSDefaultCultureCode", new SiteInfoIdentifier(Site.SiteName)); UrlSlugInfo CultureSiblingUrlSlug = UrlSlugInfoProvider.GetUrlSlugs() .WhereEquals("UrlSlug", OriginalUrlSlugNoTrim) .WhereEquals("UrlSlugNodeID", UrlSlug.UrlSlugNodeID) .WhereNotEquals("UrlSlugCultureCode", UrlSlug.UrlSlugCultureCode) .FirstOrDefault(); if (AlternativeUrl != null) { if (AlternativeUrl.AlternativeUrlDocumentID != Document.DocumentID) { // If Same NodeID, then make sure the DocumentID is of the one that is the DefaultCulture, if no DefaultCulture // Exists, then just ignore var AlternativeUrlDocument = DocumentHelper.GetDocument(AlternativeUrl.AlternativeUrlDocumentID, new TreeProvider()); // Log a warning if (AlternativeUrlDocument.NodeID != UrlSlug.UrlSlugNodeID) { EventLogProvider.LogEvent("W", "DynamicRouting", "AlternativeUrlConflict", eventDescription: string.Format("Conflict between Alternative Url '{0}' exists for Document {1} [{2}] which already exists as an Alternative Url for Document {3} [{4}].", AlternativeUrl.AlternativeUrlUrl, Document.NodeAliasPath, Document.DocumentCulture, AlternativeUrlDocument.NodeAliasPath, AlternativeUrlDocument.DocumentCulture )); } TreeNode DefaultLanguage = DocumentHelper.GetDocuments() .WhereEquals("NodeID", UrlSlug.UrlSlugNodeID) .Culture(DefaultCulture) .CombineWithDefaultCulture() .FirstOrDefault(); // Save only if there is no default language, or it is the default language, or if there is a default language adn it isn't it, that the Url doesn't match // Any of the default languages urls, as this often happens when you clone from an existing language and then save a new url. bool DefaultLanguageExists = DefaultLanguage != null; bool IsNotDefaultLanguage = DefaultLanguageExists && AlternativeUrl.AlternativeUrlDocumentID != DefaultLanguage.DocumentID; bool MatchesDefaultLang = false; if (DefaultLanguageExists && IsNotDefaultLanguage) { // See if the OriginalUrlSlug matches the default document, or one of it's alternates var DefaultLangUrlSlug = UrlSlugInfoProvider.GetUrlSlugs() .WhereEquals("UrlSlugNodeID", UrlSlug.UrlSlugNodeID) .WhereEquals("UrlSlugCultureCode", DefaultLanguage.DocumentCulture) .WhereEquals("UrlSlug", "/" + OriginalUrlSlug) .FirstOrDefault(); var DefaultLangAltUrl = AlternativeUrlInfoProvider.GetAlternativeUrls() .WhereEquals("AlternativeUrlDocumentID", DefaultLanguage.DocumentID) .WhereEquals("AlternativeUrlUrl", OriginalUrlSlug) .FirstOrDefault(); MatchesDefaultLang = DefaultLangUrlSlug != null || DefaultLangAltUrl != null; } if (!DefaultLanguageExists || !IsNotDefaultLanguage || (DefaultLanguageExists && IsNotDefaultLanguage && !MatchesDefaultLang)) { AlternativeUrl.AlternativeUrlDocumentID = DefaultLanguage.DocumentID; AlternativeUrlInfoProvider.SetAlternativeUrlInfo(AlternativeUrl); } } } // Create new one if there are no other Url Slugs with the same pattern for that node else if (CultureSiblingUrlSlug == null) { AlternativeUrl = new AlternativeUrlInfo() { AlternativeUrlDocumentID = Document.DocumentID, AlternativeUrlSiteID = Document.NodeSiteID, }; AlternativeUrl.SetValue("AlternativeUrlUrl", OriginalUrlSlug); // Save only if there is no default language, or it is the default language, or if there is a default language adn it isn't it, that the Url doesn't match // Any of the default languages urls, as this often happens when you clone from an existing language and then save a new url. TreeNode DefaultLanguage = DocumentHelper.GetDocuments() .WhereEquals("NodeID", UrlSlug.UrlSlugNodeID) .Culture(DefaultCulture) .FirstOrDefault(); bool DefaultLanguageExists = DefaultLanguage != null; bool IsNotDefaultLanguage = DefaultLanguageExists && AlternativeUrl.AlternativeUrlDocumentID != DefaultLanguage.DocumentID; bool MatchesDefaultLang = false; if (DefaultLanguageExists && IsNotDefaultLanguage) { // See if the OriginalUrlSlug matches the default document, or one of it's alternates var DefaultLangUrlSlug = UrlSlugInfoProvider.GetUrlSlugs() .WhereEquals("UrlSlugNodeID", UrlSlug.UrlSlugNodeID) .WhereEquals("UrlSlugCultureCode", DefaultLanguage.DocumentCulture) .WhereEquals("UrlSlug", "/" + OriginalUrlSlug) .FirstOrDefault(); var DefaultLangAltUrl = AlternativeUrlInfoProvider.GetAlternativeUrls() .WhereEquals("AlternativeUrlDocumentID", DefaultLanguage.DocumentID) .WhereEquals("AlternativeUrlUrl", OriginalUrlSlug) .FirstOrDefault(); MatchesDefaultLang = DefaultLangUrlSlug != null || DefaultLangAltUrl != null; } if (!DefaultLanguageExists || !IsNotDefaultLanguage || (DefaultLanguageExists && IsNotDefaultLanguage && !MatchesDefaultLang)) { try { AlternativeUrlInfoProvider.SetAlternativeUrlInfo(AlternativeUrl); } catch (InvalidAlternativeUrlException ex) { // Figure out what to do, it doesn't match the pattern constraints. } } } } catch (Exception ex) { LogErrorsInSeparateThread(ex, "DynamicRouting", "AlternateUrlError", $"Occurred on Url Slug Update for Url Slug {UrlSlug.UrlSlug} {UrlSlug.UrlSlugCultureCode}"); } #endregion #region "Remove any Alternative Url of the new Url for this node" try { // Alternative Urls don't have the slash at the beginning string NewUrlSlug = UrlSlug.UrlSlug.Trim('/'); // Check for any Alternative Urls for this node that match and remove // Get DocumentID var Document = DocumentHelper.GetDocuments() .WhereEquals("NodeID", UrlSlug.UrlSlugNodeID) .CombineWithDefaultCulture() .CombineWithAnyCulture() .Culture(UrlSlug.UrlSlugCultureCode) .FirstOrDefault(); var AllDocumentIDs = DocumentHelper.GetDocuments() .WhereEquals("NodeID", UrlSlug.UrlSlugNodeID) .AllCultures() .Columns("DocumentID") .Select(x => x.DocumentID).ToList(); // Delete any Alternate Urls for any of the culture variations of this node that match the new Url Slug, this is to prevent infinite redirect loops AlternativeUrlInfoProvider.GetAlternativeUrls() .WhereEquals("AlternativeUrlUrl", NewUrlSlug) .WhereIn("AlternativeUrlDocumentID", AllDocumentIDs) .ForEachObject(x => x.Delete()); SiteInfo Site = SiteInfoProvider.GetSiteInfo(Document.NodeSiteID); string DefaultCulture = SettingsKeyInfoProvider.GetValue("CMSDefaultCultureCode", new SiteInfoIdentifier(Site.SiteName)); var AltUrlsOnOtherNodes = AlternativeUrlInfoProvider.GetAlternativeUrls() .WhereEquals("AlternativeUrlUrl", NewUrlSlug) .WhereNotIn("AlternativeUrlDocumentID", AllDocumentIDs) .ToList(); // Add warning about conflict. if (AltUrlsOnOtherNodes.Count > 0) { EventLogProvider.LogEvent("W", "DynamicRouting", "AlternateUrlConflict", $"Another page with an alternate Url matching {UrlSlug.UrlSlug} was found, please adjust and correct."); } } catch (Exception ex) { LogErrorsInSeparateThread(ex, "DynamicRouting", "AlternateUrlError", $"Occurred on Url Slug Update for Url Slug {UrlSlug.UrlSlug} {UrlSlug.UrlSlugCultureCode}"); } #endregion }