Skip to content

Commit

Permalink
TASK: Introduce CommandSerializerInterface to centralise serialisat…
Browse files Browse the repository at this point in the history
…ion and get hold of the `$serializedCommand`
  • Loading branch information
mhsdesign committed Nov 8, 2024
1 parent fd1c8fc commit 352cd1a
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 19 deletions.
28 changes: 25 additions & 3 deletions Neos.ContentRepository.Core/Classes/CommandHandler/CommandBus.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,26 +21,48 @@
*/
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;
}

/**
* @return EventsToPublish|\Generator<int, EventsToPublish>
*/
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
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

declare(strict_types=1);

namespace Neos\ContentRepository\Core\CommandHandler;

use Neos\ContentRepository\Core\Feature\Common\RebasableToOtherWorkspaceInterface;

/**
* Optional interface for all content repository command serializer
*
* See {@see RebasableToOtherWorkspaceInterface} for more details regarding serialized commands.
*
* @internal no public API, because commands are no extension points of the CR
*/
interface CommandSerializerInterface
{
public function canSerialize(PublicCommandInterface $command): bool;

public function serialize(PublicCommandInterface $command, CommandHandlingDependencies $commandHandlingDependencies): RebasableToOtherWorkspaceInterface;
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

use Neos\ContentRepository\Core\CommandHandler\CommandHandlerInterface;
use Neos\ContentRepository\Core\CommandHandler\CommandHandlingDependencies;
use Neos\ContentRepository\Core\CommandHandler\CommandSerializerInterface;
use Neos\ContentRepository\Core\CommandHandler\PublicCommandInterface;
use Neos\ContentRepository\Core\ContentRepository;
use Neos\ContentRepository\Core\DimensionSpace;
Expand Down Expand Up @@ -58,7 +59,7 @@
/**
* @internal from userland, you'll use ContentRepository::handle to dispatch commands
*/
final class NodeAggregateCommandHandler implements CommandHandlerInterface
final class NodeAggregateCommandHandler implements CommandHandlerInterface, CommandSerializerInterface
{
use ConstraintChecks;
use RootNodeHandling;
Expand Down Expand Up @@ -96,16 +97,12 @@ public function handle(PublicCommandInterface|RebasableToOtherWorkspaceInterface
{
/** @phpstan-ignore-next-line */
return match ($command::class) {
SetNodeProperties::class => $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),
Expand All @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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);

Expand All @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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());
Expand All @@ -70,7 +70,7 @@ private function handleSetNodeProperties(
$command->propertyValues->getPropertiesToUnset()
);

return $this->handleSetSerializedNodeProperties($lowLevelCommand, $commandHandlingDependencies);
return $lowLevelCommand;
}

private function handleSetSerializedNodeProperties(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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());
Expand Down Expand Up @@ -79,7 +79,7 @@ private function handleSetNodeReferences(
$this->mapNodeReferencesToSerializedNodeReferences($command->references, $nodeTypeName),
);

return $this->handleSetSerializedNodeReferences($lowLevelCommand, $commandHandlingDependencies);
return $lowLevelCommand;
}

/**
Expand Down

0 comments on commit 352cd1a

Please sign in to comment.