Refactor content culture & variations

This commit is contained in:
Stephan
2018-04-28 21:57:07 +02:00
parent 6959e595f5
commit 7dd1efb29f
17 changed files with 156 additions and 99 deletions

View File

@@ -225,7 +225,6 @@ namespace Umbraco.Core.Models
/// <inheritdoc/>
[IgnoreDataMember]
//public IReadOnlyDictionary<string, string> PublishNames => _publishNames ?? NoNames;
public IReadOnlyDictionary<string, string> PublishNames => _publishInfos?.ToDictionary(x => x.Key, x => x.Value.Name) ?? NoNames;
/// <inheritdoc/>
@@ -263,7 +262,7 @@ namespace Umbraco.Core.Models
=> !string.IsNullOrWhiteSpace(GetPublishName(culture));
/// <inheritdoc />
public DateTime GetDateCulturePublished(string culture)
public DateTime GetCulturePublishDate(string culture)
{
if (_publishInfos != null && _publishInfos.TryGetValue(culture, out var infos))
return infos.Date;

View File

@@ -6,6 +6,7 @@ using System.Linq;
using System.Reflection;
using System.Runtime.Serialization;
using System.Web;
using Umbraco.Core.Exceptions;
using Umbraco.Core.Models.Entities;
namespace Umbraco.Core.Models
@@ -25,7 +26,7 @@ namespace Umbraco.Core.Models
protected IContentTypeComposition ContentTypeBase;
private int _writerId;
private PropertyCollection _properties;
private Dictionary<string, string> _names;
private Dictionary<string, (string Name, DateTime Date)> _cultureInfos;
/// <summary>
/// Initializes a new instance of the <see cref="ContentBase"/> class.
@@ -139,16 +140,30 @@ namespace Umbraco.Core.Models
/// <inheritdoc />
[DataMember]
public virtual IReadOnlyDictionary<string, string> Names
{
get => _names ?? NoNames;
set
{
foreach (var (culture, name) in value)
SetName(culture, name);
}
}
public virtual IReadOnlyDictionary<string, string> Names => _cultureInfos?.ToDictionary(x => x.Key, x => x.Value.Name) ?? NoNames;
// sets culture infos
// internal for repositories
// clear by clearing name
internal void SetCultureInfos(string culture, string name, DateTime date)
{
if (string.IsNullOrWhiteSpace(name))
throw new ArgumentNullOrEmptyException(nameof(name));
if (culture == null)
{
Name = name;
return;
}
// private method, assume that culture is valid
if (_cultureInfos == null)
_cultureInfos = new Dictionary<string, (string Name, DateTime Date)>(StringComparer.OrdinalIgnoreCase);
_cultureInfos[culture] = (name, date);
}
/// <inheritdoc />
public virtual void SetName(string culture, string name)
{
@@ -166,11 +181,11 @@ namespace Umbraco.Core.Models
if (!ContentTypeBase.Variations.HasAny(ContentVariation.CultureNeutral | ContentVariation.CultureSegment))
throw new NotSupportedException("Content type does not support varying name by culture.");
if (_cultureInfos == null)
_cultureInfos = new Dictionary<string, (string Name, DateTime Date)>(StringComparer.OrdinalIgnoreCase);
if (_names == null)
_names = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
_names[culture] = name;
_cultureInfos[culture] = (name, DateTime.Now) ;
OnPropertyChanged(Ps.Value.NamesSelector);
}
@@ -178,8 +193,8 @@ namespace Umbraco.Core.Models
public virtual string GetName(string culture)
{
if (culture == null) return Name;
if (_names == null) return null;
return _names.TryGetValue(culture, out var name) ? name : null;
if (_cultureInfos == null) return null;
return _cultureInfos.TryGetValue(culture, out var infos) ? infos.Name : null;
}
/// <inheritdoc />
@@ -194,17 +209,25 @@ namespace Umbraco.Core.Models
return;
}
if (_names == null) return;
_names.Remove(culture);
if (_names.Count == 0)
_names = null;
if (_cultureInfos == null) return;
_cultureInfos.Remove(culture);
if (_cultureInfos.Count == 0)
_cultureInfos = null;
}
protected virtual void ClearNames()
{
_names = null;
_cultureInfos = null;
OnPropertyChanged(Ps.Value.NamesSelector);
}
/// <inheritdoc />
public DateTime GetCultureDate(string culture)
{
if (_cultureInfos != null && _cultureInfos.TryGetValue(culture, out var infos))
return infos.Date;
throw new InvalidOperationException($"Culture \"{culture}\" is not available.");
}
#endregion

