diff --git a/Neos.ContentRepository.BehavioralTests/Tests/Behavior/Features/W10-IndividualNodeDiscarding/02-BasicFeatures.feature b/Neos.ContentRepository.BehavioralTests/Tests/Behavior/Features/W10-IndividualNodeDiscarding/02-BasicFeatures.feature index fa81a2fc56f..8591753b47e 100644 --- a/Neos.ContentRepository.BehavioralTests/Tests/Behavior/Features/W10-IndividualNodeDiscarding/02-BasicFeatures.feature +++ b/Neos.ContentRepository.BehavioralTests/Tests/Behavior/Features/W10-IndividualNodeDiscarding/02-BasicFeatures.feature @@ -106,6 +106,7 @@ Feature: Discard individual nodes (basics) | workspaceName | "user-test" | | newContentStreamId | "user-cs-identifier-new" | | previousContentStreamId | "user-cs-identifier" | + | partial | true | When I am in workspace "user-test" and dimension space point {} Then I expect node aggregate identifier "sir-david-nodenborough" to lead to node user-cs-identifier-new;sir-david-nodenborough;{} @@ -172,6 +173,7 @@ Feature: Discard individual nodes (basics) | workspaceName | "user-test" | | newContentStreamId | "user-cs-identifier-new" | | previousContentStreamId | "user-cs-identifier" | + | partial | false | When I am in workspace "user-test" and dimension space point {} Then I expect node aggregate identifier "sir-david-nodenborough" to lead to node user-cs-identifier-new;sir-david-nodenborough;{} diff --git a/Neos.ContentRepository.BehavioralTests/Tests/Behavior/Features/W7-WorkspacePublication/02-PublishWorkspace.feature b/Neos.ContentRepository.BehavioralTests/Tests/Behavior/Features/W7-WorkspacePublication/02-PublishWorkspace.feature index 43372bfcad3..b1fb6e65855 100644 --- a/Neos.ContentRepository.BehavioralTests/Tests/Behavior/Features/W7-WorkspacePublication/02-PublishWorkspace.feature +++ b/Neos.ContentRepository.BehavioralTests/Tests/Behavior/Features/W7-WorkspacePublication/02-PublishWorkspace.feature @@ -95,8 +95,19 @@ Feature: Workspace based content publishing When the command PublishWorkspace is executed with payload: | Key | Value | | workspaceName | "user-test" | + | newContentStreamId | "user-cs-new" | + Then I expect the content stream "user-cs-identifier" to not exist + Then I expect exactly 2 events to be published on stream with prefix "Workspace:user-test" + And event at index 1 is of type "WorkspaceWasPublished" with payload: + | Key | Expected | + | sourceWorkspaceName | "user-test" | + | targetWorkspaceName | "live" | + | newSourceContentStreamId | "user-cs-new" | + | previousSourceContentStreamId | "user-cs-identifier" | + | partial | false | + When I am in workspace "live" and dimension space point {} Then I expect node aggregate identifier "nody-mc-nodeface" to lead to node cs-identifier;nody-mc-nodeface;{} And I expect this node to have the following properties: diff --git a/Neos.ContentRepository.BehavioralTests/Tests/Behavior/Features/W8-IndividualNodePublication/02-BasicFeatures.feature b/Neos.ContentRepository.BehavioralTests/Tests/Behavior/Features/W8-IndividualNodePublication/02-BasicFeatures.feature index befd11ea2fc..fb1cb45054b 100644 --- a/Neos.ContentRepository.BehavioralTests/Tests/Behavior/Features/W8-IndividualNodePublication/02-BasicFeatures.feature +++ b/Neos.ContentRepository.BehavioralTests/Tests/Behavior/Features/W8-IndividualNodePublication/02-BasicFeatures.feature @@ -64,6 +64,7 @@ Feature: Individual node publication | targetWorkspaceName | "live" | | newSourceContentStreamId | "user-cs-identifier-remaining" | | previousSourceContentStreamId | "user-cs-identifier" | + | partial | true | And I am in workspace "live" diff --git a/Neos.ContentRepository.BehavioralTests/Tests/Behavior/Features/W8-IndividualNodePublication/03-MoreBasicFeatures.feature b/Neos.ContentRepository.BehavioralTests/Tests/Behavior/Features/W8-IndividualNodePublication/03-MoreBasicFeatures.feature index 6935df04575..cc0cc931a40 100644 --- a/Neos.ContentRepository.BehavioralTests/Tests/Behavior/Features/W8-IndividualNodePublication/03-MoreBasicFeatures.feature +++ b/Neos.ContentRepository.BehavioralTests/Tests/Behavior/Features/W8-IndividualNodePublication/03-MoreBasicFeatures.feature @@ -218,6 +218,7 @@ Feature: Publishing individual nodes (basics) | targetWorkspaceName | "live" | | newSourceContentStreamId | "user-cs-identifier-remaining" | | previousSourceContentStreamId | "user-cs-identifier" | + | partial | false | When I am in workspace "live" and dimension space point {} Then I expect node aggregate identifier "sir-david-nodenborough" to lead to node cs-identifier;sir-david-nodenborough;{} diff --git a/Neos.ContentRepository.BehavioralTests/Tests/Behavior/Features/W9-WorkspaceDiscarding/02-DiscardWorkspace.feature b/Neos.ContentRepository.BehavioralTests/Tests/Behavior/Features/W9-WorkspaceDiscarding/02-DiscardWorkspace.feature index 158cd4dabb5..67aecf8f51d 100644 --- a/Neos.ContentRepository.BehavioralTests/Tests/Behavior/Features/W9-WorkspaceDiscarding/02-DiscardWorkspace.feature +++ b/Neos.ContentRepository.BehavioralTests/Tests/Behavior/Features/W9-WorkspaceDiscarding/02-DiscardWorkspace.feature @@ -65,6 +65,14 @@ Feature: Workspace discarding - basic functionality | newContentStreamId | "user-cs-identifier-modified" | Then I expect the content stream "user-cs-identifier" to not exist + Then I expect exactly 2 events to be published on stream with prefix "Workspace:user-test" + And event at index 1 is of type "WorkspaceWasDiscarded" with payload: + | Key | Expected | + | workspaceName | "user-test" | + | newContentStreamId | "user-cs-identifier-modified" | + | previousContentStreamId | "user-cs-identifier" | + | partial | false | + When I am in workspace "user-test" and dimension space point {} Then I expect node aggregate identifier "nody-mc-nodeface" to lead to node user-cs-identifier-modified;nody-mc-nodeface;{} And I expect this node to have the following properties: diff --git a/Neos.ContentRepository.Core/Classes/Feature/WorkspaceCommandHandler.php b/Neos.ContentRepository.Core/Classes/Feature/WorkspaceCommandHandler.php index f9dae23bde5..abb65c4c824 100644 --- a/Neos.ContentRepository.Core/Classes/Feature/WorkspaceCommandHandler.php +++ b/Neos.ContentRepository.Core/Classes/Feature/WorkspaceCommandHandler.php @@ -260,6 +260,7 @@ static function ($handle) use ($rebaseableCommands): void { $baseWorkspace->workspaceName, $command->newContentStreamId, $workspace->currentContentStreamId, + partial: false ) ), ExpectedVersion::ANY() @@ -517,6 +518,7 @@ static function ($handle) use ($commandSimulator, $matchingCommands, $remainingC $baseWorkspace->workspaceName, $command->contentStreamIdForRemainingPart, $workspace->currentContentStreamId, + partial: !$remainingCommands->isEmpty() ) ]), ExpectedVersion::ANY() @@ -622,6 +624,7 @@ static function ($handle) use ($commandsToKeep): void { $command->workspaceName, $command->newContentStreamId, $workspace->currentContentStreamId, + partial: true ) ), ExpectedVersion::ANY() @@ -685,6 +688,7 @@ private function discardWorkspace( $workspace->workspaceName, $newContentStream, $workspace->currentContentStreamId, + partial: false ) ), ExpectedVersion::ANY() diff --git a/Neos.ContentRepository.Core/Classes/Feature/WorkspacePublication/Event/WorkspaceWasDiscarded.php b/Neos.ContentRepository.Core/Classes/Feature/WorkspacePublication/Event/WorkspaceWasDiscarded.php index 35b2a6bd321..c043ebe882d 100644 --- a/Neos.ContentRepository.Core/Classes/Feature/WorkspacePublication/Event/WorkspaceWasDiscarded.php +++ b/Neos.ContentRepository.Core/Classes/Feature/WorkspacePublication/Event/WorkspaceWasDiscarded.php @@ -34,6 +34,10 @@ public function __construct( * The old content stream (which contains the discarded data) */ public ContentStreamId $previousContentStreamId, + /** + * Indicates if all events in the workspace have been discarded or if remaining changes are reapplied + */ + public bool $partial ) { } @@ -48,15 +52,12 @@ public static function fromArray(array $values): self WorkspaceName::fromString($values['workspaceName']), ContentStreamId::fromString($values['newContentStreamId']), ContentStreamId::fromString($values['previousContentStreamId']), + $values['partial'] ?? false ); } public function jsonSerialize(): array { - return [ - 'workspaceName' => $this->workspaceName, - 'newContentStreamId' => $this->newContentStreamId, - 'previousContentStreamId' => $this->previousContentStreamId, - ]; + return get_object_vars($this); } } diff --git a/Neos.ContentRepository.Core/Classes/Feature/WorkspacePublication/Event/WorkspaceWasPartiallyDiscarded.php b/Neos.ContentRepository.Core/Classes/Feature/WorkspacePublication/Event/WorkspaceWasPartiallyDiscarded.php index 3d9d08c7e93..3748848a7c8 100644 --- a/Neos.ContentRepository.Core/Classes/Feature/WorkspacePublication/Event/WorkspaceWasPartiallyDiscarded.php +++ b/Neos.ContentRepository.Core/Classes/Feature/WorkspacePublication/Event/WorkspaceWasPartiallyDiscarded.php @@ -35,6 +35,7 @@ public static function fromArray(array $values): EventInterface WorkspaceName::fromString($values['workspaceName']), ContentStreamId::fromString($values['newContentStreamId']), ContentStreamId::fromString($values['previousContentStreamId']), + partial: true ); } diff --git a/Neos.ContentRepository.Core/Classes/Feature/WorkspacePublication/Event/WorkspaceWasPartiallyPublished.php b/Neos.ContentRepository.Core/Classes/Feature/WorkspacePublication/Event/WorkspaceWasPartiallyPublished.php index 71ba41232fc..8c69c49b22c 100644 --- a/Neos.ContentRepository.Core/Classes/Feature/WorkspacePublication/Event/WorkspaceWasPartiallyPublished.php +++ b/Neos.ContentRepository.Core/Classes/Feature/WorkspacePublication/Event/WorkspaceWasPartiallyPublished.php @@ -36,6 +36,7 @@ public static function fromArray(array $values): EventInterface WorkspaceName::fromString($values['targetWorkspaceName']), ContentStreamId::fromString($values['newSourceContentStreamId']), ContentStreamId::fromString($values['previousSourceContentStreamId']), + partial: true ); } diff --git a/Neos.ContentRepository.Core/Classes/Feature/WorkspacePublication/Event/WorkspaceWasPublished.php b/Neos.ContentRepository.Core/Classes/Feature/WorkspacePublication/Event/WorkspaceWasPublished.php index b4919821a59..7aae6d5be78 100644 --- a/Neos.ContentRepository.Core/Classes/Feature/WorkspacePublication/Event/WorkspaceWasPublished.php +++ b/Neos.ContentRepository.Core/Classes/Feature/WorkspacePublication/Event/WorkspaceWasPublished.php @@ -39,7 +39,11 @@ public function __construct( /** * The old content stream ID of $sourceWorkspaceName (which is not active anymore now) */ - public ContentStreamId $previousSourceContentStreamId + public ContentStreamId $previousSourceContentStreamId, + /** + * Indicates if all events in the workspace have been published or if remaining changes are reapplied + */ + public bool $partial ) { } @@ -50,6 +54,7 @@ public static function fromArray(array $values): self WorkspaceName::fromString($values['targetWorkspaceName']), ContentStreamId::fromString($values['newSourceContentStreamId']), ContentStreamId::fromString($values['previousSourceContentStreamId']), + $values['partial'] ?? false, ); }