public override bool CheckForRedirect(int tabId, int portalid, string httpAlias, Uri requestUri, NameValueCollection queryStringCol, FriendlyUrlOptions options, out string redirectLocation, ref List <string> messages) { redirectLocation = null; return(false); }
public void ValidatePageUrlSettings_CleanNameForUrl_URLArgumentShouldBeLocalPath(string inputUrl, string expected) { // Arrange var modified = false; var tab = new TabInfo(); var portalSettings = new PortalSettings(); var friendlyOptions = new FriendlyUrlOptions(); _urlRewriterUtilsWrapperMock.Setup(d => d.GetExtendOptionsForURLs(It.IsAny <int>())).Returns(friendlyOptions); _friendlyUrlWrapperMock.Setup(d => d.CleanNameForUrl(It.IsAny <string>(), friendlyOptions, out modified)).Returns(expected); _friendlyUrlWrapperMock.Setup(d => d.ValidateUrl(It.IsAny <string>(), It.IsAny <int>(), It.IsAny <PortalSettings>(), out modified)); InitializePageController(); PageSettings pageSettings = new PageSettings(); pageSettings.Url = inputUrl; string inValidField = string.Empty; string errorMessage = string.Empty; // Act bool result = _pagesController.ValidatePageUrlSettings(portalSettings, pageSettings, tab, ref inValidField, ref errorMessage); // Assert Assert.IsTrue(result); _urlRewriterUtilsWrapperMock.VerifyAll(); _friendlyUrlWrapperMock.Verify(d => d.CleanNameForUrl(expected, friendlyOptions, out modified), Times.Once()); }
public static string cleanUrl(string url, int portalId) { bool replaced = false; FriendlyUrlOptions options = UrlRewriterUtils.GetOptionsFromSettings(FriendlyUrlController.GetCurrentSettings(portalId)); return(FriendlyUrlController.CleanNameForUrl(url, options, out replaced).ToLower()); }
internal new string CleanNameForUrl(string title, FriendlyUrlOptions options) { bool replaced = false; //the base module Url PRovider contains a Url cleaning routine, which will remove illegal and unwanted characters from a string, using the specific friendly url options return(base.CleanNameForUrl(title, options, out replaced)); }
/// <summary> /// REbuilds the two indexes and re-stores them into the cache /// </summary> /// <param name="tabId"></param> /// <param name="portalId"></param> /// <param name="provider"></param> /// <param name="options"></param> private static void RebuildIndexes(int portalId, SocialUrlProvider provider, FriendlyUrlOptions options) { Hashtable queryStringIndex = null; Hashtable friendlyUrlIndex = null; string qsCacheKey = GetQueryStringIndexCacheKeyForPortal(portalId); string furlCacheKey = GetFriendlyUrlIndexKeyForPortal(portalId); //build index for tab BuildUrlIndexes(portalId, provider, options, out friendlyUrlIndex, out queryStringIndex); StoreIndexes(friendlyUrlIndex, furlCacheKey, queryStringIndex, qsCacheKey); }
/// <summary> /// This method is used by the Url Master Url Rewriting process. The purpose of this method is to take the supplied array of Url parameters, and transform them into a module-specific querystring for the underlying re-written Url. /// </summary> /// <param name="urlParms">The array of parameters found after the DNN page path has been identified. No key/valeu pairs are identified, the parameters are converted from the /key/value/key2/value2 format into [key,value,key2,value2] format.</param> /// <param name="tabId">TabId of identified DNN page.</param> /// <param name="portalId">PortalId of identified DNN portal.</param> /// <param name="options">The current Friendly Url options being used by the module.</param> /// <param name="cultureCode">Identified language/culture code, if supplied.</param> /// <param name="portalAlias">Identified portalAlias object for the request.</param> /// <param name="messages">List of debug messages. Add to this list to help debug your module. Can be viewed in the reponse headers of the request, or in the 'Test Url Rewriting' section of the Url Master module.</param> /// <param name="status">Out parameter, returns the Http status of the request. May be 200,301,302, or 404. For normal rewriting, return a 200 value.</param> /// <param name="location">If a 301 or 302 is returned in the status parameter, then this must contain a valid redirect location. This should be a fully-qualified Url.</param> /// <returns>The querystring to be used for rewriting the Url. NOTE: doesn't need to include the tabid if the tabid parameter is > -1</returns> public override string TransformFriendlyUrlToQueryString(string[] urlParms, int tabId, int portalId, iFinity.DNN.Modules.UrlMaster.FriendlyUrlOptions options, string cultureCode, DotNetNuke.Entities.Portals.PortalAliasInfo portalAlias, ref List <string> messages, out int status, out string location) { //store local options variable _options = options; //initialise results and output variables string result = ""; status = 200; //OK location = null; //no redirect location if (messages == null) { messages = new List <string>(); } return(result); }
/// <summary> /// The Change Friendly Url method is called for every Url generated when a page is generated by DotNetNuke. This call sits 'underneath' the 'NavigateUrl' call in DotNetNuke. /// Whenever your module calls NavigateUrl, this method will be also called. In here, the module developer should modify the friendlyUrlPath to the final state required. /// However, because this call is used for all Urls on the page, not just those generated by the target module, some type of high-level filter should be used to make sure only /// the module Urls are modified. /// </summary> /// <param name="tab">Current Tab</param> /// <param name="friendlyUrlPath">Current Friendly Url Path after going through the Friendly Url Generation process of the Url Master module.</param> /// <param name="options">The options currently applying to Urls in this portal (space replacement, max length, etc)</param> /// <param name="cultureCode">The culture code being used for this Url (if supplied, may be empty)</param> /// <param name="endingPageName">The page name the Url has been called with. Normally default.aspx, but may be different for some modules.</param> /// <param name="useDnnPagePath">Out parameter to be set by the module. If true, the path of the DNN page will be in the Url (ie /pagename). If false, this part of the Url will be removed.</param> /// <param name="messages">List of debug messages. Add any debug information to this collection to help debug your provider. This can be seen in the repsonse headers, and also in the 'test Url Rewrite' page in the Url Master module.</param> /// <returns>System.String.</returns> public override string ChangeFriendlyUrl(DotNetNuke.Entities.Tabs.TabInfo tab, string friendlyUrlPath, iFinity.DNN.Modules.UrlMaster.FriendlyUrlOptions options, string cultureCode, ref string endingPageName, out bool useDnnPagePath, ref List <string> messages) { _options = options;//keep local copy of options //set default values for out parameters useDnnPagePath = true; if (messages == null) { messages = new List <string>(); } //check if we want to try and modify this Url //first check to see if this Url is an 'edit' Url - something that loads a module-specific page. //we don't want to mess with these, because they're always permissions based Urls and thus //no need to be friendly return(friendlyUrlPath); }
public override string TransformFriendlyUrlToQueryString(string[] urlParms, int tabId, int portalId, FriendlyUrlOptions options, string cultureCode, PortalAliasInfo portalAlias, ref List <string> messages, out int status, out string location) { if (string.IsNullOrEmpty(cultureCode)) { var PortalSetting = PortalController.Instance.GetPortal(portalId); cultureCode = PortalSetting.CultureCode; } var result = string.Empty; status = 200; //OK location = null; //no redirect location var requestedPath = string.Join("/", urlParms); requestedPath = EnsureLeadingChar("/", requestedPath); var context = new HccRequestContext(); var accountServices = Factory.CreateService <AccountService>(context); if (!string.IsNullOrWhiteSpace(cultureCode)) { context.MainContentCulture = cultureCode; } context.FallbackContentCulture = string.Empty; var store = accountServices.GetStoreByUrl(portalAlias.HTTPAlias); if (store != null) { var urlSettings = store.Settings.Urls; if (urlSettings.ProductTabId == tabId || urlSettings.CategoryTabId == tabId || urlSettings.ProductReviewTabId == tabId) { var position = -1; if (urlParms.Length % 2 == 1) { position = 0; result = "slug=" + urlParms[0]; } result += CreateQueryStringFromParameters(urlParms, position); } } return(result); }
internal static bool MakeAuthorUrl(UrlProvider urlProvider, Match authorUrlMatch, Regex authorUrlRegex, string friendlyUrlPath, TabInfo tab, FriendlyUrlOptions options, ModuleUrlOptions urlOptions, string cultureCode, ref string endingPageName, ref bool useDnnPagePath, ref List <string> messages, out string authorUrl) { bool result = false; authorUrl = null; //this is a url that looks like an author url. We want to modify it and create the new one. string rawId = authorUrlMatch.Groups["authid"].Value; int authorId = 0; if (int.TryParse(rawId, out authorId)) { Hashtable friendlyUrlIndex = null; //the friendly url index is the lookup we use //we have obtained the item Id out of the Url //get the friendlyUrlIndex (it comes from the database via the cache) friendlyUrlIndex = UrlController.GetFriendlyUrlIndex(tab.TabID, tab.PortalID, urlProvider, options, urlOptions); if (friendlyUrlIndex != null) { //item urls are indexed with a + user id ("u5") - this is so authors/articles/categories can be mixed and matched string furlkey = "u" + authorId.ToString(); //create the lookup key for the friendly url index string path = (string)friendlyUrlIndex[furlkey]; //check if in the index if (path == null) { //don't normally expect to have a no-match with a friendly url path when an authorId was in the Url. //could be a new item that has been created and isn't in the index //do a direct call and find out if it's there //path = UrlController.CheckForMissingNewsauthorItem(authorId, "author", tab.TabID, tab.PortalID, provider, options, urlOptions, ref messages); } if (path != null) //got a valid path { //url found in the index for this entry. So replace the matched part of the path with the friendly url if (authorUrlMatch.Groups["l"].Success) //if the path had a leading /, then make sure to add that onto the replacement { path = urlProvider.EnsureLeadingChar("/", path); } /* finish it all off */ messages.Add("Item Friendly Url Replacing : " + friendlyUrlPath + " in Path : " + path); //this is the point where the Url is modified! //replace the path in the path - which leaves any other parts of a path intact. authorUrl = authorUrlRegex.Replace(friendlyUrlPath, path);//replace the part in the friendly Url path with it's replacement. //check if this tab is the one specified to not use a path if (urlOptions.RemovePagePathFromURL) { useDnnPagePath = false;//make this Url relative from the site root } //set back to default.aspx so that Url Master removes it - just in case it wasn't standard endingPageName = DotNetNuke.Common.Globals.glbDefaultPage; result = true; } } } return(result); }
private static void BuildUrlIndexes(int tabID, int portalID, UrlProvider provider, FriendlyUrlOptions options, ModuleUrlOptions urlOptions, out Hashtable friendlyUrlIndex, out Hashtable queryStringIndex) { friendlyUrlIndex = new Hashtable(); queryStringIndex = new Hashtable(); //call database procedure to get list of List <FriendlyUrlInfo> itemUrls = null; if (tabID > 0 && portalID > -1) { itemUrls = Data.UrlDataController.GetEverythingForProvider(tabID); if (itemUrls.Count > 0) { foreach (FriendlyUrlInfo f in itemUrls) { string furlKey = f.FUrlKey; //querystring index - look up by url, find querystring for the item string furlValue = MakeItemFriendlyUrl(f, provider, options, urlOptions); string qsKey = furlValue.ToLower();//the querystring lookup is the friendly Url value - but converted to lower case //string qsValue = null; string itemId = f.itemId.ToString(); string parentId = f.parentId.ToString(); if (urlOptions.RemovePagePathFromURL) { f.qsValue = "?TabId=" + tabID.ToString() + f.qsValue; } string suffix = ""; switch (f.itemType.ToLower()) { case "article": //f.qsValue = "&articleType=ArticleView&articleId=" + itemId;//the querystring is just the entryId parameter break; case "page": //f.qsValue = "&articleType=ArticleView&pageId=" + itemId + "&articleId=" + parentId; break; case "author": //f.qsValue = "&articleType=AuthorView&authorId=" + itemId; break; case "category": //f.qsValue = "&articleType=CategoryView&categoryId=" + itemId; //if (parentId != "-1" && urlOptions.CategoryStyle == CategoryUrlStyle.CatHierarchy) //{ // //this category has a parent // categoryParents.Add(furlKey, itemUrl.FUrlPrefix + parentId); //} break; case "archive": if (parentId == "-1") { //yearly //f.qsValue = "&articleType=ArchiveView&year=" + itemId; } else { //monthly f.qsValue = "&articleType=ArchiveView&year=" + parentId + "&month=" + f.urlNum.ToString();//url num holds the month qsKey = parentId + '/' + f.urlNum.ToString(); furlValue = qsKey; } break; } AddUniqueUrlToIndex(furlKey, ref qsKey, f.qsValue, portalID, queryStringIndex, options, true, out suffix); //if the suffix for the qsKey was changed, we need to add it to the friendly url used for the friendly url index furlValue += suffix; //friendly url index - look up by entryid, find Url //check to see if friendly url matches any page paths if (friendlyUrlIndex.ContainsKey(furlKey) == false)//shouldn't return duplicate because content is controlled by module logic { friendlyUrlIndex.Add(furlKey, furlValue); } //if the options aren't standard, also add in some other versions that will identify the right entry but will get redirected //if (options.PunctuationReplacement != "") //{ // FriendlyUrlOptions altOptions = options.Clone(); // altOptions.PunctuationReplacement = "";//how the urls look with no replacement // string altQsKey = MakeItemFriendlyUrl(f, provider, altOptions, urlOptions).ToLower();//keys are always lowercase // string altQsValue = f.qsValue + "&do301=true&&rr=Title_Space_Replacement"; // AddUniqueUrlToIndex(furlKey, ref altQsKey, altQsValue, portalID, queryStringIndex, options, false, out suffix); //} } } } }
private static void RebuildIndexes(int tabID, int portalID, UrlProvider provider, FriendlyUrlOptions options, ModuleUrlOptions urlOptions) { Hashtable queryStringIndex = null; Hashtable friendlyUrlIndex = null; string qsCacheKey = GetQueryStringIndexCacheKeyForTab(tabID); string furlCacheKey = GetFriendlyUrlIndexKeyForTab(tabID); //build index for tab BuildUrlIndexes(tabID, portalID, provider, options, urlOptions, out friendlyUrlIndex, out queryStringIndex); StoreIndexes(friendlyUrlIndex, furlCacheKey, queryStringIndex, qsCacheKey); }
internal static bool MakeArchiveUrl(UrlProvider urlProvider, Match archiveUrlMatch, Regex archiveUrlRegex, string friendlyUrlPath, TabInfo tab, FriendlyUrlOptions options, ModuleUrlOptions urlOptions, string cultureCode, ref string endingPageName, ref bool useDnnPagePath, ref List <string> messages, out string archiveUrl) { archiveUrl = friendlyUrlPath; bool result = false; Group mthGrp = archiveUrlMatch.Groups["mth"]; Group yrGrp = archiveUrlMatch.Groups["yr"]; bool month = false, year = false; string mm = null, yyyy = null; string path = null; if (mthGrp != null && mthGrp.Success) { //contains a month month = true; mm = archiveUrlMatch.Groups["mm"].Value; } if (yrGrp != null && yrGrp.Success) { year = true; yyyy = archiveUrlMatch.Groups["yyyy"].Value; } if (year) { path = "/" + yyyy; } if (month) { path += "/" + mm; } if (path != null) //got a valid path { //have a valid url replacement for this url. So replace the matched part of the path with the friendly url if (archiveUrlMatch.Groups["l"].Success) //if the path had a leading /, then make sure to add that onto the replacement { path = urlProvider.EnsureLeadingChar("/", path); } /* finish it all off */ messages.Add("Item Friendly Url Replacing Archive Url : " + friendlyUrlPath + " with Path : " + path); //this is the point where the Url is modified! //replace the path in the path - which leaves any other parts of a path intact. archiveUrl = archiveUrlRegex.Replace(friendlyUrlPath, path);//replace the part in the friendly Url path with it's replacement. //check if this tab is the one specified to not use a path if (urlOptions.RemovePagePathFromURL) { useDnnPagePath = false;//make this Url relative from the site root } //set back to default.aspx so that Url Master removes it - just in case it wasn't standard endingPageName = DotNetNuke.Common.Globals.glbDefaultPage; //return success result = true; } return(result); }
internal static Hashtable GetQueryStringIndex(int tabId, int portalId, UrlProvider provider, FriendlyUrlOptions options, ModuleUrlOptions urlOptions, bool forceRebuild) { string qsCacheKey = GetQueryStringIndexCacheKeyForTab(tabId); Hashtable queryStringIndex = DataCache.GetCache <Hashtable>(qsCacheKey); if (queryStringIndex == null || forceRebuild) { string furlCacheKey = GetFriendlyUrlIndexKeyForTab(tabId); Hashtable friendlyUrlIndex = null; //build index for tab BuildUrlIndexes(tabId, portalId, provider, options, urlOptions, out friendlyUrlIndex, out queryStringIndex); StoreIndexes(friendlyUrlIndex, furlCacheKey, queryStringIndex, qsCacheKey); } return(queryStringIndex); }
/// <summary> /// This method is used by the Url Master Url Rewriting process. The purpose of this method is to take the supplied array of Url parameters, and transform them into a module-specific querystring for the underlying re-written Url. /// </summary> /// <param name="urlParms">The array of parameters found after the DNN page path has been identified. No key/valeu pairs are identified, the parameters are converted from the /key/value/key2/value2 format into [key,value,key2,value2] format.</param> /// <param name="tabId">TabId of identified DNN page.</param> /// <param name="portalId">PortalId of identified DNN portal.</param> /// <param name="options">The current Friendly Url options being used by the module.</param> /// <param name="cultureCode">Identified language/culture code, if supplied.</param> /// <param name="portalAlias">Identified portalAlias object for the request.</param> /// <param name="messages">List of debug messages. Add to this list to help debug your module. Can be viewed in the reponse headers of the request, or in the 'Test Url Rewriting' section of the Url Master module.</param> /// <param name="status">Out parameter, returns the Http status of the request. May be 200,301,302, or 404. For normal rewriting, return a 200 value.</param> /// <param name="location">If a 301 or 302 is returned in the status parameter, then this must contain a valid redirect location. This should be a fully-qualified Url.</param> /// <returns>The querystring to be used for rewriting the Url. NOTE: doesn't need to include the tabid if the tabid parameter is > -1</returns> public override string TransformFriendlyUrlToQueryString(string[] urlParms, int tabId, int portalId, iFinity.DNN.Modules.UrlMaster.FriendlyUrlOptions options, string cultureCode, DotNetNuke.Entities.Portals.PortalAliasInfo portalAlias, ref List<string> messages, out int status, out string location) { //store local options variable _options = options; //initialise results and output variables string result = ""; status = 200; //OK location = null; //no redirect location if (messages == null) messages = new List<string>(); return result; }
public override string ChangeFriendlyUrl(DotNetNuke.Entities.Tabs.TabInfo tab, string friendlyUrlPath, FriendlyUrlOptions options, string cultureCode, ref string endingPageName, out bool useDnnPagePath, ref List <string> messages) { useDnnPagePath = true; return(friendlyUrlPath); }
private static string MakeItemFriendlyUrl(FriendlyUrlInfo vl, UrlProvider provider, FriendlyUrlOptions options, ModuleUrlOptions urlOptions) { string result = ""; result = provider.CleanNameForUrl((vl.urlFragment), options); return(result); }
public override bool CheckForRedirect(int tabId, int portalid, string httpAlias, Uri requestUri, NameValueCollection queryStringCol, FriendlyUrlOptions options, out string redirectLocation, ref List <string> messages) { bool doRedirect = false; redirectLocation = "";//set blank location //compare to known pattern of old Urls string path = requestUri.AbsoluteUri; if (string.IsNullOrEmpty(path) == false && Regex.IsMatch(path, @"(^|/)(mid|moduleId)/\d+/?", RegexOptions.IgnoreCase) == false) { //could be in old /groupId/xx format - if so, we want to redirect it Regex pathRegex = new Regex(@"/groupid/(?<groupid>\d+)", RegexOptions.IgnoreCase); Match pathMatch = pathRegex.Match(path); if (pathMatch.Success) { string groupIdRaw = pathMatch.Groups["groupid"].Value; int groupId; if (int.TryParse(groupIdRaw, out groupId)) { //ok, valid item Id found //get the valid Url for this item Hashtable friendlyUrlIndex = UrlController.GetFriendlyUrlIndex(portalid, this, options); //look up the friendly url index using the item key string furlKey = FriendlyUrlInfo.MakeKey("group", groupId); if (friendlyUrlIndex != null) { string friendlyUrl = null; TabController tc = new TabController(); TabInfo tab = tc.GetTab(tabId, portalid, false); if (tab != null && tab.ParentId == GroupPagePathTabId) { //this is the child tab of the group tab string cpFurlKey = "t" + tabId.ToString() + furlKey; friendlyUrl = (string)friendlyUrlIndex[cpFurlKey]; } if (friendlyUrl == null) { friendlyUrl = (string)friendlyUrlIndex[furlKey]; } if (friendlyUrl != null) { //ok, we're going to replace this in the Url if (HideGroupPagePath == false) { friendlyUrl = base.EnsureLeadingChar("/", friendlyUrl); string result = pathRegex.Replace(path, friendlyUrl); doRedirect = true; redirectLocation = result; } else { DotNetNuke.Entities.Portals.PortalAliasInfo pa = DotNetNuke.Entities.Portals.PortalAliasController.GetPortalAliasInfo(httpAlias); if (pa != null) { DotNetNuke.Entities.Portals.PortalSettings ps = new DotNetNuke.Entities.Portals.PortalSettings(tabId, pa); redirectLocation = DotNetNuke.Common.Globals.NavigateURL(tabId, ps, "", "groupid=" + groupId); doRedirect = true; } } } } } } } return(doRedirect); }
public override bool CheckForRedirect(int tabId, int portalid, string httpAlias, Uri requestUri, NameValueCollection queryStringCol, FriendlyUrlOptions options, out string redirectLocation, ref List <string> messages) { throw new NotImplementedException(); }
public override string TransformFriendlyUrlToQueryString(string[] urlParms, int tabId, int portalId, FriendlyUrlOptions options, string cultureCode, PortalAliasInfo portalAlias, ref List <string> messages, out int status, out string location) { //initialise results and output variables string result = ""; status = 200; //OK location = null; //no redirect location if (messages == null) { messages = new List <string>(); } Hashtable queryStringIndex = null; string path = string.Join("/", urlParms); bool found = false; bool siteRootMatch = false; if (string.IsNullOrEmpty(path) == false && Regex.IsMatch(path, @"(^|/)(mid|moduleId)/\d+/?", RegexOptions.IgnoreCase) == false) { if (urlParms.Length > 0) { //tabid == -1 when no dnn page path is in the Url. This means the DNN url rewriter can't determine the DNN page based on the Url. //In this case, it is up to this provider to identify the correct tabId that matches the Url. Failure to do so will result in the incorrect tab being loaded when the page is rendered. if (tabId == -1) { siteRootMatch = true; } queryStringIndex = UrlController.GetQueryStringIndex(portalId, this, options, false); List <string> keepParms = new List <string>(); //iterate backwards through the collection of params string lookupPath = path; if (string.IsNullOrEmpty(UrlPath) == false && lookupPath.StartsWith(UrlPath)) { lookupPath = lookupPath.Substring(UrlPath.Length); } for (int i = urlParms.GetUpperBound(0); i >= 0; i--) { //check for existence of this value in the querystring index string urlParm = urlParms[i]; string qsKey = lookupPath.ToLower(); string qs = (string)queryStringIndex[qsKey]; if (qs != null) { //found a querystring match found = true; messages.Add("Item Matched in Friendly Url Provider. Url : " + lookupPath + " Path : " + path); result += qs; break; } else { if (string.IsNullOrEmpty(urlParm) == false) { //not found - remove last url parm from lookup path if (lookupPath.Length <= urlParm.Length) { lookupPath = ""; } else { lookupPath = lookupPath.Remove(lookupPath.Length - (urlParm.Length + 1)); } keepParms.Insert(0, urlParm);//add from front always } } } if (found) { //put on any remainder of the path that wasn't to do with the friendly Url string remainder = base.CreateQueryStringFromParameters(keepParms.ToArray(), -1); //put it all together for the final rewrite string result += remainder; } } } return(result); }
/// <summary> /// Determines when to do a redirect. This is separate to the rewriting process. The module developer can create any type of Url redirect here, because the entire Url of the original request is passed in. /// </summary> /// <param name="tabId">Identified TabId, if known. -1 if no valid tabid identified.</param> /// <param name="portalid">Identified portalId.</param> /// <param name="httpAlias">Identified httpAlias of the request.</param> /// <param name="requestUri">The original requested Url</param> /// <param name="queryStringCol">The querystring collection of the original request</param> /// <param name="options">The friendly url options that currently apply.</param> /// <param name="redirectLocation">Out parameter that shows where to redirect to.</param> /// <param name="messages">List of messages for debug purposes. Add to this list to help debug your module.</param> /// <returns>true if 301 redirect is required, false if not. If true, the redirectLocation value must be a valid fully qualified Url.</returns> public override bool CheckForRedirect(int tabId, int portalid, string httpAlias, Uri requestUri, System.Collections.Specialized.NameValueCollection queryStringCol, FriendlyUrlOptions options, out string redirectLocation, ref List <string> messages) { bool doRedirect = false; if (messages == null) { messages = new List <string>(); } redirectLocation = "";//set blank location //compare to known pattern of old Urls if (_redirectUrls) { Regex oldNewsRegex = new Regex(@"(&articleType=(?<type>[^&]+))?((&(?<idname>[a-z]*Id)=(?<id>\d+))|((&month=(?<mm>[\d]{1,2}))?&year=(?<yyyy>[\d]{4})))(&(?<pgname>PageId|CurrentPage)=(?<pg>[\d]+))?", RegexOptions.IgnoreCase); Match oldNewsMatch = oldNewsRegex.Match(queryStringCol.ToString()); if (oldNewsMatch.Success) { Group typeGroup = oldNewsMatch.Groups["type"]; Group idNameGroup = oldNewsMatch.Groups["idname"]; Group idGroup = oldNewsMatch.Groups["id"]; Group pageGroup = oldNewsMatch.Groups["pg"]; Group pgNameGrp = oldNewsMatch.Groups["pgname"]; string msg = ""; string id = null; string furlKey = null; string friendlyUrl = null; if (idGroup != null && idGroup.Success) { id = idGroup.Value; } string idType = null; if (typeGroup != null && typeGroup.Success) { idType = typeGroup.Value.ToLower(); } else { if (idNameGroup != null && idNameGroup.Success) { //check if it's the 'ID' value if (idNameGroup.Value.ToLower() == "id") { idType = "id"; } } } //now look at the idType string pagePath = null; if (pgNameGrp != null && pgNameGrp.Success == true && pageGroup != null && pageGroup.Success) { pagePath = pgNameGrp.Value + "/" + pageGroup.Value; } switch (idType) { case "articleview": case "id": msg = "Identified as old-style news article"; //article if (pageGroup != null && pageGroup.Success) { furlKey = "p" + pageGroup.Value; pagePath = null; //taking care of page separately } else { int articleId = -1; //only for items that are in the range of allowed article ids if (int.TryParse(id, out articleId)) { if (articleId >= this.StartingArticleId) { furlKey = "a" + id; } } } break; case "categoryview": msg = "Identified as old-style news category"; furlKey = "c" + id; break; case "archiveview": //get the mm and yyyy msg = "Identified as old-style news archive"; Group yyyyGrp = oldNewsMatch.Groups["yyyy"]; if (yyyyGrp != null && yyyyGrp.Success) { string yyyy = yyyyGrp.Value; string mm = null; Group mmGrp = oldNewsMatch.Groups["mm"]; if (mmGrp != null && mmGrp.Success) { mm = mmGrp.Value; } friendlyUrl = yyyy; if (mm != null) { friendlyUrl += "/" + mm; } } break; case "authorview": msg = "Identified as old-style news author"; furlKey = "u" + id; break; } if (furlKey != null) { //now lookup the friendly url index TabUrlOptions urlOptions = GetTabUrlOptions(tabId); Hashtable friendlyUrlIndex = UrlController.GetFriendlyUrlIndex(tabId, portalid, this, options, urlOptions); if (friendlyUrlIndex != null && friendlyUrlIndex.ContainsKey(furlKey)) { //look up the index for the item if we don't already have a friendly Url friendlyUrl = (string)friendlyUrlIndex[furlKey]; } } if (friendlyUrl != null) { //now merge with the friendly url for the selected page PortalAliasInfo alias = PortalAliasController.GetPortalAliasInfo(httpAlias); PortalSettings ps = new PortalSettings(tabId, alias); if (pagePath != null) { friendlyUrl += this.EnsureLeadingChar("/", pagePath); } string baseUrl = ""; if (_noDnnPagePathTabId == tabId) { baseUrl = requestUri.Scheme + Uri.SchemeDelimiter + httpAlias + this.EnsureLeadingChar("/", friendlyUrl) + options.PageExtension;//put onto http Alias with no page path } else { baseUrl = DotNetNuke.Common.Globals.NavigateURL(tabId, ps, "", friendlyUrl); //add on with page path } if (baseUrl != null) { redirectLocation = baseUrl; doRedirect = true; msg += ", found friendly url " + friendlyUrl + ", redirecting"; messages.Add(msg); } } } } return(doRedirect); }
/// <summary> /// This method is used by the Url Master Url Rewriting process. The purpose of this method is to take the supplied array of Url parameters, and transform them into a module-specific querystring for the underlying re-written Url. /// </summary> /// <param name="urlParms">The array of parameters found after the DNN page path has been identified. No key/valeu pairs are identified, the parameters are converted from the /key/value/key2/value2 format into [key,value,key2,value2] format.</param> /// <param name="tabId">TabId of identified DNN page. </param> /// <param name="portalId">PortalId of identified DNN portal.</param> /// <param name="options">The current Friendly Url options being used by the module.</param> /// <param name="cultureCode">Identified language/culture code, if supplied.</param> /// <param name="portalAlias">Identified portalAlias object for the request.</param> /// <param name="messages">List of debug messages. Add to this list to help debug your module. Can be viewed in the reponse headers of the request, or in the 'Test Url Rewriting' section of the Url Master module.</param> /// <param name="status">Out parameter, returns the Http status of the request. May be 200,301,302, or 404. For normal rewriting, return a 200 value.</param> /// <param name="location">If a 301 or 302 is returned in the status parameter, then this must contain a valid redirect location. This should be a fully-qualified Url.</param> /// <returns>The querystring to be used for rewriting the Url. NOTE: doesn't need to include the tabid if the tabid parameter is > -1</returns> public override string TransformFriendlyUrlToQueryString(string[] urlParms, int tabId, int portalId, FriendlyUrlOptions options, string cultureCode, DotNetNuke.Entities.Portals.PortalAliasInfo portalAlias, ref List <string> messages, out int status, out string location) { string path = string.Join("/", urlParms); //initialise results and output variables location = null; //no redirect location if (messages == null) { messages = new List <string>(); } string result = ""; status = 200; //OK //prevent incorrect matches of Urls if (!Regex.IsMatch(path, @"(articleType/(?<type>[^/]+))|(ctl/[^/]+/(mid|moduleid)/\d)", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant)) { //store local options variable _options = options; //get the tab options TabUrlOptions urlOptions = GetTabUrlOptions(tabId); Hashtable queryStringIndex = null; int skipUpToIndex = -1; bool found = false; bool siteRootMatch = false; bool tabHasNAModule = false; //foreach (ModuleInfo mi in ModuleController.Instance.GetTabModules(tabId).Values) { //} if ((from ModuleInfo mi in ModuleController.Instance.GetTabModules(tabId).Values where mi.DesktopModule.FolderName.ToLower().Contains("dnnforge - newsarticles") select mi.ModuleTitle).Count() != 0) { tabHasNAModule = true; } //look for match on pattern for date and title - the pattern used by this provider //string path = string.Join("/", urlParms); //messages.Add("Checking for Items in Friendly Url path: " + path); if (urlParms.Length > 0) { //tabid == -1 when no dnn page path is in the Url. This means the Url Master module can't determine the DNN page based on the Url. //In this case, it is up to this provider to identify the correct tabId that matches the Url. Failure to do so will result in the incorrect tab being loaded when the page is rendered. if (tabId == -1) { siteRootMatch = true; if (_noDnnPagePathTabId > -1) { //tabid -1 means a 'site root' match - meaning that the dnn page path wasn't included in the Url tabId = _noDnnPagePathTabId;//if tabid = -1, it means a site root match (no dnn page path) so we substitute in the tabid where this is being used } } queryStringIndex = UrlController.GetQueryStringIndex(tabId, portalId, this, options, urlOptions, false); string pathBasedKey = string.Join("/", urlParms).ToLower(); string qs = null; if (queryStringIndex.ContainsKey(pathBasedKey)) { //that was easy- direct match qs = (string)queryStringIndex[pathBasedKey]; skipUpToIndex = urlParms.GetUpperBound(0); } else { //go through the parameter list backwards until we find a match for (int i = urlParms.GetUpperBound(0); i >= 0; i--) { //copy all the array minus the i index item int tempLength = i + 1; string[] tempParms = new string[tempLength]; Array.Copy(urlParms, 0, tempParms, 0, i + 1); //make a new key from the shorter array pathBasedKey = string.Join("/", tempParms).ToLower(); //check if that matches if (queryStringIndex.ContainsKey(pathBasedKey)) { qs = (string)queryStringIndex[pathBasedKey]; if (qs != null) { //the trimmed pieces need to be included skipUpToIndex = i; break; } } } } if (qs != null) { //found a querystring match found = true; messages.Add("Item Matched in Friendly Url Provider. Url : " + pathBasedKey + " Path : " + path); result += qs; } else { //no match, but look for a date archive pattern //903 : issue with matching other Urls that aren't archive Urls Regex archivePatternRegex = new Regex(@"(?<!year)(?<yr>(^|/)(?<yyyy>[\d]{4}))(?<mth>/(?<mm>[\d]{1,2}))?", RegexOptions.IgnoreCase); Match archivePatternMatch = archivePatternRegex.Match(path); if (archivePatternMatch.Success) { bool month = false, year = false; string mm = null, yyyy = null; //matched on date pattern, extract month/year Group mthGrp = archivePatternMatch.Groups["mth"]; if (mthGrp != null && mthGrp.Success) { mm = archivePatternMatch.Groups["mm"].Value; month = true; } Group yrGrp = archivePatternMatch.Groups["yyyy"]; if (yrGrp != null && yrGrp.Success) { //902 : don't allow invalid dates to be passed down int yearVal = 0; yyyy = yrGrp.Value; //check that year is a valid int, and that year is later than sql min date time if (int.TryParse(yyyy, out yearVal) && yearVal > 1753 && tabHasNAModule) { year = true; } } if (year) { qs = ""; if (this.NoDnnPagePathTabId == tabId) { qs += "?tabid=" + tabId.ToString(); } //add on the year qs += "&articleType=ArchiveView&year=" + yyyy; skipUpToIndex = 0;//1st position } if (year && month) { int mmVal = 0; if (int.TryParse(mm, out mmVal) && mmVal > 0 && mmVal < 13) { qs += "&month=" + mm; skipUpToIndex = 1;//2nd position } } if (year || month) { result += qs; } } } } if (skipUpToIndex >= 0) { //put on any remainder of the path that wasn't to do with the friendly Url //but only if there was *something* in the friendly url that we interpreted string remainder = base.CreateQueryStringFromParameters(urlParms, skipUpToIndex); //put it all together for the final rewrite string result += remainder; } } return(result); }
/// <summary> /// Creates a friendly article url, depending on the options /// </summary> /// <param name="provider"></param> /// <param name="articleUrlMatch"></param> /// <param name="articleUrlRegex"></param> /// <param name="friendlyUrlPath"></param> /// <param name="tab"></param> /// <param name="options"></param> /// <param name="urlOptions"></param> /// <param name="cultureCode"></param> /// <param name="endingPageName"></param> /// <param name="useDnnPagePath"></param> /// <param name="messages"></param> /// <param name="articleUrl"></param> /// <returns></returns> internal static bool MakeArticleUrl(UrlProvider provider, Match articleUrlMatch, Regex articleUrlRegex, string friendlyUrlPath, DotNetNuke.Entities.Tabs.TabInfo tab, FriendlyUrlOptions options, ModuleUrlOptions urlOptions, string cultureCode, ref string endingPageName, ref bool useDnnPagePath, ref List <string> messages, out string articleUrl) { bool result = false; articleUrl = null; //this is a url that looks like an article url. We want to modify it and create the new one. string rawId = articleUrlMatch.Groups["artid"].Value; int articleId = 0; if (int.TryParse(rawId, out articleId)) { Hashtable friendlyUrlIndex = null; //the friendly url index is the lookup we use //we have obtained the item Id out of the Url //get the friendlyUrlIndex (it comes from the database via the cache) friendlyUrlIndex = UrlController.GetFriendlyUrlIndex(tab.TabID, tab.PortalID, provider, options, urlOptions); if (friendlyUrlIndex != null) { string furlkey = null; int pageId = -1; //first check if we are seeking page or article if (articleUrlMatch.Groups["pageid"].Success) { //page item urls are index by p + page id. But we only use this if it is present //ie pages override articles when both are present string rawPageId = articleUrlMatch.Groups["pageid"].Value; if (int.TryParse(rawPageId, out pageId)) { furlkey = "p" + rawPageId; } } else { //item urls are indexed with a + articleId ("a5") - this is so we could mix and match entities if necessary furlkey = "a" + articleId.ToString(); //create the lookup key for the friendly url index } string path = (string)friendlyUrlIndex[furlkey]; //check if in the index if (path == null) { //don't normally expect to have a no-match with a friendly url path when an articleId was in the Url. //could be that the page id is bunk - in that case, just use the article Id if (furlkey.Contains("p")) { furlkey = "a" + articleId.ToString(); //create the lookup key for the friendly url index path = (string)friendlyUrlIndex[furlkey]; //check if in the index } if (path == null) { //could be a new item that has been created and isn't in the index //do a direct call and find out if it's there path = UrlController.CheckForMissingNewsArticleItem(articleId, "article", tab.TabID, tab.PortalID, provider, options, urlOptions, ref messages); } } if (path != null) //got a valid path { //url found in the index for this entry. So replace the matched part of the path with the friendly url if (articleUrlMatch.Groups["l"].Success) //if the path had a leading /, then make sure to add that onto the replacement { path = provider.EnsureLeadingChar("/", path); } /* finish it all off */ messages.Add("Item Friendly Url Replacing : " + friendlyUrlPath + " in Path : " + path); //this is the point where the Url is modified! //replace the path in the path - which leaves any other parts of a path intact. articleUrl = articleUrlRegex.Replace(friendlyUrlPath, path);//replace the part in the friendly Url path with it's replacement. //check if this tab is the one specified to not use a path //if (provider.NoDnnPagePathTabId == tab.TabID) // useDnnPagePath = false;//make this Url relative from the site root //set back to default.aspx so that Url Master removes it - just in case it wasn't standard endingPageName = DotNetNuke.Common.Globals.glbDefaultPage; result = true; } } } return(result); }
/// <summary> /// The Change Friendly Url method is called for every Url generated when a page is generated by DotNetNuke. This call sits 'underneath' the 'NavigateUrl' call in DotNetNuke. /// Whenever your module calls NavigateUrl, this method will be also called. In here, the module developer should modify the friendlyUrlPath to the final state required. /// However, because this call is used for all Urls on the page, not just those generated by the target module, some type of high-level filter should be used to make sure only /// the module Urls are modified. /// </summary> /// <param name="tab">Current Tab</param> /// <param name="friendlyUrlPath">Current Friendly Url Path after going through the Friendly Url Generation process of the Url Master module.</param> /// <param name="options">The options currently applying to Urls in this portal (space replacement, max length, etc)</param> /// <param name="cultureCode">The culture code being used for this Url (if supplied, may be empty)</param> /// <param name="endingPageName">The page name the Url has been called with. Normally default.aspx, but may be different for some modules.</param> /// <param name="useDnnPagePath">Out parameter to be set by the module. If true, the path of the DNN page will be in the Url (ie /pagename). If false, this part of the Url will be removed.</param> /// <param name="messages">List of debug messages. Add any debug information to this collection to help debug your provider. This can be seen in the repsonse headers, and also in the 'test Url Rewrite' page in the Url Master module.</param> /// <returns>System.String.</returns> public override string ChangeFriendlyUrl(DotNetNuke.Entities.Tabs.TabInfo tab, string friendlyUrlPath, iFinity.DNN.Modules.UrlMaster.FriendlyUrlOptions options, string cultureCode, ref string endingPageName, out bool useDnnPagePath, ref List<string> messages) { _options = options;//keep local copy of options //set default values for out parameters useDnnPagePath = true; if (messages == null) messages = new List<string>(); //check if we want to try and modify this Url //first check to see if this Url is an 'edit' Url - something that loads a module-specific page. //we don't want to mess with these, because they're always permissions based Urls and thus //no need to be friendly return friendlyUrlPath; }
private static void AddUniqueUrlToIndex(string furlKey, ref string qsKey, string qsValue, int portalID, Hashtable queryStringIndex, FriendlyUrlOptions options, bool addSuffixIfDuplicateFound, out string suffix) { DotNetNuke.Entities.Tabs.TabController tc = new DotNetNuke.Entities.Tabs.TabController(); bool duplicate = false; suffix = "";//can hold a de-duplicating suffix int suffixCounter = 1; bool furlKeyUsed = false; do { duplicate = false;//always start in the assumption that this is not a duplicate DotNetNuke.Entities.Tabs.TabInfo matchingTab = tc.GetTabByName(qsKey, portalID); if (matchingTab != null) { duplicate = true; } else if (portalID >= 0) { matchingTab = tc.GetTabByName(qsKey, -1);//host tabs if (matchingTab != null) { duplicate = true; } } if (duplicate == false) { //try and add to index if (queryStringIndex.ContainsKey(qsKey) == false) { queryStringIndex.Add(qsKey, qsValue); } else { duplicate = true; } } if (duplicate == true) { if (furlKeyUsed == false) { furlKeyUsed = true; suffix = options.PunctuationReplacement + furlKey; qsKey += suffix; } else { suffix += suffixCounter.ToString(); qsKey += suffix; } } }while (duplicate == true && addSuffixIfDuplicateFound == true); }
public PageUrlResult CreateCustomUrl(SaveUrlDto dto, TabInfo tab) { PortalSettings portalSettings = PortalController.Instance.GetCurrentSettings() as PortalSettings; PortalInfo aliasPortal = new PortalAliasController().GetPortalByPortalAliasID(dto.SiteAliasKey); if (aliasPortal != null && portalSettings.PortalId != aliasPortal.PortalID) { return(new PageUrlResult { Success = false, ErrorMessage = Localization.GetString("CustomUrlPortalAlias.Error"), SuggestedUrlPath = string.Empty }); } string urlPath = dto.Path.ValueOrEmpty().TrimStart('/'); //Clean Url FriendlyUrlOptions options = UrlRewriterUtils.ExtendOptionsForCustomURLs(UrlRewriterUtils.GetOptionsFromSettings(new FriendlyUrlSettings(portalSettings.PortalId))); urlPath = FriendlyUrlController.CleanNameForUrl(urlPath, options, out bool modified); if (modified) { return(new PageUrlResult { Success = false, ErrorMessage = Localization.GetString("CustomUrlPathCleaned.Error"), SuggestedUrlPath = "/" + urlPath }); } //Validate for uniqueness urlPath = FriendlyUrlController.ValidateUrl(urlPath, -1, portalSettings, out modified); if (modified) { return(new PageUrlResult { Success = false, ErrorMessage = Localization.GetString("UrlPathNotUnique.Error"), SuggestedUrlPath = "/" + urlPath }); } if (tab.TabUrls.Any(u => u.Url.ToLowerInvariant() == dto.Path.ValueOrEmpty().ToLowerInvariant() && (u.PortalAliasId == dto.SiteAliasKey || u.PortalAliasId == -1))) { return(new PageUrlResult { Success = false, ErrorMessage = Localization.GetString("DuplicateUrl.Error") }); } int seqNum = (tab.TabUrls.Count > 0) ? tab.TabUrls.Max(t => t.SeqNum) + 1 : 1; Dictionary <string, DNNLocalization.Locale> portalLocales = DNNLocalization.LocaleController.Instance.GetLocales(portalSettings.PortalId); string cultureCode = portalLocales.Where(l => l.Value.KeyID == dto.LocaleKey) .Select(l => l.Value.Code) .SingleOrDefault() ?? portalSettings.CultureCode; PortalAliasUsageType portalAliasUsage = (PortalAliasUsageType)dto.SiteAliasUsage; if (portalAliasUsage == PortalAliasUsageType.Default) { PortalAliasInfo alias = PortalAliasController.Instance.GetPortalAliasesByPortalId(portalSettings.PortalId) .SingleOrDefault(a => a.PortalAliasID == dto.SiteAliasKey); if (string.IsNullOrEmpty(cultureCode) || alias == null) { return(new PageUrlResult { Success = false, ErrorMessage = Localization.GetString("InvalidRequest.Error") }); } } else { PortalAliasInfo cultureAlias = PortalAliasController.Instance.GetPortalAliasesByPortalId(portalSettings.PortalId) .FirstOrDefault(a => a.CultureCode == cultureCode); if (portalLocales.Count > 1 && !portalSettings.ContentLocalizationEnabled && (string.IsNullOrEmpty(cultureCode) || cultureAlias == null)) { return(new PageUrlResult { Success = false, ErrorMessage = Localization.GetString("InvalidRequest.Error") }); } } TabUrlInfo tabUrl = new TabUrlInfo { TabId = tab.TabID, SeqNum = seqNum, PortalAliasId = dto.SiteAliasKey, PortalAliasUsage = portalAliasUsage, QueryString = dto.QueryString.ValueOrEmpty(), Url = dto.Path.ValueOrEmpty(), CultureCode = cultureCode, HttpStatus = dto.StatusCodeKey.ToString(CultureInfo.InvariantCulture), IsSystem = false }; //TabController.Instance.SaveTabUrl(tabUrl, portalSettings.PortalId, true); SaveTabUrl(tabUrl, portalSettings.PortalId, true); return(new PageUrlResult { Success = true, Id = seqNum // returns Id of the created Url }); }
public static Hashtable GetFriendlyUrlIndex(int tabID, int portalID, UrlProvider provider, FriendlyUrlOptions options, ModuleUrlOptions urlOptions) { string furlCacheKey = GetFriendlyUrlIndexKeyForTab(tabID); Hashtable friendlyUrlIndex = DataCache.GetCache <Hashtable>(furlCacheKey); if (friendlyUrlIndex == null) { string qsCacheKey = GetQueryStringIndexCacheKeyForTab(tabID); Hashtable queryStringIndex = null; //build index for tab BuildUrlIndexes(tabID, portalID, provider, options, urlOptions, out friendlyUrlIndex, out queryStringIndex); StoreIndexes(friendlyUrlIndex, furlCacheKey, queryStringIndex, qsCacheKey); } return(friendlyUrlIndex); }
/// <summary> /// Checks for, and adds to the indexes, a missing item. /// </summary> /// <param name="itemId"></param> /// <param name="tabId"></param> /// <param name="portalId"></param> /// <param name="provider"></param> /// <param name="options"></param> /// <param name="messages"></param> /// <returns>Valid path if found</returns> internal static string CheckForMissingNewsArticleItem(int itemId, string itemType, int tabId, int portalId, UrlProvider provider, FriendlyUrlOptions options, ModuleUrlOptions urlOptions, ref List <string> messages) { string path = null; FriendlyUrlInfo friendlyUrl = Data.UrlDataController.GetNewsArticleItem(itemId, itemType, urlOptions, tabId); messages.Add("articleId not found : " + itemId.ToString() + " Checking Item directly"); if (friendlyUrl != null) { messages.Add("articleId found : " + itemId.ToString() + " Rebuilding indexes"); //call and get the path path = UrlController.MakeItemFriendlyUrl(friendlyUrl, provider, options, urlOptions); //so this entry did exist but wasn't in the index. Rebuild the index UrlController.RebuildIndexes(tabId, portalId, provider, options, urlOptions); } return(path); }
public override string ChangeFriendlyUrl(TabInfo tab, string friendlyUrlPath, FriendlyUrlOptions options, string cultureCode, ref string endingPageName, out bool useDnnPagePath, ref List <string> messages) { throw new NotImplementedException(); }
/// <summary> /// Cleans the name for URL. /// </summary> /// <param name="title">The title.</param> /// <param name="options">The options.</param> /// <returns>System.String.</returns> internal new string CleanNameForUrl(string title, FriendlyUrlOptions options) { bool replaced = false; //the base module Url PRovider contains a Url cleaning routine, which will remove illegal and unwanted characters from a string, using the specific friendly url options return base.CleanNameForUrl(title, options, out replaced); }
public override string TransformFriendlyUrlToQueryString(string[] urlParms, int tabId, int portalId, FriendlyUrlOptions options, string cultureCode, PortalAliasInfo portalAlias, ref List <string> messages, out int status, out string location) { throw new NotImplementedException(); }
public override string ChangeFriendlyUrl(TabInfo tab, string friendlyUrlPath, FriendlyUrlOptions options, string cultureCode, ref string endingPageName, out bool useDnnPagePath, ref List <string> messages) { //set default values for out parameters useDnnPagePath = true; if (messages == null) { messages = new List <string>(); } //check if we want to try and modify this Url //first check to see if this Url is an 'edit' Url - something that loads a module-specific page. //we don't want to mess with these, because they're always permissions based Urls and thus //no need to be friendly if (string.IsNullOrEmpty(friendlyUrlPath) == false && Regex.IsMatch(friendlyUrlPath, @"(^|/)(mid|moduleId)/\d+/?", RegexOptions.IgnoreCase) == false) { Hashtable friendlyUrlIndex = null; //the friendly url index is the lookup we use //try and match incoming friendly url path to what we would expect from the module Regex groupUrlRegex = new Regex(@"(?<l>/)?groupid/(?<groupid>\d+)", RegexOptions.IgnoreCase); Match groupUrlMatch = groupUrlRegex.Match(friendlyUrlPath); if (groupUrlMatch.Success) { //this is a group Url we want to try and modify string rawId = groupUrlMatch.Groups["groupid"].Value; int groupId = 0; if (int.TryParse(rawId, out groupId)) { //we have obtained the groupId out of the Url //get the friendlyUrlIndex (it comes from the database via the cache) friendlyUrlIndex = UrlController.GetFriendlyUrlIndex(tab.PortalID, this, options); if (friendlyUrlIndex != null) { //item urls are indexed with i + itemId ("i5") - this is so we could mix and match entities if necessary string furlkey = FriendlyUrlInfo.MakeKey("group", groupId); //create the lookup key for the friendly url index string path = null; //check for a child pages / group ID in the index first if (GroupPagePathTabId > -1 && tab.ParentId == GroupPagePathTabId) { string cpFurlKey = "t" + tab.TabID.ToString() + furlkey; path = (string)friendlyUrlIndex[cpFurlKey]; //check if in the index for a child page } if (path == null) //now check for a match in the index { path = (string)friendlyUrlIndex[furlkey]; //check if in the index } if (path == null) { //don't normally expect to have a no-match with a friendly url path when an itemId was in the Url. //could be a new item that has been created and isn't in the index //do a direct call and find out if it's there path = UrlController.CheckForMissingItemId(groupId, "group", tab.PortalID, this, options, ref messages); } if (path != null) //got a valid path { //url found in the index for this entry. So replace the matched part of the path with the friendly url if (groupUrlMatch.Groups["l"].Success) //if the path had a leading /, then make sure to add that onto the replacement { path = base.EnsureLeadingChar("/", path); } /* finish it all off */ messages.Add("Group Friendly Url Replacing : " + friendlyUrlPath + " in Path : " + path); //this is the point where the Url is modified! //replace the path in the path - which leaves any other parts of a path intact. friendlyUrlPath = groupUrlRegex.Replace(friendlyUrlPath, path);//replace the part in the friendly Url path with it's replacement. //check if this tab is the one specified to not use a path if ((GroupPagePathTabId == tab.TabID || GroupPagePathTabId == tab.ParentId) && HideGroupPagePath) { useDnnPagePath = false;//make this Url relative from the site root } //set back to default.aspx so that DNN Url Rewriter removes it - just in case it wasn't standard endingPageName = DotNetNuke.Common.Globals.glbDefaultPage; } } } } } return(friendlyUrlPath); }
public override string TransformFriendlyUrlToQueryString(string[] urlParms, int tabId, int portalId, FriendlyUrlOptions options, string cultureCode, DotNetNuke.Entities.Portals.PortalAliasInfo portalAlias, ref List <string> messages, out int status, out string location) { status = 200; location = null; string result = string.Empty, Slug = string.Empty, PageName = string.Empty; PortalSettings pS = null; bool PageNameRedirect = false; urlParms = urlParms.Select(s => s.ToLower()).Distinct().ToArray(); List <string> urlParmsList = new List <string>(urlParms).ConvertAll(u => u.ToLower()); int SlugTabID = URLManager.GetSlugTabID(urlParms, ref Slug, tabId, PortalController.Instance.GetPortal(portalId)); if (SlugTabID != -1) //Slug Found { URLEntity CurrentURL = URLManager.GetURL(Slug); //Redirect if it's not the default URL if (CurrentURL != null && !CurrentURL.IsDefault) { InitPortalSettings(ref pS, tabId, portalAlias); return(Redirect(out status, out location, portalId, pS, SlugTabID, result, CurrentURL, null)); } if (pS == null) { pS = new PortalSettings(tabId, portalAlias); } //DNN 8580 //https://dnntracker.atlassian.net/browse/DNN-8580?page=com.googlecode.jira-suite-utilities%3Atransitions-summary-tabpanel ClearUrlParams(ref urlParmsList, ref PageName, Slug, SlugTabID, pS); //Tab not identified...need redirect if (tabId == -1) { InitPortalSettings(ref pS, tabId, portalAlias); if (CurrentURL.IgnorePageName) { return(string.Empty); } else { //Redirect based on Include PageName if we're not on homepage if (SlugTabID != pS.HomeTabId && CurrentURL.PageName && !urlParmsList.Contains(PageName) && !string.Join("/", urlParmsList).Contains(PageName)) { PageNameRedirect = true; } else if (!CurrentURL.PageName && (urlParmsList.Contains(PageName) || string.Join("/", urlParmsList).Contains(PageName))) { PageNameRedirect = true; } //Remove PageName foreach (var item in PageName.Split('/')) { urlParmsList.Remove(item); } //Setup Rewrite Path result = "?TabId=" + SlugTabID.ToString(); } } string remainder = base.CreateQueryStringFromParameters(urlParmsList.ToArray(), -1); string Prefix = urlParmsList.Count % 2 == 0 ? string.Empty : "="; if (PageNameRedirect) { InitPortalSettings(ref pS, tabId, portalAlias); return(Redirect(out status, out location, portalId, pS, SlugTabID, result, CurrentURL, remainder)); } //Rewrite URL to appropriate page if (result.StartsWith("?TabId=") && !string.IsNullOrEmpty(Slug)) { result += "&" + Slug + remainder; } else { result += Slug + remainder; } } return(result); }
public PageUrlResult UpdateCustomUrl(SaveUrlDto dto, TabInfo tab) { PortalSettings portalSettings = PortalController.Instance.GetCurrentSettings() as PortalSettings; string urlPath = dto.Path.ValueOrEmpty().TrimStart('/'); //Clean Url FriendlyUrlOptions options = UrlRewriterUtils.ExtendOptionsForCustomURLs( UrlRewriterUtils.GetOptionsFromSettings(new FriendlyUrlSettings(portalSettings.PortalId))); //now clean the path urlPath = FriendlyUrlController.CleanNameForUrl(urlPath, options, out bool modified); if (modified) { return(new PageUrlResult { Success = false, ErrorMessage = Localization.GetString("CustomUrlPathCleaned.Error"), SuggestedUrlPath = "/" + urlPath }); } //Validate for uniqueness urlPath = FriendlyUrlController.ValidateUrl(urlPath, tab.TabID, portalSettings, out modified); if (modified) { return(new PageUrlResult { Success = false, ErrorMessage = Localization.GetString("UrlPathNotUnique.Error"), SuggestedUrlPath = "/" + urlPath }); } string cultureCode = DNNLocalization.LocaleController.Instance.GetLocales(portalSettings.PortalId) .Where(l => l.Value.KeyID == dto.LocaleKey) .Select(l => l.Value.Code) .SingleOrDefault() ?? portalSettings.DefaultLanguage; string statusCodeKey = dto.StatusCodeKey.ToString(CultureInfo.InvariantCulture); TabUrlInfo tabUrl = tab.TabUrls.SingleOrDefault(t => t.SeqNum == dto.Id && t.HttpStatus == statusCodeKey); if (statusCodeKey == "200") { //We need to check if we are updating a current url or creating a new 200 if (tabUrl == null) { //Just create Url tabUrl = new TabUrlInfo { TabId = tab.TabID, SeqNum = dto.Id, PortalAliasId = dto.SiteAliasKey, PortalAliasUsage = (PortalAliasUsageType)dto.SiteAliasUsage, QueryString = dto.QueryString.ValueOrEmpty(), Url = dto.Path.ValueOrEmpty(), CultureCode = cultureCode, HttpStatus = "200", IsSystem = dto.IsSystem // false }; //TabController.Instance.SaveTabUrl(tabUrl, portalSettings.PortalId, true); SaveTabUrl(tabUrl, portalSettings.PortalId, true); } else { if (!tabUrl.Url.Equals("/" + urlPath, StringComparison.OrdinalIgnoreCase)) { //Change the original 200 url to a redirect tabUrl.HttpStatus = "301"; tabUrl.SeqNum = dto.Id; //TabController.Instance.SaveTabUrl(tabUrl, portalSettings.PortalId, true); SaveTabUrl(tabUrl, portalSettings.PortalId, true); //Add new custom url tabUrl.Url = dto.Path.ValueOrEmpty(); tabUrl.HttpStatus = "200"; tabUrl.SeqNum = tab.TabUrls.Max(t => t.SeqNum) + 1; tabUrl.CultureCode = cultureCode; tabUrl.PortalAliasId = dto.SiteAliasKey; tabUrl.PortalAliasUsage = (PortalAliasUsageType)dto.SiteAliasUsage; tabUrl.QueryString = dto.QueryString.ValueOrEmpty(); //TabController.Instance.SaveTabUrl(tabUrl, portalSettings.PortalId, true); SaveTabUrl(tabUrl, portalSettings.PortalId, true); } else { //Update the original 200 url tabUrl.CultureCode = cultureCode; tabUrl.PortalAliasId = dto.SiteAliasKey; tabUrl.PortalAliasUsage = (PortalAliasUsageType)dto.SiteAliasUsage; tabUrl.QueryString = dto.QueryString.ValueOrEmpty(); //TabController.Instance.SaveTabUrl(tabUrl, portalSettings.PortalId, true); SaveTabUrl(tabUrl, portalSettings.PortalId, true); } } } else { //Update the original non 200 url if (tabUrl == null) { tabUrl = new TabUrlInfo { TabId = tab.TabID, SeqNum = dto.Id, PortalAliasId = dto.SiteAliasKey, PortalAliasUsage = (PortalAliasUsageType)dto.SiteAliasUsage, QueryString = dto.QueryString.ValueOrEmpty(), Url = dto.Path.ValueOrEmpty(), CultureCode = cultureCode, HttpStatus = statusCodeKey, IsSystem = dto.IsSystem // false }; //TabController.Instance.SaveTabUrl(tabUrl, portalSettings.PortalId, true); SaveTabUrl(tabUrl, portalSettings.PortalId, true); } else { tabUrl.CultureCode = cultureCode; tabUrl.PortalAliasId = dto.SiteAliasKey; tabUrl.PortalAliasUsage = (PortalAliasUsageType)dto.SiteAliasUsage; tabUrl.Url = dto.Path.ValueOrEmpty(); tabUrl.HttpStatus = statusCodeKey; tabUrl.QueryString = dto.QueryString.ValueOrEmpty(); //TabController.Instance.SaveTabUrl(tabUrl, portalSettings.PortalId, true); SaveTabUrl(tabUrl, portalSettings.PortalId, true); } } return(new PageUrlResult { Success = true }); }