@@ -1140,6 +1140,8 @@ public PublishResult Publish(IContent content, string[] cultures, int userId = C
11401140 throw new ArgumentException ( "Cultures cannot be null or whitespace" , nameof ( cultures ) ) ;
11411141 }
11421142
1143+ EventMessages evtMsgs = EventMessagesFactory . Get ( ) ;
1144+
11431145 // we need to guard against unsaved changes before proceeding; the content will be saved, but we're not firing any saved notifications
11441146 if ( HasUnsavedChanges ( content ) )
11451147 {
@@ -1186,8 +1188,6 @@ public PublishResult Publish(IContent content, string[] cultures, int userId = C
11861188
11871189 var allLangs = _languageRepository . GetMany ( ) . ToList ( ) ;
11881190
1189- EventMessages evtMsgs = EventMessagesFactory . Get ( ) ;
1190-
11911191 // this will create the correct culture impact even if culture is * or null
11921192 IEnumerable < CultureImpact ? > impacts =
11931193 cultures . Select ( culture => _cultureImpactFactory . Create ( culture , IsDefaultCulture ( allLangs , culture ) , content ) ) ;
@@ -1199,7 +1199,15 @@ public PublishResult Publish(IContent content, string[] cultures, int userId = C
11991199 content . PublishCulture ( impact ) ;
12001200 }
12011201
1202- PublishResult result = CommitDocumentChangesInternal ( scope , content , evtMsgs , allLangs , userId , out _ ) ;
1202+ // Change state to publishing
1203+ content . PublishedState = PublishedState . Publishing ;
1204+ var publishingNotification = new ContentPublishingNotification ( content , evtMsgs ) ;
1205+ if ( scope . Notifications . PublishCancelable ( publishingNotification ) )
1206+ {
1207+ return new PublishResult ( PublishResultType . FailedPublishCancelledByEvent , evtMsgs , content ) ;
1208+ }
1209+
1210+ PublishResult result = CommitDocumentChangesInternal ( scope , content , evtMsgs , allLangs , publishingNotification . State , userId ) ;
12031211 scope . Complete ( ) ;
12041212 return result ;
12051213 }
@@ -1254,6 +1262,12 @@ public PublishResult Unpublish(IContent content, string? culture = "*", int user
12541262
12551263 var allLangs = _languageRepository . GetMany ( ) . ToList ( ) ;
12561264
1265+ var savingNotification = new ContentSavingNotification ( content , evtMsgs ) ;
1266+ if ( scope . Notifications . PublishCancelable ( savingNotification ) )
1267+ {
1268+ return new PublishResult ( PublishResultType . FailedPublishCancelledByEvent , evtMsgs , content ) ;
1269+ }
1270+
12571271 // all cultures = unpublish whole
12581272 if ( culture == "*" || ( ! content . ContentType . VariesByCulture ( ) && culture == null ) )
12591273 {
@@ -1262,7 +1276,7 @@ public PublishResult Unpublish(IContent content, string? culture = "*", int user
12621276 // We are however unpublishing all cultures, so we will set this to unpublishing.
12631277 content . UnpublishCulture ( culture ) ;
12641278 content . PublishedState = PublishedState . Unpublishing ;
1265- PublishResult result = CommitDocumentChangesInternal ( scope , content , evtMsgs , allLangs , userId , out _ ) ;
1279+ PublishResult result = CommitDocumentChangesInternal ( scope , content , evtMsgs , allLangs , savingNotification . State , userId ) ;
12661280 scope . Complete ( ) ;
12671281 return result ;
12681282 }
@@ -1276,7 +1290,7 @@ public PublishResult Unpublish(IContent content, string? culture = "*", int user
12761290 var removed = content . UnpublishCulture ( culture ) ;
12771291
12781292 // Save and publish any changes
1279- PublishResult result = CommitDocumentChangesInternal ( scope , content , evtMsgs , allLangs , userId , out _ ) ;
1293+ PublishResult result = CommitDocumentChangesInternal ( scope , content , evtMsgs , allLangs , savingNotification . State , userId ) ;
12801294
12811295 scope . Complete ( ) ;
12821296
@@ -1327,9 +1341,15 @@ internal PublishResult CommitDocumentChanges(IContent content, int userId = Cons
13271341
13281342 scope . WriteLock ( Constants . Locks . ContentTree ) ;
13291343
1344+ var savingNotification = new ContentSavingNotification ( content , evtMsgs ) ;
1345+ if ( scope . Notifications . PublishCancelable ( savingNotification ) )
1346+ {
1347+ return new PublishResult ( PublishResultType . FailedPublishCancelledByEvent , evtMsgs , content ) ;
1348+ }
1349+
13301350 var allLangs = _languageRepository . GetMany ( ) . ToList ( ) ;
13311351
1332- PublishResult result = CommitDocumentChangesInternal ( scope , content , evtMsgs , allLangs , userId , out _ ) ;
1352+ PublishResult result = CommitDocumentChangesInternal ( scope , content , evtMsgs , allLangs , savingNotification . State , userId ) ;
13331353 scope . Complete ( ) ;
13341354 return result ;
13351355 }
@@ -1359,8 +1379,8 @@ private PublishResult CommitDocumentChangesInternal(
13591379 IContent content ,
13601380 EventMessages eventMessages ,
13611381 IReadOnlyCollection < ILanguage > allLangs ,
1382+ IDictionary < string , object ? > ? notificationState ,
13621383 int userId ,
1363- out IDictionary < string , object ? > ? initialNotificationState ,
13641384 bool branchOne = false ,
13651385 bool branchRoot = false )
13661386 {
@@ -1422,7 +1442,6 @@ void SaveDocument(IContent c)
14221442 _documentRepository . Save ( c ) ;
14231443 }
14241444
1425- initialNotificationState = null ;
14261445 if ( publishing )
14271446 {
14281447 // Determine cultures publishing/unpublishing which will be based on previous calls to content.PublishCulture and ClearPublishInfo
@@ -1440,9 +1459,18 @@ void SaveDocument(IContent c)
14401459 culturesUnpublishing ,
14411460 eventMessages ,
14421461 allLangs ,
1443- out initialNotificationState ) ;
1462+ notificationState ) ;
1463+
14441464 if ( publishResult . Success )
14451465 {
1466+ // raise Publishing notification
1467+ if ( scope . Notifications . PublishCancelable (
1468+ new ContentPublishingNotification ( content , eventMessages ) . WithState ( notificationState ) ) )
1469+ {
1470+ _logger . LogInformation ( "Document {ContentName} (id={ContentId}) cannot be published: {Reason}" , content . Name , content . Id , "publishing was cancelled" ) ;
1471+ return new PublishResult ( PublishResultType . FailedPublishCancelledByEvent , eventMessages , content ) ;
1472+ }
1473+
14461474 // note: StrategyPublish flips the PublishedState to Publishing!
14471475 publishResult = StrategyPublish ( content , culturesPublishing , culturesUnpublishing , eventMessages ) ;
14481476
@@ -1503,7 +1531,7 @@ void SaveDocument(IContent c)
15031531 // handling events, business rules, etc
15041532 // note: StrategyUnpublish flips the PublishedState to Unpublishing!
15051533 // note: This unpublishes the entire document (not different variants)
1506- unpublishResult = StrategyCanUnpublish ( scope , content , eventMessages , out initialNotificationState ) ;
1534+ unpublishResult = StrategyCanUnpublish ( scope , content , eventMessages , notificationState ) ;
15071535 if ( unpublishResult . Success )
15081536 {
15091537 unpublishResult = StrategyUnpublish ( content , eventMessages ) ;
@@ -1539,7 +1567,7 @@ void SaveDocument(IContent c)
15391567 {
15401568 // events and audit
15411569 scope . Notifications . Publish (
1542- new ContentUnpublishedNotification ( content , eventMessages ) . WithState ( initialNotificationState ) ) ;
1570+ new ContentUnpublishedNotification ( content , eventMessages ) . WithState ( notificationState ) ) ;
15431571 scope . Notifications . Publish ( new ContentTreeChangeNotification ( content , TreeChangeTypes . RefreshBranch , eventMessages ) ) ;
15441572
15451573 if ( culturesUnpublishing != null )
@@ -1601,7 +1629,7 @@ void SaveDocument(IContent c)
16011629 scope . Notifications . Publish (
16021630 new ContentTreeChangeNotification ( content , changeType , eventMessages ) ) ;
16031631 scope . Notifications . Publish (
1604- new ContentPublishedNotification ( content , eventMessages ) . WithState ( initialNotificationState ) ) ;
1632+ new ContentPublishedNotification ( content , eventMessages ) . WithState ( notificationState ) ) ;
16051633 }
16061634
16071635 // it was not published and now is... descendants that were 'published' (but
@@ -1611,7 +1639,7 @@ void SaveDocument(IContent c)
16111639 {
16121640 IContent [ ] descendants = GetPublishedDescendantsLocked ( content ) . ToArray ( ) ;
16131641 scope . Notifications . Publish (
1614- new ContentPublishedNotification ( descendants , eventMessages ) . WithState ( initialNotificationState ) ) ;
1642+ new ContentPublishedNotification ( descendants , eventMessages ) . WithState ( notificationState ) ) ;
16151643 }
16161644
16171645 switch ( publishResult . Result )
@@ -1711,6 +1739,13 @@ private void PerformScheduledPublishingExpiration(DateTime date, List<PublishRes
17111739 continue ; // shouldn't happen but no point in processing this document if there's nothing there
17121740 }
17131741
1742+ var savingNotification = new ContentSavingNotification ( d , evtMsgs ) ;
1743+ if ( scope . Notifications . PublishCancelable ( savingNotification ) )
1744+ {
1745+ results . Add ( new PublishResult ( PublishResultType . FailedPublishCancelledByEvent , evtMsgs , d ) ) ;
1746+ continue ;
1747+ }
1748+
17141749 foreach ( var c in pendingCultures )
17151750 {
17161751 // Clear this schedule for this culture
@@ -1721,7 +1756,7 @@ private void PerformScheduledPublishingExpiration(DateTime date, List<PublishRes
17211756 }
17221757
17231758 _documentRepository . PersistContentSchedule ( d , contentSchedule ) ;
1724- PublishResult result = CommitDocumentChangesInternal ( scope , d , evtMsgs , allLangs . Value , d . WriterId , out _ ) ;
1759+ PublishResult result = CommitDocumentChangesInternal ( scope , d , evtMsgs , allLangs . Value , savingNotification . State , d . WriterId ) ;
17251760 if ( result . Success == false )
17261761 {
17271762 _logger . LogError ( null , "Failed to publish document id={DocumentId}, reason={Reason}." , d . Id , result . Result ) ;
@@ -1775,6 +1810,13 @@ private void PerformScheduledPublishingRelease(DateTime date, List<PublishResult
17751810 {
17761811 continue ; // shouldn't happen but no point in processing this document if there's nothing there
17771812 }
1813+ var savingNotification = new ContentSavingNotification ( d , evtMsgs ) ;
1814+ if ( scope . Notifications . PublishCancelable ( savingNotification ) )
1815+ {
1816+ results . Add ( new PublishResult ( PublishResultType . FailedPublishCancelledByEvent , evtMsgs , d ) ) ;
1817+ continue ;
1818+ }
1819+
17781820
17791821 var publishing = true ;
17801822 foreach ( var culture in pendingCultures )
@@ -1820,7 +1862,7 @@ private void PerformScheduledPublishingRelease(DateTime date, List<PublishResult
18201862 else
18211863 {
18221864 _documentRepository . PersistContentSchedule ( d , contentSchedule ) ;
1823- result = CommitDocumentChangesInternal ( scope , d , evtMsgs , allLangs . Value , d . WriterId , out _ ) ;
1865+ result = CommitDocumentChangesInternal ( scope , d , evtMsgs , allLangs . Value , savingNotification . State , d . WriterId ) ;
18241866 }
18251867
18261868 if ( result . Success == false )
@@ -2162,14 +2204,20 @@ internal IEnumerable<PublishResult> PublishBranch(
21622204 return new PublishResult ( PublishResultType . SuccessPublishAlready , evtMsgs , document ) ;
21632205 }
21642206
2207+ var savingNotification = new ContentSavingNotification ( document , evtMsgs ) ;
2208+ if ( scope . Notifications . PublishCancelable ( savingNotification ) )
2209+ {
2210+ return new PublishResult ( PublishResultType . FailedPublishCancelledByEvent , evtMsgs , document ) ;
2211+ }
2212+
21652213 // publish & check if values are valid
21662214 if ( ! publishCultures ( document , culturesToPublish , allLangs ) )
21672215 {
21682216 // TODO: Based on this callback behavior there is no way to know which properties may have been invalid if this failed, see other results of FailedPublishContentInvalid
21692217 return new PublishResult ( PublishResultType . FailedPublishContentInvalid , evtMsgs , document ) ;
21702218 }
21712219
2172- PublishResult result = CommitDocumentChangesInternal ( scope , document , evtMsgs , allLangs , userId , out initialNotificationState , true , isRoot ) ;
2220+ PublishResult result = CommitDocumentChangesInternal ( scope , document , evtMsgs , allLangs , savingNotification . State , userId , true , isRoot ) ;
21732221 if ( result . Success )
21742222 {
21752223 publishedDocuments . Add ( document ) ;
@@ -3018,19 +3066,8 @@ private PublishResult StrategyCanPublish(
30183066 IReadOnlyCollection < string > ? culturesUnpublishing ,
30193067 EventMessages evtMsgs ,
30203068 IReadOnlyCollection < ILanguage > allLangs ,
3021- out IDictionary < string , object ? > ? initialNotificationState )
3069+ IDictionary < string , object ? > ? notificationState )
30223070 {
3023- // raise Publishing notification
3024- var notification = new ContentPublishingNotification ( content , evtMsgs ) ;
3025- var notificationResult = scope . Notifications . PublishCancelable ( notification ) ;
3026- initialNotificationState = notification . State ;
3027-
3028- if ( notificationResult )
3029- {
3030- _logger . LogInformation ( "Document {ContentName} (id={ContentId}) cannot be published: {Reason}" , content . Name , content . Id , "publishing was cancelled" ) ;
3031- return new PublishResult ( PublishResultType . FailedPublishCancelledByEvent , evtMsgs , content ) ;
3032- }
3033-
30343071 var variesByCulture = content . ContentType . VariesByCulture ( ) ;
30353072
30363073 // If it's null it's invariant
@@ -3268,12 +3305,11 @@ private PublishResult StrategyCanUnpublish(
32683305 ICoreScope scope ,
32693306 IContent content ,
32703307 EventMessages evtMsgs ,
3271- out IDictionary < string , object ? > ? initialNotificationState )
3308+ IDictionary < string , object ? > ? notificationState )
32723309 {
32733310 // raise Unpublishing notification
3274- var notification = new ContentUnpublishingNotification ( content , evtMsgs ) ;
3311+ var notification = new ContentUnpublishingNotification ( content , evtMsgs ) . WithState ( notificationState ) ;
32753312 var notificationResult = scope . Notifications . PublishCancelable ( notification ) ;
3276- initialNotificationState = notification . State ;
32773313
32783314 if ( notificationResult )
32793315 {
0 commit comments