From 96acc1bd7e8c937c1fac1e86f7e9d4a2287e86e1 Mon Sep 17 00:00:00 2001 From: Stephan Date: Wed, 3 Oct 2018 16:19:41 +0200 Subject: [PATCH] Contextualize variations in fallback, too --- .../IPublishedValueFallback.cs | 19 +++------------ .../VariationContextAccessorExtensions.cs | 15 ++++++++++++ src/Umbraco.Core/Umbraco.Core.csproj | 1 + .../PublishedValueFallback.cs | 23 +++++++++++++++++-- .../PublishedCache/NuCache/Property.cs | 18 ++++----------- 5 files changed, 44 insertions(+), 32 deletions(-) create mode 100644 src/Umbraco.Core/Models/PublishedContent/VariationContextAccessorExtensions.cs diff --git a/src/Umbraco.Core/Models/PublishedContent/IPublishedValueFallback.cs b/src/Umbraco.Core/Models/PublishedContent/IPublishedValueFallback.cs index b03b0515cf..f30a53c8b6 100644 --- a/src/Umbraco.Core/Models/PublishedContent/IPublishedValueFallback.cs +++ b/src/Umbraco.Core/Models/PublishedContent/IPublishedValueFallback.cs @@ -5,22 +5,6 @@ /// public interface IPublishedValueFallback { - // fixme discussions & challenges - // - // - the fallback: parameter value must be open, so about anything can be passed to the IPublishedValueFallback - // we have it now, it's an integer + constants, cool - // - // - we need to be able to configure (via code for now) a default fallback policy? - // not! the default value of the fallback: parameter is 'default', not 'none', and if people - // want to implement a different default behavior, they have to override the fallback provider - // - // - (and...) - // ModelsBuilder model.Value(x => x.Price, ...) extensions need to be adjusted too - // - // - cache & perfs - // soon as ppl implement custom fallbacks, caching is a problem, so better just not cache - // OTOH we need to implement the readonly thing for languages - /// /// Tries to get a fallback value for a property. /// @@ -37,6 +21,9 @@ /// It can only fallback at property level (no recurse). /// At property level, property.GetValue() does *not* implement fallback, and one has to /// get property.Value() or property.Value{T}() to trigger fallback. + /// Note that and may not be contextualized, + /// so the variant context should be used to contextualize them (see our default implementation in + /// the web project. /// bool TryGetValue(IPublishedProperty property, string culture, string segment, Fallback fallback, object defaultValue, out object value); diff --git a/src/Umbraco.Core/Models/PublishedContent/VariationContextAccessorExtensions.cs b/src/Umbraco.Core/Models/PublishedContent/VariationContextAccessorExtensions.cs new file mode 100644 index 0000000000..6710d79cc6 --- /dev/null +++ b/src/Umbraco.Core/Models/PublishedContent/VariationContextAccessorExtensions.cs @@ -0,0 +1,15 @@ +namespace Umbraco.Core.Models.PublishedContent +{ + public static class VariationContextAccessorExtensions + { + public static void ContextualizeVariation(this IVariationContextAccessor variationContextAccessor, ContentVariation variations, ref string culture, ref string segment) + { + if (culture != null && segment != null) return; + + // use context values + var publishedVariationContext = variationContextAccessor?.VariationContext; + if (culture == null) culture = variations.VariesByCulture() ? publishedVariationContext?.Culture : ""; + if (segment == null) segment = variations.VariesBySegment() ? publishedVariationContext?.Segment : ""; + } + } +} diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index 5e53b04663..6148162c18 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -399,6 +399,7 @@ + diff --git a/src/Umbraco.Web/Models/PublishedContent/PublishedValueFallback.cs b/src/Umbraco.Web/Models/PublishedContent/PublishedValueFallback.cs index 4e9cdaa8f9..d0218b6639 100644 --- a/src/Umbraco.Web/Models/PublishedContent/PublishedValueFallback.cs +++ b/src/Umbraco.Web/Models/PublishedContent/PublishedValueFallback.cs @@ -12,14 +12,15 @@ namespace Umbraco.Web.Models.PublishedContent public class PublishedValueFallback : IPublishedValueFallback { private readonly ILocalizationService _localizationService; + private readonly IVariationContextAccessor _variationContextAccessor; /// /// Initializes a new instance of the class. /// - /// - public PublishedValueFallback(ServiceContext serviceContext) + public PublishedValueFallback(ServiceContext serviceContext, IVariationContextAccessor variationContextAccessor) { _localizationService = serviceContext.LocalizationService; + _variationContextAccessor = variationContextAccessor; } /// @@ -31,6 +32,8 @@ namespace Umbraco.Web.Models.PublishedContent /// public bool TryGetValue(IPublishedProperty property, string culture, string segment, Fallback fallback, T defaultValue, out T value) { + _variationContextAccessor.ContextualizeVariation(property.PropertyType.Variations, ref culture, ref segment); + foreach (var f in fallback) { switch (f) @@ -62,6 +65,14 @@ namespace Umbraco.Web.Models.PublishedContent /// public bool TryGetValue(IPublishedElement content, string alias, string culture, string segment, Fallback fallback, T defaultValue, out T value) { + var propertyType = content.ContentType.GetPropertyType(alias); + if (propertyType == null) + { + value = default; + return false; + } + _variationContextAccessor.ContextualizeVariation(propertyType.Variations, ref culture, ref segment); + foreach (var f in fallback) { switch (f) @@ -94,6 +105,14 @@ namespace Umbraco.Web.Models.PublishedContent /// public virtual bool TryGetValue(IPublishedContent content, string alias, string culture, string segment, Fallback fallback, T defaultValue, out T value) { + var propertyType = content.ContentType.GetPropertyType(alias); + if (propertyType == null) + { + value = default; + return false; + } + _variationContextAccessor.ContextualizeVariation(propertyType.Variations, ref culture, ref segment); + // note: we don't support "recurse & language" which would walk up the tree, // looking at languages at each level - should someone need it... they'll have // to implement it. diff --git a/src/Umbraco.Web/PublishedCache/NuCache/Property.cs b/src/Umbraco.Web/PublishedCache/NuCache/Property.cs index 8dd3bb8dc7..132c4b6d59 100644 --- a/src/Umbraco.Web/PublishedCache/NuCache/Property.cs +++ b/src/Umbraco.Web/PublishedCache/NuCache/Property.cs @@ -90,7 +90,7 @@ namespace Umbraco.Web.PublishedCache.NuCache // determines whether a property has value public override bool HasValue(string culture = null, string segment = null) { - ContextualizeVariation(ref culture, ref segment); + _content.VariationContextAccessor.ContextualizeVariation(_variations, ref culture, ref segment); var value = GetSourceValue(culture, segment); var hasValue = PropertyType.IsValue(value, PropertyValueLevel.Source); @@ -194,7 +194,7 @@ namespace Umbraco.Web.PublishedCache.NuCache public override object GetSourceValue(string culture = null, string segment = null) { - ContextualizeVariation(ref culture, ref segment); + _content.VariationContextAccessor.ContextualizeVariation(_variations, ref culture, ref segment); if (culture == "" && segment == "") return _sourceValue; @@ -206,19 +206,9 @@ namespace Umbraco.Web.PublishedCache.NuCache } } - private void ContextualizeVariation(ref string culture, ref string segment) - { - if (culture != null && segment != null) return; - - // use context values - var publishedVariationContext = _content.VariationContextAccessor?.VariationContext; - if (culture == null) culture = _variations.VariesByCulture() ? publishedVariationContext?.Culture : ""; - if (segment == null) segment = _variations.VariesBySegment() ? publishedVariationContext?.Segment : ""; - } - public override object GetValue(string culture = null, string segment = null) { - ContextualizeVariation(ref culture, ref segment); + _content.VariationContextAccessor.ContextualizeVariation(_variations, ref culture, ref segment); object value; lock (_locko) @@ -239,7 +229,7 @@ namespace Umbraco.Web.PublishedCache.NuCache public override object GetXPathValue(string culture = null, string segment = null) { - ContextualizeVariation(ref culture, ref segment); + _content.VariationContextAccessor.ContextualizeVariation(_variations, ref culture, ref segment); lock (_locko) {