private static SharedDictionary<string, string> BuildTabDictionary(out PathSizes pathSizes, FriendlyUrlSettings settings, int buildPortalId, SharedDictionary<string, string> tabIndex, out Hashtable homePageSkins, out SharedDictionary<string, string> portalTabPathDictionary, Guid parentTraceId) { if (tabIndex == null) { tabIndex = new SharedDictionary<string, string>(); } homePageSkins = new Hashtable(); pathSizes = new PathSizes { MinAliasDepth = 10, MinTabPathDepth = 10, MaxAliasDepth = 0, MaxTabPathDepth = 0 }; portalTabPathDictionary = null; if (buildPortalId >= 0) { //dictioanry for storing the tab paths in portalTabPathDictionary = new SharedDictionary<string, string>(); //init the duplicate key check dictionary - disposed after the tab dictionary is built var dupCheck = new Dictionary<string, DupKeyCheck>(); //get the list of tabs for all portals //new for 2.0 : only get tabs by portal //770 : keep track of custom alias tabs Dictionary<int, TabInfo> tabs = FriendlyUrlController.GetTabs(buildPortalId, false, settings); const bool hasSiteRootRedirect = true; /* for the requested build portal, add in the standard urls and special rules */ //735 : switch to custom method for getting portal PortalInfo thisPortal = CacheController.GetPortal(buildPortalId, true); List<PortalAliasInfo> chosenAliases; Dictionary<string, string> chosenAliasesCultures; var aliasSpecificCultures = new List<string>(); var usingHttpAliases = new List<string>(); var customHttpAliasesUsed = new List<string>(); GetAliasFromSettings(buildPortalId, out chosenAliases, out chosenAliasesCultures); FriendlyUrlOptions options = UrlRewriterUtils.GetOptionsFromSettings(settings); //keep a list of cultures specific to an alias foreach (string culture in chosenAliasesCultures.Values.Where(culture => aliasSpecificCultures.Contains(culture) == false)) { aliasSpecificCultures.Add(culture); } //the home tabid of the portal - should be the home page for the default language (all others will get page path) int homeTabId = thisPortal.HomeTabId; //Add site root redirects AddSiteRootRedirects(pathSizes, tabIndex, chosenAliases, hasSiteRootRedirect, dupCheck, usingHttpAliases); //add in any internal aliases as valid aliase AddInternalAliases(settings, usingHttpAliases); //loop through each tab and add all of the various Url paths that the tab can be found with, //for all aliases the tab will be used with foreach (TabInfo tab in tabs.Values) { int tabPathDepth = 0; //935 : get the tab path and add to the tab path dictionary if it's not just a straight conversion of the TabPath value //bool modified; string tabPath = TabPathHelper.GetFriendlyUrlTabPath(tab, options, parentTraceId); string tabKey = tab.TabID.ToString(); using (portalTabPathDictionary.GetWriteLock()) { if (portalTabPathDictionary.ContainsKey(tabKey) == false) { portalTabPathDictionary.Add(tabKey, tabPath); } } //now, go through the list of tabs for this portal and build up the dictionary if ((settings.FriendlyAdminHostUrls && tab.PortalID == -1) || tab.PortalID == buildPortalId) { //check if this value has been excluded from being a friendly url bool isExcluded = RewriteController.IsExcludedFromFriendlyUrls(tab, settings, true); string tabCulture = tab.CultureCode; //770 : custom alias per tab (and culture) bool customAliasUsed; var customHttpAlias = ManageCustomAliases(tabCulture, thisPortal, tab, usingHttpAliases, customHttpAliasesUsed, out customAliasUsed); //process each entry for the alias foreach (string httpAlias in usingHttpAliases) { //string httpAlias = portalAlias.HTTPAlias; //761 : allow duplicate tab paths between culture-specific aliases //this is done by ascertaining which culture a particular alias belongs to //then checking tab cultures as they are added to the dictionary string aliasCulture = ""; if (chosenAliasesCultures.ContainsKey(httpAlias.ToLowerInvariant())) { aliasCulture = chosenAliasesCultures[httpAlias.ToLowerInvariant()]; } bool ignoreTabWrongCulture = false; //the tab is the wrong culture, so don't add it to the dictionary if (aliasCulture != "") { if (tabCulture != aliasCulture //this is a language-specific alias that's different to the culture for this alias && !string.IsNullOrEmpty(tabCulture) //and the tab culture is set && aliasSpecificCultures.Contains(tabCulture)) //and there is a specific alias for this tab culture { ignoreTabWrongCulture = true; } } if (!ignoreTabWrongCulture) { if (!isExcluded) { //Add this tab to the dictionary //750 : user profile action not returned as buildPortalId not used tabPathDepth = AddTabToTabDict(tabIndex, dupCheck, httpAlias, aliasCulture, customHttpAlias, thisPortal, tabPath, ref customHttpAliasesUsed, tab, settings, options, homeTabId, ref homePageSkins, parentTraceId); } else { //589 : custom redirects added as 200 status not causing base urls to redirect bool excludeFriendlyUrls = true; //549 : detect excluded friendly urls by putting a known pattern into the dictionary //add this tab to the dictionary, but with the hack pattern [UseBase] to capture the fact it's a base Url //then, if there's redirects for it, add those as well. It's possible to exclude a tab from friendly urls, but //give it custom redirects string rewritePath = null; if (tab.TabUrls.Count > 0) { rewritePath = CreateRewritePath(tab.TabID, ""); string rewritePathKeep = rewritePath; //remember this value to compare AddCustomRedirectsToDictionary(tabIndex, dupCheck, httpAlias, tab, settings, options, ref rewritePath, out tabPathDepth, ref customHttpAliasesUsed, tab.IsDeleted, parentTraceId); if (rewritePath != rewritePathKeep) //check to see the rewrite path is still the same, or did it get changed? { //OK, the rewrite path was modifed by the custom redirects dictionary add excludeFriendlyUrls = false; } } if (excludeFriendlyUrls) { rewritePath = "[UseBase]"; //use hack pattern to indicate not to rewrite on this Url } AddToTabDict(tabIndex, dupCheck, httpAlias, tab.TabPath, rewritePath, tab.TabID, UrlEnums.TabKeyPreference.TabRedirected, ref tabPathDepth, true, false); } } else { //ignoring this tab because the alias culture doesn't match to the tab culture //however, we need to add it to the dictionary in case there's an old link (pre-translation/pre-friendly url/pre-alias&culture linked) string rewritePath = CreateRewritePath(tab.TabID, tabCulture); AddToTabDict(tabIndex, dupCheck, httpAlias, tab.TabPath, rewritePath, tab.TabID, UrlEnums.TabKeyPreference.TabRedirected, ref tabPathDepth, true, tab.IsDeleted); } pathSizes.SetTabPathDepth(tabPathDepth); } if (customHttpAlias != "" && customAliasUsed == false && usingHttpAliases.Contains(customHttpAlias)) { //this was using a custom Http Alias, so remove this from the using list if it wasn't already there usingHttpAliases.Remove(customHttpAlias); } } } //now build the standard Urls for all of the aliases that are used foreach (string httpAlias in usingHttpAliases) { //750 : using -1 instead of buildPortalId //850 : set culture code based on httpALias, where specific culture //is being associated with httpAlias string cultureCode = null; if (chosenAliasesCultures.ContainsKey(httpAlias)) { cultureCode = chosenAliasesCultures[httpAlias]; } AddStandardPagesToDict(tabIndex, dupCheck, httpAlias, buildPortalId, cultureCode); } //and for any custom urls being used foreach (string httpAlias in customHttpAliasesUsed) { //750 : using -1 instead of buildPortalId //is being associated with httpAlias string cultureCode = null; if (chosenAliasesCultures.ContainsKey(httpAlias)) { cultureCode = chosenAliasesCultures[httpAlias]; } AddStandardPagesToDict(tabIndex, dupCheck, httpAlias, buildPortalId, cultureCode); //if any site root, add those as well. So if any module providers or rules work //on the custom http aliases, they will work as well. if (hasSiteRootRedirect) { int tempPathDepth = 0; AddToTabDict(tabIndex, dupCheck, httpAlias, "*", "", -1, UrlEnums.TabKeyPreference.TabOK, ref tempPathDepth, false, false); } } //do a check of the rebuildData object, to see if there is anything we needed to add to the dictionary var rebuildData = (PageIndexData)DataCache.GetCache("rebuildData"); if (rebuildData != null) { //there was rebuild data stored so we could do things post-dictionary rebuild if (rebuildData.LastPageKey != null && rebuildData.LastPageValue != null) { if (tabIndex.ContainsKey(rebuildData.LastPageKey) == false) { //add this item to the list of pages, even though it no longer exists tabIndex.Add(rebuildData.LastPageKey, rebuildData.LastPageValue); } } //now clear out the rebuildData object, because we've checked and used it DataCache.RemoveCache("rebuildData"); } } return tabIndex; }
private static void AddSiteRootRedirects(PathSizes pathSizes, SharedDictionary<string, string> tabIndex, IEnumerable<PortalAliasInfo> chosenAliases, bool hasSiteRootRedirect, Dictionary<string, DupKeyCheck> dupCheck, ICollection<string> usingHttpAliases) { foreach (PortalAliasInfo alias in chosenAliases) //and that is once per portal alias per portal { string httpAlias = alias.HTTPAlias; //check to see if there is a parameter rewrite rule that allows for parameters on the site root if (hasSiteRootRedirect) { int tempPathDepth = 0; AddToTabDict(tabIndex, dupCheck, httpAlias, "*", "", -1, UrlEnums.TabKeyPreference.TabOK, ref tempPathDepth, false, false); } pathSizes.SetAliasDepth(httpAlias); //keep track of the http Aliases, this will be used to feed into the tab dictionary (ie, one alias per tab) usingHttpAliases.Add(httpAlias.ToLowerInvariant()); } }