Merge remote-tracking branch 'origin/7.3.6' into dev-v7
Conflicts: build/UmbracoVersion.txt src/SolutionInfo.cs src/Umbraco.Core/Configuration/UmbracoVersion.cs src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs src/Umbraco.Core/Persistence/Repositories/ContentTypeBaseRepository.cs src/Umbraco.Core/Persistence/Repositories/ContentTypeRepository.cs src/Umbraco.Core/Persistence/Repositories/Interfaces/IMediaTypeRepository.cs src/Umbraco.Core/Persistence/Repositories/MediaTypeRepository.cs src/Umbraco.Core/Persistence/Repositories/MemberTypeRepository.cs src/Umbraco.Core/Umbraco.Core.csproj src/Umbraco.Web.UI/Umbraco.Web.UI.csproj src/Umbraco.Web/UmbracoContext.cs
This commit is contained in:
@@ -11,6 +11,10 @@ namespace Umbraco.Core.Cache
|
||||
/// </summary>
|
||||
/// <typeparam name="TEntity"></typeparam>
|
||||
/// <typeparam name="TId"></typeparam>
|
||||
/// <remarks>
|
||||
/// This cache policy uses sliding expiration and caches instances for 5 minutes. However if allow zero count is true, then we use the
|
||||
/// default policy with no expiry.
|
||||
/// </remarks>
|
||||
internal class DefaultRepositoryCachePolicy<TEntity, TId> : DisposableObject, IRepositoryCachePolicy<TEntity, TId>
|
||||
where TEntity : class, IAggregateRoot
|
||||
{
|
||||
@@ -54,7 +58,9 @@ namespace Umbraco.Core.Cache
|
||||
//just to be safe, we cannot cache an item without an identity
|
||||
if (entity.HasIdentity)
|
||||
{
|
||||
Cache.InsertCacheItem(GetCacheIdKey(entity.Id), () => entity);
|
||||
Cache.InsertCacheItem(GetCacheIdKey(entity.Id), () => entity,
|
||||
timeout: TimeSpan.FromMinutes(5),
|
||||
isSliding: true);
|
||||
}
|
||||
|
||||
//If there's a GetAllCacheAllowZeroCount cache, ensure it is cleared
|
||||
@@ -225,7 +231,9 @@ namespace Umbraco.Core.Cache
|
||||
//just to be safe, we cannot cache an item without an identity
|
||||
if (entity.HasIdentity)
|
||||
{
|
||||
Cache.InsertCacheItem(cacheKey, () => entity);
|
||||
Cache.InsertCacheItem(cacheKey, () => entity,
|
||||
timeout: TimeSpan.FromMinutes(5),
|
||||
isSliding: true);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -244,6 +252,7 @@ namespace Umbraco.Core.Cache
|
||||
{
|
||||
//there was nothing returned but we want to cache a zero count result so add an TEntity[] to the cache
|
||||
// to signify that there is a zero count cache
|
||||
//NOTE: Don't set expiry/sliding for a zero count
|
||||
Cache.InsertCacheItem(GetCacheTypeKey(), () => new TEntity[] {});
|
||||
}
|
||||
else
|
||||
@@ -256,7 +265,9 @@ namespace Umbraco.Core.Cache
|
||||
//just to be safe, we cannot cache an item without an identity
|
||||
if (localCopy.HasIdentity)
|
||||
{
|
||||
Cache.InsertCacheItem(GetCacheIdKey(entity.Id), () => localCopy);
|
||||
Cache.InsertCacheItem(GetCacheIdKey(entity.Id), () => localCopy,
|
||||
timeout: TimeSpan.FromMinutes(5),
|
||||
isSliding: true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,10 @@ namespace Umbraco.Core.Cache
|
||||
/// </summary>
|
||||
/// <typeparam name="TEntity"></typeparam>
|
||||
/// <typeparam name="TId"></typeparam>
|
||||
/// <remarks>
|
||||
/// This caching policy has no sliding expiration but uses the default ObjectCache.InfiniteAbsoluteExpiration as it's timeout, so it
|
||||
/// should not leave the cache unless the cache memory is exceeded and it gets thrown out.
|
||||
/// </remarks>
|
||||
internal class FullDataSetRepositoryCachePolicy<TEntity, TId> : DefaultRepositoryCachePolicy<TEntity, TId>
|
||||
where TEntity : class, IAggregateRoot
|
||||
{
|
||||
|
||||
@@ -98,45 +98,10 @@ namespace Umbraco.Core.Models.PublishedContent
|
||||
|
||||
#endregion
|
||||
|
||||
#region Cache
|
||||
|
||||
// these methods are called by ContentTypeCacheRefresher and DataTypeCacheRefresher
|
||||
|
||||
internal static void ClearAll()
|
||||
{
|
||||
Logging.LogHelper.Debug<PublishedContentType>("Clear all.");
|
||||
// ok and faster to do it by types, assuming noone else caches PublishedContentType instances
|
||||
//ApplicationContext.Current.ApplicationCache.ClearStaticCacheByKeySearch("PublishedContentType_");
|
||||
ApplicationContext.Current.ApplicationCache.StaticCache.ClearCacheObjectTypes<PublishedContentType>();
|
||||
}
|
||||
|
||||
internal static void ClearContentType(int id)
|
||||
{
|
||||
Logging.LogHelper.Debug<PublishedContentType>("Clear content type w/id {0}.", () => id);
|
||||
// requires a predicate because the key does not contain the ID
|
||||
// faster than key strings comparisons anyway
|
||||
ApplicationContext.Current.ApplicationCache.StaticCache.ClearCacheObjectTypes<PublishedContentType>(
|
||||
(key, value) => value.Id == id);
|
||||
}
|
||||
|
||||
internal static void ClearDataType(int id)
|
||||
{
|
||||
Logging.LogHelper.Debug<PublishedContentType>("Clear data type w/id {0}.", () => id);
|
||||
// there is no recursion to handle here because a PublishedContentType contains *all* its
|
||||
// properties ie both its own properties and those that were inherited (it's based upon an
|
||||
// IContentTypeComposition) and so every PublishedContentType having a property based upon
|
||||
// the cleared data type, be it local or inherited, will be cleared.
|
||||
ApplicationContext.Current.ApplicationCache.StaticCache.ClearCacheObjectTypes<PublishedContentType>(
|
||||
(key, value) => value.PropertyTypes.Any(x => x.DataTypeId == id));
|
||||
}
|
||||
|
||||
public static PublishedContentType Get(PublishedItemType itemType, string alias)
|
||||
{
|
||||
var key = string.Format("PublishedContentType_{0}_{1}",
|
||||
itemType.ToString().ToLowerInvariant(), alias.ToLowerInvariant());
|
||||
|
||||
var type = ApplicationContext.Current.ApplicationCache.StaticCache.GetCacheItem<PublishedContentType>(key,
|
||||
() => CreatePublishedContentType(itemType, alias));
|
||||
var type = CreatePublishedContentType(itemType, alias);
|
||||
|
||||
return type;
|
||||
}
|
||||
@@ -169,21 +134,8 @@ namespace Umbraco.Core.Models.PublishedContent
|
||||
return new PublishedContentType(contentType);
|
||||
}
|
||||
|
||||
// for unit tests - changing the callback must reset the cache obviously
|
||||
private static Func<string, PublishedContentType> _getPublishedContentTypeCallBack;
|
||||
internal static Func<string, PublishedContentType> GetPublishedContentTypeCallback
|
||||
{
|
||||
get { return _getPublishedContentTypeCallBack; }
|
||||
set
|
||||
{
|
||||
// see note above
|
||||
//ClearAll();
|
||||
ApplicationContext.Current.ApplicationCache.StaticCache.ClearCacheByKeySearch("PublishedContentType_");
|
||||
// for unit tests
|
||||
internal static Func<string, PublishedContentType> GetPublishedContentTypeCallback { get; set; }
|
||||
|
||||
_getPublishedContentTypeCallBack = value;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,9 +17,12 @@ namespace Umbraco.Core.Persistence.Relators
|
||||
|
||||
// Is this the same DictionaryItem as the current one we're processing
|
||||
if (Current != null && Current.Id == a.Id)
|
||||
{
|
||||
if (p.AppAlias.IsNullOrWhiteSpace() == false)
|
||||
{
|
||||
// Yes, just add this User2AppDto to the current item's collection
|
||||
Current.User2AppDtos.Add(p);
|
||||
}
|
||||
|
||||
// Return null to indicate we're not done with this User yet
|
||||
return null;
|
||||
@@ -35,7 +38,7 @@ namespace Umbraco.Core.Persistence.Relators
|
||||
Current = a;
|
||||
Current.User2AppDtos = new List<User2AppDto>();
|
||||
//this can be null since we are doing a left join
|
||||
if (p.AppAlias != null)
|
||||
if (p.AppAlias.IsNullOrWhiteSpace() == false)
|
||||
{
|
||||
Current.User2AppDtos.Add(p);
|
||||
}
|
||||
|
||||
@@ -85,7 +85,6 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
|
||||
return moveInfo;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the content type ids that match the query
|
||||
/// </summary>
|
||||
|
||||
@@ -475,7 +475,7 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
if (aliases.Any() == false) return base.GetAll();
|
||||
|
||||
//return from base.GetAll, this is all cached
|
||||
return base.GetAll().Where(x => aliases.Contains(x.Alias));
|
||||
return base.GetAll().Where(x => aliases.InvariantContains(x.Alias));
|
||||
}
|
||||
|
||||
public IEnumerable<ITemplate> GetChildren(int masterTemplateId)
|
||||
|
||||
@@ -142,8 +142,6 @@ namespace Umbraco.Web.Cache
|
||||
//clear static object cache
|
||||
global::umbraco.cms.businesslogic.ContentType.RemoveAllDataTypeCache();
|
||||
|
||||
PublishedContentType.ClearAll();
|
||||
|
||||
base.RefreshAll();
|
||||
}
|
||||
|
||||
@@ -281,8 +279,6 @@ namespace Umbraco.Web.Cache
|
||||
//clears the dictionary object cache of the legacy ContentType
|
||||
global::umbraco.cms.businesslogic.ContentType.RemoveFromDataTypeCache(payload.Alias);
|
||||
|
||||
PublishedContentType.ClearContentType(payload.Id);
|
||||
|
||||
//need to recursively clear the cache for each child content type
|
||||
foreach (var descendant in payload.DescendantPayloads)
|
||||
{
|
||||
|
||||
@@ -108,7 +108,6 @@ namespace Umbraco.Web.Cache
|
||||
if (dataTypeCache)
|
||||
dataTypeCache.Result.ClearCacheByKeySearch(string.Format("{0}{1}", CacheKeys.DataTypePreValuesCacheKey, payload.Id));
|
||||
|
||||
PublishedContentType.ClearDataType(payload.Id);
|
||||
});
|
||||
|
||||
base.Refresh(jsonPayload);
|
||||
|
||||
@@ -40,8 +40,13 @@ namespace Umbraco.Web.Install.InstallSteps
|
||||
var clientDependencyConfig = new ClientDependencyConfiguration(_applicationContext.ProfilingLogger.Logger);
|
||||
var clientDependencyUpdated = clientDependencyConfig.IncreaseVersionNumber();
|
||||
|
||||
//During a new install we'll log the default user in (which is id = 0).
|
||||
// During an upgrade, the user will already need to be logged in in order to run the installer.
|
||||
if (InstallTypeTarget == InstallationType.NewInstall)
|
||||
{
|
||||
var security = new WebSecurity(_httpContext, _applicationContext);
|
||||
security.PerformLogin(0);
|
||||
}
|
||||
|
||||
//reports the ended install
|
||||
var ih = new InstallHelper(UmbracoContext.Current);
|
||||
|
||||
@@ -125,6 +125,7 @@ namespace Umbraco.Web
|
||||
if (umbracoSettings == null) throw new ArgumentNullException("umbracoSettings");
|
||||
if (urlProviders == null) throw new ArgumentNullException("urlProviders");
|
||||
|
||||
//if there's already a singleton, and we're not replacing then there's no need to ensure anything
|
||||
if (UmbracoContext.Current != null)
|
||||
{
|
||||
if (replaceContext == false)
|
||||
@@ -132,6 +133,39 @@ namespace Umbraco.Web
|
||||
UmbracoContext.Current._replacing = true;
|
||||
}
|
||||
|
||||
var umbracoContext = CreateContext(httpContext, applicationContext, webSecurity, umbracoSettings, urlProviders, preview ?? false);
|
||||
|
||||
//assign the singleton
|
||||
UmbracoContext.Current = umbracoContext;
|
||||
return UmbracoContext.Current;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a standalone UmbracoContext instance
|
||||
/// </summary>
|
||||
/// <param name="httpContext"></param>
|
||||
/// <param name="applicationContext"></param>
|
||||
/// <param name="webSecurity"></param>
|
||||
/// <param name="umbracoSettings"></param>
|
||||
/// <param name="urlProviders"></param>
|
||||
/// <param name="preview"></param>
|
||||
/// <returns>
|
||||
/// A new instance of UmbracoContext
|
||||
/// </returns>
|
||||
public static UmbracoContext CreateContext(
|
||||
HttpContextBase httpContext,
|
||||
ApplicationContext applicationContext,
|
||||
WebSecurity webSecurity,
|
||||
IUmbracoSettingsSection umbracoSettings,
|
||||
IEnumerable<IUrlProvider> urlProviders,
|
||||
bool preview)
|
||||
{
|
||||
if (httpContext == null) throw new ArgumentNullException("httpContext");
|
||||
if (applicationContext == null) throw new ArgumentNullException("applicationContext");
|
||||
if (webSecurity == null) throw new ArgumentNullException("webSecurity");
|
||||
if (umbracoSettings == null) throw new ArgumentNullException("umbracoSettings");
|
||||
if (urlProviders == null) throw new ArgumentNullException("urlProviders");
|
||||
|
||||
var umbracoContext = new UmbracoContext(
|
||||
httpContext,
|
||||
applicationContext,
|
||||
@@ -159,9 +193,7 @@ namespace Umbraco.Web
|
||||
//assign the routing context back
|
||||
umbracoContext.RoutingContext = routingContext;
|
||||
|
||||
//assign the singleton
|
||||
UmbracoContext.Current = umbracoContext;
|
||||
return UmbracoContext.Current;
|
||||
return umbracoContext;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -460,17 +492,9 @@ namespace Umbraco.Web
|
||||
protected override void DisposeResources()
|
||||
{
|
||||
Security.DisposeIfDisposable();
|
||||
Security = null;
|
||||
_umbracoContext = null;
|
||||
|
||||
//Before we set these to null but in fact these are application lifespan singletons so
|
||||
//there's no reason we need to set them to null and this also caused a problem with packages
|
||||
//trying to access the cache properties on RequestEnd.
|
||||
//http://issues.umbraco.org/issue/U4-2734
|
||||
//http://our.umbraco.org/projects/developer-tools/301-url-tracker/version-2/44327-Issues-with-URL-Tracker-in-614
|
||||
//ContentCache = null;
|
||||
//MediaCache = null;
|
||||
//Application = null;
|
||||
//If not running in a web ctx, ensure the thread based instance is nulled
|
||||
_umbracoContext = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user