Refactor IPublishedContent.CultureDate(), .Cultures

This commit is contained in:
Stephan
2019-04-17 10:03:49 +02:00
parent 7cf13cbf94
commit e062ea8d31
17 changed files with 84 additions and 76 deletions

View File

@@ -88,7 +88,7 @@ namespace Umbraco.Core.Models.PublishedContent
/// </summary>
/// <remarks>
/// <para>For published content items, this is also the date the item was published.</para>
/// <para>This date is always global to the content item, see GetCulture().Date for the
/// <para>This date is always global to the content item, see CultureDate() for the
/// date each culture was published.</para>
/// </remarks>
DateTime UpdateDate { get; }
@@ -104,19 +104,20 @@ namespace Umbraco.Core.Models.PublishedContent
string Url(string culture = null, UrlMode mode = UrlMode.Auto);
/// <summary>
/// Gets culture infos for a culture.
/// Gets the culture date of the content item.
/// </summary>
PublishedCultureInfo GetCulture(string culture = null);
/// <param name="culture">The specific culture to get the name for. If null is used the current culture is used (Default is null).</param>
DateTime CultureDate(string culture = null);
/// <summary>
/// Gets culture infos.
/// Gets all available cultures.
/// </summary>
/// <remarks>
/// <para>Contains only those culture that are available. For a published content, these are
/// the cultures that are published. For a draft content, those that are 'available' ie
/// have a non-empty content name.</para>
/// </remarks>
IReadOnlyDictionary<string, PublishedCultureInfo> Cultures { get; }
IReadOnlyList<string> Cultures { get; }
/// <summary>
/// Gets a value indicating whether the content is draft.

View File

@@ -97,10 +97,10 @@ namespace Umbraco.Core.Models.PublishedContent
public virtual string Url(string culture = null, UrlMode mode = UrlMode.Auto) => _content.Url(culture, mode);
/// <inheritdoc />
public PublishedCultureInfo GetCulture(string culture = null) => _content.GetCulture(culture);
public DateTime CultureDate(string culture = null) => _content.CultureDate(culture);
/// <inheritdoc />
public IReadOnlyDictionary<string, PublishedCultureInfo> Cultures => _content.Cultures;
public IReadOnlyList<string> Cultures => _content.Cultures;
/// <inheritdoc />
public virtual bool IsDraft(string culture = null) => _content.IsDraft(culture);

View File

@@ -153,10 +153,11 @@ namespace Umbraco.Tests.LegacyXmlPublishedCache
public override string Name(string culture = null) => _name;
public override PublishedCultureInfo GetCulture(string culture = null) => null;
public override DateTime CultureDate(string culture = null) => UpdateDate;
private static readonly Lazy<Dictionary<string, PublishedCultureInfo>> NoCultures = new Lazy<Dictionary<string, PublishedCultureInfo>>(() => new Dictionary<string, PublishedCultureInfo>());
public override IReadOnlyDictionary<string, PublishedCultureInfo> Cultures => NoCultures.Value;
// ReSharper disable once CollectionNeverUpdated.Local
private static readonly List<string> EmptyListOfString = new List<string>();
public override IReadOnlyList<string> Cultures => EmptyListOfString;
public override string UrlSegment(string culture = null) => _urlName;

View File

