View All Items in the Sitecore Archive for Non Admin Users

I recently had a requirement that specific non-admin content authors should be able to view all items in the Sitecore Archive. I opened Sitecore.Shell.Applications.Archives.RecycleBin.RecycleBinPage from the Sitecore.Client.dll in dotPeek and noticed that the method GetArchiveEntries() calls into the ArchiveManager.GetArchive and returns an IPageable object. So, we can override the default archive provider and return our own archive. To override the archive provider we can use the following patch config:

[code laguage=”xml”]
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
<sitecore>
<archives defaultProvider="sql" enabled="true">
<providers>
<add name="sql" type="Sitecore.Data.Archiving.SqlArchiveProvider, Sitecore.Kernel" database="*">
<patch:attribute name="type">HI.Global.Archiving.SqlArchiveProvider, HI.Global</patch:attribute>
</add>
</providers>
</archives>
</sitecore>
</configuration>
[/code]

Now we can add our custom provider:

[code language=”csharp”]
using Sitecore.Data;
using Sitecore.Data.Archiving;
using Sitecore.Xml;
using System.Xml;

namespace HI.Global.Archiving
{
public class SqlArchiveProvider: Sitecore.Data.Archiving.SqlArchiveProvider
{
protected override Archive GetArchive(XmlNode configNode, Database database)
{
string attribute = XmlUtil.GetAttribute("name", configNode);
if (string.IsNullOrEmpty(attribute))
{
return null;
}
return new HI.Global.Archiving.SqlArchive(attribute, database);
}
}
}
[/code]

The above class returns our custom archive so now all we need to do is override two methods of the SqlArchive class and all entries will be shared:

[code language=”csharp”]
using Sitecore.Data;
using Sitecore.Data.Archiving;
using Sitecore.Security.Accounts;
using System.Collections.Generic;

namespace HI.Global.Archiving
{
public class SqlArchive : Sitecore.Data.Archiving.SqlArchive
{
public SqlArchive(string name, Database database) : base(name, database)
{
}

protected override IEnumerable<ArchiveEntry> GetEntries(User user, int pageIndex, int pageSize, ID archivalId)
{
return base.GetEntries(null, pageIndex, pageSize, archivalId);
}

protected override int GetEntryCount(User user)
{
return base.GetEntryCount(null);
}
}
}
[/code]

The above code works because when null is passed into both base.GentEntries and base.GetEntryCount, it removed a SQL where statement to search for archived entries by user name. We can also extend this further by checking for a specific role:

[code language=”csharp”]
using Sitecore.Data;
using Sitecore.Data.Archiving;
using Sitecore.Security.Accounts;
using System.Collections.Generic;

namespace HI.Global.Archiving
{
public class SqlArchive : Sitecore.Data.Archiving.SqlArchive
{
public SqlArchive(string name, Database database) : base(name, database)
{
}

protected override IEnumerable<ArchiveEntry> GetEntries(User user, int pageIndex, int pageSize, ID archivalId)
{
if (IsAllowedToViewAllItems(user))
return base.GetEntries(null, pageIndex, pageSize, archivalId);
return base.GetEntries(user, pageIndex, pageSize, archivalId);
}

protected override int GetEntryCount(User user)
{
if (IsAllowedToViewAllItems(user))
return base.GetEntryCount(null);
return base.GetEntryCount(user);
}

private bool IsAllowedToViewAllItems(User user)
{
if (user != null)
{
return user.IsInRole("sitecore\\my specific role i created for viewing all archive items");
}
return false;
}
}
}
[/code]

If you forget to override GetEntryCount(), Your archive won’t page correctly. The reason we override GetEntries(), is because all GetEntries() methods eventually call into GetEntries(User user, int pageIndex, int pageSize, ID archivalId). Also, please note that this can also be applied to the Recycle Bin by following the same steps.