1: <%@ Control Language="C#" %>
2: <%@Assembly Name="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"%>
3: <%@Assembly Name="Microsoft.SharePoint.Publishing, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"%>
4: <%@Register TagPrefix="CMS" Assembly="Microsoft.SharePoint.Publishing, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" namespace="Microsoft.SharePoint.Publishing.WebControls"%>
5: <%@ Import Namespace="System.Collections" %>
6: <%@ Import Namespace="System.Collections.Specialized" %>
7: <%@ Import Namespace="System.Collections.Generic" %>
8: <%@ Import Namespace="System.Collections.ObjectModel" %>
9: <%@ Import Namespace="System.Globalization" %>
10: <%@ Import Namespace="Microsoft.SharePoint" %>
11: <%@ Import Namespace="Microsoft.SharePoint.Utilities" %>
12: <%@ Import Namespace="Microsoft.SharePoint.WebControls" %>
13: <%@ Import Namespace="Microsoft.SharePoint.Publishing" %>
14: <script runat="server">
15: private const string QualityValuePrefix = ";q=";
16: private enum PropertiesOnLabelToUse
17: {
18: Language,
19: Locale
20: }
21: private enum MatchingPreference
22: {
23: ImpreciseOrderFirst,
24: PreciseMatch
25: }
26: private PropertiesOnLabelToUse PropertyOnLabelToUse
27: {
28: get { return this.propertyOnLabelToUse; }
29: set { this.propertyOnLabelToUse = value; }
30: }
31: private PropertiesOnLabelToUse propertyOnLabelToUse = PropertiesOnLabelToUse.Locale;
32: private MatchingPreference PreferenceOrder
33: {
34: get { return this.preferenceOrder; }
35: set { this.preferenceOrder = value; }
36: }
37: private MatchingPreference preferenceOrder = MatchingPreference.ImpreciseOrderFirst;
38: protected override void OnLoad(EventArgs e)
39: {
40: base.OnLoad(e);
41: string targetUrl = this.GetRedirectTargetUrl();
42: if (!string.IsNullOrEmpty(targetUrl))
43: {
44: SPUtility.Redirect(targetUrl, SPRedirectFlags.Default, Context);
45: }
46: }
47: private string GetRedirectTargetUrl()
48: {
49: const string c_strDefaultLocal = "1033"; // CHANGED (1033:english / 1031:deutsch)
50:
51: ReadOnlyCollection<VariationLabel> spawnedLabels = Variations.Current.UserAccessibleLabels;
52: if (spawnedLabels.Count > 0)
53: {
54: string sourceLabelUrl = string.Empty;
55: string strDefaultlUrl = string.Empty; // CHANGED
56:
57: Dictionary<string, string> cultureCodeToUrlMapping = new Dictionary<string, string>();
58: Dictionary<string, string> cultureCodeStrippedToUrlMapping = new Dictionary<string, string>();
59: foreach (VariationLabel label in spawnedLabels)
60: {
61: if (label.IsSource)
62: {
63: sourceLabelUrl = label.TopWebUrl;
64: }
65: else
66: {
67: if (label.Locale == c_strDefaultLocal) // CHANGED
68: {
69: strDefaultlUrl = label.TopWebUrl; // CHANGED
70: }
71: }
72: CultureInfo labelCultureInfo = this.GetLabelCultureInfo(label);
73: string labelCultureInfoName = labelCultureInfo.Name.ToUpperInvariant();
74: if (!cultureCodeToUrlMapping.ContainsKey(labelCultureInfoName) || label.IsSource)
75: {
76: cultureCodeToUrlMapping.Remove(labelCultureInfoName);
77: cultureCodeToUrlMapping.Add(labelCultureInfoName, label.TopWebUrl);
78: string strippedCode = labelCultureInfoName.Split('-')[0];
79: if (!cultureCodeStrippedToUrlMapping.ContainsKey(strippedCode) || label.IsSource)
80: {
81: cultureCodeStrippedToUrlMapping.Remove(strippedCode);
82: cultureCodeStrippedToUrlMapping.Add(strippedCode, label.TopWebUrl);
83: }
84: }
85: }
86: string matchedUrl;
87: if (MatchingPreference.ImpreciseOrderFirst == this.preferenceOrder)
88: {
89: matchedUrl = this.GetRedirectTargetUrlImpreciseOrderFirst(
90: cultureCodeToUrlMapping, cultureCodeStrippedToUrlMapping);
91: }
92: else
93: {
94: matchedUrl = this.GetRedirectTargetUrlPreciseMatch(
95: cultureCodeToUrlMapping, cultureCodeStrippedToUrlMapping);
96: }
97: //return (string.IsNullOrEmpty(matchedUrl) ? sourceLabelUrl : matchedUrl);
98: return (string.IsNullOrEmpty(matchedUrl) ? strDefaultlUrl : matchedUrl); // CHANGED
99: }
100: return null;
101: }
102: private CultureInfo GetLabelCultureInfo(VariationLabel label)
103: {
104: if (PropertiesOnLabelToUse.Locale == this.propertyOnLabelToUse)
105: {
106: return new CultureInfo(Convert.ToInt32(label.Locale, CultureInfo.InvariantCulture));
107: }
108: else
109: {
110: return new CultureInfo(label.Language);
111: }
112: }
113: private string GetRedirectTargetUrlImpreciseOrderFirst(Dictionary<string, string> cultureCodeToUrlMapping, Dictionary<string, string> cultureCodeStrippedToUrlMapping)
114: {
115: string[] browserPrefLanguages = this.GetUserLanguages();
116: if (null == browserPrefLanguages)
117: return null;
118: string browserPrefLang;
119: string browserPrefLangStripped;
120: for (int i = 0; i < browserPrefLanguages.Length; i++)
121: {
122: browserPrefLang = browserPrefLanguages[i].ToUpperInvariant();
123: if (cultureCodeToUrlMapping.ContainsKey(browserPrefLang))
124: {
125: return cultureCodeToUrlMapping[browserPrefLang];
126: }
127: browserPrefLangStripped = browserPrefLang.Split('-')[0];
128: if ((browserPrefLang != browserPrefLangStripped) &&
129: (cultureCodeToUrlMapping.ContainsKey(browserPrefLangStripped)))
130: {
131: return cultureCodeToUrlMapping[browserPrefLangStripped];
132: }
133: if (cultureCodeStrippedToUrlMapping.ContainsKey(browserPrefLangStripped))
134: {
135: return cultureCodeStrippedToUrlMapping[browserPrefLangStripped];
136: }
137: }
138: return null;
139: }
140: private string GetRedirectTargetUrlPreciseMatch(Dictionary<string, string> cultureCodeToUrlMapping, Dictionary<string, string> cultureCodeStrippedToUrlMapping)
141: {
142: string[] browserPrefLanguages = this.GetUserLanguages();
143: if (null == browserPrefLanguages)
144: return null;
145: for (int i = 0; i < browserPrefLanguages.Length; i++)
146: {
147: string browserPrefLanguageName = browserPrefLanguages[i].ToUpperInvariant();
148: if (cultureCodeToUrlMapping.ContainsKey(browserPrefLanguageName))
149: {
150: return cultureCodeToUrlMapping[browserPrefLanguageName];
151: }
152: }
153: for (int i = 0; i < browserPrefLanguages.Length; i++)
154: {
155: string browserPrefLanguageName = browserPrefLanguages[i].ToUpperInvariant();
156: if (cultureCodeStrippedToUrlMapping.ContainsKey(browserPrefLanguageName))
157: {
158: return cultureCodeStrippedToUrlMapping[browserPrefLanguageName];
159: }
160: }
161: string browserPrefLangStripped;
162: for (int i = 0; i < browserPrefLanguages.Length; i++)
163: {
164: browserPrefLangStripped = browserPrefLanguages[i].Split('-')[0].ToUpperInvariant();
165: if (cultureCodeToUrlMapping.ContainsKey(browserPrefLangStripped))
166: {
167: return cultureCodeToUrlMapping[browserPrefLangStripped];
168: }
169: }
170: for (int i = 0; i < browserPrefLanguages.Length; i++)
171: {
172: browserPrefLangStripped = browserPrefLanguages[i].Split('-')[0].ToUpperInvariant();
173: if (cultureCodeStrippedToUrlMapping.ContainsKey(browserPrefLangStripped))
174: {
175: return cultureCodeStrippedToUrlMapping[browserPrefLangStripped];
176: }
177: }
178: return null;
179: }
180: private string[] GetUserLanguages()
181: {
182: string[] browserPrefLanguages = Page.Request.UserLanguages;
183: if (null != browserPrefLanguages)
184: {
185: int qualityIndexPos = -1;
186: for (int i = 0; i < browserPrefLanguages.Length; i++)
187: {
188: qualityIndexPos = browserPrefLanguages[i].IndexOf(QualityValuePrefix, StringComparison.Ordinal);
189: if (qualityIndexPos > 0)
190: {
191: browserPrefLanguages[i] = browserPrefLanguages[i].Substring(0, qualityIndexPos);
192: }
193: }
194: }
195: return browserPrefLanguages;
196: }
197: private string ConcatUrls(string firstPart, string secondPart)
198: {
199: if (firstPart.EndsWith("/"))
200: {
201: if (secondPart.StartsWith("/"))
202: {
203: firstPart = firstPart.TrimEnd('/');
204: }
205: return firstPart + secondPart;
206: }
207: else
208: {
209: if (secondPart.StartsWith("/"))
210: return firstPart + secondPart;
211: else
212: return firstPart + "/" + secondPart;
213: }
214: }
215: </script>
216: <!--
217: The following control renders runtime fallback logic when the logic above cannot determine proper Variation sub Site to redirect to.
218: If the control is removed, it will affect the runtime fallback behavior of the Variation Root redirect.
219: -->
220: <cms:VariationsRootLandingRunTime id="VariationsRootLandingRunTime" runat="server"/>
221: <!--
222: The following control renders UI for SharePointDesigner. If the control is removed,
223: it will affect SharePointDesigner design time experience.
224: -->
225: <cms:VariationsRootLandingDesignTime id="VariationsRootLandingDesignTime" runat="server"/>