using System; using System.Web.Script.Serialization; using Umbraco.Core; using Umbraco.Core.Cache; using umbraco; using umbraco.cms.businesslogic.macro; using umbraco.interfaces; using System.Linq; namespace Umbraco.Web.Cache { /// /// A cache refresher to ensure macro cache is updated when members change /// /// /// This is not intended to be used directly in your code and it should be sealed but due to legacy code we cannot seal it. /// public class MacroCacheRefresher : JsonCacheRefresherBase { #region Static helpers internal static string[] GetAllMacroCacheKeys() { return new[] { CacheKeys.MacroCacheKey, CacheKeys.MacroControlCacheKey, CacheKeys.MacroHtmlCacheKey, CacheKeys.MacroHtmlDateAddedCacheKey, CacheKeys.MacroControlDateAddedCacheKey }; } internal static string[] GetCacheKeysForAlias(string alias) { return GetAllMacroCacheKeys().Select(x => x + alias).ToArray(); } /// /// Converts the json to a JsonPayload object /// /// /// private static JsonPayload[] DeserializeFromJsonPayload(string json) { var serializer = new JavaScriptSerializer(); var jsonObject = serializer.Deserialize(json); return jsonObject; } /// /// Creates the custom Json payload used to refresh cache amongst the servers /// /// /// internal static string SerializeToJsonPayload(params Macro[] macros) { var serializer = new JavaScriptSerializer(); var items = macros.Select(FromMacro).ToArray(); var json = serializer.Serialize(items); return json; } /// /// Creates the custom Json payload used to refresh cache amongst the servers /// /// /// internal static string SerializeToJsonPayload(params macro[] macros) { var serializer = new JavaScriptSerializer(); var items = macros.Select(FromMacro).ToArray(); var json = serializer.Serialize(items); return json; } /// /// Converts a macro to a jsonPayload object /// /// /// private static JsonPayload FromMacro(Macro macro) { var payload = new JsonPayload { Alias = macro.Alias, Id = macro.Id }; return payload; } /// /// Converts a macro to a jsonPayload object /// /// /// private static JsonPayload FromMacro(macro macro) { var payload = new JsonPayload { Alias = macro.Alias, Id = macro.Model.Id }; return payload; } #endregion #region Sub classes private class JsonPayload { public string Alias { get; set; } public int Id { get; set; } } #endregion protected override MacroCacheRefresher Instance { get { return this; } } public override string Name { get { return "Macro cache refresher"; } } public override Guid UniqueIdentifier { get { return new Guid(DistributedCache.MacroCacheRefresherId); } } public override void RefreshAll() { ApplicationContext.Current.ApplicationCache.ClearCacheObjectTypes(); GetAllMacroCacheKeys().ForEach( prefix => ApplicationContext.Current.ApplicationCache.ClearCacheByKeySearch(prefix)); base.RefreshAll(); } public override void Refresh(string jsonPayload) { Remove(jsonPayload); base.Refresh(jsonPayload); } public override void Remove(string jsonPayload) { var payloads = DeserializeFromJsonPayload(jsonPayload); payloads.ForEach(payload => { GetCacheKeysForAlias(payload.Alias).ForEach( alias => ApplicationContext.Current.ApplicationCache.ClearCacheByKeySearch(alias)); }); base.Remove(jsonPayload); } } }