FixVariationRelationships

  1. #if MOSS
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Collections.Specialized;
  5. using System.Text;
  6. using Lapointe.SharePoint.STSADM.Commands.OperationHelpers;
  7. using Lapointe.SharePoint.STSADM.Commands.SPValidators;
  8. using Microsoft.SharePoint;
  9. using Microsoft.SharePoint.Publishing;
  10.  
  11. namespace Lapointe.SharePoint.STSADM.Commands.Pages
  12. {
  13. public class FixVariationRelationships : SPOperation
  14. {
  15. private static bool m_verbose;
  16. private static string url = null;
  17.  
  18.  
  19. /// <summary>
  20. /// Initializes a new instance of the <see cref="FixPublishingPagesPageLayoutUrl"> class.
  21. /// </see>
  22. public FixVariationRelationships()
  23. {
  24. var parameters = new SPParamCollection();
  25. parameters.Add(new SPParam(&quot;url&quot;, &quot;url&quot;, true, null, new SPNonEmptyValidator(), &quot;Please specify the site collection url.&quot;));
  26. parameters.Add(new SPParam(&quot;pagename&quot;, &quot;page&quot;, false, null, new SPNonEmptyValidator()));
  27. parameters.Add(new SPParam(&quot;verbose&quot;, &quot;v&quot;));
  28. parameters.Add(new SPParam(&quot;web&quot;, &quot;w&quot;, false, null, new SPNonEmptyValidator()));
  29.  
  30. var sb = new StringBuilder();
  31. sb.Append(&quot;\r\n\r\nLinks publishing pages using information in the hidden Relationship List list.\r\n\r\nParameters:&quot;);
  32. sb.Append(&quot;\r\n\t-url <url>&quot;);
  33. sb.Append(&quot;\r\n\t[-pagename <name>]&quot;);
  34. sb.Append(&quot;\r\n\t[-verbose]&quot;);
  35. sb.Append(&quot;\r\n\t[-web <path><summary>
  36. /// Gets the help message.
  37. /// </summary>
  38. /// <param name="command"></param>The command.
  39. /// <returns></returns>
  40. public override string GetHelpMessage(string command)
  41. {
  42. return HelpMessage;
  43. }
  44.  
  45.  
  46. /// <summary>
  47. /// Runs the specified command.
  48. /// </summary>
  49. /// <param name="command"></param>The command.
  50. /// <param name="keyValues"></param>The key values.
  51. /// <param name="output"></param>The output.
  52. /// <returns></returns>
  53. public override int Execute(string command, StringDictionary keyValues, out string output)
  54. {
  55. output = string.Empty;
  56.  
  57. url = Params[&quot;url&quot;].Value;
  58. if (url != null) url = url.TrimEnd('/');
  59.  
  60. string webUrl = Params[&quot;web&quot;].Value;
  61.  
  62. string pageName = null;
  63. if (Params[&quot;pagename&quot;].UserTypedIn)
  64. pageName = Params[&quot;pagename&quot;].Value;
  65.  
  66. using (var site = new SPSite(url))
  67. {
  68. Process(site, Params[&quot;verbose&quot;].UserTypedIn, pageName,webUrl);
  69. }
  70. return OUTPUT_SUCCESS;
  71. }
  72.  
  73. #endregion
  74.  
  75. /// <summary>
  76. /// Processes the specified site.
  77. /// </summary>
  78. /// <param name="site"></param>The site.
  79. /// <param name="verbose"></param>if set to <c>true</c> [verbose].
  80. /// <param name="pageName"></param>Name of the page.
  81. /// <param name="webUrl"></param>Optional name of the web
  82. public static void Process(SPSite site, bool verbose, string pageName, string webUrl)
  83. {
  84. m_verbose = verbose;
  85.  
  86. using (SPWeb rootWeb = site.RootWeb)
  87. {
  88. Log(string.Format(&quot;Begin processing site collection '{0}', passed url was {1}.&quot;, site.ServerRelativeUrl, url));
  89.  
  90. SPList relationshipList = rootWeb.Lists[&quot;Relationships List&quot;];
  91. SPList variationLabelsList = rootWeb.Lists[&quot;Variation Labels&quot;];
  92. PublishingWeb sourceLabelWeb = null;
  93. var labelWebs = new Dictionary<publishingweb,>();
  94. foreach (SPListItem item in variationLabelsList.Items)
  95. {
  96. Log(string.Format(&quot;Getting variation web '{0}'.&quot;, item[&quot;Label&quot;]));
  97.  
  98. SPWeb web;
  99. if (webUrl != null)
  100. {
  101. Log(String.Format(&quot;Looking up web {0}&quot;, webUrl));
  102. web = site.OpenWeb(webUrl+&quot;/&quot;+item[&quot;Label&quot;].ToString());
  103. }
  104. else
  105. {
  106. Log(String.Format(&quot;Using Root-Site, no web Parameter provided&quot;));
  107. web = site.OpenWeb(item[&quot;Label&quot;].ToString());
  108. }
  109.  
  110. if (!PublishingWeb.IsPublishingWeb(web))
  111. continue;
  112.  
  113. if ((bool) item[&quot;Is Source&quot;])
  114. sourceLabelWeb = PublishingWeb.GetPublishingWeb(web);
  115.  
  116. labelWebs.Add(PublishingWeb.GetPublishingWeb(web), (bool) item[&quot;Is Source&quot;]);
  117. }
  118. if (sourceLabelWeb == null)
  119. throw new SPException(&quot;Unable to identify source label web.&quot;);
  120.  
  121. var sourcePages = new Dictionary<publishingpage,>();
  122.  
  123. Log(string.Format(&quot;Begin resetting GroupIDs.&quot;));
  124.  
  125. // First - make sure that all the matching pages have the same group ID
  126. foreach (PublishingPage page in sourceLabelWeb.GetPublishingPages())
  127. {
  128. if (!(pageName == null || pageName.ToLowerInvariant() == page.Name.ToLowerInvariant()))
  129. continue;
  130.  
  131. Log(string.Format(&quot;Procesing page '{0}'.&quot;, page.Url));
  132.  
  133. Guid groupID = Guid.Empty;
  134. if (page.Fields.ContainsField(&quot;PublishingVariationGroupID&quot;))
  135. {
  136. if (page.ListItem[&quot;PublishingVariationGroupID&quot;] + &quot;&quot; != &quot;&quot; &amp;&amp;
  137. page.ListItem[&quot;PublishingVariationGroupID&quot;] + &quot;&quot; != Guid.Empty.ToString())
  138. {
  139. groupID = new Guid(page.ListItem[&quot;PublishingVariationGroupID&quot;] + &quot;&quot;);
  140. Log(
  141. string.Format(&quot;GroupID '{0}' found in variation source '{1}'.&quot;, groupID,
  142. sourceLabelWeb.Url));
  143. }
  144. }
  145. else
  146. {
  147. Log(string.Format(&quot;Unable to locate PublishingVariationGroupID field for page '{0}'&quot;, pageName));
  148. }
  149. if (groupID == Guid.Empty)
  150. {
  151. Log(string.Format(&quot;GroupID not found in source - begin searching variations.&quot;));
  152. // See if we can find a group ID in matching pages within the other variations
  153. foreach (PublishingWeb varWeb in labelWebs.Keys)
  154. {
  155. if (labelWebs[varWeb])
  156. continue; // Don't consider the source as we've already done that
  157. try
  158. {
  159. // Get the matching page
  160. PublishingPage varPage = varWeb.GetPublishingPages()[page.Url];
  161. if (varPage == null)
  162. continue;
  163. if (varPage.Fields.ContainsField(&quot;PublishingVariationGroupID&quot;))
  164. {
  165. // If the matching page has a group ID then use that
  166. if (varPage.ListItem[&quot;PublishingVariationGroupID&quot;] + &quot;&quot; != &quot;&quot;)
  167. groupID = new Guid(varPage.ListItem[&quot;PublishingVariationGroupID&quot;] + &quot;&quot;);
  168. }
  169. }
  170. catch (ArgumentException)
  171. {
  172. }
  173. if (groupID.ToString() != Guid.Empty.ToString())
  174. {
  175. Log(string.Format(&quot;GroupID '{0}' found in variation '{1}'.&quot;, groupID, varWeb.Url));
  176. break;
  177. }
  178. }
  179. }
  180. if (groupID == Guid.Empty)
  181. {
  182. groupID = Guid.NewGuid();
  183. Log(string.Format(&quot;GroupID not found - new GroupID created: '{0}'.&quot;, groupID));
  184. }
  185.  
  186. // Now that we have a groupID reset all pages to use that same groupID
  187. Log(string.Format(&quot;Begin resetting variations to use new GroupID.&quot;));
  188. foreach (PublishingWeb varWeb in labelWebs.Keys)
  189. {
  190. try
  191. {
  192. // Get the matching page
  193. PublishingPage varPage = varWeb.GetPublishingPages()[page.Url];
  194. if (varPage == null)
  195. continue;
  196. if (varPage.Fields.ContainsField(&quot;PublishingVariationGroupID&quot;))
  197. {
  198. // Set the groupID if it doesn't match what we have
  199. if ((varPage.ListItem[&quot;PublishingVariationGroupID&quot;] + &quot;&quot;).ToLower() !=
  200. groupID.ToString().ToLower())
  201. {
  202. Log(
  203. string.Format(&quot;Assigning GroupID to page '{0}' in variation '{1}'.&quot;,
  204. varPage.Url, varWeb.Url));
  205.  
  206. varPage.ListItem[&quot;PublishingVariationGroupID&quot;] = groupID.ToString();
  207. varPage.ListItem.SystemUpdate();
  208. }
  209. }
  210. }
  211. catch (ArgumentException)
  212. {
  213. }
  214. }
  215. Log(string.Format(&quot;Finished resetting variations to use new GroupID.&quot;));
  216.  
  217. sourcePages.Add(page, groupID);
  218. }
  219. // Now that all the pages have been reset to use the same group ID for each variation we can now deal with the relationships list
  220. Log(string.Format(&quot;Finished resetting GroupIDs.\r\n&quot;));
  221. Log(string.Format(&quot;X Begin processing of Relationships List.&quot;));
  222.  
  223. foreach (PublishingPage page in sourcePages.Keys)
  224. {
  225. foreach (PublishingWeb varWeb in labelWebs.Keys)
  226. {
  227. Log(string.Format(&quot;Processing page '{0}' on variation '{1}'&quot;, page.Url, varWeb.Url));
  228.  
  229. var objectID = new SPFieldUrlValue();
  230. objectID.Description = varWeb.Web.ServerRelativeUrl + &quot;/&quot; + page.Url;
  231. objectID.Url = site.MakeFullUrl(objectID.Description);
  232. string groupID = sourcePages[page].ToString();
  233.  
  234. SPListItem relationshipItem = null;
  235. foreach (SPListItem item in relationshipList.Items)
  236. {
  237. if (item[&quot;ObjectID&quot;].ToString().ToLower() == objectID.ToString().ToLower())
  238. {
  239. Log(
  240. string.Format(&quot;Found item in relationships list matching ObjectID '{0}'.&quot;,
  241. objectID.Description));
  242.  
  243. relationshipItem = item;
  244. relationshipItem[&quot;Deleted&quot;] = varWeb.GetPublishingPages()[page.Url] == null;
  245. break;
  246. }
  247. }
  248. if (relationshipItem == null)
  249. {
  250. Log(
  251. string.Format(
  252. &quot;Unable to locate item in Relationships List for ObjectID '{0}' - creating a new item.&quot;,
  253. objectID.Description));
  254. // We couldn't find a matching item for the variation so we have to create one
  255. relationshipItem =
  256. relationshipList.Items.Add(relationshipList.RootFolder.ServerRelativeUrl,
  257. SPFileSystemObjectType.File);
  258. relationshipItem[&quot;ObjectID&quot;] = objectID.ToString();
  259. relationshipItem[&quot;Deleted&quot;] = varWeb.GetPublishingPages()[page.Url] == null;
  260. }
  261. relationshipItem[&quot;GroupID&quot;] = groupID;
  262. relationshipItem.Update();
  263.  
  264. Log(
  265. string.Format(&quot;Relationships List item updated - assigning link to page '{0}'.&quot;,
  266. page.Url));
  267.  
  268. // Now that the relationship list item is set the way we need it we have to link the corresponding page to the item.
  269. try
  270. {
  271. PublishingPage varPage = varWeb.GetPublishingPages()[page.Url];
  272. if (varPage == null)
  273. continue;
  274. string newLinkID = &quot;/&quot; +
  275. (rootWeb.ServerRelativeUrl + &quot;/&quot; + relationshipItem.Url).Trim('/');
  276. newLinkID = site.MakeFullUrl(newLinkID.Replace(&quot; &quot;, &quot;%20&quot;)) + &quot;, &quot; + newLinkID;
  277.  
  278. varPage.ListItem[&quot;PublishingVariationRelationshipLinkFieldID&quot;] = newLinkID;
  279. varPage.ListItem.SystemUpdate();
  280. }
  281. catch (ArgumentException)
  282. {
  283. }
  284. }
  285. }
  286. Log(string.Format(&quot;Finished processing of Relationships List.&quot;));
  287.  
  288. foreach (PublishingWeb web in labelWebs.Keys)
  289. {
  290. web.Web.Dispose();
  291. }
  292. Log(string.Format(&quot;Finished processing site collection '{0}'.&quot;, site.ServerRelativeUrl));
  293. }
  294. }
  295.  
  296.  
  297. /// <summary>
  298. /// Logs the specified message.
  299. /// </summary>
  300. /// <param name="message"></param>The message.
  301. private static void Log(string message)
  302. {
  303. if (m_verbose)
  304. Console.WriteLine(&quot;Progress: {0}&quot;, message);
  305. }
  306. }
  307. }
  308.  
  309. #endif
  310. </publishingpage,></publishingweb,></path></name></url></summary>