Skip to main content

Sitecore 7.0 Upgrade (from 6.5) Sharepoint Integration Framework 1.0 Upgrade

Part of the extra work in the SC upgrade process is making sure that your modules still work after the upgrade. Since we were using SPIF as one of our major modules, it was important that this was validated and updated as well.
From our current 111115 revision, we chose to upgrade to 1.1 rev 130613. Installation was pretty straightforward we followed the SDN instructions nothing difficult there. What struck us though was the note in one of the upgrade path; it says, upon first access, any existing integration folder will be recreated.
Whoa! This did not sound too refreshing to us as we already have thousands of references to these integration items.
We had to find out a way to sync the refs once the upgrade completes, one route we took was to leverage the SC Links DB.
We used the steps below:
1) After upgrade, rebuild the Links DB, since the web DB still contains the current live refs, we can use the media IDs here as refs once the SPIF in master has refreshed.
2) We then created a one-off page with code logic to basically do a replace operation on all referrers to the integration items. Since the web still contains our current references, we can use this and point our link DB query to web instead of master. One tricky thing here is to get all Integration files regardless of the File type (pdf, xls, png etc.). You would have to create a recursive call to get to the base template, i.e. Unversioned File in our case.

    /// <summary>
    /// Recursive call to get base templates
    /// </summary>
    /// <param name="list"></param>
    /// <param name="template"></param>
    private static void SearchTemplates(ICollection<string> list, TemplateItem template)
    {
        foreach (var baseTemplateItem in template.BaseTemplates)
        {
            list.Add(baseTemplateItem.ID.ToString());
            if (baseTemplateItem.ID != TemplateIDs.StandardTemplate)
                SearchTemplates(list, baseTemplateItem);
        }
    }

    /// <summary>
    /// Check if item belongs to the target template e.g. File
    /// </summary>
    /// <param name="targetTemplateId"></param>
    /// <param name="item"></param>
    /// <returns></returns>
    private static bool BaseTargetTemplateFound(string targetTemplateId, Item item)
    {
        var list = new List<string> { item.TemplateID.ToString() };
        SearchTemplates(list, item.Template);
        return list.Contains(targetTemplateId);
    }

3) The logic is basically three steps: 1. Run a pre-process (using the web DB) that saves all the current referrers of an integration file to a flat file.


    /// <summary>
    /// Preprocessor
    /// </summary>
    private void PreProcess()
    {

        var totalItems = 0;
        var sw = new Stopwatch();
        sw.Start();

        var resultList = new StringBuilder();
        using (new SecurityDisabler())
        {
            Sitecore.Context.SetActiveSite("shell");

            var master = Database.GetDatabase("web");
            //var core = Sitecore.Data.Database.GetDatabase("core");
            var spifLib = master.GetItem("{GUID}");
            if (spifLib == null)
                throw new Exception("SPIF Media Library is MISSING - {GUID}.");
            var spifChildren =
                spifLib.Axes.GetDescendants()
                              .Where(x => BaseTargetTemplateFound("{GUID}", x))
                              .ToList();
            if (!spifChildren.Any())
                throw new Exception("SPIF media Library does not contain any document items!");
            foreach (var documentItem in spifChildren)
            {
                ItemLink[] links;
                if (!(links = GetLinkedItems(master, documentItem)).Any()) continue;
                var item1 = documentItem;
                foreach (var delimited in from link in links
                                          let item = master.GetItem(link.SourceItemID)
                                          let field = new Field(link.SourceFieldID, item)
                                          select
                                              string.Format("{0}|{1}|{2}|{3}|{4}|{5}", link.SourceItemID, item.Name,
                                                            field.Name, item1.ID, item1.Name, item1.Paths.FullPath))
                {
                    resultList.AppendFormat("{0}{1}", delimited, Environment.NewLine);
                    totalItems++;
                }
            }

            var w = new StreamWriter("C:\\temp\\results.txt");
            w.Write(resultList.ToString());
            w.Flush();
            w.Close();

        }

        sw.Stop();
        litResults.Text = "Finished ... Processing took: " + sw.Elapsed.TotalMinutes + "mins." +
                          "<br/>Total Items to modify: " + totalItems + " " + "Total Errors: " + _errorCount;

    }

       2. Run a post process that will replace the previous IDs with the new IDs (from the refreshed SPIF tree). 3. Publish modified items.



Comments

Popular posts from this blog

Add Export to File Functionality in Sitecore's Search Options

One of our business users was requesting for a listing of items they've already added and have it available in a format that can be opened in a spreadsheet (Excel). My initial thought was to create a blank aspx page and write all the logic to get the data in the code-behind, run it and save the resulting file to a csv then I'm done.
But then it got me to think, it might be a better idea to have this functionality plugged in to Sitecore and made available for everyone to use.  Sitecore Bucket's Search Options fly-out seemed a good candidate for this feature (See image below). So doing some quick readings I got myself in to the "zone" and started implementing this quick and dirty PoC.

Just to explain what it actually does.

User will basically do a search, (Note that all search options require some filters or search keyword before any of the options can be used) clicks the Export to File, it pops up a dialog to confirm the action and executes, after which a browser-…

Rich Text Editor (RTE) Stripping Script tags

Ran across an issue today wherein one of our Content Editors was complaining that their page was not working, i.e. some page scripts where not firing.
Upon closer inspection, we found out that their content inside their RTE was missing.
We added them back but, it just kept getting stripped-off when we close the editor.
This did not happen to us before when we were using SC6.5, so this basically smells more like an upgrade issue.
I scanned all of the config changes (I kept a log) and found one curious setting:

<setting name="HtmlEditor.RemoveScripts" value="true" />

This setting was by default removing any embedded scripts inside the RTE.
Just turn it off in your CM and keep it on in your CD.

Implementing a Secure Media library in Sitecore

Our internal clients wanted us to secure some of their resources stored in the media library so that only authenticated and authorized extranet users are able to view or download them. Our current setup has the following components, I'll simply focus on the 3rd and 4th points:
Sharepoint Workflows on a Sharepoint 2007 Server. This serves as the working repository of the resource owners.Sitecore Sharepoint Integration Framework. This hooks up Sitecore with the designated document library in Sharepoint for all finalized files/documentsIntegration folder in the Media libraryLogin page to handle the authenticationCreate your login page. You have the option to create your sublayout for this (mostly to control the page contents etc.) or you can just quickly create one and put it in one of your folders in your solution. I normally use CodeFile directive in my pages as we found it easier to maintain this type of setup in the long run. There are plenty of samples of the login functionality …