#if MOSS
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Text;
using Lapointe.SharePoint.STSADM.Commands.OperationHelpers;
using Lapointe.SharePoint.STSADM.Commands.SPValidators;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Publishing;
namespace Lapointe.SharePoint.STSADM.Commands.Pages
{
public class FixVariationRelationships : SPOperation
{
private static bool m_verbose;
private static string url = null;
///
/// Initializes a new instance of the class.
///
public FixVariationRelationships()
{
var parameters = new SPParamCollection();
parameters.Add(new SPParam("url", "url", true, null, new SPNonEmptyValidator(), "Please specify the site collection url."));
parameters.Add(new SPParam("pagename", "page", false, null, new SPNonEmptyValidator()));
parameters.Add(new SPParam("verbose", "v"));
parameters.Add(new SPParam("web", "w", false, null, new SPNonEmptyValidator()));
var sb = new StringBuilder();
sb.Append("\r\n\r\nLinks publishing pages using information in the hidden Relationship List list.\r\n\r\nParameters:");
sb.Append("\r\n\t-url ");
sb.Append("\r\n\t[-pagename ]");
sb.Append("\r\n\t[-verbose]");
sb.Append("\r\n\t[-web
/// Gets the help message.
///
/// The command.
///
public override string GetHelpMessage(string command)
{
return HelpMessage;
}
///
/// Runs the specified command.
///
/// The command.
/// The key values.
/// The output.
///
public override int Execute(string command, StringDictionary keyValues, out string output)
{
output = string.Empty;
url = Params["url"].Value;
if (url != null) url = url.TrimEnd('/');
string webUrl = Params["web"].Value;
string pageName = null;
if (Params["pagename"].UserTypedIn)
pageName = Params["pagename"].Value;
using (var site = new SPSite(url))
{
Process(site, Params["verbose"].UserTypedIn, pageName,webUrl);
}
return OUTPUT_SUCCESS;
}
#endregion
///
/// Processes the specified site.
///
/// The site.
/// if set to true [verbose].
/// Name of the page.
/// Optional name of the web
public static void Process(SPSite site, bool verbose, string pageName, string webUrl)
{
m_verbose = verbose;
using (SPWeb rootWeb = site.RootWeb)
{
Log(string.Format("Begin processing site collection '{0}', passed url was {1}.", site.ServerRelativeUrl, url));
SPList relationshipList = rootWeb.Lists["Relationships List"];
SPList variationLabelsList = rootWeb.Lists["Variation Labels"];
PublishingWeb sourceLabelWeb = null;
var labelWebs = new Dictionary();
foreach (SPListItem item in variationLabelsList.Items)
{
Log(string.Format("Getting variation web '{0}'.", item["Label"]));
SPWeb web;
if (webUrl != null)
{
Log(String.Format("Looking up web {0}", webUrl));
web = site.OpenWeb(webUrl+"/"+item["Label"].ToString());
}
else
{
Log(String.Format("Using Root-Site, no web Parameter provided"));
web = site.OpenWeb(item["Label"].ToString());
}
if (!PublishingWeb.IsPublishingWeb(web))
continue;
if ((bool) item["Is Source"])
sourceLabelWeb = PublishingWeb.GetPublishingWeb(web);
labelWebs.Add(PublishingWeb.GetPublishingWeb(web), (bool) item["Is Source"]);
}
if (sourceLabelWeb == null)
throw new SPException("Unable to identify source label web.");
var sourcePages = new Dictionary();
Log(string.Format("Begin resetting GroupIDs."));
// First - make sure that all the matching pages have the same group ID
foreach (PublishingPage page in sourceLabelWeb.GetPublishingPages())
{
if (!(pageName == null || pageName.ToLowerInvariant() == page.Name.ToLowerInvariant()))
continue;
Log(string.Format("Procesing page '{0}'.", page.Url));
Guid groupID = Guid.Empty;
if (page.Fields.ContainsField("PublishingVariationGroupID"))
{
if (page.ListItem["PublishingVariationGroupID"] + "" != "" &&
page.ListItem["PublishingVariationGroupID"] + "" != Guid.Empty.ToString())
{
groupID = new Guid(page.ListItem["PublishingVariationGroupID"] + "");
Log(
string.Format("GroupID '{0}' found in variation source '{1}'.", groupID,
sourceLabelWeb.Url));
}
}
else
{
Log(string.Format("Unable to locate PublishingVariationGroupID field for page '{0}'", pageName));
}
if (groupID == Guid.Empty)
{
Log(string.Format("GroupID not found in source - begin searching variations."));
// See if we can find a group ID in matching pages within the other variations
foreach (PublishingWeb varWeb in labelWebs.Keys)
{
if (labelWebs[varWeb])
continue; // Don't consider the source as we've already done that
try
{
// Get the matching page
PublishingPage varPage = varWeb.GetPublishingPages()[page.Url];
if (varPage == null)
continue;
if (varPage.Fields.ContainsField("PublishingVariationGroupID"))
{
// If the matching page has a group ID then use that
if (varPage.ListItem["PublishingVariationGroupID"] + "" != "")
groupID = new Guid(varPage.ListItem["PublishingVariationGroupID"] + "");
}
}
catch (ArgumentException)
{
}
if (groupID.ToString() != Guid.Empty.ToString())
{
Log(string.Format("GroupID '{0}' found in variation '{1}'.", groupID, varWeb.Url));
break;
}
}
}
if (groupID == Guid.Empty)
{
groupID = Guid.NewGuid();
Log(string.Format("GroupID not found - new GroupID created: '{0}'.", groupID));
}
// Now that we have a groupID reset all pages to use that same groupID
Log(string.Format("Begin resetting variations to use new GroupID."));
foreach (PublishingWeb varWeb in labelWebs.Keys)
{
try
{
// Get the matching page
PublishingPage varPage = varWeb.GetPublishingPages()[page.Url];
if (varPage == null)
continue;
if (varPage.Fields.ContainsField("PublishingVariationGroupID"))
{
// Set the groupID if it doesn't match what we have
if ((varPage.ListItem["PublishingVariationGroupID"] + "").ToLower() !=
groupID.ToString().ToLower())
{
Log(
string.Format("Assigning GroupID to page '{0}' in variation '{1}'.",
varPage.Url, varWeb.Url));
varPage.ListItem["PublishingVariationGroupID"] = groupID.ToString();
varPage.ListItem.SystemUpdate();
}
}
}
catch (ArgumentException)
{
}
}
Log(string.Format("Finished resetting variations to use new GroupID."));
sourcePages.Add(page, groupID);
}
// 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
Log(string.Format("Finished resetting GroupIDs.\r\n"));
Log(string.Format("X Begin processing of Relationships List."));
foreach (PublishingPage page in sourcePages.Keys)
{
foreach (PublishingWeb varWeb in labelWebs.Keys)
{
Log(string.Format("Processing page '{0}' on variation '{1}'", page.Url, varWeb.Url));
var objectID = new SPFieldUrlValue();
objectID.Description = varWeb.Web.ServerRelativeUrl + "/" + page.Url;
objectID.Url = site.MakeFullUrl(objectID.Description);
string groupID = sourcePages[page].ToString();
SPListItem relationshipItem = null;
foreach (SPListItem item in relationshipList.Items)
{
if (item["ObjectID"].ToString().ToLower() == objectID.ToString().ToLower())
{
Log(
string.Format("Found item in relationships list matching ObjectID '{0}'.",
objectID.Description));
relationshipItem = item;
relationshipItem["Deleted"] = varWeb.GetPublishingPages()[page.Url] == null;
break;
}
}
if (relationshipItem == null)
{
Log(
string.Format(
"Unable to locate item in Relationships List for ObjectID '{0}' - creating a new item.",
objectID.Description));
// We couldn't find a matching item for the variation so we have to create one
relationshipItem =
relationshipList.Items.Add(relationshipList.RootFolder.ServerRelativeUrl,
SPFileSystemObjectType.File);
relationshipItem["ObjectID"] = objectID.ToString();
relationshipItem["Deleted"] = varWeb.GetPublishingPages()[page.Url] == null;
}
relationshipItem["GroupID"] = groupID;
relationshipItem.Update();
Log(
string.Format("Relationships List item updated - assigning link to page '{0}'.",
page.Url));
// Now that the relationship list item is set the way we need it we have to link the corresponding page to the item.
try
{
PublishingPage varPage = varWeb.GetPublishingPages()[page.Url];
if (varPage == null)
continue;
string newLinkID = "/" +
(rootWeb.ServerRelativeUrl + "/" + relationshipItem.Url).Trim('/');
newLinkID = site.MakeFullUrl(newLinkID.Replace(" ", "%20")) + ", " + newLinkID;
varPage.ListItem["PublishingVariationRelationshipLinkFieldID"] = newLinkID;
varPage.ListItem.SystemUpdate();
}
catch (ArgumentException)
{
}
}
}
Log(string.Format("Finished processing of Relationships List."));
foreach (PublishingWeb web in labelWebs.Keys)
{
web.Web.Dispose();
}
Log(string.Format("Finished processing site collection '{0}'.", site.ServerRelativeUrl));
}
}
///
/// Logs the specified message.
///
/// The message.
private static void Log(string message)
{
if (m_verbose)
Console.WriteLine("Progress: {0}", message);
}
}
}
#endif