From f8b52a57c3cbdf99ab497b9018fb5c34073e085a Mon Sep 17 00:00:00 2001 From: Bjarke Berg Date: Wed, 23 Jan 2019 14:16:42 +0100 Subject: [PATCH] Injecting Umbraco Context Accessor and not saving the url on the class --- .../PublishedContentCacheTests.cs | 7 ++-- .../PublishedMediaCacheTests.cs | 18 ++++++---- .../Published/NestedContentTests.cs | 7 ++-- .../PublishedContent/NuCacheTests.cs | 1 + .../PublishedContent/PublishedMediaTests.cs | 6 ++-- .../Scoping/ScopedNuCacheTests.cs | 1 + .../ContentTypeServiceVariantsTests.cs | 2 ++ .../TestHelpers/TestWithDatabaseBase.cs | 1 + .../Web/Mvc/UmbracoViewPageTests.cs | 8 +++-- .../Models/PublishedContentBase.cs | 34 +++++++++---------- .../PublishedCache/NuCache/ContentNode.cs | 29 +++++++++------- .../PublishedCache/NuCache/ContentNodeKit.cs | 9 +++-- .../PublishedCache/NuCache/ContentStore.cs | 19 +++++++---- .../PublishedCache/NuCache/MemberCache.cs | 14 +++++--- .../NuCache/PublishedContent.cs | 22 +++++++++--- .../PublishedCache/NuCache/PublishedMember.cs | 21 +++++++++--- .../NuCache/PublishedSnapshotService.cs | 14 ++++---- .../PublishedCache/PublishedMember.cs | 6 +++- .../DictionaryPublishedContent.cs | 4 ++- .../PublishedContentCache.cs | 7 ++-- .../XmlPublishedCache/PublishedMediaCache.cs | 9 +++-- .../XmlPublishedCache/PublishedMemberCache.cs | 15 ++++---- .../PublishedSnapshotService.cs | 18 ++++++---- .../XmlPublishedCache/XmlPublishedContent.cs | 22 ++++++++---- 24 files changed, 194 insertions(+), 100 deletions(-) diff --git a/src/Umbraco.Tests/Cache/PublishedCache/PublishedContentCacheTests.cs b/src/Umbraco.Tests/Cache/PublishedCache/PublishedContentCacheTests.cs index 147a159d5f..e868e32b07 100644 --- a/src/Umbraco.Tests/Cache/PublishedCache/PublishedContentCacheTests.cs +++ b/src/Umbraco.Tests/Cache/PublishedCache/PublishedContentCacheTests.cs @@ -59,6 +59,7 @@ namespace Umbraco.Tests.Cache.PublishedCache var umbracoSettings = Factory.GetInstance(); var globalSettings = Factory.GetInstance(); + var umbracoContextAccessor = Factory.GetInstance(); _xml = new XmlDocument(); _xml.LoadXml(GetXml()); @@ -66,9 +67,9 @@ namespace Umbraco.Tests.Cache.PublishedCache var appCache = new DictionaryAppCache(); var domainCache = new DomainCache(ServiceContext.DomainService, DefaultCultureAccessor); var publishedShapshot = new Umbraco.Web.PublishedCache.XmlPublishedCache.PublishedSnapshot( - new PublishedContentCache(xmlStore, domainCache, appCache, globalSettings, new SiteDomainHelper(), ContentTypesCache, null, null), - new PublishedMediaCache(xmlStore, ServiceContext.MediaService, ServiceContext.UserService, appCache, ContentTypesCache, Factory.GetInstance()), - new PublishedMemberCache(null, appCache, Current.Services.MemberService, ContentTypesCache), + new PublishedContentCache(xmlStore, domainCache, appCache, globalSettings, new SiteDomainHelper(), umbracoContextAccessor, ContentTypesCache, null, null), + new PublishedMediaCache(xmlStore, ServiceContext.MediaService, ServiceContext.UserService, appCache, ContentTypesCache, Factory.GetInstance(), umbracoContextAccessor), + new PublishedMemberCache(null, appCache, Current.Services.MemberService, ContentTypesCache, umbracoContextAccessor), domainCache); var publishedSnapshotService = new Mock(); publishedSnapshotService.Setup(x => x.CreatePublishedSnapshot(It.IsAny())).Returns(publishedShapshot); diff --git a/src/Umbraco.Tests/Cache/PublishedCache/PublishedMediaCacheTests.cs b/src/Umbraco.Tests/Cache/PublishedCache/PublishedMediaCacheTests.cs index bd4f1610cd..07a6a6ee82 100644 --- a/src/Umbraco.Tests/Cache/PublishedCache/PublishedMediaCacheTests.cs +++ b/src/Umbraco.Tests/Cache/PublishedCache/PublishedMediaCacheTests.cs @@ -17,6 +17,7 @@ using Umbraco.Core.Models; using Umbraco.Core.Models.Membership; using Umbraco.Core.Services; using Umbraco.Tests.PublishedContent; +using Umbraco.Web; namespace Umbraco.Tests.Cache.PublishedCache { @@ -26,6 +27,7 @@ namespace Umbraco.Tests.Cache.PublishedCache { private Dictionary _mediaTypes; + private IUmbracoContextAccessor _umbracoContextAccessor; protected override void Compose() { base.Compose(); @@ -33,6 +35,8 @@ namespace Umbraco.Tests.Cache.PublishedCache Composition.WithCollectionBuilder() .Clear() .Append(); + + _umbracoContextAccessor = Current.UmbracoContextAccessor; } protected override void Initialize() @@ -75,7 +79,7 @@ namespace Umbraco.Tests.Cache.PublishedCache var mChild2 = MakeNewMedia("Child2", mType, user, mRoot2.Id); var ctx = GetUmbracoContext("/test"); - var cache = new PublishedMediaCache(new XmlStore((XmlDocument) null, null, null, null), ServiceContext.MediaService, ServiceContext.UserService, new DictionaryAppCache(), ContentTypesCache, Factory.GetInstance()); + var cache = new PublishedMediaCache(new XmlStore((XmlDocument) null, null, null, null), ServiceContext.MediaService, ServiceContext.UserService, new DictionaryAppCache(), ContentTypesCache, Factory.GetInstance(), Factory.GetInstance()); var roots = cache.GetAtRoot(); Assert.AreEqual(2, roots.Count()); Assert.IsTrue(roots.Select(x => x.Id).ContainsAll(new[] {mRoot1.Id, mRoot2.Id})); @@ -93,7 +97,7 @@ namespace Umbraco.Tests.Cache.PublishedCache //var publishedMedia = PublishedMediaTests.GetNode(mRoot.Id, GetUmbracoContext("/test", 1234)); var umbracoContext = GetUmbracoContext("/test"); - var cache = new PublishedMediaCache(new XmlStore((XmlDocument)null, null, null, null), Current.Services.MediaService, Current.Services.UserService, new DictionaryAppCache(), ContentTypesCache, Factory.GetInstance()); + var cache = new PublishedMediaCache(new XmlStore((XmlDocument)null, null, null, null), Current.Services.MediaService, Current.Services.UserService, new DictionaryAppCache(), ContentTypesCache, Factory.GetInstance(), Factory.GetInstance()); var publishedMedia = cache.GetById(mRoot.Id); Assert.IsNotNull(publishedMedia); @@ -204,7 +208,7 @@ namespace Umbraco.Tests.Cache.PublishedCache var result = new SearchResult("1234", 1, () => fields.ToDictionary(x => x.Key, x => new List { x.Value })); - var store = new PublishedMediaCache(new XmlStore((XmlDocument)null, null, null, null), ServiceContext.MediaService, ServiceContext.UserService, new DictionaryAppCache(), ContentTypesCache, Factory.GetInstance()); + var store = new PublishedMediaCache(new XmlStore((XmlDocument)null, null, null, null), ServiceContext.MediaService, ServiceContext.UserService, new DictionaryAppCache(), ContentTypesCache, Factory.GetInstance(), Factory.GetInstance()); var doc = store.CreateFromCacheValues(store.ConvertFromSearchResult(result)); DoAssert(doc, 1234, key, null, 0, "/media/test.jpg", "Image", 23, "Shannon", "Shannon", 0, 0, "-1,1234", DateTime.Parse("2012-07-17T10:34:09"), DateTime.Parse("2012-07-16T10:34:09"), 2); @@ -220,7 +224,7 @@ namespace Umbraco.Tests.Cache.PublishedCache var xmlDoc = GetMediaXml(); ((XmlElement)xmlDoc.DocumentElement.FirstChild).SetAttribute("key", key.ToString()); var navigator = xmlDoc.SelectSingleNode("/root/Image").CreateNavigator(); - var cache = new PublishedMediaCache(new XmlStore((XmlDocument)null, null, null, null), ServiceContext.MediaService, ServiceContext.UserService, new DictionaryAppCache(), ContentTypesCache, Factory.GetInstance()); + var cache = new PublishedMediaCache(new XmlStore((XmlDocument)null, null, null, null), ServiceContext.MediaService, ServiceContext.UserService, new DictionaryAppCache(), ContentTypesCache, Factory.GetInstance(), Factory.GetInstance()); var doc = cache.CreateFromCacheValues(cache.ConvertFromXPathNavigator(navigator, true)); DoAssert(doc, 2000, key, null, 2, "image1", "Image", 23, "Shannon", "Shannon", 33, 33, "-1,2000", DateTime.Parse("2012-06-12T14:13:17"), DateTime.Parse("2012-07-20T18:50:43"), 1); @@ -319,7 +323,8 @@ namespace Umbraco.Tests.Cache.PublishedCache // no xpath null, // not from examine - false), + false, + _umbracoContextAccessor), //callback to get the children (dd, n) => children, // callback to get a property @@ -329,7 +334,8 @@ namespace Umbraco.Tests.Cache.PublishedCache // no xpath null, // not from examine - false); + false, + _umbracoContextAccessor); return dicDoc; } diff --git a/src/Umbraco.Tests/Published/NestedContentTests.cs b/src/Umbraco.Tests/Published/NestedContentTests.cs index b5d6182c28..375fb5ee0f 100644 --- a/src/Umbraco.Tests/Published/NestedContentTests.cs +++ b/src/Umbraco.Tests/Published/NestedContentTests.cs @@ -161,7 +161,7 @@ namespace Umbraco.Tests.Published new TestPublishedProperty(contentType1.GetPropertyType("property1"), $@"[ {{ ""key"": ""{keyA}"", ""propertyN1"": ""foo"", ""ncContentTypeAlias"": ""contentN1"" }} ]") - }); + }, Mock.Of()); var value = content.Value("property1"); // nested single converter returns proper TestModel value @@ -189,7 +189,8 @@ namespace Umbraco.Tests.Published {{ ""key"": ""{keyA}"", ""propertyN1"": ""foo"", ""ncContentTypeAlias"": ""contentN1"" }}, {{ ""key"": ""{keyB}"", ""propertyN1"": ""bar"", ""ncContentTypeAlias"": ""contentN1"" }} ]") - }); + }, + Mock.Of()); var value = content.Value("property2"); // nested many converter returns proper IEnumerable value @@ -249,7 +250,7 @@ namespace Umbraco.Tests.Published class TestPublishedContent : PublishedContentBase { - public TestPublishedContent(PublishedContentType contentType, Guid key, IEnumerable properties) + public TestPublishedContent(PublishedContentType contentType, Guid key, IEnumerable properties, IUmbracoContextAccessor umbracoContextAccessor): base(umbracoContextAccessor) { ContentType = contentType; Key = key; diff --git a/src/Umbraco.Tests/PublishedContent/NuCacheTests.cs b/src/Umbraco.Tests/PublishedContent/NuCacheTests.cs index ef37a822c1..9130161d3a 100644 --- a/src/Umbraco.Tests/PublishedContent/NuCacheTests.cs +++ b/src/Umbraco.Tests/PublishedContent/NuCacheTests.cs @@ -144,6 +144,7 @@ namespace Umbraco.Tests.PublishedContent null, new TestPublishedSnapshotAccessor(), variationAccessor, + Mock.Of(), Mock.Of(), scopeProvider, Mock.Of(), diff --git a/src/Umbraco.Tests/PublishedContent/PublishedMediaTests.cs b/src/Umbraco.Tests/PublishedContent/PublishedMediaTests.cs index dfb51e83fb..bc1d8c2b70 100644 --- a/src/Umbraco.Tests/PublishedContent/PublishedMediaTests.cs +++ b/src/Umbraco.Tests/PublishedContent/PublishedMediaTests.cs @@ -69,7 +69,7 @@ namespace Umbraco.Tests.PublishedContent { var cache = new PublishedMediaCache(new XmlStore((XmlDocument)null, null, null, null), ServiceContext.MediaService, ServiceContext.UserService, new DictionaryAppCache(), ContentTypesCache, - Factory.GetInstance()); + Factory.GetInstance(), Factory.GetInstance()); var doc = cache.GetById(id); Assert.IsNotNull(doc); return doc; @@ -482,7 +482,7 @@ namespace Umbraco.Tests.PublishedContent "); var node = xml.DescendantsAndSelf("Image").Single(x => (int)x.Attribute("id") == nodeId); - var publishedMedia = new PublishedMediaCache(new XmlStore((XmlDocument)null, null, null, null), ServiceContext.MediaService, ServiceContext.UserService, new DictionaryAppCache(), ContentTypesCache, Factory.GetInstance()); + var publishedMedia = new PublishedMediaCache(new XmlStore((XmlDocument)null, null, null, null), ServiceContext.MediaService, ServiceContext.UserService, new DictionaryAppCache(), ContentTypesCache, Factory.GetInstance(), Factory.GetInstance()); var nav = node.CreateNavigator(); @@ -502,7 +502,7 @@ namespace Umbraco.Tests.PublishedContent var errorXml = new XElement("error", string.Format("No media is maching '{0}'", 1234)); var nav = errorXml.CreateNavigator(); - var publishedMedia = new PublishedMediaCache(new XmlStore((XmlDocument)null, null, null, null), ServiceContext.MediaService, ServiceContext.UserService, new DictionaryAppCache(), ContentTypesCache, Factory.GetInstance()); + var publishedMedia = new PublishedMediaCache(new XmlStore((XmlDocument)null, null, null, null), ServiceContext.MediaService, ServiceContext.UserService, new DictionaryAppCache(), ContentTypesCache, Factory.GetInstance(), Factory.GetInstance()); var converted = publishedMedia.ConvertFromXPathNodeIterator(nav.Select("/"), 1234); Assert.IsNull(converted); diff --git a/src/Umbraco.Tests/Scoping/ScopedNuCacheTests.cs b/src/Umbraco.Tests/Scoping/ScopedNuCacheTests.cs index e8f3463ca7..eb545fdb4f 100644 --- a/src/Umbraco.Tests/Scoping/ScopedNuCacheTests.cs +++ b/src/Umbraco.Tests/Scoping/ScopedNuCacheTests.cs @@ -90,6 +90,7 @@ namespace Umbraco.Tests.Scoping null, publishedSnapshotAccessor, Mock.Of(), + Mock.Of(), Logger, ScopeProvider, documentRepository, mediaRepository, memberRepository, diff --git a/src/Umbraco.Tests/Services/ContentTypeServiceVariantsTests.cs b/src/Umbraco.Tests/Services/ContentTypeServiceVariantsTests.cs index d0c0b93b48..3d9a36ca80 100644 --- a/src/Umbraco.Tests/Services/ContentTypeServiceVariantsTests.cs +++ b/src/Umbraco.Tests/Services/ContentTypeServiceVariantsTests.cs @@ -17,6 +17,7 @@ using Umbraco.Core.PropertyEditors; using Umbraco.Core.Services; using Umbraco.Core.Sync; using Umbraco.Tests.Testing; +using Umbraco.Web; using Umbraco.Web.PublishedCache; using Umbraco.Web.PublishedCache.NuCache; using Umbraco.Web.PublishedCache.NuCache.DataSource; @@ -62,6 +63,7 @@ namespace Umbraco.Tests.Services null, publishedSnapshotAccessor, Mock.Of(), + Mock.Of(), Logger, ScopeProvider, documentRepository, mediaRepository, memberRepository, diff --git a/src/Umbraco.Tests/TestHelpers/TestWithDatabaseBase.cs b/src/Umbraco.Tests/TestHelpers/TestWithDatabaseBase.cs index 2deb30bbdd..b312bc1607 100644 --- a/src/Umbraco.Tests/TestHelpers/TestWithDatabaseBase.cs +++ b/src/Umbraco.Tests/TestHelpers/TestWithDatabaseBase.cs @@ -264,6 +264,7 @@ namespace Umbraco.Tests.TestHelpers Factory.GetInstance(), ScopeProvider, cache, publishedSnapshotAccessor, variationContextAccessor, + Factory.GetInstance(), Factory.GetInstance(), Factory.GetInstance(), Factory.GetInstance(), DefaultCultureAccessor, Logger, diff --git a/src/Umbraco.Tests/Web/Mvc/UmbracoViewPageTests.cs b/src/Umbraco.Tests/Web/Mvc/UmbracoViewPageTests.cs index 133cbb2ee7..fee18cb382 100644 --- a/src/Umbraco.Tests/Web/Mvc/UmbracoViewPageTests.cs +++ b/src/Umbraco.Tests/Web/Mvc/UmbracoViewPageTests.cs @@ -419,13 +419,15 @@ namespace Umbraco.Tests.Web.Mvc //var provider = new ScopeUnitOfWorkProvider(databaseFactory, new RepositoryFactory(Mock.Of())); var scopeProvider = TestObjects.GetScopeProvider(Mock.Of()); var factory = Mock.Of(); - _service = new PublishedSnapshotService(svcCtx, factory, scopeProvider, cache, + var umbracoContextAccessor = Mock.Of(); + _service = new PublishedSnapshotService(svcCtx, factory, scopeProvider, cache, null, null, - null, null, null, + umbracoContextAccessor, null, null, null, new TestDefaultCultureAccessor(), Current.Logger, TestObjects.GetGlobalSettings(), new SiteDomainHelper(), Factory.GetInstance(), - null, true, false); // no events + null, true, false + ); // no events var http = GetHttpContextFactory(url, routeData).HttpContext; diff --git a/src/Umbraco.Web/Models/PublishedContentBase.cs b/src/Umbraco.Web/Models/PublishedContentBase.cs index c772f6ca85..d165209f0d 100644 --- a/src/Umbraco.Web/Models/PublishedContentBase.cs +++ b/src/Umbraco.Web/Models/PublishedContentBase.cs @@ -15,7 +15,12 @@ namespace Umbraco.Web.Models [DebuggerDisplay("Content Id: {Id}, Name: {Name}")] public abstract class PublishedContentBase : IPublishedContent { - private string _url; // fixme/task - cannot cache urls, they depends on the current request + private readonly IUmbracoContextAccessor _umbracoContextAccessor; + + protected PublishedContentBase(IUmbracoContextAccessor umbracoContextAccessor) + { + _umbracoContextAccessor = umbracoContextAccessor; + } #region ContentType @@ -81,24 +86,21 @@ namespace Umbraco.Web.Models /// public virtual string GetUrl(string culture = null) // todo - consider .GetCulture("fr-FR").Url { + var umbracoContext = _umbracoContextAccessor.UmbracoContext; switch (ItemType) { case PublishedItemType.Content: - // todo - consider injecting an umbraco context accessor - if (UmbracoContext.Current == null) - throw new InvalidOperationException("Cannot compute Url for a content item when UmbracoContext.Current is null."); - if (UmbracoContext.Current.UrlProvider == null) - throw new InvalidOperationException("Cannot compute Url for a content item when UmbracoContext.Current.UrlProvider is null."); - return UmbracoContext.Current.UrlProvider.GetUrl(this, culture); + if (umbracoContext == null) + throw new InvalidOperationException("Cannot compute Url for a content item when UmbracoContext is null."); + if (umbracoContext.UrlProvider == null) + throw new InvalidOperationException("Cannot compute Url for a content item when UmbracoContext.UrlProvider is null."); + return umbracoContext.UrlProvider.GetUrl(this, culture); case PublishedItemType.Media: - if (_url != null) return _url; // assume it will not depend on current uri/culture - var prop = GetProperty(Constants.Conventions.Media.File); if (prop?.GetValue() == null) { - _url = string.Empty; - return _url; + return string.Empty; } var propType = ContentType.GetPropertyType(Constants.Conventions.Media.File); @@ -110,7 +112,7 @@ namespace Umbraco.Web.Models switch (propType.EditorAlias) { case Constants.PropertyEditors.Aliases.UploadField: - _url = prop.GetValue().ToString(); + return prop.GetValue().ToString(); break; case Constants.PropertyEditors.Aliases.ImageCropper: //get the url from the json format @@ -118,14 +120,12 @@ namespace Umbraco.Web.Models var stronglyTyped = prop.GetValue() as ImageCropperValue; if (stronglyTyped != null) { - _url = stronglyTyped.Src; - break; + return stronglyTyped.Src; } - _url = prop.GetValue()?.ToString(); - break; + return prop.GetValue()?.ToString(); } - return _url; + return string.Empty; default: throw new NotSupportedException(); diff --git a/src/Umbraco.Web/PublishedCache/NuCache/ContentNode.cs b/src/Umbraco.Web/PublishedCache/NuCache/ContentNode.cs index 647adaad91..d6e72b03d5 100644 --- a/src/Umbraco.Web/PublishedCache/NuCache/ContentNode.cs +++ b/src/Umbraco.Web/PublishedCache/NuCache/ContentNode.cs @@ -34,10 +34,11 @@ namespace Umbraco.Web.PublishedCache.NuCache DateTime createDate, int creatorId, ContentData draftData, ContentData publishedData, IPublishedSnapshotAccessor publishedSnapshotAccessor, - IVariationContextAccessor variationContextAccessor) + IVariationContextAccessor variationContextAccessor, + IUmbracoContextAccessor umbracoContextAccessor) : this(id, uid, level, path, sortOrder, parentContentId, createDate, creatorId) { - SetContentTypeAndData(contentType, draftData, publishedData, publishedSnapshotAccessor, variationContextAccessor); + SetContentTypeAndData(contentType, draftData, publishedData, publishedSnapshotAccessor, variationContextAccessor, umbracoContextAccessor); } // 2-phases ctor, phase 1 @@ -59,7 +60,7 @@ namespace Umbraco.Web.PublishedCache.NuCache } // two-phase ctor, phase 2 - public void SetContentTypeAndData(PublishedContentType contentType, ContentData draftData, ContentData publishedData, IPublishedSnapshotAccessor publishedSnapshotAccessor, IVariationContextAccessor variationContextAccessor) + public void SetContentTypeAndData(PublishedContentType contentType, ContentData draftData, ContentData publishedData, IPublishedSnapshotAccessor publishedSnapshotAccessor, IVariationContextAccessor variationContextAccessor, IUmbracoContextAccessor umbracoContextAccessor) { ContentType = contentType; @@ -67,13 +68,13 @@ namespace Umbraco.Web.PublishedCache.NuCache throw new ArgumentException("Both draftData and publishedData cannot be null at the same time."); if (draftData != null) - Draft = new PublishedContent(this, draftData, publishedSnapshotAccessor, variationContextAccessor).CreateModel(); + Draft = new PublishedContent(this, draftData, publishedSnapshotAccessor, variationContextAccessor, umbracoContextAccessor).CreateModel(); if (publishedData != null) - Published = new PublishedContent(this, publishedData, publishedSnapshotAccessor, variationContextAccessor).CreateModel(); + Published = new PublishedContent(this, publishedData, publishedSnapshotAccessor, variationContextAccessor, umbracoContextAccessor).CreateModel(); } // clone parent - private ContentNode(ContentNode origin) + private ContentNode(ContentNode origin, IUmbracoContextAccessor umbracoContextAccessor) { // everything is the same, except for the child items // list which is a clone of the original list @@ -91,14 +92,14 @@ namespace Umbraco.Web.PublishedCache.NuCache var originDraft = origin.Draft == null ? null : PublishedContent.UnwrapIPublishedContent(origin.Draft); var originPublished = origin.Published == null ? null : PublishedContent.UnwrapIPublishedContent(origin.Published); - Draft = originDraft == null ? null : new PublishedContent(this, originDraft).CreateModel(); - Published = originPublished == null ? null : new PublishedContent(this, originPublished).CreateModel(); + Draft = originDraft == null ? null : new PublishedContent(this, originDraft, umbracoContextAccessor).CreateModel(); + Published = originPublished == null ? null : new PublishedContent(this, originPublished, umbracoContextAccessor).CreateModel(); ChildContentIds = new List(origin.ChildContentIds); // needs to be *another* list } // clone with new content type - public ContentNode(ContentNode origin, PublishedContentType contentType, IPublishedSnapshotAccessor publishedSnapshotAccessor, IVariationContextAccessor variationContextAccessor) + public ContentNode(ContentNode origin, PublishedContentType contentType, IPublishedSnapshotAccessor publishedSnapshotAccessor, IVariationContextAccessor variationContextAccessor, IUmbracoContextAccessor umbracoContextAccessor) { Id = origin.Id; Uid = origin.Uid; @@ -113,8 +114,8 @@ namespace Umbraco.Web.PublishedCache.NuCache var originDraft = origin.Draft == null ? null : PublishedContent.UnwrapIPublishedContent(origin.Draft); var originPublished = origin.Published == null ? null : PublishedContent.UnwrapIPublishedContent(origin.Published); - Draft = originDraft == null ? null : new PublishedContent(this, originDraft._contentData, publishedSnapshotAccessor, variationContextAccessor).CreateModel(); - Published = originPublished == null ? null : new PublishedContent(this, originPublished._contentData, publishedSnapshotAccessor, variationContextAccessor).CreateModel(); + Draft = originDraft == null ? null : new PublishedContent(this, originDraft._contentData, publishedSnapshotAccessor, variationContextAccessor, umbracoContextAccessor).CreateModel(); + Published = originPublished == null ? null : new PublishedContent(this, originPublished._contentData, publishedSnapshotAccessor, variationContextAccessor, umbracoContextAccessor).CreateModel(); ChildContentIds = origin.ChildContentIds; // can be the *same* list } @@ -137,9 +138,11 @@ namespace Umbraco.Web.PublishedCache.NuCache public IPublishedContent Draft; public IPublishedContent Published; - public ContentNode CloneParent(IPublishedSnapshotAccessor publishedSnapshotAccessor) + public ContentNode CloneParent( + IPublishedSnapshotAccessor publishedSnapshotAccessor, + IUmbracoContextAccessor umbracoContextAccessor) { - return new ContentNode(this); + return new ContentNode(this, umbracoContextAccessor); } public ContentNodeKit ToKit() diff --git a/src/Umbraco.Web/PublishedCache/NuCache/ContentNodeKit.cs b/src/Umbraco.Web/PublishedCache/NuCache/ContentNodeKit.cs index 5a47b99382..739a6141be 100644 --- a/src/Umbraco.Web/PublishedCache/NuCache/ContentNodeKit.cs +++ b/src/Umbraco.Web/PublishedCache/NuCache/ContentNodeKit.cs @@ -17,9 +17,14 @@ namespace Umbraco.Web.PublishedCache.NuCache public static ContentNodeKit Null { get; } = new ContentNodeKit { ContentTypeId = -1 }; - public void Build(PublishedContentType contentType, IPublishedSnapshotAccessor publishedSnapshotAccessor, IVariationContextAccessor variationContextAccessor, bool canBePublished) + public void Build( + PublishedContentType contentType, + IPublishedSnapshotAccessor publishedSnapshotAccessor, + IVariationContextAccessor variationContextAccessor, + bool canBePublished, + IUmbracoContextAccessor umbracoContextAccessor) { - Node.SetContentTypeAndData(contentType, DraftData, canBePublished ? PublishedData : null, publishedSnapshotAccessor, variationContextAccessor); + Node.SetContentTypeAndData(contentType, DraftData, canBePublished ? PublishedData : null, publishedSnapshotAccessor, variationContextAccessor,umbracoContextAccessor); } } } diff --git a/src/Umbraco.Web/PublishedCache/NuCache/ContentStore.cs b/src/Umbraco.Web/PublishedCache/NuCache/ContentStore.cs index 0cf2c231b5..aaf1ce29a3 100644 --- a/src/Umbraco.Web/PublishedCache/NuCache/ContentStore.cs +++ b/src/Umbraco.Web/PublishedCache/NuCache/ContentStore.cs @@ -20,6 +20,7 @@ namespace Umbraco.Web.PublishedCache.NuCache private readonly IPublishedSnapshotAccessor _publishedSnapshotAccessor; private readonly IVariationContextAccessor _variationContextAccessor; + private readonly IUmbracoContextAccessor _umbracoContextAccessor; private readonly ConcurrentDictionary> _contentNodes; private readonly ConcurrentDictionary> _contentRootNodes; private readonly ConcurrentDictionary> _contentTypesById; @@ -44,10 +45,16 @@ namespace Umbraco.Web.PublishedCache.NuCache #region Ctor - public ContentStore(IPublishedSnapshotAccessor publishedSnapshotAccessor, IVariationContextAccessor variationContextAccessor, ILogger logger, BPlusTree localDb = null) + public ContentStore( + IPublishedSnapshotAccessor publishedSnapshotAccessor, + IVariationContextAccessor variationContextAccessor, + IUmbracoContextAccessor umbracoContextAccessor, + ILogger logger, + BPlusTree localDb = null) { _publishedSnapshotAccessor = publishedSnapshotAccessor; _variationContextAccessor = variationContextAccessor; + _umbracoContextAccessor = umbracoContextAccessor; _logger = logger; _localDb = localDb; @@ -279,7 +286,7 @@ namespace Umbraco.Web.PublishedCache.NuCache if (node == null) continue; var contentTypeId = node.ContentType.Id; if (index.TryGetValue(contentTypeId, out PublishedContentType contentType) == false) continue; - SetValueLocked(_contentNodes, node.Id, new ContentNode(node, contentType, _publishedSnapshotAccessor, _variationContextAccessor)); + SetValueLocked(_contentNodes, node.Id, new ContentNode(node, contentType, _publishedSnapshotAccessor, _variationContextAccessor, _umbracoContextAccessor)); } } finally @@ -393,7 +400,7 @@ namespace Umbraco.Web.PublishedCache.NuCache _contentNodes.TryGetValue(id, out LinkedNode link); if (link?.Value == null) continue; - var node = new ContentNode(link.Value, contentType, _publishedSnapshotAccessor, _variationContextAccessor); + var node = new ContentNode(link.Value, contentType, _publishedSnapshotAccessor, _variationContextAccessor, _umbracoContextAccessor); SetValueLocked(_contentNodes, id, node); if (_localDb != null) RegisterChange(id, node.ToKit()); } @@ -419,7 +426,7 @@ namespace Umbraco.Web.PublishedCache.NuCache var canBePublished = ParentPublishedLocked(kit); // and use - kit.Build(link.Value, _publishedSnapshotAccessor, _variationContextAccessor, canBePublished); + kit.Build(link.Value, _publishedSnapshotAccessor, _variationContextAccessor, canBePublished, _umbracoContextAccessor); return true; } @@ -631,7 +638,7 @@ namespace Umbraco.Web.PublishedCache.NuCache var link = GetParentLink(content); var parent = link.Value; if (link.Gen < _liveGen) - parent = parent.CloneParent(_publishedSnapshotAccessor); + parent = parent.CloneParent(_publishedSnapshotAccessor, _umbracoContextAccessor); parent.ChildContentIds.Remove(content.Id); if (link.Gen < _liveGen) SetValueLocked(_contentNodes, parent.Id, parent); @@ -670,7 +677,7 @@ namespace Umbraco.Web.PublishedCache.NuCache var link = GetParentLink(content); var parent = link.Value; if (link.Gen < _liveGen) - parent = parent.CloneParent(_publishedSnapshotAccessor); + parent = parent.CloneParent(_publishedSnapshotAccessor, _umbracoContextAccessor); parent.ChildContentIds.Add(content.Id); if (link.Gen < _liveGen) SetValueLocked(_contentNodes, parent.Id, parent); diff --git a/src/Umbraco.Web/PublishedCache/NuCache/MemberCache.cs b/src/Umbraco.Web/PublishedCache/NuCache/MemberCache.cs index ecf099f90b..f7ffe73109 100644 --- a/src/Umbraco.Web/PublishedCache/NuCache/MemberCache.cs +++ b/src/Umbraco.Web/PublishedCache/NuCache/MemberCache.cs @@ -17,18 +17,22 @@ namespace Umbraco.Web.PublishedCache.NuCache internal class MemberCache : IPublishedMemberCache, INavigableData { private readonly IPublishedSnapshotAccessor _publishedSnapshotAccessor; + public readonly IVariationContextAccessor VariationContextAccessor; + private readonly IUmbracoContextAccessor _umbracoContextAccessor; private readonly IEntityXmlSerializer _entitySerializer; private readonly IAppCache _snapshotCache; private readonly IMemberService _memberService; private readonly PublishedContentTypeCache _contentTypeCache; private readonly bool _previewDefault; - public MemberCache(bool previewDefault, IAppCache snapshotCache, IMemberService memberService, PublishedContentTypeCache contentTypeCache, IPublishedSnapshotAccessor publishedSnapshotAccessor, IVariationContextAccessor variationContextAccessor, IEntityXmlSerializer entitySerializer) + public MemberCache(bool previewDefault, IAppCache snapshotCache, IMemberService memberService, PublishedContentTypeCache contentTypeCache, + IPublishedSnapshotAccessor publishedSnapshotAccessor, IVariationContextAccessor variationContextAccessor, IUmbracoContextAccessor umbracoContextAccessor, IEntityXmlSerializer entitySerializer) { _snapshotCache = snapshotCache; _publishedSnapshotAccessor = publishedSnapshotAccessor; VariationContextAccessor = variationContextAccessor; + _umbracoContextAccessor = umbracoContextAccessor; _entitySerializer = entitySerializer; _memberService = memberService; _previewDefault = previewDefault; @@ -64,14 +68,14 @@ namespace Umbraco.Web.PublishedCache.NuCache var member = _memberService.GetById(memberId); return member == null ? null - : PublishedMember.Create(member, GetContentType(member.ContentTypeId), _previewDefault, _publishedSnapshotAccessor, VariationContextAccessor); + : PublishedMember.Create(member, GetContentType(member.ContentTypeId), _previewDefault, _publishedSnapshotAccessor, VariationContextAccessor, _umbracoContextAccessor); }); } private IPublishedContent /*IPublishedMember*/ GetById(IMember member, bool previewing) { return GetCacheItem(CacheKeys.MemberCacheMember("ById", _previewDefault, member.Id), () => - PublishedMember.Create(member, GetContentType(member.ContentTypeId), previewing, _publishedSnapshotAccessor, VariationContextAccessor)); + PublishedMember.Create(member, GetContentType(member.ContentTypeId), previewing, _publishedSnapshotAccessor, VariationContextAccessor, _umbracoContextAccessor)); } public IPublishedContent /*IPublishedMember*/ GetByProviderKey(object key) @@ -106,7 +110,7 @@ namespace Umbraco.Web.PublishedCache.NuCache public IPublishedContent /*IPublishedMember*/ GetByMember(IMember member) { - return PublishedMember.Create(member, GetContentType(member.ContentTypeId), _previewDefault, _publishedSnapshotAccessor, VariationContextAccessor); + return PublishedMember.Create(member, GetContentType(member.ContentTypeId), _previewDefault, _publishedSnapshotAccessor, VariationContextAccessor, _umbracoContextAccessor); } public IEnumerable GetAtRoot(bool preview) @@ -114,7 +118,7 @@ namespace Umbraco.Web.PublishedCache.NuCache // because members are flat (not a tree) everything is at root // because we're loading everything... let's just not cache? var members = _memberService.GetAllMembers(); - return members.Select(m => PublishedMember.Create(m, GetContentType(m.ContentTypeId), preview, _publishedSnapshotAccessor, VariationContextAccessor)); + return members.Select(m => PublishedMember.Create(m, GetContentType(m.ContentTypeId), preview, _publishedSnapshotAccessor, VariationContextAccessor, _umbracoContextAccessor)); } public XPathNavigator CreateNavigator() diff --git a/src/Umbraco.Web/PublishedCache/NuCache/PublishedContent.cs b/src/Umbraco.Web/PublishedCache/NuCache/PublishedContent.cs index d1e1d63630..5228c3f876 100644 --- a/src/Umbraco.Web/PublishedCache/NuCache/PublishedContent.cs +++ b/src/Umbraco.Web/PublishedCache/NuCache/PublishedContent.cs @@ -14,6 +14,7 @@ namespace Umbraco.Web.PublishedCache.NuCache internal class PublishedContent : PublishedContentBase { private readonly IPublishedSnapshotAccessor _publishedSnapshotAccessor; + private readonly IUmbracoContextAccessor _umbracoContextAccessor; private readonly ContentNode _contentNode; // ReSharper disable once InconsistentNaming internal readonly ContentData _contentData; // internal for ContentNode cloning @@ -22,11 +23,17 @@ namespace Umbraco.Web.PublishedCache.NuCache #region Constructors - public PublishedContent(ContentNode contentNode, ContentData contentData, IPublishedSnapshotAccessor publishedSnapshotAccessor, IVariationContextAccessor variationContextAccessor) + public PublishedContent( + ContentNode contentNode, + ContentData contentData, + IPublishedSnapshotAccessor publishedSnapshotAccessor, + IVariationContextAccessor variationContextAccessor, + IUmbracoContextAccessor umbracoContextAccessor) :base(umbracoContextAccessor) { _contentNode = contentNode; _contentData = contentData; _publishedSnapshotAccessor = publishedSnapshotAccessor; + _umbracoContextAccessor = umbracoContextAccessor; VariationContextAccessor = variationContextAccessor; _urlSegment = _contentData.Name.ToUrlSegment(); @@ -66,7 +73,10 @@ namespace Umbraco.Web.PublishedCache.NuCache } // (see ContentNode.CloneParent) - public PublishedContent(ContentNode contentNode, PublishedContent origin) + public PublishedContent( + ContentNode contentNode, + PublishedContent origin, + IUmbracoContextAccessor umbracoContextAccessor) :base(umbracoContextAccessor) { _contentNode = contentNode; _publishedSnapshotAccessor = origin._publishedSnapshotAccessor; @@ -83,7 +93,9 @@ namespace Umbraco.Web.PublishedCache.NuCache } // clone for previewing as draft a published content that is published and has no draft - private PublishedContent(PublishedContent origin) + private PublishedContent( + PublishedContent origin, + IUmbracoContextAccessor umbracoContextAccessor) :base(umbracoContextAccessor) { _publishedSnapshotAccessor = origin._publishedSnapshotAccessor; VariationContextAccessor = origin.VariationContextAccessor; @@ -433,8 +445,8 @@ namespace Umbraco.Web.PublishedCache.NuCache return this; var cache = GetAppropriateCache(); - if (cache == null) return new PublishedContent(this).CreateModel(); - return (IPublishedContent)cache.Get(AsPreviewingCacheKey, () => new PublishedContent(this).CreateModel()); + if (cache == null) return new PublishedContent(this, _umbracoContextAccessor).CreateModel(); + return (IPublishedContent)cache.Get(AsPreviewingCacheKey, () => new PublishedContent(this, _umbracoContextAccessor).CreateModel()); } // used by Navigable.Source,... diff --git a/src/Umbraco.Web/PublishedCache/NuCache/PublishedMember.cs b/src/Umbraco.Web/PublishedCache/NuCache/PublishedMember.cs index 47c8d738f1..db50fc3fe6 100644 --- a/src/Umbraco.Web/PublishedCache/NuCache/PublishedMember.cs +++ b/src/Umbraco.Web/PublishedCache/NuCache/PublishedMember.cs @@ -15,13 +15,26 @@ namespace Umbraco.Web.PublishedCache.NuCache { private readonly IMember _member; - private PublishedMember(IMember member, ContentNode contentNode, ContentData contentData, IPublishedSnapshotAccessor publishedSnapshotAccessor, IVariationContextAccessor variationContextAccessor) - : base(contentNode, contentData, publishedSnapshotAccessor, variationContextAccessor) + private PublishedMember( + IMember member, + ContentNode contentNode, + ContentData contentData, + IPublishedSnapshotAccessor publishedSnapshotAccessor, + IVariationContextAccessor variationContextAccessor, + IUmbracoContextAccessor umbracoContextAccessor + ) + : base(contentNode, contentData, publishedSnapshotAccessor, variationContextAccessor, umbracoContextAccessor) { _member = member; } - public static IPublishedContent Create(IMember member, PublishedContentType contentType, bool previewing, IPublishedSnapshotAccessor publishedSnapshotAccessor, IVariationContextAccessor variationContextAccessor) + public static IPublishedContent Create( + IMember member, + PublishedContentType contentType, + bool previewing, + IPublishedSnapshotAccessor publishedSnapshotAccessor, + IVariationContextAccessor variationContextAccessor, + IUmbracoContextAccessor umbracoContextAccessor) { var d = new ContentData { @@ -37,7 +50,7 @@ namespace Umbraco.Web.PublishedCache.NuCache member.Level, member.Path, member.SortOrder, member.ParentId, member.CreateDate, member.CreatorId); - return new PublishedMember(member, n, d, publishedSnapshotAccessor, variationContextAccessor).CreateModel(); + return new PublishedMember(member, n, d, publishedSnapshotAccessor, variationContextAccessor, umbracoContextAccessor).CreateModel(); } private static Dictionary GetPropertyValues(PublishedContentType contentType, IMember member) diff --git a/src/Umbraco.Web/PublishedCache/NuCache/PublishedSnapshotService.cs b/src/Umbraco.Web/PublishedCache/NuCache/PublishedSnapshotService.cs index 8675aefd1a..34c495ece9 100755 --- a/src/Umbraco.Web/PublishedCache/NuCache/PublishedSnapshotService.cs +++ b/src/Umbraco.Web/PublishedCache/NuCache/PublishedSnapshotService.cs @@ -32,6 +32,7 @@ namespace Umbraco.Web.PublishedCache.NuCache { private readonly ServiceContext _serviceContext; private readonly IPublishedContentTypeFactory _publishedContentTypeFactory; + private readonly IUmbracoContextAccessor _umbracoContextAccessor; private readonly IScopeProvider _scopeProvider; private readonly IDataSource _dataSource; private readonly ILogger _logger; @@ -80,7 +81,7 @@ namespace Umbraco.Web.PublishedCache.NuCache public PublishedSnapshotService(Options options, IMainDom mainDom, IRuntimeState runtime, ServiceContext serviceContext, IPublishedContentTypeFactory publishedContentTypeFactory, IdkMap idkMap, IPublishedSnapshotAccessor publishedSnapshotAccessor, IVariationContextAccessor variationContextAccessor, - ILogger logger, IScopeProvider scopeProvider, + IUmbracoContextAccessor umbracoContextAccessor, ILogger logger, IScopeProvider scopeProvider, IDocumentRepository documentRepository, IMediaRepository mediaRepository, IMemberRepository memberRepository, IDefaultCultureAccessor defaultCultureAccessor, IDataSource dataSource, IGlobalSettings globalSettings, ISiteDomainHelper siteDomainHelper, @@ -92,6 +93,7 @@ namespace Umbraco.Web.PublishedCache.NuCache _serviceContext = serviceContext; _publishedContentTypeFactory = publishedContentTypeFactory; + _umbracoContextAccessor = umbracoContextAccessor; _dataSource = dataSource; _logger = logger; _scopeProvider = scopeProvider; @@ -148,13 +150,13 @@ namespace Umbraco.Web.PublishedCache.NuCache // stores are created with a db so they can write to it, but they do not read from it, // stores need to be populated, happens in OnResolutionFrozen which uses _localDbExists to // figure out whether it can read the dbs or it should populate them from sql - _contentStore = new ContentStore(publishedSnapshotAccessor, variationContextAccessor, logger, _localContentDb); - _mediaStore = new ContentStore(publishedSnapshotAccessor, variationContextAccessor, logger, _localMediaDb); + _contentStore = new ContentStore(publishedSnapshotAccessor, variationContextAccessor, _umbracoContextAccessor, logger, _localContentDb); + _mediaStore = new ContentStore(publishedSnapshotAccessor, variationContextAccessor, _umbracoContextAccessor, logger, _localMediaDb); } else { - _contentStore = new ContentStore(publishedSnapshotAccessor, variationContextAccessor, logger); - _mediaStore = new ContentStore(publishedSnapshotAccessor, variationContextAccessor, logger); + _contentStore = new ContentStore(publishedSnapshotAccessor, variationContextAccessor, _umbracoContextAccessor, logger); + _mediaStore = new ContentStore(publishedSnapshotAccessor, variationContextAccessor, _umbracoContextAccessor, logger); } _domainStore = new SnapDictionary(); @@ -1015,7 +1017,7 @@ namespace Umbraco.Web.PublishedCache.NuCache { ContentCache = new ContentCache(previewDefault, contentSnap, snapshotCache, elementsCache, domainHelper, _globalSettings, _serviceContext.LocalizationService), MediaCache = new MediaCache(previewDefault, mediaSnap, snapshotCache, elementsCache), - MemberCache = new MemberCache(previewDefault, snapshotCache, _serviceContext.MemberService, memberTypeCache, PublishedSnapshotAccessor, VariationContextAccessor, _entitySerializer), + MemberCache = new MemberCache(previewDefault, snapshotCache, _serviceContext.MemberService, memberTypeCache, PublishedSnapshotAccessor, VariationContextAccessor, _umbracoContextAccessor, _entitySerializer), DomainCache = domainCache, SnapshotCache = snapshotCache, ElementsCache = elementsCache diff --git a/src/Umbraco.Web/PublishedCache/PublishedMember.cs b/src/Umbraco.Web/PublishedCache/PublishedMember.cs index ef95b2846c..56a0110f45 100644 --- a/src/Umbraco.Web/PublishedCache/PublishedMember.cs +++ b/src/Umbraco.Web/PublishedCache/PublishedMember.cs @@ -19,7 +19,11 @@ namespace Umbraco.Web.PublishedCache private readonly IPublishedProperty[] _properties; private readonly PublishedContentType _publishedMemberType; - public PublishedMember(IMember member, PublishedContentType publishedMemberType) + public PublishedMember( + IMember member, + PublishedContentType publishedMemberType, + IUmbracoContextAccessor umbracoContextAccessor) + :base(umbracoContextAccessor) { _member = member ?? throw new ArgumentNullException(nameof(member)); _membershipUser = member; diff --git a/src/Umbraco.Web/PublishedCache/XmlPublishedCache/DictionaryPublishedContent.cs b/src/Umbraco.Web/PublishedCache/XmlPublishedCache/DictionaryPublishedContent.cs index 83bd84dab6..24b3ed6ab5 100644 --- a/src/Umbraco.Web/PublishedCache/XmlPublishedCache/DictionaryPublishedContent.cs +++ b/src/Umbraco.Web/PublishedCache/XmlPublishedCache/DictionaryPublishedContent.cs @@ -38,7 +38,9 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache IAppCache appCache, PublishedContentTypeCache contentTypeCache, XPathNavigator nav, - bool fromExamine) + bool fromExamine, + IUmbracoContextAccessor umbracoContextAccessor) + :base(umbracoContextAccessor) { if (valueDictionary == null) throw new ArgumentNullException(nameof(valueDictionary)); if (getParent == null) throw new ArgumentNullException(nameof(getParent)); diff --git a/src/Umbraco.Web/PublishedCache/XmlPublishedCache/PublishedContentCache.cs b/src/Umbraco.Web/PublishedCache/XmlPublishedCache/PublishedContentCache.cs index d8c7c41ea1..6fd9f1da2b 100644 --- a/src/Umbraco.Web/PublishedCache/XmlPublishedCache/PublishedContentCache.cs +++ b/src/Umbraco.Web/PublishedCache/XmlPublishedCache/PublishedContentCache.cs @@ -17,6 +17,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache { private readonly IAppCache _appCache; private readonly IGlobalSettings _globalSettings; + private readonly IUmbracoContextAccessor _umbracoContextAccessor; private readonly RoutesCache _routesCache; private readonly IDomainCache _domainCache; private readonly DomainHelper _domainHelper; @@ -33,6 +34,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache IAppCache appCache, // an IAppCache that should be at request-level IGlobalSettings globalSettings, ISiteDomainHelper siteDomainHelper, + IUmbracoContextAccessor umbracoContextAccessor, PublishedContentTypeCache contentTypeCache, // a PublishedContentType cache RoutesCache routesCache, // a RoutesCache string previewToken) // a preview token string (or null if not previewing) @@ -40,6 +42,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache { _appCache = appCache; _globalSettings = globalSettings; + _umbracoContextAccessor = umbracoContextAccessor; _routesCache = routesCache; // may be null for unit-testing _contentTypeCache = contentTypeCache; _domainCache = domainCache; @@ -315,13 +318,13 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache private IPublishedContent ConvertToDocument(XmlNode xmlNode, bool isPreviewing) { - return xmlNode == null ? null : XmlPublishedContent.Get(xmlNode, isPreviewing, _appCache, _contentTypeCache); + return xmlNode == null ? null : XmlPublishedContent.Get(xmlNode, isPreviewing, _appCache, _contentTypeCache,_umbracoContextAccessor); } private IEnumerable ConvertToDocuments(XmlNodeList xmlNodes, bool isPreviewing) { return xmlNodes.Cast() - .Select(xmlNode => XmlPublishedContent.Get(xmlNode, isPreviewing, _appCache, _contentTypeCache)); + .Select(xmlNode => XmlPublishedContent.Get(xmlNode, isPreviewing, _appCache, _contentTypeCache, _umbracoContextAccessor)); } #endregion diff --git a/src/Umbraco.Web/PublishedCache/XmlPublishedCache/PublishedMediaCache.cs b/src/Umbraco.Web/PublishedCache/XmlPublishedCache/PublishedMediaCache.cs index dadf40a33b..85a9725f17 100644 --- a/src/Umbraco.Web/PublishedCache/XmlPublishedCache/PublishedMediaCache.cs +++ b/src/Umbraco.Web/PublishedCache/XmlPublishedCache/PublishedMediaCache.cs @@ -41,11 +41,14 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache private readonly XmlStore _xmlStore; private readonly PublishedContentTypeCache _contentTypeCache; private readonly IEntityXmlSerializer _entitySerializer; + private readonly IUmbracoContextAccessor _umbracoContextAccessor; // must be specified by the ctor private readonly IAppCache _appCache; - public PublishedMediaCache(XmlStore xmlStore, IMediaService mediaService, IUserService userService, IAppCache appCache, PublishedContentTypeCache contentTypeCache, IEntityXmlSerializer entitySerializer) + public PublishedMediaCache(XmlStore xmlStore, IMediaService mediaService, IUserService userService, + IAppCache appCache, PublishedContentTypeCache contentTypeCache, IEntityXmlSerializer entitySerializer, + IUmbracoContextAccessor umbracoContextAccessor) : base(false) { _mediaService = mediaService ?? throw new ArgumentNullException(nameof(mediaService)); @@ -55,6 +58,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache _xmlStore = xmlStore; _contentTypeCache = contentTypeCache; _entitySerializer = entitySerializer; + _umbracoContextAccessor = umbracoContextAccessor; } /// @@ -666,7 +670,8 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache _appCache, _contentTypeCache, cacheValues.XPath, // though, outside of tests, that should be null - cacheValues.FromExamine + cacheValues.FromExamine, + _umbracoContextAccessor ); return content.CreateModel(); } diff --git a/src/Umbraco.Web/PublishedCache/XmlPublishedCache/PublishedMemberCache.cs b/src/Umbraco.Web/PublishedCache/XmlPublishedCache/PublishedMemberCache.cs index 816eb3c545..db6d85fb2d 100644 --- a/src/Umbraco.Web/PublishedCache/XmlPublishedCache/PublishedMemberCache.cs +++ b/src/Umbraco.Web/PublishedCache/XmlPublishedCache/PublishedMemberCache.cs @@ -16,13 +16,16 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache private readonly IAppCache _requestCache; private readonly XmlStore _xmlStore; private readonly PublishedContentTypeCache _contentTypeCache; + private readonly IUmbracoContextAccessor _umbracoContextAccessor; - public PublishedMemberCache(XmlStore xmlStore, IAppCache requestCache, IMemberService memberService, PublishedContentTypeCache contentTypeCache) + public PublishedMemberCache(XmlStore xmlStore, IAppCache requestCache, IMemberService memberService, + PublishedContentTypeCache contentTypeCache, IUmbracoContextAccessor umbracoContextAccessor) { _requestCache = requestCache; _memberService = memberService; _xmlStore = xmlStore; _contentTypeCache = contentTypeCache; + _umbracoContextAccessor = umbracoContextAccessor; } public IPublishedContent GetByProviderKey(object key) @@ -39,7 +42,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache var result = _memberService.GetByProviderKey(key); if (result == null) return null; var type = _contentTypeCache.Get(PublishedItemType.Member, result.ContentTypeId); - return new PublishedMember(result, type).CreateModel(); + return new PublishedMember(result, type, _umbracoContextAccessor).CreateModel(); }); } @@ -57,7 +60,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache var result = _memberService.GetById(memberId); if (result == null) return null; var type = _contentTypeCache.Get(PublishedItemType.Member, result.ContentTypeId); - return new PublishedMember(result, type).CreateModel(); + return new PublishedMember(result, type, _umbracoContextAccessor).CreateModel(); }); } @@ -75,7 +78,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache var result = _memberService.GetByUsername(username); if (result == null) return null; var type = _contentTypeCache.Get(PublishedItemType.Member, result.ContentTypeId); - return new PublishedMember(result, type).CreateModel(); + return new PublishedMember(result, type, _umbracoContextAccessor).CreateModel(); }); } @@ -93,14 +96,14 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache var result = _memberService.GetByEmail(email); if (result == null) return null; var type = _contentTypeCache.Get(PublishedItemType.Member, result.ContentTypeId); - return new PublishedMember(result, type).CreateModel(); + return new PublishedMember(result, type, _umbracoContextAccessor).CreateModel(); }); } public IPublishedContent GetByMember(IMember member) { var type = _contentTypeCache.Get(PublishedItemType.Member, member.ContentTypeId); - return new PublishedMember(member, type).CreateModel(); + return new PublishedMember(member, type, _umbracoContextAccessor).CreateModel(); } public XPathNavigator CreateNavigator() diff --git a/src/Umbraco.Web/PublishedCache/XmlPublishedCache/PublishedSnapshotService.cs b/src/Umbraco.Web/PublishedCache/XmlPublishedCache/PublishedSnapshotService.cs index c4ce05c9a9..d96bfd8a0a 100644 --- a/src/Umbraco.Web/PublishedCache/XmlPublishedCache/PublishedSnapshotService.cs +++ b/src/Umbraco.Web/PublishedCache/XmlPublishedCache/PublishedSnapshotService.cs @@ -35,6 +35,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache private readonly IDefaultCultureAccessor _defaultCultureAccessor; private readonly ISiteDomainHelper _siteDomainHelper; private readonly IEntityXmlSerializer _entitySerializer; + private readonly IUmbracoContextAccessor _umbracoContextAccessor; #region Constructors @@ -44,6 +45,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache IScopeProvider scopeProvider, IAppCache requestCache, IPublishedSnapshotAccessor publishedSnapshotAccessor, IVariationContextAccessor variationContextAccessor, + IUmbracoContextAccessor umbracoContextAccessor, IDocumentRepository documentRepository, IMediaRepository mediaRepository, IMemberRepository memberRepository, IDefaultCultureAccessor defaultCultureAccessor, ILogger logger, @@ -52,12 +54,14 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache IEntityXmlSerializer entitySerializer, MainDom mainDom, bool testing = false, bool enableRepositoryEvents = true) - : this(serviceContext, publishedContentTypeFactory, scopeProvider, requestCache, - publishedSnapshotAccessor, variationContextAccessor, + : this(serviceContext, publishedContentTypeFactory, scopeProvider, requestCache, + publishedSnapshotAccessor, variationContextAccessor, umbracoContextAccessor, documentRepository, mediaRepository, memberRepository, defaultCultureAccessor, logger, globalSettings, siteDomainHelper, entitySerializer, null, mainDom, testing, enableRepositoryEvents) - { } + { + _umbracoContextAccessor = umbracoContextAccessor; + } // used in some tests internal PublishedSnapshotService(ServiceContext serviceContext, @@ -65,6 +69,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache IScopeProvider scopeProvider, IAppCache requestCache, IPublishedSnapshotAccessor publishedSnapshotAccessor, IVariationContextAccessor variationContextAccessor, + IUmbracoContextAccessor umbracoContextAccessor, IDocumentRepository documentRepository, IMediaRepository mediaRepository, IMemberRepository memberRepository, IDefaultCultureAccessor defaultCultureAccessor, ILogger logger, @@ -92,6 +97,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache _defaultCultureAccessor = defaultCultureAccessor; _requestCache = requestCache; + _umbracoContextAccessor = umbracoContextAccessor; _globalSettings = globalSettings; _siteDomainHelper = siteDomainHelper; _entitySerializer = entitySerializer; @@ -138,9 +144,9 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache var domainCache = new DomainCache(_domainService, _defaultCultureAccessor); return new PublishedSnapshot( - new PublishedContentCache(_xmlStore, domainCache, _requestCache, _globalSettings, _siteDomainHelper, _contentTypeCache, _routesCache, previewToken), - new PublishedMediaCache(_xmlStore, _mediaService, _userService, _requestCache, _contentTypeCache, _entitySerializer), - new PublishedMemberCache(_xmlStore, _requestCache, _memberService, _contentTypeCache), + new PublishedContentCache(_xmlStore, domainCache, _requestCache, _globalSettings, _siteDomainHelper,_umbracoContextAccessor, _contentTypeCache, _routesCache, previewToken), + new PublishedMediaCache(_xmlStore, _mediaService, _userService, _requestCache, _contentTypeCache, _entitySerializer, _umbracoContextAccessor), + new PublishedMemberCache(_xmlStore, _requestCache, _memberService, _contentTypeCache, _umbracoContextAccessor), domainCache); } diff --git a/src/Umbraco.Web/PublishedCache/XmlPublishedCache/XmlPublishedContent.cs b/src/Umbraco.Web/PublishedCache/XmlPublishedCache/XmlPublishedContent.cs index 2b3bc39452..00919e6a87 100644 --- a/src/Umbraco.Web/PublishedCache/XmlPublishedCache/XmlPublishedContent.cs +++ b/src/Umbraco.Web/PublishedCache/XmlPublishedCache/XmlPublishedContent.cs @@ -20,21 +20,29 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache [XmlType(Namespace = "http://umbraco.org/webservices/")] internal class XmlPublishedContent : PublishedContentBase { - private XmlPublishedContent(XmlNode xmlNode, bool isPreviewing, IAppCache appCache, PublishedContentTypeCache contentTypeCache) + private XmlPublishedContent( + XmlNode xmlNode, + bool isPreviewing, + IAppCache appCache, + PublishedContentTypeCache contentTypeCache, + IUmbracoContextAccessor umbracoContextAccessor) + :base(umbracoContextAccessor) { _xmlNode = xmlNode; _isPreviewing = isPreviewing; _appCache = appCache; _contentTypeCache = contentTypeCache; + _umbracoContextAccessor = umbracoContextAccessor; } private readonly XmlNode _xmlNode; private readonly bool _isPreviewing; private readonly IAppCache _appCache; // at snapshot/request level (see PublishedContentCache) private readonly PublishedContentTypeCache _contentTypeCache; + private readonly IUmbracoContextAccessor _umbracoContextAccessor; - private readonly object _initializeLock = new object(); + private readonly object _initializeLock = new object(); private bool _nodeInitialized; private bool _parentInitialized; @@ -252,7 +260,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache if (parent == null) return; if (parent.Attributes?.GetNamedItem("isDoc") != null) - _parent = Get(parent, _isPreviewing, _appCache, _contentTypeCache); + _parent = Get(parent, _isPreviewing, _appCache, _contentTypeCache, _umbracoContextAccessor); _parentInitialized = true; } @@ -409,7 +417,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache var iterator = nav.Select(expr); _children = iterator.Cast() - .Select(n => Get(((IHasXmlNode) n).GetNode(), _isPreviewing, _appCache, _contentTypeCache)) + .Select(n => Get(((IHasXmlNode) n).GetNode(), _isPreviewing, _appCache, _contentTypeCache, _umbracoContextAccessor)) .OrderBy(x => x.SortOrder) .ToList(); @@ -423,11 +431,13 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache /// A value indicating whether we are previewing or not. /// A cache. /// A content type cache. + /// A umbraco context accessor /// The IPublishedContent corresponding to the Xml cache node. /// Maintains a per-request cache of IPublishedContent items in order to make /// sure that we create only one instance of each for the duration of a request. The /// returned IPublishedContent is a model, if models are enabled. - public static IPublishedContent Get(XmlNode node, bool isPreviewing, IAppCache appCache, PublishedContentTypeCache contentTypeCache) + public static IPublishedContent Get(XmlNode node, bool isPreviewing, IAppCache appCache, + PublishedContentTypeCache contentTypeCache, IUmbracoContextAccessor umbracoContextAccessor) { // only 1 per request @@ -435,7 +445,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache var id = attrs?.GetNamedItem("id").Value; if (id.IsNullOrWhiteSpace()) throw new InvalidOperationException("Node has no ID attribute."); var key = CacheKeyPrefix + id; // dont bother with preview, wont change during request in Xml cache - return (IPublishedContent) appCache.Get(key, () => (new XmlPublishedContent(node, isPreviewing, appCache, contentTypeCache)).CreateModel()); + return (IPublishedContent) appCache.Get(key, () => (new XmlPublishedContent(node, isPreviewing, appCache, contentTypeCache, umbracoContextAccessor)).CreateModel()); } public static void ClearRequest()