View File

@@ -93,7 +93,7 @@ namespace Umbraco.Core.Models
/// <summary>
/// Gets the date a culture was published.
/// </summary>
DateTime GetDateCulturePublished(string culture);
DateTime GetCulturePublishDate(string culture);
/// <summary>
/// Gets a value indicated whether a given culture is edited.

View File

@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using Umbraco.Core.Models.Entities;
namespace Umbraco.Core.Models
@@ -46,13 +47,13 @@ namespace Umbraco.Core.Models
string GetName(string culture);
/// <summary>
/// Gets or sets the names of the content item.
/// Gets the names of the content item.
/// </summary>
/// <remarks>
/// <para>Because a dictionary key cannot be <c>null</c> this cannot get nor set the invariant
/// <para>Because a dictionary key cannot be <c>null</c> this cannot get the invariant
/// name, which must be get or set via the <see cref="TreeEntityBase.Name"/> property.</para>
/// </remarks>
IReadOnlyDictionary<string, string> Names { get; set; }
IReadOnlyDictionary<string, string> Names { get; }
/// <summary>
/// Gets a value indicating whether a given culture is available.
@@ -63,6 +64,11 @@ namespace Umbraco.Core.Models
/// </remarks>
bool IsCultureAvailable(string culture);
/// <summary>
/// Gets the date a culture was created.
/// </summary>
DateTime GetCultureDate(string culture);
/// <summary>
/// List of properties, which make up all the data available for this Content object
/// </summary>

View File

@@ -3,21 +3,6 @@ using Umbraco.Core.Exceptions;
namespace Umbraco.Core.Models.PublishedContent
{
/// <summary>
/// Contains the culture specific data for a <see cref="IPublishedContent"/> item
/// </summary>
public struct PublishedCultureName
{
public PublishedCultureName(string name, string urlName) : this()
{
Name = name ?? throw new ArgumentNullException(nameof(name));
UrlName = urlName ?? throw new ArgumentNullException(nameof(urlName));
}
public string Name { get; }
public string UrlName { get; }
}
/// <summary>
/// Contains culture specific values for <see cref="IPublishedContent"/>.
/// </summary>

View File

@@ -945,7 +945,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
{
if (contentVariations.TryGetValue(content.VersionId, out var contentVariation))
foreach (var v in contentVariation)
content.SetName(v.Culture, v.Name);
content.SetCultureInfos(v.Culture, v.Name, v.Date);
if (content.PublishedVersionId > 0 && contentVariations.TryGetValue(content.PublishedVersionId, out contentVariation))
foreach (var v in contentVariation)
content.SetPublishInfos(v.Culture, v.Name, v.Date);
@@ -1028,7 +1028,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
LanguageId = LanguageRepository.GetIdByIsoCode(culture) ?? throw new InvalidOperationException("Not a valid culture."),
Culture = culture,
Name = name,
Date = content.UpdateDate
Date = content.GetCultureDate(culture)
};
// if not publishing, we're just updating the 'current' (non-published) version,
@@ -1043,7 +1043,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
LanguageId = LanguageRepository.GetIdByIsoCode(culture) ?? throw new InvalidOperationException("Not a valid culture."),
Culture = culture,
Name = name,
Date = content.GetDateCulturePublished(culture)
Date = content.GetCulturePublishDate(culture)
};
}

View File

