diff --git a/src/Umbraco.Core/Services/ContentService.cs b/src/Umbraco.Core/Services/ContentService.cs index 1d8811ba5017..e9d0f8f4fd15 100644 --- a/src/Umbraco.Core/Services/ContentService.cs +++ b/src/Umbraco.Core/Services/ContentService.cs @@ -1950,7 +1950,7 @@ private bool SaveAndPublishBranch_PublishCultures(IContent content, HashSet(); // empty means 'already published' } - if (edited) + if (isRoot || edited) { cultures.Add(c); // means 'republish this culture' } @@ -2105,11 +2105,13 @@ internal IEnumerable SaveAndPublishBranch( } // deal with the branch root - if it fails, abort - PublishResult? result = SaveAndPublishBranchItem(scope, document, shouldPublish, publishCultures, true, publishedDocuments, eventMessages, userId, allLangs); - if (result != null) + var rootPublishNotificationState = new Dictionary(); + PublishResult? rootResult = SaveAndPublishBranchItem(scope, document, shouldPublish, publishCultures, true, + publishedDocuments, eventMessages, userId, allLangs, rootPublishNotificationState); + if (rootResult != null) { - results.Add(result); - if (!result.Success) + results.Add(rootResult); + if (!rootResult.Success) { return results; } @@ -2122,6 +2124,7 @@ internal IEnumerable SaveAndPublishBranch( int count; var page = 0; const int pageSize = 100; + PublishResult? result = null; do { count = 0; @@ -2140,7 +2143,8 @@ internal IEnumerable SaveAndPublishBranch( } // no need to check path here, parent has to be published here - result = SaveAndPublishBranchItem(scope, d, shouldPublish, publishCultures, false, publishedDocuments, eventMessages, userId, allLangs); + result = SaveAndPublishBranchItem(scope, d, shouldPublish, publishCultures, false, + publishedDocuments, eventMessages, userId, allLangs,null); if (result != null) { results.Add(result); @@ -2164,7 +2168,12 @@ internal IEnumerable SaveAndPublishBranch( // (SaveAndPublishBranchOne does *not* do it) scope.Notifications.Publish( new ContentTreeChangeNotification(document, TreeChangeTypes.RefreshBranch, eventMessages)); - scope.Notifications.Publish(new ContentPublishedNotification(publishedDocuments, eventMessages)); + if (rootResult?.Success is true) + { + scope.Notifications.Publish( + new ContentPublishedNotification(rootResult!.Content!, eventMessages) + .WithState(rootPublishNotificationState)); + } scope.Complete(); } @@ -2175,6 +2184,9 @@ internal IEnumerable SaveAndPublishBranch( // shouldPublish: a function determining whether the document has changes that need to be published // note - 'force' is handled by 'editing' // publishValues: a function publishing values (using the appropriate PublishCulture calls) + /// Only set this when processing a the root of the branch + /// Published notification will not be send when this property is set + /// private PublishResult? SaveAndPublishBranchItem( ICoreScope scope, IContent document, @@ -2185,7 +2197,8 @@ internal IEnumerable SaveAndPublishBranch( ICollection publishedDocuments, EventMessages evtMsgs, int userId, - IReadOnlyCollection allLangs) + IReadOnlyCollection allLangs, + IDictionary? rootPublishingNotificationState) { HashSet? culturesToPublish = shouldPublish(document); @@ -2214,10 +2227,17 @@ internal IEnumerable SaveAndPublishBranch( return new PublishResult(PublishResultType.FailedPublishContentInvalid, evtMsgs, document); } - PublishResult result = CommitDocumentChangesInternal(scope, document, evtMsgs, allLangs, savingNotification.State, userId, true, isRoot); - if (result.Success) + var notificationState = rootPublishingNotificationState ?? new Dictionary(); + PublishResult result = CommitDocumentChangesInternal(scope, document, evtMsgs, allLangs, notificationState, userId, true, isRoot); + if (!result.Success) + { + return result; + } + + publishedDocuments.Add(document); + if (rootPublishingNotificationState == null) { - publishedDocuments.Add(document); + scope.Notifications.Publish(new ContentPublishedNotification(result.Content!, evtMsgs).WithState(notificationState)); } return result; diff --git a/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentServicePublishBranchTests.cs b/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentServicePublishBranchTests.cs index e5ef5789db3a..f6e6aaf0a789 100644 --- a/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentServicePublishBranchTests.cs +++ b/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentServicePublishBranchTests.cs @@ -91,7 +91,7 @@ public void Can_Publish_Invariant_Branch(int method) AssertPublishResults( r, x => x.Result, - PublishResultType.SuccessPublishAlready, + PublishResultType.SuccessPublish, // During branch publishing, the change detection of the root branch runs AFTER the check to process the branchItem => root is always saved&Published as the intent requires it. PublishResultType.SuccessPublishAlready, PublishResultType.SuccessPublishAlready); @@ -138,7 +138,7 @@ public void Can_Publish_Invariant_Branch(int method) AssertPublishResults( r, x => x.Result, - PublishResultType.SuccessPublishAlready, + PublishResultType.SuccessPublish, // During branch publishing, the change detection of the root branch runs AFTER the check to process the branchItem => root is always saved&Published as the intent requires it. PublishResultType.SuccessPublishAlready, PublishResultType.SuccessPublishAlready, PublishResultType.SuccessPublish, @@ -183,7 +183,7 @@ public void Can_Publish_Variant_Branch_When_No_Changes_On_Root_All_Cultures() var r = ContentService.SaveAndPublishBranch(vRoot, false) .ToArray(); // no culture specified so "*" is used, so all cultures - Assert.AreEqual(PublishResultType.SuccessPublishAlready, r[0].Result); + Assert.AreEqual(PublishResultType.SuccessPublishCulture, r[0].Result); // During branch publishing, the change detection of the root branch runs AFTER the check to process the branchItem => root is always saved&Published as the intent requires it. Assert.AreEqual(PublishResultType.SuccessPublishCulture, r[1].Result); } @@ -219,7 +219,7 @@ public void Can_Publish_Variant_Branch_When_No_Changes_On_Root_Specific_Culture( var saveResult = ContentService.Save(iv1); var r = ContentService.SaveAndPublishBranch(vRoot, false, "de").ToArray(); - Assert.AreEqual(PublishResultType.SuccessPublishAlready, r[0].Result); + Assert.AreEqual(PublishResultType.SuccessPublishCulture, r[0].Result); // During branch publishing, the change detection of the root branch runs AFTER the check to process the branchItem => root is always saved&Published as the intent requires it. Assert.AreEqual(PublishResultType.SuccessPublishCulture, r[1].Result); } @@ -379,7 +379,7 @@ public void Can_Publish_Mixed_Branch_1() AssertPublishResults( r, x => x.Result, - PublishResultType.SuccessPublishAlready, + PublishResultType.SuccessPublish, // During branch publishing, the change detection of the root branch runs AFTER the check to process the branchItem => root is always saved&Published as the intent requires it. PublishResultType.SuccessPublish, PublishResultType.SuccessPublishCulture); @@ -405,7 +405,7 @@ public void Can_Publish_MixedBranch_2() AssertPublishResults( r, x => x.Result, - PublishResultType.SuccessPublishAlready, + PublishResultType.SuccessPublish, // During branch publishing, the change detection of the root branch runs AFTER the check to process the branchItem => root is always saved&Published as the intent requires it. PublishResultType.SuccessPublish, PublishResultType.SuccessPublishCulture);