diff --git a/src/Umbraco.Core/Cache/CacheKeys.cs b/src/Umbraco.Core/Cache/CacheKeys.cs
index f37d20bd19..e2ea37cee9 100644
--- a/src/Umbraco.Core/Cache/CacheKeys.cs
+++ b/src/Umbraco.Core/Cache/CacheKeys.cs
@@ -26,5 +26,7 @@ namespace Umbraco.Core.Cache
public const string PropertyTypeCacheKey = "UmbracoPropertyTypeCache";
+ public const string LanguageCacheKey = "UmbracoLanguageCache";
+
}
}
\ No newline at end of file
diff --git a/src/Umbraco.Web/Cache/CacheRefresherEventHandler.cs b/src/Umbraco.Web/Cache/CacheRefresherEventHandler.cs
index 1b4ff703d6..4d6215bf10 100644
--- a/src/Umbraco.Web/Cache/CacheRefresherEventHandler.cs
+++ b/src/Umbraco.Web/Cache/CacheRefresherEventHandler.cs
@@ -30,6 +30,15 @@ namespace Umbraco.Web.Cache
content.AfterUpdateDocumentCache += ContentAfterUpdateDocumentCache;
content.AfterClearDocumentCache += ContentAfterClearDocumentCache;
+ //Bind to language events
+ //NOTE: we need to bind to legacy and new API events currently: http://issues.umbraco.org/issue/U4-1979
+
+ global::umbraco.cms.businesslogic.language.Language.AfterDelete += LanguageAfterDelete;
+ global::umbraco.cms.businesslogic.language.Language.New += LanguageNew;
+ global::umbraco.cms.businesslogic.language.Language.AfterSave += LanguageAfterSave;
+ LocalizationService.SavedLanguage += LocalizationServiceSavedLanguage;
+ LocalizationService.DeletedLanguage += LocalizationServiceDeletedLanguage;
+
//Bind to content type events
ContentTypeService.SavedContentType += ContentTypeServiceSavedContentType;
@@ -68,6 +77,56 @@ namespace Umbraco.Web.Cache
MediaService.Trashing += MediaServiceTrashing;
}
+ ///
+ /// Fires when a langauge is deleted
+ ///
+ ///
+ ///
+ static void LocalizationServiceDeletedLanguage(ILocalizationService sender, Core.Events.DeleteEventArgs e)
+ {
+ e.DeletedEntities.ForEach(x => DistributedCache.Instance.RemoveLanguageCache(x));
+ }
+
+ ///
+ /// Fires when a langauge is saved
+ ///
+ ///
+ ///
+ static void LocalizationServiceSavedLanguage(ILocalizationService sender, Core.Events.SaveEventArgs e)
+ {
+ e.SavedEntities.ForEach(x => DistributedCache.Instance.RefreshLanguageCache(x));
+ }
+
+ ///
+ /// Fires when a langauge is saved
+ ///
+ ///
+ ///
+ static void LanguageAfterSave(global::umbraco.cms.businesslogic.language.Language sender, SaveEventArgs e)
+ {
+ DistributedCache.Instance.RefreshLanguageCache(sender);
+ }
+
+ ///
+ /// Fires when a langauge is created
+ ///
+ ///
+ ///
+ static void LanguageNew(global::umbraco.cms.businesslogic.language.Language sender, NewEventArgs e)
+ {
+ DistributedCache.Instance.RefreshLanguageCache(sender);
+ }
+
+ ///
+ /// Fires when a langauge is deleted
+ ///
+ ///
+ ///
+ static void LanguageAfterDelete(global::umbraco.cms.businesslogic.language.Language sender, DeleteEventArgs e)
+ {
+ DistributedCache.Instance.RemoveLanguageCache(sender);
+ }
+
///
/// Fires when a media type is deleted
///
diff --git a/src/Umbraco.Web/Cache/DistributedCache.cs b/src/Umbraco.Web/Cache/DistributedCache.cs
index d919510b9f..a34ef5e48a 100644
--- a/src/Umbraco.Web/Cache/DistributedCache.cs
+++ b/src/Umbraco.Web/Cache/DistributedCache.cs
@@ -42,6 +42,7 @@ namespace Umbraco.Web.Cache
public const string MacroCacheRefresherId = "7B1E683C-5F34-43dd-803D-9699EA1E98CA";
public const string UserCacheRefresherId = "E057AF6D-2EE6-41F4-8045-3694010F0AA6";
public const string ContentTypeCacheRefresherId = "6902E22C-9C10-483C-91F3-66B7CAE9E2F5";
+ public const string LanguageCacheRefresherId = "3E0F95D8-0BE5-44B8-8394-2B8750B62654";
#endregion
diff --git a/src/Umbraco.Web/Cache/DistributedCacheExtensions.cs b/src/Umbraco.Web/Cache/DistributedCacheExtensions.cs
index 53ab7adf27..85a66f814e 100644
--- a/src/Umbraco.Web/Cache/DistributedCacheExtensions.cs
+++ b/src/Umbraco.Web/Cache/DistributedCacheExtensions.cs
@@ -278,6 +278,42 @@ namespace Umbraco.Web.Cache
}
#endregion
+ #region Language Cache
+
+ public static void RefreshLanguageCache(this DistributedCache dc, ILanguage language)
+ {
+ if (language != null)
+ {
+ dc.Refresh(new Guid(DistributedCache.LanguageCacheRefresherId), language.Id);
+ }
+ }
+
+ public static void RemoveLanguageCache(this DistributedCache dc, ILanguage language)
+ {
+ if (language != null)
+ {
+ dc.Remove(new Guid(DistributedCache.LanguageCacheRefresherId), language.Id);
+ }
+ }
+
+ public static void RefreshLanguageCache(this DistributedCache dc, global::umbraco.cms.businesslogic.language.Language language)
+ {
+ if (language != null)
+ {
+ dc.Refresh(new Guid(DistributedCache.LanguageCacheRefresherId), language.id);
+ }
+ }
+
+ public static void RemoveLanguageCache(this DistributedCache dc, global::umbraco.cms.businesslogic.language.Language language)
+ {
+ if (language != null)
+ {
+ dc.Remove(new Guid(DistributedCache.LanguageCacheRefresherId), language.id);
+ }
+ }
+
+ #endregion
+
public static void ClearXsltCacheOnCurrentServer(this DistributedCache dc)
{
if (UmbracoSettings.UmbracoLibraryCacheDuration > 0)
diff --git a/src/Umbraco.Web/Cache/LanguageCacheRefresher.cs b/src/Umbraco.Web/Cache/LanguageCacheRefresher.cs
new file mode 100644
index 0000000000..59214b7258
--- /dev/null
+++ b/src/Umbraco.Web/Cache/LanguageCacheRefresher.cs
@@ -0,0 +1,39 @@
+using System;
+using Umbraco.Core;
+using Umbraco.Core.Cache;
+
+namespace Umbraco.Web.Cache
+{
+ ///
+ /// A cache refresher to ensure language cache is refreshed when languages change
+ ///
+ public sealed class LanguageCacheRefresher : CacheRefresherBase
+ {
+ protected override LanguageCacheRefresher Instance
+ {
+ get { return this; }
+ }
+
+ public override Guid UniqueIdentifier
+ {
+ get { return new Guid(DistributedCache.LanguageCacheRefresherId); }
+ }
+
+ public override string Name
+ {
+ get { return "Language cache refresher"; }
+ }
+
+ public override void Refresh(int id)
+ {
+ ApplicationContext.Current.ApplicationCache.ClearCacheItem(CacheKeys.LanguageCacheKey);
+ base.Refresh(id);
+ }
+
+ public override void Remove(int id)
+ {
+ ApplicationContext.Current.ApplicationCache.ClearCacheItem(CacheKeys.LanguageCacheKey);
+ base.Remove(id);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj
index 08cd74b77b..a59ec5c5c0 100644
--- a/src/Umbraco.Web/Umbraco.Web.csproj
+++ b/src/Umbraco.Web/Umbraco.Web.csproj
@@ -267,6 +267,7 @@
+
diff --git a/src/umbraco.cms/businesslogic/language/Language.cs b/src/umbraco.cms/businesslogic/language/Language.cs
index fd1da001ab..91aaa03f9b 100644
--- a/src/umbraco.cms/businesslogic/language/Language.cs
+++ b/src/umbraco.cms/businesslogic/language/Language.cs
@@ -3,6 +3,8 @@ using System.Collections.Generic;
using System.Data;
using System.Globalization;
using System.Xml;
+using Umbraco.Core;
+using Umbraco.Core.Cache;
using Umbraco.Core.Logging;
using umbraco.cms.businesslogic.cache;
using umbraco.DataLayer;
@@ -31,12 +33,7 @@ namespace umbraco.cms.businesslogic.language
#endregion
#region Constants and static members
-
- private static object getLanguageSyncLock = new object();
- private static readonly string UmbracoLanguageCacheKey = "UmbracoLanguageCache";
-
- private const int DefaultLanguageId = 1;
-
+
///
/// Gets the SQL helper.
///
@@ -48,8 +45,6 @@ namespace umbraco.cms.businesslogic.language
protected internal const string m_SQLOptimizedGetAll = @"select * from umbracoLanguage";
- private static readonly object m_Locker = new object();
-
#endregion
#region Constructors
@@ -93,19 +88,12 @@ namespace umbraco.cms.businesslogic.language
SqlHelper.ExecuteNonQuery(
"insert into umbracoLanguage (languageISOCode) values (@CultureCode)",
SqlHelper.CreateParameter("@CultureCode", CultureCode));
-
- InvalidateCache();
-
+
NewEventArgs e = new NewEventArgs();
GetByCultureCode(CultureCode).OnNew(e);
}
}
- private static void InvalidateCache()
- {
- Cache.ClearCacheItem(UmbracoLanguageCacheKey);
- }
-
///
/// Method for accessing all installed languagess
///
@@ -127,23 +115,24 @@ namespace umbraco.cms.businesslogic.language
///
public static IEnumerable GetAllAsList()
{
- return Cache.GetCacheItem>(UmbracoLanguageCacheKey, getLanguageSyncLock, TimeSpan.FromMinutes(60),
- delegate
- {
- var languages = new List();
-
- using (IRecordsReader dr = SqlHelper.ExecuteReader(m_SQLOptimizedGetAll))
+ return ApplicationContext.Current.ApplicationCache.GetCacheItem>(
+ CacheKeys.LanguageCacheKey,
+ TimeSpan.FromMinutes(60),
+ () =>
{
- while (dr.Read())
+ var languages = new List();
+ using (var dr = SqlHelper.ExecuteReader(m_SQLOptimizedGetAll))
{
- //create the ContentType object without setting up
- Language ct = new Language();
- ct.PopulateFromReader(dr);
- languages.Add(ct);
+ while (dr.Read())
+ {
+ //create the ContentType object without setting up
+ var ct = new Language();
+ ct.PopulateFromReader(dr);
+ languages.Add(ct);
+ }
}
- }
- return languages;
- });
+ return languages;
+ });
}
///
@@ -252,7 +241,6 @@ namespace umbraco.cms.businesslogic.language
if (!e.Cancel)
{
- InvalidateCache();
FireAfterSave(e);
}
}
@@ -287,8 +275,6 @@ namespace umbraco.cms.businesslogic.language
//remove the dictionary entries first
Item.RemoveByLanguage(id);
- InvalidateCache();
-
SqlHelper.ExecuteNonQuery("delete from umbracoLanguage where id = @id",
SqlHelper.CreateParameter("@id", id));