2018-07-08 16:11:26 +02:00
|
|
|
|
using Umbraco.Core.Models;
|
2018-07-08 15:17:38 +02:00
|
|
|
|
using Umbraco.Core.Models.PublishedContent;
|
|
|
|
|
|
using Umbraco.Core.Services;
|
|
|
|
|
|
|
|
|
|
|
|
namespace Umbraco.Web.Models.PublishedContent
|
|
|
|
|
|
{
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Provides a default implementation for <see cref="IPublishedValueFallback"/> that allows
|
|
|
|
|
|
/// for use of fall-back languages
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <remarks>
|
|
|
|
|
|
/// Inherits from <see cref="PublishedValueFallback" /> that implments what was available in v7.
|
|
|
|
|
|
/// </remarks>
|
|
|
|
|
|
public class PublishedValueLanguageFallback : PublishedValueFallback
|
|
|
|
|
|
{
|
2018-07-08 16:11:26 +02:00
|
|
|
|
private readonly ILocalizationService _localizationService;
|
|
|
|
|
|
|
2018-07-11 22:15:58 +01:00
|
|
|
|
public PublishedValueLanguageFallback(ServiceContext services)
|
2018-07-08 16:11:26 +02:00
|
|
|
|
{
|
2018-07-11 22:15:58 +01:00
|
|
|
|
_localizationService = services.LocalizationService;
|
2018-07-08 16:11:26 +02:00
|
|
|
|
}
|
2018-07-08 15:17:38 +02:00
|
|
|
|
|
|
|
|
|
|
/// <inheritdoc />
|
|
|
|
|
|
public override object GetValue(IPublishedProperty property, string culture, string segment, object defaultValue)
|
|
|
|
|
|
{
|
|
|
|
|
|
object value;
|
|
|
|
|
|
if (TryGetValueFromFallbackLanguage(property, culture, segment, defaultValue, out value))
|
|
|
|
|
|
{
|
|
|
|
|
|
return value;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return base.GetValue(property, culture, segment, defaultValue);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <inheritdoc />
|
|
|
|
|
|
public override T GetValue<T>(IPublishedProperty property, string culture, string segment, T defaultValue)
|
|
|
|
|
|
{
|
|
|
|
|
|
T value;
|
|
|
|
|
|
if (TryGetValueFromFallbackLanguage(property, culture, segment, defaultValue, out value))
|
|
|
|
|
|
{
|
|
|
|
|
|
return value;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return base.GetValue(property, culture, segment, defaultValue);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <inheritdoc />
|
|
|
|
|
|
public override object GetValue(IPublishedElement content, string alias, string culture, string segment, object defaultValue)
|
|
|
|
|
|
{
|
|
|
|
|
|
object value;
|
|
|
|
|
|
if (TryGetValueFromFallbackLanguage(content, alias, culture, segment, defaultValue, out value))
|
|
|
|
|
|
{
|
|
|
|
|
|
return value;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return base.GetValue(content, alias, culture, segment, defaultValue);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <inheritdoc />
|
|
|
|
|
|
public override T GetValue<T>(IPublishedElement content, string alias, string culture, string segment, T defaultValue)
|
|
|
|
|
|
{
|
|
|
|
|
|
T value;
|
|
|
|
|
|
if (TryGetValueFromFallbackLanguage(content, alias, culture, segment, defaultValue, out value))
|
|
|
|
|
|
{
|
|
|
|
|
|
return value;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return base.GetValue(content, alias, culture, segment, defaultValue);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <inheritdoc />
|
|
|
|
|
|
public override object GetValue(IPublishedContent content, string alias, string culture, string segment, object defaultValue, bool recurse, PublishedValueFallbackPriority fallbackPriority)
|
|
|
|
|
|
{
|
|
|
|
|
|
return GetValue<object>(content, alias, culture, segment, defaultValue, recurse, fallbackPriority);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <inheritdoc />
|
|
|
|
|
|
public override T GetValue<T>(IPublishedContent content, string alias, string culture, string segment, T defaultValue, bool recurse, PublishedValueFallbackPriority fallbackPriority)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (fallbackPriority == PublishedValueFallbackPriority.RecursiveTree)
|
|
|
|
|
|
{
|
|
|
|
|
|
var result = base.GetValue<T>(content, alias, culture, segment, defaultValue, recurse, PublishedValueFallbackPriority.RecursiveTree);
|
|
|
|
|
|
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))
|
|
|
|
|
|
{
|
|
|
|
|
|
return result;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return defaultValue;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (fallbackPriority == PublishedValueFallbackPriority.FallbackLanguage)
|
|
|
|
|
|
{
|
|
|
|
|
|
T result;
|
|
|
|
|
|
if (TryGetValueFromFallbackLanguage(content, alias, culture, segment, defaultValue, recurse, 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);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private bool TryGetValueFromFallbackLanguage<T>(IPublishedProperty property, string culture, string segment, T defaultValue, out T value)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (string.IsNullOrEmpty(culture))
|
|
|
|
|
|
{
|
|
|
|
|
|
value = defaultValue;
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-07-08 16:11:26 +02:00
|
|
|
|
var language = _localizationService.GetLanguageByIsoCode(culture);
|
2018-07-12 20:52:02 +01:00
|
|
|
|
if (language.FallbackLanguageId.HasValue == false)
|
2018-07-08 15:17:38 +02:00
|
|
|
|
{
|
|
|
|
|
|
value = defaultValue;
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-07-12 20:52:02 +01:00
|
|
|
|
var fallbackLanguageId = language.FallbackLanguageId;
|
|
|
|
|
|
while (fallbackLanguageId.HasValue)
|
2018-07-08 15:17:38 +02:00
|
|
|
|
{
|
2018-07-12 20:52:02 +01:00
|
|
|
|
var fallbackLanguage = GetLanguageById(fallbackLanguageId.Value);
|
2018-07-08 15:17:38 +02:00
|
|
|
|
value = property.Value(fallbackLanguage.IsoCode, segment, defaultValue);
|
|
|
|
|
|
if (ValueIsNotNullEmptyOrDefault(value, defaultValue))
|
|
|
|
|
|
{
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-07-12 20:52:02 +01:00
|
|
|
|
fallbackLanguageId = fallbackLanguage.FallbackLanguageId;
|
2018-07-08 15:17:38 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
value = defaultValue;
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private bool TryGetValueFromFallbackLanguage<T>(IPublishedElement content, string alias, string culture, string segment, T defaultValue, out T value)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (string.IsNullOrEmpty(culture))
|
|
|
|
|
|
{
|
|
|
|
|
|
value = defaultValue;
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-07-08 16:11:26 +02:00
|
|
|
|
var language = _localizationService.GetLanguageByIsoCode(culture);
|
2018-07-12 20:52:02 +01:00
|
|
|
|
if (language.FallbackLanguageId.HasValue == false)
|
2018-07-08 15:17:38 +02:00
|
|
|
|
{
|
|
|
|
|
|
value = defaultValue;
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-07-12 20:52:02 +01:00
|
|
|
|
var fallbackLanguageId = language.FallbackLanguageId;
|
|
|
|
|
|
while (fallbackLanguageId.HasValue)
|
2018-07-08 15:17:38 +02:00
|
|
|
|
{
|
2018-07-12 20:52:02 +01:00
|
|
|
|
var fallbackLanguage = GetLanguageById(fallbackLanguageId.Value);
|
2018-07-08 15:17:38 +02:00
|
|
|
|
value = content.Value(alias, fallbackLanguage.IsoCode, segment, defaultValue);
|
|
|
|
|
|
if (ValueIsNotNullEmptyOrDefault(value, defaultValue))
|
|
|
|
|
|
{
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-07-12 20:52:02 +01:00
|
|
|
|
fallbackLanguageId = fallbackLanguage.FallbackLanguageId;
|
2018-07-08 15:17:38 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
value = defaultValue;
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private bool TryGetValueFromFallbackLanguage<T>(IPublishedContent content, string alias, string culture, string segment, T defaultValue, bool recurse, out T value)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (string.IsNullOrEmpty(culture))
|
|
|
|
|
|
{
|
|
|
|
|
|
value = defaultValue;
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-07-08 16:11:26 +02:00
|
|
|
|
var language = _localizationService.GetLanguageByIsoCode(culture);
|
2018-07-12 20:52:02 +01:00
|
|
|
|
if (language.FallbackLanguageId.HasValue == false)
|
2018-07-08 15:17:38 +02:00
|
|
|
|
{
|
|
|
|
|
|
value = defaultValue;
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-07-12 20:52:02 +01:00
|
|
|
|
var fallbackLanguageId = language.FallbackLanguageId;
|
|
|
|
|
|
while (fallbackLanguageId.HasValue)
|
2018-07-08 15:17:38 +02:00
|
|
|
|
{
|
2018-07-12 20:52:02 +01:00
|
|
|
|
var fallbackLanguage = GetLanguageById(fallbackLanguageId.Value);
|
2018-07-08 15:17:38 +02:00
|
|
|
|
value = content.Value(alias, fallbackLanguage.IsoCode, segment, defaultValue, recurse);
|
|
|
|
|
|
if (ValueIsNotNullEmptyOrDefault(value, defaultValue))
|
|
|
|
|
|
{
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-07-12 20:52:02 +01:00
|
|
|
|
fallbackLanguageId = fallbackLanguage.FallbackLanguageId;
|
2018-07-08 15:17:38 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
value = defaultValue;
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-07-12 20:52:02 +01:00
|
|
|
|
private ILanguage GetLanguageById(int id)
|
2018-07-08 15:17:38 +02:00
|
|
|
|
{
|
2018-07-12 20:52:02 +01:00
|
|
|
|
return _localizationService.GetLanguageById(id);
|
|
|
|
|
|
}
|
2018-07-08 16:11:26 +02:00
|
|
|
|
|
2018-07-12 20:52:02 +01:00
|
|
|
|
private static bool ValueIsNotNullEmptyOrDefault<T>(T value, T defaultValue)
|
|
|
|
|
|
{
|
|
|
|
|
|
return value != null &&
|
|
|
|
|
|
string.IsNullOrEmpty(value.ToString()) == false &&
|
|
|
|
|
|
value.Equals(defaultValue) == false;
|
2018-07-08 15:17:38 +02:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|