using System; using System.Collections.Generic; using System.Web.Script.Serialization; using Umbraco.Core; using Umbraco.Core.Cache; using Umbraco.Core.Models; using umbraco.interfaces; using System.Linq; namespace Umbraco.Web.Cache { /// /// A cache refresher to ensure media cache is updated /// /// /// 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 MediaCacheRefresher : JsonCacheRefresherBase { #region Static helpers /// /// 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 IMedia[] media) { var serializer = new JavaScriptSerializer(); var items = media.Select(FromMedia).ToArray(); var json = serializer.Serialize(items); return json; } /// /// Converts a macro to a jsonPayload object /// /// /// private static JsonPayload FromMedia(IMedia media) { if (media == null) return null; var payload = new JsonPayload { Id = media.Id, Path = media.Path }; return payload; } #endregion #region Sub classes private class JsonPayload { public string Path { get; set; } public int Id { get; set; } } #endregion protected override MediaCacheRefresher Instance { get { return this; } } public override Guid UniqueIdentifier { get { return new Guid(DistributedCache.MediaCacheRefresherId); } } public override string Name { get { return "Clears Media Cache from umbraco.library"; } } public override void Refresh(string jsonPayload) { ClearCache(DeserializeFromJsonPayload(jsonPayload)); base.Refresh(jsonPayload); } public override void Refresh(int id) { ClearCache(FromMedia(ApplicationContext.Current.Services.MediaService.GetById(id))); base.Refresh(id); } public override void Remove(int id) { ClearCache(FromMedia(ApplicationContext.Current.Services.MediaService.GetById(id))); base.Remove(id); } private static void ClearCache(params JsonPayload[] payloads) { if (payloads == null) return; payloads.ForEach(payload => { foreach (var idPart in payload.Path.Split(',')) { ApplicationContext.Current.ApplicationCache.ClearCacheByKeySearch( string.Format("{0}_{1}_True", CacheKeys.MediaCacheKey, idPart)); // Also clear calls that only query this specific item! if (idPart == payload.Id.ToString()) ApplicationContext.Current.ApplicationCache.ClearCacheByKeySearch( string.Format("{0}_{1}", CacheKeys.MediaCacheKey, payload.Id)); } }); } } }