As I was walking along a beach near my apartment tonight, I thought “wouldn’t it be nifty to have a button in the Sitecore ribbon to accept all notifications on clones of an Item instead of having to accept these manually on each clone?”
I immediately returned home, and whipped up the following command class:
using System.Collections.Generic;
using System.Linq;
using Sitecore.Data.Clones;
using Sitecore.Data.Items;
using Sitecore.Diagnostics;
using Sitecore.Shell.Framework.Commands;
namespace Sitecore.Sandbox.Shell.Framework.Commands
{
public class AcceptAllNotificationsOnClones : Command
{
public override CommandState QueryState(CommandContext context)
{
Assert.ArgumentNotNull(context, "context");
IEnumerable<Item> clones = GetClonesWithNotifications(GetItem(context));
if(!clones.Any())
{
return CommandState.Hidden;
}
return CommandState.Enabled;
}
public override void Execute(CommandContext context)
{
Assert.ArgumentNotNull(context, "context");
Item item = GetItem(context);
IEnumerable<Item> clones = GetClonesWithNotifications(item);
if(!clones.Any())
{
return;
}
foreach (Item clone in clones)
{
AcceptAllNotifications(item.Database.NotificationProvider, clone);
}
}
protected virtual Item GetItem(CommandContext context)
{
Assert.ArgumentNotNull(context, "context");
return context.Items.FirstOrDefault();
}
protected virtual IEnumerable<Item> GetClonesWithNotifications(Item item)
{
Assert.ArgumentNotNull(item, "item");
IEnumerable<Item> clones = item.GetClones();
if(!clones.Any())
{
return new List<Item>();
}
IEnumerable<Item> clonesWithNotifications = GetClonesWithNotifications(item.Database.NotificationProvider, clones);
if(!clonesWithNotifications.Any())
{
return new List<Item>();
}
return clonesWithNotifications;
}
protected virtual IEnumerable<Item> GetClonesWithNotifications(NotificationProvider notificationProvider, IEnumerable<Item> clones)
{
Assert.ArgumentNotNull(notificationProvider, "notificationProvider");
Assert.ArgumentNotNull(clones, "clones");
return (from clone in clones
let notifications = notificationProvider.GetNotifications(clone)
where notifications.Any()
select clone).ToList();
}
protected virtual void AcceptAllNotifications(NotificationProvider notificationProvider, Item clone)
{
Assert.ArgumentNotNull(notificationProvider, "notificationProvider");
Assert.ArgumentNotNull(clone, "clone");
foreach (Notification notification in notificationProvider.GetNotifications(clone))
{
notification.Accept(clone);
}
}
}
}
The code in the command above ensures the command is only visible when the selected Item in the Sitecore content tree has clones, and those clones have notifications — this visibility logic is contained in the QueryState() method.
When the command is invoked — this happens through the Execute() method — all clones with notifications of the selected Item are retrieved, and iterated over — each are passed to the AcceptAllNotifications() method which contains logic to accept all notifications on them via the Accept() method on a NotificationProvider instance: this NotificationProvider instance comes from the source Item’s Database property.
I then registered the above command class in Sitecore using the following configuration file:
<?xml version="1.0" encoding="utf-8" ?>
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
<sitecore>
<commands>
<command name="item:AcceptAllNotificationsOnClones" type="Sitecore.Sandbox.Shell.Framework.Commands.AcceptAllNotificationsOnClones, Sitecore.Sandbox"/>
</commands>
</sitecore>
</configuration>
We need a way to invoke this command. I created a new button to go into the ‘Item Clones’ chunk in the ribbon:
Let’s take this for a test drive!
I first created some clones:
I then changed a field value on one of those clones:
On the clone’s source Item, I changed the same field’s value with something completely different, and added a new child item — the new button appeared after saving the Item:
Now, the clone has notifications on it:
I went back to the source Item, clicked the ‘Accept Notifications On Clones’ button in the ribbon, and navigated back to the clone:
As you can see, the notifications were accepted.
If you have any thoughts on this, please share in a comment.









