From 3fce592689e3b53f332e35a47631c354e6052b24 Mon Sep 17 00:00:00 2001 From: Max Slabyak Date: Mon, 20 Jan 2014 14:51:56 -0500 Subject: [PATCH 1/5] stored strings in constants.cs added template support for versioned redirects, defined when querying for redirects) --- source/Constants.cs | 43 +++++++++++++++++++++++ source/RedirectModule.csproj | 1 + source/Redirects.cs | 66 ++++++++++++++++++++++++------------ 3 files changed, 88 insertions(+), 22 deletions(-) create mode 100644 source/Constants.cs diff --git a/source/Constants.cs b/source/Constants.cs new file mode 100644 index 0000000..b16c652 --- /dev/null +++ b/source/Constants.cs @@ -0,0 +1,43 @@ +using System.ComponentModel; + +namespace SharedSource.RedirectModule +{ + public static class Constants + { + public static class Paths + { + public static string VisitorIdentification = "/layouts/system/visitoridentification"; + } + + public static class Types + { + public static string RedirExactMatch = "SharedSource.RedirectModule.RedirectionType.ExactMatch"; + public static string RedirPatternMatch = "SharedSource.RedirectModule.RedirectionType.Pattern"; + public static string QueryExactMatch = "SharedSource.RedirectModule.QueryType.ExactMatch"; + public static string QueryPatternMatch = "SharedSource.RedirectModule.QueryType.PatternMatch"; + public static string RedirectRootNode = "SharedSource.RedirectModule.RedirectRootNode"; + + } + public static class Templates + { + public static string RedirectUrl = "Redirect Url"; + public static string VersionedRedirectUrl = "Versioned Redirect Url"; + public static string RedirectPattern = "Redirect Pattern"; + public static string VersionedRedirectPattern = "Versioned Redirect Pattern"; + } + public static class Fields + { + public static string RequestedUrl = "Requested Url"; + public static string RedirectTo = "redirect to"; + public static string RequestedExpression = "requested expression"; + public static string SourceItem = "souce item"; + public static string ItemProcessRedirects = "Items Which Always Process Redirects"; + } + + public static class Settings + { + + } + + } +} diff --git a/source/RedirectModule.csproj b/source/RedirectModule.csproj index 3946eff..40cdad9 100644 --- a/source/RedirectModule.csproj +++ b/source/RedirectModule.csproj @@ -46,6 +46,7 @@ + diff --git a/source/Redirects.cs b/source/Redirects.cs index aca9a86..483c67e 100644 --- a/source/Redirects.cs +++ b/source/Redirects.cs @@ -26,7 +26,7 @@ public override void Process(HttpRequestArgs args) // This processer is added to the pipeline after the Sitecore Item Resolver. We want to skip everything if the item resolved successfully. // Also, skip processing for the visitor identification items related to DMS. Assert.ArgumentNotNull(args, "args"); - if ((Context.Item == null || AllowRedirectsOnFoundItem(Context.Database)) && args.LocalPath != "/layouts/system/visitoridentification" && Context.Database != null) + if ((Context.Item == null || AllowRedirectsOnFoundItem(Context.Database)) && args.LocalPath != Constants.Paths.VisitorIdentification && Context.Database != null) { // Grab the actual requested path for use in both the item and pattern match sections. var requestedUrl = HttpContext.Current.Request.Url.ToString(); @@ -35,15 +35,15 @@ public override void Process(HttpRequestArgs args) var db = Context.Database; // First, we check for exact matches because those take priority over pattern matches. - if (Sitecore.Configuration.Settings.GetBoolSetting("SharedSource.RedirectModule.RedirectionType.ExactMatch", true)) + if (Sitecore.Configuration.Settings.GetBoolSetting(Constants.Types.RedirExactMatch, true)) { // Loop through the exact match entries to look for a match. - foreach (Item possibleRedirect in GetRedirects(db, "Redirect Url", Sitecore.Configuration.Settings.GetSetting("SharedSource.RedirectModule.QueryType.ExactMatch"))) + foreach (Item possibleRedirect in GetRedirects(db, Constants.Templates.RedirectUrl, Constants.Templates.VersionedRedirectUrl, Sitecore.Configuration.Settings.GetSetting(Constants.Types.QueryExactMatch))) { - if (requestedUrl.Equals(possibleRedirect["Requested Url"], StringComparison.OrdinalIgnoreCase) || - requestedPath.Equals(possibleRedirect["Requested Url"], StringComparison.OrdinalIgnoreCase)) + if (requestedUrl.Equals(possibleRedirect[Constants.Fields.RequestedUrl], StringComparison.OrdinalIgnoreCase) || + requestedPath.Equals(possibleRedirect[Constants.Fields.RequestedUrl], StringComparison.OrdinalIgnoreCase)) { - var redirectToItem = db.GetItem(ID.Parse(possibleRedirect.Fields["redirect to"])); + var redirectToItem = db.GetItem(ID.Parse(possibleRedirect.Fields[Constants.Fields.RedirectTo])); if (redirectToItem != null) { SendResponse(redirectToItem, HttpContext.Current.Request.Url.Query, args); @@ -53,22 +53,22 @@ public override void Process(HttpRequestArgs args) } // Second, we check for pattern matches because we didn't hit on an exact match. - if (Sitecore.Configuration.Settings.GetBoolSetting("SharedSource.RedirectModule.RedirectionType.Pattern", true)) + if (Sitecore.Configuration.Settings.GetBoolSetting(Constants.Types.RedirPatternMatch, true)) { // Loop through the pattern match items to find a match - foreach (Item possibleRedirectPattern in GetRedirects(db, "Redirect Pattern", Sitecore.Configuration.Settings.GetSetting("SharedSource.RedirectModule.QueryType.ExactMatch"))) + foreach (Item possibleRedirectPattern in GetRedirects(db, Constants.Templates.RedirectPattern, Constants.Templates.VersionedRedirectPattern, Sitecore.Configuration.Settings.GetSetting("SharedSource.RedirectModule.QueryType.ExactMatch"))) { var redirectPath = string.Empty; - if (Regex.IsMatch(requestedUrl, possibleRedirectPattern["requested expression"], RegexOptions.IgnoreCase)) + if (Regex.IsMatch(requestedUrl, possibleRedirectPattern[Constants.Fields.RequestedExpression], RegexOptions.IgnoreCase)) { - redirectPath = Regex.Replace(requestedUrl, possibleRedirectPattern["requested expression"], - possibleRedirectPattern["source item"], RegexOptions.IgnoreCase); + redirectPath = Regex.Replace(requestedUrl, possibleRedirectPattern[Constants.Fields.RequestedExpression], + possibleRedirectPattern[Constants.Fields.SourceItem], RegexOptions.IgnoreCase); } - else if (Regex.IsMatch(requestedPathAndQuery, possibleRedirectPattern["requested expression"], RegexOptions.IgnoreCase)) + else if (Regex.IsMatch(requestedPathAndQuery, possibleRedirectPattern[Constants.Fields.RequestedExpression], RegexOptions.IgnoreCase)) { redirectPath = Regex.Replace(requestedPathAndQuery, - possibleRedirectPattern["requested expression"], - possibleRedirectPattern["source item"], RegexOptions.IgnoreCase); + possibleRedirectPattern[Constants.Fields.RequestedExpression], + possibleRedirectPattern[Constants.Fields.SourceItem], RegexOptions.IgnoreCase); } if (string.IsNullOrEmpty(redirectPath)) continue; @@ -100,36 +100,58 @@ private static bool AllowRedirectsOnFoundItem(Database db) var redirectFolderRoot = db.SelectSingleItem(redirectRoot); if (redirectFolderRoot == null) return false; - var allowRedirectsOnItemIDs = redirectFolderRoot["Items Which Always Process Redirects"]; + var allowRedirectsOnItemIDs = redirectFolderRoot[Constants.Fields.ItemProcessRedirects]; return allowRedirectsOnItemIDs != null && allowRedirectsOnItemIDs.Contains(Context.Item.ID.ToString()); } /// - /// This method return all of the possible matches for either the exact matches or the pattern matches + /// This method return all of the possible matches for either the exact matches or the pattern matches. + /// Note: Because Fast Query does not guarantee to return items in the current language context + /// (e.g. while in US/English, results may include other language items as well, even if the + /// US/EN langauge has no active versions. /// - private static IEnumerable GetRedirects(Database db, string templateName, string queryType) + private static IEnumerable GetRedirects(Database db, string templateName, string versionedTemplateName, string queryType) { // Based off the config file, we can run different types of queries. IEnumerable ret = null; - var redirectRoot = Sitecore.Configuration.Settings.GetSetting("SharedSource.RedirectModule.RedirectRootNode"); + var redirectRoot = Sitecore.Configuration.Settings.GetSetting(Constants.Types.RedirectRootNode); switch (queryType) { case "fast": // fast query { - ret = db.SelectItems(String.Format("fast:{0}//*[@@templatename='{1}']", redirectRoot, templateName)); - break; + //process shared template items + ret = db.SelectItems(String.Format("fast:{0}//*[@@templatename='{1}']", redirectRoot, templateName)); + + //because fast query requires to check for active versions in the current language + //run a separate query for versioned items to see if this is even necessary. + //if only shared templates exist in System/Modules, this step is extraneous and unnecessary. + IEnumerable versionedItems = db.SelectItems(String.Format("fast:{0}//*[@@templatename='{1}']", redirectRoot, versionedTemplateName)); + if (versionedItems != null) + { + versionedItems = + versionedItems.Where(i => + { + var firstOrDefault = i.Languages.FirstOrDefault(); + return firstOrDefault != null && (i.Versions.Count > 0 && firstOrDefault.Name == Context.Language.Name); + }); + + if (versionedItems.FirstOrDefault() != null) + ret = ret.Union(versionedItems); + } + + break; } case "query": // Sitecore query { - ret = db.SelectItems(String.Format("{0}//*[@@templatename='{1}']", redirectRoot, templateName)); + ret = db.SelectItems(String.Format("{0}//*[@@templatename='{1}' or @@templatename='{2}]", redirectRoot, templateName,versionedTemplateName)); break; } default: // API LINQ { Item redirectFolderRoot = db.SelectSingleItem(redirectRoot); if (redirectFolderRoot != null) - ret = redirectFolderRoot.Axes.GetDescendants().Where(i => i.TemplateName == templateName); + ret = redirectFolderRoot.Axes.GetDescendants().Where(i => (i.TemplateName == templateName) || (i.TemplateName == versionedTemplateName)); break; } } From 6439c186848e03c7b0f9dc0ceb335677d3bfbfb3 Mon Sep 17 00:00:00 2001 From: Max Slabyak Date: Mon, 20 Jan 2014 21:43:08 -0500 Subject: [PATCH 2/5] fixed constant references --- source/Constants.cs | 5 +- source/Redirects.cs | 292 ++++++++++++++++++++++---------------------- 2 files changed, 150 insertions(+), 147 deletions(-) diff --git a/source/Constants.cs b/source/Constants.cs index b16c652..c7f2dbf 100644 --- a/source/Constants.cs +++ b/source/Constants.cs @@ -7,10 +7,11 @@ public static class Constants public static class Paths { public static string VisitorIdentification = "/layouts/system/visitoridentification"; + public static string MediaLibrary = "/sitecore/media library/"; } public static class Types - { + { public static string RedirExactMatch = "SharedSource.RedirectModule.RedirectionType.ExactMatch"; public static string RedirPatternMatch = "SharedSource.RedirectModule.RedirectionType.Pattern"; public static string QueryExactMatch = "SharedSource.RedirectModule.QueryType.ExactMatch"; @@ -30,7 +31,7 @@ public static class Fields public static string RequestedUrl = "Requested Url"; public static string RedirectTo = "redirect to"; public static string RequestedExpression = "requested expression"; - public static string SourceItem = "souce item"; + public static string SourceItem = "source item"; public static string ItemProcessRedirects = "Items Which Always Process Redirects"; } diff --git a/source/Redirects.cs b/source/Redirects.cs index 483c67e..12ae893 100644 --- a/source/Redirects.cs +++ b/source/Redirects.cs @@ -13,168 +13,170 @@ namespace SharedSource.RedirectModule { - /// - /// Redirection Module which handles 301 redirects. Both exact matches and regular expression pattern matches are supported. - /// - public class Redirects : HttpRequestProcessor - { - /// - /// The main method for the processor. It simply overrides the Process method. - /// - public override void Process(HttpRequestArgs args) - { - // This processer is added to the pipeline after the Sitecore Item Resolver. We want to skip everything if the item resolved successfully. - // Also, skip processing for the visitor identification items related to DMS. - Assert.ArgumentNotNull(args, "args"); - if ((Context.Item == null || AllowRedirectsOnFoundItem(Context.Database)) && args.LocalPath != Constants.Paths.VisitorIdentification && Context.Database != null) - { - // Grab the actual requested path for use in both the item and pattern match sections. - var requestedUrl = HttpContext.Current.Request.Url.ToString(); - var requestedPath = HttpContext.Current.Request.Url.AbsolutePath; - var requestedPathAndQuery = HttpContext.Current.Request.Url.PathAndQuery; - var db = Context.Database; + /// + /// Redirection Module which handles 301 redirects. Both exact matches and regular expression pattern matches are supported. + /// + public class Redirects : HttpRequestProcessor + { + /// + /// The main method for the processor. It simply overrides the Process method. + /// + public override void Process(HttpRequestArgs args) + { + // This processer is added to the pipeline after the Sitecore Item Resolver. We want to skip everything if the item resolved successfully. + // Also, skip processing for the visitor identification items related to DMS. + Assert.ArgumentNotNull(args, "args"); + if ((Context.Item == null || AllowRedirectsOnFoundItem(Context.Database)) && args.LocalPath != Constants.Paths.VisitorIdentification && Context.Database != null) + { + // Grab the actual requested path for use in both the item and pattern match sections. + var requestedUrl = HttpContext.Current.Request.Url.ToString(); + var requestedPath = HttpContext.Current.Request.Url.AbsolutePath; + var requestedPathAndQuery = HttpContext.Current.Request.Url.PathAndQuery; + var db = Context.Database; - // First, we check for exact matches because those take priority over pattern matches. - if (Sitecore.Configuration.Settings.GetBoolSetting(Constants.Types.RedirExactMatch, true)) - { - // Loop through the exact match entries to look for a match. - foreach (Item possibleRedirect in GetRedirects(db, Constants.Templates.RedirectUrl, Constants.Templates.VersionedRedirectUrl, Sitecore.Configuration.Settings.GetSetting(Constants.Types.QueryExactMatch))) - { - if (requestedUrl.Equals(possibleRedirect[Constants.Fields.RequestedUrl], StringComparison.OrdinalIgnoreCase) || + // First, we check for exact matches because those take priority over pattern matches. + if (Sitecore.Configuration.Settings.GetBoolSetting(Constants.Types.RedirExactMatch, true)) + { + // Loop through the exact match entries to look for a match. + foreach (Item possibleRedirect in GetRedirects(db, Constants.Templates.RedirectUrl, Constants.Templates.VersionedRedirectPattern, Sitecore.Configuration.Settings.GetSetting(Constants.Types.QueryExactMatch))) + { + if (requestedUrl.Equals(possibleRedirect[Constants.Fields.RequestedUrl], StringComparison.OrdinalIgnoreCase) || requestedPath.Equals(possibleRedirect[Constants.Fields.RequestedUrl], StringComparison.OrdinalIgnoreCase)) - { - var redirectToItem = db.GetItem(ID.Parse(possibleRedirect.Fields[Constants.Fields.RedirectTo])); - if (redirectToItem != null) - { - SendResponse(redirectToItem, HttpContext.Current.Request.Url.Query, args); - } - } - } - } + { + var redirectToItem = db.GetItem(ID.Parse(possibleRedirect.Fields[Constants.Fields.RedirectTo])); + if (redirectToItem != null) + { + SendResponse(redirectToItem, HttpContext.Current.Request.Url.Query, args); + } + } + } + } - // Second, we check for pattern matches because we didn't hit on an exact match. - if (Sitecore.Configuration.Settings.GetBoolSetting(Constants.Types.RedirPatternMatch, true)) - { - // Loop through the pattern match items to find a match - foreach (Item possibleRedirectPattern in GetRedirects(db, Constants.Templates.RedirectPattern, Constants.Templates.VersionedRedirectPattern, Sitecore.Configuration.Settings.GetSetting("SharedSource.RedirectModule.QueryType.ExactMatch"))) - { - var redirectPath = string.Empty; - if (Regex.IsMatch(requestedUrl, possibleRedirectPattern[Constants.Fields.RequestedExpression], RegexOptions.IgnoreCase)) - { + // Second, we check for pattern matches because we didn't hit on an exact match. + if (Sitecore.Configuration.Settings.GetBoolSetting(Constants.Types.RedirPatternMatch, true)) + { + // Loop through the pattern match items to find a match + foreach (Item possibleRedirectPattern in GetRedirects(db, Constants.Templates.RedirectPattern, Constants.Templates.VersionedRedirectPattern, Sitecore.Configuration.Settings.GetSetting(Constants.Types.QueryExactMatch))) + { + var redirectPath = string.Empty; + if (Regex.IsMatch(requestedUrl, possibleRedirectPattern[Constants.Fields.RequestedExpression], RegexOptions.IgnoreCase)) + { redirectPath = Regex.Replace(requestedUrl, possibleRedirectPattern[Constants.Fields.RequestedExpression], - possibleRedirectPattern[Constants.Fields.SourceItem], RegexOptions.IgnoreCase); - } + possibleRedirectPattern[Constants.Fields.SourceItem], RegexOptions.IgnoreCase); + } else if (Regex.IsMatch(requestedPathAndQuery, possibleRedirectPattern[Constants.Fields.RequestedExpression], RegexOptions.IgnoreCase)) - { - redirectPath = Regex.Replace(requestedPathAndQuery, + { + redirectPath = Regex.Replace(requestedPathAndQuery, possibleRedirectPattern[Constants.Fields.RequestedExpression], possibleRedirectPattern[Constants.Fields.SourceItem], RegexOptions.IgnoreCase); - } - if (string.IsNullOrEmpty(redirectPath)) continue; + } + if (string.IsNullOrEmpty(redirectPath)) continue; - // Query portion gets in the way of getting the sitecore item. - var pathAndQuery = redirectPath.Split('?'); - var path = pathAndQuery[0]; - if (LinkManager.Provider != null && - LinkManager.Provider.GetDefaultUrlOptions() != null && - LinkManager.Provider.GetDefaultUrlOptions().EncodeNames) - { - path = MainUtil.DecodeName(path); - } - var redirectToItem = db.GetItem(path); - if (redirectToItem != null) - { - var query = pathAndQuery.Length > 1 ? "?" + pathAndQuery[1] : ""; - SendResponse(redirectToItem, query, args); - } - } - } - } - } + // Query portion gets in the way of getting the sitecore item. + var pathAndQuery = redirectPath.Split('?'); + var path = pathAndQuery[0]; + if (LinkManager.Provider != null && + LinkManager.Provider.GetDefaultUrlOptions() != null && + LinkManager.Provider.GetDefaultUrlOptions().EncodeNames) + { + path = MainUtil.DecodeName(path); + } + var redirectToItem = db.GetItem(path); + if (redirectToItem != null) + { + var query = pathAndQuery.Length > 1 ? "?" + pathAndQuery[1] : ""; + SendResponse(redirectToItem, query, args); + } + } + } + } + } - private static bool AllowRedirectsOnFoundItem(Database db) - { - if (db == null) - return false; - var redirectRoot = Sitecore.Configuration.Settings.GetSetting("SharedSource.RedirectModule.RedirectRootNode"); - var redirectFolderRoot = db.SelectSingleItem(redirectRoot); - if (redirectFolderRoot == null) - return false; - var allowRedirectsOnItemIDs = redirectFolderRoot[Constants.Fields.ItemProcessRedirects]; - return allowRedirectsOnItemIDs != null && - allowRedirectsOnItemIDs.Contains(Context.Item.ID.ToString()); - } + private static bool AllowRedirectsOnFoundItem(Database db) + { + if (db == null) + return false; + var redirectRoot = Sitecore.Configuration.Settings.GetSetting(Constants.Types.RedirectRootNode); + var redirectFolderRoot = db.SelectSingleItem(redirectRoot); + if (redirectFolderRoot == null) + return false; + var allowRedirectsOnItemIDs = redirectFolderRoot[Constants.Fields.ItemProcessRedirects]; + return allowRedirectsOnItemIDs != null && + allowRedirectsOnItemIDs.Contains(Context.Item.ID.ToString()); + } - /// - /// This method return all of the possible matches for either the exact matches or the pattern matches. - /// Note: Because Fast Query does not guarantee to return items in the current language context + /// + /// This method return all of the possible matches for either the exact matches or the pattern matches + /// Note: Because Fast Query does not guarantee to return items in the current language context /// (e.g. while in US/English, results may include other language items as well, even if the - /// US/EN langauge has no active versions. - /// - private static IEnumerable GetRedirects(Database db, string templateName, string versionedTemplateName, string queryType) - { - // Based off the config file, we can run different types of queries. - IEnumerable ret = null; - var redirectRoot = Sitecore.Configuration.Settings.GetSetting(Constants.Types.RedirectRootNode); - switch (queryType) - { - case "fast": // fast query - { - //process shared template items - ret = db.SelectItems(String.Format("fast:{0}//*[@@templatename='{1}']", redirectRoot, templateName)); + /// US/EN language has no active versions), an additional LINQ query has to be run to filter for language. + /// Choose your query type appropriately. + /// + private static IEnumerable GetRedirects(Database db, string templateName, string versionedTemplateName, string queryType) + { + // Based off the config file, we can run different types of queries. + IEnumerable ret = null; + var redirectRoot = Sitecore.Configuration.Settings.GetSetting(Constants.Types.RedirectRootNode); + switch (queryType) + { + case "fast": // fast query + { + //process shared template items + ret = db.SelectItems(String.Format("fast:{0}//*[@@templatename='{1}']", redirectRoot, templateName)); + + //because fast query requires to check for active versions in the current language + //run a separate query for versioned items to see if this is even necessary. + //if only shared templates exist in System/Modules, this step is extraneous and unnecessary. + IEnumerable versionedItems = db.SelectItems(String.Format("fast:{0}//*[@@templatename='{1}']", redirectRoot, versionedTemplateName)); + if (versionedItems != null) + { + versionedItems = + versionedItems.Where(i => + { + var firstOrDefault = i.Languages.FirstOrDefault(); + return firstOrDefault != null && (i.Versions.Count > 0 && firstOrDefault.Name == Context.Language.Name); + }); - //because fast query requires to check for active versions in the current language - //run a separate query for versioned items to see if this is even necessary. - //if only shared templates exist in System/Modules, this step is extraneous and unnecessary. - IEnumerable versionedItems = db.SelectItems(String.Format("fast:{0}//*[@@templatename='{1}']", redirectRoot, versionedTemplateName)); - if (versionedItems != null) - { - versionedItems = - versionedItems.Where(i => - { - var firstOrDefault = i.Languages.FirstOrDefault(); - return firstOrDefault != null && (i.Versions.Count > 0 && firstOrDefault.Name == Context.Language.Name); - }); - if (versionedItems.FirstOrDefault() != null) - ret = ret.Union(versionedItems); - } - - break; - } - case "query": // Sitecore query - { - ret = db.SelectItems(String.Format("{0}//*[@@templatename='{1}' or @@templatename='{2}]", redirectRoot, templateName,versionedTemplateName)); - break; - } - default: // API LINQ - { - Item redirectFolderRoot = db.SelectSingleItem(redirectRoot); - if (redirectFolderRoot != null) - ret = redirectFolderRoot.Axes.GetDescendants().Where(i => (i.TemplateName == templateName) || (i.TemplateName == versionedTemplateName)); - break; - } - } + if (versionedItems.FirstOrDefault() != null) + ret = ret.Union(versionedItems); + } - // make sure to return an empty list instead of null - return ret ?? new Item[0]; - } + break; + } + case "query": // Sitecore query + { + ret = db.SelectItems(String.Format("{0}//*[@@templatename='{1}' or @@templatename='{2}']", redirectRoot, templateName, versionedTemplateName)); + break; + } + default: // API LINQ + { + Item redirectFolderRoot = db.SelectSingleItem(redirectRoot); + if (redirectFolderRoot != null) + ret = redirectFolderRoot.Axes.GetDescendants().Where(i => i.TemplateName == templateName || i.TemplateName == versionedTemplateName); + break; + } + } - /// - /// Once a match is found and we have a Sitecore Item, we can send the 301 response. - /// - private static void SendResponse(Item redirectToItem, string queryString, HttpRequestArgs args) - { - var redirectToUrl = GetRedirectToUrl(redirectToItem); - args.Context.Response.Status = "301 Moved Permanently"; - args.Context.Response.StatusCode = 301; - args.Context.Response.AddHeader("Location", redirectToUrl + queryString); - args.Context.Response.End(); - } + // make sure to return an empty list instead of null + return ret ?? new Item[0]; + } + + /// + /// Once a match is found and we have a Sitecore Item, we can send the 301 response. + /// + private static void SendResponse(Item redirectToItem, string queryString, HttpRequestArgs args) + { + var redirectToUrl = GetRedirectToUrl(redirectToItem); + args.Context.Response.Status = "301 Moved Permanently"; + args.Context.Response.StatusCode = 301; + args.Context.Response.AddHeader("Location", redirectToUrl + queryString); + args.Context.Response.End(); + } private static string GetRedirectToUrl(Item redirectToItem) { - if (redirectToItem.Paths.Path.StartsWith("/sitecore/media library/")) + if (redirectToItem.Paths.Path.StartsWith(Constants.Paths.MediaLibrary)) { var mediaItem = (MediaItem)redirectToItem; var mediaUrl = MediaManager.GetMediaUrl(mediaItem); @@ -184,6 +186,6 @@ private static string GetRedirectToUrl(Item redirectToItem) return LinkManager.GetItemUrl(redirectToItem); } - } + } } From 98366c9561a732c07622fc99fa141b4db6377443 Mon Sep 17 00:00:00 2001 From: Max Slabyak Date: Mon, 20 Jan 2014 23:00:45 -0500 Subject: [PATCH 3/5] fixed fast query context language lookup --- source/Redirects.cs | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/source/Redirects.cs b/source/Redirects.cs index 12ae893..070005c 100644 --- a/source/Redirects.cs +++ b/source/Redirects.cs @@ -38,7 +38,7 @@ public override void Process(HttpRequestArgs args) if (Sitecore.Configuration.Settings.GetBoolSetting(Constants.Types.RedirExactMatch, true)) { // Loop through the exact match entries to look for a match. - foreach (Item possibleRedirect in GetRedirects(db, Constants.Templates.RedirectUrl, Constants.Templates.VersionedRedirectPattern, Sitecore.Configuration.Settings.GetSetting(Constants.Types.QueryExactMatch))) + foreach (Item possibleRedirect in GetRedirects(db, Constants.Templates.RedirectUrl, Constants.Templates.VersionedRedirectUrl, Sitecore.Configuration.Settings.GetSetting(Constants.Types.QueryExactMatch))) { if (requestedUrl.Equals(possibleRedirect[Constants.Fields.RequestedUrl], StringComparison.OrdinalIgnoreCase) || requestedPath.Equals(possibleRedirect[Constants.Fields.RequestedUrl], StringComparison.OrdinalIgnoreCase)) @@ -131,12 +131,8 @@ private static IEnumerable GetRedirects(Database db, string templateName, if (versionedItems != null) { versionedItems = - versionedItems.Where(i => - { - var firstOrDefault = i.Languages.FirstOrDefault(); - return firstOrDefault != null && (i.Versions.Count > 0 && firstOrDefault.Name == Context.Language.Name); - }); - + versionedItems.Where(i => i.Versions.Count > 0); + if (versionedItems.FirstOrDefault() != null) ret = ret.Union(versionedItems); From 8718f93b9341b609a82250b4ec711f94ad651f82 Mon Sep 17 00:00:00 2001 From: Max Slabyak Date: Mon, 20 Jan 2014 23:09:05 -0500 Subject: [PATCH 4/5] updating class name in constants --- source/Constants.cs | 7 +------ source/Redirects.cs | 12 ++++++------ 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/source/Constants.cs b/source/Constants.cs index c7f2dbf..7689975 100644 --- a/source/Constants.cs +++ b/source/Constants.cs @@ -10,7 +10,7 @@ public static class Paths public static string MediaLibrary = "/sitecore/media library/"; } - public static class Types + public static class Settings { public static string RedirExactMatch = "SharedSource.RedirectModule.RedirectionType.ExactMatch"; public static string RedirPatternMatch = "SharedSource.RedirectModule.RedirectionType.Pattern"; @@ -35,10 +35,5 @@ public static class Fields public static string ItemProcessRedirects = "Items Which Always Process Redirects"; } - public static class Settings - { - - } - } } diff --git a/source/Redirects.cs b/source/Redirects.cs index 070005c..6745a11 100644 --- a/source/Redirects.cs +++ b/source/Redirects.cs @@ -35,10 +35,10 @@ public override void Process(HttpRequestArgs args) var db = Context.Database; // First, we check for exact matches because those take priority over pattern matches. - if (Sitecore.Configuration.Settings.GetBoolSetting(Constants.Types.RedirExactMatch, true)) + if (Sitecore.Configuration.Settings.GetBoolSetting(Constants.Settings.RedirExactMatch, true)) { // Loop through the exact match entries to look for a match. - foreach (Item possibleRedirect in GetRedirects(db, Constants.Templates.RedirectUrl, Constants.Templates.VersionedRedirectUrl, Sitecore.Configuration.Settings.GetSetting(Constants.Types.QueryExactMatch))) + foreach (Item possibleRedirect in GetRedirects(db, Constants.Templates.RedirectUrl, Constants.Templates.VersionedRedirectUrl, Sitecore.Configuration.Settings.GetSetting(Constants.Settings.QueryExactMatch))) { if (requestedUrl.Equals(possibleRedirect[Constants.Fields.RequestedUrl], StringComparison.OrdinalIgnoreCase) || requestedPath.Equals(possibleRedirect[Constants.Fields.RequestedUrl], StringComparison.OrdinalIgnoreCase)) @@ -53,10 +53,10 @@ public override void Process(HttpRequestArgs args) } // Second, we check for pattern matches because we didn't hit on an exact match. - if (Sitecore.Configuration.Settings.GetBoolSetting(Constants.Types.RedirPatternMatch, true)) + if (Sitecore.Configuration.Settings.GetBoolSetting(Constants.Settings.RedirPatternMatch, true)) { // Loop through the pattern match items to find a match - foreach (Item possibleRedirectPattern in GetRedirects(db, Constants.Templates.RedirectPattern, Constants.Templates.VersionedRedirectPattern, Sitecore.Configuration.Settings.GetSetting(Constants.Types.QueryExactMatch))) + foreach (Item possibleRedirectPattern in GetRedirects(db, Constants.Templates.RedirectPattern, Constants.Templates.VersionedRedirectPattern, Sitecore.Configuration.Settings.GetSetting(Constants.Settings.QueryExactMatch))) { var redirectPath = string.Empty; if (Regex.IsMatch(requestedUrl, possibleRedirectPattern[Constants.Fields.RequestedExpression], RegexOptions.IgnoreCase)) @@ -96,7 +96,7 @@ private static bool AllowRedirectsOnFoundItem(Database db) { if (db == null) return false; - var redirectRoot = Sitecore.Configuration.Settings.GetSetting(Constants.Types.RedirectRootNode); + var redirectRoot = Sitecore.Configuration.Settings.GetSetting(Constants.Settings.RedirectRootNode); var redirectFolderRoot = db.SelectSingleItem(redirectRoot); if (redirectFolderRoot == null) return false; @@ -116,7 +116,7 @@ private static IEnumerable GetRedirects(Database db, string templateName, { // Based off the config file, we can run different types of queries. IEnumerable ret = null; - var redirectRoot = Sitecore.Configuration.Settings.GetSetting(Constants.Types.RedirectRootNode); + var redirectRoot = Sitecore.Configuration.Settings.GetSetting(Constants.Settings.RedirectRootNode); switch (queryType) { case "fast": // fast query From 06838f8d25bb5eabe882a42c6baef661dbb71bd9 Mon Sep 17 00:00:00 2001 From: Max Slabyak Date: Tue, 21 Jan 2014 11:20:49 -0500 Subject: [PATCH 5/5] cleaned up LINQ for brevity in GetRedirects() --- source/Redirects.cs | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/source/Redirects.cs b/source/Redirects.cs index 6745a11..af0aef6 100644 --- a/source/Redirects.cs +++ b/source/Redirects.cs @@ -128,16 +128,13 @@ private static IEnumerable GetRedirects(Database db, string templateName, //run a separate query for versioned items to see if this is even necessary. //if only shared templates exist in System/Modules, this step is extraneous and unnecessary. IEnumerable versionedItems = db.SelectItems(String.Format("fast:{0}//*[@@templatename='{1}']", redirectRoot, versionedTemplateName)); - if (versionedItems != null) - { - versionedItems = - versionedItems.Where(i => i.Versions.Count > 0); - - if (versionedItems.FirstOrDefault() != null) - ret = ret.Union(versionedItems); - } + //if active versions of items in the current context exist, union the two IEnumerable lists together. + ret = versionedItems.Any(i => i.Versions.Count > 0) + ? ret.Union(versionedItems.Where(i => i.Versions.Count > 0)) + : ret; + break; } case "query": // Sitecore query