diff --git a/src/Umbraco.Core/PublishedModelFactoryExtensions.cs b/src/Umbraco.Core/PublishedModelFactoryExtensions.cs index d428accbbf..de6eeb6a42 100644 --- a/src/Umbraco.Core/PublishedModelFactoryExtensions.cs +++ b/src/Umbraco.Core/PublishedModelFactoryExtensions.cs @@ -8,6 +8,13 @@ namespace Umbraco.Core /// public static class PublishedModelFactoryExtensions { + /// + /// Returns true if the current is an implementation of + /// + /// + /// + public static bool IsLiveFactory(this IPublishedModelFactory factory) => factory is ILivePublishedModelFactory; + /// /// Executes an action with a safe live factory /// diff --git a/src/Umbraco.Core/Services/Changes/ContentTypeChangeTypes.cs b/src/Umbraco.Core/Services/Changes/ContentTypeChangeTypes.cs index 497f7d47a9..bf7f87fd1a 100644 --- a/src/Umbraco.Core/Services/Changes/ContentTypeChangeTypes.cs +++ b/src/Umbraco.Core/Services/Changes/ContentTypeChangeTypes.cs @@ -6,9 +6,25 @@ namespace Umbraco.Core.Services.Changes public enum ContentTypeChangeTypes : byte { None = 0, - Create = 1, // item type has been created, no impact - RefreshMain = 2, // changed, impacts content (adding property or composition does NOT) - RefreshOther = 4, // changed, other changes - Remove = 8 // item type has been removed + + /// + /// Item type has been created, no impact + /// + Create = 1, + + /// + /// Content type changes impact only the Content type being saved + /// + RefreshMain = 2, + + /// + /// Content type changes impacts the content type being saved and others used that are composed of it + /// + RefreshOther = 4, // changed, other change + + /// + /// Content type was removed + /// + Remove = 8 } } diff --git a/src/Umbraco.Web/Cache/ContentTypeCacheRefresher.cs b/src/Umbraco.Web/Cache/ContentTypeCacheRefresher.cs index 75f2889cab..266cddf6d5 100644 --- a/src/Umbraco.Web/Cache/ContentTypeCacheRefresher.cs +++ b/src/Umbraco.Web/Cache/ContentTypeCacheRefresher.cs @@ -18,17 +18,15 @@ namespace Umbraco.Web.Cache private readonly IPublishedSnapshotService _publishedSnapshotService; private readonly IPublishedModelFactory _publishedModelFactory; private readonly IContentTypeCommonRepository _contentTypeCommonRepository; - private readonly IContentTypeService _contentTypeService; private readonly IdkMap _idkMap; - public ContentTypeCacheRefresher(AppCaches appCaches, IPublishedSnapshotService publishedSnapshotService, IPublishedModelFactory publishedModelFactory, IdkMap idkMap, IContentTypeCommonRepository contentTypeCommonRepository, IContentTypeService contentTypeService) + public ContentTypeCacheRefresher(AppCaches appCaches, IPublishedSnapshotService publishedSnapshotService, IPublishedModelFactory publishedModelFactory, IdkMap idkMap, IContentTypeCommonRepository contentTypeCommonRepository) : base(appCaches) { _publishedSnapshotService = publishedSnapshotService; _publishedModelFactory = publishedModelFactory; _idkMap = idkMap; _contentTypeCommonRepository = contentTypeCommonRepository; - _contentTypeService = contentTypeService; } #region Define @@ -53,16 +51,6 @@ namespace Umbraco.Web.Cache _contentTypeCommonRepository.ClearCache(); // always - //// We need to special handle the IContentType if modelsbuilder is in live mode, because all models are updated when a IContentType is changed, we need to clear all from cache also. - //if (_publishedModelFactory is ILivePublishedModelFactory && payloads.Any(x => x.ItemType == typeof(IContentType).Name)) - //{ - // //This is super nasty, and we need to figure out a better way to to this - // //Ensure all doc type ids is part of the payload - // var missingPayloads = GetMissingContentTypePayloads(payloads); - - // payloads = payloads.Union(missingPayloads).ToArray(); - //} - if (payloads.Any(x => x.ItemType == typeof(IContentType).Name)) { ClearAllIsolatedCacheByEntityType(); @@ -109,19 +97,6 @@ namespace Umbraco.Web.Cache base.Refresh(payloads); } - //private IEnumerable GetMissingContentTypePayloads(JsonPayload[] payloads) - //{ - // var existingPayloadIds = new HashSet(payloads.Select(x => x.Id)); - // var contentTypeIds = _contentTypeService.GetAll().Select(x => x.Id).ToArray(); - - // foreach (var contentTypeId in contentTypeIds) - // { - // if (!existingPayloadIds.Contains(contentTypeId)) - // { - // yield return new JsonPayload(typeof(IContentType).Name, contentTypeId, ContentTypeChangeTypes.RefreshOther); - // } - // } - //} public override void RefreshAll() { diff --git a/src/Umbraco.Web/PublishedCache/NuCache/PublishedSnapshotService.cs b/src/Umbraco.Web/PublishedCache/NuCache/PublishedSnapshotService.cs index e407dde1bb..b585781ea4 100755 --- a/src/Umbraco.Web/PublishedCache/NuCache/PublishedSnapshotService.cs +++ b/src/Umbraco.Web/PublishedCache/NuCache/PublishedSnapshotService.cs @@ -42,6 +42,7 @@ namespace Umbraco.Web.PublishedCache.NuCache private readonly IMemberRepository _memberRepository; private readonly IGlobalSettings _globalSettings; private readonly IEntityXmlSerializer _entitySerializer; + private readonly IPublishedModelFactory _publishedModelFactory; private readonly IDefaultCultureAccessor _defaultCultureAccessor; private readonly UrlSegmentProviderCollection _urlSegmentProviders; @@ -73,7 +74,8 @@ namespace Umbraco.Web.PublishedCache.NuCache IDocumentRepository documentRepository, IMediaRepository mediaRepository, IMemberRepository memberRepository, IDefaultCultureAccessor defaultCultureAccessor, IDataSource dataSource, IGlobalSettings globalSettings, - IEntityXmlSerializer entitySerializer, IPublishedModelFactory publishedModelFactory, + IEntityXmlSerializer entitySerializer, + IPublishedModelFactory publishedModelFactory, UrlSegmentProviderCollection urlSegmentProviders) : base(publishedSnapshotAccessor, variationContextAccessor) { @@ -95,6 +97,7 @@ namespace Umbraco.Web.PublishedCache.NuCache // we need an Xml serializer here so that the member cache can support XPath, // for members this is done by navigating the serialized-to-xml member _entitySerializer = entitySerializer; + _publishedModelFactory = publishedModelFactory; // we always want to handle repository events, configured or not // assuming no repository event will trigger before the whole db is ready @@ -708,6 +711,7 @@ namespace Umbraco.Web.PublishedCache.NuCache } } + /// public override void Notify(MediaCacheRefresher.JsonPayload[] payloads, out bool anythingChanged) { // no cache, trash everything @@ -800,6 +804,7 @@ namespace Umbraco.Web.PublishedCache.NuCache } } + /// public override void Notify(ContentTypeCacheRefresher.JsonPayload[] payloads) { // no cache, nothing we can do @@ -812,6 +817,16 @@ namespace Umbraco.Web.PublishedCache.NuCache Notify(_contentStore, payloads, RefreshContentTypesLocked); Notify(_mediaStore, payloads, RefreshMediaTypesLocked); + if (_publishedModelFactory.IsLiveFactory()) + { + //In the case of Pure Live - we actually need to refresh all of the content + using (_contentStore.GetScopedWriteLock(_scopeProvider)) + { + NotifyLocked(new[] { new ContentCacheRefresher.JsonPayload(0, TreeChangeTypes.RefreshAll) }, out var draftChanged, out var publishedChanged); + + } + } + ((PublishedSnapshot)CurrentPublishedSnapshot)?.Resync(); } @@ -820,9 +835,6 @@ namespace Umbraco.Web.PublishedCache.NuCache { if (payloads.Length == 0) return; //nothing to do - //TODO: In the case of Pure Live here - we actually need to refresh all of the content types - // AFAIK this is a call to SetValueLocked(_contentNodes... ) or is it a call to _contentStore.SetAll - var nameOfT = typeof(T).Name; List removedIds = null, refreshedIds = null, otherIds = null, newIds = null;