diff --git a/src/Umbraco.Core/Models/Content.cs b/src/Umbraco.Core/Models/Content.cs
index 6de1a9d909..815812279d 100644
--- a/src/Umbraco.Core/Models/Content.cs
+++ b/src/Umbraco.Core/Models/Content.cs
@@ -246,14 +246,17 @@ namespace Umbraco.Core.Models
// clears all publish names
private void ClearPublishNames()
{
+ PublishName = null;
_publishNames = null;
- }
+ }
+
+ ///
+ public bool IsCultureAvailable(int? languageId)
+ => !string.IsNullOrWhiteSpace(GetName(languageId));
///
public bool IsCulturePublished(int? languageId)
- {
- return !string.IsNullOrWhiteSpace(GetPublishName(languageId));
- }
+ => !string.IsNullOrWhiteSpace(GetPublishName(languageId));
[IgnoreDataMember]
public int PublishedVersionId { get; internal set; }
@@ -273,7 +276,8 @@ namespace Umbraco.Core.Models
property.PublishAllValues();
// Name and PublishName are managed by the repository, but Names and PublishNames
- // must be managed here as they depend on the existing / supported variations.
+ // must be managed here as they depend on the existing / supported variations.
+ PublishName = Name;
foreach (var (languageId, name) in Names)
SetPublishName(languageId, name);
@@ -331,7 +335,7 @@ namespace Umbraco.Core.Models
// Name and PublishName are managed by the repository, but Names and PublishNames
// must be managed here as they depend on the existing / supported variations.
- ClearPublishNames();
+ ClearPublishNames();
_publishedState = PublishedState.Publishing;
}
diff --git a/src/Umbraco.Core/Models/ContentExtensions.cs b/src/Umbraco.Core/Models/ContentExtensions.cs
index 64144748e0..5b7e825d68 100644
--- a/src/Umbraco.Core/Models/ContentExtensions.cs
+++ b/src/Umbraco.Core/Models/ContentExtensions.cs
@@ -171,19 +171,6 @@ namespace Umbraco.Core.Models
return content.PropertyTypes.Any(x => x.Variations == ContentVariation.CultureNeutral);
}
- ///
- /// Returns true if the content has a variation for the language/segment combination
- ///
- ///
- ///
- ///
- ///
- public static bool HasVariation(this IContent content, int langId, string segment = null)
- {
- // fixme - wire - but: purpose? are we looking for a 'published' variation? what is this?
- return false;
- }
-
#endregion
///
diff --git a/src/Umbraco.Core/Models/IContent.cs b/src/Umbraco.Core/Models/IContent.cs
index a294040dbc..3f7a335620 100644
--- a/src/Umbraco.Core/Models/IContent.cs
+++ b/src/Umbraco.Core/Models/IContent.cs
@@ -84,8 +84,18 @@ namespace Umbraco.Core.Models
/// Gets a value indicating whether a given culture is available.
///
///
- /// A culture becomes available whenever values for this culture are published,
- /// and it becomes unavailable whenever values for this culture are unpublished.
+ /// A culture becomes available whenever the content name for this culture is
+ /// non-null, and it becomes unavailable whenever the content name is null.
+ ///
+ bool IsCultureAvailable(int? languageId);
+
+ ///
+ /// Gets a value indicating whether a given culture is published.
+ ///
+ ///
+ /// A culture becomes published whenever values for this culture are published,
+ /// and the content published name for this culture is non-null. It becomes non-published
+ /// whenever values for this culture are unpublished.
///
bool IsCulturePublished(int? languageId);
diff --git a/src/Umbraco.Core/Persistence/Repositories/Implement/DocumentRepository.cs b/src/Umbraco.Core/Persistence/Repositories/Implement/DocumentRepository.cs
index 2a1aa5c403..8463010d0f 100644
--- a/src/Umbraco.Core/Persistence/Repositories/Implement/DocumentRepository.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/Implement/DocumentRepository.cs
@@ -344,7 +344,6 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
if (content.PublishedState == PublishedState.Publishing)
{
content.Published = true;
- content.PublishName = content.Name;
content.PublishTemplate = content.Template;
content.PublisherId = content.WriterId;
content.PublishDate = content.UpdateDate;
@@ -354,7 +353,6 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
else if (content.PublishedState == PublishedState.Unpublishing)
{
content.Published = false;
- content.PublishName = null;
content.PublishTemplate = null;
content.PublisherId = null;
content.PublishDate = null;
@@ -497,7 +495,6 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
if (content.PublishedState == PublishedState.Publishing)
{
content.Published = true;
- content.PublishName = content.Name;
content.PublishTemplate = content.Template;
content.PublisherId = content.WriterId;
content.PublishDate = content.UpdateDate;
@@ -507,7 +504,6 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
else if (content.PublishedState == PublishedState.Unpublishing)
{
content.Published = false;
- content.PublishName = null;
content.PublishTemplate = null;
content.PublisherId = null;
content.PublishDate = null;
diff --git a/src/Umbraco.Tests/Services/ContentServiceTests.cs b/src/Umbraco.Tests/Services/ContentServiceTests.cs
index 723418ace1..88a3f7821d 100644
--- a/src/Umbraco.Tests/Services/ContentServiceTests.cs
+++ b/src/Umbraco.Tests/Services/ContentServiceTests.cs
@@ -2480,22 +2480,27 @@ namespace Umbraco.Tests.Services
var languageService = ServiceContext.LocalizationService;
var langFr = new Language("fr-FR");
- var langUk = new Language("en-UK");
+ var langUk = new Language("en-UK");
+ var langDe = new Language("de-DE");
languageService.Save(langFr);
- languageService.Save(langUk);
+ languageService.Save(langUk);
+ languageService.Save(langDe);
var contentTypeService = ServiceContext.ContentTypeService;
var contentType = contentTypeService.Get("umbTextpage");
contentType.Variations = ContentVariation.CultureNeutral;
- contentTypeService.Save(contentType);
-
+ contentType.AddPropertyType(new PropertyType(Constants.PropertyEditors.Aliases.TextBox, ValueStorageType.Nvarchar, "prop") { Variations = ContentVariation.CultureNeutral });
+ contentTypeService.Save(contentType);
+
var contentService = ServiceContext.ContentService;
var content = contentService.Create("Home US", - 1, "umbTextpage");
// act
- content.SetValue("author", "Barack Obama");
+ content.SetValue("author", "Barack Obama");
+ content.SetValue("prop", "value-fr1", langFr.Id);
+ content.SetValue("prop", "value-uk1", langUk.Id);
content.SetName(langFr.Id, "name-fr");
content.SetName(langUk.Id, "name-uk");
contentService.Save(content);
@@ -2507,12 +2512,21 @@ namespace Umbraco.Tests.Services
Assert.AreEqual("Home US", content2.Name);
Assert.AreEqual("name-fr", content2.GetName(langFr.Id));
- Assert.AreEqual("name-uk", content2.GetName(langUk.Id));
+ Assert.AreEqual("name-uk", content2.GetName(langUk.Id));
+
+ Assert.AreEqual("value-fr1", content2.GetValue("prop", langFr.Id));
+ Assert.AreEqual("value-uk1", content2.GetValue("prop", langUk.Id));
+ Assert.IsNull(content2.GetValue("prop", langFr.Id, published: true));
+ Assert.IsNull(content2.GetValue("prop", langUk.Id, published: true));
Assert.IsNull(content2.PublishName);
Assert.IsNull(content2.GetPublishName(langFr.Id));
Assert.IsNull(content2.GetPublishName(langUk.Id));
+ Assert.IsTrue(content.IsCultureAvailable(langFr.Id));
+ Assert.IsTrue(content.IsCultureAvailable(langUk.Id));
+ Assert.IsFalse(content.IsCultureAvailable(langDe.Id));
+
Assert.IsFalse(content.IsCulturePublished(langFr.Id));
Assert.IsFalse(content.IsCulturePublished(langUk.Id));
@@ -2536,6 +2550,11 @@ namespace Umbraco.Tests.Services
Assert.AreEqual("name-fr", content2.GetPublishName(langFr.Id));
Assert.AreEqual("name-uk", content2.GetPublishName(langUk.Id));
+ Assert.AreEqual("value-fr1", content2.GetValue("prop", langFr.Id));
+ Assert.AreEqual("value-uk1", content2.GetValue("prop", langUk.Id));
+ Assert.AreEqual("value-fr1", content2.GetValue("prop", langFr.Id, published: true));
+ Assert.AreEqual("value-uk1", content2.GetValue("prop", langUk.Id, published: true));
+
Assert.IsTrue(content.IsCulturePublished(langFr.Id));
Assert.IsTrue(content.IsCulturePublished(langUk.Id));
@@ -2544,6 +2563,9 @@ namespace Umbraco.Tests.Services
content.SetName(null, "Home US2");
content.SetName(langFr.Id, "name-fr2");
content.SetName(langUk.Id, "name-uk2");
+ content.SetValue("author", "Barack Obama2");
+ content.SetValue("prop", "value-fr2", langFr.Id);
+ content.SetValue("prop", "value-uk2", langUk.Id);
contentService.Save(content);
// content has been saved,
@@ -2558,7 +2580,15 @@ namespace Umbraco.Tests.Services
Assert.AreEqual("Home US", content2.PublishName);
Assert.AreEqual("name-fr", content2.GetPublishName(langFr.Id));
Assert.AreEqual("name-uk", content2.GetPublishName(langUk.Id));
+
+ Assert.AreEqual("Barack Obama2", content2.GetValue("author"));
+ Assert.IsNull(content2.GetValue("author", published: true)); // because, we never published the InvariantNeutral variation
+ Assert.AreEqual("value-fr2", content2.GetValue("prop", langFr.Id));
+ Assert.AreEqual("value-uk2", content2.GetValue("prop", langUk.Id));
+ Assert.AreEqual("value-fr1", content2.GetValue("prop", langFr.Id, published: true));
+ Assert.AreEqual("value-uk1", content2.GetValue("prop", langUk.Id, published: true));
+
Assert.IsTrue(content.IsCulturePublished(langFr.Id));
Assert.IsTrue(content.IsCulturePublished(langUk.Id));
@@ -2577,10 +2607,15 @@ namespace Umbraco.Tests.Services
Assert.AreEqual("name-fr2", content2.GetName(langFr.Id));
Assert.AreEqual("name-uk2", content2.GetName(langUk.Id));
- Assert.AreEqual("Home US2", content2.PublishName); // fixme why? -- and what about properties?
+ Assert.AreEqual("Home US2", content2.PublishName); // fixme why? -- and what about properties? -- we haven't published invariants?!
Assert.IsNull(content2.GetPublishName(langFr.Id));
Assert.AreEqual("name-uk", content2.GetPublishName(langUk.Id));
+ Assert.AreEqual("value-fr2", content2.GetValue("prop", langFr.Id));
+ Assert.AreEqual("value-uk2", content2.GetValue("prop", langUk.Id));
+ Assert.IsNull(content2.GetValue("prop", langFr.Id, published: true));
+ Assert.AreEqual("value-uk1", content2.GetValue("prop", langUk.Id, published: true));
+
Assert.IsFalse(content.IsCulturePublished(langFr.Id));
Assert.IsTrue(content.IsCulturePublished(langUk.Id));
@@ -2592,7 +2627,14 @@ namespace Umbraco.Tests.Services
// but properties, names, etc. retain their 'published' values so the content
// can be re-published in its exact original state (before being unpublished)
//
- // fixme should PublishName, GetPublishName and IsCulturePublished check content.Published?
+ // BEWARE!
+ // in order for a content to be unpublished as a whole, and then republished in
+ // its exact previous state, properties and names etc. retain their published
+ // values even though the content is not published - hence many things being
+ // non-null or true below - always check against content.Published to be sure
+
+ // FIXME
+ // still, we have some inconsistencies, publishName should go NULL when unpublishing it whole, see repository?
content2 = contentService.GetById(content.Id);
@@ -2606,6 +2648,11 @@ namespace Umbraco.Tests.Services
Assert.IsNull(content2.GetPublishName(langFr.Id));
Assert.AreEqual("name-uk", content2.GetPublishName(langUk.Id)); // not null, see note above
+ Assert.AreEqual("value-fr2", content2.GetValue("prop", langFr.Id));
+ Assert.AreEqual("value-uk2", content2.GetValue("prop", langUk.Id));
+ Assert.IsNull(content2.GetValue("prop", langFr.Id, published: true));
+ Assert.AreEqual("value-uk1", content2.GetValue("prop", langUk.Id, published: true)); // has value, see note above
+
Assert.IsFalse(content.IsCulturePublished(langFr.Id));
Assert.IsTrue(content.IsCulturePublished(langUk.Id)); // still true, see note above
@@ -2628,6 +2675,11 @@ namespace Umbraco.Tests.Services
Assert.IsNull(content2.GetPublishName(langFr.Id));
Assert.AreEqual("name-uk", content2.GetPublishName(langUk.Id));
+ Assert.AreEqual("value-fr2", content2.GetValue("prop", langFr.Id));
+ Assert.AreEqual("value-uk2", content2.GetValue("prop", langUk.Id));
+ Assert.IsNull(content2.GetValue("prop", langFr.Id, published: true));
+ Assert.AreEqual("value-uk1", content2.GetValue("prop", langUk.Id, published: true));
+
Assert.IsFalse(content.IsCulturePublished(langFr.Id));
Assert.IsTrue(content.IsCulturePublished(langUk.Id));
}
diff --git a/src/Umbraco.Web/Models/Mapping/VariationResolver.cs b/src/Umbraco.Web/Models/Mapping/VariationResolver.cs
index 7106b58fbd..9d3de07d77 100644
--- a/src/Umbraco.Web/Models/Mapping/VariationResolver.cs
+++ b/src/Umbraco.Web/Models/Mapping/VariationResolver.cs
@@ -30,7 +30,7 @@ namespace Umbraco.Web.Models.Mapping
Language = x,
Mandatory = x.Mandatory,
Name = source.GetName(x.Id),
- Exists = source.HasVariation(x.Id), // fixme - what's the purpose? "exists" or "published"? exists is a new thing?
+ Exists = source.IsCultureAvailable(x.Id), // segments ??
PublishedState = source.PublishedState.ToString(),
//Segment = ?? We'll need to populate this one day when we support segments
}).ToList();