Skip to content

Instantly share code, notes, and snippets.

@markgibbons25
Last active April 22, 2020 00:39
Show Gist options
  • Save markgibbons25/9d2588528628d5ac90c7801e65f27175 to your computer and use it in GitHub Desktop.
Save markgibbons25/9d2588528628d5ac90c7801e65f27175 to your computer and use it in GitHub Desktop.
using System;
using System.Collections.Generic;
using System.Linq;
using Sitecore.Abstractions;
using Sitecore.Caching;
using Sitecore.Configuration;
using Sitecore.Data;
using Sitecore.Data.Events;
using Sitecore.Data.Items;
using Sitecore.Diagnostics;
using Sitecore.Events;
using Sitecore.Publishing;
using Sitecore.Sites;
using Sitecore.Web;
namespace
{
public class SmartCacheClearer
{
private const string PreventCacheClear = "preventHtmlCacheClear";
private readonly BaseCacheManager _cacheManager;
private readonly BaseSiteContextFactory _siteContextFactory;
public SmartCacheClearer(
BaseCacheManager cacheManager,
BaseSiteContextFactory siteContextFactory)
{
Assert.ArgumentNotNull(cacheManager, nameof(cacheManager));
Assert.ArgumentNotNull(siteContextFactory, nameof(siteContextFactory));
this._cacheManager = cacheManager;
this._siteContextFactory = siteContextFactory;
}
/// <summary>Clears the cache.</summary>
/// <param name="sender">The sender.</param>
/// <param name="args">The arguments.</param>
public void ClearCache(object sender, EventArgs args)
{
Assert.ArgumentNotNull(sender, nameof(sender));
Assert.ArgumentNotNull(args, nameof(args));
this.NotifyStart();
var allSites = this.GetSites();
Item rootItem = null;
bool deep = false;
var remoteEventArgs = args as PublishEndRemoteEventArgs;
if (remoteEventArgs != null)
{
var rootItemId = remoteEventArgs.RootItemId;
var rootItemDatabase = remoteEventArgs.TargetDatabaseName;
Database database;
if (Factory.GetDatabaseNames().Any(name => name.Equals(rootItemDatabase, StringComparison.OrdinalIgnoreCase)))
database = Factory.GetDatabase(rootItemDatabase);
else
database = Factory.GetDatabase("web");
if (database != null)
{
rootItem = database.GetItem(new ID(rootItemId));
}
deep = remoteEventArgs.Deep;
}
else
{
var publisher = Event.ExtractParameter(args, 0) as Publisher;
if (publisher != null)
{
rootItem = publisher.Options.RootItem;
if (rootItem != null)
{
deep = publisher.Options.Deep;
}
}
}
var sitesToClear = allSites;
if (rootItem != null)
{
var sites = allSites
.Where(x => rootItem.Paths.FullPath.ToLower().Contains(x.RootPath.ToLowerInvariant()))
.Where(x => x.Name != "modules_website")
.ToList();
if (sites.Any())
{
sitesToClear = sites;
}
}
foreach (SiteInfo info in sitesToClear)
{
var htmlCache = GetHtmlCacheForSite(new SiteContext(info));
this.ClearHtmlCacheForSite(htmlCache);
if (info.RenderingParametersCache != null)
{
info.RenderingParametersCache.Clear();
}
}
this.NotifyEnd(sitesToClear);
}
private IReadOnlyCollection<SiteInfo> GetSites()
{
List<SiteInfo> sites = this._siteContextFactory.GetSites();
return sites == null ? Array.Empty<SiteInfo>() : sites.Where<SiteInfo>(s => s.CacheHtml && s.Properties[PreventCacheClear] != "true").ToArray<SiteInfo>();
}
private HtmlCache GetHtmlCacheForSite(SiteContext siteContext)
{
return this._cacheManager.GetHtmlCache(siteContext);
}
private void ClearHtmlCacheForSite(HtmlCache htmlCache)
{
htmlCache?.Clear();
}
private void ClearHtmlCacheForItem(HtmlCache htmlCache, Item item)
{
htmlCache.RemoveKeysContaining(item.Paths.FullPath);
}
private void NotifyStart()
{
Log.Info("SmartCacheClearer: Cache clearing - start.", this);
}
private void NotifyEnd(IReadOnlyCollection<SiteInfo> sites)
{
//if (!Log.IsDebugEnabled)
// return;
Log.Info("SmartCacheClearer: Cache clearing - end. Affected sites: " + string.Join(", ", sites.Select<SiteInfo, string>(s => s.Name)), this);
}
}
}
<?xml version="1.0" encoding="utf-8" ?>
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/"
xmlns:set="http://www.sitecore.net/xmlconfig/set/"
xmlns:env="http://www.sitecore.net/xmlconfig/env/">
<sitecore>
<events>
<event name="publish:end">
<handler type="Sitecore.Publishing.HtmlCacheClearer, Sitecore.Kernel" method="ClearCache">
<patch:attribute name="type">SmartCacheClearer, Foundation.Infrastructure</patch:attribute>
<patch:attribute name="resolve">true</patch:attribute>
<sites hint="list">
<patch:delete />
</sites>
</handler>
<!--SmartCacheClearer handles these cases so patch them out-->
<handler type="Sitecore.XA.Foundation.Multisite.EventHandlers.HtmlCacheClearer, Sitecore.XA.Foundation.Multisite" method="OnPublishEnd">
<patch:delete />
</handler>
<handler type="Sitecore.Publishing.RenderingParametersCacheClearer, Sitecore.Kernel" method="ClearCache">
<patch:delete />
</handler>
</event>
<event name="publish:end:remote">
<handler type="Sitecore.Publishing.HtmlCacheClearer, Sitecore.Kernel" method="ClearCache">
<patch:attribute name="type">SmartCacheClearer, Foundation.Infrastructure</patch:attribute>
<patch:attribute name="resolve">true</patch:attribute>
<sites hint="list">
<patch:delete />
</sites>
</handler>
<!--SmartCacheClearer handles these cases so patch them out-->
<handler type="Sitecore.XA.Foundation.Multisite.EventHandlers.HtmlCacheClearer, Sitecore.XA.Foundation.Multisite" method="OnPublishEndRemote">
<patch:delete />
</handler>
<handler type="Sitecore.Publishing.RenderingParametersCacheClearer, Sitecore.Kernel" method="ClearCache">
<patch:delete />
</handler>
</event>
</events>
</sitecore>
</configuration>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment