Removed unnecessary loop in looking up value from a fall-back language.
Put in a check to abort fall-back if there's a loop in language fall-backs.
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
using Umbraco.Core.Models;
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using Umbraco.Core.Services;
|
||||
|
||||
@@ -21,72 +22,72 @@ namespace Umbraco.Web.Models.PublishedContent
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override object GetValue(IPublishedProperty property, string culture, string segment, object defaultValue)
|
||||
public override object GetValue(IPublishedProperty property, string culture, string segment, object defaultValue, ICollection<int> visitedLanguages)
|
||||
{
|
||||
object value;
|
||||
if (TryGetValueFromFallbackLanguage(property, culture, segment, defaultValue, out value))
|
||||
if (TryGetValueFromFallbackLanguage(property, culture, segment, defaultValue, visitedLanguages, out value))
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
return base.GetValue(property, culture, segment, defaultValue);
|
||||
return base.GetValue(property, culture, segment, defaultValue, visitedLanguages);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override T GetValue<T>(IPublishedProperty property, string culture, string segment, T defaultValue)
|
||||
public override T GetValue<T>(IPublishedProperty property, string culture, string segment, T defaultValue, ICollection<int> visitedLanguages)
|
||||
{
|
||||
T value;
|
||||
if (TryGetValueFromFallbackLanguage(property, culture, segment, defaultValue, out value))
|
||||
if (TryGetValueFromFallbackLanguage(property, culture, segment, defaultValue, visitedLanguages, out value))
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
return base.GetValue(property, culture, segment, defaultValue);
|
||||
return base.GetValue(property, culture, segment, defaultValue, visitedLanguages);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override object GetValue(IPublishedElement content, string alias, string culture, string segment, object defaultValue)
|
||||
public override object GetValue(IPublishedElement content, string alias, string culture, string segment, object defaultValue, ICollection<int> visitedLanguages)
|
||||
{
|
||||
object value;
|
||||
if (TryGetValueFromFallbackLanguage(content, alias, culture, segment, defaultValue, out value))
|
||||
if (TryGetValueFromFallbackLanguage(content, alias, culture, segment, defaultValue, visitedLanguages, out value))
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
return base.GetValue(content, alias, culture, segment, defaultValue);
|
||||
return base.GetValue(content, alias, culture, segment, defaultValue, visitedLanguages);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override T GetValue<T>(IPublishedElement content, string alias, string culture, string segment, T defaultValue)
|
||||
public override T GetValue<T>(IPublishedElement content, string alias, string culture, string segment, T defaultValue, ICollection<int> visitedLanguages)
|
||||
{
|
||||
T value;
|
||||
if (TryGetValueFromFallbackLanguage(content, alias, culture, segment, defaultValue, out value))
|
||||
if (TryGetValueFromFallbackLanguage(content, alias, culture, segment, defaultValue, visitedLanguages, out value))
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
return base.GetValue(content, alias, culture, segment, defaultValue);
|
||||
return base.GetValue(content, alias, culture, segment, defaultValue, visitedLanguages);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override object GetValue(IPublishedContent content, string alias, string culture, string segment, object defaultValue, bool recurse, PublishedValueFallbackPriority fallbackPriority)
|
||||
public override object GetValue(IPublishedContent content, string alias, string culture, string segment, object defaultValue, bool recurse, PublishedValueFallbackPriority fallbackPriority, ICollection<int> visitedLanguages)
|
||||
{
|
||||
return GetValue<object>(content, alias, culture, segment, defaultValue, recurse, fallbackPriority);
|
||||
return GetValue<object>(content, alias, culture, segment, defaultValue, recurse, fallbackPriority, visitedLanguages);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override T GetValue<T>(IPublishedContent content, string alias, string culture, string segment, T defaultValue, bool recurse, PublishedValueFallbackPriority fallbackPriority)
|
||||
public override T GetValue<T>(IPublishedContent content, string alias, string culture, string segment, T defaultValue, bool recurse, PublishedValueFallbackPriority fallbackPriority, ICollection<int> visitedLanguages)
|
||||
{
|
||||
if (fallbackPriority == PublishedValueFallbackPriority.RecursiveTree)
|
||||
{
|
||||
var result = base.GetValue<T>(content, alias, culture, segment, defaultValue, recurse, PublishedValueFallbackPriority.RecursiveTree);
|
||||
var result = base.GetValue<T>(content, alias, culture, segment, defaultValue, recurse, PublishedValueFallbackPriority.RecursiveTree, visitedLanguages);
|
||||
if (ValueIsNotNullEmptyOrDefault(result, defaultValue))
|
||||
{
|
||||
// We've prioritised recursive tree search and found a value, so can return it.
|
||||
return result;
|
||||
}
|
||||
|
||||
if (TryGetValueFromFallbackLanguage(content, alias, culture, segment, defaultValue, recurse, out result))
|
||||
if (TryGetValueFromFallbackLanguage(content, alias, culture, segment, defaultValue, recurse, fallbackPriority, visitedLanguages, out result))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
@@ -97,112 +98,116 @@ namespace Umbraco.Web.Models.PublishedContent
|
||||
if (fallbackPriority == PublishedValueFallbackPriority.FallbackLanguage)
|
||||
{
|
||||
T result;
|
||||
if (TryGetValueFromFallbackLanguage(content, alias, culture, segment, defaultValue, recurse, out result))
|
||||
if (TryGetValueFromFallbackLanguage(content, alias, culture, segment, defaultValue, recurse, fallbackPriority, visitedLanguages, out result))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
// No language fall back content found, so use base implementation
|
||||
return base.GetValue<T>(content, alias, culture, segment, defaultValue, recurse, fallbackPriority);
|
||||
return base.GetValue<T>(content, alias, culture, segment, defaultValue, recurse, fallbackPriority, visitedLanguages);
|
||||
}
|
||||
|
||||
private bool TryGetValueFromFallbackLanguage<T>(IPublishedProperty property, string culture, string segment, T defaultValue, out T value)
|
||||
private bool TryGetValueFromFallbackLanguage<T>(IPublishedProperty property, string culture, string segment, T defaultValue, ICollection<int> visitedLanguages, out T value)
|
||||
{
|
||||
value = defaultValue;
|
||||
|
||||
if (string.IsNullOrEmpty(culture))
|
||||
{
|
||||
value = defaultValue;
|
||||
return false;
|
||||
}
|
||||
|
||||
var language = _localizationService.GetLanguageByIsoCode(culture);
|
||||
if (language.FallbackLanguageId.HasValue == false)
|
||||
{
|
||||
value = defaultValue;
|
||||
return false;
|
||||
}
|
||||
|
||||
var fallbackLanguageId = language.FallbackLanguageId;
|
||||
while (fallbackLanguageId.HasValue)
|
||||
if (AlreadyVisitedLanguage(visitedLanguages, language.FallbackLanguageId.Value))
|
||||
{
|
||||
var fallbackLanguage = GetLanguageById(fallbackLanguageId.Value);
|
||||
value = property.Value(fallbackLanguage.IsoCode, segment, defaultValue);
|
||||
if (ValueIsNotNullEmptyOrDefault(value, defaultValue))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
fallbackLanguageId = fallbackLanguage.FallbackLanguageId;
|
||||
return false;
|
||||
}
|
||||
|
||||
visitedLanguages.Add(language.FallbackLanguageId.Value);
|
||||
|
||||
var fallbackLanguage = GetLanguageById(language.FallbackLanguageId.Value);
|
||||
value = property.Value(fallbackLanguage.IsoCode, segment, defaultValue, visitedLanguages);
|
||||
if (ValueIsNotNullEmptyOrDefault(value, defaultValue))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
value = defaultValue;
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool TryGetValueFromFallbackLanguage<T>(IPublishedElement content, string alias, string culture, string segment, T defaultValue, out T value)
|
||||
private bool TryGetValueFromFallbackLanguage<T>(IPublishedElement content, string alias, string culture, string segment, T defaultValue, ICollection<int> visitedLanguages, out T value)
|
||||
{
|
||||
value = defaultValue;
|
||||
|
||||
if (string.IsNullOrEmpty(culture))
|
||||
{
|
||||
value = defaultValue;
|
||||
return false;
|
||||
}
|
||||
|
||||
var language = _localizationService.GetLanguageByIsoCode(culture);
|
||||
if (language.FallbackLanguageId.HasValue == false)
|
||||
{
|
||||
value = defaultValue;
|
||||
return false;
|
||||
}
|
||||
|
||||
var fallbackLanguageId = language.FallbackLanguageId;
|
||||
while (fallbackLanguageId.HasValue)
|
||||
if (AlreadyVisitedLanguage(visitedLanguages, language.FallbackLanguageId.Value))
|
||||
{
|
||||
var fallbackLanguage = GetLanguageById(fallbackLanguageId.Value);
|
||||
value = content.Value(alias, fallbackLanguage.IsoCode, segment, defaultValue);
|
||||
if (ValueIsNotNullEmptyOrDefault(value, defaultValue))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
fallbackLanguageId = fallbackLanguage.FallbackLanguageId;
|
||||
return false;
|
||||
}
|
||||
|
||||
visitedLanguages.Add(language.FallbackLanguageId.Value);
|
||||
|
||||
var fallbackLanguage = GetLanguageById(language.FallbackLanguageId.Value);
|
||||
value = content.Value(alias, fallbackLanguage.IsoCode, segment, defaultValue, visitedLanguages);
|
||||
if (ValueIsNotNullEmptyOrDefault(value, defaultValue))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
value = defaultValue;
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool TryGetValueFromFallbackLanguage<T>(IPublishedContent content, string alias, string culture, string segment, T defaultValue, bool recurse, out T value)
|
||||
private bool TryGetValueFromFallbackLanguage<T>(IPublishedContent content, string alias, string culture, string segment, T defaultValue, bool recurse, PublishedValueFallbackPriority fallbackPriority, ICollection<int> visitedLanguages, out T value)
|
||||
{
|
||||
value = defaultValue;
|
||||
if (string.IsNullOrEmpty(culture))
|
||||
{
|
||||
value = defaultValue;
|
||||
return false;
|
||||
}
|
||||
|
||||
var language = _localizationService.GetLanguageByIsoCode(culture);
|
||||
if (language.FallbackLanguageId.HasValue == false)
|
||||
{
|
||||
value = defaultValue;
|
||||
return false;
|
||||
}
|
||||
|
||||
var fallbackLanguageId = language.FallbackLanguageId;
|
||||
while (fallbackLanguageId.HasValue)
|
||||
if (AlreadyVisitedLanguage(visitedLanguages, language.FallbackLanguageId.Value))
|
||||
{
|
||||
var fallbackLanguage = GetLanguageById(fallbackLanguageId.Value);
|
||||
value = content.Value(alias, fallbackLanguage.IsoCode, segment, defaultValue, recurse);
|
||||
if (ValueIsNotNullEmptyOrDefault(value, defaultValue))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
fallbackLanguageId = fallbackLanguage.FallbackLanguageId;
|
||||
return false;
|
||||
}
|
||||
|
||||
visitedLanguages.Add(language.FallbackLanguageId.Value);
|
||||
|
||||
var fallbackLanguage = GetLanguageById(language.FallbackLanguageId.Value);
|
||||
value = content.Value(alias, fallbackLanguage.IsoCode, segment, defaultValue, recurse, fallbackPriority, visitedLanguages);
|
||||
if (ValueIsNotNullEmptyOrDefault(value, defaultValue))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
value = defaultValue;
|
||||
return false;
|
||||
}
|
||||
|
||||
private static bool AlreadyVisitedLanguage(ICollection<int> visitedLanguages, int fallbackLanguageId)
|
||||
{
|
||||
return visitedLanguages.Contains(fallbackLanguageId);
|
||||
}
|
||||
|
||||
private ILanguage GetLanguageById(int id)
|
||||
{
|
||||
return _localizationService.GetLanguageById(id);
|
||||
|
||||
Reference in New Issue
Block a user