Sitecore Large Publish Notification

Large number of items are being created, modified and deleted on the Sitecore CMS everyday. Also, the number of media items being uploaded can be large depending on the size of the site or the content to be displayed on the live site. For example, an product detail page may contains lots images.

Most companies make use of an Incremental Auto Publish agent which will automatically publish items at a define interval of time. Due to this, when the Auto Publish is triggered and if there are large amount of items, especially media items, the time taken for the publish to complete can be enormous. I had an experience with this issue whereby we had uploaded around 200 to 300 images to the Back Office and the incremental publish took days to complete.

Based on this, we had to know when there is a large publish on going since we will not be checking the Job.aspx page everytime. Throughout this post, I will explain how you can easily send a notification if there is a large publish.

We need to hook into the Publish Pipeline in order to retrieve the required information. The event in which I will hook is the publish:itemProcessed. In this event, I will be able to know the items that have been processed and the number of items that needs to be published. You may read my previous post on how to retrieve the list of items that have been published here.

The Class

public class PublishNotification
{
    private static bool FlagPublish { get; set; }

    public void OnItemProcessed(object sender, EventArgs args)
    {
        var itemArgs = args as ItemProcessedEventArgs;

        if (itemArgs != null)
        {
            var publishContext = itemArgs.Context.PublishContext;

            if (itemArgs.Context.PublishOptions.Mode == PublishMode.Incremental)
            {
                if (!FlagPublish)
                {
                    var itemsToProcess = publishContext.Queue[2].Count();

                    var publishingThreshold = Sitecore.Configuration.Settings.GetSetting("PublishingThreshold");

                    var totalItems = Math.Pow(itemArgs.Context.PublishContext.Languages.Count(), 2)
                        + (itemArgs.Context.PublishContext.Languages.Count() * itemsToProcess);

                    if (totalItems >= Int32.Parse(publishingThreshold))
                    {
                        FlagPublish = true;

                        var emailSender = Sitecore.Configuration.Settings.GetSetting("EmailSender");
                        var emailRecipients = Sitecore.Configuration.Settings.GetSetting("EmailRecipients");
                        var emailSubject = Sitecore.Configuration.Settings.GetSetting("EmailSubject");
                        var emailBody = Sitecore.Configuration.Settings.GetSetting("EmailBody");

                        dynamic template = new ExpandoObject();

                        template.Sender = emailSender;
                        template.Recipients = emailRecipients.Split(new [] { ';', '|', ',' }).Select(r => r.Trim()).ToArray();
                        template.Subject = emailSubject;
                        template.Body = emailBody.Replace("{0}", totalItems.ToString(CultureInfo.InvariantCulture));

                        try
                        {
                            //Send Mail Here and Pass template as Param
                            SendMail(template);
                        }
                        catch (Exception ex)
                        {
                            Log.Error("EmailService |" + ex.Message, this);
                            FlagPublish = false;
                        }
                    }
                }
            }
        }
    }

    public void OnPublishEnd(object sender, EventArgs args)
    {
        FlagPublish = false;
    }
}

By making use of the Property FlagPublish, this will prevent the system to send each time a mail. In other words, if there is a large publish, it will notify the user only once since this event is being triggered for each item being published.

The Configuration

Below is the configuration. You can specify the different values for the Recipient, Subject, Sender and Body. Moreover, you need to specify a threshold. The threshold will be used to see if the total items to be processed is greater or less and based on this, it will know if an email should be sent.

<settings>
   <setting name="PublishingThreshold" value="200"/>

   <setting name="EmailSender" value="noreply@companyname.com"/>

   <setting name="EmailRecipients" value="recipient@companyname.com"/>

   <setting name="EmailSubject" value="Publishing Threshold" />

   <setting name="EmailBody" value="There is currently a large publish going on. Number of items to be published: {0}" />
</settings>

In order for our code to trigger, we need to patch the event as shown below:

<events timingLevel="custom">
   <event patch:replace="*[@name='publish:itemProcessed']" name="publish:itemProcessed">
     <handler type="YourNamespace.ClassName, YourAssembly" method="OnItemProcessed" />
   </event>
</events>

Are we finished? The answer is no. We have one more step to do. When the FlagPublish is set to true, it will always remains to true since the application will keep on running. So, we need to set it back to false after the publish has completed. To do so, we need to patch the event publish:end:

<events timingLevel="custom">
   <event name="publish:end">
     <handler type="YourNamespace.ClassName, YourAssembly" method="OnPublishEnd" />
   </event>
</events>

So, the final config will looks as below:

<events timingLevel="custom">
   <event patch:replace="*[@name='publish:itemProcessed']" name="publish:itemProcessed">
     <handler type="YourNamespace.ClassName, YourAssembly" method="OnItemProcessed" />
   </event>
   <event name="publish:end">
     <handler type="YourNamespace.ClassName, YourAssembly" method="OnPublishEnd" />
   </event>
 </events>

 

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