@@ -142,10 +142,11 @@ namespace Umbraco.Tests.LegacyXmlPublishedCache
return _name;
}
public override PublishedCultureInfo GetCulture(string culture = null) => null;
public override DateTime CultureDate(string culture = null) => UpdateDate;
private static readonly Lazy<Dictionary<string, PublishedCultureInfo>> NoCultures = new Lazy<Dictionary<string, PublishedCultureInfo>>(() => new Dictionary<string, PublishedCultureInfo>());
public override IReadOnlyDictionary<string, PublishedCultureInfo> Cultures => NoCultures.Value;
// ReSharper disable once CollectionNeverUpdated.Local
private static readonly List<string> EmptyListOfString = new List<string>();
public override IReadOnlyList<string> Cultures => EmptyListOfString;
public override string WriterName
{

View File

@@ -284,8 +284,8 @@ namespace Umbraco.Tests.Published
public override int? TemplateId { get; }
public override int SortOrder { get; }
public override string Name(string culture = null) => default;
public override PublishedCultureInfo GetCulture(string culture = ".") => throw new NotSupportedException();
public override IReadOnlyDictionary<string, PublishedCultureInfo> Cultures => throw new NotSupportedException();
public override DateTime CultureDate(string culture = null) => throw new NotSupportedException();
public override IReadOnlyList<string> Cultures => throw new NotSupportedException();
public override string UrlSegment(string culture = null) => default;
public override string WriterName { get; }
public override string CreatorName { get; }

View File

@@ -223,13 +223,13 @@ namespace Umbraco.Tests.PublishedContent
_variationAccesor.VariationContext = new VariationContext("fr-FR");
Assert.AreEqual("val-fr1", publishedContent.Value<string>("prop"));
Assert.AreEqual("name-fr1", publishedContent.Name());
Assert.AreEqual(new DateTime(2018, 01, 01, 01, 00, 00), publishedContent.GetCulture().Date);
Assert.AreEqual(new DateTime(2018, 01, 01, 01, 00, 00), publishedContent.CultureDate());
// now uk is default
_variationAccesor.VariationContext = new VariationContext("en-UK");
Assert.AreEqual("val-uk1", publishedContent.Value<string>("prop"));
Assert.AreEqual("name-uk1", publishedContent.Name());
Assert.AreEqual(new DateTime(2018, 01, 02, 01, 00, 00), publishedContent.GetCulture().Date);
Assert.AreEqual(new DateTime(2018, 01, 02, 01, 00, 00), publishedContent.CultureDate());
// invariant needs to be retrieved explicitly, when it's not default
Assert.AreEqual("val1", publishedContent.Value<string>("prop", culture: ""));

View File

@@ -205,8 +205,8 @@ namespace Umbraco.Tests.PublishedContent
public int SortOrder { get; set; }
public string Name(string culture = null) => _names.TryGetValue(culture ?? "", out var name) ? name : null;
public void SetName(string name, string culture = null) => _names[culture ?? ""] = name;
public PublishedCultureInfo GetCulture(string culture = null) => throw new NotSupportedException();
public IReadOnlyDictionary<string, PublishedCultureInfo> Cultures => throw new NotSupportedException();
public DateTime CultureDate(string culture = null) => throw new NotSupportedException();
public IReadOnlyList<string> Cultures => throw new NotSupportedException();
public string UrlSegment(string culture = null) => _urlSegments.TryGetValue(culture ?? "", out var urlSegment) ? urlSegment : null;
public void SetUrlSegment(string urlSegment, string culture = null) => _urlSegments[culture ?? ""] = urlSegment;
public string WriterName { get; set; }

View File

@@ -183,8 +183,8 @@ namespace Umbraco.Tests.PublishedContent
public int SortOrder { get; set; }
public string Name(string culture = null) => _names.TryGetValue(culture ?? "", out var name) ? name : null;
public void SetName(string name, string culture = null) => _names[culture ?? ""] = name;
public PublishedCultureInfo GetCulture(string culture = null) => throw new NotSupportedException();
public IReadOnlyDictionary<string, PublishedCultureInfo> Cultures => throw new NotSupportedException();
public DateTime CultureDate(string culture = null) => throw new NotSupportedException();
public IReadOnlyList<string> Cultures => throw new NotSupportedException();
public string UrlSegment(string culture = null) => _urlSegments.TryGetValue(culture ?? "", out var urlSegment) ? urlSegment : null;
public void SetUrlSegment(string urlSegment, string culture = null) => _urlSegments[culture ?? ""] = urlSegment;
public string WriterName { get; set; }

View File

@@ -9,12 +9,13 @@ namespace Umbraco.Tests.TestHelpers.Stubs
{
private readonly Dictionary<string, string> _names = new Dictionary<string, string>();
private readonly Dictionary<string, string> _urlSegments = new Dictionary<string, string>();
private readonly Dictionary<string, DateTime> _cultures;
public TestPublishedContent(IPublishedContentType contentType, int id, Guid key, Dictionary<string, object> values, bool previewing, Dictionary<string, PublishedCultureInfo> cultures = null)
public TestPublishedContent(IPublishedContentType contentType, int id, Guid key, Dictionary<string, object> values, bool previewing, Dictionary<string, DateTime> cultures = null)
: base(contentType, key, values, previewing)
{
Id = id;
Cultures = cultures;
_cultures = cultures ?? new Dictionary<string, DateTime>();
}
public int Id { get; }
@@ -23,19 +24,19 @@ namespace Umbraco.Tests.TestHelpers.Stubs
public string Name(string culture = null) => _names.TryGetValue(culture ?? "", out var name) ? name : null;
public void SetName(string name, string culture = null) => _names[culture ?? ""] = name;
public IVariationContextAccessor VariationContextAccessor { get; set; }
public PublishedCultureInfo GetCulture(string culture = null)
public DateTime CultureDate(string culture = null)
{
// handle context culture
if (culture == null)
culture = VariationContextAccessor?.VariationContext?.Culture;
// no invariant culture infos
if (culture == "" || Cultures == null) return null;
if (culture == "" || Cultures == null) return UpdateDate;
// get
return Cultures.TryGetValue(culture, out var cultureInfos) ? cultureInfos : null;
return _cultures.TryGetValue(culture, out var date) ? date : DateTime.MinValue;
}
public IReadOnlyDictionary<string, PublishedCultureInfo> Cultures { get; set; }
public IReadOnlyList<string> Cultures { get; set; }
public string UrlSegment(string culture = null) => _urlSegments.TryGetValue(culture ?? "", out var urlSegment) ? urlSegment : null;
public void SetUrlSegment(string urlSegment, string culture = null) => _urlSegments[culture ?? ""] = urlSegment;
public string DocumentTypeAlias => ContentType.Alias;

View File

@@ -123,12 +123,22 @@ namespace Umbraco.Web.Editors
// Since a Macro might contain thing thats related to the culture of the "IPublishedContent" (ie Dictionary keys) we want
// to set the current culture to the culture related to the content item. This is hacky but it works.
var culture = publishedContent.GetCulture();
_variationContextAccessor.VariationContext = new VariationContext(); //must have an active variation context!
// fixme I don't even know how this ever worked?!
// assume this was some sort of "the culture of the item"
// but... with multilingual it does not make any sense?!
//var culture = publishedContent.GetCulture();
string culture = ""; // needs to be eg fr-FR
if (culture != null)
{
Thread.CurrentThread.CurrentCulture = Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo(culture.Culture);
_variationContextAccessor.VariationContext = new VariationContext(Thread.CurrentThread.CurrentCulture.Name);
Thread.CurrentThread.CurrentCulture = Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo(culture);
_variationContextAccessor.VariationContext = new VariationContext(culture);
}
else
{
_variationContextAccessor.VariationContext = new VariationContext(); //must have an active variation context!
}
var result = Request.CreateResponse();

View File

@@ -230,32 +230,31 @@ namespace Umbraco.Web.Macros
public string Name(string culture = null) => _inner.GetCultureName(culture);
public PublishedCultureInfo GetCulture(string culture = null)
public DateTime CultureDate(string culture = null)
{
// handle context culture
// invariant has invariant value (whatever the requested culture)
if (!ContentType.VariesByCulture())
return UpdateDate;
// handle context culture for variant
if (culture == null)
culture = _variationContextAccessor.VariationContext.Culture;
// no invariant culture infos
if (culture == "") return null;
// get
return Cultures.TryGetValue(culture, out var cultureInfos) ? cultureInfos : null;
return culture != "" && _inner.PublishCultureInfos.TryGetValue(culture, out var infos) ? infos.Date : DateTime.MinValue;
}
public IReadOnlyDictionary<string, PublishedCultureInfo> Cultures
// ReSharper disable once CollectionNeverUpdated.Local
private static readonly List<string> EmptyListOfString = new List<string>();
private IReadOnlyList<string> _cultures;
public IReadOnlyList<string> Cultures
{
get
{
if (!_inner.ContentType.VariesByCulture())
return NoCultureInfos;
if (_cultureInfos != null)
return _cultureInfos;
var urlSegmentProviders = Current.UrlSegmentProviders; // TODO inject
return _cultureInfos = _inner.PublishCultureInfos.Values
.ToDictionary(x => x.Culture, x => new PublishedCultureInfo(x.Culture, x.Name, _inner.GetUrlSegment(urlSegmentProviders, x.Culture), x.Date));
return EmptyListOfString;
return _cultures ?? (_cultures = _inner.PublishCultureInfos.Values.Select(x => x.Culture).ToList());
}
}

View File

@@ -135,10 +135,10 @@ namespace Umbraco.Web.Models
}
/// <inheritdoc />
public abstract PublishedCultureInfo GetCulture(string culture = null);
public abstract DateTime CultureDate(string culture = null);
/// <inheritdoc />
public abstract IReadOnlyDictionary<string, PublishedCultureInfo> Cultures { get; }
public abstract IReadOnlyList<string> Cultures { get; }
/// <inheritdoc />
public abstract bool IsDraft(string culture = null);

View File

@@ -196,7 +196,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
culture = VariationContextAccessor?.VariationContext?.Culture ?? "";
// get
return culture != "" && Cultures.TryGetValue(culture, out var infos) ? infos.Name : null;
return culture != "" && ContentData.CultureInfos.TryGetValue(culture, out var infos) ? infos.Name : null;
}
/// <inheritdoc />
@@ -206,12 +206,12 @@ namespace Umbraco.Web.PublishedCache.NuCache
if (!ContentType.VariesByCulture())
return _urlSegment;
// handle context culture fpr variant
// handle context culture for variant
if (culture == null)
culture = VariationContextAccessor?.VariationContext?.Culture ?? "";
// get
return culture != "" && Cultures.TryGetValue(culture, out var infos) ? infos.UrlSegment : null;
return ContentData.CultureInfos.TryGetValue(culture, out var infos) ? infos.UrlSegment : null;
}
/// <inheritdoc />
@@ -244,39 +244,34 @@ namespace Umbraco.Web.PublishedCache.NuCache
/// <inheritdoc />
public override DateTime UpdateDate => ContentData.VersionDate;
private IReadOnlyDictionary<string, PublishedCultureInfo> _cultureInfos;
private static readonly IReadOnlyDictionary<string, PublishedCultureInfo> NoCultureInfos = new Dictionary<string, PublishedCultureInfo>();
/// <inheritdoc />
public override PublishedCultureInfo GetCulture(string culture = null)
public override DateTime CultureDate(string culture = null)
{
// handle context culture
// invariant has invariant value (whatever the requested culture)
if (!ContentType.VariesByCulture())
return UpdateDate;
// handle context culture for variant
if (culture == null)
culture = VariationContextAccessor?.VariationContext?.Culture ?? "";
// no invariant culture infos
if (culture == "") return null;
// get
return Cultures.TryGetValue(culture, out var cultureInfos) ? cultureInfos : null;
return culture != "" && ContentData.CultureInfos.TryGetValue(culture, out var infos) ? infos.Date : DateTime.MinValue;
}
// ReSharper disable once CollectionNeverUpdated.Local
private static readonly List<string> EmptyListOfString = new List<string>();
private IReadOnlyList<string> _cultures;
/// <inheritdoc />
public override IReadOnlyDictionary<string, PublishedCultureInfo> Cultures
public override IReadOnlyList<string> Cultures
{
get
{
if (!ContentType.VariesByCulture())
return NoCultureInfos;
return EmptyListOfString;
if (_cultureInfos != null) return _cultureInfos;
if (ContentData.CultureInfos == null)
throw new Exception("oops: _contentDate.CultureInfos is null.");
return _cultureInfos = ContentData.CultureInfos
.ToDictionary(x => x.Key, x => new PublishedCultureInfo(x.Key, x.Value.Name, x.Value.UrlSegment, x.Value.Date), StringComparer.OrdinalIgnoreCase);
return _cultures ?? (_cultures = ContentData.CultureInfos.Keys.ToList());
}
}