@@ -368,7 +368,7 @@
<Compile Include="Models\PathValidationExtensions.cs" />
<Compile Include="Models\Entities\TreeEntityBase.cs" />
<Compile Include="Models\PropertyTagsExtensions.cs" />
<Compile Include="Models\PublishedContent\PublishedCultureName.cs" />
<Compile Include="Models\PublishedContent\PublishedCultureInfos.cs" />
<Compile Include="Models\PublishedContent\IPublishedVariationContextAccessor.cs" />
<Compile Include="Models\PublishedContent\IPublishedValueFallback.cs" />
<Compile Include="Models\PublishedContent\PublishedVariationContext.cs" />

View File

@@ -336,19 +336,19 @@ namespace Umbraco.Tests.Models
Assert.IsTrue(content.IsCultureAvailable(langFr));
Assert.IsTrue(content.IsCulturePublished(langFr));
Assert.AreEqual("name-fr", content.GetPublishName(langFr));
Assert.AreNotEqual(DateTime.MinValue, content.GetDateCulturePublished(langFr));
Assert.AreNotEqual(DateTime.MinValue, content.GetCulturePublishDate(langFr));
Assert.IsFalse(content.IsCultureEdited(langFr)); // once published, edited is *wrong* until saved
Assert.IsTrue(content.IsCultureAvailable(langUk));
Assert.IsFalse(content.IsCulturePublished(langUk));
Assert.IsNull(content.GetPublishName(langUk));
Assert.Throws<InvalidOperationException>(() => content.GetDateCulturePublished(langUk)); // not published!
Assert.Throws<InvalidOperationException>(() => content.GetCulturePublishDate(langUk)); // not published!
Assert.IsTrue(content.IsCultureEdited(langEs)); // not published, so... edited
Assert.IsFalse(content.IsCultureAvailable(langEs));
Assert.IsFalse(content.IsCulturePublished(langEs));
Assert.IsNull(content.GetPublishName(langEs));
Assert.Throws<InvalidOperationException>(() => content.GetDateCulturePublished(langEs)); // not published!
Assert.Throws<InvalidOperationException>(() => content.GetCulturePublishDate(langEs)); // not published!
Assert.IsTrue(content.IsCultureEdited(langEs)); // not published, so... edited
// cannot test IsCultureEdited here - as that requires the content service and repository

View File

