Monday, December 22, 2014

How to Get the Publishing Status of a SharePoint Page in an Event Receiver

Brian Hulse, Solutions Architect

On a recent project I was tasked with doing a number of operations on a SharePoint publishing page after it had been published and unpublished. If you have ever tried this before you will have undoubtedly felt the frustration of not having built in events for ItemPublished and ItemUnpublished like exist for ItemAdded and ItemUpdated. To further complicate things, item scheduling and an approval workflow were also enabled for the Pages library.

After spending some time figuring out how to determine the status of the page in the item events available to me I wrote a nice extension method to make it easy to determine the status of the page. First I’ll give you the research I did to determine the publishing status of the page and then I will give you the code I wrote to make the code in my event receiver much cleaner.

There are a number of properties you can get from the SPItemEventProperties object given to you in an item event receiver to determine the publishing status of the page during that event. By comparing the BeforeProperties and AfterProperties of these values, along with the list item’s moderation status, you will be able to determine the publishing status of a page during either the ItemUpdating or ItemUpdated events.

Below are the values I captured for each event during different scenarios that involve publishing a page with approval and scheduling both enabled. You will note that during a few events the events are called multiple times, this is standard SharePoint behavior. (Note: These values are not always the same when there is no approval workflow running on the item)

The values documented in the tables below can be retrieved from the SPItemEventProperties object in the following manner:

//assume object of type "SPItemEventProperties" named "properties" exists in this context



//Before: Level

properties.BeforeProperties["vti_level"];



//After: Level

properties.AfterProperties["vti_level"];



//Before: Mod

(SPModerationStatusType)int.Parse(properties.BeforeProperties["vti_doclibmodstat"]);

 

//After: Mod

(SPModerationStatusType)int.Parse(properties.AfterProperties["vti_doclibmodstat"]);



//Item Moderation Status

properties.ListItem.ModerationInformation.Status;

 

Scenario: Publish Page Immediately After Approval, Unpublish Manually using Unpublish Button

 

ItemUpdating Event

  Before: Level After: Level Before: Mod After: Mod Item Moderation Status
Create Page (1st Run) 255 255 NULL NULL Draft
Create Page(2nd Run) 255 255 NULL Draft Draft
Save Page 255 255 NULL Draft Draft
Check-in  (1st Run) 255 255 NULL Draft Draft
Check-in (2nd Run) 255 255 NULL NULL Draft
Start approval workflow 2 2 Draft Pending Draft
Final Approval Received (Publish) 2 2 Pending Approved Pending
Unpublish Manually 1 1 NULL Draft Approved

 

ItemUpdated Event


Before: Level After: Level Before: Mod After: Mod Item Moderation Status
Create Page (1st Run) 255 255 NULL NULL Draft
Create Page(2nd Run) 255 255 NULL NULL Draft
Save Page 255 255 NULL NULL Draft
Check-in  (1st Run) 255 255 NULL NULL Draft
Check-in (2nd Run) 255 255 NULL NULL Draft
Start approval workflow 2 2 Draft Pending Pending
Final Approval Received (Publish) 2 2 Pending Approved Approved
Unpublish Manually 1 1 NULL Draft Draft

 

Scenario: Publish and Unpublish Page on Schedule After Approval

NOTE: If a page is unpublished on a schedule it does not cause the ItemUpdating event to be fired so it can only be captured in the ItemUpdated event.

ItemUpdating Event

  Before: Level After: Level Before: Mod After: Mod Item Moderation Status
Create Page (1st Run) 255 255 NULL NULL Draft
Create Page(2nd Run) 255 255 NULL Draft Draft
Save Page 255 255 NULL Draft Draft
Check-in  (1st Run) 255 255 NULL Draft Draft
Check-in (2nd Run) 255 255 NULL NULL Draft
Start approval workflow 2 2 Draft Pending Draft
Final Approval Received (Scheduled to publish) 2 2 Pending