diff --git a/src/Umbraco.Core/Models/Content.cs b/src/Umbraco.Core/Models/Content.cs
index 8bfb5718a2..73f462b65d 100644
--- a/src/Umbraco.Core/Models/Content.cs
+++ b/src/Umbraco.Core/Models/Content.cs
@@ -225,7 +225,6 @@ namespace Umbraco.Core.Models
///
[IgnoreDataMember]
- //public IReadOnlyDictionary PublishNames => _publishNames ?? NoNames;
public IReadOnlyDictionary PublishNames => _publishInfos?.ToDictionary(x => x.Key, x => x.Value.Name) ?? NoNames;
///
@@ -263,7 +262,7 @@ namespace Umbraco.Core.Models
=> !string.IsNullOrWhiteSpace(GetPublishName(culture));
///
- public DateTime GetDateCulturePublished(string culture)
+ public DateTime GetCulturePublishDate(string culture)
{
if (_publishInfos != null && _publishInfos.TryGetValue(culture, out var infos))
return infos.Date;
diff --git a/src/Umbraco.Core/Models/ContentBase.cs b/src/Umbraco.Core/Models/ContentBase.cs
index 7bc327c2d0..b40e11e25d 100644
--- a/src/Umbraco.Core/Models/ContentBase.cs
+++ b/src/Umbraco.Core/Models/ContentBase.cs
@@ -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 _names;
+ private Dictionary _cultureInfos;
///
/// Initializes a new instance of the class.
@@ -139,16 +140,30 @@ namespace Umbraco.Core.Models
///
[DataMember]
- public virtual IReadOnlyDictionary Names
- {
- get => _names ?? NoNames;
- set
- {
- foreach (var (culture, name) in value)
- SetName(culture, name);
- }
- }
+ public virtual IReadOnlyDictionary 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(StringComparer.OrdinalIgnoreCase);
+
+ _cultureInfos[culture] = (name, date);
+ }
+
///
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(StringComparer.OrdinalIgnoreCase);
- if (_names == null)
- _names = new Dictionary(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;
}
///
@@ -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);
}
+
+ ///
+ 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
diff --git a/src/Umbraco.Core/Models/IContent.cs b/src/Umbraco.Core/Models/IContent.cs
index 2f3fd06f5f..59ff548e16 100644
--- a/src/Umbraco.Core/Models/IContent.cs
+++ b/src/Umbraco.Core/Models/IContent.cs
@@ -93,7 +93,7 @@ namespace Umbraco.Core.Models
///
/// Gets the date a culture was published.
///
- DateTime GetDateCulturePublished(string culture);
+ DateTime GetCulturePublishDate(string culture);
///
/// Gets a value indicated whether a given culture is edited.
diff --git a/src/Umbraco.Core/Models/IContentBase.cs b/src/Umbraco.Core/Models/IContentBase.cs
index 93a6e82ada..b6e05fa7dd 100644
--- a/src/Umbraco.Core/Models/IContentBase.cs
+++ b/src/Umbraco.Core/Models/IContentBase.cs
@@ -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);
///
- /// Gets or sets the names of the content item.
+ /// Gets the names of the content item.
///
///
- /// Because a dictionary key cannot be null this cannot get nor set the invariant
+ /// Because a dictionary key cannot be null this cannot get the invariant
/// name, which must be get or set via the property.
///
- IReadOnlyDictionary Names { get; set; }
+ IReadOnlyDictionary Names { get; }
///
/// Gets a value indicating whether a given culture is available.
@@ -63,6 +64,11 @@ namespace Umbraco.Core.Models
///
bool IsCultureAvailable(string culture);
+ ///
+ /// Gets the date a culture was created.
+ ///
+ DateTime GetCultureDate(string culture);
+
///
/// List of properties, which make up all the data available for this Content object
///
diff --git a/src/Umbraco.Core/Models/PublishedContent/PublishedCultureName.cs b/src/Umbraco.Core/Models/PublishedContent/PublishedCultureInfos.cs
similarity index 78%
rename from src/Umbraco.Core/Models/PublishedContent/PublishedCultureName.cs
rename to src/Umbraco.Core/Models/PublishedContent/PublishedCultureInfos.cs
index 898649f2e5..7a563544a4 100644
--- a/src/Umbraco.Core/Models/PublishedContent/PublishedCultureName.cs
+++ b/src/Umbraco.Core/Models/PublishedContent/PublishedCultureInfos.cs
@@ -3,21 +3,6 @@ using Umbraco.Core.Exceptions;
namespace Umbraco.Core.Models.PublishedContent
{
- ///
- /// Contains the culture specific data for a item
- ///
- 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; }
- }
-
///
/// Contains culture specific values for .
///
diff --git a/src/Umbraco.Core/Persistence/Repositories/Implement/DocumentRepository.cs b/src/Umbraco.Core/Persistence/Repositories/Implement/DocumentRepository.cs
index 76321abe6a..a9eed7edb1 100644
--- a/src/Umbraco.Core/Persistence/Repositories/Implement/DocumentRepository.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/Implement/DocumentRepository.cs
@@ -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)
};
}
diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj
index 7d6f27083b..954391c8a6 100644
--- a/src/Umbraco.Core/Umbraco.Core.csproj
+++ b/src/Umbraco.Core/Umbraco.Core.csproj
@@ -368,7 +368,7 @@
-
+
diff --git a/src/Umbraco.Tests/Models/VariationTests.cs b/src/Umbraco.Tests/Models/VariationTests.cs
index bc0891e397..8502af0e68 100644
--- a/src/Umbraco.Tests/Models/VariationTests.cs
+++ b/src/Umbraco.Tests/Models/VariationTests.cs
@@ -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(() => content.GetDateCulturePublished(langUk)); // not published!
+ Assert.Throws(() => 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(() => content.GetDateCulturePublished(langEs)); // not published!
+ Assert.Throws(() => 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
diff --git a/src/Umbraco.Tests/PublishedContent/PublishedContentOtherTests.cs b/src/Umbraco.Tests/PublishedContent/PublishedContentOtherTests.cs
index e4fce2a3be..3aa1fbf41f 100644
--- a/src/Umbraco.Tests/PublishedContent/PublishedContentOtherTests.cs
+++ b/src/Umbraco.Tests/PublishedContent/PublishedContentOtherTests.cs
@@ -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
+ {
+ { "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 { { "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
+ {
+ { "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();
Mock.Get(contentTypeService).Setup(x => x.GetAll()).Returns(contentTypes);
+ Mock.Get(contentTypeService).Setup(x => x.GetAll(It.IsAny())).Returns(contentTypes);
var dataTypeService = Mock.Of();
Mock.Get(dataTypeService).Setup(x => x.GetAll()).Returns(dataTypes);
var serviceContext = new ServiceContext(
dataTypeService : dataTypeService,
-
memberTypeService: Mock.Of(),
memberService: Mock.Of(),
-
contentTypeService : contentTypeService,
-
localizationService: Mock.Of()
);
@@ -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("prop"));
Assert.AreEqual("val-fr1", publishedContent.Value("prop", "fr-FR"));
Assert.AreEqual("val-uk1", publishedContent.Value("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("prop"));
Assert.AreEqual("val-fr2", draftContent.Value("prop", "fr-FR"));
Assert.AreEqual("val-uk2", draftContent.Value("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("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("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("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("prop"));
+
// then, test fallback
}
diff --git a/src/Umbraco.Tests/Services/ContentServiceTests.cs b/src/Umbraco.Tests/Services/ContentServiceTests.cs
index 8bb5f1bc9e..47f1d49c2a 100644
--- a/src/Umbraco.Tests/Services/ContentServiceTests.cs
+++ b/src/Umbraco.Tests/Services/ContentServiceTests.cs
@@ -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
diff --git a/src/Umbraco.Web/PublishedCache/NuCache/DataSource/BTree.DictionaryOfCultureVariationSerializer.cs b/src/Umbraco.Web/PublishedCache/NuCache/DataSource/BTree.DictionaryOfCultureVariationSerializer.cs
index a835886254..c9d809714d 100644
--- a/src/Umbraco.Web/PublishedCache/NuCache/DataSource/BTree.DictionaryOfCultureVariationSerializer.cs
+++ b/src/Umbraco.Web/PublishedCache/NuCache/DataSource/BTree.DictionaryOfCultureVariationSerializer.cs
@@ -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);
}
}
}
diff --git a/src/Umbraco.Web/PublishedCache/NuCache/DataSource/ContentData.cs b/src/Umbraco.Web/PublishedCache/NuCache/DataSource/ContentData.cs
index 6841937c14..4721a1f4ca 100644
--- a/src/Umbraco.Web/PublishedCache/NuCache/DataSource/ContentData.cs
+++ b/src/Umbraco.Web/PublishedCache/NuCache/DataSource/ContentData.cs
@@ -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 Properties { get; set; }
+
///
/// The collection of language Id to name for the content item
///
public IReadOnlyDictionary 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 Properties { get; set; }
}
}
diff --git a/src/Umbraco.Web/PublishedCache/NuCache/DataSource/CultureVariation.cs b/src/Umbraco.Web/PublishedCache/NuCache/DataSource/CultureVariation.cs
index aad416a925..50a2adaeb8 100644
--- a/src/Umbraco.Web/PublishedCache/NuCache/DataSource/CultureVariation.cs
+++ b/src/Umbraco.Web/PublishedCache/NuCache/DataSource/CultureVariation.cs
@@ -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; }
}
}
diff --git a/src/Umbraco.Web/PublishedCache/NuCache/Property.cs b/src/Umbraco.Web/PublishedCache/NuCache/Property.cs
index d2f37a1488..02dfc4e934 100644
--- a/src/Umbraco.Web/PublishedCache/NuCache/Property.cs
+++ b/src/Umbraco.Web/PublishedCache/NuCache/Property.cs
@@ -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 = ".")
diff --git a/src/Umbraco.Web/PublishedCache/NuCache/PublishedContent.cs b/src/Umbraco.Web/PublishedCache/NuCache/PublishedContent.cs
index 5b6c8ca783..0ca20fd625 100644
--- a/src/Umbraco.Web/PublishedCache/NuCache/PublishedContent.cs
+++ b/src/Umbraco.Web/PublishedCache/NuCache/PublishedContent.cs
@@ -19,7 +19,6 @@ namespace Umbraco.Web.PublishedCache.NuCache
internal readonly ContentData _contentData; // internal for ContentNode cloning
private readonly string _urlSegment;
- private IReadOnlyDictionary _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!
}
}
diff --git a/src/Umbraco.Web/PublishedCache/NuCache/PublishedSnapshotService.cs b/src/Umbraco.Web/PublishedCache/NuCache/PublishedSnapshotService.cs
index af84f54c11..b2cb8bbcf8 100644
--- a/src/Umbraco.Web/PublishedCache/NuCache/PublishedSnapshotService.cs
+++ b/src/Umbraco.Web/PublishedCache/NuCache/PublishedSnapshotService.cs
@@ -722,7 +722,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
Notify(_contentStore, payloads, RefreshContentTypesLocked);
Notify(_mediaStore, payloads, RefreshMediaTypesLocked);
- ((PublishedSnapshot)CurrentPublishedSnapshot).Resync();
+ ((PublishedSnapshot)CurrentPublishedSnapshot)?.Resync(); // fixme all
}
private void Notify(ContentStore store, ContentTypeCacheRefresher.JsonPayload[] payloads, Action, IEnumerable, IEnumerable, IEnumerable> 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();
- // 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
diff --git a/src/Umbraco.Web/umbraco.presentation/page.cs b/src/Umbraco.Web/umbraco.presentation/page.cs
index b37a5d42e0..f65f04fb76 100644
--- a/src/Umbraco.Web/umbraco.presentation/page.cs
+++ b/src/Umbraco.Web/umbraco.presentation/page.cs
@@ -408,7 +408,6 @@ namespace umbraco
private readonly PublishedContentType _contentType;
private readonly IPublishedProperty[] _properties;
private readonly IPublishedContent _parent;
- private IReadOnlyDictionary _cultureNames;
private IReadOnlyDictionary _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!
}
}