2018-06-29 19:52:40 +02:00
using System ;
2018-05-02 14:52:00 +10:00
using System.Linq ;
2018-06-29 19:52:40 +02:00
using Umbraco.Core.Cache ;
using Umbraco.Core.Models ;
2018-05-02 14:52:00 +10:00
using Umbraco.Core.Services ;
using Umbraco.Core.Services.Changes ;
using Umbraco.Web.PublishedCache ;
2018-06-29 19:52:40 +02:00
namespace Umbraco.Web.Cache
{
2019-10-14 15:21:00 +11:00
public sealed class LanguageCacheRefresher : PayloadCacheRefresherBase < LanguageCacheRefresher , LanguageCacheRefresher . JsonPayload >
//CacheRefresherBase<LanguageCacheRefresher>
2018-06-29 19:52:40 +02:00
{
2019-01-17 08:34:29 +01:00
public LanguageCacheRefresher ( AppCaches appCaches , IPublishedSnapshotService publishedSnapshotService , IDomainService domainService )
: base ( appCaches )
2018-05-02 14:52:00 +10:00
{
_publishedSnapshotService = publishedSnapshotService ;
_domainService = domainService ;
2018-06-29 19:52:40 +02:00
}
#region Define
protected override LanguageCacheRefresher This = > this ;
2018-05-02 14:52:00 +10:00
public static readonly Guid UniqueId = Guid . Parse ( "3E0F95D8-0BE5-44B8-8394-2B8750B62654" ) ;
private readonly IPublishedSnapshotService _publishedSnapshotService ;
private readonly IDomainService _domainService ;
2018-06-29 19:52:40 +02:00
public override Guid RefresherUniqueId = > UniqueId ;
public override string Name = > "Language Cache Refresher" ;
#endregion
#region Refresher
2019-10-14 15:21:00 +11:00
public override void Refresh ( JsonPayload [ ] payloads )
2018-06-29 19:52:40 +02:00
{
2019-10-14 15:21:00 +11:00
if ( payloads . Length = = 0 ) return ;
2018-06-29 19:52:40 +02:00
2019-10-14 15:21:00 +11:00
var clearDictionary = false ;
var clearContent = false ;
//clear all no matter what type of payload
2018-06-29 19:52:40 +02:00
ClearAllIsolatedCacheByEntityType < ILanguage > ( ) ;
2019-10-14 15:21:00 +11:00
foreach ( var payload in payloads )
{
RefreshDomains ( payload . Id ) ;
switch ( payload . ChangeType )
{
case JsonPayload . LanguageChangeType . Update :
clearDictionary = true ;
break ;
case JsonPayload . LanguageChangeType . Remove :
clearDictionary = true ;
clearContent = true ;
break ;
case JsonPayload . LanguageChangeType . ChangeCulture :
clearDictionary = true ;
clearContent = true ;
break ;
}
}
if ( clearDictionary )
{
ClearAllIsolatedCacheByEntityType < IDictionaryItem > ( ) ;
}
//if this flag is set, we will tell the published snapshot service to refresh ALL content
if ( clearContent )
{
var clearContentPayload = new [ ] { new ContentCacheRefresher . JsonPayload ( 0 , null , TreeChangeTypes . RefreshAll ) } ;
ContentCacheRefresher . NotifyPublishedSnapshotService ( _publishedSnapshotService , AppCaches , clearContentPayload ) ;
}
// then trigger event
base . Refresh ( payloads ) ;
2018-06-29 19:52:40 +02:00
}
2019-10-14 15:21:00 +11:00
// these events should never trigger
// everything should be PAYLOAD/JSON
public override void RefreshAll ( ) = > throw new NotSupportedException ( ) ;
public override void Refresh ( int id ) = > throw new NotSupportedException ( ) ;
public override void Refresh ( Guid id ) = > throw new NotSupportedException ( ) ;
public override void Remove ( int id ) = > throw new NotSupportedException ( ) ;
2018-05-02 14:52:00 +10:00
#endregion
private void RefreshDomains ( int langId )
{
var assignedDomains = _domainService . GetAll ( true ) . Where ( x = > x . LanguageId . HasValue & & x . LanguageId . Value = = langId ) . ToList ( ) ;
if ( assignedDomains . Count > 0 )
{
2019-01-26 10:52:19 -05:00
// TODO: this is duplicating the logic in DomainCacheRefresher BUT we cannot inject that into this because it it not registered explicitly in the container,
2018-05-02 14:52:00 +10:00
// and we cannot inject the CacheRefresherCollection since that would be a circular reference, so what is the best way to call directly in to the
// DomainCacheRefresher?
ClearAllIsolatedCacheByEntityType < IDomain > ( ) ;
// note: must do what's above FIRST else the repositories still have the old cached
// content and when the PublishedCachesService is notified of changes it does not see
// the new content...
// notify
_publishedSnapshotService . Notify ( assignedDomains . Select ( x = > new DomainCacheRefresher . JsonPayload ( x . Id , DomainChangeTypes . Remove ) ) . ToArray ( ) ) ;
}
2018-06-29 19:52:40 +02:00
}
2019-10-14 15:21:00 +11:00
#region Json
public class JsonPayload
{
public JsonPayload ( int id , string isoCode , LanguageChangeType changeType )
{
Id = id ;
IsoCode = isoCode ;
ChangeType = changeType ;
}
public int Id { get ; }
public string IsoCode { get ; }
public LanguageChangeType ChangeType { get ; }
public enum LanguageChangeType
{
/// <summary>
/// A new languages has been added
/// </summary>
Add = 0 ,
/// <summary>
/// A language has been deleted
/// </summary>
Remove = 1 ,
/// <summary>
/// A language has been updated - but it's culture remains the same
/// </summary>
Update = 2 ,
/// <summary>
/// A language has been updated - it's culture has changed
/// </summary>
ChangeCulture = 3
}
}
#endregion
2018-06-29 19:52:40 +02:00
}
}