Thursday, March 12, 2015

Coding Event Handlers for Document Sets

using System;

using System.Collections.Generic;

using Microsoft.SharePoint;

using System.Diagnostics;

using System.Net;

using System.Collections.Specialized;

using System.Data;

using System.Configuration;

using System.Web;

using System.Runtime.Serialization;

using System.IO;

using System.Text;

using System.Xml;

using System.Security.Cryptography;

namespace UCOP.Custom.RPACEventReceiver.MemoEventReceiver



{

/// <summary>

/// Document Library Item Events

/// </summary>

public class MemoEventReceiver : SPItemEventReceiver



{

public static string DRAFT_MEMOS_LIBRARY_TITLE = "Draft Memos";

public static string PUBLISHED_MEMOS_LIBRARY_TITLE = "Published Memos";

/// <summary>

/// An item was added. Specifically for when the memo set is initially created. This calls the same code in ItemUpdated.

/// Note: Since this was added later I had to turn the feature off and then on again for it to register this new event receiver

/// </summary>

public override void ItemAdded(SPItemEventProperties properties)



{

this.ItemUpdated(properties);

base.ItemAdded(properties);



}

/// <summary>

/// An item was updated. Most of the code is here.

/// </summary>

public override void ItemUpdated(SPItemEventProperties properties)



{

//check to see if this is the correct document library

if (properties.ListTitle.Equals(DRAFT_MEMOS_LIBRARY_TITLE) || properties.ListTitle.Equals(PUBLISHED_MEMOS_LIBRARY_TITLE))



{

try



{

properties.ListItem["SharePoint_x0020_ID"] = properties.ListItem["ID"];

//create the md5 hash

//only if it has a file do we put the hash. if it has no file then it's probably a memo set

if (properties.ListItem.File != null)



{

SPFile spfile = properties.ListItem.File;

Stream fileStream = spfile.OpenBinaryStream();

MD5 md5Hash = MD5.Create();

string hash = GetMd5Hash(md5Hash, fileStream);

//add file hash and id to item

properties.ListItem["File_x0020_Hash"] = hash;



properties.ListItem.SystemUpdate();

}

//get a reference to the item from the properties

SPListItem selectItem = properties.ListItem;

//do the following for memo sets only

if (selectItem["Content Type"].Equals("Memo Set"))



{

//loop through all the files in the memo set and increment the count

int memoCount = 0;

foreach (SPFile file in selectItem.Folder.Files)



{

if (file.ListItemAllFields["Content Type"].Equals("Guidance Memo"))



memoCount++;

}

//get a hook to the web and the warning list

SPWeb web = properties.Web;

SPList warningList = web.Lists["Guidance Memo Warnings"];

//todo: loop through all the listitems in the list and delete any with Memo Set == selectItem.Title

try



{

string memoID = (string)selectItem["Memo ID"];

SPQuery query = new SPQuery();

query.Query = "<Where><Eq><FieldRef Name = \"Document_x0020_Set\"/>" +

"<Value Type = \"Lookup\">" + memoID + "</Value></Eq></Where>";

//get the items in the warning list that have to do with the memo set

SPListItemCollection items = warningList.GetItems(query);

//create an array for deleting the items since you can't delete when iterating the collection

SPListItem[] itemsToDelete = new SPListItem[items.Count];

int i = 0;

foreach (SPListItem item in items)



{



itemsToDelete[i]=(item);

i++;

}

//for all the items to delete loop through the array and delete them

foreach(SPListItem itemToDelete in itemsToDelete){

if (itemToDelete != null)itemToDelete.Delete();



}

}

catch (Exception errorDeleting) { }

//if the memoCount is greater than 1 add a listitem to the list

if (memoCount > 1)



{

SPListItem warningItem = warningList.AddItem();

//since this is a lookup have to use a special object

warningItem["Document Set"] = new SPFieldLookupValue(selectItem.ID, selectItem.Title);

warningItem["Title"] = "There are more memos than one";



warningItem.Update();

}

//if the memoCount is 0 then add a list item to the list

if (memoCount == 0)



{

SPListItem warningItem = warningList.AddItem();

//since this is a lookup have to use a special object

warningItem["Document Set"] = new SPFieldLookupValue(selectItem.ID, selectItem.Title);

warningItem["Title"] = "There are no memos in the memo set";



warningItem.Update();

}

}

else //the item is a file in the memo set



{

//so find the memo set and trigger an update

string memoID = (string)selectItem["Memo ID"];

//get a hook to the publishing library

SPList list = selectItem.ParentList;

//query the list for the memo id

SPQuery query = new SPQuery();





query.Query = "<Where><Eq><FieldRef Name = \"Title\"/>" +

"<Value Type = \"Text\">"+memoID+"</Value></Eq></Where>";

//get a list of memo sets that match, should be only one

SPListItemCollection myItems = list.GetItems(query);

for (int i = 0; i < myItems.Count; i++)



{

SPListItem item = myItems[i];

//trigger the event handler for the parent memo set



item.SystemUpdate();

}

}

}

catch (Exception cantUpdateListItem)



{

}



}

base.ItemUpdated(properties);



}

static string GetMd5Hash(MD5 md5Hash, Stream fileStream)



{

// Convert the input string to a byte array and compute the hash.

byte[] data = md5Hash.ComputeHash(fileStream);

// Create a new Stringbuilder to collect the bytes

// and create a string.

StringBuilder sBuilder = new StringBuilder();

// Loop through each byte of the hashed data

// and format each one as a hexadecimal string.

for (int i = 0; i < data.Length; i++)



{

sBuilder.Append(data[i].ToString("x2"));



}

// Return the hexadecimal string.

return sBuilder.ToString();



}

}

}