@@ -14,11 +14,11 @@ using Umbraco.Core.Persistence.Repositories;
using Umbraco.Core.PropertyEditors;
using Umbraco.Core.Scoping;
using Umbraco.Core.Services;
using Umbraco.Core.Services.Changes;
using Umbraco.Tests.TestHelpers;
using Umbraco.Tests.TestHelpers.Stubs;
using Umbraco.Tests.Testing.Objects.Accessors;
using Umbraco.Web;
using Umbraco.Web.PublishedCache;
using Umbraco.Web.Cache;
using Umbraco.Web.PublishedCache.NuCache;
using Umbraco.Web.PublishedCache.NuCache.DataSource;
using Umbraco.Web.Routing;
@@ -34,7 +34,6 @@ namespace Umbraco.Tests.PublishedContent
SettingsForTests.ConfigureSettings(SettingsForTests.GenerateMockUmbracoSettings());
var globalSettings = UmbracoConfig.For.GlobalSettings();
// fixme - missing variant names here, and what else?
var kit = new ContentNodeKit
{
ContentTypeId = 2,
@@ -45,14 +44,26 @@ namespace Umbraco.Tests.PublishedContent
new PropertyData { Value = "val2" },
new PropertyData { Culture = "fr-FR", Value = "val-fr2" },
new PropertyData { Culture = "en-UK", Value = "val-uk2" }
} } } },
} } },
CultureInfos = new Dictionary<string, CultureVariation>
{
{ "fr-FR", new CultureVariation { Name = "name-fr2", Date = new DateTime(2018, 01, 03, 01, 00, 00) } },
{ "en-UK", new CultureVariation { Name = "name-uk2", Date = new DateTime(2018, 01, 04, 01, 00, 00) } }
}
},
PublishedData = new ContentData { Name="It Works1!", Published = true, TemplateId = 0, VersionId = 1, VersionDate = DateTime.Now, WriterId = 0,
Properties = new Dictionary<string, PropertyData[]> { { "prop", new[]
{
new PropertyData { Value = "val1" },
new PropertyData { Culture = "fr-FR", Value = "val-fr1" },
new PropertyData { Culture = "en-UK", Value = "val-uk1" }
} } } }
} } },
CultureInfos = new Dictionary<string, CultureVariation>
{
{ "fr-FR", new CultureVariation { Name = "name-fr1", Date = new DateTime(2018, 01, 01, 01, 00, 00) } },
{ "en-UK", new CultureVariation { Name = "name-uk1", Date = new DateTime(2018, 01, 02, 01, 00, 00) } }
}
}
};
var dataSource = new TestDataSource(kit);
@@ -78,18 +89,16 @@ namespace Umbraco.Tests.PublishedContent
var contentTypeService = Mock.Of<IContentTypeService>();
Mock.Get(contentTypeService).Setup(x => x.GetAll()).Returns(contentTypes);
Mock.Get(contentTypeService).Setup(x => x.GetAll(It.IsAny<int[]>())).Returns(contentTypes);
var dataTypeService = Mock.Of<IDataTypeService>();
Mock.Get(dataTypeService).Setup(x => x.GetAll()).Returns(dataTypes);
var serviceContext = new ServiceContext(
dataTypeService : dataTypeService,
memberTypeService: Mock.Of<IMemberTypeService>(),
memberService: Mock.Of<IMemberService>(),
contentTypeService : contentTypeService,
localizationService: Mock.Of<ILocalizationService>()
);
@@ -117,9 +126,6 @@ namespace Umbraco.Tests.PublishedContent
var variationAccessor = new TestPublishedVariationContextAccessor();
// invariant is the current default
variationAccessor.Context = new PublishedVariationContext();
var options = new PublishedSnapshotService.Options { IgnoreLocalDb = true };
var snapshotService = new PublishedSnapshotService(options,
null,
@@ -134,7 +140,7 @@ namespace Umbraco.Tests.PublishedContent
documentRepository,
mediaRepository,
memberRepository,
new TestSystemDefaultCultureAccessor(),
new TestSystemDefaultCultureAccessor(),
dataSource,
globalSettings,
new SiteDomainHelper());
@@ -142,26 +148,59 @@ namespace Umbraco.Tests.PublishedContent
var snapshot = snapshotService.CreatePublishedSnapshot(previewToken: null);
var publishedContent = snapshot.Content.GetById(1);
// invariant is the current default
variationAccessor.Context = new PublishedVariationContext();
Assert.IsNotNull(publishedContent);
Assert.AreEqual("It Works1!", publishedContent.Name);
Assert.AreEqual("val1", publishedContent.Value<string>("prop"));
Assert.AreEqual("val-fr1", publishedContent.Value<string>("prop", "fr-FR"));
Assert.AreEqual("val-uk1", publishedContent.Value<string>("prop", "en-UK"));
Assert.AreEqual("name-fr1", publishedContent.GetCulture("fr-FR").Name);
Assert.AreEqual("name-uk1", publishedContent.GetCulture("en-UK").Name);
var draftContent = snapshot.Content.GetById(true, 1);
Assert.AreEqual("It Works2!", draftContent.Name);
Assert.AreEqual("val2", draftContent.Value<string>("prop"));
Assert.AreEqual("val-fr2", draftContent.Value<string>("prop", "fr-FR"));
Assert.AreEqual("val-uk2", draftContent.Value<string>("prop", "en-UK"));
Assert.AreEqual("name-fr2", draftContent.GetCulture("fr-FR").Name);
Assert.AreEqual("name-uk2", draftContent.GetCulture("en-UK").Name);
// now french is default
variationAccessor.Context = new PublishedVariationContext("fr-FR");
Assert.AreEqual("val-fr1", publishedContent.Value<string>("prop"));
Assert.AreEqual("name-fr1", publishedContent.GetCulture().Name);
Assert.AreEqual("name-fr1", publishedContent.Name);
Assert.AreEqual(new DateTime(2018, 01, 01, 01, 00, 00), publishedContent.GetCulture().PublishedDate);
// now uk is default
variationAccessor.Context = new PublishedVariationContext("en-UK");
Assert.AreEqual("val-uk1", publishedContent.Value<string>("prop"));
Assert.AreEqual("name-uk1", publishedContent.GetCulture().Name);
Assert.AreEqual("name-uk1", publishedContent.Name);
Assert.AreEqual(new DateTime(2018, 01, 02, 01, 00, 00), publishedContent.GetCulture().PublishedDate);
// invariant needs to be retrieved explicitely, when it's not default
Assert.AreEqual("val1", publishedContent.Value<string>("prop", culture: null));
// but,
// if the content type / property type does not vary, then it's all invariant again
contentType.Variations = ContentVariation.InvariantNeutral;
propertyType.Variations = ContentVariation.InvariantNeutral;
snapshotService.Notify(new[] { new ContentTypeCacheRefresher.JsonPayload("IContentType", publishedContent.ContentType.Id, ContentTypeChangeTypes.RefreshMain) });
var anotherSnapshot = snapshotService.CreatePublishedSnapshot(previewToken: null);
var againContent = anotherSnapshot.Content.GetById(1);
Assert.AreEqual(ContentVariation.InvariantNeutral, againContent.ContentType.Variations);
Assert.AreEqual(ContentVariation.InvariantNeutral, againContent.ContentType.GetPropertyType("prop").Variations);
Assert.AreEqual("It Works1!", againContent.Name);
Assert.AreEqual("val1", againContent.Value<string>("prop"));
// then, test fallback
}

View File

@@ -2583,8 +2583,8 @@ namespace Umbraco.Tests.Services
AssertPerCulture(content, (x, c) => x.IsCultureEdited(c), (langFr, false), (langUk, false), (langDe, true));
AssertPerCulture(content2, (x, c) => x.IsCultureEdited(c), (langFr, false), (langUk, false), (langDe, true));
AssertPerCulture(content, (x, c) => x.GetDateCulturePublished(c) == DateTime.MinValue, (langFr, false), (langUk, false)); // DE would throw
AssertPerCulture(content2, (x, c) => x.GetDateCulturePublished(c) == DateTime.MinValue, (langFr, false), (langUk, false)); // DE would throw
AssertPerCulture(content, (x, c) => x.GetCulturePublishDate(c) == DateTime.MinValue, (langFr, false), (langUk, false)); // DE would throw
AssertPerCulture(content2, (x, c) => x.GetCulturePublishDate(c) == DateTime.MinValue, (langFr, false), (langUk, false)); // DE would throw
// note that content and content2 culture published dates might be slightly different due to roundtrip to database
@@ -2644,8 +2644,8 @@ namespace Umbraco.Tests.Services
AssertPerCulture(content, (x, c) => x.IsCultureEdited(c), (langFr, true), (langUk, true), (langDe, true));
AssertPerCulture(content2, (x, c) => x.IsCultureEdited(c), (langFr, true), (langUk, true), (langDe, true));
AssertPerCulture(content, (x, c) => x.GetDateCulturePublished(c) == DateTime.MinValue, (langFr, false), (langUk, false)); // DE would throw
AssertPerCulture(content2, (x, c) => x.GetDateCulturePublished(c) == DateTime.MinValue, (langFr, false), (langUk, false)); // DE would throw
AssertPerCulture(content, (x, c) => x.GetCulturePublishDate(c) == DateTime.MinValue, (langFr, false), (langUk, false)); // DE would throw
AssertPerCulture(content2, (x, c) => x.GetCulturePublishDate(c) == DateTime.MinValue, (langFr, false), (langUk, false)); // DE would throw
// act
@@ -2687,8 +2687,8 @@ namespace Umbraco.Tests.Services
AssertPerCulture(content, (x, c) => x.IsCultureEdited(c), (langFr, true), (langUk, true), (langDe, true));
AssertPerCulture(content2, (x, c) => x.IsCultureEdited(c), (langFr, true), (langUk, true), (langDe, true));
AssertPerCulture(content, (x, c) => x.GetDateCulturePublished(c) == DateTime.MinValue, (langUk, false)); // FR, DE would throw
AssertPerCulture(content2, (x, c) => x.GetDateCulturePublished(c) == DateTime.MinValue, (langUk, false)); // FR, DE would throw
AssertPerCulture(content, (x, c) => x.GetCulturePublishDate(c) == DateTime.MinValue, (langUk, false)); // FR, DE would throw
AssertPerCulture(content2, (x, c) => x.GetCulturePublishDate(c) == DateTime.MinValue, (langUk, false)); // FR, DE would throw
// act
@@ -2734,8 +2734,8 @@ namespace Umbraco.Tests.Services
AssertPerCulture(content, (x, c) => x.IsCultureEdited(c), (langFr, true), (langUk, true), (langDe, true));
AssertPerCulture(content2, (x, c) => x.IsCultureEdited(c), (langFr, true), (langUk, true), (langDe, true));
AssertPerCulture(content, (x, c) => x.GetDateCulturePublished(c) == DateTime.MinValue, (langUk, false)); // FR, DE would throw
AssertPerCulture(content2, (x, c) => x.GetDateCulturePublished(c) == DateTime.MinValue, (langUk, false)); // FR, DE would throw
AssertPerCulture(content, (x, c) => x.GetCulturePublishDate(c) == DateTime.MinValue, (langUk, false)); // FR, DE would throw
AssertPerCulture(content2, (x, c) => x.GetCulturePublishDate(c) == DateTime.MinValue, (langUk, false)); // FR, DE would throw
// act
@@ -2774,8 +2774,8 @@ namespace Umbraco.Tests.Services
AssertPerCulture(content, (x, c) => x.IsCultureEdited(c), (langFr, true), (langUk, true), (langDe, true));
AssertPerCulture(content2, (x, c) => x.IsCultureEdited(c), (langFr, true), (langUk, true), (langDe, true));
AssertPerCulture(content, (x, c) => x.GetDateCulturePublished(c) == DateTime.MinValue, (langUk, false)); // FR, DE would throw
AssertPerCulture(content2, (x, c) => x.GetDateCulturePublished(c) == DateTime.MinValue, (langUk, false)); // FR, DE would throw
AssertPerCulture(content, (x, c) => x.GetCulturePublishDate(c) == DateTime.MinValue, (langUk, false)); // FR, DE would throw
AssertPerCulture(content2, (x, c) => x.GetCulturePublishDate(c) == DateTime.MinValue, (langUk, false)); // FR, DE would throw
// act
@@ -2797,8 +2797,8 @@ namespace Umbraco.Tests.Services
AssertPerCulture(content, (x, c) => x.IsCultureEdited(c), (langFr, true), (langUk, false), (langDe, true));
AssertPerCulture(content2, (x, c) => x.IsCultureEdited(c), (langFr, true), (langUk, false), (langDe, true));
AssertPerCulture(content, (x, c) => x.GetDateCulturePublished(c) == DateTime.MinValue, (langUk, false)); // FR, DE would throw
AssertPerCulture(content2, (x, c) => x.GetDateCulturePublished(c) == DateTime.MinValue, (langUk, false)); // FR, DE would throw
AssertPerCulture(content, (x, c) => x.GetCulturePublishDate(c) == DateTime.MinValue, (langUk, false)); // FR, DE would throw
AssertPerCulture(content2, (x, c) => x.GetCulturePublishDate(c) == DateTime.MinValue, (langUk, false)); // FR, DE would throw
// act

View File

@@ -18,7 +18,7 @@ namespace Umbraco.Web.PublishedCache.NuCache.DataSource
for (var i = 0; i < pcount; i++)
{
var languageId = PrimitiveSerializer.String.ReadFrom(stream);
var cultureVariation = new CultureVariation { Name = ReadStringObject(stream) };
var cultureVariation = new CultureVariation { Name = ReadStringObject(stream), Date = ReadDateTime(stream) };
dict[languageId] = cultureVariation;
}
return dict;
@@ -40,6 +40,7 @@ namespace Umbraco.Web.PublishedCache.NuCache.DataSource
PrimitiveSerializer.String.WriteTo(culture, stream); // should never be null
WriteObject(variation.Name, stream); // write an object in case it's null (though... should not happen)
PrimitiveSerializer.DateTime.WriteTo(variation.Date, stream);
}
}
}

View File

@@ -6,20 +6,18 @@ namespace Umbraco.Web.PublishedCache.NuCache.DataSource
// represents everything that is specific to edited or published version
internal class ContentData
{
public string Name { get; set; }
public int VersionId { get; set; }
public DateTime VersionDate { get; set; }
public int WriterId { get; set; }
public int TemplateId { get; set; }
public bool Published { get; set; }
public IDictionary<string, PropertyData[]> Properties { get; set; }
/// <summary>
/// The collection of language Id to name for the content item
/// </summary>
public IReadOnlyDictionary<string, CultureVariation> CultureInfos { get; set; }
public string Name { get; set; }
public int VersionId { get; set; }
//TODO: This will not make a lot of sense since we'll have dates for each variant publishing, need to wait on Stephane
public DateTime VersionDate { get; set; }
public int WriterId { get; set; }
public int TemplateId { get; set; }
public IDictionary<string, PropertyData[]> Properties { get; set; }
}
}

