CheckedIn / Added events on libraries

So I had to do another event receiver for a wiki pages library. There are different versions depending on the development state – they are different in that the library either has a force checkout or not. See below image and then the lower of the two red rectangles shows the setting that is either yes or no. The other one defines if a simple approval workflow is used to manage versions.
Versioning Settings

So, what am I doing in my eventreceiver? I am adding the title, if it was not set (watch out, there is a difference between the dialog for a new page via the site settings menu and the new item in the pages library. The other thing I am doing is changing the settings of XsltListViewWebParts (change the view, set the row limit to at least 100 and filter the view using the title and a column I use called ‘page’.

These are the two interesting parts of the code:

This one sets the title. That means I need a web opened as an administrator and then check to see if the title is the way I want it to be…

So I get the list and the item and then check the title field.
if the title is null, then I set it, item.Title does not have a set-method so there we go…quick question what is faster? GetItemById, or GetItemByUniqueId? I would expect the first option…I did try it once though, and the id returned 33 while the number of items was 13 (I deleted a lot of pages) and the method returned an error, so I was playing safe here.

      private void SetTitle(SPItemEventProperties properties)
        {
            SPListItem item = properties.ListItem;
            if (properties.Web != null)
            {
                SPSecurity.RunWithElevatedPrivileges(
                    delegate
                    {
                        using (SPSite site = new SPSite(properties.Web.Url))
                        using (SPWeb web = site.OpenWeb())
                        {
                            SPList list = web.Lists[properties.ListId];
                            SPListItem admItem = 
                                           list.GetItemByUniqueId(item.UniqueId);
                            if (string.IsNullOrEmpty(
                                admItem[SPBuiltInFieldId.Title] as string)
                            )
                            {
                                title = admItem.Name.Replace(".aspx", "");
                                admItem[SPBuiltInFieldId.Title] = title;
                            }
                            else 
                            {
                                title = item.Title;
                            }
                            EventFiringEnabled = false;
                            site.AllowUnsafeUpdates = true;
                            web.AllowUnsafeUpdates = true;
                            admItem.SystemUpdate(false);
                            web.AllowUnsafeUpdates = false;
                            site.AllowUnsafeUpdates = false;
                            EventFiringEnabled = true;
                        }
                    });
            }
        }

The event firing and the updating is just fine right there. Watch for the system update, which is crucial.

Problem right now is still, that the check-in will overwrite the modified-by user that did the check-in that triggered the event, that I will solve with <a href="this.

     private void CheckView(SPWeb web, XsltListViewWebPart wp)
        {
            Guid oGuid = new Guid(wp.ViewGuid);
            SPList list = web.Lists[wp.ListId];
            SPView oWebPartView = list.Views[oGuid];
            int limit = 100;
            bool changed = false;
            if (oWebPartView.RowLimit < limit)
            {
                oWebPartView.RowLimit = 
                        Math.Max(limit, oWebPartView.RowLimit);
                changed = true;
            }
            string query = "" + title + "";
            if(!query.Equals(oWebPartView.Query))
            {
                oWebPartView.Query = query;
                changed = true;        
            }
            if(changed)
                oWebPartView.Update();
        }

In this method I simply take the webpart, which was already casted, then I pick up the Guid and get the view from the list. Initially I thought: what if somebody has an XsltListViewWebPart referring to a list in a sub-web…well that’s not possible – I checked – at least not ootb.

So now that I developed these two functions for the check-in event I thought: what if there is no force-checkout? Well that I still need to implement, adding an added-event and having it work only if there is a valid item to work on, because the properties.ListItem member does not exist after the added event when force-checkout is in-place.
So you got to watch that!

        private SPLimitedWebPartManager GetManagerFromItem(SPListItem item)
        {
            if (item == null || item.File == null) return null;
            SPFile itemFile = item.File;
            // open file...
            // GetLimitedWebPartManager from SPFile object
            SPLimitedWebPartManager wpmgr = 
                         itemFile.Web.GetLimitedWebPartManager(
                         itemFile.ServerRelativeUrl, 
                         PersonalizationScope.Shared);
            return wpmgr;
        }
        ...
        SPLimitedWebPartCollection collection = wpmngr.WebParts;
        List consumers = new List();
        foreach (var wp in collection)
        {
          if (wp != null)
          {
            if (wp is XsltListViewWebPart)
            {
              XsltListViewWebPart view = (XsltListViewWebPart) wp;
              CheckView(web, view);
              consumers.Add(view);
            }
          }
        } 
        ...                        

So what happens here is just that I get the limited webpart manager from the spfile object’s relativeurl and then iterate over the webpartcollection getting only the xsltlistviewwebparts…this is also discussed at many other places, you can google that, if you need more in-depth information.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: