diff --git a/Neos.ContentGraph.DoctrineDbalAdapter/src/DoctrineDbalContentGraphProjection.php b/Neos.ContentGraph.DoctrineDbalAdapter/src/DoctrineDbalContentGraphProjection.php index 39186aa616f..28aef165b3f 100644 --- a/Neos.ContentGraph.DoctrineDbalAdapter/src/DoctrineDbalContentGraphProjection.php +++ b/Neos.ContentGraph.DoctrineDbalAdapter/src/DoctrineDbalContentGraphProjection.php @@ -56,8 +56,6 @@ use Neos\ContentRepository\Core\Feature\WorkspaceModification\Event\WorkspaceBaseWorkspaceWasChanged; use Neos\ContentRepository\Core\Feature\WorkspaceModification\Event\WorkspaceWasRemoved; use Neos\ContentRepository\Core\Feature\WorkspacePublication\Event\WorkspaceWasDiscarded; -use Neos\ContentRepository\Core\Feature\WorkspacePublication\Event\WorkspaceWasPartiallyDiscarded; -use Neos\ContentRepository\Core\Feature\WorkspacePublication\Event\WorkspaceWasPartiallyPublished; use Neos\ContentRepository\Core\Feature\WorkspacePublication\Event\WorkspaceWasPublished; use Neos\ContentRepository\Core\Feature\WorkspaceRebase\Event\WorkspaceRebaseFailed; use Neos\ContentRepository\Core\Feature\WorkspaceRebase\Event\WorkspaceWasRebased; @@ -196,8 +194,6 @@ public function canHandle(EventInterface $event): bool WorkspaceRebaseFailed::class, WorkspaceWasCreated::class, WorkspaceWasDiscarded::class, - WorkspaceWasPartiallyDiscarded::class, - WorkspaceWasPartiallyPublished::class, WorkspaceWasPublished::class, WorkspaceWasRebased::class, WorkspaceWasRemoved::class, @@ -233,8 +229,6 @@ public function apply(EventInterface $event, EventEnvelope $eventEnvelope): void WorkspaceRebaseFailed::class => $this->whenWorkspaceRebaseFailed($event), WorkspaceWasCreated::class => $this->whenWorkspaceWasCreated($event), WorkspaceWasDiscarded::class => $this->whenWorkspaceWasDiscarded($event), - WorkspaceWasPartiallyDiscarded::class => $this->whenWorkspaceWasPartiallyDiscarded($event), - WorkspaceWasPartiallyPublished::class => $this->whenWorkspaceWasPartiallyPublished($event), WorkspaceWasPublished::class => $this->whenWorkspaceWasPublished($event), WorkspaceWasRebased::class => $this->whenWorkspaceWasRebased($event), WorkspaceWasRemoved::class => $this->whenWorkspaceWasRemoved($event), @@ -774,16 +768,6 @@ private function whenWorkspaceWasDiscarded(WorkspaceWasDiscarded $event): void $this->updateWorkspaceContentStreamId($event->workspaceName, $event->newContentStreamId); } - private function whenWorkspaceWasPartiallyDiscarded(WorkspaceWasPartiallyDiscarded $event): void - { - $this->updateWorkspaceContentStreamId($event->workspaceName, $event->newContentStreamId); - } - - private function whenWorkspaceWasPartiallyPublished(WorkspaceWasPartiallyPublished $event): void - { - $this->updateWorkspaceContentStreamId($event->sourceWorkspaceName, $event->newSourceContentStreamId); - } - private function whenWorkspaceWasPublished(WorkspaceWasPublished $event): void { $this->updateWorkspaceContentStreamId($event->sourceWorkspaceName, $event->newSourceContentStreamId); diff --git a/Neos.ContentRepository.BehavioralTests/Tests/Behavior/Features/W10-IndividualNodeDiscarding/01-ConstraintChecks.feature b/Neos.ContentRepository.BehavioralTests/Tests/Behavior/Features/W10-IndividualNodeDiscarding/01-ConstraintChecks.feature index 0965e664d40..dab40e0c641 100644 --- a/Neos.ContentRepository.BehavioralTests/Tests/Behavior/Features/W10-IndividualNodeDiscarding/01-ConstraintChecks.feature +++ b/Neos.ContentRepository.BehavioralTests/Tests/Behavior/Features/W10-IndividualNodeDiscarding/01-ConstraintChecks.feature @@ -70,7 +70,7 @@ Feature: Workspace discarding - complex chained functionality When the command DiscardIndividualNodesFromWorkspace is executed with payload and exceptions are caught: | Key | Value | | workspaceName | "user-ws" | - | nodesToDiscard | [{"workspaceName": "user-ws", "dimensionSpacePoint": {"language": "en"}, "nodeAggregateId": "sir-david-nodenborough"}, {"workspaceName": "user-ws", "dimensionSpacePoint": {"language": "en"}, "nodeAggregateId": "sir-david-nodenborough"}] | + | nodesToDiscard | ["sir-david-nodenborough", "sir-david-nodenborough"] | | newContentStreamId | "user-cs-id-rebased" | Then the last command should have thrown the PartialWorkspaceRebaseFailed exception with: | SequenceNumber | Event | Exception | 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 94c2077c647..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 @@ -96,10 +96,18 @@ Feature: Discard individual nodes (basics) When the command DiscardIndividualNodesFromWorkspace is executed with payload: | Key | Value | | workspaceName | "user-test" | - | nodesToDiscard | [{"workspaceName": "user-test", "dimensionSpacePoint": {}, "nodeAggregateId": "sir-nodeward-nodington-iii"}] | + | nodesToDiscard | ["sir-nodeward-nodington-iii"] | | newContentStreamId | "user-cs-identifier-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 "WorkspaceWasDiscarded" with payload: + | Key | Expected | + | 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;{} And I expect this node to have the following properties: @@ -126,7 +134,7 @@ Feature: Discard individual nodes (basics) When the command DiscardIndividualNodesFromWorkspace is executed with payload: | Key | Value | | workspaceName | "user-test" | - | nodesToDiscard | [{"dimensionSpacePoint": {}, "nodeAggregateId": "non-existing-node"}, {"dimensionSpacePoint": {}, "nodeAggregateId": "sir-unchanged"}] | + | nodesToDiscard | ["non-existing-node", "sir-unchanged"] | | newContentStreamId | "user-cs-identifier-new-two" | # all nodes are still on the original user cs @@ -156,16 +164,16 @@ Feature: Discard individual nodes (basics) When the command DiscardIndividualNodesFromWorkspace is executed with payload: | Key | Value | | workspaceName | "user-test" | - | nodesToDiscard | [{"workspaceName": "user-test", "dimensionSpacePoint": {}, "nodeAggregateId": "sir-david-nodenborough"}, {"workspaceName": "user-test", "dimensionSpacePoint": {}, "nodeAggregateId": "nody-mc-nodeface"}, {"workspaceName": "user-test", "dimensionSpacePoint": {}, "nodeAggregateId": "sir-nodeward-nodington-iii"}] | + | nodesToDiscard | ["sir-david-nodenborough", "nody-mc-nodeface", "sir-nodeward-nodington-iii"] | | newContentStreamId | "user-cs-identifier-new" | - # when discarding all nodes we expect a full discard via WorkspaceWasDiscarded 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-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;{} @@ -186,7 +194,7 @@ Feature: Discard individual nodes (basics) When the command DiscardIndividualNodesFromWorkspace is executed with payload: | Key | Value | | workspaceName | "user-test" | - | nodesToDiscard | [{"workspaceName": "user-test", "dimensionSpacePoint": {}, "nodeAggregateId": "sir-nodeward-nodington-iii"}] | + | nodesToDiscard | ["sir-nodeward-nodington-iii"] | # live WS does not change because of a discard When I am in workspace "live" and dimension space point {} 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/01-ConstraintChecks.feature b/Neos.ContentRepository.BehavioralTests/Tests/Behavior/Features/W8-IndividualNodePublication/01-ConstraintChecks.feature index e21feac7c86..1eefc590c1d 100644 --- a/Neos.ContentRepository.BehavioralTests/Tests/Behavior/Features/W8-IndividualNodePublication/01-ConstraintChecks.feature +++ b/Neos.ContentRepository.BehavioralTests/Tests/Behavior/Features/W8-IndividualNodePublication/01-ConstraintChecks.feature @@ -82,7 +82,7 @@ Feature: Workspace publication - complex chained functionality When the command PublishIndividualNodesFromWorkspace is executed with payload and exceptions are caught: | Key | Value | | workspaceName | "user-ws" | - | nodesToPublish | [{"dimensionSpacePoint": {"language": "de"}, "nodeAggregateId": "sir-nodebelig"}] | + | nodesToPublish | ["sir-nodebelig"] | | newContentStreamId | "user-cs-id-rebased" | Then the last command should have thrown the WorkspaceRebaseFailed exception with: | SequenceNumber | Event | Exception | @@ -108,7 +108,7 @@ Feature: Workspace publication - complex chained functionality When the command PublishIndividualNodesFromWorkspace is executed with payload and exceptions are caught: | Key | Value | | workspaceName | "user-ws" | - | nodesToPublish | [{"workspaceName": "user-ws", "dimensionSpacePoint": {"language": "en"}, "nodeAggregateId": "nody-mc-nodeface"}] | + | nodesToPublish | ["nody-mc-nodeface"] | | newContentStreamId | "user-cs-id-rebased" | Then the last command should have thrown the PartialWorkspaceRebaseFailed exception with: | SequenceNumber | Event | Exception | @@ -144,7 +144,7 @@ Feature: Workspace publication - complex chained functionality When the command PublishIndividualNodesFromWorkspace is executed with payload and exceptions are caught: | Key | Value | | workspaceName | "user-ws" | - | nodesToPublish | [{"dimensionSpacePoint": {"language": "de"}, "nodeAggregateId": "sir-david-nodenborough"}] | + | nodesToPublish | ["sir-david-nodenborough"] | | newContentStreamId | "user-cs-id-rebased" | Then the last command should have thrown the PartialWorkspaceRebaseFailed exception with: | SequenceNumber | Event | Exception | 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 dfa2d30a523..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 @@ -54,9 +54,18 @@ Feature: Individual node publication | nody-mc-nodeface | Neos.ContentRepository.Testing:Content | $child2Id | nody | {} | When the command PublishIndividualNodesFromWorkspace is executed with payload: | Key | Value | - | nodesToPublish | [{"workspaceName": "user-test", "dimensionSpacePoint": {}, "nodeAggregateId": "sir-david-nodenborough"}] | + | nodesToPublish | ["sir-david-nodenborough"] | | contentStreamIdForRemainingPart | "user-cs-identifier-remaining" | + 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-identifier-remaining" | + | previousSourceContentStreamId | "user-cs-identifier" | + | partial | true | + And I am in workspace "live" Then I expect a node identified by cs-identifier;sir-david-nodenborough;{} to exist in the content graph @@ -79,7 +88,7 @@ Feature: Individual node publication When the command PublishIndividualNodesFromWorkspace is executed with payload: | Key | Value | | workspaceName | "user-test" | - | nodesToPublish | [{"dimensionSpacePoint": {}, "nodeAggregateId": "non-existing"}] | + | nodesToPublish | ["non-existing"] | | contentStreamIdForRemainingPart | "user-cs-new" | Then workspaces user-test has status OUTDATED 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 68a71a14266..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 @@ -97,7 +97,7 @@ Feature: Publishing individual nodes (basics) When the command PublishIndividualNodesFromWorkspace is executed with payload: | Key | Value | | workspaceName | "user-test" | - | nodesToPublish | [{"workspaceName": "user-test", "dimensionSpacePoint": {}, "nodeAggregateId": "sir-nodeward-nodington-iii"}] | + | nodesToPublish | ["sir-nodeward-nodington-iii"] | | contentStreamIdForRemainingPart | "user-cs-identifier-remaining" | Then I expect the content stream "user-cs-identifier" to not exist @@ -142,7 +142,7 @@ Feature: Publishing individual nodes (basics) When the command PublishIndividualNodesFromWorkspace is executed with payload: | Key | Value | | workspaceName | "user-test" | - | nodesToPublish | [{"dimensionSpacePoint": {}, "nodeAggregateId": "non-existing-node"}, {"dimensionSpacePoint": {}, "nodeAggregateId": "sir-unchanged"}] | + | nodesToPublish | ["non-existing-node", "sir-unchanged"] | | contentStreamIdForRemainingPart | "user-cs-identifier-remaining-two" | When I am in workspace "live" and dimension space point {} @@ -198,7 +198,7 @@ Feature: Publishing individual nodes (basics) When the command PublishIndividualNodesFromWorkspace is executed with payload and exceptions are caught: | Key | Value | | workspaceName | "user-test" | - | nodesToPublish | [{"dimensionSpacePoint": {}, "nodeAggregateId": "sir-unchanged"}] | + | nodesToPublish | ["sir-unchanged"] | | contentStreamIdForRemainingPart | "user-cs-identifier-remaining" | Then the last command should have thrown the WorkspaceRebaseFailed exception with: | SequenceNumber | Event | Exception | @@ -208,10 +208,9 @@ Feature: Publishing individual nodes (basics) When the command PublishIndividualNodesFromWorkspace is executed with payload: | Key | Value | | workspaceName | "user-test" | - | nodesToPublish | [{"workspaceName": "user-test", "dimensionSpacePoint": {}, "nodeAggregateId": "sir-david-nodenborough"}, {"workspaceName": "user-test", "dimensionSpacePoint": {}, "nodeAggregateId": "nody-mc-nodeface"}, {"workspaceName": "user-test", "dimensionSpacePoint": {}, "nodeAggregateId": "sir-nodeward-nodington-iii"}] | + | nodesToPublish | ["sir-david-nodenborough", "nody-mc-nodeface", "sir-nodeward-nodington-iii"] | | contentStreamIdForRemainingPart | "user-cs-identifier-remaining" | - # when publishing all nodes we expect a full discard via WorkspaceWasPublished 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 | @@ -219,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;{} @@ -252,7 +252,7 @@ Feature: Publishing individual nodes (basics) When the command PublishIndividualNodesFromWorkspace is executed with payload: | Key | Value | | workspaceName | "user-test" | - | nodesToPublish | [{"dimensionSpacePoint": {}, "nodeAggregateId": "sir-nodeward-nodington-iii"}, {"dimensionSpacePoint": {}, "nodeAggregateId": "sir-david-nodenborough"}] | + | nodesToPublish | ["sir-nodeward-nodington-iii", "sir-david-nodenborough"] | | contentStreamIdForRemainingPart | "user-cs-identifier-remaining" | Then I expect exactly 8 events to be published on stream "ContentStream:cs-identifier" @@ -291,7 +291,7 @@ Feature: Publishing individual nodes (basics) When the command PublishIndividualNodesFromWorkspace is executed with payload: | Key | Value | | workspaceName | "user-test" | - | nodesToPublish | [{"dimensionSpacePoint": {}, "nodeAggregateId": "non-existing"}] | + | nodesToPublish | ["non-existing"] | | contentStreamIdForRemainingPart | "user-cs-new" | Then workspaces user-test has status OUTDATED diff --git a/Neos.ContentRepository.BehavioralTests/Tests/Behavior/Features/W8-IndividualNodePublication/04-AllFeaturePublication.feature b/Neos.ContentRepository.BehavioralTests/Tests/Behavior/Features/W8-IndividualNodePublication/04-AllFeaturePublication.feature index 37de2e73450..761610c3ae4 100644 --- a/Neos.ContentRepository.BehavioralTests/Tests/Behavior/Features/W8-IndividualNodePublication/04-AllFeaturePublication.feature +++ b/Neos.ContentRepository.BehavioralTests/Tests/Behavior/Features/W8-IndividualNodePublication/04-AllFeaturePublication.feature @@ -100,7 +100,7 @@ Feature: Publishing hide/show scenario of nodes When the command PublishIndividualNodesFromWorkspace is executed with payload: | Key | Value | | workspaceName | "user-test" | - | nodesToPublish | [{"nodeAggregateId": "sir-david-nodenborough", "workspaceName": "user-test", "dimensionSpacePoint": {}}] | + | nodesToPublish | ["sir-david-nodenborough"] | | contentStreamIdForRemainingPart | "remaining-cs-id" | When I am in workspace "live" @@ -151,7 +151,7 @@ Feature: Publishing hide/show scenario of nodes When the command PublishIndividualNodesFromWorkspace is executed with payload: | Key | Value | | workspaceName | "user-test" | - | nodesToPublish | [{"nodeAggregateId": "sir-david-nodenborough", "workspaceName": "user-test", "dimensionSpacePoint": {}}] | + | nodesToPublish | ["sir-david-nodenborough"] | | contentStreamIdForRemainingPart | "user-cs-identifier-modified" | When I am in workspace "live" and dimension space point {} @@ -191,7 +191,7 @@ Feature: Publishing hide/show scenario of nodes # When the command PublishIndividualNodesFromWorkspace is executed with payload: # | Key | Value | # | workspaceName | "user-test" | - # | nodesToPublish | [{"nodeAggregateId": "sir-david-nodenborough", "contentStreamId": "user-cs-identifier", "dimensionSpacePoint": {}}] | + # | nodesToPublish | ["sir-david-nodenborough"] | #And the graph projection is fully up to date # When I am in workspace "live" and dimension space point {} @@ -232,7 +232,7 @@ Feature: Publishing hide/show scenario of nodes When the command PublishIndividualNodesFromWorkspace is executed with payload: | Key | Value | | workspaceName | "user-test" | - | nodesToPublish | [{"nodeAggregateId": "sir-david-nodenborough", "workspaceName": "user-test", "dimensionSpacePoint": {}}] | + | nodesToPublish | ["sir-david-nodenborough"] | | contentStreamIdForRemainingPart | "user-cs-identifier-modified" | When I am in workspace "live" and dimension space point {} @@ -270,7 +270,7 @@ Feature: Publishing hide/show scenario of nodes When the command PublishIndividualNodesFromWorkspace is executed with payload: | Key | Value | | workspaceName | "user-test" | - | nodesToPublish | [{"nodeAggregateId": "sir-david-nodenborough", "workspaceName": "user-test", "dimensionSpacePoint": {}}] | + | nodesToPublish | ["sir-david-nodenborough"] | When I am in workspace "live" and dimension space point {} Then I expect node aggregate identifier "sir-david-nodenborough" to lead to no node @@ -307,7 +307,7 @@ Feature: Publishing hide/show scenario of nodes When the command PublishIndividualNodesFromWorkspace is executed with payload: | Key | Value | | workspaceName | "user-test" | - | nodesToPublish | [{"nodeAggregateId": "sir-david-nodenborough", "workspaceName": "user-test", "dimensionSpacePoint": {}}] | + | nodesToPublish | ["sir-david-nodenborough"] | | contentStreamIdForRemainingPart | "user-cs-identifier-modified" | When I am in workspace "live" and dimension space point {} @@ -366,7 +366,7 @@ Feature: Publishing hide/show scenario of nodes When the command PublishIndividualNodesFromWorkspace is executed with payload: | Key | Value | | workspaceName | "user-test" | - | nodesToPublish | [{"nodeAggregateId": "new1-agg", "workspaceName": "user-test", "dimensionSpacePoint": {}}] | + | nodesToPublish | ["new1-agg"] | | contentStreamIdForRemainingPart | "user-cs-identifier-modified" | When I am in workspace "live" and dimension space point {} diff --git a/Neos.ContentRepository.BehavioralTests/Tests/Behavior/Features/W8-IndividualNodePublication/05-PublishMovedNodesWithoutDimensions.feature b/Neos.ContentRepository.BehavioralTests/Tests/Behavior/Features/W8-IndividualNodePublication/05-PublishMovedNodesWithoutDimensions.feature index 35203d3d865..dc16fb4711d 100644 --- a/Neos.ContentRepository.BehavioralTests/Tests/Behavior/Features/W8-IndividualNodePublication/05-PublishMovedNodesWithoutDimensions.feature +++ b/Neos.ContentRepository.BehavioralTests/Tests/Behavior/Features/W8-IndividualNodePublication/05-PublishMovedNodesWithoutDimensions.feature @@ -78,7 +78,7 @@ Feature: Publishing moved nodes without dimensions And the command PublishIndividualNodesFromWorkspace is executed with payload: | Key | Value | | workspaceName | "user" | - | nodesToPublish | [{"workspaceName": "user", "dimensionSpacePoint": {}, "nodeAggregateId": "sir-david-nodenborough"}] | + | nodesToPublish | ["sir-david-nodenborough"] | Then I expect the graph projection to consist of exactly 4 nodes And I expect a node identified by cs-identifier;lady-eleonode-rootford;{} to exist in the content graph @@ -117,7 +117,7 @@ Feature: Publishing moved nodes without dimensions And the command PublishIndividualNodesFromWorkspace is executed with payload: | Key | Value | | workspaceName | "user" | - | nodesToPublish | [{"workspaceName": "user", "dimensionSpacePoint": {}, "nodeAggregateId": "sir-nodeward-nodington-iii"}] | + | nodesToPublish | ["sir-nodeward-nodington-iii"] | Then I expect the graph projection to consist of exactly 4 nodes And I expect a node identified by cs-identifier;lady-eleonode-rootford;{} to exist in the content graph @@ -166,7 +166,7 @@ Feature: Publishing moved nodes without dimensions And the command PublishIndividualNodesFromWorkspace is executed with payload: | Key | Value | | workspaceName | "user" | - | nodesToPublish | [{"workspaceName": "user", "dimensionSpacePoint": {}, "nodeAggregateId": "sir-david-nodenborough"}] | + | nodesToPublish | ["sir-david-nodenborough"] | Then I expect the graph projection to consist of exactly 5 nodes And I expect a node identified by cs-identifier;lady-eleonode-rootford;{} to exist in the content graph @@ -210,7 +210,7 @@ Feature: Publishing moved nodes without dimensions And the command PublishIndividualNodesFromWorkspace is executed with payload: | Key | Value | | workspaceName | "user" | - | nodesToPublish | [{"workspaceName": "user", "dimensionSpacePoint": {}, "nodeAggregateId": "nody-mc-nodeface"}] | + | nodesToPublish | ["nody-mc-nodeface"] | Then I expect the graph projection to consist of exactly 4 nodes And I expect a node identified by cs-identifier;lady-eleonode-rootford;{} to exist in the content graph 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/EventStore/EventInterface.php b/Neos.ContentRepository.Core/Classes/EventStore/EventInterface.php index c892bfe0f5a..dbffa23718b 100644 --- a/Neos.ContentRepository.Core/Classes/EventStore/EventInterface.php +++ b/Neos.ContentRepository.Core/Classes/EventStore/EventInterface.php @@ -13,9 +13,8 @@ interface EventInterface extends \JsonSerializable { /** * @param array $values - * @return static */ - public static function fromArray(array $values): self; + public static function fromArray(array $values): EventInterface; /** * @return array diff --git a/Neos.ContentRepository.Core/Classes/EventStore/EventNormalizer.php b/Neos.ContentRepository.Core/Classes/EventStore/EventNormalizer.php index 52f23d63910..6a7ca968917 100644 --- a/Neos.ContentRepository.Core/Classes/EventStore/EventNormalizer.php +++ b/Neos.ContentRepository.Core/Classes/EventStore/EventNormalizer.php @@ -162,13 +162,7 @@ public function denormalize(Event $event): EventInterface throw new \RuntimeException(sprintf('Expected array got %s', $eventDataAsArray)); } /** {@see EventInterface::fromArray()} */ - $eventInstance = $eventClassName::fromArray($eventDataAsArray); - return match ($eventInstance::class) { - // upcast disabled / enabled events to the corresponding SubtreeTag events - NodeAggregateWasDisabled::class => new SubtreeWasTagged($eventInstance->workspaceName, $eventInstance->contentStreamId, $eventInstance->nodeAggregateId, $eventInstance->affectedDimensionSpacePoints, SubtreeTag::disabled()), - NodeAggregateWasEnabled::class => new SubtreeWasUntagged($eventInstance->workspaceName, $eventInstance->contentStreamId, $eventInstance->nodeAggregateId, $eventInstance->affectedDimensionSpacePoints, SubtreeTag::disabled()), - default => $eventInstance, - }; + return $eventClassName::fromArray($eventDataAsArray); } private function getEventData(EventInterface $event): EventData diff --git a/Neos.ContentRepository.Core/Classes/Feature/Common/MatchableWithNodeIdToPublishOrDiscardInterface.php b/Neos.ContentRepository.Core/Classes/Feature/Common/MatchableWithNodeIdToPublishOrDiscardInterface.php deleted file mode 100644 index edde6697d10..00000000000 --- a/Neos.ContentRepository.Core/Classes/Feature/Common/MatchableWithNodeIdToPublishOrDiscardInterface.php +++ /dev/null @@ -1,30 +0,0 @@ -nodeAggregateId->equals($nodeIdToPublish->nodeAggregateId) - && $nodeIdToPublish->dimensionSpacePoint?->equals($this->originDimensionSpacePoint) - ); - } - public function createCopyForWorkspace( WorkspaceName $targetWorkspaceName, ): self { diff --git a/Neos.ContentRepository.Core/Classes/Feature/NodeDisabling/Command/DisableNodeAggregate.php b/Neos.ContentRepository.Core/Classes/Feature/NodeDisabling/Command/DisableNodeAggregate.php index 90c725e6a69..9b2bd395bd1 100644 --- a/Neos.ContentRepository.Core/Classes/Feature/NodeDisabling/Command/DisableNodeAggregate.php +++ b/Neos.ContentRepository.Core/Classes/Feature/NodeDisabling/Command/DisableNodeAggregate.php @@ -16,12 +16,9 @@ use Neos\ContentRepository\Core\CommandHandler\CommandInterface; use Neos\ContentRepository\Core\DimensionSpace\DimensionSpacePoint; -use Neos\ContentRepository\Core\Feature\Common\MatchableWithNodeIdToPublishOrDiscardInterface; use Neos\ContentRepository\Core\Feature\Common\RebasableToOtherWorkspaceInterface; -use Neos\ContentRepository\Core\Feature\WorkspacePublication\Dto\NodeIdToPublishOrDiscard; use Neos\ContentRepository\Core\SharedModel\Node\NodeAggregateId; use Neos\ContentRepository\Core\SharedModel\Node\NodeVariantSelectionStrategy; -use Neos\ContentRepository\Core\SharedModel\Workspace\ContentStreamId; use Neos\ContentRepository\Core\SharedModel\Workspace\WorkspaceName; /** @@ -32,7 +29,6 @@ final readonly class DisableNodeAggregate implements CommandInterface, \JsonSerializable, - MatchableWithNodeIdToPublishOrDiscardInterface, RebasableToOtherWorkspaceInterface { /** @@ -78,14 +74,6 @@ public function jsonSerialize(): array return get_object_vars($this); } - public function matchesNodeId(NodeIdToPublishOrDiscard $nodeIdToPublish): bool - { - return ( - $this->coveredDimensionSpacePoint === $nodeIdToPublish->dimensionSpacePoint - && $this->nodeAggregateId->equals($nodeIdToPublish->nodeAggregateId) - ); - } - public function createCopyForWorkspace( WorkspaceName $targetWorkspaceName, ): self { diff --git a/Neos.ContentRepository.Core/Classes/Feature/NodeDisabling/Command/EnableNodeAggregate.php b/Neos.ContentRepository.Core/Classes/Feature/NodeDisabling/Command/EnableNodeAggregate.php index 37c8407b0c7..25d1919960e 100644 --- a/Neos.ContentRepository.Core/Classes/Feature/NodeDisabling/Command/EnableNodeAggregate.php +++ b/Neos.ContentRepository.Core/Classes/Feature/NodeDisabling/Command/EnableNodeAggregate.php @@ -16,12 +16,9 @@ use Neos\ContentRepository\Core\CommandHandler\CommandInterface; use Neos\ContentRepository\Core\DimensionSpace\DimensionSpacePoint; -use Neos\ContentRepository\Core\Feature\Common\MatchableWithNodeIdToPublishOrDiscardInterface; use Neos\ContentRepository\Core\Feature\Common\RebasableToOtherWorkspaceInterface; -use Neos\ContentRepository\Core\Feature\WorkspacePublication\Dto\NodeIdToPublishOrDiscard; use Neos\ContentRepository\Core\SharedModel\Node\NodeAggregateId; use Neos\ContentRepository\Core\SharedModel\Node\NodeVariantSelectionStrategy; -use Neos\ContentRepository\Core\SharedModel\Workspace\ContentStreamId; use Neos\ContentRepository\Core\SharedModel\Workspace\WorkspaceName; /** @@ -32,7 +29,6 @@ final readonly class EnableNodeAggregate implements CommandInterface, \JsonSerializable, - MatchableWithNodeIdToPublishOrDiscardInterface, RebasableToOtherWorkspaceInterface { /** @@ -78,14 +74,6 @@ public function jsonSerialize(): array return get_object_vars($this); } - public function matchesNodeId(NodeIdToPublishOrDiscard $nodeIdToPublish): bool - { - return ( - $this->coveredDimensionSpacePoint === $nodeIdToPublish->dimensionSpacePoint - && $this->nodeAggregateId->equals($nodeIdToPublish->nodeAggregateId) - ); - } - public function createCopyForWorkspace( WorkspaceName $targetWorkspaceName, ): self { diff --git a/Neos.ContentRepository.Core/Classes/Feature/NodeDisabling/Event/NodeAggregateWasDisabled.php b/Neos.ContentRepository.Core/Classes/Feature/NodeDisabling/Event/NodeAggregateWasDisabled.php index e65d6ce7055..5a9c93ad5f2 100644 --- a/Neos.ContentRepository.Core/Classes/Feature/NodeDisabling/Event/NodeAggregateWasDisabled.php +++ b/Neos.ContentRepository.Core/Classes/Feature/NodeDisabling/Event/NodeAggregateWasDisabled.php @@ -16,74 +16,36 @@ use Neos\ContentRepository\Core\DimensionSpace\DimensionSpacePointSet; use Neos\ContentRepository\Core\EventStore\EventInterface; -use Neos\ContentRepository\Core\Feature\Common\EmbedsContentStreamId; -use Neos\ContentRepository\Core\Feature\Common\EmbedsNodeAggregateId; -use Neos\ContentRepository\Core\Feature\Common\EmbedsWorkspaceName; -use Neos\ContentRepository\Core\Feature\Common\PublishableToWorkspaceInterface; +use Neos\ContentRepository\Core\Feature\SubtreeTagging\Dto\SubtreeTag; use Neos\ContentRepository\Core\Feature\SubtreeTagging\Event\SubtreeWasTagged; use Neos\ContentRepository\Core\SharedModel\Node\NodeAggregateId; use Neos\ContentRepository\Core\SharedModel\Workspace\ContentStreamId; use Neos\ContentRepository\Core\SharedModel\Workspace\WorkspaceName; /** - * A node aggregate was disabled - * - * @deprecated This event will never be emitted, it is up-casted to a corresponding {@see SubtreeWasTagged} event instead in the {@see EventNormalizer}. This implementation is just kept for backwards-compatibility + * @deprecated This event will never be emitted, it is up-casted to a corresponding {@see SubtreeWasTagged} event instead. This implementation is just kept for backwards-compatibility * @internal */ -final readonly class NodeAggregateWasDisabled implements - EventInterface, - PublishableToWorkspaceInterface, - EmbedsContentStreamId, - EmbedsNodeAggregateId, - EmbedsWorkspaceName +final readonly class NodeAggregateWasDisabled implements EventInterface { - public function __construct( - public WorkspaceName $workspaceName, - public ContentStreamId $contentStreamId, - public NodeAggregateId $nodeAggregateId, - /** The dimension space points the node aggregate was disabled in */ - public DimensionSpacePointSet $affectedDimensionSpacePoints, - ) { - } - - public function getContentStreamId(): ContentStreamId + private function __construct() { - return $this->contentStreamId; - } - - public function getNodeAggregateId(): NodeAggregateId - { - return $this->nodeAggregateId; - } - - public function getWorkspaceName(): WorkspaceName - { - return $this->workspaceName; - } - - public function withWorkspaceNameAndContentStreamId(WorkspaceName $targetWorkspaceName, ContentStreamId $contentStreamId): self - { - return new self( - $targetWorkspaceName, - $contentStreamId, - $this->nodeAggregateId, - $this->affectedDimensionSpacePoints, - ); + // legacy event must not be instantiated } public static function fromArray(array $values): EventInterface { - return new self( + return new SubtreeWasTagged( WorkspaceName::fromString($values['workspaceName']), ContentStreamId::fromString($values['contentStreamId']), NodeAggregateId::fromString($values['nodeAggregateId']), DimensionSpacePointSet::fromArray($values['affectedDimensionSpacePoints']), + SubtreeTag::disabled() ); } public function jsonSerialize(): array { - return get_object_vars($this); + throw new \RuntimeException('Legacy event instance must not exist.'); } } diff --git a/Neos.ContentRepository.Core/Classes/Feature/NodeDisabling/Event/NodeAggregateWasEnabled.php b/Neos.ContentRepository.Core/Classes/Feature/NodeDisabling/Event/NodeAggregateWasEnabled.php index f863fd97a8a..accc0d0317d 100644 --- a/Neos.ContentRepository.Core/Classes/Feature/NodeDisabling/Event/NodeAggregateWasEnabled.php +++ b/Neos.ContentRepository.Core/Classes/Feature/NodeDisabling/Event/NodeAggregateWasEnabled.php @@ -16,74 +16,36 @@ use Neos\ContentRepository\Core\DimensionSpace\DimensionSpacePointSet; use Neos\ContentRepository\Core\EventStore\EventInterface; -use Neos\ContentRepository\Core\EventStore\EventNormalizer; -use Neos\ContentRepository\Core\Feature\Common\EmbedsContentStreamId; -use Neos\ContentRepository\Core\Feature\Common\EmbedsNodeAggregateId; -use Neos\ContentRepository\Core\Feature\Common\EmbedsWorkspaceName; -use Neos\ContentRepository\Core\Feature\Common\PublishableToWorkspaceInterface; +use Neos\ContentRepository\Core\Feature\SubtreeTagging\Dto\SubtreeTag; use Neos\ContentRepository\Core\Feature\SubtreeTagging\Event\SubtreeWasUntagged; use Neos\ContentRepository\Core\SharedModel\Node\NodeAggregateId; use Neos\ContentRepository\Core\SharedModel\Workspace\ContentStreamId; use Neos\ContentRepository\Core\SharedModel\Workspace\WorkspaceName; /** - * A node aggregate was enabled - * - * @deprecated This event will never be emitted, it is up-casted to a corresponding {@see SubtreeWasUntagged} event instead in the {@see EventNormalizer}. This implementation is just kept for backwards-compatibility + * @deprecated This event will never be emitted, it is up-casted to a corresponding {@see SubtreeWasUntagged} event instead. This implementation is just kept for backwards-compatibility * @internal */ -final readonly class NodeAggregateWasEnabled implements - EventInterface, - PublishableToWorkspaceInterface, - EmbedsContentStreamId, - EmbedsNodeAggregateId, - EmbedsWorkspaceName +final readonly class NodeAggregateWasEnabled implements EventInterface { - public function __construct( - public WorkspaceName $workspaceName, - public ContentStreamId $contentStreamId, - public NodeAggregateId $nodeAggregateId, - public DimensionSpacePointSet $affectedDimensionSpacePoints, - ) { - } - - public function getContentStreamId(): ContentStreamId + private function __construct() { - return $this->contentStreamId; - } - - public function getNodeAggregateId(): NodeAggregateId - { - return $this->nodeAggregateId; - } - - public function getWorkspaceName(): WorkspaceName - { - return $this->workspaceName; - } - - public function withWorkspaceNameAndContentStreamId(WorkspaceName $targetWorkspaceName, ContentStreamId $contentStreamId): self - { - return new self( - $targetWorkspaceName, - $contentStreamId, - $this->nodeAggregateId, - $this->affectedDimensionSpacePoints, - ); + // legacy event must not be instantiated } public static function fromArray(array $values): EventInterface { - return new self( + return new SubtreeWasUntagged( WorkspaceName::fromString($values['workspaceName']), ContentStreamId::fromString($values['contentStreamId']), NodeAggregateId::fromString($values['nodeAggregateId']), DimensionSpacePointSet::fromArray($values['affectedDimensionSpacePoints']), + SubtreeTag::disabled() ); } public function jsonSerialize(): array { - return get_object_vars($this); + throw new \RuntimeException('Legacy event instance must not exist.'); } } diff --git a/Neos.ContentRepository.Core/Classes/Feature/NodeDuplication/Command/CopyNodesRecursively.php b/Neos.ContentRepository.Core/Classes/Feature/NodeDuplication/Command/CopyNodesRecursively.php index e3219fa695a..ef175733c40 100644 --- a/Neos.ContentRepository.Core/Classes/Feature/NodeDuplication/Command/CopyNodesRecursively.php +++ b/Neos.ContentRepository.Core/Classes/Feature/NodeDuplication/Command/CopyNodesRecursively.php @@ -15,10 +15,8 @@ namespace Neos\ContentRepository\Core\Feature\NodeDuplication\Command; use Neos\ContentRepository\Core\DimensionSpace\OriginDimensionSpacePoint; -use Neos\ContentRepository\Core\Feature\Common\MatchableWithNodeIdToPublishOrDiscardInterface; use Neos\ContentRepository\Core\Feature\Common\RebasableToOtherWorkspaceInterface; use Neos\ContentRepository\Core\Feature\NodeDuplication\Dto\NodeSubtreeSnapshot; -use Neos\ContentRepository\Core\Feature\WorkspacePublication\Dto\NodeIdToPublishOrDiscard; use Neos\ContentRepository\Core\Projection\ContentGraph\ContentSubgraphInterface; use Neos\ContentRepository\Core\Projection\ContentGraph\Node; use Neos\ContentRepository\Core\SharedModel\Node\NodeAggregateId; @@ -38,7 +36,6 @@ */ final readonly class CopyNodesRecursively implements \JsonSerializable, - MatchableWithNodeIdToPublishOrDiscardInterface, RebasableToOtherWorkspaceInterface { /** @@ -121,18 +118,6 @@ public function jsonSerialize(): array return get_object_vars($this); } - public function matchesNodeId(NodeIdToPublishOrDiscard $nodeIdToPublish): bool - { - $targetNodeAggregateId = $this->nodeAggregateIdMapping->getNewNodeAggregateId( - $this->nodeTreeToInsert->nodeAggregateId - ); - return ( - !is_null($targetNodeAggregateId) - && $nodeIdToPublish->dimensionSpacePoint?->equals($this->targetDimensionSpacePoint) - && $targetNodeAggregateId->equals($nodeIdToPublish->nodeAggregateId) - ); - } - public function withNodeAggregateIdMapping( NodeAggregateIdMapping $nodeAggregateIdMapping ): self { diff --git a/Neos.ContentRepository.Core/Classes/Feature/NodeModification/Command/SetSerializedNodeProperties.php b/Neos.ContentRepository.Core/Classes/Feature/NodeModification/Command/SetSerializedNodeProperties.php index c3906bae03f..9420f3a4069 100644 --- a/Neos.ContentRepository.Core/Classes/Feature/NodeModification/Command/SetSerializedNodeProperties.php +++ b/Neos.ContentRepository.Core/Classes/Feature/NodeModification/Command/SetSerializedNodeProperties.php @@ -15,10 +15,8 @@ namespace Neos\ContentRepository\Core\Feature\NodeModification\Command; use Neos\ContentRepository\Core\DimensionSpace\OriginDimensionSpacePoint; -use Neos\ContentRepository\Core\Feature\Common\MatchableWithNodeIdToPublishOrDiscardInterface; use Neos\ContentRepository\Core\Feature\Common\RebasableToOtherWorkspaceInterface; use Neos\ContentRepository\Core\Feature\NodeModification\Dto\SerializedPropertyValues; -use Neos\ContentRepository\Core\Feature\WorkspacePublication\Dto\NodeIdToPublishOrDiscard; use Neos\ContentRepository\Core\SharedModel\Node\NodeAggregateId; use Neos\ContentRepository\Core\SharedModel\Node\PropertyNames; use Neos\ContentRepository\Core\SharedModel\Workspace\WorkspaceName; @@ -32,7 +30,6 @@ */ final readonly class SetSerializedNodeProperties implements \JsonSerializable, - MatchableWithNodeIdToPublishOrDiscardInterface, RebasableToOtherWorkspaceInterface { /** @@ -94,14 +91,6 @@ public function jsonSerialize(): array return get_object_vars($this); } - public function matchesNodeId(NodeIdToPublishOrDiscard $nodeIdToPublish): bool - { - return ( - $nodeIdToPublish->dimensionSpacePoint?->equals($this->originDimensionSpacePoint) - && $this->nodeAggregateId->equals($nodeIdToPublish->nodeAggregateId) - ); - } - public function createCopyForWorkspace( WorkspaceName $targetWorkspaceName, ): self { diff --git a/Neos.ContentRepository.Core/Classes/Feature/NodeMove/Command/MoveNodeAggregate.php b/Neos.ContentRepository.Core/Classes/Feature/NodeMove/Command/MoveNodeAggregate.php index 054316a2022..c7c60eebba9 100644 --- a/Neos.ContentRepository.Core/Classes/Feature/NodeMove/Command/MoveNodeAggregate.php +++ b/Neos.ContentRepository.Core/Classes/Feature/NodeMove/Command/MoveNodeAggregate.php @@ -16,12 +16,9 @@ use Neos\ContentRepository\Core\CommandHandler\CommandInterface; use Neos\ContentRepository\Core\DimensionSpace\DimensionSpacePoint; -use Neos\ContentRepository\Core\Feature\Common\MatchableWithNodeIdToPublishOrDiscardInterface; use Neos\ContentRepository\Core\Feature\Common\RebasableToOtherWorkspaceInterface; use Neos\ContentRepository\Core\Feature\NodeMove\Dto\RelationDistributionStrategy; -use Neos\ContentRepository\Core\Feature\WorkspacePublication\Dto\NodeIdToPublishOrDiscard; use Neos\ContentRepository\Core\SharedModel\Node\NodeAggregateId; -use Neos\ContentRepository\Core\SharedModel\Workspace\ContentStreamId; use Neos\ContentRepository\Core\SharedModel\Workspace\WorkspaceName; /** @@ -45,7 +42,6 @@ final readonly class MoveNodeAggregate implements CommandInterface, \JsonSerializable, - MatchableWithNodeIdToPublishOrDiscardInterface, RebasableToOtherWorkspaceInterface { /** @@ -111,12 +107,6 @@ public function jsonSerialize(): array return get_object_vars($this); } - public function matchesNodeId(NodeIdToPublishOrDiscard $nodeIdToPublish): bool - { - return $this->nodeAggregateId->equals($nodeIdToPublish->nodeAggregateId) - && $this->dimensionSpacePoint === $nodeIdToPublish->dimensionSpacePoint; - } - public function createCopyForWorkspace( WorkspaceName $targetWorkspaceName, ): self { diff --git a/Neos.ContentRepository.Core/Classes/Feature/NodeReferencing/Command/SetSerializedNodeReferences.php b/Neos.ContentRepository.Core/Classes/Feature/NodeReferencing/Command/SetSerializedNodeReferences.php index 132f1299ed7..42f3d5b5a95 100644 --- a/Neos.ContentRepository.Core/Classes/Feature/NodeReferencing/Command/SetSerializedNodeReferences.php +++ b/Neos.ContentRepository.Core/Classes/Feature/NodeReferencing/Command/SetSerializedNodeReferences.php @@ -15,10 +15,8 @@ namespace Neos\ContentRepository\Core\Feature\NodeReferencing\Command; use Neos\ContentRepository\Core\DimensionSpace\OriginDimensionSpacePoint; -use Neos\ContentRepository\Core\Feature\Common\MatchableWithNodeIdToPublishOrDiscardInterface; use Neos\ContentRepository\Core\Feature\Common\RebasableToOtherWorkspaceInterface; use Neos\ContentRepository\Core\Feature\NodeReferencing\Dto\SerializedNodeReferences; -use Neos\ContentRepository\Core\Feature\WorkspacePublication\Dto\NodeIdToPublishOrDiscard; use Neos\ContentRepository\Core\SharedModel\Node\NodeAggregateId; use Neos\ContentRepository\Core\SharedModel\Workspace\WorkspaceName; @@ -31,7 +29,6 @@ */ final readonly class SetSerializedNodeReferences implements \JsonSerializable, - MatchableWithNodeIdToPublishOrDiscardInterface, RebasableToOtherWorkspaceInterface { /** @@ -78,13 +75,6 @@ public function jsonSerialize(): array return get_object_vars($this); } - public function matchesNodeId(NodeIdToPublishOrDiscard $nodeIdToPublish): bool - { - return ($nodeIdToPublish->dimensionSpacePoint?->equals($this->sourceOriginDimensionSpacePoint) - && $this->sourceNodeAggregateId->equals($nodeIdToPublish->nodeAggregateId) - ); - } - public function createCopyForWorkspace( WorkspaceName $targetWorkspaceName, ): self { diff --git a/Neos.ContentRepository.Core/Classes/Feature/NodeRemoval/Command/RemoveNodeAggregate.php b/Neos.ContentRepository.Core/Classes/Feature/NodeRemoval/Command/RemoveNodeAggregate.php index 92292bd34da..ad4948d6a49 100644 --- a/Neos.ContentRepository.Core/Classes/Feature/NodeRemoval/Command/RemoveNodeAggregate.php +++ b/Neos.ContentRepository.Core/Classes/Feature/NodeRemoval/Command/RemoveNodeAggregate.php @@ -16,9 +16,7 @@ use Neos\ContentRepository\Core\CommandHandler\CommandInterface; use Neos\ContentRepository\Core\DimensionSpace\DimensionSpacePoint; -use Neos\ContentRepository\Core\Feature\Common\MatchableWithNodeIdToPublishOrDiscardInterface; use Neos\ContentRepository\Core\Feature\Common\RebasableToOtherWorkspaceInterface; -use Neos\ContentRepository\Core\Feature\WorkspacePublication\Dto\NodeIdToPublishOrDiscard; use Neos\ContentRepository\Core\SharedModel\Node\NodeAggregateId; use Neos\ContentRepository\Core\SharedModel\Node\NodeVariantSelectionStrategy; use Neos\ContentRepository\Core\SharedModel\Workspace\WorkspaceName; @@ -29,7 +27,6 @@ final readonly class RemoveNodeAggregate implements CommandInterface, \JsonSerializable, - MatchableWithNodeIdToPublishOrDiscardInterface, RebasableToOtherWorkspaceInterface { /** @@ -97,14 +94,6 @@ public function jsonSerialize(): array return get_object_vars($this); } - public function matchesNodeId(NodeIdToPublishOrDiscard $nodeIdToPublish): bool - { - return ( - $this->nodeAggregateId->equals($nodeIdToPublish->nodeAggregateId) - && $this->coveredDimensionSpacePoint === $nodeIdToPublish->dimensionSpacePoint - ); - } - public function createCopyForWorkspace( WorkspaceName $targetWorkspaceName, ): self { diff --git a/Neos.ContentRepository.Core/Classes/Feature/NodeRenaming/Command/ChangeNodeAggregateName.php b/Neos.ContentRepository.Core/Classes/Feature/NodeRenaming/Command/ChangeNodeAggregateName.php index d19d6210a48..027f7294be2 100644 --- a/Neos.ContentRepository.Core/Classes/Feature/NodeRenaming/Command/ChangeNodeAggregateName.php +++ b/Neos.ContentRepository.Core/Classes/Feature/NodeRenaming/Command/ChangeNodeAggregateName.php @@ -15,9 +15,7 @@ namespace Neos\ContentRepository\Core\Feature\NodeRenaming\Command; use Neos\ContentRepository\Core\CommandHandler\CommandInterface; -use Neos\ContentRepository\Core\Feature\Common\MatchableWithNodeIdToPublishOrDiscardInterface; use Neos\ContentRepository\Core\Feature\Common\RebasableToOtherWorkspaceInterface; -use Neos\ContentRepository\Core\Feature\WorkspacePublication\Dto\NodeIdToPublishOrDiscard; use Neos\ContentRepository\Core\SharedModel\Node\NodeAggregateId; use Neos\ContentRepository\Core\SharedModel\Node\NodeName; use Neos\ContentRepository\Core\SharedModel\Workspace\WorkspaceName; @@ -34,7 +32,6 @@ final readonly class ChangeNodeAggregateName implements CommandInterface, \JsonSerializable, - MatchableWithNodeIdToPublishOrDiscardInterface, RebasableToOtherWorkspaceInterface { /** @@ -76,11 +73,6 @@ public function jsonSerialize(): array return get_object_vars($this); } - public function matchesNodeId(NodeIdToPublishOrDiscard $nodeIdToPublish): bool - { - return $this->nodeAggregateId->equals($nodeIdToPublish->nodeAggregateId); - } - public function createCopyForWorkspace( WorkspaceName $targetWorkspaceName, ): self { diff --git a/Neos.ContentRepository.Core/Classes/Feature/NodeTypeChange/Command/ChangeNodeAggregateType.php b/Neos.ContentRepository.Core/Classes/Feature/NodeTypeChange/Command/ChangeNodeAggregateType.php index 4a13da56621..736802a3e6c 100644 --- a/Neos.ContentRepository.Core/Classes/Feature/NodeTypeChange/Command/ChangeNodeAggregateType.php +++ b/Neos.ContentRepository.Core/Classes/Feature/NodeTypeChange/Command/ChangeNodeAggregateType.php @@ -15,14 +15,11 @@ namespace Neos\ContentRepository\Core\Feature\NodeTypeChange\Command; use Neos\ContentRepository\Core\CommandHandler\CommandInterface; -use Neos\ContentRepository\Core\Feature\Common\MatchableWithNodeIdToPublishOrDiscardInterface; use Neos\ContentRepository\Core\Feature\Common\RebasableToOtherWorkspaceInterface; use Neos\ContentRepository\Core\Feature\NodeCreation\Dto\NodeAggregateIdsByNodePaths; use Neos\ContentRepository\Core\Feature\NodeTypeChange\Dto\NodeAggregateTypeChangeChildConstraintConflictResolutionStrategy; -use Neos\ContentRepository\Core\Feature\WorkspacePublication\Dto\NodeIdToPublishOrDiscard; use Neos\ContentRepository\Core\NodeType\NodeTypeName; use Neos\ContentRepository\Core\SharedModel\Node\NodeAggregateId; -use Neos\ContentRepository\Core\SharedModel\Workspace\ContentStreamId; use Neos\ContentRepository\Core\SharedModel\Workspace\WorkspaceName; /** @@ -31,7 +28,6 @@ final readonly class ChangeNodeAggregateType implements CommandInterface, \JsonSerializable, - MatchableWithNodeIdToPublishOrDiscardInterface, RebasableToOtherWorkspaceInterface { /** @@ -74,11 +70,6 @@ public static function fromArray(array $array): self ); } - public function matchesNodeId(NodeIdToPublishOrDiscard $nodeIdToPublish): bool - { - return $this->nodeAggregateId->equals($nodeIdToPublish->nodeAggregateId); - } - /** * @return array */ diff --git a/Neos.ContentRepository.Core/Classes/Feature/NodeVariation/Command/CreateNodeVariant.php b/Neos.ContentRepository.Core/Classes/Feature/NodeVariation/Command/CreateNodeVariant.php index 2064e99e0b2..581bfd8b6d8 100644 --- a/Neos.ContentRepository.Core/Classes/Feature/NodeVariation/Command/CreateNodeVariant.php +++ b/Neos.ContentRepository.Core/Classes/Feature/NodeVariation/Command/CreateNodeVariant.php @@ -16,9 +16,7 @@ use Neos\ContentRepository\Core\CommandHandler\CommandInterface; use Neos\ContentRepository\Core\DimensionSpace\OriginDimensionSpacePoint; -use Neos\ContentRepository\Core\Feature\Common\MatchableWithNodeIdToPublishOrDiscardInterface; use Neos\ContentRepository\Core\Feature\Common\RebasableToOtherWorkspaceInterface; -use Neos\ContentRepository\Core\Feature\WorkspacePublication\Dto\NodeIdToPublishOrDiscard; use Neos\ContentRepository\Core\SharedModel\Node\NodeAggregateId; use Neos\ContentRepository\Core\SharedModel\Workspace\WorkspaceName; @@ -32,7 +30,6 @@ final readonly class CreateNodeVariant implements CommandInterface, \JsonSerializable, - MatchableWithNodeIdToPublishOrDiscardInterface, RebasableToOtherWorkspaceInterface { /** @@ -78,12 +75,6 @@ public function jsonSerialize(): array return get_object_vars($this); } - public function matchesNodeId(NodeIdToPublishOrDiscard $nodeIdToPublish): bool - { - return $this->nodeAggregateId->equals($nodeIdToPublish->nodeAggregateId) - && $nodeIdToPublish->dimensionSpacePoint?->equals($this->targetOrigin); - } - public function createCopyForWorkspace( WorkspaceName $targetWorkspaceName, ): self { diff --git a/Neos.ContentRepository.Core/Classes/Feature/RebaseableCommands.php b/Neos.ContentRepository.Core/Classes/Feature/RebaseableCommands.php index fd746e051a4..4d5e6764b45 100644 --- a/Neos.ContentRepository.Core/Classes/Feature/RebaseableCommands.php +++ b/Neos.ContentRepository.Core/Classes/Feature/RebaseableCommands.php @@ -4,8 +4,26 @@ namespace Neos\ContentRepository\Core\Feature; -use Neos\ContentRepository\Core\Feature\Common\MatchableWithNodeIdToPublishOrDiscardInterface; -use Neos\ContentRepository\Core\Feature\WorkspacePublication\Dto\NodeIdsToPublishOrDiscard; +use Neos\ContentRepository\Core\Feature\Common\EmbedsNodeAggregateId; +use Neos\ContentRepository\Core\Feature\Common\RebasableToOtherWorkspaceInterface; +use Neos\ContentRepository\Core\Feature\DimensionSpaceAdjustment\Command\AddDimensionShineThrough; +use Neos\ContentRepository\Core\Feature\DimensionSpaceAdjustment\Command\MoveDimensionSpacePoint; +use Neos\ContentRepository\Core\Feature\NodeCreation\Command\CreateNodeAggregateWithNodeAndSerializedProperties; +use Neos\ContentRepository\Core\Feature\NodeDisabling\Command\DisableNodeAggregate; +use Neos\ContentRepository\Core\Feature\NodeDisabling\Command\EnableNodeAggregate; +use Neos\ContentRepository\Core\Feature\NodeDuplication\Command\CopyNodesRecursively; +use Neos\ContentRepository\Core\Feature\NodeModification\Command\SetSerializedNodeProperties; +use Neos\ContentRepository\Core\Feature\NodeMove\Command\MoveNodeAggregate; +use Neos\ContentRepository\Core\Feature\NodeReferencing\Command\SetSerializedNodeReferences; +use Neos\ContentRepository\Core\Feature\NodeRemoval\Command\RemoveNodeAggregate; +use Neos\ContentRepository\Core\Feature\NodeRenaming\Command\ChangeNodeAggregateName; +use Neos\ContentRepository\Core\Feature\NodeTypeChange\Command\ChangeNodeAggregateType; +use Neos\ContentRepository\Core\Feature\NodeVariation\Command\CreateNodeVariant; +use Neos\ContentRepository\Core\Feature\RootNodeCreation\Command\CreateRootNodeAggregateWithNode; +use Neos\ContentRepository\Core\Feature\RootNodeCreation\Command\UpdateRootNodeAggregateDimensions; +use Neos\ContentRepository\Core\Feature\SubtreeTagging\Command\TagSubtree; +use Neos\ContentRepository\Core\Feature\SubtreeTagging\Command\UntagSubtree; +use Neos\ContentRepository\Core\SharedModel\Node\NodeAggregateIds; use Neos\EventStore\Model\EventStream\EventStreamInterface; /** @@ -41,20 +59,12 @@ public static function extractFromEventStream(EventStreamInterface $eventStream) * @return array{RebaseableCommands,RebaseableCommands} */ public function separateMatchingAndRemainingCommands( - NodeIdsToPublishOrDiscard $nodeIdsToPublishOrDiscard + NodeAggregateIds $nodeIdsToMatch ): array { $matchingCommands = []; $remainingCommands = []; foreach ($this->items as $extractedCommand) { - $originalCommand = $extractedCommand->originalCommand; - if (!$originalCommand instanceof MatchableWithNodeIdToPublishOrDiscardInterface) { - throw new \Exception( - 'Command class ' . get_class($originalCommand) . ' does not implement ' - . MatchableWithNodeIdToPublishOrDiscardInterface::class, - 1645393655 - ); - } - if (self::commandMatchesAtLeastOneNode($originalCommand, $nodeIdsToPublishOrDiscard)) { + if (self::commandMatchesAtLeastOneNode($extractedCommand->originalCommand, $nodeIdsToMatch)) { $matchingCommands[] = $extractedCommand; } else { $remainingCommands[] = $extractedCommand; @@ -67,11 +77,44 @@ public function separateMatchingAndRemainingCommands( } private static function commandMatchesAtLeastOneNode( - MatchableWithNodeIdToPublishOrDiscardInterface $command, - NodeIdsToPublishOrDiscard $nodeIds, + RebasableToOtherWorkspaceInterface $command, + NodeAggregateIds $nodeAggregateIdsToMatch, ): bool { - foreach ($nodeIds as $nodeId) { - if ($command->matchesNodeId($nodeId)) { + foreach ($nodeAggregateIdsToMatch as $nodeId) { + /** + * This match must contain all commands which are working with individual nodes, such that they are + * filterable whether they are applying their action to a $nodeAggregateId in question + * + * Used to separate commands for publish and discard individual nodes + * + * NOTE: We could refactor and simplify this by asking the events {@see EmbedsNodeAggregateId} + * instead which would be more clean. But that only makes sense if we start rebasing events. + */ + $matches = match ($command::class) { + CreateRootNodeAggregateWithNode::class, + CreateNodeAggregateWithNodeAndSerializedProperties::class, + DisableNodeAggregate::class, + EnableNodeAggregate::class, + SetSerializedNodeProperties::class, + MoveNodeAggregate::class, + RemoveNodeAggregate::class, + ChangeNodeAggregateName::class, + ChangeNodeAggregateType::class, + CreateNodeVariant::class, + TagSubtree::class, + UntagSubtree::class, + UpdateRootNodeAggregateDimensions::class, + => $command->nodeAggregateId->equals($nodeId), + CopyNodesRecursively::class => $command->nodeAggregateIdMapping->getNewNodeAggregateId( + $command->nodeTreeToInsert->nodeAggregateId + )?->equals($nodeId), + SetSerializedNodeReferences::class => $command->sourceNodeAggregateId->equals($nodeId), + // for non node-aggregate-changes we return false, so they are kept as remainder: + AddDimensionShineThrough::class, + MoveDimensionSpacePoint::class => false, + default => throw new \RuntimeException(sprintf('Command %s does not have matching strategy for node aggregate id (%s). Partial workspace rebase not possible.', $nodeId->value, $command::class), 1645393655) + }; + if ($matches) { return true; } } diff --git a/Neos.ContentRepository.Core/Classes/Feature/SubtreeTagging/Command/TagSubtree.php b/Neos.ContentRepository.Core/Classes/Feature/SubtreeTagging/Command/TagSubtree.php index 824bb402ca9..0c1adaa6ab6 100644 --- a/Neos.ContentRepository.Core/Classes/Feature/SubtreeTagging/Command/TagSubtree.php +++ b/Neos.ContentRepository.Core/Classes/Feature/SubtreeTagging/Command/TagSubtree.php @@ -16,10 +16,8 @@ use Neos\ContentRepository\Core\CommandHandler\CommandInterface; use Neos\ContentRepository\Core\DimensionSpace\DimensionSpacePoint; -use Neos\ContentRepository\Core\Feature\Common\MatchableWithNodeIdToPublishOrDiscardInterface; use Neos\ContentRepository\Core\Feature\Common\RebasableToOtherWorkspaceInterface; use Neos\ContentRepository\Core\Feature\SubtreeTagging\Dto\SubtreeTag; -use Neos\ContentRepository\Core\Feature\WorkspacePublication\Dto\NodeIdToPublishOrDiscard; use Neos\ContentRepository\Core\SharedModel\Node\NodeAggregateId; use Neos\ContentRepository\Core\SharedModel\Node\NodeVariantSelectionStrategy; use Neos\ContentRepository\Core\SharedModel\Workspace\WorkspaceName; @@ -32,8 +30,7 @@ final readonly class TagSubtree implements CommandInterface, \JsonSerializable, - RebasableToOtherWorkspaceInterface, - MatchableWithNodeIdToPublishOrDiscardInterface + RebasableToOtherWorkspaceInterface { /** * @param WorkspaceName $workspaceName The workspace in which the tagging operation is to be performed @@ -85,12 +82,6 @@ public function createCopyForWorkspace(WorkspaceName $targetWorkspaceName): self ); } - public function matchesNodeId(NodeIdToPublishOrDiscard $nodeIdToPublish): bool - { - return $this->nodeAggregateId->equals($nodeIdToPublish->nodeAggregateId) - && $nodeIdToPublish->dimensionSpacePoint === $this->coveredDimensionSpacePoint; - } - /** * @return array */ diff --git a/Neos.ContentRepository.Core/Classes/Feature/SubtreeTagging/Command/UntagSubtree.php b/Neos.ContentRepository.Core/Classes/Feature/SubtreeTagging/Command/UntagSubtree.php index 02bea45d58b..d0d49a47d5b 100644 --- a/Neos.ContentRepository.Core/Classes/Feature/SubtreeTagging/Command/UntagSubtree.php +++ b/Neos.ContentRepository.Core/Classes/Feature/SubtreeTagging/Command/UntagSubtree.php @@ -16,10 +16,8 @@ use Neos\ContentRepository\Core\CommandHandler\CommandInterface; use Neos\ContentRepository\Core\DimensionSpace\DimensionSpacePoint; -use Neos\ContentRepository\Core\Feature\Common\MatchableWithNodeIdToPublishOrDiscardInterface; use Neos\ContentRepository\Core\Feature\Common\RebasableToOtherWorkspaceInterface; use Neos\ContentRepository\Core\Feature\SubtreeTagging\Dto\SubtreeTag; -use Neos\ContentRepository\Core\Feature\WorkspacePublication\Dto\NodeIdToPublishOrDiscard; use Neos\ContentRepository\Core\SharedModel\Node\NodeAggregateId; use Neos\ContentRepository\Core\SharedModel\Node\NodeVariantSelectionStrategy; use Neos\ContentRepository\Core\SharedModel\Workspace\WorkspaceName; @@ -33,8 +31,7 @@ final readonly class UntagSubtree implements CommandInterface, \JsonSerializable, - RebasableToOtherWorkspaceInterface, - MatchableWithNodeIdToPublishOrDiscardInterface + RebasableToOtherWorkspaceInterface { /** * @param WorkspaceName $workspaceName The workspace in which the remove tag operation is to be performed @@ -86,12 +83,6 @@ public function createCopyForWorkspace(WorkspaceName $targetWorkspaceName): self ); } - public function matchesNodeId(NodeIdToPublishOrDiscard $nodeIdToPublish): bool - { - return $this->nodeAggregateId->equals($nodeIdToPublish->nodeAggregateId) - && $this->coveredDimensionSpacePoint === $nodeIdToPublish->dimensionSpacePoint; - } - /** * @return array */ diff --git a/Neos.ContentRepository.Core/Classes/Feature/WorkspaceCommandHandler.php b/Neos.ContentRepository.Core/Classes/Feature/WorkspaceCommandHandler.php index 3f166babf20..abb65c4c824 100644 --- a/Neos.ContentRepository.Core/Classes/Feature/WorkspaceCommandHandler.php +++ b/Neos.ContentRepository.Core/Classes/Feature/WorkspaceCommandHandler.php @@ -47,8 +47,6 @@ use Neos\ContentRepository\Core\Feature\WorkspacePublication\Command\PublishIndividualNodesFromWorkspace; use Neos\ContentRepository\Core\Feature\WorkspacePublication\Command\PublishWorkspace; use Neos\ContentRepository\Core\Feature\WorkspacePublication\Event\WorkspaceWasDiscarded; -use Neos\ContentRepository\Core\Feature\WorkspacePublication\Event\WorkspaceWasPartiallyDiscarded; -use Neos\ContentRepository\Core\Feature\WorkspacePublication\Event\WorkspaceWasPartiallyPublished; use Neos\ContentRepository\Core\Feature\WorkspacePublication\Event\WorkspaceWasPublished; use Neos\ContentRepository\Core\Feature\WorkspaceRebase\Command\RebaseWorkspace; use Neos\ContentRepository\Core\Feature\WorkspaceRebase\Dto\RebaseErrorHandlingStrategy; @@ -211,26 +209,6 @@ private function handlePublishWorkspace( $workspaceContentStreamVersion ); - yield from $this->publishWorkspace( - $workspace, - $baseWorkspace, - $baseWorkspaceContentStreamVersion, - $command->newContentStreamId, - $rebaseableCommands - ); - } - - /** - * Note that the workspaces content stream must be closed beforehand. - * It will be reopened here in case of error. - */ - private function publishWorkspace( - Workspace $workspace, - Workspace $baseWorkspace, - Version $baseWorkspaceContentStreamVersion, - ContentStreamId $newContentStreamId, - RebaseableCommands $rebaseableCommands - ): \Generator { $commandSimulator = $this->commandSimulatorFactory->createSimulatorForWorkspace($baseWorkspace->workspaceName); $commandSimulator->run( @@ -269,7 +247,7 @@ static function ($handle) use ($rebaseableCommands): void { } yield $this->forkContentStream( - $newContentStreamId, + $command->newContentStreamId, $baseWorkspace->currentContentStreamId, Version::fromInteger($baseWorkspaceContentStreamVersion->value + $eventsOfWorkspaceToPublish->count()) ); @@ -280,8 +258,9 @@ static function ($handle) use ($rebaseableCommands): void { new WorkspaceWasPublished( $workspace->workspaceName, $baseWorkspace->workspaceName, - $newContentStreamId, + $command->newContentStreamId, $workspace->currentContentStreamId, + partial: false ) ), ExpectedVersion::ANY() @@ -477,18 +456,6 @@ private function handlePublishIndividualNodesFromWorkspace( $workspaceContentStreamVersion ); - if ($remainingCommands->isEmpty()) { - // do a full publish, this is simpler for the projections to handle - yield from $this->publishWorkspace( - $workspace, - $baseWorkspace, - $baseWorkspaceContentStreamVersion, - $command->contentStreamIdForRemainingPart, - $matchingCommands - ); - return; - } - $commandSimulator = $this->commandSimulatorFactory->createSimulatorForWorkspace($baseWorkspace->workspaceName); $highestSequenceNumberForMatching = $commandSimulator->run( @@ -546,12 +513,12 @@ static function ($handle) use ($commandSimulator, $matchingCommands, $remainingC new EventsToPublish( WorkspaceEventStreamName::fromWorkspaceName($command->workspaceName)->getEventStreamName(), Events::fromArray([ - new WorkspaceWasPartiallyPublished( + new WorkspaceWasPublished( $command->workspaceName, $baseWorkspace->workspaceName, $command->contentStreamIdForRemainingPart, $workspace->currentContentStreamId, - $command->nodesToPublish + partial: !$remainingCommands->isEmpty() ) ]), ExpectedVersion::ANY() @@ -653,11 +620,11 @@ static function ($handle) use ($commandsToKeep): void { new EventsToPublish( WorkspaceEventStreamName::fromWorkspaceName($command->workspaceName)->getEventStreamName(), Events::with( - new WorkspaceWasPartiallyDiscarded( + new WorkspaceWasDiscarded( $command->workspaceName, $command->newContentStreamId, $workspace->currentContentStreamId, - $command->nodesToDiscard, + partial: true ) ), ExpectedVersion::ANY() @@ -721,6 +688,7 @@ private function discardWorkspace( $workspace->workspaceName, $newContentStream, $workspace->currentContentStreamId, + partial: false ) ), ExpectedVersion::ANY() diff --git a/Neos.ContentRepository.Core/Classes/Feature/WorkspacePublication/Command/DiscardIndividualNodesFromWorkspace.php b/Neos.ContentRepository.Core/Classes/Feature/WorkspacePublication/Command/DiscardIndividualNodesFromWorkspace.php index 7f6a2915c3d..220a65aba96 100644 --- a/Neos.ContentRepository.Core/Classes/Feature/WorkspacePublication/Command/DiscardIndividualNodesFromWorkspace.php +++ b/Neos.ContentRepository.Core/Classes/Feature/WorkspacePublication/Command/DiscardIndividualNodesFromWorkspace.php @@ -15,7 +15,7 @@ namespace Neos\ContentRepository\Core\Feature\WorkspacePublication\Command; use Neos\ContentRepository\Core\CommandHandler\CommandInterface; -use Neos\ContentRepository\Core\Feature\WorkspacePublication\Dto\NodeIdsToPublishOrDiscard; +use Neos\ContentRepository\Core\SharedModel\Node\NodeAggregateIds; use Neos\ContentRepository\Core\SharedModel\Workspace\ContentStreamId; use Neos\ContentRepository\Core\SharedModel\Workspace\WorkspaceName; @@ -28,23 +28,23 @@ { /** * @param WorkspaceName $workspaceName Name of the affected workspace - * @param NodeIdsToPublishOrDiscard $nodesToDiscard Ids of the nodes to be discarded + * @param NodeAggregateIds $nodesToDiscard Ids of the nodes to be discarded * @param ContentStreamId $newContentStreamId The id of the new content stream, that will contain the remaining changes which were not discarded */ private function __construct( public WorkspaceName $workspaceName, - public NodeIdsToPublishOrDiscard $nodesToDiscard, + public NodeAggregateIds $nodesToDiscard, public ContentStreamId $newContentStreamId ) { } /** * @param WorkspaceName $workspaceName Name of the affected workspace - * @param NodeIdsToPublishOrDiscard $nodesToDiscard Ids of the nodes to be discarded + * @param NodeAggregateIds $nodesToDiscard Ids of the nodes to be discarded */ public static function create( WorkspaceName $workspaceName, - NodeIdsToPublishOrDiscard $nodesToDiscard, + NodeAggregateIds $nodesToDiscard, ): self { return new self( $workspaceName, @@ -57,7 +57,7 @@ public static function fromArray(array $array): self { return new self( WorkspaceName::fromString($array['workspaceName']), - NodeIdsToPublishOrDiscard::fromArray($array['nodesToDiscard']), + NodeAggregateIds::fromArray($array['nodesToDiscard']), isset($array['newContentStreamId']) ? ContentStreamId::fromString($array['newContentStreamId']) : ContentStreamId::create(), ); } diff --git a/Neos.ContentRepository.Core/Classes/Feature/WorkspacePublication/Command/PublishIndividualNodesFromWorkspace.php b/Neos.ContentRepository.Core/Classes/Feature/WorkspacePublication/Command/PublishIndividualNodesFromWorkspace.php index 7f9cf111dd8..77407e412b2 100644 --- a/Neos.ContentRepository.Core/Classes/Feature/WorkspacePublication/Command/PublishIndividualNodesFromWorkspace.php +++ b/Neos.ContentRepository.Core/Classes/Feature/WorkspacePublication/Command/PublishIndividualNodesFromWorkspace.php @@ -15,7 +15,7 @@ namespace Neos\ContentRepository\Core\Feature\WorkspacePublication\Command; use Neos\ContentRepository\Core\CommandHandler\CommandInterface; -use Neos\ContentRepository\Core\Feature\WorkspacePublication\Dto\NodeIdsToPublishOrDiscard; +use Neos\ContentRepository\Core\SharedModel\Node\NodeAggregateIds; use Neos\ContentRepository\Core\SharedModel\Workspace\ContentStreamId; use Neos\ContentRepository\Core\SharedModel\Workspace\WorkspaceName; @@ -28,21 +28,21 @@ { /** * @param WorkspaceName $workspaceName Name of the affected workspace - * @param NodeIdsToPublishOrDiscard $nodesToPublish Ids of the nodes to publish or discard + * @param NodeAggregateIds $nodesToPublish Ids of the nodes to publish or discard * @param ContentStreamId $contentStreamIdForRemainingPart The id of the new content stream that will contain all remaining events {@see self::withContentStreamIdForRemainingPart()} */ private function __construct( public WorkspaceName $workspaceName, - public NodeIdsToPublishOrDiscard $nodesToPublish, + public NodeAggregateIds $nodesToPublish, public ContentStreamId $contentStreamIdForRemainingPart ) { } /** * @param WorkspaceName $workspaceName Name of the affected workspace - * @param NodeIdsToPublishOrDiscard $nodesToPublish Ids of the nodes to publish or discard + * @param NodeAggregateIds $nodesToPublish Ids of the nodes to publish or discard */ - public static function create(WorkspaceName $workspaceName, NodeIdsToPublishOrDiscard $nodesToPublish): self + public static function create(WorkspaceName $workspaceName, NodeAggregateIds $nodesToPublish): self { return new self( $workspaceName, @@ -55,7 +55,7 @@ public static function fromArray(array $array): self { return new self( WorkspaceName::fromString($array['workspaceName']), - NodeIdsToPublishOrDiscard::fromArray($array['nodesToPublish']), + NodeAggregateIds::fromArray($array['nodesToPublish']), isset($array['contentStreamIdForRemainingPart']) ? ContentStreamId::fromString($array['contentStreamIdForRemainingPart']) : ContentStreamId::create(), ); } diff --git a/Neos.ContentRepository.Core/Classes/Feature/WorkspacePublication/Dto/NodeIdToPublishOrDiscard.php b/Neos.ContentRepository.Core/Classes/Feature/WorkspacePublication/Dto/NodeIdToPublishOrDiscard.php deleted file mode 100644 index b2b5c346be7..00000000000 --- a/Neos.ContentRepository.Core/Classes/Feature/WorkspacePublication/Dto/NodeIdToPublishOrDiscard.php +++ /dev/null @@ -1,58 +0,0 @@ - $array - */ - public static function fromArray(array $array): self - { - return new self( - NodeAggregateId::fromString($array['nodeAggregateId']), - is_array($array['dimensionSpacePoint'] ?? null) - ? DimensionSpacePoint::fromArray($array['dimensionSpacePoint']) - : null, - ); - } - - /** - * @return array - */ - public function jsonSerialize(): array - { - return get_object_vars($this); - } -} diff --git a/Neos.ContentRepository.Core/Classes/Feature/WorkspacePublication/Dto/NodeIdsToPublishOrDiscard.php b/Neos.ContentRepository.Core/Classes/Feature/WorkspacePublication/Dto/NodeIdsToPublishOrDiscard.php deleted file mode 100644 index 53aa7a73363..00000000000 --- a/Neos.ContentRepository.Core/Classes/Feature/WorkspacePublication/Dto/NodeIdsToPublishOrDiscard.php +++ /dev/null @@ -1,76 +0,0 @@ - - * @api used as part of commands - */ -final readonly class NodeIdsToPublishOrDiscard implements \IteratorAggregate, \Countable, \JsonSerializable -{ - /** - * @param array $nodeIds - */ - private function __construct( - public array $nodeIds - ) { - } - - public static function create(NodeIdToPublishOrDiscard ...$nodeIds): self - { - return new self($nodeIds); - } - - /** - * @param array> $nodeIdData - */ - public static function fromArray(array $nodeIdData): self - { - return new self(array_map( - fn (array $nodeIdDatum): NodeIdToPublishOrDiscard => NodeIdToPublishOrDiscard::fromArray($nodeIdDatum), - $nodeIdData - )); - } - - public function merge(self $other): self - { - return new self(array_merge($this->nodeIds, $other->nodeIds)); - } - - public function getIterator(): \Traversable - { - yield from $this->nodeIds; - } - - public function isEmpty(): bool - { - return $this->nodeIds === []; - } - - public function count(): int - { - return count($this->nodeIds); - } - - /** - * @return array - */ - public function jsonSerialize(): array - { - return $this->nodeIds; - } -} 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 d9d88cddfac..3748848a7c8 100644 --- a/Neos.ContentRepository.Core/Classes/Feature/WorkspacePublication/Event/WorkspaceWasPartiallyDiscarded.php +++ b/Neos.ContentRepository.Core/Classes/Feature/WorkspacePublication/Event/WorkspaceWasPartiallyDiscarded.php @@ -15,47 +15,32 @@ namespace Neos\ContentRepository\Core\Feature\WorkspacePublication\Event; use Neos\ContentRepository\Core\EventStore\EventInterface; -use Neos\ContentRepository\Core\Feature\Common\EmbedsWorkspaceName; -use Neos\ContentRepository\Core\Feature\WorkspacePublication\Dto\NodeIdsToPublishOrDiscard; use Neos\ContentRepository\Core\SharedModel\Workspace\ContentStreamId; use Neos\ContentRepository\Core\SharedModel\Workspace\WorkspaceName; /** - * @api events are the persistence-API of the content repository + * @deprecated This event will never be emitted, it is up-casted to a corresponding {@see WorkspaceWasDiscarded} event instead. This implementation is just kept for backwards-compatibility + * @internal */ -final readonly class WorkspaceWasPartiallyDiscarded implements EventInterface, EmbedsWorkspaceName +final readonly class WorkspaceWasPartiallyDiscarded implements EventInterface { - public function __construct( - public WorkspaceName $workspaceName, - /** - * The new content stream; containing the data which we want to keep - */ - public ContentStreamId $newContentStreamId, - /** - * The old content stream, which contains ALL the data (discarded and non-discarded) - */ - public ContentStreamId $previousContentStreamId, - public NodeIdsToPublishOrDiscard $discardedNodes, - ) { - } - - public function getWorkspaceName(): WorkspaceName + private function __construct() { - return $this->workspaceName; + // legacy event must not be instantiated } - public static function fromArray(array $values): self + public static function fromArray(array $values): EventInterface { - return new self( + return new WorkspaceWasDiscarded( WorkspaceName::fromString($values['workspaceName']), ContentStreamId::fromString($values['newContentStreamId']), ContentStreamId::fromString($values['previousContentStreamId']), - NodeIdsToPublishOrDiscard::fromArray($values['discardedNodes']), + partial: true ); } public function jsonSerialize(): array { - return get_object_vars($this); + throw new \RuntimeException('Legacy event instance must not exist.'); } } diff --git a/Neos.ContentRepository.Core/Classes/Feature/WorkspacePublication/Event/WorkspaceWasPartiallyPublished.php b/Neos.ContentRepository.Core/Classes/Feature/WorkspacePublication/Event/WorkspaceWasPartiallyPublished.php index f07ef11882d..8c69c49b22c 100644 --- a/Neos.ContentRepository.Core/Classes/Feature/WorkspacePublication/Event/WorkspaceWasPartiallyPublished.php +++ b/Neos.ContentRepository.Core/Classes/Feature/WorkspacePublication/Event/WorkspaceWasPartiallyPublished.php @@ -15,49 +15,33 @@ namespace Neos\ContentRepository\Core\Feature\WorkspacePublication\Event; use Neos\ContentRepository\Core\EventStore\EventInterface; -use Neos\ContentRepository\Core\Feature\WorkspacePublication\Dto\NodeIdsToPublishOrDiscard; use Neos\ContentRepository\Core\SharedModel\Workspace\ContentStreamId; use Neos\ContentRepository\Core\SharedModel\Workspace\WorkspaceName; /** - * @api events are the persistence-API of the content repository + * @deprecated This event will never be emitted, it is up-casted to a corresponding {@see WorkspaceWasPublished} event instead. This implementation is just kept for backwards-compatibility + * @internal */ final readonly class WorkspaceWasPartiallyPublished implements EventInterface { - public function __construct( - /** - * From which workspace have changes been partially published? - */ - public WorkspaceName $sourceWorkspaceName, - /** - * The target workspace where the changes have been published to. - */ - public WorkspaceName $targetWorkspaceName, - /** - * The new content stream for the $sourceWorkspaceName - */ - public ContentStreamId $newSourceContentStreamId, - /** - * The old content stream, which contains ALL the data (discarded and non-discarded) - */ - public ContentStreamId $previousSourceContentStreamId, - public NodeIdsToPublishOrDiscard $publishedNodes, - ) { + private function __construct() + { + // legacy event must not be instantiated } - public static function fromArray(array $values): self + public static function fromArray(array $values): EventInterface { - return new self( + return new WorkspaceWasPublished( WorkspaceName::fromString($values['sourceWorkspaceName']), WorkspaceName::fromString($values['targetWorkspaceName']), ContentStreamId::fromString($values['newSourceContentStreamId']), ContentStreamId::fromString($values['previousSourceContentStreamId']), - NodeIdsToPublishOrDiscard::fromArray($values['publishedNodes']), + partial: true ); } public function jsonSerialize(): array { - return get_object_vars($this); + throw new \RuntimeException('Legacy event instance must not exist.'); } } 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, ); } diff --git a/Neos.ContentRepository.Core/Classes/Service/ContentStreamPruner.php b/Neos.ContentRepository.Core/Classes/Service/ContentStreamPruner.php index 5afbcddc590..6ed5d7c09fc 100644 --- a/Neos.ContentRepository.Core/Classes/Service/ContentStreamPruner.php +++ b/Neos.ContentRepository.Core/Classes/Service/ContentStreamPruner.php @@ -15,8 +15,6 @@ use Neos\ContentRepository\Core\Feature\WorkspaceCreation\Event\WorkspaceWasCreated; use Neos\ContentRepository\Core\Feature\WorkspaceEventStreamName; use Neos\ContentRepository\Core\Feature\WorkspacePublication\Event\WorkspaceWasDiscarded; -use Neos\ContentRepository\Core\Feature\WorkspacePublication\Event\WorkspaceWasPartiallyDiscarded; -use Neos\ContentRepository\Core\Feature\WorkspacePublication\Event\WorkspaceWasPartiallyPublished; use Neos\ContentRepository\Core\Feature\WorkspacePublication\Event\WorkspaceWasPublished; use Neos\ContentRepository\Core\Feature\WorkspaceRebase\Event\WorkspaceRebaseFailed; use Neos\ContentRepository\Core\Feature\WorkspaceRebase\Event\WorkspaceWasRebased; @@ -323,6 +321,7 @@ private function findAllContentStreams(): array EventType::fromString('RootWorkspaceWasCreated'), EventType::fromString('WorkspaceWasCreated'), EventType::fromString('WorkspaceWasDiscarded'), + // we must include these two legacy events in the query for they exist and will be upcasted at runtime EventType::fromString('WorkspaceWasPartiallyDiscarded'), EventType::fromString('WorkspaceWasPartiallyPublished'), EventType::fromString('WorkspaceWasPublished'), @@ -358,26 +357,6 @@ private function findAllContentStreams(): array ->withStatus(ContentStreamStatus::NO_LONGER_IN_USE); } break; - case WorkspaceWasPartiallyDiscarded::class: - if (isset($cs[$domainEvent->newContentStreamId->value])) { - $cs[$domainEvent->newContentStreamId->value] = $cs[$domainEvent->newContentStreamId->value] - ->withStatus(ContentStreamStatus::IN_USE_BY_WORKSPACE); - } - if (isset($cs[$domainEvent->previousContentStreamId->value])) { - $cs[$domainEvent->previousContentStreamId->value] = $cs[$domainEvent->previousContentStreamId->value] - ->withStatus(ContentStreamStatus::NO_LONGER_IN_USE); - } - break; - case WorkspaceWasPartiallyPublished::class: - if (isset($cs[$domainEvent->newSourceContentStreamId->value])) { - $cs[$domainEvent->newSourceContentStreamId->value] = $cs[$domainEvent->newSourceContentStreamId->value] - ->withStatus(ContentStreamStatus::IN_USE_BY_WORKSPACE); - } - if (isset($cs[$domainEvent->previousSourceContentStreamId->value])) { - $cs[$domainEvent->previousSourceContentStreamId->value] = $cs[$domainEvent->previousSourceContentStreamId->value] - ->withStatus(ContentStreamStatus::NO_LONGER_IN_USE); - } - break; case WorkspaceWasPublished::class: if (isset($cs[$domainEvent->newSourceContentStreamId->value])) { $cs[$domainEvent->newSourceContentStreamId->value] = $cs[$domainEvent->newSourceContentStreamId->value] diff --git a/Neos.ContentRepository.Core/Classes/SharedModel/Node/NodeAggregateIds.php b/Neos.ContentRepository.Core/Classes/SharedModel/Node/NodeAggregateIds.php index f0e30b17b67..3b400ac31ba 100644 --- a/Neos.ContentRepository.Core/Classes/SharedModel/Node/NodeAggregateIds.php +++ b/Neos.ContentRepository.Core/Classes/SharedModel/Node/NodeAggregateIds.php @@ -128,4 +128,9 @@ public function count(): int { return count($this->nodeAggregateIds); } + + public function isEmpty(): bool + { + return $this->nodeAggregateIds === []; + } } diff --git a/Neos.Neos/Classes/AssetUsage/CatchUpHook/AssetUsageCatchUpHook.php b/Neos.Neos/Classes/AssetUsage/CatchUpHook/AssetUsageCatchUpHook.php index 59e2c733a99..631175e83d8 100644 --- a/Neos.Neos/Classes/AssetUsage/CatchUpHook/AssetUsageCatchUpHook.php +++ b/Neos.Neos/Classes/AssetUsage/CatchUpHook/AssetUsageCatchUpHook.php @@ -7,7 +7,6 @@ use Neos\ContentRepository\Core\DimensionSpace\DimensionSpacePoint; use Neos\ContentRepository\Core\DimensionSpace\DimensionSpacePointSet; use Neos\ContentRepository\Core\EventStore\EventInterface; -use Neos\ContentRepository\Core\Feature\Common\EmbedsContentStreamId; use Neos\ContentRepository\Core\Feature\Common\EmbedsWorkspaceName; use Neos\ContentRepository\Core\Feature\DimensionSpaceAdjustment\Event\DimensionSpacePointWasMoved; use Neos\ContentRepository\Core\Feature\NodeCreation\Event\NodeAggregateWithNodeWasCreated; @@ -16,9 +15,7 @@ use Neos\ContentRepository\Core\Feature\NodeVariation\Event\NodeGeneralizationVariantWasCreated; use Neos\ContentRepository\Core\Feature\NodeVariation\Event\NodePeerVariantWasCreated; use Neos\ContentRepository\Core\Feature\NodeVariation\Event\NodeSpecializationVariantWasCreated; -use Neos\ContentRepository\Core\Feature\WorkspacePublication\Dto\NodeIdsToPublishOrDiscard; use Neos\ContentRepository\Core\Feature\WorkspacePublication\Event\WorkspaceWasDiscarded; -use Neos\ContentRepository\Core\Feature\WorkspacePublication\Event\WorkspaceWasPartiallyDiscarded; use Neos\ContentRepository\Core\Projection\CatchUpHookInterface; use Neos\ContentRepository\Core\Projection\ContentGraph\ContentGraphReadModelInterface; use Neos\ContentRepository\Core\Projection\ContentGraph\Filter\FindDescendantNodesFilter; @@ -60,7 +57,6 @@ public function onBeforeEvent(EventInterface $eventInstance, EventEnvelope $even match ($eventInstance::class) { NodeAggregateWasRemoved::class => $this->removeNodes($eventInstance->getWorkspaceName(), $eventInstance->nodeAggregateId, $eventInstance->affectedCoveredDimensionSpacePoints), - WorkspaceWasPartiallyDiscarded::class => $this->discardNodes($eventInstance->getWorkspaceName(), $eventInstance->discardedNodes), default => null }; } @@ -145,22 +141,6 @@ private function discardWorkspace(WorkspaceName $workspaceName): void $this->assetUsageIndexingService->removeIndexForWorkspace($this->contentRepositoryId, $workspaceName); } - private function discardNodes(WorkspaceName $workspaceName, NodeIdsToPublishOrDiscard $nodeIds): void - { - foreach ($nodeIds as $nodeId) { - if (!$nodeId->dimensionSpacePoint) { - // NodeAggregateTypeWasChanged and NodeAggregateNameWasChanged don't impact asset usage - continue; - } - $this->assetUsageIndexingService->removeIndexForWorkspaceNameNodeAggregateIdAndDimensionSpacePoint( - $this->contentRepositoryId, - $workspaceName, - $nodeId->nodeAggregateId, - $nodeId->dimensionSpacePoint - ); - } - } - private function updateDimensionSpacePoint(WorkspaceName $workspaceName, DimensionSpacePoint $source, DimensionSpacePoint $target): void { $this->assetUsageIndexingService->updateDimensionSpacePointInIndex($this->contentRepositoryId, $workspaceName, $source, $target); diff --git a/Neos.Neos/Classes/Domain/Service/WorkspacePublishingService.php b/Neos.Neos/Classes/Domain/Service/WorkspacePublishingService.php index dea005af9e1..49c2e5ce40c 100644 --- a/Neos.Neos/Classes/Domain/Service/WorkspacePublishingService.php +++ b/Neos.Neos/Classes/Domain/Service/WorkspacePublishingService.php @@ -21,8 +21,6 @@ use Neos\ContentRepository\Core\Feature\WorkspacePublication\Command\DiscardWorkspace; use Neos\ContentRepository\Core\Feature\WorkspacePublication\Command\PublishIndividualNodesFromWorkspace; use Neos\ContentRepository\Core\Feature\WorkspacePublication\Command\PublishWorkspace; -use Neos\ContentRepository\Core\Feature\WorkspacePublication\Dto\NodeIdsToPublishOrDiscard; -use Neos\ContentRepository\Core\Feature\WorkspacePublication\Dto\NodeIdToPublishOrDiscard; use Neos\ContentRepository\Core\Feature\WorkspaceRebase\Command\RebaseWorkspace; use Neos\ContentRepository\Core\Feature\WorkspaceRebase\Dto\RebaseErrorHandlingStrategy; use Neos\ContentRepository\Core\Feature\WorkspaceRebase\Exception\WorkspaceRebaseFailed; @@ -266,7 +264,7 @@ public function changeBaseWorkspace(ContentRepositoryId $contentRepositoryId, Wo private function discardNodes( ContentRepository $contentRepository, WorkspaceName $workspaceName, - NodeIdsToPublishOrDiscard $nodeIdsToDiscard + NodeAggregateIds $nodeIdsToDiscard ): void { $contentRepository->handle( DiscardIndividualNodesFromWorkspace::create( @@ -283,7 +281,7 @@ private function discardNodes( private function publishNodes( ContentRepository $contentRepository, WorkspaceName $workspaceName, - NodeIdsToPublishOrDiscard $nodeIdsToPublish + NodeAggregateIds $nodeIdsToPublish ): void { $contentRepository->handle( PublishIndividualNodesFromWorkspace::create( @@ -341,7 +339,7 @@ private function resolveNodeIdsToPublishOrDiscard( WorkspaceName $workspaceName, NodeAggregateId $ancestorId, NodeTypeName $ancestorNodeTypeName - ): NodeIdsToPublishOrDiscard { + ): NodeAggregateIds { $nodeIdsToPublishOrDiscard = []; foreach ($this->pendingWorkspaceChangesInternal($contentRepository, $workspaceName) as $change) { if ( @@ -356,13 +354,10 @@ private function resolveNodeIdsToPublishOrDiscard( continue; } - $nodeIdsToPublishOrDiscard[] = new NodeIdToPublishOrDiscard( - $change->nodeAggregateId, - $change->originDimensionSpacePoint?->toDimensionSpacePoint() - ); + $nodeIdsToPublishOrDiscard[] = $change->nodeAggregateId; } - return NodeIdsToPublishOrDiscard::create(...$nodeIdsToPublishOrDiscard); + return NodeAggregateIds::create(...$nodeIdsToPublishOrDiscard); } private function pendingWorkspaceChangesInternal(ContentRepository $contentRepository, WorkspaceName $workspaceName): Changes diff --git a/Neos.Neos/Classes/Fusion/Cache/GraphProjectorCatchUpHookForCacheFlushing.php b/Neos.Neos/Classes/Fusion/Cache/GraphProjectorCatchUpHookForCacheFlushing.php index 4acf758411e..ec1b8ac4c5c 100644 --- a/Neos.Neos/Classes/Fusion/Cache/GraphProjectorCatchUpHookForCacheFlushing.php +++ b/Neos.Neos/Classes/Fusion/Cache/GraphProjectorCatchUpHookForCacheFlushing.php @@ -32,7 +32,6 @@ use Neos\ContentRepository\Core\Feature\SubtreeTagging\Event\SubtreeWasTagged; use Neos\ContentRepository\Core\Feature\SubtreeTagging\Event\SubtreeWasUntagged; use Neos\ContentRepository\Core\Feature\WorkspacePublication\Event\WorkspaceWasDiscarded; -use Neos\ContentRepository\Core\Feature\WorkspacePublication\Event\WorkspaceWasPartiallyDiscarded; use Neos\ContentRepository\Core\Feature\WorkspaceRebase\Event\WorkspaceWasRebased; use Neos\ContentRepository\Core\Projection\CatchUpHookInterface; use Neos\ContentRepository\Core\Projection\ContentGraph\ContentGraphReadModelInterface; @@ -130,7 +129,6 @@ public function canHandle(EventInterface $event): bool SubtreeWasTagged::class, SubtreeWasUntagged::class, WorkspaceWasDiscarded::class, - WorkspaceWasPartiallyDiscarded::class, WorkspaceWasRebased::class ]); } @@ -190,7 +188,6 @@ public function onAfterEvent(EventInterface $eventInstance, EventEnvelope $event if ( $eventInstance instanceof WorkspaceWasDiscarded - || $eventInstance instanceof WorkspaceWasPartiallyDiscarded || $eventInstance instanceof WorkspaceWasRebased ) { $this->scheduleCacheFlushJobForWorkspaceName($this->contentRepositoryId, $eventInstance->workspaceName); diff --git a/Neos.Neos/Tests/Behavior/Features/AssetUsage/W01-WorkspacePublication/03-PublishIndividualNodesFromWorkspace_WithoutDimensions.feature b/Neos.Neos/Tests/Behavior/Features/AssetUsage/W01-WorkspacePublication/03-PublishIndividualNodesFromWorkspace_WithoutDimensions.feature index 3d56189288c..e6c292625a1 100644 --- a/Neos.Neos/Tests/Behavior/Features/AssetUsage/W01-WorkspacePublication/03-PublishIndividualNodesFromWorkspace_WithoutDimensions.feature +++ b/Neos.Neos/Tests/Behavior/Features/AssetUsage/W01-WorkspacePublication/03-PublishIndividualNodesFromWorkspace_WithoutDimensions.feature @@ -63,7 +63,7 @@ Feature: Publish nodes partially without dimensions When the command PublishIndividualNodesFromWorkspace is executed with payload: | Key | Value | - | nodesToPublish | [{"workspaceName": "user-workspace", "dimensionSpacePoint": {}, "nodeAggregateId": "sir-david-nodenborough"}] | + | nodesToPublish | ["sir-david-nodenborough"] | | contentStreamIdForRemainingPart | "user-cs-identifier-remaining" | Then I expect the AssetUsageService to have the following AssetUsages: @@ -111,7 +111,7 @@ Feature: Publish nodes partially without dimensions When the command PublishIndividualNodesFromWorkspace is executed with payload: | Key | Value | - | nodesToPublish | [{"workspaceName": "user-workspace", "dimensionSpacePoint": {}, "nodeAggregateId": "sir-david-nodenborough"}] | + | nodesToPublish | ["sir-david-nodenborough"] | | contentStreamIdForRemainingPart | "user-cs-identifier-remaining" | And I expect the AssetUsageService to have the following AssetUsages: diff --git a/Neos.Neos/Tests/Behavior/Features/AssetUsage/W01-WorkspacePublication/04-PublishIndividualNodesFromWorkspace_WithDimensions.feature b/Neos.Neos/Tests/Behavior/Features/AssetUsage/W01-WorkspacePublication/04-PublishIndividualNodesFromWorkspace_WithDimensions.feature index 932602a17dd..db01883e695 100644 --- a/Neos.Neos/Tests/Behavior/Features/AssetUsage/W01-WorkspacePublication/04-PublishIndividualNodesFromWorkspace_WithDimensions.feature +++ b/Neos.Neos/Tests/Behavior/Features/AssetUsage/W01-WorkspacePublication/04-PublishIndividualNodesFromWorkspace_WithDimensions.feature @@ -69,7 +69,7 @@ Feature: Publish nodes partially with dimensions When the command PublishIndividualNodesFromWorkspace is executed with payload: | Key | Value | - | nodesToPublish | [{"workspaceName": "user-workspace", "dimensionSpacePoint": {"language": "de"}, "nodeAggregateId": "sir-david-nodenborough"}] | + | nodesToPublish | ["sir-david-nodenborough"] | | contentStreamIdForRemainingPart | "user-cs-identifier-remaining" | Then I expect the AssetUsageService to have the following AssetUsages: @@ -135,7 +135,7 @@ Feature: Publish nodes partially with dimensions When the command PublishIndividualNodesFromWorkspace is executed with payload: | Key | Value | - | nodesToPublish | [{"workspaceName": "user-workspace", "dimensionSpacePoint": {"language": "de"}, "nodeAggregateId": "sir-david-nodenborough"}] | + | nodesToPublish | ["sir-david-nodenborough"] | | contentStreamIdForRemainingPart | "user-cs-identifier-remaining" | Then I expect the AssetUsageService to have the following AssetUsages: @@ -180,7 +180,7 @@ Feature: Publish nodes partially with dimensions When the command PublishIndividualNodesFromWorkspace is executed with payload: | Key | Value | - | nodesToPublish | [{"workspaceName": "user-workspace", "dimensionSpacePoint": {"language": "de"}, "nodeAggregateId": "sir-david-nodenborough"},{"workspaceName": "user-workspace", "dimensionSpacePoint": {"language": "en"}, "nodeAggregateId": "sir-david-nodenborough"}] | + | nodesToPublish | ["sir-david-nodenborough"] | | contentStreamIdForRemainingPart | "user-cs-identifier-remaining" | And I expect the AssetUsageService to have the following AssetUsages: diff --git a/Neos.Neos/Tests/Behavior/Features/AssetUsage/W02-WorkspaceDiscarding/03-DiscardIndividualNodesFromWorkspace_WithoutDimensions.feature b/Neos.Neos/Tests/Behavior/Features/AssetUsage/W02-WorkspaceDiscarding/03-DiscardIndividualNodesFromWorkspace_WithoutDimensions.feature index 1f9927aeb50..94f90ccf63a 100644 --- a/Neos.Neos/Tests/Behavior/Features/AssetUsage/W02-WorkspaceDiscarding/03-DiscardIndividualNodesFromWorkspace_WithoutDimensions.feature +++ b/Neos.Neos/Tests/Behavior/Features/AssetUsage/W02-WorkspaceDiscarding/03-DiscardIndividualNodesFromWorkspace_WithoutDimensions.feature @@ -68,7 +68,7 @@ Feature: Discard nodes partially without dimensions When the command DiscardIndividualNodesFromWorkspace is executed with payload: | Key | Value | | workspaceName | "user-workspace" | - | nodesToDiscard | [{"workspaceName": "user-workspace", "dimensionSpacePoint": {}, "nodeAggregateId": "sir-nodeward-nodington-iiii"}] | + | nodesToDiscard | ["sir-nodeward-nodington-iiii"] | | newContentStreamId | "user-cs-identifier-new" | Then I expect the AssetUsageService to have the following AssetUsages: @@ -105,7 +105,7 @@ Feature: Discard nodes partially without dimensions When the command DiscardIndividualNodesFromWorkspace is executed with payload: | Key | Value | | workspaceName | "user-workspace" | - | nodesToDiscard | [{"workspaceName": "user-workspace", "dimensionSpacePoint": {}, "nodeAggregateId": "sir-nodeward-nodington-iii"},{"workspaceName": "user-workspace", "dimensionSpacePoint": {}, "nodeAggregateId": "sir-nodeward-nodington-iiii"}] | + | nodesToDiscard | ["sir-nodeward-nodington-iii", "sir-nodeward-nodington-iiii"] | | newContentStreamId | "user-cs-identifier-new" | Then I expect the AssetUsageService to have the following AssetUsages: @@ -157,7 +157,7 @@ Feature: Discard nodes partially without dimensions When the command DiscardIndividualNodesFromWorkspace is executed with payload: | Key | Value | | workspaceName | "user-workspace" | - | nodesToDiscard | [{"workspaceName": "user-workspace", "dimensionSpacePoint": {}, "nodeAggregateId": "sir-nodeward-nodington-iiii"}] | + | nodesToDiscard | ["sir-nodeward-nodington-iiii"] | | newContentStreamId | "user-cs-identifier-new" | And I expect the AssetUsageService to have the following AssetUsages: @@ -210,7 +210,7 @@ Feature: Discard nodes partially without dimensions When the command DiscardIndividualNodesFromWorkspace is executed with payload: | Key | Value | | workspaceName | "user-workspace" | - | nodesToDiscard | [{"workspaceName": "user-workspace", "dimensionSpacePoint": {}, "nodeAggregateId": "sir-nodeward-nodington-iii"},{"workspaceName": "user-workspace", "dimensionSpacePoint": {}, "nodeAggregateId": "sir-nodeward-nodington-iiii"}] | + | nodesToDiscard | ["sir-nodeward-nodington-iii", "sir-nodeward-nodington-iiii"] | | newContentStreamId | "user-cs-identifier-new" | And I expect the AssetUsageService to have the following AssetUsages: diff --git a/Neos.Neos/Tests/Behavior/Features/AssetUsage/W02-WorkspaceDiscarding/04-DiscardIndividualNodesFromWorkspace_WithDimensions.feature b/Neos.Neos/Tests/Behavior/Features/AssetUsage/W02-WorkspaceDiscarding/04-DiscardIndividualNodesFromWorkspace_WithDimensions.feature index e34fcaa0303..ce7811f4421 100644 --- a/Neos.Neos/Tests/Behavior/Features/AssetUsage/W02-WorkspaceDiscarding/04-DiscardIndividualNodesFromWorkspace_WithDimensions.feature +++ b/Neos.Neos/Tests/Behavior/Features/AssetUsage/W02-WorkspaceDiscarding/04-DiscardIndividualNodesFromWorkspace_WithDimensions.feature @@ -70,7 +70,7 @@ Feature: Discard nodes partially with dimensions When the command DiscardIndividualNodesFromWorkspace is executed with payload: | Key | Value | | workspaceName | "user-workspace" | - | nodesToDiscard | [{"workspaceName": "user-workspace", "dimensionSpacePoint": {"language": "de"}, "nodeAggregateId": "sir-david-nodenborough"}, {"workspaceName": "user-workspace", "dimensionSpacePoint": {"language": "de"}, "nodeAggregateId": "nody-mc-nodeface"}] | + | nodesToDiscard | ["sir-david-nodenborough", "nody-mc-nodeface"] | | newContentStreamId | "user-cs-identifier-new" | Then I expect the AssetUsageService to have the following AssetUsages: @@ -135,13 +135,12 @@ Feature: Discard nodes partially with dimensions When the command DiscardIndividualNodesFromWorkspace is executed with payload: | Key | Value | | workspaceName | "user-workspace" | - | nodesToDiscard | [{"workspaceName": "user-workspace", "dimensionSpacePoint": {"language": "gsw"}, "nodeAggregateId": "nody-mc-nodeface"}] | + | nodesToDiscard | ["nody-mc-nodeface"] | | newContentStreamId | "user-cs-identifier-new" | Then I expect the AssetUsageService to have the following AssetUsages: | assetId | nodeAggregateId | propertyName | workspaceName | originDimensionSpacePoint | | asset-1 | sir-david-nodenborough | asset | user-workspace | {"language": "de"} | - | asset-2 | nody-mc-nodeface | assets | user-workspace | {"language": "de"} | | asset-3 | sir-nodeward-nodington-iii | text | user-workspace | {"language": "fr"} | Scenario: Discard nodes partially from user workspace with live base workspace with new generalization @@ -151,10 +150,6 @@ Feature: Discard nodes partially with dimensions | baseWorkspaceName | "live" | | newContentStreamId | "user-cs-id" | And I am in workspace "user-workspace" - And the command RebaseWorkspace is executed with payload: - | Key | Value | - | workspaceName | "user-workspace" | - Then I am in dimension space point {"language": "de"} And the following CreateNodeAggregateWithNode commands are executed: | nodeAggregateId | nodeName | parentNodeAggregateId | nodeTypeName | initialPropertyValues | @@ -179,10 +174,8 @@ Feature: Discard nodes partially with dimensions When the command DiscardIndividualNodesFromWorkspace is executed with payload: | Key | Value | | workspaceName | "user-workspace" | - | nodesToDiscard | [{"workspaceName": "user-workspace", "dimensionSpacePoint": {"language": "en"} , "nodeAggregateId": "sir-david-nodenborough"}, {"workspaceName": "user-workspace", "dimensionSpacePoint": {"language": "de"} , "nodeAggregateId": "sir-nodeward-nodington-iii"}] | - | newContentStreamId | "user-cs-identifier-new" | + | nodesToDiscard | ["sir-david-nodenborough", "nody-mc-nodeface", "sir-nodeward-nodington-iii"] | + | newContentStreamId | "user-cs-identifier-new" | And I expect the AssetUsageService to have the following AssetUsages: - | assetId | nodeAggregateId | propertyName | workspaceName | originDimensionSpacePoint | - | asset-1 | sir-david-nodenborough | asset | user-workspace | {"language": "de"} | - | asset-2 | nody-mc-nodeface | assets | user-workspace | {"language": "de"} | \ No newline at end of file + | assetId | nodeAggregateId | propertyName | workspaceName | originDimensionSpacePoint | diff --git a/Neos.Neos/Tests/Behavior/Features/Bootstrap/AssetUsageTrait.php b/Neos.Neos/Tests/Behavior/Features/Bootstrap/AssetUsageTrait.php index 53d5e61c49f..d798c5cae98 100644 --- a/Neos.Neos/Tests/Behavior/Features/Bootstrap/AssetUsageTrait.php +++ b/Neos.Neos/Tests/Behavior/Features/Bootstrap/AssetUsageTrait.php @@ -42,7 +42,7 @@ abstract private function getObject(string $className): object; public function iExpectTheAssetUsageServiceToHaveTheFollowingAssetUsages(TableNode $table) { $assetUsageService = $this->getObject(AssetUsageService::class); - $assetUsages = $assetUsageService->findByFilter($this->currentContentRepository->id, AssetUsageFilter::create()); + $assetUsages = iterator_to_array($assetUsageService->findByFilter($this->currentContentRepository->id, AssetUsageFilter::create())); $tableRows = $table->getHash(); foreach ($assetUsages as $assetUsage) { @@ -60,9 +60,10 @@ public function iExpectTheAssetUsageServiceToHaveTheFollowingAssetUsages(TableNo } } - Assert::assertEmpty($tableRows, "Not all given asset usages where found."); - Assert::assertSame($assetUsages->count(), count($table->getHash()), "More asset usages found as given."); - + Assert::assertTrue( + $tableRows === [] && count($assetUsages) === count($table->getHash()), + sprintf('Mismatch between all actual asset usages %s and leftover asset usages to match %s', json_encode($assetUsages, JSON_PRETTY_PRINT), json_encode($tableRows, JSON_PRETTY_PRINT)) + ); } /** @@ -75,4 +76,4 @@ public function iRunTheAssetUsageIndexingProcessor(string $rootNodeTypeName) NodeTypeName::fromString($rootNodeTypeName), ); } -} \ No newline at end of file +} diff --git a/Neos.Neos/Tests/Behavior/Features/Bootstrap/ChangeProjectionTrait.php b/Neos.Neos/Tests/Behavior/Features/Bootstrap/ChangeProjectionTrait.php index b7828cbf7a6..db4d422f975 100644 --- a/Neos.Neos/Tests/Behavior/Features/Bootstrap/ChangeProjectionTrait.php +++ b/Neos.Neos/Tests/Behavior/Features/Bootstrap/ChangeProjectionTrait.php @@ -40,7 +40,7 @@ abstract private function getObject(string $className): object; public function iExpectTheChangeProjectionToHaveTheFollowingChangesInContentStream(TableNode $table, string $contentStreamId) { $changeFinder = $this->currentContentRepository->projectionState(ChangeFinder::class); - $changes = $changeFinder->findByContentStreamId(ContentStreamId::fromString($contentStreamId)); + $changes = iterator_to_array($changeFinder->findByContentStreamId(ContentStreamId::fromString($contentStreamId))); $tableRows = $table->getHash(); foreach ($changes as $change) { @@ -63,14 +63,11 @@ public function iExpectTheChangeProjectionToHaveTheFollowingChangesInContentStre } } - if (count($tableRows) !== 0) { - $tableHeader = array_combine(array_values($table->getRow(0)), array_values($table->getRow(0))); - $tableRemain = $tableRows; - array_unshift($tableRemain, $tableHeader); - Assert::assertEmpty($tableRows, "Not all given changes where found." . PHP_EOL . (new TableNode($tableRemain))->getTableAsString()); - } - Assert::assertSame(count($table->getHash()), $changes->count(), "More changes found as given."); + Assert::assertTrue( + $tableRows === [] && count($table->getHash()) === count($changes), + sprintf('Mismatch between all actual changes usages %s and leftover changes to match %s', json_encode($changes, JSON_PRETTY_PRINT), json_encode($tableRows, JSON_PRETTY_PRINT)) + ); } /** @@ -79,8 +76,8 @@ public function iExpectTheChangeProjectionToHaveTheFollowingChangesInContentStre public function iExpectTheChangeProjectionToHaveNoChangesInContentStream(string $contentStreamId) { $changeFinder = $this->currentContentRepository->projectionState(ChangeFinder::class); - $changes = $changeFinder->findByContentStreamId(ContentStreamId::fromString($contentStreamId)); + $changes = iterator_to_array($changeFinder->findByContentStreamId(ContentStreamId::fromString($contentStreamId))); - Assert::assertSame(0, $changes->count(), "No changes expected."); + Assert::assertEmpty($changes, "No changes expected, got: " . json_encode($changes, JSON_PRETTY_PRINT)); } } diff --git a/Neos.Neos/Tests/Behavior/Features/ContentCache/NodesInUserWorkspace.feature b/Neos.Neos/Tests/Behavior/Features/ContentCache/NodesInUserWorkspace.feature index 014162ccebf..d52b54f4ca8 100644 --- a/Neos.Neos/Tests/Behavior/Features/ContentCache/NodesInUserWorkspace.feature +++ b/Neos.Neos/Tests/Behavior/Features/ContentCache/NodesInUserWorkspace.feature @@ -179,7 +179,7 @@ Feature: Tests for the ContentCacheFlusher and cache flushing when applied in us When the command DiscardIndividualNodesFromWorkspace is executed with payload: | Key | Value | | workspaceName | "user-editor" | - | nodesToDiscard | [{"workspaceName": "user-editor", "dimensionSpacePoint": {}, "nodeAggregateId": "text-node-middle"}] | + | nodesToDiscard | ["text-node-middle"] | | newContentStreamId | "user-cs-id-discard" | Then I expect node aggregate identifier "text-node-middle" to lead to no node @@ -295,4 +295,4 @@ Feature: Tests for the ContentCacheFlusher and cache flushing when applied in us """
secondRender[Text Node at the start of the document]secondRender[Text Node in the middle of the document]secondRender[Text Node at the end of the document]
""" - + diff --git a/Neos.Neos/Tests/Behavior/Features/ContentRepository/Security/WorkspacePermissions.feature b/Neos.Neos/Tests/Behavior/Features/ContentRepository/Security/WorkspacePermissions.feature index 7b02cca647b..c039224874b 100644 --- a/Neos.Neos/Tests/Behavior/Features/ContentRepository/Security/WorkspacePermissions.feature +++ b/Neos.Neos/Tests/Behavior/Features/ContentRepository/Security/WorkspacePermissions.feature @@ -208,9 +208,9 @@ Feature: Workspace permission related features | MoveDimensionSpacePoint | {"source":{"language":"de"},"target":{"language":"ch"}} | | UpdateRootNodeAggregateDimensions | {"nodeAggregateId":"root"} | | DiscardWorkspace | {} | - | DiscardIndividualNodesFromWorkspace | {"nodesToDiscard":[{"nodeAggregateId":"a1"}]} | + | DiscardIndividualNodesFromWorkspace | {"nodesToDiscard":["a1"]} | | PublishWorkspace | {} | - | PublishIndividualNodesFromWorkspace | {"nodesToPublish":[{"nodeAggregateId":"a1"}]} | + | PublishIndividualNodesFromWorkspace | {"nodesToPublish":["a1"]} | | RebaseWorkspace | {} | | CreateWorkspace | {"workspaceName":"new-workspace","baseWorkspaceName":"workspace","newContentStreamId":"any"} | diff --git a/Neos.Neos/Tests/Behavior/Features/FrontendRouting/PartialPublish.feature b/Neos.Neos/Tests/Behavior/Features/FrontendRouting/PartialPublish.feature index 6c82bbeacbb..803b0e8b5eb 100644 --- a/Neos.Neos/Tests/Behavior/Features/FrontendRouting/PartialPublish.feature +++ b/Neos.Neos/Tests/Behavior/Features/FrontendRouting/PartialPublish.feature @@ -54,7 +54,7 @@ Feature: Test cases for partial publish to live and uri path generation And the command PublishIndividualNodesFromWorkspace is executed with payload: | Key | Value | | workspaceName | "myworkspace" | - | nodesToPublish | [{"nodeAggregateId": "justsomepage", "dimensionSpacePoint": {"example":"source"}}] | + | nodesToPublish | ["justsomepage"] | Then I expect the documenturipath table to contain exactly: # source: 65901ded4f068dac14ad0dce4f459b29 diff --git a/Neos.Neos/Tests/Behavior/Features/PendingChanges/W01-WorkspacePublication/03-PublishIndividualNodesFromWorkspace_WithoutDimensions.feature b/Neos.Neos/Tests/Behavior/Features/PendingChanges/W01-WorkspacePublication/03-PublishIndividualNodesFromWorkspace_WithoutDimensions.feature index 98e67598008..62c2cbb1cf1 100644 --- a/Neos.Neos/Tests/Behavior/Features/PendingChanges/W01-WorkspacePublication/03-PublishIndividualNodesFromWorkspace_WithoutDimensions.feature +++ b/Neos.Neos/Tests/Behavior/Features/PendingChanges/W01-WorkspacePublication/03-PublishIndividualNodesFromWorkspace_WithoutDimensions.feature @@ -50,7 +50,7 @@ Feature: Publish nodes partially without dimensions When the command PublishIndividualNodesFromWorkspace is executed with payload: | Key | Value | - | nodesToPublish | [{"workspaceName": "user-workspace", "dimensionSpacePoint": {}, "nodeAggregateId": "sir-david-nodenborough"}] | + | nodesToPublish | ["sir-david-nodenborough"] | | contentStreamIdForRemainingPart | "user-cs-id-remaining" | Then I expect the ChangeProjection to have the following changes in "user-cs-id-remaining": @@ -99,7 +99,7 @@ Feature: Publish nodes partially without dimensions When the command PublishIndividualNodesFromWorkspace is executed with payload: | Key | Value | - | nodesToPublish | [{"workspaceName": "user-workspace", "dimensionSpacePoint": {}, "nodeAggregateId": "nody-mc-nodeface"}] | + | nodesToPublish | ["nody-mc-nodeface"] | | contentStreamIdForRemainingPart | "user-cs-id-remaining" | Then I expect the ChangeProjection to have the following changes in "user-cs-id-remaining": diff --git a/Neos.Neos/Tests/Behavior/Features/PendingChanges/W01-WorkspacePublication/04-PublishIndividualNodesFromWorkspace_WithDimensions.feature b/Neos.Neos/Tests/Behavior/Features/PendingChanges/W01-WorkspacePublication/04-PublishIndividualNodesFromWorkspace_WithDimensions.feature index a0227c2e0ad..846c9fec035 100644 --- a/Neos.Neos/Tests/Behavior/Features/PendingChanges/W01-WorkspacePublication/04-PublishIndividualNodesFromWorkspace_WithDimensions.feature +++ b/Neos.Neos/Tests/Behavior/Features/PendingChanges/W01-WorkspacePublication/04-PublishIndividualNodesFromWorkspace_WithDimensions.feature @@ -60,7 +60,7 @@ Feature: Publish nodes partially with dimensions When the command PublishIndividualNodesFromWorkspace is executed with payload: | Key | Value | - | nodesToPublish | [{"workspaceName": "user-workspace", "dimensionSpacePoint": {"language": "de"}, "nodeAggregateId": "sir-david-nodenborough"}] | + | nodesToPublish | ["sir-david-nodenborough"] | | contentStreamIdForRemainingPart | "user-cs-id-remaining" | Then I expect the ChangeProjection to have the following changes in "user-cs-id-remaining": @@ -129,12 +129,11 @@ Feature: Publish nodes partially with dimensions When the command PublishIndividualNodesFromWorkspace is executed with payload: | Key | Value | - | nodesToPublish | [{"workspaceName": "user-workspace", "dimensionSpacePoint": {"language": "de"}, "nodeAggregateId": "nody-mc-nodeface"}] | + | nodesToPublish | ["nody-mc-nodeface"] | | contentStreamIdForRemainingPart | "user-cs-id-remaining" | Then I expect the ChangeProjection to have the following changes in "user-cs-id-remaining": | nodeAggregateId | created | changed | moved | deleted | originDimensionSpacePoint | - | nody-mc-nodeface | 1 | 1 | 0 | 0 | {"language":"gsw"} | | sir-nodeward-nodington-iv | 1 | 1 | 0 | 0 | {"language":"de"} | | sir-nodeward-nodington-iii | 1 | 1 | 0 | 0 | {"language":"fr"} | And I expect the ChangeProjection to have no changes in "user-cs-id" @@ -142,6 +141,7 @@ Feature: Publish nodes partially with dimensions | nodeAggregateId | created | changed | moved | deleted | originDimensionSpacePoint | | sir-david-nodenborough | 1 | 1 | 0 | 0 | {"language":"de"} | | nody-mc-nodeface | 1 | 1 | 0 | 0 | {"language":"de"} | + | nody-mc-nodeface | 1 | 1 | 0 | 0 | {"language":"gsw"} | And I expect the ChangeProjection to have no changes in "cs-identifier" Scenario: Publish nodes partially from user workspace to live with new generalization @@ -174,7 +174,7 @@ Feature: Publish nodes partially with dimensions When the command PublishIndividualNodesFromWorkspace is executed with payload: | Key | Value | - | nodesToPublish | [{"workspaceName": "user-workspace", "dimensionSpacePoint": {"language": "de"}, "nodeAggregateId": "sir-david-nodenborough"},{"workspaceName": "user-workspace", "dimensionSpacePoint": {"language": "en"}, "nodeAggregateId": "sir-david-nodenborough"}] | + | nodesToPublish | ["sir-david-nodenborough", "sir-david-nodenborough"] | | contentStreamIdForRemainingPart | "user-cs-id-remaining" | Then I expect the ChangeProjection to have the following changes in "user-cs-id-remaining": diff --git a/Neos.Neos/Tests/Behavior/Features/PendingChanges/W02-WorkspaceDiscarding/03-DiscardIndividualNodesFromWorkspace_WithoutDimensions.feature b/Neos.Neos/Tests/Behavior/Features/PendingChanges/W02-WorkspaceDiscarding/03-DiscardIndividualNodesFromWorkspace_WithoutDimensions.feature index 1f47143ce90..71d6382226c 100644 --- a/Neos.Neos/Tests/Behavior/Features/PendingChanges/W02-WorkspaceDiscarding/03-DiscardIndividualNodesFromWorkspace_WithoutDimensions.feature +++ b/Neos.Neos/Tests/Behavior/Features/PendingChanges/W02-WorkspaceDiscarding/03-DiscardIndividualNodesFromWorkspace_WithoutDimensions.feature @@ -53,7 +53,7 @@ Feature: Discard nodes partially without dimensions When the command DiscardIndividualNodesFromWorkspace is executed with payload: | Key | Value | | workspaceName | "user-workspace" | - | nodesToDiscard | [{"workspaceName": "user-workspace", "dimensionSpacePoint": {}, "nodeAggregateId": "sir-nodeward-nodington-iii"}] | + | nodesToDiscard | ["sir-nodeward-nodington-iii"] | | newContentStreamId | "user-cs-id-remaining" | Then I expect the ChangeProjection to have the following changes in "user-cs-id-remaining": @@ -85,7 +85,7 @@ Feature: Discard nodes partially without dimensions When the command DiscardIndividualNodesFromWorkspace is executed with payload: | Key | Value | | workspaceName | "user-workspace" | - | nodesToDiscard | [{"workspaceName": "user-workspace", "dimensionSpacePoint": {}, "nodeAggregateId": "sir-nodeward-nodington-iii"},{"workspaceName": "user-workspace", "dimensionSpacePoint": {}, "nodeAggregateId": "sir-nodeward-nodington-iv"}] | + | nodesToDiscard | ["sir-nodeward-nodington-iii", "sir-nodeward-nodington-iv"] | | newContentStreamId | "user-cs-id-remaining" | Then I expect the ChangeProjection to have the following changes in "user-cs-id-remaining": @@ -131,7 +131,7 @@ Feature: Discard nodes partially without dimensions When the command DiscardIndividualNodesFromWorkspace is executed with payload: | Key | Value | | workspaceName | "user-workspace" | - | nodesToDiscard | [{"workspaceName": "user-workspace", "dimensionSpacePoint": {}, "nodeAggregateId": "sir-nodeward-nodington-iv"}] | + | nodesToDiscard | ["sir-nodeward-nodington-iv"] | | newContentStreamId | "user-cs-id-remaining" | Then I expect the ChangeProjection to have the following changes in "user-cs-id-remaining": @@ -182,7 +182,7 @@ Feature: Discard nodes partially without dimensions When the command DiscardIndividualNodesFromWorkspace is executed with payload: | Key | Value | | workspaceName | "user-workspace" | - | nodesToDiscard | [{"workspaceName": "user-workspace", "dimensionSpacePoint": {}, "nodeAggregateId": "sir-nodeward-nodington-iv"},{"workspaceName": "user-workspace", "dimensionSpacePoint": {}, "nodeAggregateId": "sir-nodeward-nodington-v"}] | + | nodesToDiscard | ["sir-nodeward-nodington-iv", "sir-nodeward-nodington-v"] | | newContentStreamId | "user-cs-id-remaining" | Then I expect the ChangeProjection to have the following changes in "user-cs-id-remaining": diff --git a/Neos.Neos/Tests/Behavior/Features/PendingChanges/W02-WorkspaceDiscarding/04-DiscardIndividualNodesFromWorkspace_WithDimensions.feature b/Neos.Neos/Tests/Behavior/Features/PendingChanges/W02-WorkspaceDiscarding/04-DiscardIndividualNodesFromWorkspace_WithDimensions.feature index 522aaf2028c..520f8296bd8 100644 --- a/Neos.Neos/Tests/Behavior/Features/PendingChanges/W02-WorkspaceDiscarding/04-DiscardIndividualNodesFromWorkspace_WithDimensions.feature +++ b/Neos.Neos/Tests/Behavior/Features/PendingChanges/W02-WorkspaceDiscarding/04-DiscardIndividualNodesFromWorkspace_WithDimensions.feature @@ -60,7 +60,7 @@ Feature: Discard nodes partially with dimensions When the command DiscardIndividualNodesFromWorkspace is executed with payload: | Key | Value | | workspaceName | "user-workspace" | - | nodesToDiscard | [{"workspaceName": "user-workspace", "dimensionSpacePoint": {"language": "de"}, "nodeAggregateId": "sir-david-nodenborough"}, {"workspaceName": "user-workspace", "dimensionSpacePoint": {"language": "de"}, "nodeAggregateId": "nody-mc-nodeface"}] | + | nodesToDiscard | ["sir-david-nodenborough", "nody-mc-nodeface"] | | newContentStreamId | "user-cs-id-remaining" | Then I expect the ChangeProjection to have the following changes in "user-cs-id-remaining": @@ -129,7 +129,7 @@ Feature: Discard nodes partially with dimensions When the command DiscardIndividualNodesFromWorkspace is executed with payload: | Key | Value | | workspaceName | "user-workspace" | - | nodesToDiscard | [{"workspaceName": "user-workspace", "dimensionSpacePoint": {"language": "gsw"}, "nodeAggregateId": "nody-mc-nodeface"}] | + | nodesToDiscard | ["nody-mc-nodeface"] | | newContentStreamId | "user-cs-id-remaining" | Then I expect the ChangeProjection to have the following changes in "review-cs-id": @@ -137,7 +137,6 @@ Feature: Discard nodes partially with dimensions | sir-david-nodenborough | 1 | 1 | 0 | 0 | {"language":"de"} | And I expect the ChangeProjection to have the following changes in "user-cs-id-remaining": | nodeAggregateId | created | changed | moved | deleted | originDimensionSpacePoint | - | nody-mc-nodeface | 1 | 1 | 0 | 0 | {"language":"de"} | | sir-nodeward-nodington-iii | 1 | 1 | 0 | 0 | {"language":"fr"} | | sir-nodeward-nodington-iv | 1 | 1 | 0 | 0 | {"language":"fr"} | And I expect the ChangeProjection to have no changes in "user-cs-id" @@ -176,13 +175,11 @@ Feature: Discard nodes partially with dimensions When the command DiscardIndividualNodesFromWorkspace is executed with payload: | Key | Value | | workspaceName | "user-workspace" | - | nodesToDiscard | [{"workspaceName": "user-workspace", "dimensionSpacePoint": {"language": "en"} , "nodeAggregateId": "sir-david-nodenborough"}, {"workspaceName": "user-workspace", "dimensionSpacePoint": {"language": "de"} , "nodeAggregateId": "sir-nodeward-nodington-iii"}] | + | nodesToDiscard | ["sir-david-nodenborough", "nody-mc-nodeface", "sir-nodeward-nodington-iii"] | | newContentStreamId | "user-cs-id-remaining" | Then I expect the ChangeProjection to have the following changes in "user-cs-id-remaining": | nodeAggregateId | created | changed | moved | deleted | originDimensionSpacePoint | - | sir-david-nodenborough | 1 | 1 | 0 | 0 | {"language":"de"} | - | nody-mc-nodeface | 1 | 1 | 0 | 0 | {"language":"de"} | | sir-nodeward-nodington-iv | 1 | 1 | 0 | 0 | {"language":"de"} | And I expect the ChangeProjection to have no changes in "user-cs-id" And I expect the ChangeProjection to have no changes in "cs-identifier" diff --git a/Neos.Workspace.Ui/Classes/Controller/WorkspaceController.php b/Neos.Workspace.Ui/Classes/Controller/WorkspaceController.php index e8f02988acb..8718f28aedb 100644 --- a/Neos.Workspace.Ui/Classes/Controller/WorkspaceController.php +++ b/Neos.Workspace.Ui/Classes/Controller/WorkspaceController.php @@ -21,14 +21,13 @@ use Neos\ContentRepository\Core\Feature\WorkspaceModification\Command\DeleteWorkspace; use Neos\ContentRepository\Core\Feature\WorkspacePublication\Command\DiscardIndividualNodesFromWorkspace; use Neos\ContentRepository\Core\Feature\WorkspacePublication\Command\PublishIndividualNodesFromWorkspace; -use Neos\ContentRepository\Core\Feature\WorkspacePublication\Dto\NodeIdsToPublishOrDiscard; -use Neos\ContentRepository\Core\Feature\WorkspacePublication\Dto\NodeIdToPublishOrDiscard; use Neos\ContentRepository\Core\Projection\ContentGraph\Filter\FindAncestorNodesFilter; use Neos\ContentRepository\Core\Projection\ContentGraph\Node; use Neos\ContentRepository\Core\Projection\ContentGraph\Nodes; use Neos\ContentRepository\Core\Projection\ContentGraph\VisibilityConstraints; use Neos\ContentRepository\Core\SharedModel\ContentRepository\ContentRepositoryId; use Neos\ContentRepository\Core\SharedModel\Node\NodeAddress; +use Neos\ContentRepository\Core\SharedModel\Node\NodeAggregateIds; use Neos\ContentRepository\Core\SharedModel\Node\NodeName; use Neos\ContentRepository\Core\SharedModel\Workspace\ContentStreamId; use Neos\ContentRepository\Core\SharedModel\Workspace\Workspace; @@ -490,12 +489,7 @@ public function publishNodeAction(string $nodeAddress, WorkspaceName $selectedWo $command = PublishIndividualNodesFromWorkspace::create( $selectedWorkspace, - NodeIdsToPublishOrDiscard::create( - new NodeIdToPublishOrDiscard( - $nodeAddress->aggregateId, - $nodeAddress->dimensionSpacePoint - ) - ), + NodeAggregateIds::create($nodeAddress->aggregateId), ); $contentRepository->handle($command); @@ -524,11 +518,8 @@ public function discardNodeAction(string $nodeAddress, WorkspaceName $selectedWo $command = DiscardIndividualNodesFromWorkspace::create( $selectedWorkspace, - NodeIdsToPublishOrDiscard::create( - new NodeIdToPublishOrDiscard( - $nodeAddress->aggregateId, - $nodeAddress->dimensionSpacePoint - ) + NodeAggregateIds::create( + $nodeAddress->aggregateId ), ); $contentRepository->handle($command); @@ -560,17 +551,14 @@ public function publishOrDiscardNodesAction(array $nodes, string $action, string $nodesToPublishOrDiscard = []; foreach ($nodes as $node) { $nodeAddress = NodeAddress::fromJsonString($node); - $nodesToPublishOrDiscard[] = new NodeIdToPublishOrDiscard( - $nodeAddress->aggregateId, - $nodeAddress->dimensionSpacePoint - ); + $nodesToPublishOrDiscard[] = $nodeAddress->aggregateId; } switch ($action) { case 'publish': $command = PublishIndividualNodesFromWorkspace::create( $selectedWorkspaceName, - NodeIdsToPublishOrDiscard::create(...$nodesToPublishOrDiscard), + NodeAggregateIds::create(...$nodesToPublishOrDiscard), ); $contentRepository->handle($command); $this->addFlashMessage($this->translator->translateById( @@ -585,7 +573,7 @@ public function publishOrDiscardNodesAction(array $nodes, string $action, string case 'discard': $command = DiscardIndividualNodesFromWorkspace::create( $selectedWorkspaceName, - NodeIdsToPublishOrDiscard::create(...$nodesToPublishOrDiscard), + NodeAggregateIds::create(...$nodesToPublishOrDiscard), ); $contentRepository->handle($command); $this->addFlashMessage($this->translator->translateById(