Refactoring
This commit is contained in:
@@ -1,6 +1,9 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using Umbraco.Core.Services;
|
||||
using ValueFallback = Umbraco.Core.Constants.Content.ValueFallback;
|
||||
|
||||
namespace Umbraco.Web.Models.PublishedContent
|
||||
{
|
||||
@@ -9,90 +12,72 @@ namespace Umbraco.Web.Models.PublishedContent
|
||||
/// </summary>
|
||||
public class PublishedValueFallback : IPublishedValueFallback
|
||||
{
|
||||
// kinda reproducing what was available in v7
|
||||
private readonly ILocalizationService _localizationService;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="PublishedValueFallback"/> class.
|
||||
/// </summary>
|
||||
/// <param name="localizationService"></param>
|
||||
public PublishedValueFallback(ILocalizationService localizationService)
|
||||
{
|
||||
_localizationService = localizationService;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public object GetValue(IPublishedProperty property, string culture, string segment, object defaultValue, ICollection<int> visitedLanguages)
|
||||
public object GetValue(IPublishedProperty property, string culture, string segment, object defaultValue)
|
||||
{
|
||||
// no fallback here
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public T GetValue<T>(IPublishedProperty property, string culture, string segment, T defaultValue, ICollection<int> visitedLanguages)
|
||||
public T GetValue<T>(IPublishedProperty property, string culture, string segment, T defaultValue)
|
||||
{
|
||||
// no fallback here
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public object GetValue(IPublishedElement content, string alias, string culture, string segment, object defaultValue, ICollection<int> visitedLanguages)
|
||||
public object GetValue(IPublishedElement content, string alias, string culture, string segment, object defaultValue)
|
||||
{
|
||||
// no fallback here
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public T GetValue<T>(IPublishedElement content, string alias, string culture, string segment, T defaultValue, ICollection<int> visitedLanguages)
|
||||
public T GetValue<T>(IPublishedElement content, string alias, string culture, string segment, T defaultValue)
|
||||
{
|
||||
// no fallback here
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public object GetValue(IPublishedContent content, string alias, string culture, string segment, object defaultValue, IEnumerable<int> fallbackMethods, ICollection<int> visitedLanguages)
|
||||
public object GetValue(IPublishedContent content, string alias, string culture, string segment, object defaultValue, int fallback)
|
||||
{
|
||||
// is that ok?
|
||||
return GetValue<object>(content, alias, culture, segment, defaultValue, fallbackMethods, visitedLanguages);
|
||||
return GetValue<object>(content, alias, culture, segment, defaultValue, fallback);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public T GetValue<T>(IPublishedContent content, string alias, string culture, string segment, T defaultValue, IEnumerable<int> fallbackMethods, ICollection<int> visitedLanguages)
|
||||
public virtual T GetValue<T>(IPublishedContent content, string alias, string culture, string segment, T defaultValue, int fallback)
|
||||
{
|
||||
if (fallbackMethods == null)
|
||||
switch (fallback)
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
foreach (var fallbackMethod in fallbackMethods)
|
||||
{
|
||||
if (TryGetValueWithFallbackMethod(content, alias, culture, segment, defaultValue, fallbackMethods, visitedLanguages, fallbackMethod, out T value))
|
||||
{
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
protected virtual bool TryGetValueWithFallbackMethod<T>(IPublishedContent content, string alias, string culture, string segment, T defaultValue, IEnumerable<int> fallbackMethods, ICollection<int> visitedLanguages, int fallbackMethod, out T value)
|
||||
{
|
||||
value = defaultValue;
|
||||
switch (fallbackMethod)
|
||||
{
|
||||
case Core.Constants.Content.FallbackMethods.None:
|
||||
return false;
|
||||
case Core.Constants.Content.FallbackMethods.RecursiveTree:
|
||||
return TryGetValueWithRecursiveTree(content, alias, culture, segment, defaultValue, out value);
|
||||
case ValueFallback.None:
|
||||
case ValueFallback.Default:
|
||||
return defaultValue;
|
||||
case ValueFallback.Recurse:
|
||||
return TryGetValueWithRecursiveFallback(content, alias, culture, segment, defaultValue, out var value1) ? value1 : defaultValue;
|
||||
case ValueFallback.Language:
|
||||
return TryGetValueWithLanguageFallback(content, alias, culture, segment, defaultValue, out var value2) ? value2 : defaultValue;
|
||||
default:
|
||||
throw new NotSupportedException($"Fallback method with indentifying number {fallbackMethod} is not supported within {GetType().Name}.");
|
||||
throw new NotSupportedException($"Fallback {GetType().Name} does not support policy code '{fallback}'.");
|
||||
}
|
||||
}
|
||||
|
||||
protected static bool TryGetValueWithRecursiveTree<T>(IPublishedContent content, string alias, string culture, string segment, T defaultValue, out T value)
|
||||
// tries to get a value, recursing the tree
|
||||
protected static bool TryGetValueWithRecursiveFallback<T>(IPublishedContent content, string alias, string culture, string segment, T defaultValue, out T value)
|
||||
{
|
||||
// Implement recursion as it was implemented in PublishedContentBase
|
||||
|
||||
// fixme caching?
|
||||
//
|
||||
// all caches were using PublishedContentBase.GetProperty(alias, recurse) to get the property,
|
||||
// then,
|
||||
// NuCache.PublishedContent was storing the property in GetAppropriateCache() with key "NuCache.Property.Recurse[" + DraftOrPub(previewing) + contentUid + ":" + typeAlias + "]";
|
||||
// XmlPublishedContent was storing the property in _cacheProvider with key $"XmlPublishedCache.PublishedContentCache:RecursiveProperty-{Id}-{alias.ToLowerInvariant()}";
|
||||
// DictionaryPublishedContent was storing the property in _cacheProvider with key $"XmlPublishedCache.PublishedMediaCache:RecursiveProperty-{Id}-{alias.ToLowerInvariant()}";
|
||||
//
|
||||
// at the moment, caching has been entirely removed, until we better understand caching + fallback
|
||||
|
||||
IPublishedProperty property = null; // if we are here, content's property has no value
|
||||
IPublishedProperty noValueProperty = null;
|
||||
do
|
||||
@@ -125,5 +110,44 @@ namespace Umbraco.Web.Models.PublishedContent
|
||||
value = defaultValue;
|
||||
return false;
|
||||
}
|
||||
|
||||
// tries to get a value, falling back onto other languages
|
||||
private bool TryGetValueWithLanguageFallback<T>(IPublishedContent content, string alias, string culture, string segment, T defaultValue, out T value)
|
||||
{
|
||||
value = defaultValue;
|
||||
|
||||
if (culture.IsNullOrWhiteSpace()) return false;
|
||||
|
||||
var visited = new HashSet<int>();
|
||||
|
||||
// fixme
|
||||
// _localizationService.GetXxx() is expensive, it deep clones objects
|
||||
// we want _localizationService.GetReadOnlyXxx() returning IReadOnlyLanguage which cannot be saved back = no need to clone
|
||||
|
||||
var language = _localizationService.GetLanguageByIsoCode(culture);
|
||||
if (language == null) return false;
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (language.FallbackLanguageId == null) return false;
|
||||
|
||||
var language2Id = language.FallbackLanguageId.Value;
|
||||
if (visited.Contains(language2Id)) return false;
|
||||
visited.Add(language2Id);
|
||||
|
||||
var language2 = _localizationService.GetLanguageById(language2Id);
|
||||
if (language2 == null) return false;
|
||||
var culture2 = language2.IsoCode;
|
||||
|
||||
if (content.HasValue(alias, culture2, segment))
|
||||
{
|
||||
value = content.Value<T>(alias, culture2, segment);
|
||||
return true;
|
||||
}
|
||||
|
||||
language = language2;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user