View File

@@ -1,4 +1,5 @@
using Newtonsoft.Json;
using System;
using Newtonsoft.Json;
namespace Umbraco.Web.PublishedCache.NuCache.DataSource
{
@@ -10,6 +11,7 @@ namespace Umbraco.Web.PublishedCache.NuCache.DataSource
[JsonProperty("name")]
public string Name { get; set; }
//TODO: We may want some date stamps here
[JsonProperty("date")]
public DateTime Date { get; set; }
}
}

View File

@@ -2,8 +2,10 @@
using System.Collections.Generic;
using System.Linq;
using System.Xml.Serialization;
using Umbraco.Core;
using Umbraco.Core.Cache;
using Umbraco.Core.Collections;
using Umbraco.Core.Models;
using Umbraco.Core.Models.PublishedContent;
using Umbraco.Core.PropertyEditors;
using Umbraco.Web.PublishedCache.NuCache.DataSource;
@@ -19,6 +21,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
private readonly bool _isPreviewing;
private readonly bool _isMember;
private readonly PublishedContent _content;
private readonly ContentVariation _variations;
private readonly object _locko = new object();
@@ -68,6 +71,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
_isPreviewing = content.IsPreviewing;
_isMember = content.ContentType.ItemType == PublishedItemType.Member;
_publishedSnapshotAccessor = publishedSnapshotAccessor;
_variations = propertyType.Variations;
}
// clone for previewing as draft a published content that is published and has no draft
@@ -82,6 +86,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
_isPreviewing = true;
_isMember = origin._isMember;
_publishedSnapshotAccessor = origin._publishedSnapshotAccessor;
_variations = origin._variations;
}
public override bool HasValue(string culture = ".", string segment = ".") => _sourceValue != null
@@ -185,9 +190,10 @@ namespace Umbraco.Web.PublishedCache.NuCache
if (culture != "." && segment != ".") return;
// use context values
// fixme CultureSegment?
var publishedVariationContext = _content.VariationContextAccessor?.Context;
if (culture == ".") culture = publishedVariationContext?.Culture;
if (segment == ".") segment = publishedVariationContext?.Segment;
if (culture == ".") culture = _variations.Has(ContentVariation.CultureNeutral) ? publishedVariationContext?.Culture : null;
if (segment == ".") segment = _variations.Has(ContentVariation.CultureNeutral) ? publishedVariationContext?.Segment : null;
}
public override object GetValue(string culture = ".", string segment = ".")

