diff --git a/src/Umbraco.Core/Models/Content.cs b/src/Umbraco.Core/Models/Content.cs index b396e6a4f2..3f6e387dec 100644 --- a/src/Umbraco.Core/Models/Content.cs +++ b/src/Umbraco.Core/Models/Content.cs @@ -208,7 +208,6 @@ namespace Umbraco.Core.Models public IEnumerable PublishedCultures => _publishInfos?.Keys ?? Enumerable.Empty(); /// - // fixme/review: Do we deal with passing in * here since this can happen when publishing branches public bool IsCulturePublished(string culture) // just check _publishInfos // a non-available culture could not become published anyways @@ -241,7 +240,6 @@ namespace Umbraco.Core.Models } /// - // fixme/review: Do we deal with passing in * here since this can happen when publishing branches public bool IsCultureEdited(string culture) => IsCultureAvailable(culture) && // is available, and (!IsCulturePublished(culture) || // is not published, or diff --git a/src/Umbraco.Core/Models/ContentBase.cs b/src/Umbraco.Core/Models/ContentBase.cs index d3e46a90ad..b0c786d4b0 100644 --- a/src/Umbraco.Core/Models/ContentBase.cs +++ b/src/Umbraco.Core/Models/ContentBase.cs @@ -153,7 +153,6 @@ namespace Umbraco.Core.Models => _cultureInfos?.Keys ?? Enumerable.Empty(); /// - // fixme/review: Do we deal with passing in * here since this can happen when publishing branches public bool IsCultureAvailable(string culture) => _cultureInfos != null && _cultureInfos.ContainsKey(culture); diff --git a/src/Umbraco.Core/Models/IContent.cs b/src/Umbraco.Core/Models/IContent.cs index 6ce96e5170..a414a03d2f 100644 --- a/src/Umbraco.Core/Models/IContent.cs +++ b/src/Umbraco.Core/Models/IContent.cs @@ -80,6 +80,7 @@ namespace Umbraco.Core.Models /// whenever values for this culture are unpublished. /// A culture becomes published as soon as PublishCulture has been invoked, /// even though the document might now have been saved yet (and can have no identity). + /// Does not support the '*' wildcard (returns false). /// bool IsCulturePublished(string culture); @@ -103,6 +104,7 @@ namespace Umbraco.Core.Models /// A culture is edited when it is available, and not published or published but /// with changes. /// A culture can be edited even though the document might now have been saved yet (and can have no identity). + /// Does not support the '*' wildcard (returns false). /// bool IsCultureEdited(string culture); diff --git a/src/Umbraco.Core/Models/IContentBase.cs b/src/Umbraco.Core/Models/IContentBase.cs index cef8086207..fb3714cfc0 100644 --- a/src/Umbraco.Core/Models/IContentBase.cs +++ b/src/Umbraco.Core/Models/IContentBase.cs @@ -76,6 +76,7 @@ namespace Umbraco.Core.Models /// Returns false for the invariant culture, in order to be consistent /// with , even though the invariant culture is /// always available. + /// Does not support the '*' wildcard (returns false). /// bool IsCultureAvailable(string culture); diff --git a/src/Umbraco.Core/Services/Implement/ContentService.cs b/src/Umbraco.Core/Services/Implement/ContentService.cs index d5308dae1f..3d207a726d 100644 --- a/src/Umbraco.Core/Services/Implement/ContentService.cs +++ b/src/Umbraco.Core/Services/Implement/ContentService.cs @@ -1303,26 +1303,21 @@ namespace Umbraco.Core.Services.Implement if (c.ContentType.VariesByCulture()) { - //we need to check all available cultures when * + // if "*" ie all cultures, see if at least one culture should be published if (culture == "*") { + // variant content type, all cultures + // ensure that at least one culture is edited, and already published or forced var culturesToPublish = new HashSet(); - foreach (var availableCulture in c.AvailableCultures) - { - // variant content type - // add culture if edited, and already published or forced - if (c.IsCultureEdited(availableCulture) && (c.IsCulturePublished(availableCulture) || force || isRoot)) - culturesToPublish.Add(availableCulture.ToLowerInvariant()); - } - return culturesToPublish; - } - else - { - // variant content type - // add culture if edited, and already published or forced - if (c.IsCultureEdited(culture) && (c.IsCulturePublished(culture) || force || isRoot)) - return new HashSet { culture.ToLowerInvariant() }; + if (c.AvailableCultures.Any(x => c.IsCultureEdited(x) && (c.IsCulturePublished(x) || force || isRoot))) + culturesToPublish.Add("*"); // and then ok to do everything + return culturesToPublish; // empty or "*" } + + // else, variant content type, specific culture + // add culture if edited, and already published or forced + if (c.IsCultureEdited(culture) && (c.IsCulturePublished(culture) || force || isRoot)) + return new HashSet { culture.ToLowerInvariant() }; } else { @@ -1489,7 +1484,10 @@ namespace Umbraco.Core.Services.Implement if (publishCultures != null && !publishCultures(document, culturesToPublish)) return new PublishResult(PublishResultType.FailedPublishContentInvalid, evtMsgs, document); - return SavePublishingInternal(scope, document, userId, branchOne: true, branchRoot: isRoot); + var result = SavePublishingInternal(scope, document, userId, branchOne: true, branchRoot: isRoot); + if (result.Success) + publishedDocuments.Add(document); + return result; } #endregion diff --git a/src/Umbraco.Tests/Services/ContentServicePublishBranchTests.cs b/src/Umbraco.Tests/Services/ContentServicePublishBranchTests.cs index 49edd24d9f..115e002274 100644 --- a/src/Umbraco.Tests/Services/ContentServicePublishBranchTests.cs +++ b/src/Umbraco.Tests/Services/ContentServicePublishBranchTests.cs @@ -33,7 +33,7 @@ namespace Umbraco.Tests.Services ServiceContext.ContentService.Save(ii2); // iroot !published !edited - // ii1 !published !edited + // ii1 !published !edited // ii2 !published !edited // !force = publishes those that are actually published, and have changes @@ -69,7 +69,7 @@ namespace Umbraco.Tests.Services ServiceContext.ContentService.Unpublish(ii2); // iroot published !edited - // ii1 published !edited + // ii1 published !edited // ii11 published !edited // ii12 !published !edited // ii2 !published !edited @@ -99,7 +99,7 @@ namespace Umbraco.Tests.Services ServiceContext.ContentService.Save(ii11); // iroot published edited *** - // ii1 published !edited + // ii1 published !edited // ii11 published edited *** // ii12 !published !edited // ii2 !published !edited @@ -248,41 +248,44 @@ namespace Umbraco.Tests.Services ServiceContext.ContentService.Save(iv2); // vroot !published !edited - // iv1 !published !edited + // iv1 !published !edited // iv2 !published !edited // !force = publishes those that are actually published, and have changes // here: nothing - var r = ServiceContext.ContentService.SaveAndPublishBranch(vRoot, false).ToArray(); //no culture specified = all cultures + var r = ServiceContext.ContentService.SaveAndPublishBranch(vRoot, false).ToArray(); // no culture specified = all cultures AssertPublishResults(r, x => x.Content.Name, "vroot.de", "iv1.de", "iv2.de"); AssertPublishResults(r, x => x.Result, - PublishResultType.SuccessPublishCulture, //the root will always get published + PublishResultType.SuccessPublishCulture, // the root will always get published PublishResultType.SuccessPublishAlready, PublishResultType.SuccessPublishAlready); // prepare - //ServiceContext.ContentService.SaveAndPublish(vRoot, "de"); //fixme/review no need for this, all cultures in the root are published above vRoot.SetValue("ip", "changed"); vRoot.SetValue("vp", "changed.de", "de"); vRoot.SetValue("vp", "changed.ru", "ru"); vRoot.SetValue("vp", "changed.es", "es"); - ServiceContext.ContentService.Save(vRoot); //now there's drafts in all cultures + ServiceContext.ContentService.Save(vRoot); // now root has drafts in all cultures + iv1.PublishCulture("de"); iv1.PublishCulture("ru"); - ServiceContext.ContentService.SavePublishing(iv1); + ServiceContext.ContentService.SavePublishing(iv1); // now iv1 de and ru are published + iv1.SetValue("ip", "changed"); iv1.SetValue("vp", "changed.de", "de"); iv1.SetValue("vp", "changed.ru", "ru"); iv1.SetValue("vp", "changed.es", "es"); - ServiceContext.ContentService.Save(iv1); + ServiceContext.ContentService.Save(iv1); // now iv1 has drafts in all cultures - // validate + // validate - everything published for root, because no culture was specified = all Assert.IsTrue(vRoot.Published); - Assert.IsTrue(vRoot.IsCulturePublished("de")); //all cultures are published because "*" was specified - Assert.IsTrue(vRoot.IsCulturePublished("ru")); //all cultures are published because "*" was specified - Assert.IsTrue(vRoot.IsCulturePublished("es")); //all cultures are published because "*" was specified + Assert.IsTrue(vRoot.IsCulturePublished("de")); + Assert.IsTrue(vRoot.IsCulturePublished("ru")); + Assert.IsTrue(vRoot.IsCulturePublished("es")); + + // validate - only some cultures published for iv1 Assert.IsTrue(iv1.Published); Assert.IsTrue(iv1.IsCulturePublished("de")); Assert.IsTrue(iv1.IsCulturePublished("ru")); @@ -300,19 +303,19 @@ namespace Umbraco.Tests.Services Reload(ref iv1); Reload(ref iv2); - // de is published, ru and es have not been published + // validate - root Assert.IsTrue(vRoot.Published); Assert.IsTrue(vRoot.IsCulturePublished("de")); - Assert.IsFalse(vRoot.IsCultureEdited("de")); //no drafts, this was just published + Assert.IsFalse(vRoot.IsCultureEdited("de")); // no drafts, this was just published Assert.IsTrue(vRoot.IsCulturePublished("ru")); - Assert.IsTrue(vRoot.IsCultureEdited("ru")); //has draft + Assert.IsTrue(vRoot.IsCultureEdited("ru")); // has draft Assert.IsTrue(vRoot.IsCulturePublished("es")); - Assert.IsTrue(vRoot.IsCultureEdited("es")); //has draft + Assert.IsTrue(vRoot.IsCultureEdited("es")); // has draft Assert.AreEqual("changed", vRoot.GetValue("ip", published: true)); // publishing de implies publishing invariants Assert.AreEqual("changed.de", vRoot.GetValue("vp", "de", published: true)); - // de and ru are published, es has not been published + // validate - de and ru are published, es has not been published Assert.IsTrue(iv1.Published); Assert.IsTrue(iv1.IsCulturePublished("de")); Assert.IsTrue(iv1.IsCulturePublished("ru")); @@ -320,7 +323,6 @@ namespace Umbraco.Tests.Services Assert.AreEqual("changed", iv1.GetValue("ip", published: true)); Assert.AreEqual("changed.de", iv1.GetValue("vp", "de", published: true)); Assert.AreEqual("iv1.ru", iv1.GetValue("vp", "ru", published: true)); - } [Test]