Variation Labels for a site collection

11/1/2011

I had to implement an event receiver to delete all the variation peer pages, on the deletion of the source variation page.
How difficult could it be, I thought. I would use the "Variations.Current.UserAccessibleLabels" property to loop through all
the labels and call the "PublishingPage.GetVariation()" function to delete the
individual pages....

Nopes, SharePoint has this hidden gems which sometimes leave you surprised. Turns out, "Variations.Current.UserAccessibleLabels" property internally uses SPContext.Current.Site to access the site collection. In an event receiver ( and so in a console application etc ) this property is not initialised and hence you would get a "NullReferenceException" (object reference not set to an instance of an object).

To overcome this, I wrote a function which shall read the Variation List and then return me the VariationLabel objects. This again is not so simply, as there is no public constructor for VariationLabel class. The work around is to create the Publishing Web object of each variation web and then access the Label property.

Here is the complete function to return the VariationLabels for a site collection..hope it saves you some time..

        public static ReadOnlyCollection GetAllVariationLabels(SPSite spSite)
        {
            SPWeb spWeb = spSite.RootWeb;
            SPList variationLabelsList = spWeb.GetList(spWeb.ServerRelativeUrl + "/Variation Labels/Allitems.aspx");
            Collection
list = new Collection();
            SPQuery query = new SPQuery
            {
                Query = ""
            };

            foreach (SPListItem item in variationLabelsList.GetItems(query))
            {
                bool isHeirarchyCreated = (bool) item["Hierarchy Is Created"];

                if (!isHeirarchyCreated)
                    continue;

                string webUrl = (string)item["Top Web URL"];
                webUrl = webUrl.Substring(webUrl.IndexOf(',') + 1);
                PublishingWeb pubWeb = PublishingWeb.GetPublishingWeb(spSite.OpenWeb(webUrl));
                VariationLabel varLbl = pubWeb.Label;
                list.Add(varLbl);
            }
            return new ReadOnlyCollection
(list);
        }


and the function to delete the pages..

internal void DeleteSubVariationPeerPages(SPListItem spItm, SPSite spSite)
       {

           ReadOnlyCollection
collVarLbl = GetAllVariationLabels( spSite);

           PublishingPage currPage = PublishingPage.GetPublishingPage(spItm);
           base.EventFiringEnabled = false;

           foreach (VariationLabel lbl in collVarLbl)
           {
               if (lbl.IsSource)
                   continue;

               PublishingPage varPeer = currPage.GetVariation(lbl);
               varPeer.ListItem.Delete();
           }
           
           base.EventFiringEnabled = true;
       }

PS
Here is an alternative approach which involves Faking the SPContext.

Name

Email

WebSite