From 352cd1ae297d2efbe0dc630a4c8ea85459538a6e Mon Sep 17 00:00:00 2001 From: mhsdesign <85400359+mhsdesign@users.noreply.github.com> Date: Fri, 8 Nov 2024 17:36:45 +0100 Subject: [PATCH] TASK: Introduce `CommandSerializerInterface` to centralise serialisation and get hold of the `$serializedCommand` --- .../Classes/CommandHandler/CommandBus.php | 28 +++++++++++++++++-- .../CommandSerializerInterface.php | 21 ++++++++++++++ .../Feature/NodeAggregateCommandHandler.php | 22 +++++++++++---- .../Feature/NodeCreation/NodeCreation.php | 8 +++--- .../NodeModification/NodeModification.php | 8 +++--- .../NodeReferencing/NodeReferencing.php | 6 ++-- 6 files changed, 74 insertions(+), 19 deletions(-) create mode 100644 Neos.ContentRepository.Core/Classes/CommandHandler/CommandSerializerInterface.php diff --git a/Neos.ContentRepository.Core/Classes/CommandHandler/CommandBus.php b/Neos.ContentRepository.Core/Classes/CommandHandler/CommandBus.php index 5f39a7606c3..6b055a84349 100644 --- a/Neos.ContentRepository.Core/Classes/CommandHandler/CommandBus.php +++ b/Neos.ContentRepository.Core/Classes/CommandHandler/CommandBus.php @@ -21,12 +21,24 @@ */ private array $handlers; + /** + * @var CommandSerializerInterface[] + */ + private array $serializers; + public function __construct( // todo pass $commandHandlingDependencies in each command handler instead of into the commandBus private CommandHandlingDependencies $commandHandlingDependencies, CommandHandlerInterface ...$handlers ) { $this->handlers = $handlers; + $serializers = []; + foreach ($handlers as $handler) { + if ($handler instanceof CommandSerializerInterface) { + $serializers[] = $handler; + } + } + $this->serializers = $serializers; } /** @@ -34,13 +46,23 @@ public function __construct( */ public function handle(PublicCommandInterface|RebasableToOtherWorkspaceInterface $command): EventsToPublish|\Generator { + $possiblySerializedCommand = $command; + if (!$command instanceof RebasableToOtherWorkspaceInterface) { + foreach ($this->serializers as $serializer) { + if ($serializer->canSerialize($command)) { + $possiblySerializedCommand = $serializer->serialize($command, $this->commandHandlingDependencies); + break; + } + } + } + // multiple handlers must not handle the same command foreach ($this->handlers as $handler) { - if ($handler->canHandle($command)) { - return $handler->handle($command, $this->commandHandlingDependencies); + if ($handler->canHandle($possiblySerializedCommand)) { + return $handler->handle($possiblySerializedCommand, $this->commandHandlingDependencies); } } - throw new \RuntimeException(sprintf('No handler found for Command "%s"', get_debug_type($command)), 1649582778); + throw new \RuntimeException(sprintf('No handler found for Command "%s"', get_debug_type($possiblySerializedCommand)), 1649582778); } public function withAdditionalHandlers(CommandHandlerInterface ...$handlers): self diff --git a/Neos.ContentRepository.Core/Classes/CommandHandler/CommandSerializerInterface.php b/Neos.ContentRepository.Core/Classes/CommandHandler/CommandSerializerInterface.php new file mode 100644 index 00000000000..b1775878b4e --- /dev/null +++ b/Neos.ContentRepository.Core/Classes/CommandHandler/CommandSerializerInterface.php @@ -0,0 +1,21 @@ + $this->handleSetNodeProperties($command, $commandHandlingDependencies), SetSerializedNodeProperties::class => $this->handleSetSerializedNodeProperties($command, $commandHandlingDependencies), - SetNodeReferences::class => $this->handleSetNodeReferences($command, $commandHandlingDependencies), SetSerializedNodeReferences::class => $this->handleSetSerializedNodeReferences($command, $commandHandlingDependencies), ChangeNodeAggregateType::class => $this->handleChangeNodeAggregateType($command, $commandHandlingDependencies), RemoveNodeAggregate::class => $this->handleRemoveNodeAggregate($command, $commandHandlingDependencies), - CreateNodeAggregateWithNode::class - => $this->handleCreateNodeAggregateWithNode($command, $commandHandlingDependencies), CreateNodeAggregateWithNodeAndSerializedProperties::class => $this->handleCreateNodeAggregateWithNodeAndSerializedProperties($command, $commandHandlingDependencies), MoveNodeAggregate::class => $this->handleMoveNodeAggregate($command, $commandHandlingDependencies), @@ -122,6 +119,21 @@ public function handle(PublicCommandInterface|RebasableToOtherWorkspaceInterface }; } + public function canSerialize(PublicCommandInterface $command): bool + { + return method_exists($this, 'serialize' . (new \ReflectionClass($command))->getShortName()); + } + + public function serialize(PublicCommandInterface $command, CommandHandlingDependencies $commandHandlingDependencies): RebasableToOtherWorkspaceInterface + { + /** @phpstan-ignore-next-line */ + return match ($command::class) { + SetNodeProperties::class => $this->serializeSetNodeProperties($command, $commandHandlingDependencies), + SetNodeReferences::class => $this->serializeSetNodeReferences($command, $commandHandlingDependencies), + CreateNodeAggregateWithNode::class => $this->serializeCreateNodeAggregateWithNode($command, $commandHandlingDependencies), + }; + } + protected function getNodeTypeManager(): NodeTypeManager { return $this->nodeTypeManager; diff --git a/Neos.ContentRepository.Core/Classes/Feature/NodeCreation/NodeCreation.php b/Neos.ContentRepository.Core/Classes/Feature/NodeCreation/NodeCreation.php index b73ba4750f6..e4acb706166 100644 --- a/Neos.ContentRepository.Core/Classes/Feature/NodeCreation/NodeCreation.php +++ b/Neos.ContentRepository.Core/Classes/Feature/NodeCreation/NodeCreation.php @@ -20,7 +20,6 @@ use Neos\ContentRepository\Core\EventStore\Events; use Neos\ContentRepository\Core\EventStore\EventsToPublish; use Neos\ContentRepository\Core\Feature\Common\InterdimensionalSiblings; -use Neos\ContentRepository\Core\Feature\RebaseableCommand; use Neos\ContentRepository\Core\Feature\Common\NodeCreationInternals; use Neos\ContentRepository\Core\Feature\Common\NodeReferencingInternals; use Neos\ContentRepository\Core\Feature\ContentStreamEventStreamName; @@ -31,6 +30,7 @@ use Neos\ContentRepository\Core\Feature\NodeModification\Dto\PropertyValuesToWrite; use Neos\ContentRepository\Core\Feature\NodeModification\Dto\SerializedPropertyValues; use Neos\ContentRepository\Core\Feature\NodeReferencing\Dto\SerializedNodeReferences; +use Neos\ContentRepository\Core\Feature\RebaseableCommand; use Neos\ContentRepository\Core\Infrastructure\Property\PropertyConverter; use Neos\ContentRepository\Core\Infrastructure\Property\PropertyType; use Neos\ContentRepository\Core\NodeType\NodeType; @@ -72,10 +72,10 @@ abstract protected function getPropertyConverter(): PropertyConverter; abstract protected function getNodeTypeManager(): NodeTypeManager; - private function handleCreateNodeAggregateWithNode( + private function serializeCreateNodeAggregateWithNode( CreateNodeAggregateWithNode $command, CommandHandlingDependencies $commandHandlingDependencies - ): EventsToPublish { + ): CreateNodeAggregateWithNodeAndSerializedProperties { $this->requireNodeType($command->nodeTypeName); $this->validateProperties($command->initialPropertyValues, $command->nodeTypeName); @@ -99,7 +99,7 @@ private function handleCreateNodeAggregateWithNode( $lowLevelCommand = $lowLevelCommand->withNodeName($command->nodeName); } - return $this->handleCreateNodeAggregateWithNodeAndSerializedProperties($lowLevelCommand, $commandHandlingDependencies); + return $lowLevelCommand; } private function validateProperties(?PropertyValuesToWrite $propertyValues, NodeTypeName $nodeTypeName): void diff --git a/Neos.ContentRepository.Core/Classes/Feature/NodeModification/NodeModification.php b/Neos.ContentRepository.Core/Classes/Feature/NodeModification/NodeModification.php index 7608fef3c50..6c6d4935c65 100644 --- a/Neos.ContentRepository.Core/Classes/Feature/NodeModification/NodeModification.php +++ b/Neos.ContentRepository.Core/Classes/Feature/NodeModification/NodeModification.php @@ -17,13 +17,13 @@ use Neos\ContentRepository\Core\CommandHandler\CommandHandlingDependencies; use Neos\ContentRepository\Core\EventStore\Events; use Neos\ContentRepository\Core\EventStore\EventsToPublish; -use Neos\ContentRepository\Core\Feature\RebaseableCommand; use Neos\ContentRepository\Core\Feature\ContentStreamEventStreamName; use Neos\ContentRepository\Core\Feature\NodeModification\Command\SetNodeProperties; use Neos\ContentRepository\Core\Feature\NodeModification\Command\SetSerializedNodeProperties; use Neos\ContentRepository\Core\Feature\NodeModification\Dto\PropertyScope; use Neos\ContentRepository\Core\Feature\NodeModification\Dto\SerializedPropertyValues; use Neos\ContentRepository\Core\Feature\NodeModification\Event\NodePropertiesWereSet; +use Neos\ContentRepository\Core\Feature\RebaseableCommand; use Neos\ContentRepository\Core\NodeType\NodeType; use Neos\ContentRepository\Core\NodeType\NodeTypeName; use Neos\ContentRepository\Core\Projection\ContentGraph\ContentGraphInterface; @@ -43,10 +43,10 @@ abstract protected function requireProjectedNodeAggregate( NodeAggregateId $nodeAggregateId ): NodeAggregate; - private function handleSetNodeProperties( + private function serializeSetNodeProperties( SetNodeProperties $command, CommandHandlingDependencies $commandHandlingDependencies - ): EventsToPublish { + ): SetSerializedNodeProperties { $this->requireContentStream($command->workspaceName, $commandHandlingDependencies); $contentGraph = $commandHandlingDependencies->getContentGraph($command->workspaceName); $this->requireDimensionSpacePointToExist($command->originDimensionSpacePoint->toDimensionSpacePoint()); @@ -70,7 +70,7 @@ private function handleSetNodeProperties( $command->propertyValues->getPropertiesToUnset() ); - return $this->handleSetSerializedNodeProperties($lowLevelCommand, $commandHandlingDependencies); + return $lowLevelCommand; } private function handleSetSerializedNodeProperties( diff --git a/Neos.ContentRepository.Core/Classes/Feature/NodeReferencing/NodeReferencing.php b/Neos.ContentRepository.Core/Classes/Feature/NodeReferencing/NodeReferencing.php index cbfb71679d5..6bba3804a58 100644 --- a/Neos.ContentRepository.Core/Classes/Feature/NodeReferencing/NodeReferencing.php +++ b/Neos.ContentRepository.Core/Classes/Feature/NodeReferencing/NodeReferencing.php @@ -46,10 +46,10 @@ abstract protected function requireProjectedNodeAggregate( ): NodeAggregate; - private function handleSetNodeReferences( + private function serializeSetNodeReferences( SetNodeReferences $command, CommandHandlingDependencies $commandHandlingDependencies - ): EventsToPublish { + ): SetSerializedNodeReferences { $this->requireContentStream($command->workspaceName, $commandHandlingDependencies); $contentGraph = $commandHandlingDependencies->getContentGraph($command->workspaceName); $this->requireDimensionSpacePointToExist($command->sourceOriginDimensionSpacePoint->toDimensionSpacePoint()); @@ -79,7 +79,7 @@ private function handleSetNodeReferences( $this->mapNodeReferencesToSerializedNodeReferences($command->references, $nodeTypeName), ); - return $this->handleSetSerializedNodeReferences($lowLevelCommand, $commandHandlingDependencies); + return $lowLevelCommand; } /**