View File

@@ -19,7 +19,6 @@ namespace Umbraco.Web.PublishedCache.NuCache
internal readonly ContentData _contentData; // internal for ContentNode cloning
private readonly string _urlSegment;
private IReadOnlyDictionary<string, PublishedCultureName> _cultureNames;
#region Constructors
@@ -265,7 +264,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
if (_cultureInfos != null) return _cultureInfos;
return _cultureInfos = _contentData.CultureInfos // fixme can it be null?
.ToDictionary(x => x.Key, x => new PublishedCultureInfos(x.Key, x.Value.Name, false, DateTime.MinValue)); // fixme values!
.ToDictionary(x => x.Key, x => new PublishedCultureInfos(x.Key, x.Value.Name, false, x.Value.Date)); // fixme values!
}
}

View File

@@ -722,7 +722,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
Notify<IContentType>(_contentStore, payloads, RefreshContentTypesLocked);
Notify<IMediaType>(_mediaStore, payloads, RefreshMediaTypesLocked);
((PublishedSnapshot)CurrentPublishedSnapshot).Resync();
((PublishedSnapshot)CurrentPublishedSnapshot)?.Resync(); // fixme all
}
private void Notify<T>(ContentStore store, ContentTypeCacheRefresher.JsonPayload[] payloads, Action<IEnumerable<int>, IEnumerable<int>, IEnumerable<int>, IEnumerable<int>> action)
@@ -799,7 +799,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
}
}
((PublishedSnapshot)CurrentPublishedSnapshot).Resync();
((PublishedSnapshot)CurrentPublishedSnapshot)?.Resync(); // fixme elsewhere!
}
public override void Notify(DomainCacheRefresher.JsonPayload[] payloads)
@@ -900,8 +900,9 @@ namespace Umbraco.Web.PublishedCache.NuCache
// contentStore is wlocked (so readable, only no new views)
// and it can be wlocked by 1 thread only at a time
if (!(_serviceContext.ContentService is ContentService))
throw new Exception("oops");
// fixme wtf?
//if (!(_serviceContext.ContentService is ContentService))
// throw new Exception("oops");
var refreshedIdsA = refreshedIds.ToArray();
@@ -1219,7 +1220,6 @@ namespace Umbraco.Web.PublishedCache.NuCache
var cultureData = new Dictionary<string, CultureVariation>();
// fixme refactor!!!
var names = content is IContent document
? (published
? document.PublishNames
@@ -1228,7 +1228,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
foreach (var (culture, name) in names)
{
cultureData[culture] = new CultureVariation { Name = name };
cultureData[culture] = new CultureVariation { Name = name, Date = content.GetCultureDate(culture) };
}
//the dictionary that will be serialized

View File

@@ -408,7 +408,6 @@ namespace umbraco
private readonly PublishedContentType _contentType;
private readonly IPublishedProperty[] _properties;
private readonly IPublishedContent _parent;
private IReadOnlyDictionary<string, PublishedCultureName> _cultureNames;
private IReadOnlyDictionary<string, PublishedCultureInfos> _cultureInfos;
private readonly IPublishedVariationContextAccessor _variationContextAccessor;
@@ -500,8 +499,8 @@ namespace umbraco
if (_cultureInfos != null)
return _cultureInfos;
return _cultureInfos = _inner.Names
.ToDictionary(x => x.Key, x => new PublishedCultureInfos(x.Key, x.Value, false, DateTime.MinValue)); // fixme values!
return _cultureInfos = _inner.Names // fixme names, or PublishNames?
.ToDictionary(x => x.Key, x => new PublishedCultureInfos(x.Key, x.Value, false, _inner.GetCulturePublishDate(x.Key))); // fixme values!
}
}