View File

@@ -140,9 +140,9 @@ namespace Umbraco.Web.PublishedCache
return _member.Name;
}
public override PublishedCultureInfo GetCulture(string culture = null) => throw new NotSupportedException();
public override DateTime CultureDate(string culture = null) => throw new NotSupportedException();
public override IReadOnlyDictionary<string, PublishedCultureInfo> Cultures => throw new NotSupportedException();
public override IReadOnlyList<string> Cultures => throw new NotSupportedException();
public override string UrlSegment(string culture = null) => throw new NotSupportedException();

View File

@@ -168,7 +168,7 @@ namespace Umbraco.Web
/// </summary>
/// <remarks>Culture is case-insensitive.</remarks>
public static bool HasCulture(this IPublishedContent content, string culture)
=> content.Cultures.ContainsKey(culture ?? string.Empty);
=> content.Cultures.Contains(culture ?? string.Empty);
/// <summary>
/// Filters a sequence of <see cref="IPublishedContent"/> to return invariant items, and items that are published for the specified culture.

View File

@@ -276,7 +276,7 @@ namespace Umbraco.Web.Routing
return true;
// variant, ensure that the culture corresponding to the domain's language is published
return domainDocument.Cultures.ContainsKey(domain.Culture.Name);
return domainDocument.Cultures.Contains(domain.Culture.Name);
}
domains = domains.Where(IsPublishedContentDomain).ToList();

View File

@@ -171,12 +171,12 @@ namespace Umbraco.Web.Routing
if (entityContent == null) continue;
// get the default affected cultures by going up the tree until we find the first culture variant entity (default to no cultures)
var defaultCultures = entityContent.AncestorsOrSelf()?.FirstOrDefault(a => a.Cultures.Any())?.Cultures.Select(c => c.Key).ToArray()
var defaultCultures = entityContent.AncestorsOrSelf()?.FirstOrDefault(a => a.Cultures.Any())?.Cultures.ToArray()
?? new[] {(string) null};
foreach (var x in entityContent.DescendantsOrSelf())
{
// if this entity defines specific cultures, use those instead of the default ones
var cultures = x.Cultures.Any() ? x.Cultures.Select(c => c.Key) : defaultCultures;
var cultures = x.Cultures.Any() ? x.Cultures : defaultCultures;
foreach (var culture in cultures)
{