From 76f551bd7af79f935c89563122a384448d761494 Mon Sep 17 00:00:00 2001 From: mhsdesign <85400359+mhsdesign@users.noreply.github.com> Date: Wed, 2 Oct 2024 16:24:51 +0200 Subject: [PATCH 01/12] FEATURE: Refactor cr readmodel projection to be first level A ContentRepository cannot exist without this projection --- .../src/ContentRepositoryReadModelAdapter.php | 7 +-- .../DoctrineDbalContentGraphProjection.php | 5 +- ...trineDbalContentGraphProjectionFactory.php | 5 +- ...ContentHyperRepositoryReadModelAdapter.php | 6 +- .../Projection/HypergraphProjection.php | 5 +- .../src/HypergraphProjectionFactory.php | 3 +- .../Classes/CommandHandlingDependencies.php | 23 ++++--- .../Classes/ContentRepository.php | 44 +++++++------ .../Classes/ContentRepositoryReadModel.php | 63 +++---------------- ...entRepositoryReadModelAdapterInterface.php | 42 ------------- .../Factory/ContentRepositoryFactory.php | 4 +- ...ntRepositoryServiceFactoryDependencies.php | 8 +-- .../ProjectionsAndCatchUpHooksFactory.php | 14 ++++- .../ContentRepositoryReadModelProjection.php | 16 +++++ .../Classes/Projection/ProjectionStatuses.php | 7 ++- .../Classes/Projection/Projections.php | 9 +++ .../Projection/ProjectionsAndCatchUpHooks.php | 21 ++++++- .../Behavior/Bootstrap/FeatureContext.php | 1 - .../Bootstrap/CRTestSuiteRuntimeVariables.php | 5 +- .../Features/Bootstrap/ProjectedNodeTrait.php | 1 - .../Classes/ContentRepositoryRegistry.php | 2 +- .../ProjectionReplayServiceFactory.php | 2 +- .../Configuration/Settings.yaml | 2 +- 23 files changed, 131 insertions(+), 164 deletions(-) delete mode 100644 Neos.ContentRepository.Core/Classes/ContentRepositoryReadModelAdapterInterface.php create mode 100644 Neos.ContentRepository.Core/Classes/Projection/ContentRepositoryReadModelProjection.php diff --git a/Neos.ContentGraph.DoctrineDbalAdapter/src/ContentRepositoryReadModelAdapter.php b/Neos.ContentGraph.DoctrineDbalAdapter/src/ContentRepositoryReadModelAdapter.php index 56ad85a9d63..32cf74dca9c 100644 --- a/Neos.ContentGraph.DoctrineDbalAdapter/src/ContentRepositoryReadModelAdapter.php +++ b/Neos.ContentGraph.DoctrineDbalAdapter/src/ContentRepositoryReadModelAdapter.php @@ -18,7 +18,7 @@ use Doctrine\DBAL\Exception; use Neos\ContentGraph\DoctrineDbalAdapter\Domain\Repository\ContentGraph; use Neos\ContentGraph\DoctrineDbalAdapter\Domain\Repository\NodeFactory; -use Neos\ContentRepository\Core\ContentRepositoryReadModelAdapterInterface; +use Neos\ContentRepository\Core\ContentRepositoryReadModel; use Neos\ContentRepository\Core\NodeType\NodeTypeManager; use Neos\ContentRepository\Core\SharedModel\ContentRepository\ContentRepositoryId; use Neos\ContentRepository\Core\SharedModel\Workspace\ContentStream; @@ -32,10 +32,9 @@ use Neos\EventStore\Model\Event\Version; /** - * @internal only used inside the - * @see ContentRepositoryReadModel + * @internal */ -final readonly class ContentRepositoryReadModelAdapter implements ContentRepositoryReadModelAdapterInterface +final readonly class ContentRepositoryReadModelAdapter implements ContentRepositoryReadModel { public function __construct( private Connection $dbal, diff --git a/Neos.ContentGraph.DoctrineDbalAdapter/src/DoctrineDbalContentGraphProjection.php b/Neos.ContentGraph.DoctrineDbalAdapter/src/DoctrineDbalContentGraphProjection.php index ecd410b0a07..10422b5c2f3 100644 --- a/Neos.ContentGraph.DoctrineDbalAdapter/src/DoctrineDbalContentGraphProjection.php +++ b/Neos.ContentGraph.DoctrineDbalAdapter/src/DoctrineDbalContentGraphProjection.php @@ -65,8 +65,8 @@ use Neos\ContentRepository\Core\Projection\CheckpointStorageStatusType; use Neos\ContentRepository\Core\Projection\ContentGraph\NodeTags; use Neos\ContentRepository\Core\Projection\ContentGraph\Timestamps; -use Neos\ContentRepository\Core\Projection\ProjectionInterface; use Neos\ContentRepository\Core\Projection\ProjectionStatus; +use Neos\ContentRepository\Core\Projection\ContentRepositoryReadModelProjection; use Neos\ContentRepository\Core\SharedModel\Node\NodeAggregateClassification; use Neos\ContentRepository\Core\SharedModel\Node\NodeAggregateId; use Neos\ContentRepository\Core\SharedModel\Node\NodeName; @@ -76,10 +76,9 @@ use Neos\EventStore\Model\EventEnvelope; /** - * @implements ProjectionInterface * @internal but the graph projection is api */ -final class DoctrineDbalContentGraphProjection implements ProjectionInterface +final class DoctrineDbalContentGraphProjection implements ContentRepositoryReadModelProjection { use ContentStream; use NodeMove; diff --git a/Neos.ContentGraph.DoctrineDbalAdapter/src/DoctrineDbalContentGraphProjectionFactory.php b/Neos.ContentGraph.DoctrineDbalAdapter/src/DoctrineDbalContentGraphProjectionFactory.php index 1b750c114a4..4194d2d3b52 100644 --- a/Neos.ContentGraph.DoctrineDbalAdapter/src/DoctrineDbalContentGraphProjectionFactory.php +++ b/Neos.ContentGraph.DoctrineDbalAdapter/src/DoctrineDbalContentGraphProjectionFactory.php @@ -8,7 +8,6 @@ use Neos\ContentGraph\DoctrineDbalAdapter\Domain\Repository\DimensionSpacePointsRepository; use Neos\ContentGraph\DoctrineDbalAdapter\Domain\Repository\NodeFactory; use Neos\ContentGraph\DoctrineDbalAdapter\Domain\Repository\ProjectionContentGraph; -use Neos\ContentRepository\Core\ContentRepositoryReadModel; use Neos\ContentRepository\Core\Factory\ProjectionFactoryDependencies; use Neos\ContentRepository\Core\Projection\ProjectionFactoryInterface; @@ -42,7 +41,7 @@ public function build( $dimensionSpacePointsRepository ); - $contentRepositoryReadModelAdapter = new ContentRepositoryReadModelAdapter( + $contentRepositoryReadModel = new ContentRepositoryReadModelAdapter( $this->dbal, $nodeFactory, $projectionFactoryDependencies->contentRepositoryId, @@ -58,7 +57,7 @@ public function build( ), $tableNames, $dimensionSpacePointsRepository, - new ContentRepositoryReadModel($contentRepositoryReadModelAdapter) + $contentRepositoryReadModel ); } } diff --git a/Neos.ContentGraph.PostgreSQLAdapter/src/ContentHyperRepositoryReadModelAdapter.php b/Neos.ContentGraph.PostgreSQLAdapter/src/ContentHyperRepositoryReadModelAdapter.php index 245ddd82d1f..534e84b7853 100644 --- a/Neos.ContentGraph.PostgreSQLAdapter/src/ContentHyperRepositoryReadModelAdapter.php +++ b/Neos.ContentGraph.PostgreSQLAdapter/src/ContentHyperRepositoryReadModelAdapter.php @@ -8,7 +8,6 @@ use Neos\ContentGraph\PostgreSQLAdapter\Domain\Repository\ContentHypergraph; use Neos\ContentGraph\PostgreSQLAdapter\Domain\Repository\NodeFactory; use Neos\ContentRepository\Core\ContentRepositoryReadModel; -use Neos\ContentRepository\Core\ContentRepositoryReadModelAdapterInterface; use Neos\ContentRepository\Core\NodeType\NodeTypeManager; use Neos\ContentRepository\Core\Projection\ContentGraph\ContentGraphInterface; use Neos\ContentRepository\Core\SharedModel\ContentRepository\ContentRepositoryId; @@ -20,10 +19,9 @@ use Neos\ContentRepository\Core\SharedModel\Workspace\Workspaces; /** - * @internal only used within - * @see ContentRepositoryReadModel + * @internal */ -final readonly class ContentHyperRepositoryReadModelAdapter implements ContentRepositoryReadModelAdapterInterface +final readonly class ContentHyperRepositoryReadModelAdapter implements ContentRepositoryReadModel { public function __construct( private Connection $dbal, diff --git a/Neos.ContentGraph.PostgreSQLAdapter/src/Domain/Projection/HypergraphProjection.php b/Neos.ContentGraph.PostgreSQLAdapter/src/Domain/Projection/HypergraphProjection.php index d5e9fb999bf..ae077580077 100644 --- a/Neos.ContentGraph.PostgreSQLAdapter/src/Domain/Projection/HypergraphProjection.php +++ b/Neos.ContentGraph.PostgreSQLAdapter/src/Domain/Projection/HypergraphProjection.php @@ -44,18 +44,17 @@ use Neos\ContentRepository\Core\Infrastructure\DbalCheckpointStorage; use Neos\ContentRepository\Core\Infrastructure\DbalSchemaDiff; use Neos\ContentRepository\Core\Projection\CheckpointStorageStatusType; -use Neos\ContentRepository\Core\Projection\ProjectionInterface; use Neos\ContentRepository\Core\Projection\ProjectionStatus; +use Neos\ContentRepository\Core\Projection\ContentRepositoryReadModelProjection; use Neos\EventStore\Model\Event\SequenceNumber; use Neos\EventStore\Model\EventEnvelope; /** * The alternate reality-aware hypergraph projector for the PostgreSQL backend via Doctrine DBAL * - * @implements ProjectionInterface * @internal the parent Content Graph is public */ -final class HypergraphProjection implements ProjectionInterface +final class HypergraphProjection implements ContentRepositoryReadModelProjection { use ContentStreamForking; use NodeCreation; diff --git a/Neos.ContentGraph.PostgreSQLAdapter/src/HypergraphProjectionFactory.php b/Neos.ContentGraph.PostgreSQLAdapter/src/HypergraphProjectionFactory.php index 1e3fbdb872a..8d0349518f3 100644 --- a/Neos.ContentGraph.PostgreSQLAdapter/src/HypergraphProjectionFactory.php +++ b/Neos.ContentGraph.PostgreSQLAdapter/src/HypergraphProjectionFactory.php @@ -7,7 +7,6 @@ use Doctrine\DBAL\Connection; use Neos\ContentGraph\PostgreSQLAdapter\Domain\Projection\HypergraphProjection; use Neos\ContentGraph\PostgreSQLAdapter\Domain\Repository\NodeFactory; -use Neos\ContentRepository\Core\ContentRepositoryReadModel; use Neos\ContentRepository\Core\Factory\ProjectionFactoryDependencies; use Neos\ContentRepository\Core\Projection\ProjectionFactoryInterface; use Neos\ContentRepository\Core\SharedModel\ContentRepository\ContentRepositoryId; @@ -45,7 +44,7 @@ public function build( return new HypergraphProjection( $this->dbal, $tableNamePrefix, - new ContentRepositoryReadModel(new ContentHyperRepositoryReadModelAdapter($this->dbal, $nodeFactory, $projectionFactoryDependencies->contentRepositoryId, $projectionFactoryDependencies->nodeTypeManager, $tableNamePrefix)) + new ContentHyperRepositoryReadModelAdapter($this->dbal, $nodeFactory, $projectionFactoryDependencies->contentRepositoryId, $projectionFactoryDependencies->nodeTypeManager, $tableNamePrefix) ); } } diff --git a/Neos.ContentRepository.Core/Classes/CommandHandlingDependencies.php b/Neos.ContentRepository.Core/Classes/CommandHandlingDependencies.php index 1c778159fcd..9140ff7ca5a 100644 --- a/Neos.ContentRepository.Core/Classes/CommandHandlingDependencies.php +++ b/Neos.ContentRepository.Core/Classes/CommandHandlingDependencies.php @@ -38,8 +38,10 @@ final class CommandHandlingDependencies */ private array $overriddenContentGraphInstances = []; - public function __construct(private readonly ContentRepository $contentRepository) - { + public function __construct( + private readonly ContentRepository $contentRepository, + private readonly ContentRepositoryReadModel $adapter + ) { } public function handle(CommandInterface $command): CommandResult @@ -49,7 +51,7 @@ public function handle(CommandInterface $command): CommandResult public function getContentStreamVersion(ContentStreamId $contentStreamId): Version { - $contentStream = $this->contentRepository->findContentStreamById($contentStreamId); + $contentStream = $this->adapter->findContentStreamById($contentStreamId); if ($contentStream === null) { throw new \InvalidArgumentException(sprintf('Failed to find content stream with id "%s"', $contentStreamId->value), 1716902051); } @@ -58,12 +60,12 @@ public function getContentStreamVersion(ContentStreamId $contentStreamId): Versi public function contentStreamExists(ContentStreamId $contentStreamId): bool { - return $this->contentRepository->findContentStreamById($contentStreamId) !== null; + return $this->adapter->findContentStreamById($contentStreamId) !== null; } public function getContentStreamStatus(ContentStreamId $contentStreamId): ContentStreamStatus { - $contentStream = $this->contentRepository->findContentStreamById($contentStreamId); + $contentStream = $this->adapter->findContentStreamById($contentStreamId); if ($contentStream === null) { throw new \InvalidArgumentException(sprintf('Failed to find content stream with id "%s"', $contentStreamId->value), 1716902219); } @@ -72,7 +74,7 @@ public function getContentStreamStatus(ContentStreamId $contentStreamId): Conten public function findWorkspaceByName(WorkspaceName $workspaceName): ?Workspace { - return $this->contentRepository->findWorkspaceByName($workspaceName); + return $this->adapter->findWorkspaceByName($workspaceName); } /** @@ -83,8 +85,11 @@ public function getContentGraph(WorkspaceName $workspaceName): ContentGraphInter if (isset($this->overriddenContentGraphInstances[$workspaceName->value])) { return $this->overriddenContentGraphInstances[$workspaceName->value]; } - - return $this->contentRepository->getContentGraph($workspaceName); + $workspace = $this->adapter->findWorkspaceByName($workspaceName); + if ($workspace === null) { + throw WorkspaceDoesNotExist::butWasSupposedTo($workspaceName); + } + return $this->adapter->buildContentGraph($workspace->workspaceName, $workspace->currentContentStreamId); } /** @@ -102,7 +107,7 @@ public function overrideContentStreamId(WorkspaceName $workspaceName, ContentStr throw new \RuntimeException('Contentstream override for this workspace already in effect, nesting not allowed.', 1715170938); } - $contentGraph = $this->contentRepository->projectionState(ContentRepositoryReadModel::class)->getContentGraphByWorkspaceNameAndContentStreamId($workspaceName, $contentStreamId); + $contentGraph = $this->adapter->buildContentGraph($workspaceName, $contentStreamId); $this->overriddenContentGraphInstances[$workspaceName->value] = $contentGraph; try { diff --git a/Neos.ContentRepository.Core/Classes/ContentRepository.php b/Neos.ContentRepository.Core/Classes/ContentRepository.php index 2acb37f73e2..9a395894ef9 100644 --- a/Neos.ContentRepository.Core/Classes/ContentRepository.php +++ b/Neos.ContentRepository.Core/Classes/ContentRepository.php @@ -30,6 +30,7 @@ use Neos\ContentRepository\Core\Projection\CatchUp; use Neos\ContentRepository\Core\Projection\CatchUpOptions; use Neos\ContentRepository\Core\Projection\ContentGraph\ContentGraphInterface; +use Neos\ContentRepository\Core\Projection\ContentRepositoryReadModelProjection; use Neos\ContentRepository\Core\Projection\ProjectionInterface; use Neos\ContentRepository\Core\Projection\ProjectionsAndCatchUpHooks; use Neos\ContentRepository\Core\Projection\ProjectionStateInterface; @@ -69,8 +70,9 @@ final class ContentRepository */ private array $projectionStateCache; - private CommandHandlingDependencies $commandHandlingDependencies; + private ContentRepositoryReadModel $adapter; + private CommandHandlingDependencies $commandHandlingDependencies; /** * @internal use the {@see ContentRepositoryFactory::getOrBuild()} to instantiate @@ -88,7 +90,8 @@ public function __construct( private readonly UserIdProviderInterface $userIdProvider, private readonly ClockInterface $clock, ) { - $this->commandHandlingDependencies = new CommandHandlingDependencies($this); + $this->adapter = $this->projectionsAndCatchUpHooks->readModelProjection->getState(); + $this->commandHandlingDependencies = new CommandHandlingDependencies($this, $this->adapter); } /** @@ -148,7 +151,7 @@ public function projectionState(string $projectionStateClassName): ProjectionSta $projectionState = $this->projectionStateCache[$projectionStateClassName]; return $projectionState; } - foreach ($this->projectionsAndCatchUpHooks->projections as $projection) { + foreach ($this->projectionsAndCatchUpHooks->additionalProjections as $projection) { $projectionState = $projection->getState(); if ($projectionState instanceof $projectionStateClassName) { $this->projectionStateCache[$projectionStateClassName] = $projectionState; @@ -163,7 +166,7 @@ public function projectionState(string $projectionStateClassName): ProjectionSta */ public function catchUpProjection(string $projectionClassName, CatchUpOptions $options): void { - $projection = $this->projectionsAndCatchUpHooks->projections->get($projectionClassName); + $projection = $this->projectionsAndCatchUpHooks->getProjection($projectionClassName); $catchUpHookFactory = $this->projectionsAndCatchUpHooks->getCatchUpHookFactoryForProjection($projection); $catchUpHook = $catchUpHookFactory?->build($this); @@ -204,15 +207,18 @@ public function catchUpProjection(string $projectionClassName, CatchUpOptions $o public function setUp(): void { $this->eventStore->setup(); - foreach ($this->projectionsAndCatchUpHooks->projections as $projection) { + $this->projectionsAndCatchUpHooks->readModelProjection->setUp(); + foreach ($this->projectionsAndCatchUpHooks->additionalProjections as $projection) { $projection->setUp(); } } public function status(): ContentRepositoryStatus { - $projectionStatuses = ProjectionStatuses::create(); - foreach ($this->projectionsAndCatchUpHooks->projections as $projectionClassName => $projection) { + $projectionStatuses = ProjectionStatuses::create([ + ContentRepositoryReadModelProjection::class => $this->projectionsAndCatchUpHooks->readModelProjection->status() + ]); + foreach ($this->projectionsAndCatchUpHooks->additionalProjections as $projectionClassName => $projection) { $projectionStatuses = $projectionStatuses->with($projectionClassName, $projection->status()); } return new ContentRepositoryStatus( @@ -223,7 +229,8 @@ public function status(): ContentRepositoryStatus public function resetProjectionStates(): void { - foreach ($this->projectionsAndCatchUpHooks->projections as $projection) { + $this->projectionsAndCatchUpHooks->readModelProjection->reset(); + foreach ($this->projectionsAndCatchUpHooks->additionalProjections as $projection) { $projection->reset(); } } @@ -233,7 +240,7 @@ public function resetProjectionStates(): void */ public function resetProjectionState(string $projectionClassName): void { - $projection = $this->projectionsAndCatchUpHooks->projections->get($projectionClassName); + $projection = $this->projectionsAndCatchUpHooks->getProjection($projectionClassName); $projection->reset(); } @@ -242,7 +249,11 @@ public function resetProjectionState(string $projectionClassName): void */ public function getContentGraph(WorkspaceName $workspaceName): ContentGraphInterface { - return $this->getContentRepositoryReadModel()->getContentGraphByWorkspaceName($workspaceName); + $workspace = $this->adapter->findWorkspaceByName($workspaceName); + if ($workspace === null) { + throw WorkspaceDoesNotExist::butWasSupposedTo($workspaceName); + } + return $this->adapter->buildContentGraph($workspaceName, $workspace->currentContentStreamId); } /** @@ -250,7 +261,7 @@ public function getContentGraph(WorkspaceName $workspaceName): ContentGraphInter */ public function findWorkspaceByName(WorkspaceName $workspaceName): ?Workspace { - return $this->getContentRepositoryReadModel()->findWorkspaceByName($workspaceName); + return $this->adapter->findWorkspaceByName($workspaceName); } /** @@ -259,17 +270,17 @@ public function findWorkspaceByName(WorkspaceName $workspaceName): ?Workspace */ public function findWorkspaces(): Workspaces { - return $this->getContentRepositoryReadModel()->findWorkspaces(); + return $this->adapter->findWorkspaces(); } public function findContentStreamById(ContentStreamId $contentStreamId): ?ContentStream { - return $this->getContentRepositoryReadModel()->findContentStreamById($contentStreamId); + return $this->adapter->findContentStreamById($contentStreamId); } public function findContentStreams(): ContentStreams { - return $this->getContentRepositoryReadModel()->findContentStreams(); + return $this->adapter->findContentStreams(); } public function getNodeTypeManager(): NodeTypeManager @@ -286,9 +297,4 @@ public function getContentDimensionSource(): ContentDimensionSourceInterface { return $this->contentDimensionSource; } - - private function getContentRepositoryReadModel(): ContentRepositoryReadModel - { - return $this->projectionState(ContentRepositoryReadModel::class); - } } diff --git a/Neos.ContentRepository.Core/Classes/ContentRepositoryReadModel.php b/Neos.ContentRepository.Core/Classes/ContentRepositoryReadModel.php index 38733eaf7a7..e19363b1480 100644 --- a/Neos.ContentRepository.Core/Classes/ContentRepositoryReadModel.php +++ b/Neos.ContentRepository.Core/Classes/ContentRepositoryReadModel.php @@ -16,7 +16,6 @@ use Neos\ContentRepository\Core\Projection\ContentGraph\ContentGraphInterface; use Neos\ContentRepository\Core\Projection\ProjectionStateInterface; -use Neos\ContentRepository\Core\SharedModel\Exception\WorkspaceDoesNotExist; use Neos\ContentRepository\Core\SharedModel\Workspace\ContentStream; use Neos\ContentRepository\Core\SharedModel\Workspace\ContentStreamId; use Neos\ContentRepository\Core\SharedModel\Workspace\ContentStreams; @@ -25,65 +24,19 @@ use Neos\ContentRepository\Core\SharedModel\Workspace\Workspaces; /** - * A finder for a ContentGraph bound to contentStream / workspaceName + * Create implementations of ContentGraphs bound to a specific Workspace and/or ContentStream * - * The API way of accessing a ContentGraph is via ContentRepository::getContentGraph() - * - * @internal User land code should not use this directly. - * @see ContentRepository::getContentGraph() + * @internal This is just an implementation detail to be implemented by the specific adapters */ -final class ContentRepositoryReadModel implements ProjectionStateInterface +interface ContentRepositoryReadModel extends ProjectionStateInterface { - public function __construct( - private readonly ContentRepositoryReadModelAdapterInterface $adapter - ) { - } - - public function findWorkspaceByName(WorkspaceName $workspaceName): ?Workspace - { - return $this->adapter->findWorkspaceByName($workspaceName); - } - - public function findWorkspaces(): Workspaces - { - return $this->adapter->findWorkspaces(); - } + public function buildContentGraph(WorkspaceName $workspaceName, ContentStreamId $contentStreamId): ContentGraphInterface; - public function findContentStreamById(ContentStreamId $contentStreamId): ?ContentStream - { - return $this->adapter->findContentStreamById($contentStreamId); - } + public function findWorkspaceByName(WorkspaceName $workspaceName): ?Workspace; - public function findContentStreams(): ContentStreams - { - return $this->adapter->findContentStreams(); - } + public function findWorkspaces(): Workspaces; - /** - * The default way to get a content graph to operate on. - * The currently assigned ContentStreamId for the given Workspace is resolved internally. - * - * @throws WorkspaceDoesNotExist if the provided workspace does not resolve to an existing content stream - * @see ContentRepository::getContentGraph() - */ - public function getContentGraphByWorkspaceName(WorkspaceName $workspaceName): ContentGraphInterface - { - $workspace = $this->findWorkspaceByName($workspaceName); - if ($workspace === null) { - throw WorkspaceDoesNotExist::butWasSupposedTo($workspaceName); - } - return $this->adapter->buildContentGraph($workspace->workspaceName, $workspace->currentContentStreamId); - } + public function findContentStreamById(ContentStreamId $contentStreamId): ?ContentStream; - /** - * For testing we allow getting an instance set by both parameters, effectively overriding the relationship at will - * - * @param WorkspaceName $workspaceName - * @param ContentStreamId $contentStreamId - * @internal Only for testing - */ - public function getContentGraphByWorkspaceNameAndContentStreamId(WorkspaceName $workspaceName, ContentStreamId $contentStreamId): ContentGraphInterface - { - return $this->adapter->buildContentGraph($workspaceName, $contentStreamId); - } + public function findContentStreams(): ContentStreams; } diff --git a/Neos.ContentRepository.Core/Classes/ContentRepositoryReadModelAdapterInterface.php b/Neos.ContentRepository.Core/Classes/ContentRepositoryReadModelAdapterInterface.php deleted file mode 100644 index 7d266fdec9d..00000000000 --- a/Neos.ContentRepository.Core/Classes/ContentRepositoryReadModelAdapterInterface.php +++ /dev/null @@ -1,42 +0,0 @@ -projectionFactoryDependencies, $this->getOrBuild(), $this->buildEventPersister(), - $this->projectionsAndCatchUpHooks->projections, + $this->projectionsAndCatchUpHooks, ); return $serviceFactory->build($serviceFactoryDependencies); } @@ -168,7 +168,7 @@ private function buildEventPersister(): EventPersister $this->projectionFactoryDependencies->eventStore, $this->projectionCatchUpTrigger, $this->projectionFactoryDependencies->eventNormalizer, - $this->projectionsAndCatchUpHooks->projections, + $this->projectionsAndCatchUpHooks->getAllProjections(), ); } return $this->eventPersister; diff --git a/Neos.ContentRepository.Core/Classes/Factory/ContentRepositoryServiceFactoryDependencies.php b/Neos.ContentRepository.Core/Classes/Factory/ContentRepositoryServiceFactoryDependencies.php index ca9df198cee..0cbe70adc6b 100644 --- a/Neos.ContentRepository.Core/Classes/Factory/ContentRepositoryServiceFactoryDependencies.php +++ b/Neos.ContentRepository.Core/Classes/Factory/ContentRepositoryServiceFactoryDependencies.php @@ -22,7 +22,7 @@ use Neos\ContentRepository\Core\EventStore\EventPersister; use Neos\ContentRepository\Core\Infrastructure\Property\PropertyConverter; use Neos\ContentRepository\Core\NodeType\NodeTypeManager; -use Neos\ContentRepository\Core\Projection\Projections; +use Neos\ContentRepository\Core\Projection\ProjectionsAndCatchUpHooks; use Neos\ContentRepository\Core\SharedModel\ContentRepository\ContentRepositoryId; use Neos\EventStore\EventStoreInterface; @@ -46,7 +46,7 @@ private function __construct( public ContentRepository $contentRepository, // we don't need CommandBus, because this is included in ContentRepository->handle() public EventPersister $eventPersister, - public Projections $projections, + public ProjectionsAndCatchUpHooks $projectionsAndCatchUpHooks, ) { } @@ -57,7 +57,7 @@ public static function create( ProjectionFactoryDependencies $projectionFactoryDependencies, ContentRepository $contentRepository, EventPersister $eventPersister, - Projections $projections, + ProjectionsAndCatchUpHooks $projectionsAndCatchUpHooks, ): self { return new self( $projectionFactoryDependencies->contentRepositoryId, @@ -70,7 +70,7 @@ public static function create( $projectionFactoryDependencies->propertyConverter, $contentRepository, $eventPersister, - $projections, + $projectionsAndCatchUpHooks, ); } } diff --git a/Neos.ContentRepository.Core/Classes/Factory/ProjectionsAndCatchUpHooksFactory.php b/Neos.ContentRepository.Core/Classes/Factory/ProjectionsAndCatchUpHooksFactory.php index 609afd289a8..b72522a17ee 100644 --- a/Neos.ContentRepository.Core/Classes/Factory/ProjectionsAndCatchUpHooksFactory.php +++ b/Neos.ContentRepository.Core/Classes/Factory/ProjectionsAndCatchUpHooksFactory.php @@ -11,6 +11,7 @@ use Neos\ContentRepository\Core\Projection\Projections; use Neos\ContentRepository\Core\Projection\ProjectionsAndCatchUpHooks; use Neos\ContentRepository\Core\Projection\ProjectionStateInterface; +use Neos\ContentRepository\Core\Projection\ContentRepositoryReadModelProjection; /** * @api for custom framework integrations, not for users of the CR @@ -53,6 +54,7 @@ public function registerCatchUpHookFactory(ProjectionFactoryInterface $factory, */ public function build(ProjectionFactoryDependencies $projectionFactoryDependencies): ProjectionsAndCatchUpHooks { + $contentRepositoryReadModelProjection = null; $projectionsArray = []; $catchUpHookFactoriesByProjectionClassName = []; foreach ($this->factories as $factoryDefinition) { @@ -71,9 +73,17 @@ public function build(ProjectionFactoryDependencies $projectionFactoryDependenci $options, ); $catchUpHookFactoriesByProjectionClassName[$projection::class] = $catchUpHookFactories; - $projectionsArray[] = $projection; + if ($projection instanceof ContentRepositoryReadModelProjection) { + $contentRepositoryReadModelProjection = $projection; + } else { + $projectionsArray[] = $projection; + } + } + + if ($contentRepositoryReadModelProjection === null) { + throw new \RuntimeException('A content repository requires the ContentRepositoryReadModelProjection to be registered.'); } - return new ProjectionsAndCatchUpHooks(Projections::fromArray($projectionsArray), $catchUpHookFactoriesByProjectionClassName); + return new ProjectionsAndCatchUpHooks($contentRepositoryReadModelProjection, Projections::fromArray($projectionsArray), $catchUpHookFactoriesByProjectionClassName); } } diff --git a/Neos.ContentRepository.Core/Classes/Projection/ContentRepositoryReadModelProjection.php b/Neos.ContentRepository.Core/Classes/Projection/ContentRepositoryReadModelProjection.php new file mode 100644 index 00000000000..2c5bfcb955f --- /dev/null +++ b/Neos.ContentRepository.Core/Classes/Projection/ContentRepositoryReadModelProjection.php @@ -0,0 +1,16 @@ + + * @api + */ +interface ContentRepositoryReadModelProjection extends ProjectionInterface +{ + public function getState(): ContentRepositoryReadModel; +} diff --git a/Neos.ContentRepository.Core/Classes/Projection/ProjectionStatuses.php b/Neos.ContentRepository.Core/Classes/Projection/ProjectionStatuses.php index 79a59b0a550..347abc0de6d 100644 --- a/Neos.ContentRepository.Core/Classes/Projection/ProjectionStatuses.php +++ b/Neos.ContentRepository.Core/Classes/Projection/ProjectionStatuses.php @@ -18,9 +18,12 @@ private function __construct( ) { } - public static function create(): self + /** + * @param array>, ProjectionStatus> $statuses + */ + public static function create(array $statuses = []): self { - return new self([]); + return new self($statuses); } /** diff --git a/Neos.ContentRepository.Core/Classes/Projection/Projections.php b/Neos.ContentRepository.Core/Classes/Projection/Projections.php index 0bc7dffec20..4a6f6a3bb3a 100644 --- a/Neos.ContentRepository.Core/Classes/Projection/Projections.php +++ b/Neos.ContentRepository.Core/Classes/Projection/Projections.php @@ -78,6 +78,15 @@ public function has(string $projectionClassName): bool return array_key_exists($projectionClassName, $this->projections); } + /** + * @param ProjectionInterface $projection + * @return self + */ + public function with(ProjectionInterface $projection): self + { + return self::fromArray([...$this->projections, $projection]); + } + /** * @return list>> */ diff --git a/Neos.ContentRepository.Core/Classes/Projection/ProjectionsAndCatchUpHooks.php b/Neos.ContentRepository.Core/Classes/Projection/ProjectionsAndCatchUpHooks.php index 86eebadae4a..807b82f0ce8 100644 --- a/Neos.ContentRepository.Core/Classes/Projection/ProjectionsAndCatchUpHooks.php +++ b/Neos.ContentRepository.Core/Classes/Projection/ProjectionsAndCatchUpHooks.php @@ -13,7 +13,8 @@ * @param array>, CatchUpHookFactories> $catchUpHookFactoriesByProjectionClassName */ public function __construct( - public Projections $projections, + public ContentRepositoryReadModelProjection $readModelProjection, + public Projections $additionalProjections, private array $catchUpHookFactoriesByProjectionClassName, ) { } @@ -25,4 +26,22 @@ public function getCatchUpHookFactoryForProjection(ProjectionInterface $projecti { return $this->catchUpHookFactoriesByProjectionClassName[$projection::class] ?? null; } + + /** + * @template T of ProjectionInterface + * @param class-string $projectionClassName + * @return T + */ + public function getProjection(string $projectionClassName): ProjectionInterface + { + if ($this->readModelProjection instanceof $projectionClassName) { + return $this->readModelProjection; + } + return $this->additionalProjections->get($projectionClassName); + } + + public function getAllProjections(): Projections + { + return $this->additionalProjections->with($this->readModelProjection); + } } diff --git a/Neos.ContentRepository.LegacyNodeMigration/Tests/Behavior/Bootstrap/FeatureContext.php b/Neos.ContentRepository.LegacyNodeMigration/Tests/Behavior/Bootstrap/FeatureContext.php index 00421a6bea4..775919a753a 100644 --- a/Neos.ContentRepository.LegacyNodeMigration/Tests/Behavior/Bootstrap/FeatureContext.php +++ b/Neos.ContentRepository.LegacyNodeMigration/Tests/Behavior/Bootstrap/FeatureContext.php @@ -12,7 +12,6 @@ use Neos\ContentRepository\BehavioralTests\TestSuite\Behavior\GherkinPyStringNodeBasedNodeTypeManagerFactory; use Neos\ContentRepository\BehavioralTests\TestSuite\Behavior\GherkinTableNodeBasedContentDimensionSourceFactory; use Neos\ContentRepository\Core\ContentRepository; -use Neos\ContentRepository\Core\ContentRepositoryReadModel; use Neos\ContentRepository\Core\EventStore\EventNormalizer; use Neos\ContentRepository\Core\Factory\ContentRepositoryServiceFactoryDependencies; use Neos\ContentRepository\Core\Factory\ContentRepositoryServiceFactoryInterface; diff --git a/Neos.ContentRepository.TestSuite/Classes/Behavior/Features/Bootstrap/CRTestSuiteRuntimeVariables.php b/Neos.ContentRepository.TestSuite/Classes/Behavior/Features/Bootstrap/CRTestSuiteRuntimeVariables.php index 12ebd6b0a5f..e4505319463 100644 --- a/Neos.ContentRepository.TestSuite/Classes/Behavior/Features/Bootstrap/CRTestSuiteRuntimeVariables.php +++ b/Neos.ContentRepository.TestSuite/Classes/Behavior/Features/Bootstrap/CRTestSuiteRuntimeVariables.php @@ -14,7 +14,6 @@ namespace Neos\ContentRepository\TestSuite\Behavior\Features\Bootstrap; -use Neos\ContentRepository\Core\ContentRepositoryReadModel; use Neos\ContentRepository\Core\ContentRepository; use Neos\ContentRepository\Core\DimensionSpace\DimensionSpacePoint; use Neos\ContentRepository\Core\Projection\ContentGraph\ContentSubgraphInterface; @@ -125,9 +124,7 @@ public function visibilityConstraintsAreSetTo(string $restrictionType): void public function getCurrentSubgraph(): ContentSubgraphInterface { - $contentRepositoryReadModel = $this->currentContentRepository->projectionState(ContentRepositoryReadModel::class); - - return $contentRepositoryReadModel->getContentGraphByWorkspaceName($this->currentWorkspaceName)->getSubgraph( + return $this->currentContentRepository->getContentGraph($this->currentWorkspaceName)->getSubgraph( $this->currentDimensionSpacePoint, $this->currentVisibilityConstraints ); diff --git a/Neos.ContentRepository.TestSuite/Classes/Behavior/Features/Bootstrap/ProjectedNodeTrait.php b/Neos.ContentRepository.TestSuite/Classes/Behavior/Features/Bootstrap/ProjectedNodeTrait.php index d5fde970ec4..40c02ccde08 100644 --- a/Neos.ContentRepository.TestSuite/Classes/Behavior/Features/Bootstrap/ProjectedNodeTrait.php +++ b/Neos.ContentRepository.TestSuite/Classes/Behavior/Features/Bootstrap/ProjectedNodeTrait.php @@ -16,7 +16,6 @@ use Behat\Gherkin\Node\TableNode; use GuzzleHttp\Psr7\Uri; -use Neos\ContentRepository\Core\ContentRepositoryReadModel; use Neos\ContentRepository\Core\Feature\SubtreeTagging\Dto\SubtreeTag; use Neos\ContentRepository\Core\NodeType\NodeTypeName; use Neos\ContentRepository\Core\Projection\ContentGraph\ContentSubgraphInterface; diff --git a/Neos.ContentRepositoryRegistry/Classes/ContentRepositoryRegistry.php b/Neos.ContentRepositoryRegistry/Classes/ContentRepositoryRegistry.php index 0a4bf64988f..edbc98e092f 100644 --- a/Neos.ContentRepositoryRegistry/Classes/ContentRepositoryRegistry.php +++ b/Neos.ContentRepositoryRegistry/Classes/ContentRepositoryRegistry.php @@ -244,7 +244,7 @@ private function buildProjectionsFactory(ContentRepositoryId $contentRepositoryI if ($projectionOptions === null) { continue; } - $projectionFactory = $this->objectManager->get($projectionOptions['factoryObjectName']); + $projectionFactory = isset($projectionOptions['factoryObjectName']) ? $this->objectManager->get($projectionOptions['factoryObjectName']) : null; if (!$projectionFactory instanceof ProjectionFactoryInterface) { throw InvalidConfigurationException::fromMessage('Projection factory object name for projection "%s" (content repository "%s") is not an instance of %s but %s.', $projectionName, $contentRepositoryId->value, ProjectionFactoryInterface::class, get_debug_type($projectionFactory)); } diff --git a/Neos.ContentRepositoryRegistry/Classes/Service/ProjectionReplayServiceFactory.php b/Neos.ContentRepositoryRegistry/Classes/Service/ProjectionReplayServiceFactory.php index 337297d9bb6..7f72d4f872e 100644 --- a/Neos.ContentRepositoryRegistry/Classes/Service/ProjectionReplayServiceFactory.php +++ b/Neos.ContentRepositoryRegistry/Classes/Service/ProjectionReplayServiceFactory.php @@ -22,7 +22,7 @@ final class ProjectionReplayServiceFactory implements ContentRepositoryServiceFa public function build(ContentRepositoryServiceFactoryDependencies $serviceFactoryDependencies): ContentRepositoryServiceInterface { return new ProjectionReplayService( - $serviceFactoryDependencies->projections, + $serviceFactoryDependencies->projectionsAndCatchUpHooks->getAllProjections(), $serviceFactoryDependencies->contentRepository, $serviceFactoryDependencies->eventStore, ); diff --git a/Neos.ContentRepositoryRegistry/Configuration/Settings.yaml b/Neos.ContentRepositoryRegistry/Configuration/Settings.yaml index 44e28699641..90b3a14e339 100644 --- a/Neos.ContentRepositoryRegistry/Configuration/Settings.yaml +++ b/Neos.ContentRepositoryRegistry/Configuration/Settings.yaml @@ -69,7 +69,7 @@ Neos: className: Neos\ContentRepositoryRegistry\Infrastructure\Property\Normalizer\ProxyAwareObjectNormalizer projections: - # NOTE: the following name must be stable, because we use it f.e. in Neos UI to register catchUpHooks for content cache flushing + # TODO make first level special option and rename 'Neos.ContentRepository:ContentGraph': # NOTE: This introduces a soft-dependency to the neos/contentgraph-doctrinedbaladapter package, but it can be overridden when a different adapter is used factoryObjectName: Neos\ContentGraph\DoctrineDbalAdapter\DoctrineDbalContentGraphProjectionFactory From 2b12446356a73bc1f6a5c85f7b1b1fad8fd4b708 Mon Sep 17 00:00:00 2001 From: mhsdesign <85400359+mhsdesign@users.noreply.github.com> Date: Wed, 2 Oct 2024 16:35:25 +0200 Subject: [PATCH 02/12] BUGFIX: Simplify `projectionState` to be more reliable Previously if called with `ProjectionStateInterface::class` it would return the first state which will then not be callable again by its fqn. Now only fqn are allowed. Initially the interface logic was needed for interchangeable cr readmodel projection states --- .../Classes/ContentRepository.php | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/Neos.ContentRepository.Core/Classes/ContentRepository.php b/Neos.ContentRepository.Core/Classes/ContentRepository.php index 9a395894ef9..d1a48f0a20a 100644 --- a/Neos.ContentRepository.Core/Classes/ContentRepository.php +++ b/Neos.ContentRepository.Core/Classes/ContentRepository.php @@ -146,18 +146,17 @@ public function handle(CommandInterface $command): CommandResult */ public function projectionState(string $projectionStateClassName): ProjectionStateInterface { + if (!isset($this->projectionStateCache)) { + foreach ($this->projectionsAndCatchUpHooks->additionalProjections as $projection) { + $projectionState = $projection->getState(); + $this->projectionStateCache[$projectionState::class] = $projectionState; + } + } if (isset($this->projectionStateCache[$projectionStateClassName])) { /** @var T $projectionState */ $projectionState = $this->projectionStateCache[$projectionStateClassName]; return $projectionState; } - foreach ($this->projectionsAndCatchUpHooks->additionalProjections as $projection) { - $projectionState = $projection->getState(); - if ($projectionState instanceof $projectionStateClassName) { - $this->projectionStateCache[$projectionStateClassName] = $projectionState; - return $projectionState; - } - } throw new \InvalidArgumentException(sprintf('A projection state of type "%s" is not registered in this content repository instance.', $projectionStateClassName), 1662033650); } From d20bb657e721b01290c1c0d5f9153c45980bfb90 Mon Sep 17 00:00:00 2001 From: mhsdesign <85400359+mhsdesign@users.noreply.github.com> Date: Tue, 8 Oct 2024 23:01:36 +0200 Subject: [PATCH 03/12] TASK: Remove ContentGraphInterface::countNodes as the method is not bound to a workspace but cross content stream Also since its internal and only used for the tests it a good to be hidden in the low level `ContentRepositoryReadModel` next to other low level methods --- .../src/ContentRepositoryReadModelAdapter.php | 15 +++++++++++++++ .../src/Domain/Repository/ContentGraph.php | 13 ------------- .../ContentHyperRepositoryReadModelAdapter.php | 6 ++++++ .../src/Domain/Repository/ContentHypergraph.php | 11 ----------- .../Classes/ContentRepositoryReadModel.php | 7 +++++++ .../ContentGraph/ContentGraphInterface.php | 7 ------- .../Features/Bootstrap/CRTestSuiteTrait.php | 17 ++++++++++++++++- 7 files changed, 44 insertions(+), 32 deletions(-) diff --git a/Neos.ContentGraph.DoctrineDbalAdapter/src/ContentRepositoryReadModelAdapter.php b/Neos.ContentGraph.DoctrineDbalAdapter/src/ContentRepositoryReadModelAdapter.php index 32cf74dca9c..6e7d09d380f 100644 --- a/Neos.ContentGraph.DoctrineDbalAdapter/src/ContentRepositoryReadModelAdapter.php +++ b/Neos.ContentGraph.DoctrineDbalAdapter/src/ContentRepositoryReadModelAdapter.php @@ -130,6 +130,21 @@ public function findContentStreams(): ContentStreams return ContentStreams::fromArray(array_map(self::contentStreamFromDatabaseRow(...), $rows)); } + public function countNodes(): int + { + $countNodesStatement = <<tableNames->node()} + SQL; + try { + return (int)$this->dbal->fetchOne($countNodesStatement); + } catch (Exception $e) { + throw new \RuntimeException(sprintf('Failed to count rows in database: %s', $e->getMessage()), 1701444590, $e); + } + } + /** * @param array $row */ diff --git a/Neos.ContentGraph.DoctrineDbalAdapter/src/Domain/Repository/ContentGraph.php b/Neos.ContentGraph.DoctrineDbalAdapter/src/Domain/Repository/ContentGraph.php index 68b0fd85fc0..d88070f7351 100644 --- a/Neos.ContentGraph.DoctrineDbalAdapter/src/Domain/Repository/ContentGraph.php +++ b/Neos.ContentGraph.DoctrineDbalAdapter/src/Domain/Repository/ContentGraph.php @@ -277,19 +277,6 @@ public function getDimensionSpacePointsOccupiedByChildNodeName(NodeName $nodeNam return new DimensionSpacePointSet($dimensionSpacePoints); } - public function countNodes(): int - { - $queryBuilder = $this->createQueryBuilder() - ->select('COUNT(*)') - ->from($this->nodeQueryBuilder->tableNames->node()); - try { - $result = $queryBuilder->executeQuery(); - return (int)$result->fetchOne(); - } catch (DBALException $e) { - throw new \RuntimeException(sprintf('Failed to count rows in database: %s', $e->getMessage()), 1701444590, $e); - } - } - public function findUsedNodeTypeNames(): NodeTypeNames { return NodeTypeNames::fromArray(array_map( diff --git a/Neos.ContentGraph.PostgreSQLAdapter/src/ContentHyperRepositoryReadModelAdapter.php b/Neos.ContentGraph.PostgreSQLAdapter/src/ContentHyperRepositoryReadModelAdapter.php index 534e84b7853..70a37942b99 100644 --- a/Neos.ContentGraph.PostgreSQLAdapter/src/ContentHyperRepositoryReadModelAdapter.php +++ b/Neos.ContentGraph.PostgreSQLAdapter/src/ContentHyperRepositoryReadModelAdapter.php @@ -60,4 +60,10 @@ public function findContentStreams(): ContentStreams // TODO: Implement getContentStreams() method. return ContentStreams::createEmpty(); } + + public function countNodes(): int + { + // TODO: Implement countNodes method. + return 0; + } } diff --git a/Neos.ContentGraph.PostgreSQLAdapter/src/Domain/Repository/ContentHypergraph.php b/Neos.ContentGraph.PostgreSQLAdapter/src/Domain/Repository/ContentHypergraph.php index cfab1b47fb8..29cc36eb21b 100644 --- a/Neos.ContentGraph.PostgreSQLAdapter/src/Domain/Repository/ContentHypergraph.php +++ b/Neos.ContentGraph.PostgreSQLAdapter/src/Domain/Repository/ContentHypergraph.php @@ -259,17 +259,6 @@ public function getDimensionSpacePointsOccupiedByChildNodeName( return new DimensionSpacePointSet($occupiedDimensionSpacePoints); } - /** - * @throws \Doctrine\DBAL\Driver\Exception - * @throws \Doctrine\DBAL\Exception - */ - public function countNodes(): int - { - $query = 'SELECT COUNT(*) FROM ' . $this->tableNamePrefix . '_node'; - - return $this->dbal->executeQuery($query)->fetchOne(); - } - public function findUsedNodeTypeNames(): NodeTypeNames { return NodeTypeNames::createEmpty(); diff --git a/Neos.ContentRepository.Core/Classes/ContentRepositoryReadModel.php b/Neos.ContentRepository.Core/Classes/ContentRepositoryReadModel.php index e19363b1480..0fc7abd4668 100644 --- a/Neos.ContentRepository.Core/Classes/ContentRepositoryReadModel.php +++ b/Neos.ContentRepository.Core/Classes/ContentRepositoryReadModel.php @@ -39,4 +39,11 @@ public function findWorkspaces(): Workspaces; public function findContentStreamById(ContentStreamId $contentStreamId): ?ContentStream; public function findContentStreams(): ContentStreams; + + /** + * Provides the total number of projected nodes regardless of workspace or content stream. + * + * @internal only for consumption in testcases + */ + public function countNodes(): int; } diff --git a/Neos.ContentRepository.Core/Classes/Projection/ContentGraph/ContentGraphInterface.php b/Neos.ContentRepository.Core/Classes/Projection/ContentGraph/ContentGraphInterface.php index 67af3f6d5ff..e8cac17eb67 100644 --- a/Neos.ContentRepository.Core/Classes/Projection/ContentGraph/ContentGraphInterface.php +++ b/Neos.ContentRepository.Core/Classes/Projection/ContentGraph/ContentGraphInterface.php @@ -142,13 +142,6 @@ public function getDimensionSpacePointsOccupiedByChildNodeName( DimensionSpacePointSet $dimensionSpacePointsToCheck ): DimensionSpacePointSet; - /** - * Provides the total number of projected nodes regardless of workspace or content stream. - * - * @internal only for consumption in testcases - */ - public function countNodes(): int; - /** @internal The content stream id where the workspace name points to for this instance */ public function getContentStreamId(): ContentStreamId; } diff --git a/Neos.ContentRepository.TestSuite/Classes/Behavior/Features/Bootstrap/CRTestSuiteTrait.php b/Neos.ContentRepository.TestSuite/Classes/Behavior/Features/Bootstrap/CRTestSuiteTrait.php index ab550c6bd35..15610168130 100644 --- a/Neos.ContentRepository.TestSuite/Classes/Behavior/Features/Bootstrap/CRTestSuiteTrait.php +++ b/Neos.ContentRepository.TestSuite/Classes/Behavior/Features/Bootstrap/CRTestSuiteTrait.php @@ -16,6 +16,8 @@ use Behat\Behat\Hook\Scope\BeforeScenarioScope; use Behat\Gherkin\Node\TableNode; +use Neos\ContentRepository\Core\ContentRepositoryReadModel; +use Neos\ContentRepository\Core\Factory\ContentRepositoryServiceFactoryDependencies; use Neos\ContentRepository\Core\Factory\ContentRepositoryServiceFactoryInterface; use Neos\ContentRepository\Core\Factory\ContentRepositoryServiceInterface; use Neos\ContentRepository\Core\Feature\NodeModification\Dto\PropertyValuesToWrite; @@ -155,7 +157,20 @@ public function workspaceHasStatus(string $rawWorkspaceName, string $status): vo */ public function iExpectTheGraphProjectionToConsistOfExactlyNodes(int $expectedNumberOfNodes): void { - $actualNumberOfNodes = $this->currentContentRepository->getContentGraph($this->currentWorkspaceName)->countNodes(); + // HACK to access + $contentRepositoryReadModelAccess = new class implements ContentRepositoryServiceFactoryInterface { + public ContentRepositoryReadModel|null $instance; + public function build(ContentRepositoryServiceFactoryDependencies $serviceFactoryDependencies): ContentRepositoryServiceInterface + { + $this->instance = $serviceFactoryDependencies->projectionsAndCatchUpHooks->readModelProjection->getState(); + return new class implements ContentRepositoryServiceInterface + { + }; + } + }; + $this->getContentRepositoryService($contentRepositoryReadModelAccess); + + $actualNumberOfNodes = $contentRepositoryReadModelAccess->instance->countNodes(); Assert::assertSame($expectedNumberOfNodes, $actualNumberOfNodes, 'Content graph consists of ' . $actualNumberOfNodes . ' nodes, expected were ' . $expectedNumberOfNodes . '.'); } From fb56a0728a727515e333085ef9e737e1a7d55bd1 Mon Sep 17 00:00:00 2001 From: mhsdesign <85400359+mhsdesign@users.noreply.github.com> Date: Thu, 17 Oct 2024 14:13:44 +0200 Subject: [PATCH 04/12] TASK: Ignore phpstan error --- phpstan-baseline.neon | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index ebbd2ba29a9..888835ae0e3 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -5,6 +5,11 @@ parameters: count: 1 path: Neos.ContentRepositoryRegistry/Classes/Service/ProjectionReplayService.php + - + message: "#^The internal method \"Neos\\\\ContentRepository\\\\Core\\\\Projection\\\\ProjectionsAndCatchUpHooks\\:\\:getAllProjections\" is called\\.$#" + count: 1 + path: Neos.ContentRepositoryRegistry/Classes/Service/ProjectionReplayServiceFactory.php + - message: "#^Method Neos\\\\Neos\\\\Controller\\\\Backend\\\\MenuHelper\\:\\:buildModuleList\\(\\) return type has no value type specified in iterable type array\\.$#" count: 1 From cd4de7115d372af3ade69bf21afe1608ffa181c4 Mon Sep 17 00:00:00 2001 From: mhsdesign <85400359+mhsdesign@users.noreply.github.com> Date: Sat, 19 Oct 2024 10:57:30 +0200 Subject: [PATCH 05/12] TASK: Adjust namings --- .../src/ContentRepositoryReadModelAdapter.php | 4 +-- .../DoctrineDbalContentGraphProjection.php | 10 +++---- ...ContentHyperRepositoryReadModelAdapter.php | 4 +-- .../Projection/HypergraphProjection.php | 10 +++---- .../Classes/CommandHandlingDependencies.php | 16 ++++++------ .../Classes/ContentRepository.php | 26 +++++++++---------- ...> ContentRepositoryReadModelInterface.php} | 6 ++--- .../Factory/ContentRepositoryFactory.php | 1 + .../ProjectionsAndCatchUpHooksFactory.php | 12 ++++----- .../ContentRepositoryProjectionInterface.php | 16 ++++++++++++ .../ContentRepositoryReadModelProjection.php | 16 ------------ .../Projection/ProjectionsAndCatchUpHooks.php | 8 +++--- .../Features/Bootstrap/CRTestSuiteTrait.php | 6 ++--- 13 files changed, 66 insertions(+), 69 deletions(-) rename Neos.ContentRepository.Core/Classes/{ContentRepositoryReadModel.php => ContentRepositoryReadModelInterface.php} (85%) create mode 100644 Neos.ContentRepository.Core/Classes/Projection/ContentRepositoryProjectionInterface.php delete mode 100644 Neos.ContentRepository.Core/Classes/Projection/ContentRepositoryReadModelProjection.php diff --git a/Neos.ContentGraph.DoctrineDbalAdapter/src/ContentRepositoryReadModelAdapter.php b/Neos.ContentGraph.DoctrineDbalAdapter/src/ContentRepositoryReadModelAdapter.php index 6e7d09d380f..82f49831731 100644 --- a/Neos.ContentGraph.DoctrineDbalAdapter/src/ContentRepositoryReadModelAdapter.php +++ b/Neos.ContentGraph.DoctrineDbalAdapter/src/ContentRepositoryReadModelAdapter.php @@ -18,7 +18,7 @@ use Doctrine\DBAL\Exception; use Neos\ContentGraph\DoctrineDbalAdapter\Domain\Repository\ContentGraph; use Neos\ContentGraph\DoctrineDbalAdapter\Domain\Repository\NodeFactory; -use Neos\ContentRepository\Core\ContentRepositoryReadModel; +use Neos\ContentRepository\Core\ContentRepositoryReadModelInterface; use Neos\ContentRepository\Core\NodeType\NodeTypeManager; use Neos\ContentRepository\Core\SharedModel\ContentRepository\ContentRepositoryId; use Neos\ContentRepository\Core\SharedModel\Workspace\ContentStream; @@ -34,7 +34,7 @@ /** * @internal */ -final readonly class ContentRepositoryReadModelAdapter implements ContentRepositoryReadModel +final readonly class ContentRepositoryReadModelAdapter implements ContentRepositoryReadModelInterface { public function __construct( private Connection $dbal, diff --git a/Neos.ContentGraph.DoctrineDbalAdapter/src/DoctrineDbalContentGraphProjection.php b/Neos.ContentGraph.DoctrineDbalAdapter/src/DoctrineDbalContentGraphProjection.php index 10422b5c2f3..1cae3d1bc9f 100644 --- a/Neos.ContentGraph.DoctrineDbalAdapter/src/DoctrineDbalContentGraphProjection.php +++ b/Neos.ContentGraph.DoctrineDbalAdapter/src/DoctrineDbalContentGraphProjection.php @@ -17,7 +17,7 @@ use Neos\ContentGraph\DoctrineDbalAdapter\Domain\Projection\NodeRelationAnchorPoint; use Neos\ContentGraph\DoctrineDbalAdapter\Domain\Repository\DimensionSpacePointsRepository; use Neos\ContentGraph\DoctrineDbalAdapter\Domain\Repository\ProjectionContentGraph; -use Neos\ContentRepository\Core\ContentRepositoryReadModel; +use Neos\ContentRepository\Core\ContentRepositoryReadModelInterface; use Neos\ContentRepository\Core\DimensionSpace\DimensionSpacePoint; use Neos\ContentRepository\Core\DimensionSpace\DimensionSpacePointSet; use Neos\ContentRepository\Core\DimensionSpace\OriginDimensionSpacePoint; @@ -66,7 +66,7 @@ use Neos\ContentRepository\Core\Projection\ContentGraph\NodeTags; use Neos\ContentRepository\Core\Projection\ContentGraph\Timestamps; use Neos\ContentRepository\Core\Projection\ProjectionStatus; -use Neos\ContentRepository\Core\Projection\ContentRepositoryReadModelProjection; +use Neos\ContentRepository\Core\Projection\ContentRepositoryProjectionInterface; use Neos\ContentRepository\Core\SharedModel\Node\NodeAggregateClassification; use Neos\ContentRepository\Core\SharedModel\Node\NodeAggregateId; use Neos\ContentRepository\Core\SharedModel\Node\NodeName; @@ -78,7 +78,7 @@ /** * @internal but the graph projection is api */ -final class DoctrineDbalContentGraphProjection implements ContentRepositoryReadModelProjection +final class DoctrineDbalContentGraphProjection implements ContentRepositoryProjectionInterface { use ContentStream; use NodeMove; @@ -97,7 +97,7 @@ public function __construct( private readonly ProjectionContentGraph $projectionContentGraph, private readonly ContentGraphTableNames $tableNames, private readonly DimensionSpacePointsRepository $dimensionSpacePointsRepository, - private readonly ContentRepositoryReadModel $contentRepositoryReadModel + private readonly ContentRepositoryReadModelInterface $contentRepositoryReadModel ) { $this->checkpointStorage = new DbalCheckpointStorage( $this->dbal, @@ -176,7 +176,7 @@ public function getCheckpointStorage(): DbalCheckpointStorage return $this->checkpointStorage; } - public function getState(): ContentRepositoryReadModel + public function getState(): ContentRepositoryReadModelInterface { return $this->contentRepositoryReadModel; } diff --git a/Neos.ContentGraph.PostgreSQLAdapter/src/ContentHyperRepositoryReadModelAdapter.php b/Neos.ContentGraph.PostgreSQLAdapter/src/ContentHyperRepositoryReadModelAdapter.php index 70a37942b99..2c5abcf1a6b 100644 --- a/Neos.ContentGraph.PostgreSQLAdapter/src/ContentHyperRepositoryReadModelAdapter.php +++ b/Neos.ContentGraph.PostgreSQLAdapter/src/ContentHyperRepositoryReadModelAdapter.php @@ -7,7 +7,7 @@ use Doctrine\DBAL\Connection; use Neos\ContentGraph\PostgreSQLAdapter\Domain\Repository\ContentHypergraph; use Neos\ContentGraph\PostgreSQLAdapter\Domain\Repository\NodeFactory; -use Neos\ContentRepository\Core\ContentRepositoryReadModel; +use Neos\ContentRepository\Core\ContentRepositoryReadModelInterface; use Neos\ContentRepository\Core\NodeType\NodeTypeManager; use Neos\ContentRepository\Core\Projection\ContentGraph\ContentGraphInterface; use Neos\ContentRepository\Core\SharedModel\ContentRepository\ContentRepositoryId; @@ -21,7 +21,7 @@ /** * @internal */ -final readonly class ContentHyperRepositoryReadModelAdapter implements ContentRepositoryReadModel +final readonly class ContentHyperRepositoryReadModelAdapter implements ContentRepositoryReadModelInterface { public function __construct( private Connection $dbal, diff --git a/Neos.ContentGraph.PostgreSQLAdapter/src/Domain/Projection/HypergraphProjection.php b/Neos.ContentGraph.PostgreSQLAdapter/src/Domain/Projection/HypergraphProjection.php index ae077580077..eee11654669 100644 --- a/Neos.ContentGraph.PostgreSQLAdapter/src/Domain/Projection/HypergraphProjection.php +++ b/Neos.ContentGraph.PostgreSQLAdapter/src/Domain/Projection/HypergraphProjection.php @@ -26,7 +26,7 @@ use Neos\ContentGraph\PostgreSQLAdapter\Domain\Projection\Feature\NodeVariation; use Neos\ContentGraph\PostgreSQLAdapter\Domain\Projection\Feature\SubtreeTagging; use Neos\ContentGraph\PostgreSQLAdapter\Domain\Projection\SchemaBuilder\HypergraphSchemaBuilder; -use Neos\ContentRepository\Core\ContentRepositoryReadModel; +use Neos\ContentRepository\Core\ContentRepositoryReadModelInterface; use Neos\ContentRepository\Core\EventStore\EventInterface; use Neos\ContentRepository\Core\Feature\ContentStreamForking\Event\ContentStreamWasForked; use Neos\ContentRepository\Core\Feature\NodeCreation\Event\NodeAggregateWithNodeWasCreated; @@ -45,7 +45,7 @@ use Neos\ContentRepository\Core\Infrastructure\DbalSchemaDiff; use Neos\ContentRepository\Core\Projection\CheckpointStorageStatusType; use Neos\ContentRepository\Core\Projection\ProjectionStatus; -use Neos\ContentRepository\Core\Projection\ContentRepositoryReadModelProjection; +use Neos\ContentRepository\Core\Projection\ContentRepositoryProjectionInterface; use Neos\EventStore\Model\Event\SequenceNumber; use Neos\EventStore\Model\EventEnvelope; @@ -54,7 +54,7 @@ * * @internal the parent Content Graph is public */ -final class HypergraphProjection implements ContentRepositoryReadModelProjection +final class HypergraphProjection implements ContentRepositoryProjectionInterface { use ContentStreamForking; use NodeCreation; @@ -72,7 +72,7 @@ final class HypergraphProjection implements ContentRepositoryReadModelProjection public function __construct( private readonly Connection $dbal, private readonly string $tableNamePrefix, - private readonly ContentRepositoryReadModel $contentRepositoryReadModel + private readonly ContentRepositoryReadModelInterface $contentRepositoryReadModel ) { $this->projectionHypergraph = new ProjectionHypergraph($this->dbal, $this->tableNamePrefix); $this->checkpointStorage = new DbalCheckpointStorage( @@ -218,7 +218,7 @@ public function getCheckpointStorage(): DbalCheckpointStorage return $this->checkpointStorage; } - public function getState(): ContentRepositoryReadModel + public function getState(): ContentRepositoryReadModelInterface { return $this->contentRepositoryReadModel; } diff --git a/Neos.ContentRepository.Core/Classes/CommandHandlingDependencies.php b/Neos.ContentRepository.Core/Classes/CommandHandlingDependencies.php index 9140ff7ca5a..52f2882a8d1 100644 --- a/Neos.ContentRepository.Core/Classes/CommandHandlingDependencies.php +++ b/Neos.ContentRepository.Core/Classes/CommandHandlingDependencies.php @@ -40,7 +40,7 @@ final class CommandHandlingDependencies public function __construct( private readonly ContentRepository $contentRepository, - private readonly ContentRepositoryReadModel $adapter + private readonly ContentRepositoryReadModelInterface $contentRepositoryReadModel ) { } @@ -51,7 +51,7 @@ public function handle(CommandInterface $command): CommandResult public function getContentStreamVersion(ContentStreamId $contentStreamId): Version { - $contentStream = $this->adapter->findContentStreamById($contentStreamId); + $contentStream = $this->contentRepositoryReadModel->findContentStreamById($contentStreamId); if ($contentStream === null) { throw new \InvalidArgumentException(sprintf('Failed to find content stream with id "%s"', $contentStreamId->value), 1716902051); } @@ -60,12 +60,12 @@ public function getContentStreamVersion(ContentStreamId $contentStreamId): Versi public function contentStreamExists(ContentStreamId $contentStreamId): bool { - return $this->adapter->findContentStreamById($contentStreamId) !== null; + return $this->contentRepositoryReadModel->findContentStreamById($contentStreamId) !== null; } public function getContentStreamStatus(ContentStreamId $contentStreamId): ContentStreamStatus { - $contentStream = $this->adapter->findContentStreamById($contentStreamId); + $contentStream = $this->contentRepositoryReadModel->findContentStreamById($contentStreamId); if ($contentStream === null) { throw new \InvalidArgumentException(sprintf('Failed to find content stream with id "%s"', $contentStreamId->value), 1716902219); } @@ -74,7 +74,7 @@ public function getContentStreamStatus(ContentStreamId $contentStreamId): Conten public function findWorkspaceByName(WorkspaceName $workspaceName): ?Workspace { - return $this->adapter->findWorkspaceByName($workspaceName); + return $this->contentRepositoryReadModel->findWorkspaceByName($workspaceName); } /** @@ -85,11 +85,11 @@ public function getContentGraph(WorkspaceName $workspaceName): ContentGraphInter if (isset($this->overriddenContentGraphInstances[$workspaceName->value])) { return $this->overriddenContentGraphInstances[$workspaceName->value]; } - $workspace = $this->adapter->findWorkspaceByName($workspaceName); + $workspace = $this->contentRepositoryReadModel->findWorkspaceByName($workspaceName); if ($workspace === null) { throw WorkspaceDoesNotExist::butWasSupposedTo($workspaceName); } - return $this->adapter->buildContentGraph($workspace->workspaceName, $workspace->currentContentStreamId); + return $this->contentRepositoryReadModel->buildContentGraph($workspace->workspaceName, $workspace->currentContentStreamId); } /** @@ -107,7 +107,7 @@ public function overrideContentStreamId(WorkspaceName $workspaceName, ContentStr throw new \RuntimeException('Contentstream override for this workspace already in effect, nesting not allowed.', 1715170938); } - $contentGraph = $this->adapter->buildContentGraph($workspaceName, $contentStreamId); + $contentGraph = $this->contentRepositoryReadModel->buildContentGraph($workspaceName, $contentStreamId); $this->overriddenContentGraphInstances[$workspaceName->value] = $contentGraph; try { diff --git a/Neos.ContentRepository.Core/Classes/ContentRepository.php b/Neos.ContentRepository.Core/Classes/ContentRepository.php index d1a48f0a20a..5aa59b6e726 100644 --- a/Neos.ContentRepository.Core/Classes/ContentRepository.php +++ b/Neos.ContentRepository.Core/Classes/ContentRepository.php @@ -30,7 +30,7 @@ use Neos\ContentRepository\Core\Projection\CatchUp; use Neos\ContentRepository\Core\Projection\CatchUpOptions; use Neos\ContentRepository\Core\Projection\ContentGraph\ContentGraphInterface; -use Neos\ContentRepository\Core\Projection\ContentRepositoryReadModelProjection; +use Neos\ContentRepository\Core\Projection\ContentRepositoryProjectionInterface; use Neos\ContentRepository\Core\Projection\ProjectionInterface; use Neos\ContentRepository\Core\Projection\ProjectionsAndCatchUpHooks; use Neos\ContentRepository\Core\Projection\ProjectionStateInterface; @@ -70,8 +70,6 @@ final class ContentRepository */ private array $projectionStateCache; - private ContentRepositoryReadModel $adapter; - private CommandHandlingDependencies $commandHandlingDependencies; /** @@ -89,9 +87,9 @@ public function __construct( private readonly ContentDimensionSourceInterface $contentDimensionSource, private readonly UserIdProviderInterface $userIdProvider, private readonly ClockInterface $clock, + private readonly ContentRepositoryReadModelInterface $contentRepositoryReadModel ) { - $this->adapter = $this->projectionsAndCatchUpHooks->readModelProjection->getState(); - $this->commandHandlingDependencies = new CommandHandlingDependencies($this, $this->adapter); + $this->commandHandlingDependencies = new CommandHandlingDependencies($this, $this->contentRepositoryReadModel); } /** @@ -206,7 +204,7 @@ public function catchUpProjection(string $projectionClassName, CatchUpOptions $o public function setUp(): void { $this->eventStore->setup(); - $this->projectionsAndCatchUpHooks->readModelProjection->setUp(); + $this->projectionsAndCatchUpHooks->contentRepositoryProjection->setUp(); foreach ($this->projectionsAndCatchUpHooks->additionalProjections as $projection) { $projection->setUp(); } @@ -215,7 +213,7 @@ public function setUp(): void public function status(): ContentRepositoryStatus { $projectionStatuses = ProjectionStatuses::create([ - ContentRepositoryReadModelProjection::class => $this->projectionsAndCatchUpHooks->readModelProjection->status() + ContentRepositoryProjectionInterface::class => $this->projectionsAndCatchUpHooks->contentRepositoryProjection->status() ]); foreach ($this->projectionsAndCatchUpHooks->additionalProjections as $projectionClassName => $projection) { $projectionStatuses = $projectionStatuses->with($projectionClassName, $projection->status()); @@ -228,7 +226,7 @@ public function status(): ContentRepositoryStatus public function resetProjectionStates(): void { - $this->projectionsAndCatchUpHooks->readModelProjection->reset(); + $this->projectionsAndCatchUpHooks->contentRepositoryProjection->reset(); foreach ($this->projectionsAndCatchUpHooks->additionalProjections as $projection) { $projection->reset(); } @@ -248,11 +246,11 @@ public function resetProjectionState(string $projectionClassName): void */ public function getContentGraph(WorkspaceName $workspaceName): ContentGraphInterface { - $workspace = $this->adapter->findWorkspaceByName($workspaceName); + $workspace = $this->contentRepositoryReadModel->findWorkspaceByName($workspaceName); if ($workspace === null) { throw WorkspaceDoesNotExist::butWasSupposedTo($workspaceName); } - return $this->adapter->buildContentGraph($workspaceName, $workspace->currentContentStreamId); + return $this->contentRepositoryReadModel->buildContentGraph($workspaceName, $workspace->currentContentStreamId); } /** @@ -260,7 +258,7 @@ public function getContentGraph(WorkspaceName $workspaceName): ContentGraphInter */ public function findWorkspaceByName(WorkspaceName $workspaceName): ?Workspace { - return $this->adapter->findWorkspaceByName($workspaceName); + return $this->contentRepositoryReadModel->findWorkspaceByName($workspaceName); } /** @@ -269,17 +267,17 @@ public function findWorkspaceByName(WorkspaceName $workspaceName): ?Workspace */ public function findWorkspaces(): Workspaces { - return $this->adapter->findWorkspaces(); + return $this->contentRepositoryReadModel->findWorkspaces(); } public function findContentStreamById(ContentStreamId $contentStreamId): ?ContentStream { - return $this->adapter->findContentStreamById($contentStreamId); + return $this->contentRepositoryReadModel->findContentStreamById($contentStreamId); } public function findContentStreams(): ContentStreams { - return $this->adapter->findContentStreams(); + return $this->contentRepositoryReadModel->findContentStreams(); } public function getNodeTypeManager(): NodeTypeManager diff --git a/Neos.ContentRepository.Core/Classes/ContentRepositoryReadModel.php b/Neos.ContentRepository.Core/Classes/ContentRepositoryReadModelInterface.php similarity index 85% rename from Neos.ContentRepository.Core/Classes/ContentRepositoryReadModel.php rename to Neos.ContentRepository.Core/Classes/ContentRepositoryReadModelInterface.php index 0fc7abd4668..8723e8460ba 100644 --- a/Neos.ContentRepository.Core/Classes/ContentRepositoryReadModel.php +++ b/Neos.ContentRepository.Core/Classes/ContentRepositoryReadModelInterface.php @@ -24,11 +24,9 @@ use Neos\ContentRepository\Core\SharedModel\Workspace\Workspaces; /** - * Create implementations of ContentGraphs bound to a specific Workspace and/or ContentStream - * - * @internal This is just an implementation detail to be implemented by the specific adapters + * @api for creating a custom content repository graph and workspace implementation, **not for users of the CR** */ -interface ContentRepositoryReadModel extends ProjectionStateInterface +interface ContentRepositoryReadModelInterface extends ProjectionStateInterface { public function buildContentGraph(WorkspaceName $workspaceName, ContentStreamId $contentStreamId): ContentGraphInterface; diff --git a/Neos.ContentRepository.Core/Classes/Factory/ContentRepositoryFactory.php b/Neos.ContentRepository.Core/Classes/Factory/ContentRepositoryFactory.php index e803003c9a7..6743815c453 100644 --- a/Neos.ContentRepository.Core/Classes/Factory/ContentRepositoryFactory.php +++ b/Neos.ContentRepository.Core/Classes/Factory/ContentRepositoryFactory.php @@ -101,6 +101,7 @@ public function getOrBuild(): ContentRepository $this->projectionFactoryDependencies->contentDimensionSource, $this->userIdProvider, $this->clock, + $this->projectionsAndCatchUpHooks->contentRepositoryProjection->getState() ); } return $this->contentRepository; diff --git a/Neos.ContentRepository.Core/Classes/Factory/ProjectionsAndCatchUpHooksFactory.php b/Neos.ContentRepository.Core/Classes/Factory/ProjectionsAndCatchUpHooksFactory.php index b72522a17ee..9eb85a4615f 100644 --- a/Neos.ContentRepository.Core/Classes/Factory/ProjectionsAndCatchUpHooksFactory.php +++ b/Neos.ContentRepository.Core/Classes/Factory/ProjectionsAndCatchUpHooksFactory.php @@ -11,7 +11,7 @@ use Neos\ContentRepository\Core\Projection\Projections; use Neos\ContentRepository\Core\Projection\ProjectionsAndCatchUpHooks; use Neos\ContentRepository\Core\Projection\ProjectionStateInterface; -use Neos\ContentRepository\Core\Projection\ContentRepositoryReadModelProjection; +use Neos\ContentRepository\Core\Projection\ContentRepositoryProjectionInterface; /** * @api for custom framework integrations, not for users of the CR @@ -54,7 +54,7 @@ public function registerCatchUpHookFactory(ProjectionFactoryInterface $factory, */ public function build(ProjectionFactoryDependencies $projectionFactoryDependencies): ProjectionsAndCatchUpHooks { - $contentRepositoryReadModelProjection = null; + $contentRepositoryProjection = null; $projectionsArray = []; $catchUpHookFactoriesByProjectionClassName = []; foreach ($this->factories as $factoryDefinition) { @@ -73,17 +73,17 @@ public function build(ProjectionFactoryDependencies $projectionFactoryDependenci $options, ); $catchUpHookFactoriesByProjectionClassName[$projection::class] = $catchUpHookFactories; - if ($projection instanceof ContentRepositoryReadModelProjection) { - $contentRepositoryReadModelProjection = $projection; + if ($projection instanceof ContentRepositoryProjectionInterface) { + $contentRepositoryProjection = $projection; } else { $projectionsArray[] = $projection; } } - if ($contentRepositoryReadModelProjection === null) { + if ($contentRepositoryProjection === null) { throw new \RuntimeException('A content repository requires the ContentRepositoryReadModelProjection to be registered.'); } - return new ProjectionsAndCatchUpHooks($contentRepositoryReadModelProjection, Projections::fromArray($projectionsArray), $catchUpHookFactoriesByProjectionClassName); + return new ProjectionsAndCatchUpHooks($contentRepositoryProjection, Projections::fromArray($projectionsArray), $catchUpHookFactoriesByProjectionClassName); } } diff --git a/Neos.ContentRepository.Core/Classes/Projection/ContentRepositoryProjectionInterface.php b/Neos.ContentRepository.Core/Classes/Projection/ContentRepositoryProjectionInterface.php new file mode 100644 index 00000000000..e2d87e8b95d --- /dev/null +++ b/Neos.ContentRepository.Core/Classes/Projection/ContentRepositoryProjectionInterface.php @@ -0,0 +1,16 @@ + + * @api for creating a custom content repository graph and workspace implementation, **not for users of the CR** + */ +interface ContentRepositoryProjectionInterface extends ProjectionInterface +{ + public function getState(): ContentRepositoryReadModelInterface; +} diff --git a/Neos.ContentRepository.Core/Classes/Projection/ContentRepositoryReadModelProjection.php b/Neos.ContentRepository.Core/Classes/Projection/ContentRepositoryReadModelProjection.php deleted file mode 100644 index 2c5bfcb955f..00000000000 --- a/Neos.ContentRepository.Core/Classes/Projection/ContentRepositoryReadModelProjection.php +++ /dev/null @@ -1,16 +0,0 @@ - - * @api - */ -interface ContentRepositoryReadModelProjection extends ProjectionInterface -{ - public function getState(): ContentRepositoryReadModel; -} diff --git a/Neos.ContentRepository.Core/Classes/Projection/ProjectionsAndCatchUpHooks.php b/Neos.ContentRepository.Core/Classes/Projection/ProjectionsAndCatchUpHooks.php index 807b82f0ce8..4ed000660f2 100644 --- a/Neos.ContentRepository.Core/Classes/Projection/ProjectionsAndCatchUpHooks.php +++ b/Neos.ContentRepository.Core/Classes/Projection/ProjectionsAndCatchUpHooks.php @@ -13,7 +13,7 @@ * @param array>, CatchUpHookFactories> $catchUpHookFactoriesByProjectionClassName */ public function __construct( - public ContentRepositoryReadModelProjection $readModelProjection, + public ContentRepositoryProjectionInterface $contentRepositoryProjection, public Projections $additionalProjections, private array $catchUpHookFactoriesByProjectionClassName, ) { @@ -34,14 +34,14 @@ public function getCatchUpHookFactoryForProjection(ProjectionInterface $projecti */ public function getProjection(string $projectionClassName): ProjectionInterface { - if ($this->readModelProjection instanceof $projectionClassName) { - return $this->readModelProjection; + if ($this->contentRepositoryProjection instanceof $projectionClassName) { + return $this->contentRepositoryProjection; } return $this->additionalProjections->get($projectionClassName); } public function getAllProjections(): Projections { - return $this->additionalProjections->with($this->readModelProjection); + return $this->additionalProjections->with($this->contentRepositoryProjection); } } diff --git a/Neos.ContentRepository.TestSuite/Classes/Behavior/Features/Bootstrap/CRTestSuiteTrait.php b/Neos.ContentRepository.TestSuite/Classes/Behavior/Features/Bootstrap/CRTestSuiteTrait.php index 15610168130..972f0a92407 100644 --- a/Neos.ContentRepository.TestSuite/Classes/Behavior/Features/Bootstrap/CRTestSuiteTrait.php +++ b/Neos.ContentRepository.TestSuite/Classes/Behavior/Features/Bootstrap/CRTestSuiteTrait.php @@ -16,7 +16,7 @@ use Behat\Behat\Hook\Scope\BeforeScenarioScope; use Behat\Gherkin\Node\TableNode; -use Neos\ContentRepository\Core\ContentRepositoryReadModel; +use Neos\ContentRepository\Core\ContentRepositoryReadModelInterface; use Neos\ContentRepository\Core\Factory\ContentRepositoryServiceFactoryDependencies; use Neos\ContentRepository\Core\Factory\ContentRepositoryServiceFactoryInterface; use Neos\ContentRepository\Core\Factory\ContentRepositoryServiceInterface; @@ -159,10 +159,10 @@ public function iExpectTheGraphProjectionToConsistOfExactlyNodes(int $expectedNu { // HACK to access $contentRepositoryReadModelAccess = new class implements ContentRepositoryServiceFactoryInterface { - public ContentRepositoryReadModel|null $instance; + public ContentRepositoryReadModelInterface|null $instance; public function build(ContentRepositoryServiceFactoryDependencies $serviceFactoryDependencies): ContentRepositoryServiceInterface { - $this->instance = $serviceFactoryDependencies->projectionsAndCatchUpHooks->readModelProjection->getState(); + $this->instance = $serviceFactoryDependencies->projectionsAndCatchUpHooks->contentRepositoryProjection->getState(); return new class implements ContentRepositoryServiceInterface { }; From c1756bc33b54ca0d1bb02d619e92c11c923b2a00 Mon Sep 17 00:00:00 2001 From: mhsdesign <85400359+mhsdesign@users.noreply.github.com> Date: Sat, 19 Oct 2024 13:05:27 +0200 Subject: [PATCH 06/12] TASK: Introduce dedicated `contentRepositoryProjection` and factory --- .github/workflows/build.yml | 9 ++-- ...trineDbalContentGraphProjectionFactory.php | 6 +-- .../src/HypergraphProjectionFactory.php | 5 +-- .../Configuration/Settings.yaml | 3 +- .../Testing/Behat/Postgres/Settings.yaml | 5 +-- .../Configuration/Testing/Behat/Settings.yaml | 9 ++-- .../ProjectionsAndCatchUpHooksFactory.php | 2 +- ...ntRepositoryProjectionFactoryInterface.php | 22 ++++++++++ .../Classes/ContentRepositoryRegistry.php | 44 ++++++++++++------- .../Configuration/Settings.yaml | 22 ++++++---- .../Settings.ContentRepositoryRegistry.yaml | 13 +++--- 11 files changed, 88 insertions(+), 52 deletions(-) create mode 100644 Neos.ContentRepository.Core/Classes/Projection/ContentRepositoryProjectionFactoryInterface.php diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 2ab48800296..5f0b21a33d6 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -182,11 +182,10 @@ jobs: # We enable the race condition tracker presets: 'default': - projections: - 'Neos.ContentRepository:ContentGraph': - catchUpHooks: - 'Neos.ContentRepository.BehavioralTests:RaceConditionTracker': - factoryObjectName: Neos\ContentRepository\BehavioralTests\ProjectionRaceConditionTester\RaceTrackerCatchUpHookFactory + contentRepositoryProjection: + catchUpHooks: + 'Neos.ContentRepository.BehavioralTests:RaceConditionTracker': + factoryObjectName: Neos\ContentRepository\BehavioralTests\ProjectionRaceConditionTester\RaceTrackerCatchUpHookFactory ContentRepository: BehavioralTests: raceConditionTracker: diff --git a/Neos.ContentGraph.DoctrineDbalAdapter/src/DoctrineDbalContentGraphProjectionFactory.php b/Neos.ContentGraph.DoctrineDbalAdapter/src/DoctrineDbalContentGraphProjectionFactory.php index 4194d2d3b52..7b7b4498024 100644 --- a/Neos.ContentGraph.DoctrineDbalAdapter/src/DoctrineDbalContentGraphProjectionFactory.php +++ b/Neos.ContentGraph.DoctrineDbalAdapter/src/DoctrineDbalContentGraphProjectionFactory.php @@ -9,16 +9,14 @@ use Neos\ContentGraph\DoctrineDbalAdapter\Domain\Repository\NodeFactory; use Neos\ContentGraph\DoctrineDbalAdapter\Domain\Repository\ProjectionContentGraph; use Neos\ContentRepository\Core\Factory\ProjectionFactoryDependencies; -use Neos\ContentRepository\Core\Projection\ProjectionFactoryInterface; +use Neos\ContentRepository\Core\Projection\ContentRepositoryProjectionFactoryInterface; /** * Use this class as ProjectionFactory in your configuration to construct a content graph * - * @implements ProjectionFactoryInterface - * * @api */ -final class DoctrineDbalContentGraphProjectionFactory implements ProjectionFactoryInterface +final class DoctrineDbalContentGraphProjectionFactory implements ContentRepositoryProjectionFactoryInterface { public function __construct( private readonly Connection $dbal, diff --git a/Neos.ContentGraph.PostgreSQLAdapter/src/HypergraphProjectionFactory.php b/Neos.ContentGraph.PostgreSQLAdapter/src/HypergraphProjectionFactory.php index 8d0349518f3..55e776c42e2 100644 --- a/Neos.ContentGraph.PostgreSQLAdapter/src/HypergraphProjectionFactory.php +++ b/Neos.ContentGraph.PostgreSQLAdapter/src/HypergraphProjectionFactory.php @@ -8,14 +8,13 @@ use Neos\ContentGraph\PostgreSQLAdapter\Domain\Projection\HypergraphProjection; use Neos\ContentGraph\PostgreSQLAdapter\Domain\Repository\NodeFactory; use Neos\ContentRepository\Core\Factory\ProjectionFactoryDependencies; -use Neos\ContentRepository\Core\Projection\ProjectionFactoryInterface; +use Neos\ContentRepository\Core\Projection\ContentRepositoryProjectionFactoryInterface; use Neos\ContentRepository\Core\SharedModel\ContentRepository\ContentRepositoryId; /** - * @implements ProjectionFactoryInterface * @api */ -final class HypergraphProjectionFactory implements ProjectionFactoryInterface +final class HypergraphProjectionFactory implements ContentRepositoryProjectionFactoryInterface { public function __construct( private readonly Connection $dbal, diff --git a/Neos.ContentRepository.BehavioralTests/Configuration/Settings.yaml b/Neos.ContentRepository.BehavioralTests/Configuration/Settings.yaml index f5877126acc..d33e7ec2839 100644 --- a/Neos.ContentRepository.BehavioralTests/Configuration/Settings.yaml +++ b/Neos.ContentRepository.BehavioralTests/Configuration/Settings.yaml @@ -5,8 +5,7 @@ Neos: #ContentRepositoryRegistry: # presets: # 'default': - # projections: - # 'Neos.ContentRepository:ContentGraph': + # contentRepositoryProjection: # catchUpHooks: # 'Neos.ContentRepository.BehavioralTests:RaceConditionTracker': # factoryObjectName: Neos\ContentRepository\BehavioralTests\ProjectionRaceConditionTester\RaceTrackerCatchUpHookFactory diff --git a/Neos.ContentRepository.BehavioralTests/Configuration/Testing/Behat/Postgres/Settings.yaml b/Neos.ContentRepository.BehavioralTests/Configuration/Testing/Behat/Postgres/Settings.yaml index c8c79383b53..ea990a27050 100644 --- a/Neos.ContentRepository.BehavioralTests/Configuration/Testing/Behat/Postgres/Settings.yaml +++ b/Neos.ContentRepository.BehavioralTests/Configuration/Testing/Behat/Postgres/Settings.yaml @@ -2,7 +2,6 @@ Neos: ContentRepositoryRegistry: presets: 'default': - projections: - 'Neos.ContentRepository:ContentGraph': - factoryObjectName: Neos\ContentGraph\PostgreSQLAdapter\HypergraphProjectionFactory + contentRepositoryProjection: + factoryObjectName: Neos\ContentGraph\PostgreSQLAdapter\HypergraphProjectionFactory diff --git a/Neos.ContentRepository.BehavioralTests/deployment/neos-in-docker/Configuration/Testing/Behat/Settings.yaml b/Neos.ContentRepository.BehavioralTests/deployment/neos-in-docker/Configuration/Testing/Behat/Settings.yaml index 32051f54db4..db8932adcb7 100644 --- a/Neos.ContentRepository.BehavioralTests/deployment/neos-in-docker/Configuration/Testing/Behat/Settings.yaml +++ b/Neos.ContentRepository.BehavioralTests/deployment/neos-in-docker/Configuration/Testing/Behat/Settings.yaml @@ -28,11 +28,10 @@ Neos: # We enable the race condition tracker. For details on how this works, see RaceTrackerCatchUpHook.php presets: 'default': - projections: - 'Neos.ContentRepository:ContentGraph': - catchUpHooks: - 'Neos.ContentRepository.BehavioralTests:RaceConditionTracker': - factoryObjectName: Neos\ContentRepository\BehavioralTests\ProjectionRaceConditionTester\RaceTrackerCatchUpHookFactory + contentRepositoryProjection: + catchUpHooks: + 'Neos.ContentRepository.BehavioralTests:RaceConditionTracker': + factoryObjectName: Neos\ContentRepository\BehavioralTests\ProjectionRaceConditionTester\RaceTrackerCatchUpHookFactory ContentRepository: BehavioralTests: raceConditionTracker: diff --git a/Neos.ContentRepository.Core/Classes/Factory/ProjectionsAndCatchUpHooksFactory.php b/Neos.ContentRepository.Core/Classes/Factory/ProjectionsAndCatchUpHooksFactory.php index 9eb85a4615f..725f1013532 100644 --- a/Neos.ContentRepository.Core/Classes/Factory/ProjectionsAndCatchUpHooksFactory.php +++ b/Neos.ContentRepository.Core/Classes/Factory/ProjectionsAndCatchUpHooksFactory.php @@ -81,7 +81,7 @@ public function build(ProjectionFactoryDependencies $projectionFactoryDependenci } if ($contentRepositoryProjection === null) { - throw new \RuntimeException('A content repository requires the ContentRepositoryReadModelProjection to be registered.'); + throw new \RuntimeException(sprintf('Content repository requires the %s to be registered.', ContentRepositoryProjectionInterface::class)); } return new ProjectionsAndCatchUpHooks($contentRepositoryProjection, Projections::fromArray($projectionsArray), $catchUpHookFactoriesByProjectionClassName); diff --git a/Neos.ContentRepository.Core/Classes/Projection/ContentRepositoryProjectionFactoryInterface.php b/Neos.ContentRepository.Core/Classes/Projection/ContentRepositoryProjectionFactoryInterface.php new file mode 100644 index 00000000000..26cb6bf8586 --- /dev/null +++ b/Neos.ContentRepository.Core/Classes/Projection/ContentRepositoryProjectionFactoryInterface.php @@ -0,0 +1,22 @@ + + */ +interface ContentRepositoryProjectionFactoryInterface extends ProjectionFactoryInterface +{ + /** + * @param array $options + */ + public function build( + ProjectionFactoryDependencies $projectionFactoryDependencies, + array $options, + ): ContentRepositoryProjectionInterface; +} diff --git a/Neos.ContentRepositoryRegistry/Classes/ContentRepositoryRegistry.php b/Neos.ContentRepositoryRegistry/Classes/ContentRepositoryRegistry.php index edbc98e092f..6ad00d2f8f7 100644 --- a/Neos.ContentRepositoryRegistry/Classes/ContentRepositoryRegistry.php +++ b/Neos.ContentRepositoryRegistry/Classes/ContentRepositoryRegistry.php @@ -14,8 +14,11 @@ use Neos\ContentRepository\Core\Projection\CatchUpHookFactoryInterface; use Neos\ContentRepository\Core\Projection\ContentGraph\ContentSubgraphInterface; use Neos\ContentRepository\Core\Projection\ContentGraph\Node; +use Neos\ContentRepository\Core\Projection\ContentRepositoryProjectionFactoryInterface; use Neos\ContentRepository\Core\Projection\ProjectionCatchUpTriggerInterface; use Neos\ContentRepository\Core\Projection\ProjectionFactoryInterface; +use Neos\ContentRepository\Core\Projection\ProjectionInterface; +use Neos\ContentRepository\Core\Projection\ProjectionStateInterface; use Neos\ContentRepository\Core\SharedModel\ContentRepository\ContentRepositoryId; use Neos\ContentRepository\Core\SharedModel\ContentRepository\ContentRepositoryIds; use Neos\ContentRepository\Core\SharedModel\User\UserIdProviderInterface; @@ -238,29 +241,40 @@ private function buildPropertySerializer(ContentRepositoryId $contentRepositoryI /** @param array $contentRepositorySettings */ private function buildProjectionsFactory(ContentRepositoryId $contentRepositoryId, array $contentRepositorySettings): ProjectionsAndCatchUpHooksFactory { - (isset($contentRepositorySettings['projections']) && is_array($contentRepositorySettings['projections'])) || throw InvalidConfigurationException::fromMessage('Content repository "%s" does not have projections configured, or the value is no array.', $contentRepositoryId->value); + (is_array($contentRepositorySettings['contentRepositoryProjection'] ?? null)) || throw InvalidConfigurationException::fromMessage('Content repository "%s" does not have the contentRepositoryProjection configured, or the value is no array.', $contentRepositoryId->value); + (is_array($contentRepositorySettings['projections'] ?? [])) || throw InvalidConfigurationException::fromMessage('Content repository "%s" expects projections configured as array.', $contentRepositoryId->value); $projectionsFactory = new ProjectionsAndCatchUpHooksFactory(); + $this->registerProjection($contentRepositorySettings['contentRepositoryProjection'], $projectionsFactory, ContentRepositoryProjectionFactoryInterface::class, 'contentRepositoryProjection', $contentRepositoryId); foreach ($contentRepositorySettings['projections'] as $projectionName => $projectionOptions) { if ($projectionOptions === null) { continue; } - $projectionFactory = isset($projectionOptions['factoryObjectName']) ? $this->objectManager->get($projectionOptions['factoryObjectName']) : null; - if (!$projectionFactory instanceof ProjectionFactoryInterface) { - throw InvalidConfigurationException::fromMessage('Projection factory object name for projection "%s" (content repository "%s") is not an instance of %s but %s.', $projectionName, $contentRepositoryId->value, ProjectionFactoryInterface::class, get_debug_type($projectionFactory)); + $this->registerProjection($projectionOptions, $projectionsFactory, ProjectionFactoryInterface::class, $projectionName, $contentRepositoryId); + } + return $projectionsFactory; + } + + /** + * @param class-string>> $expectedProjectionFactory + */ + private function registerProjection(mixed $projectionOptions, ProjectionsAndCatchUpHooksFactory $projectionsFactory, string $expectedProjectionFactory, string $projectionName, ContentRepositoryId $contentRepositoryId): void + { + (is_array($projectionOptions)) || throw InvalidConfigurationException::fromMessage('Projection "%s" (content repository "%s") must be configured as array got %s', $projectionName, $contentRepositoryId->value, get_debug_type($projectionOptions)); + $projectionFactory = isset($projectionOptions['factoryObjectName']) ? $this->objectManager->get($projectionOptions['factoryObjectName']) : null; + if (!$projectionFactory instanceof $expectedProjectionFactory) { + throw InvalidConfigurationException::fromMessage('Projection factory object name for projection "%s" (content repository "%s") is not an instance of %s but %s.', $projectionName, $contentRepositoryId->value, $expectedProjectionFactory, get_debug_type($projectionFactory)); + } + $projectionsFactory->registerFactory($projectionFactory, $projectionOptions['options'] ?? []); + foreach (($projectionOptions['catchUpHooks'] ?? []) as $catchUpHookOptions) { + if ($catchUpHookOptions === null) { + continue; } - $projectionsFactory->registerFactory($projectionFactory, $projectionOptions['options'] ?? []); - foreach (($projectionOptions['catchUpHooks'] ?? []) as $catchUpHookOptions) { - if ($catchUpHookOptions === null) { - continue; - } - $catchUpHookFactory = $this->objectManager->get($catchUpHookOptions['factoryObjectName']); - if (!$catchUpHookFactory instanceof CatchUpHookFactoryInterface) { - throw InvalidConfigurationException::fromMessage('CatchUpHook factory object name for projection "%s" (content repository "%s") is not an instance of %s but %s', $projectionName, $contentRepositoryId->value, CatchUpHookFactoryInterface::class, get_debug_type($catchUpHookFactory)); - } - $projectionsFactory->registerCatchUpHookFactory($projectionFactory, $catchUpHookFactory); + $catchUpHookFactory = $this->objectManager->get($catchUpHookOptions['factoryObjectName']); + if (!$catchUpHookFactory instanceof CatchUpHookFactoryInterface) { + throw InvalidConfigurationException::fromMessage('CatchUpHook factory object name for projection "%s" (content repository "%s") is not an instance of %s but %s', $projectionName, $contentRepositoryId->value, CatchUpHookFactoryInterface::class, get_debug_type($catchUpHookFactory)); } + $projectionsFactory->registerCatchUpHookFactory($projectionFactory, $catchUpHookFactory); } - return $projectionsFactory; } /** @param array $contentRepositorySettings */ diff --git a/Neos.ContentRepositoryRegistry/Configuration/Settings.yaml b/Neos.ContentRepositoryRegistry/Configuration/Settings.yaml index 90b3a14e339..5597988b00d 100644 --- a/Neos.ContentRepositoryRegistry/Configuration/Settings.yaml +++ b/Neos.ContentRepositoryRegistry/Configuration/Settings.yaml @@ -68,12 +68,18 @@ Neos: ProxyAwareObjectNormalizer: className: Neos\ContentRepositoryRegistry\Infrastructure\Property\Normalizer\ProxyAwareObjectNormalizer - projections: - # TODO make first level special option and rename - 'Neos.ContentRepository:ContentGraph': - # NOTE: This introduces a soft-dependency to the neos/contentgraph-doctrinedbaladapter package, but it can be overridden when a different adapter is used - factoryObjectName: Neos\ContentGraph\DoctrineDbalAdapter\DoctrineDbalContentGraphProjectionFactory + contentRepositoryProjection: + # NOTE: This introduces a soft-dependency to the neos/contentgraph-doctrinedbaladapter package, but it can be overridden when a different adapter is used + factoryObjectName: Neos\ContentGraph\DoctrineDbalAdapter\DoctrineDbalContentGraphProjectionFactory - catchUpHooks: - 'Neos.ContentRepositoryRegistry:FlushSubgraphCachePool': - factoryObjectName: Neos\ContentRepositoryRegistry\SubgraphCachingInMemory\FlushSubgraphCachePoolCatchUpHookFactory + catchUpHooks: + 'Neos.ContentRepositoryRegistry:FlushSubgraphCachePool': + factoryObjectName: Neos\ContentRepositoryRegistry\SubgraphCachingInMemory\FlushSubgraphCachePoolCatchUpHookFactory + + # additional projections: + # + # projections: + # 'My.Package:SomeProjection': # just a name + # factoryObjectName: My\Package\Projection\SomeProjectionFactory + # options: {} + # catchUpHooks: {} diff --git a/Neos.Neos/Configuration/Settings.ContentRepositoryRegistry.yaml b/Neos.Neos/Configuration/Settings.ContentRepositoryRegistry.yaml index a3ae6ab53c0..d139c46112a 100644 --- a/Neos.Neos/Configuration/Settings.ContentRepositoryRegistry.yaml +++ b/Neos.Neos/Configuration/Settings.ContentRepositoryRegistry.yaml @@ -6,6 +6,13 @@ Neos: userIdProvider: factoryObjectName: Neos\Neos\UserIdProvider\UserIdProviderFactory + contentRepositoryProjection: + catchUpHooks: + 'Neos.Neos:FlushContentCache': + factoryObjectName: Neos\Neos\Fusion\Cache\GraphProjectorCatchUpHookForCacheFlushingFactory + 'Neos.Neos:AssetUsage': + factoryObjectName: Neos\Neos\AssetUsage\CatchUpHook\AssetUsageCatchUpHookFactory + projections: 'Neos.Neos:DocumentUriPathProjection': factoryObjectName: Neos\Neos\FrontendRouting\Projection\DocumentUriPathProjectionFactory @@ -15,9 +22,3 @@ Neos: 'Neos.Neos:PendingChangesProjection': factoryObjectName: Neos\Neos\PendingChangesProjection\ChangeProjectionFactory - 'Neos.ContentRepository:ContentGraph': - catchUpHooks: - 'Neos.Neos:FlushContentCache': - factoryObjectName: Neos\Neos\Fusion\Cache\GraphProjectorCatchUpHookForCacheFlushingFactory - 'Neos.Neos:AssetUsage': - factoryObjectName: Neos\Neos\AssetUsage\CatchUpHook\AssetUsageCatchUpHookFactory From 41e35504abef2cdaf8846d79275ce34d1c9dbbcc Mon Sep 17 00:00:00 2001 From: mhsdesign <85400359+mhsdesign@users.noreply.github.com> Date: Sat, 19 Oct 2024 13:56:56 +0200 Subject: [PATCH 07/12] TASK: Simplify ProjectionsAndCatchUpHooks --- .../Classes/ContentRepository.php | 25 +++++++++++-------- .../Factory/ContentRepositoryFactory.php | 2 +- .../Projection/ProjectionsAndCatchUpHooks.php | 23 +++-------------- .../ProjectionReplayServiceFactory.php | 2 +- phpstan-baseline.neon | 5 ---- 5 files changed, 20 insertions(+), 37 deletions(-) diff --git a/Neos.ContentRepository.Core/Classes/ContentRepository.php b/Neos.ContentRepository.Core/Classes/ContentRepository.php index 5aa59b6e726..aac1b3ddebd 100644 --- a/Neos.ContentRepository.Core/Classes/ContentRepository.php +++ b/Neos.ContentRepository.Core/Classes/ContentRepository.php @@ -145,7 +145,10 @@ public function handle(CommandInterface $command): CommandResult public function projectionState(string $projectionStateClassName): ProjectionStateInterface { if (!isset($this->projectionStateCache)) { - foreach ($this->projectionsAndCatchUpHooks->additionalProjections as $projection) { + foreach ($this->projectionsAndCatchUpHooks->projections as $projection) { + if ($projection instanceof ContentRepositoryProjectionInterface) { + continue; + } $projectionState = $projection->getState(); $this->projectionStateCache[$projectionState::class] = $projectionState; } @@ -155,6 +158,10 @@ public function projectionState(string $projectionStateClassName): ProjectionSta $projectionState = $this->projectionStateCache[$projectionStateClassName]; return $projectionState; } + if (in_array(ContentRepositoryReadModelInterface::class, class_implements($projectionStateClassName), true)) { + throw new \InvalidArgumentException(sprintf('Accessing the internal content repository projection state via %s(%s) is not allowed. Please use the API on the content repository instead.', __FUNCTION__, $projectionStateClassName), 1729338679); + } + throw new \InvalidArgumentException(sprintf('A projection state of type "%s" is not registered in this content repository instance.', $projectionStateClassName), 1662033650); } @@ -163,7 +170,7 @@ public function projectionState(string $projectionStateClassName): ProjectionSta */ public function catchUpProjection(string $projectionClassName, CatchUpOptions $options): void { - $projection = $this->projectionsAndCatchUpHooks->getProjection($projectionClassName); + $projection = $this->projectionsAndCatchUpHooks->projections->get($projectionClassName); $catchUpHookFactory = $this->projectionsAndCatchUpHooks->getCatchUpHookFactoryForProjection($projection); $catchUpHook = $catchUpHookFactory?->build($this); @@ -204,18 +211,15 @@ public function catchUpProjection(string $projectionClassName, CatchUpOptions $o public function setUp(): void { $this->eventStore->setup(); - $this->projectionsAndCatchUpHooks->contentRepositoryProjection->setUp(); - foreach ($this->projectionsAndCatchUpHooks->additionalProjections as $projection) { + foreach ($this->projectionsAndCatchUpHooks->projections as $projection) { $projection->setUp(); } } public function status(): ContentRepositoryStatus { - $projectionStatuses = ProjectionStatuses::create([ - ContentRepositoryProjectionInterface::class => $this->projectionsAndCatchUpHooks->contentRepositoryProjection->status() - ]); - foreach ($this->projectionsAndCatchUpHooks->additionalProjections as $projectionClassName => $projection) { + $projectionStatuses = ProjectionStatuses::create(); + foreach ($this->projectionsAndCatchUpHooks->projections as $projectionClassName => $projection) { $projectionStatuses = $projectionStatuses->with($projectionClassName, $projection->status()); } return new ContentRepositoryStatus( @@ -226,8 +230,7 @@ public function status(): ContentRepositoryStatus public function resetProjectionStates(): void { - $this->projectionsAndCatchUpHooks->contentRepositoryProjection->reset(); - foreach ($this->projectionsAndCatchUpHooks->additionalProjections as $projection) { + foreach ($this->projectionsAndCatchUpHooks->projections as $projection) { $projection->reset(); } } @@ -237,7 +240,7 @@ public function resetProjectionStates(): void */ public function resetProjectionState(string $projectionClassName): void { - $projection = $this->projectionsAndCatchUpHooks->getProjection($projectionClassName); + $projection = $this->projectionsAndCatchUpHooks->projections->get($projectionClassName); $projection->reset(); } diff --git a/Neos.ContentRepository.Core/Classes/Factory/ContentRepositoryFactory.php b/Neos.ContentRepository.Core/Classes/Factory/ContentRepositoryFactory.php index 6743815c453..43df81b8f91 100644 --- a/Neos.ContentRepository.Core/Classes/Factory/ContentRepositoryFactory.php +++ b/Neos.ContentRepository.Core/Classes/Factory/ContentRepositoryFactory.php @@ -169,7 +169,7 @@ private function buildEventPersister(): EventPersister $this->projectionFactoryDependencies->eventStore, $this->projectionCatchUpTrigger, $this->projectionFactoryDependencies->eventNormalizer, - $this->projectionsAndCatchUpHooks->getAllProjections(), + $this->projectionsAndCatchUpHooks->projections, ); } return $this->eventPersister; diff --git a/Neos.ContentRepository.Core/Classes/Projection/ProjectionsAndCatchUpHooks.php b/Neos.ContentRepository.Core/Classes/Projection/ProjectionsAndCatchUpHooks.php index 4ed000660f2..af2cb1f4861 100644 --- a/Neos.ContentRepository.Core/Classes/Projection/ProjectionsAndCatchUpHooks.php +++ b/Neos.ContentRepository.Core/Classes/Projection/ProjectionsAndCatchUpHooks.php @@ -9,14 +9,17 @@ */ final readonly class ProjectionsAndCatchUpHooks { + public Projections $projections; + /** * @param array>, CatchUpHookFactories> $catchUpHookFactoriesByProjectionClassName */ public function __construct( public ContentRepositoryProjectionInterface $contentRepositoryProjection, - public Projections $additionalProjections, + Projections $additionalProjections, private array $catchUpHookFactoriesByProjectionClassName, ) { + $this->projections = $additionalProjections->with($this->contentRepositoryProjection); } /** @@ -26,22 +29,4 @@ public function getCatchUpHookFactoryForProjection(ProjectionInterface $projecti { return $this->catchUpHookFactoriesByProjectionClassName[$projection::class] ?? null; } - - /** - * @template T of ProjectionInterface - * @param class-string $projectionClassName - * @return T - */ - public function getProjection(string $projectionClassName): ProjectionInterface - { - if ($this->contentRepositoryProjection instanceof $projectionClassName) { - return $this->contentRepositoryProjection; - } - return $this->additionalProjections->get($projectionClassName); - } - - public function getAllProjections(): Projections - { - return $this->additionalProjections->with($this->contentRepositoryProjection); - } } diff --git a/Neos.ContentRepositoryRegistry/Classes/Service/ProjectionReplayServiceFactory.php b/Neos.ContentRepositoryRegistry/Classes/Service/ProjectionReplayServiceFactory.php index 7f72d4f872e..0f4bc5f7a05 100644 --- a/Neos.ContentRepositoryRegistry/Classes/Service/ProjectionReplayServiceFactory.php +++ b/Neos.ContentRepositoryRegistry/Classes/Service/ProjectionReplayServiceFactory.php @@ -22,7 +22,7 @@ final class ProjectionReplayServiceFactory implements ContentRepositoryServiceFa public function build(ContentRepositoryServiceFactoryDependencies $serviceFactoryDependencies): ContentRepositoryServiceInterface { return new ProjectionReplayService( - $serviceFactoryDependencies->projectionsAndCatchUpHooks->getAllProjections(), + $serviceFactoryDependencies->projectionsAndCatchUpHooks->projections, $serviceFactoryDependencies->contentRepository, $serviceFactoryDependencies->eventStore, ); diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 888835ae0e3..ebbd2ba29a9 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -5,11 +5,6 @@ parameters: count: 1 path: Neos.ContentRepositoryRegistry/Classes/Service/ProjectionReplayService.php - - - message: "#^The internal method \"Neos\\\\ContentRepository\\\\Core\\\\Projection\\\\ProjectionsAndCatchUpHooks\\:\\:getAllProjections\" is called\\.$#" - count: 1 - path: Neos.ContentRepositoryRegistry/Classes/Service/ProjectionReplayServiceFactory.php - - message: "#^Method Neos\\\\Neos\\\\Controller\\\\Backend\\\\MenuHelper\\:\\:buildModuleList\\(\\) return type has no value type specified in iterable type array\\.$#" count: 1 From b35a28d43e82e6606e1835ddc71facaca7341cbd Mon Sep 17 00:00:00 2001 From: mhsdesign <85400359+mhsdesign@users.noreply.github.com> Date: Mon, 21 Oct 2024 22:24:41 +0200 Subject: [PATCH 08/12] TASK: Adjust namings (again xD) The name `ContentRepositoryProjectionInterface` doesnt specify what makes it different to `ProjectionInterface` and indeed its a graph that has to be implemented by the adapter --- .../src/DoctrineDbalContentGraphProjection.php | 4 ++-- .../src/Domain/Projection/HypergraphProjection.php | 4 ++-- .../Classes/ContentRepository.php | 4 ++-- .../Classes/Factory/ContentRepositoryFactory.php | 2 +- .../Factory/ProjectionsAndCatchUpHooksFactory.php | 14 +++++++------- ...ace.php => ContentGraphProjectionInterface.php} | 2 +- ...ContentRepositoryProjectionFactoryInterface.php | 4 ++-- .../Projection/ProjectionsAndCatchUpHooks.php | 4 ++-- .../Features/Bootstrap/CRTestSuiteTrait.php | 2 +- 9 files changed, 20 insertions(+), 20 deletions(-) rename Neos.ContentRepository.Core/Classes/Projection/{ContentRepositoryProjectionInterface.php => ContentGraphProjectionInterface.php} (84%) diff --git a/Neos.ContentGraph.DoctrineDbalAdapter/src/DoctrineDbalContentGraphProjection.php b/Neos.ContentGraph.DoctrineDbalAdapter/src/DoctrineDbalContentGraphProjection.php index 1cae3d1bc9f..a900e8f064d 100644 --- a/Neos.ContentGraph.DoctrineDbalAdapter/src/DoctrineDbalContentGraphProjection.php +++ b/Neos.ContentGraph.DoctrineDbalAdapter/src/DoctrineDbalContentGraphProjection.php @@ -66,7 +66,7 @@ use Neos\ContentRepository\Core\Projection\ContentGraph\NodeTags; use Neos\ContentRepository\Core\Projection\ContentGraph\Timestamps; use Neos\ContentRepository\Core\Projection\ProjectionStatus; -use Neos\ContentRepository\Core\Projection\ContentRepositoryProjectionInterface; +use Neos\ContentRepository\Core\Projection\ContentGraphProjectionInterface; use Neos\ContentRepository\Core\SharedModel\Node\NodeAggregateClassification; use Neos\ContentRepository\Core\SharedModel\Node\NodeAggregateId; use Neos\ContentRepository\Core\SharedModel\Node\NodeName; @@ -78,7 +78,7 @@ /** * @internal but the graph projection is api */ -final class DoctrineDbalContentGraphProjection implements ContentRepositoryProjectionInterface +final class DoctrineDbalContentGraphProjection implements ContentGraphProjectionInterface { use ContentStream; use NodeMove; diff --git a/Neos.ContentGraph.PostgreSQLAdapter/src/Domain/Projection/HypergraphProjection.php b/Neos.ContentGraph.PostgreSQLAdapter/src/Domain/Projection/HypergraphProjection.php index eee11654669..37197799cb1 100644 --- a/Neos.ContentGraph.PostgreSQLAdapter/src/Domain/Projection/HypergraphProjection.php +++ b/Neos.ContentGraph.PostgreSQLAdapter/src/Domain/Projection/HypergraphProjection.php @@ -45,7 +45,7 @@ use Neos\ContentRepository\Core\Infrastructure\DbalSchemaDiff; use Neos\ContentRepository\Core\Projection\CheckpointStorageStatusType; use Neos\ContentRepository\Core\Projection\ProjectionStatus; -use Neos\ContentRepository\Core\Projection\ContentRepositoryProjectionInterface; +use Neos\ContentRepository\Core\Projection\ContentGraphProjectionInterface; use Neos\EventStore\Model\Event\SequenceNumber; use Neos\EventStore\Model\EventEnvelope; @@ -54,7 +54,7 @@ * * @internal the parent Content Graph is public */ -final class HypergraphProjection implements ContentRepositoryProjectionInterface +final class HypergraphProjection implements ContentGraphProjectionInterface { use ContentStreamForking; use NodeCreation; diff --git a/Neos.ContentRepository.Core/Classes/ContentRepository.php b/Neos.ContentRepository.Core/Classes/ContentRepository.php index 21eb96a4fd5..11e184298b2 100644 --- a/Neos.ContentRepository.Core/Classes/ContentRepository.php +++ b/Neos.ContentRepository.Core/Classes/ContentRepository.php @@ -29,7 +29,7 @@ use Neos\ContentRepository\Core\Projection\CatchUp; use Neos\ContentRepository\Core\Projection\CatchUpOptions; use Neos\ContentRepository\Core\Projection\ContentGraph\ContentGraphInterface; -use Neos\ContentRepository\Core\Projection\ContentRepositoryProjectionInterface; +use Neos\ContentRepository\Core\Projection\ContentGraphProjectionInterface; use Neos\ContentRepository\Core\Projection\ProjectionInterface; use Neos\ContentRepository\Core\Projection\ProjectionsAndCatchUpHooks; use Neos\ContentRepository\Core\Projection\ProjectionStateInterface; @@ -144,7 +144,7 @@ public function projectionState(string $projectionStateClassName): ProjectionSta { if (!isset($this->projectionStateCache)) { foreach ($this->projectionsAndCatchUpHooks->projections as $projection) { - if ($projection instanceof ContentRepositoryProjectionInterface) { + if ($projection instanceof ContentGraphProjectionInterface) { continue; } $projectionState = $projection->getState(); diff --git a/Neos.ContentRepository.Core/Classes/Factory/ContentRepositoryFactory.php b/Neos.ContentRepository.Core/Classes/Factory/ContentRepositoryFactory.php index 43df81b8f91..94f84547f74 100644 --- a/Neos.ContentRepository.Core/Classes/Factory/ContentRepositoryFactory.php +++ b/Neos.ContentRepository.Core/Classes/Factory/ContentRepositoryFactory.php @@ -101,7 +101,7 @@ public function getOrBuild(): ContentRepository $this->projectionFactoryDependencies->contentDimensionSource, $this->userIdProvider, $this->clock, - $this->projectionsAndCatchUpHooks->contentRepositoryProjection->getState() + $this->projectionsAndCatchUpHooks->contentGraphProjection->getState() ); } return $this->contentRepository; diff --git a/Neos.ContentRepository.Core/Classes/Factory/ProjectionsAndCatchUpHooksFactory.php b/Neos.ContentRepository.Core/Classes/Factory/ProjectionsAndCatchUpHooksFactory.php index 725f1013532..f684806f73a 100644 --- a/Neos.ContentRepository.Core/Classes/Factory/ProjectionsAndCatchUpHooksFactory.php +++ b/Neos.ContentRepository.Core/Classes/Factory/ProjectionsAndCatchUpHooksFactory.php @@ -11,7 +11,7 @@ use Neos\ContentRepository\Core\Projection\Projections; use Neos\ContentRepository\Core\Projection\ProjectionsAndCatchUpHooks; use Neos\ContentRepository\Core\Projection\ProjectionStateInterface; -use Neos\ContentRepository\Core\Projection\ContentRepositoryProjectionInterface; +use Neos\ContentRepository\Core\Projection\ContentGraphProjectionInterface; /** * @api for custom framework integrations, not for users of the CR @@ -54,7 +54,7 @@ public function registerCatchUpHookFactory(ProjectionFactoryInterface $factory, */ public function build(ProjectionFactoryDependencies $projectionFactoryDependencies): ProjectionsAndCatchUpHooks { - $contentRepositoryProjection = null; + $contentGraphProjection = null; $projectionsArray = []; $catchUpHookFactoriesByProjectionClassName = []; foreach ($this->factories as $factoryDefinition) { @@ -73,17 +73,17 @@ public function build(ProjectionFactoryDependencies $projectionFactoryDependenci $options, ); $catchUpHookFactoriesByProjectionClassName[$projection::class] = $catchUpHookFactories; - if ($projection instanceof ContentRepositoryProjectionInterface) { - $contentRepositoryProjection = $projection; + if ($projection instanceof ContentGraphProjectionInterface) { + $contentGraphProjection = $projection; } else { $projectionsArray[] = $projection; } } - if ($contentRepositoryProjection === null) { - throw new \RuntimeException(sprintf('Content repository requires the %s to be registered.', ContentRepositoryProjectionInterface::class)); + if ($contentGraphProjection === null) { + throw new \RuntimeException(sprintf('Content repository requires the %s to be registered.', ContentGraphProjectionInterface::class)); } - return new ProjectionsAndCatchUpHooks($contentRepositoryProjection, Projections::fromArray($projectionsArray), $catchUpHookFactoriesByProjectionClassName); + return new ProjectionsAndCatchUpHooks($contentGraphProjection, Projections::fromArray($projectionsArray), $catchUpHookFactoriesByProjectionClassName); } } diff --git a/Neos.ContentRepository.Core/Classes/Projection/ContentRepositoryProjectionInterface.php b/Neos.ContentRepository.Core/Classes/Projection/ContentGraphProjectionInterface.php similarity index 84% rename from Neos.ContentRepository.Core/Classes/Projection/ContentRepositoryProjectionInterface.php rename to Neos.ContentRepository.Core/Classes/Projection/ContentGraphProjectionInterface.php index e2d87e8b95d..c7c05fdd409 100644 --- a/Neos.ContentRepository.Core/Classes/Projection/ContentRepositoryProjectionInterface.php +++ b/Neos.ContentRepository.Core/Classes/Projection/ContentGraphProjectionInterface.php @@ -10,7 +10,7 @@ * @extends ProjectionInterface * @api for creating a custom content repository graph and workspace implementation, **not for users of the CR** */ -interface ContentRepositoryProjectionInterface extends ProjectionInterface +interface ContentGraphProjectionInterface extends ProjectionInterface { public function getState(): ContentRepositoryReadModelInterface; } diff --git a/Neos.ContentRepository.Core/Classes/Projection/ContentRepositoryProjectionFactoryInterface.php b/Neos.ContentRepository.Core/Classes/Projection/ContentRepositoryProjectionFactoryInterface.php index 26cb6bf8586..9fda7349906 100644 --- a/Neos.ContentRepository.Core/Classes/Projection/ContentRepositoryProjectionFactoryInterface.php +++ b/Neos.ContentRepository.Core/Classes/Projection/ContentRepositoryProjectionFactoryInterface.php @@ -8,7 +8,7 @@ /** * @api - * @extends ProjectionFactoryInterface + * @extends ProjectionFactoryInterface */ interface ContentRepositoryProjectionFactoryInterface extends ProjectionFactoryInterface { @@ -18,5 +18,5 @@ interface ContentRepositoryProjectionFactoryInterface extends ProjectionFactoryI public function build( ProjectionFactoryDependencies $projectionFactoryDependencies, array $options, - ): ContentRepositoryProjectionInterface; + ): ContentGraphProjectionInterface; } diff --git a/Neos.ContentRepository.Core/Classes/Projection/ProjectionsAndCatchUpHooks.php b/Neos.ContentRepository.Core/Classes/Projection/ProjectionsAndCatchUpHooks.php index af2cb1f4861..c591d538637 100644 --- a/Neos.ContentRepository.Core/Classes/Projection/ProjectionsAndCatchUpHooks.php +++ b/Neos.ContentRepository.Core/Classes/Projection/ProjectionsAndCatchUpHooks.php @@ -15,11 +15,11 @@ * @param array>, CatchUpHookFactories> $catchUpHookFactoriesByProjectionClassName */ public function __construct( - public ContentRepositoryProjectionInterface $contentRepositoryProjection, + public ContentGraphProjectionInterface $contentGraphProjection, Projections $additionalProjections, private array $catchUpHookFactoriesByProjectionClassName, ) { - $this->projections = $additionalProjections->with($this->contentRepositoryProjection); + $this->projections = $additionalProjections->with($this->contentGraphProjection); } /** diff --git a/Neos.ContentRepository.TestSuite/Classes/Behavior/Features/Bootstrap/CRTestSuiteTrait.php b/Neos.ContentRepository.TestSuite/Classes/Behavior/Features/Bootstrap/CRTestSuiteTrait.php index 972f0a92407..22594663fc0 100644 --- a/Neos.ContentRepository.TestSuite/Classes/Behavior/Features/Bootstrap/CRTestSuiteTrait.php +++ b/Neos.ContentRepository.TestSuite/Classes/Behavior/Features/Bootstrap/CRTestSuiteTrait.php @@ -162,7 +162,7 @@ public function iExpectTheGraphProjectionToConsistOfExactlyNodes(int $expectedNu public ContentRepositoryReadModelInterface|null $instance; public function build(ContentRepositoryServiceFactoryDependencies $serviceFactoryDependencies): ContentRepositoryServiceInterface { - $this->instance = $serviceFactoryDependencies->projectionsAndCatchUpHooks->contentRepositoryProjection->getState(); + $this->instance = $serviceFactoryDependencies->projectionsAndCatchUpHooks->contentGraphProjection->getState(); return new class implements ContentRepositoryServiceInterface { }; From 25a6d46d7cb5c98d88ec80a7de213939c6d94198 Mon Sep 17 00:00:00 2001 From: mhsdesign <85400359+mhsdesign@users.noreply.github.com> Date: Mon, 21 Oct 2024 22:28:26 +0200 Subject: [PATCH 09/12] TASK: Adjust also naming of ContentGraphReadModel --- ...er.php => ContentGraphReadModelAdapter.php} | 4 ++-- .../src/DoctrineDbalContentGraphProjection.php | 8 ++++---- ...ctrineDbalContentGraphProjectionFactory.php | 4 ++-- ...p => ContentHyperGraphReadModelAdapter.php} | 4 ++-- .../Domain/Projection/HypergraphProjection.php | 8 ++++---- .../src/HypergraphProjectionFactory.php | 2 +- .../Classes/CommandHandlingDependencies.php | 16 ++++++++-------- ....php => ContentGraphReadModelInterface.php} | 2 +- .../Classes/ContentRepository.php | 18 +++++++++--------- .../ContentGraphProjectionInterface.php | 6 +++--- .../Features/Bootstrap/CRTestSuiteTrait.php | 10 +++++----- 11 files changed, 41 insertions(+), 41 deletions(-) rename Neos.ContentGraph.DoctrineDbalAdapter/src/{ContentRepositoryReadModelAdapter.php => ContentGraphReadModelAdapter.php} (97%) rename Neos.ContentGraph.PostgreSQLAdapter/src/{ContentHyperRepositoryReadModelAdapter.php => ContentHyperGraphReadModelAdapter.php} (92%) rename Neos.ContentRepository.Core/Classes/{ContentRepositoryReadModelInterface.php => ContentGraphReadModelInterface.php} (95%) diff --git a/Neos.ContentGraph.DoctrineDbalAdapter/src/ContentRepositoryReadModelAdapter.php b/Neos.ContentGraph.DoctrineDbalAdapter/src/ContentGraphReadModelAdapter.php similarity index 97% rename from Neos.ContentGraph.DoctrineDbalAdapter/src/ContentRepositoryReadModelAdapter.php rename to Neos.ContentGraph.DoctrineDbalAdapter/src/ContentGraphReadModelAdapter.php index 82f49831731..79738e459ec 100644 --- a/Neos.ContentGraph.DoctrineDbalAdapter/src/ContentRepositoryReadModelAdapter.php +++ b/Neos.ContentGraph.DoctrineDbalAdapter/src/ContentGraphReadModelAdapter.php @@ -18,7 +18,7 @@ use Doctrine\DBAL\Exception; use Neos\ContentGraph\DoctrineDbalAdapter\Domain\Repository\ContentGraph; use Neos\ContentGraph\DoctrineDbalAdapter\Domain\Repository\NodeFactory; -use Neos\ContentRepository\Core\ContentRepositoryReadModelInterface; +use Neos\ContentRepository\Core\ContentGraphReadModelInterface; use Neos\ContentRepository\Core\NodeType\NodeTypeManager; use Neos\ContentRepository\Core\SharedModel\ContentRepository\ContentRepositoryId; use Neos\ContentRepository\Core\SharedModel\Workspace\ContentStream; @@ -34,7 +34,7 @@ /** * @internal */ -final readonly class ContentRepositoryReadModelAdapter implements ContentRepositoryReadModelInterface +final readonly class ContentGraphReadModelAdapter implements ContentGraphReadModelInterface { public function __construct( private Connection $dbal, diff --git a/Neos.ContentGraph.DoctrineDbalAdapter/src/DoctrineDbalContentGraphProjection.php b/Neos.ContentGraph.DoctrineDbalAdapter/src/DoctrineDbalContentGraphProjection.php index a900e8f064d..778fb17ae15 100644 --- a/Neos.ContentGraph.DoctrineDbalAdapter/src/DoctrineDbalContentGraphProjection.php +++ b/Neos.ContentGraph.DoctrineDbalAdapter/src/DoctrineDbalContentGraphProjection.php @@ -17,7 +17,7 @@ use Neos\ContentGraph\DoctrineDbalAdapter\Domain\Projection\NodeRelationAnchorPoint; use Neos\ContentGraph\DoctrineDbalAdapter\Domain\Repository\DimensionSpacePointsRepository; use Neos\ContentGraph\DoctrineDbalAdapter\Domain\Repository\ProjectionContentGraph; -use Neos\ContentRepository\Core\ContentRepositoryReadModelInterface; +use Neos\ContentRepository\Core\ContentGraphReadModelInterface; use Neos\ContentRepository\Core\DimensionSpace\DimensionSpacePoint; use Neos\ContentRepository\Core\DimensionSpace\DimensionSpacePointSet; use Neos\ContentRepository\Core\DimensionSpace\OriginDimensionSpacePoint; @@ -97,7 +97,7 @@ public function __construct( private readonly ProjectionContentGraph $projectionContentGraph, private readonly ContentGraphTableNames $tableNames, private readonly DimensionSpacePointsRepository $dimensionSpacePointsRepository, - private readonly ContentRepositoryReadModelInterface $contentRepositoryReadModel + private readonly ContentGraphReadModelInterface $contentGraphReadModel ) { $this->checkpointStorage = new DbalCheckpointStorage( $this->dbal, @@ -176,9 +176,9 @@ public function getCheckpointStorage(): DbalCheckpointStorage return $this->checkpointStorage; } - public function getState(): ContentRepositoryReadModelInterface + public function getState(): ContentGraphReadModelInterface { - return $this->contentRepositoryReadModel; + return $this->contentGraphReadModel; } public function canHandle(EventInterface $event): bool diff --git a/Neos.ContentGraph.DoctrineDbalAdapter/src/DoctrineDbalContentGraphProjectionFactory.php b/Neos.ContentGraph.DoctrineDbalAdapter/src/DoctrineDbalContentGraphProjectionFactory.php index 7b7b4498024..43af83562be 100644 --- a/Neos.ContentGraph.DoctrineDbalAdapter/src/DoctrineDbalContentGraphProjectionFactory.php +++ b/Neos.ContentGraph.DoctrineDbalAdapter/src/DoctrineDbalContentGraphProjectionFactory.php @@ -39,7 +39,7 @@ public function build( $dimensionSpacePointsRepository ); - $contentRepositoryReadModel = new ContentRepositoryReadModelAdapter( + $contentGraphReadModel = new ContentGraphReadModelAdapter( $this->dbal, $nodeFactory, $projectionFactoryDependencies->contentRepositoryId, @@ -55,7 +55,7 @@ public function build( ), $tableNames, $dimensionSpacePointsRepository, - $contentRepositoryReadModel + $contentGraphReadModel ); } } diff --git a/Neos.ContentGraph.PostgreSQLAdapter/src/ContentHyperRepositoryReadModelAdapter.php b/Neos.ContentGraph.PostgreSQLAdapter/src/ContentHyperGraphReadModelAdapter.php similarity index 92% rename from Neos.ContentGraph.PostgreSQLAdapter/src/ContentHyperRepositoryReadModelAdapter.php rename to Neos.ContentGraph.PostgreSQLAdapter/src/ContentHyperGraphReadModelAdapter.php index 2c5abcf1a6b..70b7570eeb5 100644 --- a/Neos.ContentGraph.PostgreSQLAdapter/src/ContentHyperRepositoryReadModelAdapter.php +++ b/Neos.ContentGraph.PostgreSQLAdapter/src/ContentHyperGraphReadModelAdapter.php @@ -7,7 +7,7 @@ use Doctrine\DBAL\Connection; use Neos\ContentGraph\PostgreSQLAdapter\Domain\Repository\ContentHypergraph; use Neos\ContentGraph\PostgreSQLAdapter\Domain\Repository\NodeFactory; -use Neos\ContentRepository\Core\ContentRepositoryReadModelInterface; +use Neos\ContentRepository\Core\ContentGraphReadModelInterface; use Neos\ContentRepository\Core\NodeType\NodeTypeManager; use Neos\ContentRepository\Core\Projection\ContentGraph\ContentGraphInterface; use Neos\ContentRepository\Core\SharedModel\ContentRepository\ContentRepositoryId; @@ -21,7 +21,7 @@ /** * @internal */ -final readonly class ContentHyperRepositoryReadModelAdapter implements ContentRepositoryReadModelInterface +final readonly class ContentHyperGraphReadModelAdapter implements ContentGraphReadModelInterface { public function __construct( private Connection $dbal, diff --git a/Neos.ContentGraph.PostgreSQLAdapter/src/Domain/Projection/HypergraphProjection.php b/Neos.ContentGraph.PostgreSQLAdapter/src/Domain/Projection/HypergraphProjection.php index 37197799cb1..cd10e4f088d 100644 --- a/Neos.ContentGraph.PostgreSQLAdapter/src/Domain/Projection/HypergraphProjection.php +++ b/Neos.ContentGraph.PostgreSQLAdapter/src/Domain/Projection/HypergraphProjection.php @@ -26,7 +26,7 @@ use Neos\ContentGraph\PostgreSQLAdapter\Domain\Projection\Feature\NodeVariation; use Neos\ContentGraph\PostgreSQLAdapter\Domain\Projection\Feature\SubtreeTagging; use Neos\ContentGraph\PostgreSQLAdapter\Domain\Projection\SchemaBuilder\HypergraphSchemaBuilder; -use Neos\ContentRepository\Core\ContentRepositoryReadModelInterface; +use Neos\ContentRepository\Core\ContentGraphReadModelInterface; use Neos\ContentRepository\Core\EventStore\EventInterface; use Neos\ContentRepository\Core\Feature\ContentStreamForking\Event\ContentStreamWasForked; use Neos\ContentRepository\Core\Feature\NodeCreation\Event\NodeAggregateWithNodeWasCreated; @@ -72,7 +72,7 @@ final class HypergraphProjection implements ContentGraphProjectionInterface public function __construct( private readonly Connection $dbal, private readonly string $tableNamePrefix, - private readonly ContentRepositoryReadModelInterface $contentRepositoryReadModel + private readonly ContentGraphReadModelInterface $contentGraphReadModel ) { $this->projectionHypergraph = new ProjectionHypergraph($this->dbal, $this->tableNamePrefix); $this->checkpointStorage = new DbalCheckpointStorage( @@ -218,9 +218,9 @@ public function getCheckpointStorage(): DbalCheckpointStorage return $this->checkpointStorage; } - public function getState(): ContentRepositoryReadModelInterface + public function getState(): ContentGraphReadModelInterface { - return $this->contentRepositoryReadModel; + return $this->contentGraphReadModel; } protected function getProjectionHypergraph(): ProjectionHypergraph diff --git a/Neos.ContentGraph.PostgreSQLAdapter/src/HypergraphProjectionFactory.php b/Neos.ContentGraph.PostgreSQLAdapter/src/HypergraphProjectionFactory.php index 55e776c42e2..095d42561cd 100644 --- a/Neos.ContentGraph.PostgreSQLAdapter/src/HypergraphProjectionFactory.php +++ b/Neos.ContentGraph.PostgreSQLAdapter/src/HypergraphProjectionFactory.php @@ -43,7 +43,7 @@ public function build( return new HypergraphProjection( $this->dbal, $tableNamePrefix, - new ContentHyperRepositoryReadModelAdapter($this->dbal, $nodeFactory, $projectionFactoryDependencies->contentRepositoryId, $projectionFactoryDependencies->nodeTypeManager, $tableNamePrefix) + new ContentHyperGraphReadModelAdapter($this->dbal, $nodeFactory, $projectionFactoryDependencies->contentRepositoryId, $projectionFactoryDependencies->nodeTypeManager, $tableNamePrefix) ); } } diff --git a/Neos.ContentRepository.Core/Classes/CommandHandlingDependencies.php b/Neos.ContentRepository.Core/Classes/CommandHandlingDependencies.php index 2c3797e907f..fc12b4e899c 100644 --- a/Neos.ContentRepository.Core/Classes/CommandHandlingDependencies.php +++ b/Neos.ContentRepository.Core/Classes/CommandHandlingDependencies.php @@ -39,7 +39,7 @@ final class CommandHandlingDependencies public function __construct( private readonly ContentRepository $contentRepository, - private readonly ContentRepositoryReadModelInterface $contentRepositoryReadModel + private readonly ContentGraphReadModelInterface $contentGraphReadModel ) { } @@ -50,7 +50,7 @@ public function handle(CommandInterface $command): void public function getContentStreamVersion(ContentStreamId $contentStreamId): Version { - $contentStream = $this->contentRepositoryReadModel->findContentStreamById($contentStreamId); + $contentStream = $this->contentGraphReadModel->findContentStreamById($contentStreamId); if ($contentStream === null) { throw new \InvalidArgumentException(sprintf('Failed to find content stream with id "%s"', $contentStreamId->value), 1716902051); } @@ -59,12 +59,12 @@ public function getContentStreamVersion(ContentStreamId $contentStreamId): Versi public function contentStreamExists(ContentStreamId $contentStreamId): bool { - return $this->contentRepositoryReadModel->findContentStreamById($contentStreamId) !== null; + return $this->contentGraphReadModel->findContentStreamById($contentStreamId) !== null; } public function getContentStreamStatus(ContentStreamId $contentStreamId): ContentStreamStatus { - $contentStream = $this->contentRepositoryReadModel->findContentStreamById($contentStreamId); + $contentStream = $this->contentGraphReadModel->findContentStreamById($contentStreamId); if ($contentStream === null) { throw new \InvalidArgumentException(sprintf('Failed to find content stream with id "%s"', $contentStreamId->value), 1716902219); } @@ -73,7 +73,7 @@ public function getContentStreamStatus(ContentStreamId $contentStreamId): Conten public function findWorkspaceByName(WorkspaceName $workspaceName): ?Workspace { - return $this->contentRepositoryReadModel->findWorkspaceByName($workspaceName); + return $this->contentGraphReadModel->findWorkspaceByName($workspaceName); } /** @@ -84,11 +84,11 @@ public function getContentGraph(WorkspaceName $workspaceName): ContentGraphInter if (isset($this->overriddenContentGraphInstances[$workspaceName->value])) { return $this->overriddenContentGraphInstances[$workspaceName->value]; } - $workspace = $this->contentRepositoryReadModel->findWorkspaceByName($workspaceName); + $workspace = $this->contentGraphReadModel->findWorkspaceByName($workspaceName); if ($workspace === null) { throw WorkspaceDoesNotExist::butWasSupposedTo($workspaceName); } - return $this->contentRepositoryReadModel->buildContentGraph($workspace->workspaceName, $workspace->currentContentStreamId); + return $this->contentGraphReadModel->buildContentGraph($workspace->workspaceName, $workspace->currentContentStreamId); } /** @@ -106,7 +106,7 @@ public function overrideContentStreamId(WorkspaceName $workspaceName, ContentStr throw new \RuntimeException('Contentstream override for this workspace already in effect, nesting not allowed.', 1715170938); } - $contentGraph = $this->contentRepositoryReadModel->buildContentGraph($workspaceName, $contentStreamId); + $contentGraph = $this->contentGraphReadModel->buildContentGraph($workspaceName, $contentStreamId); $this->overriddenContentGraphInstances[$workspaceName->value] = $contentGraph; try { diff --git a/Neos.ContentRepository.Core/Classes/ContentRepositoryReadModelInterface.php b/Neos.ContentRepository.Core/Classes/ContentGraphReadModelInterface.php similarity index 95% rename from Neos.ContentRepository.Core/Classes/ContentRepositoryReadModelInterface.php rename to Neos.ContentRepository.Core/Classes/ContentGraphReadModelInterface.php index 8723e8460ba..47660c4cd4f 100644 --- a/Neos.ContentRepository.Core/Classes/ContentRepositoryReadModelInterface.php +++ b/Neos.ContentRepository.Core/Classes/ContentGraphReadModelInterface.php @@ -26,7 +26,7 @@ /** * @api for creating a custom content repository graph and workspace implementation, **not for users of the CR** */ -interface ContentRepositoryReadModelInterface extends ProjectionStateInterface +interface ContentGraphReadModelInterface extends ProjectionStateInterface { public function buildContentGraph(WorkspaceName $workspaceName, ContentStreamId $contentStreamId): ContentGraphInterface; diff --git a/Neos.ContentRepository.Core/Classes/ContentRepository.php b/Neos.ContentRepository.Core/Classes/ContentRepository.php index 11e184298b2..3641803d3cb 100644 --- a/Neos.ContentRepository.Core/Classes/ContentRepository.php +++ b/Neos.ContentRepository.Core/Classes/ContentRepository.php @@ -86,9 +86,9 @@ public function __construct( private readonly ContentDimensionSourceInterface $contentDimensionSource, private readonly UserIdProviderInterface $userIdProvider, private readonly ClockInterface $clock, - private readonly ContentRepositoryReadModelInterface $contentRepositoryReadModel + private readonly ContentGraphReadModelInterface $contentGraphReadModel ) { - $this->commandHandlingDependencies = new CommandHandlingDependencies($this, $this->contentRepositoryReadModel); + $this->commandHandlingDependencies = new CommandHandlingDependencies($this, $this->contentGraphReadModel); } /** @@ -156,7 +156,7 @@ public function projectionState(string $projectionStateClassName): ProjectionSta $projectionState = $this->projectionStateCache[$projectionStateClassName]; return $projectionState; } - if (in_array(ContentRepositoryReadModelInterface::class, class_implements($projectionStateClassName), true)) { + if (in_array(ContentGraphReadModelInterface::class, class_implements($projectionStateClassName), true)) { throw new \InvalidArgumentException(sprintf('Accessing the internal content repository projection state via %s(%s) is not allowed. Please use the API on the content repository instead.', __FUNCTION__, $projectionStateClassName), 1729338679); } @@ -247,11 +247,11 @@ public function resetProjectionState(string $projectionClassName): void */ public function getContentGraph(WorkspaceName $workspaceName): ContentGraphInterface { - $workspace = $this->contentRepositoryReadModel->findWorkspaceByName($workspaceName); + $workspace = $this->contentGraphReadModel->findWorkspaceByName($workspaceName); if ($workspace === null) { throw WorkspaceDoesNotExist::butWasSupposedTo($workspaceName); } - return $this->contentRepositoryReadModel->buildContentGraph($workspaceName, $workspace->currentContentStreamId); + return $this->contentGraphReadModel->buildContentGraph($workspaceName, $workspace->currentContentStreamId); } /** @@ -259,7 +259,7 @@ public function getContentGraph(WorkspaceName $workspaceName): ContentGraphInter */ public function findWorkspaceByName(WorkspaceName $workspaceName): ?Workspace { - return $this->contentRepositoryReadModel->findWorkspaceByName($workspaceName); + return $this->contentGraphReadModel->findWorkspaceByName($workspaceName); } /** @@ -268,17 +268,17 @@ public function findWorkspaceByName(WorkspaceName $workspaceName): ?Workspace */ public function findWorkspaces(): Workspaces { - return $this->contentRepositoryReadModel->findWorkspaces(); + return $this->contentGraphReadModel->findWorkspaces(); } public function findContentStreamById(ContentStreamId $contentStreamId): ?ContentStream { - return $this->contentRepositoryReadModel->findContentStreamById($contentStreamId); + return $this->contentGraphReadModel->findContentStreamById($contentStreamId); } public function findContentStreams(): ContentStreams { - return $this->contentRepositoryReadModel->findContentStreams(); + return $this->contentGraphReadModel->findContentStreams(); } public function getNodeTypeManager(): NodeTypeManager diff --git a/Neos.ContentRepository.Core/Classes/Projection/ContentGraphProjectionInterface.php b/Neos.ContentRepository.Core/Classes/Projection/ContentGraphProjectionInterface.php index c7c05fdd409..d51e37f4481 100644 --- a/Neos.ContentRepository.Core/Classes/Projection/ContentGraphProjectionInterface.php +++ b/Neos.ContentRepository.Core/Classes/Projection/ContentGraphProjectionInterface.php @@ -4,13 +4,13 @@ namespace Neos\ContentRepository\Core\Projection; -use Neos\ContentRepository\Core\ContentRepositoryReadModelInterface; +use Neos\ContentRepository\Core\ContentGraphReadModelInterface; /** - * @extends ProjectionInterface + * @extends ProjectionInterface * @api for creating a custom content repository graph and workspace implementation, **not for users of the CR** */ interface ContentGraphProjectionInterface extends ProjectionInterface { - public function getState(): ContentRepositoryReadModelInterface; + public function getState(): ContentGraphReadModelInterface; } diff --git a/Neos.ContentRepository.TestSuite/Classes/Behavior/Features/Bootstrap/CRTestSuiteTrait.php b/Neos.ContentRepository.TestSuite/Classes/Behavior/Features/Bootstrap/CRTestSuiteTrait.php index 22594663fc0..dd4f30ec4c1 100644 --- a/Neos.ContentRepository.TestSuite/Classes/Behavior/Features/Bootstrap/CRTestSuiteTrait.php +++ b/Neos.ContentRepository.TestSuite/Classes/Behavior/Features/Bootstrap/CRTestSuiteTrait.php @@ -16,7 +16,7 @@ use Behat\Behat\Hook\Scope\BeforeScenarioScope; use Behat\Gherkin\Node\TableNode; -use Neos\ContentRepository\Core\ContentRepositoryReadModelInterface; +use Neos\ContentRepository\Core\ContentGraphReadModelInterface; use Neos\ContentRepository\Core\Factory\ContentRepositoryServiceFactoryDependencies; use Neos\ContentRepository\Core\Factory\ContentRepositoryServiceFactoryInterface; use Neos\ContentRepository\Core\Factory\ContentRepositoryServiceInterface; @@ -158,8 +158,8 @@ public function workspaceHasStatus(string $rawWorkspaceName, string $status): vo public function iExpectTheGraphProjectionToConsistOfExactlyNodes(int $expectedNumberOfNodes): void { // HACK to access - $contentRepositoryReadModelAccess = new class implements ContentRepositoryServiceFactoryInterface { - public ContentRepositoryReadModelInterface|null $instance; + $contentGraphReadModelAccess = new class implements ContentRepositoryServiceFactoryInterface { + public ContentGraphReadModelInterface|null $instance; public function build(ContentRepositoryServiceFactoryDependencies $serviceFactoryDependencies): ContentRepositoryServiceInterface { $this->instance = $serviceFactoryDependencies->projectionsAndCatchUpHooks->contentGraphProjection->getState(); @@ -168,9 +168,9 @@ public function build(ContentRepositoryServiceFactoryDependencies $serviceFactor }; } }; - $this->getContentRepositoryService($contentRepositoryReadModelAccess); + $this->getContentRepositoryService($contentGraphReadModelAccess); - $actualNumberOfNodes = $contentRepositoryReadModelAccess->instance->countNodes(); + $actualNumberOfNodes = $contentGraphReadModelAccess->instance->countNodes(); Assert::assertSame($expectedNumberOfNodes, $actualNumberOfNodes, 'Content graph consists of ' . $actualNumberOfNodes . ' nodes, expected were ' . $expectedNumberOfNodes . '.'); } From 3dce85d16978e58728eba4a777fab08eb91da178 Mon Sep 17 00:00:00 2001 From: mhsdesign <85400359+mhsdesign@users.noreply.github.com> Date: Mon, 21 Oct 2024 22:33:29 +0200 Subject: [PATCH 10/12] TASK: Move content graph projection interfaces to `Projection\ContentGraph` --- .../src/ContentGraphReadModelAdapter.php | 2 +- .../src/DoctrineDbalContentGraphProjection.php | 4 ++-- .../src/DoctrineDbalContentGraphProjectionFactory.php | 2 +- .../src/ContentHyperGraphReadModelAdapter.php | 2 +- .../src/Domain/Projection/HypergraphProjection.php | 4 ++-- .../src/HypergraphProjectionFactory.php | 2 +- .../Classes/CommandHandlingDependencies.php | 1 + Neos.ContentRepository.Core/Classes/ContentRepository.php | 3 ++- .../Classes/Factory/ProjectionsAndCatchUpHooksFactory.php | 2 +- .../{ => ContentGraph}/ContentGraphProjectionInterface.php | 6 +++--- .../ContentGraph}/ContentGraphReadModelInterface.php | 5 ++--- .../ContentRepositoryProjectionFactoryInterface.php | 5 +++-- .../Classes/Projection/ProjectionsAndCatchUpHooks.php | 2 ++ .../Behavior/Features/Bootstrap/CRTestSuiteTrait.php | 2 +- .../Classes/ContentRepositoryRegistry.php | 2 +- 15 files changed, 24 insertions(+), 20 deletions(-) rename Neos.ContentRepository.Core/Classes/Projection/{ => ContentGraph}/ContentGraphProjectionInterface.php (50%) rename Neos.ContentRepository.Core/Classes/{ => Projection/ContentGraph}/ContentGraphReadModelInterface.php (86%) rename Neos.ContentRepository.Core/Classes/Projection/{ => ContentGraph}/ContentRepositoryProjectionFactoryInterface.php (67%) diff --git a/Neos.ContentGraph.DoctrineDbalAdapter/src/ContentGraphReadModelAdapter.php b/Neos.ContentGraph.DoctrineDbalAdapter/src/ContentGraphReadModelAdapter.php index 79738e459ec..891a07e441d 100644 --- a/Neos.ContentGraph.DoctrineDbalAdapter/src/ContentGraphReadModelAdapter.php +++ b/Neos.ContentGraph.DoctrineDbalAdapter/src/ContentGraphReadModelAdapter.php @@ -18,7 +18,7 @@ use Doctrine\DBAL\Exception; use Neos\ContentGraph\DoctrineDbalAdapter\Domain\Repository\ContentGraph; use Neos\ContentGraph\DoctrineDbalAdapter\Domain\Repository\NodeFactory; -use Neos\ContentRepository\Core\ContentGraphReadModelInterface; +use Neos\ContentRepository\Core\Projection\ContentGraph\ContentGraphReadModelInterface; use Neos\ContentRepository\Core\NodeType\NodeTypeManager; use Neos\ContentRepository\Core\SharedModel\ContentRepository\ContentRepositoryId; use Neos\ContentRepository\Core\SharedModel\Workspace\ContentStream; diff --git a/Neos.ContentGraph.DoctrineDbalAdapter/src/DoctrineDbalContentGraphProjection.php b/Neos.ContentGraph.DoctrineDbalAdapter/src/DoctrineDbalContentGraphProjection.php index 778fb17ae15..2b6ef815f5d 100644 --- a/Neos.ContentGraph.DoctrineDbalAdapter/src/DoctrineDbalContentGraphProjection.php +++ b/Neos.ContentGraph.DoctrineDbalAdapter/src/DoctrineDbalContentGraphProjection.php @@ -17,7 +17,7 @@ use Neos\ContentGraph\DoctrineDbalAdapter\Domain\Projection\NodeRelationAnchorPoint; use Neos\ContentGraph\DoctrineDbalAdapter\Domain\Repository\DimensionSpacePointsRepository; use Neos\ContentGraph\DoctrineDbalAdapter\Domain\Repository\ProjectionContentGraph; -use Neos\ContentRepository\Core\ContentGraphReadModelInterface; +use Neos\ContentRepository\Core\Projection\ContentGraph\ContentGraphReadModelInterface; use Neos\ContentRepository\Core\DimensionSpace\DimensionSpacePoint; use Neos\ContentRepository\Core\DimensionSpace\DimensionSpacePointSet; use Neos\ContentRepository\Core\DimensionSpace\OriginDimensionSpacePoint; @@ -66,7 +66,7 @@ use Neos\ContentRepository\Core\Projection\ContentGraph\NodeTags; use Neos\ContentRepository\Core\Projection\ContentGraph\Timestamps; use Neos\ContentRepository\Core\Projection\ProjectionStatus; -use Neos\ContentRepository\Core\Projection\ContentGraphProjectionInterface; +use Neos\ContentRepository\Core\Projection\ContentGraph\ContentGraphProjectionInterface; use Neos\ContentRepository\Core\SharedModel\Node\NodeAggregateClassification; use Neos\ContentRepository\Core\SharedModel\Node\NodeAggregateId; use Neos\ContentRepository\Core\SharedModel\Node\NodeName; diff --git a/Neos.ContentGraph.DoctrineDbalAdapter/src/DoctrineDbalContentGraphProjectionFactory.php b/Neos.ContentGraph.DoctrineDbalAdapter/src/DoctrineDbalContentGraphProjectionFactory.php index 43af83562be..01437eb88f4 100644 --- a/Neos.ContentGraph.DoctrineDbalAdapter/src/DoctrineDbalContentGraphProjectionFactory.php +++ b/Neos.ContentGraph.DoctrineDbalAdapter/src/DoctrineDbalContentGraphProjectionFactory.php @@ -9,7 +9,7 @@ use Neos\ContentGraph\DoctrineDbalAdapter\Domain\Repository\NodeFactory; use Neos\ContentGraph\DoctrineDbalAdapter\Domain\Repository\ProjectionContentGraph; use Neos\ContentRepository\Core\Factory\ProjectionFactoryDependencies; -use Neos\ContentRepository\Core\Projection\ContentRepositoryProjectionFactoryInterface; +use Neos\ContentRepository\Core\Projection\ContentGraph\ContentRepositoryProjectionFactoryInterface; /** * Use this class as ProjectionFactory in your configuration to construct a content graph diff --git a/Neos.ContentGraph.PostgreSQLAdapter/src/ContentHyperGraphReadModelAdapter.php b/Neos.ContentGraph.PostgreSQLAdapter/src/ContentHyperGraphReadModelAdapter.php index 70b7570eeb5..d4d68465df2 100644 --- a/Neos.ContentGraph.PostgreSQLAdapter/src/ContentHyperGraphReadModelAdapter.php +++ b/Neos.ContentGraph.PostgreSQLAdapter/src/ContentHyperGraphReadModelAdapter.php @@ -7,7 +7,7 @@ use Doctrine\DBAL\Connection; use Neos\ContentGraph\PostgreSQLAdapter\Domain\Repository\ContentHypergraph; use Neos\ContentGraph\PostgreSQLAdapter\Domain\Repository\NodeFactory; -use Neos\ContentRepository\Core\ContentGraphReadModelInterface; +use Neos\ContentRepository\Core\Projection\ContentGraph\ContentGraphReadModelInterface; use Neos\ContentRepository\Core\NodeType\NodeTypeManager; use Neos\ContentRepository\Core\Projection\ContentGraph\ContentGraphInterface; use Neos\ContentRepository\Core\SharedModel\ContentRepository\ContentRepositoryId; diff --git a/Neos.ContentGraph.PostgreSQLAdapter/src/Domain/Projection/HypergraphProjection.php b/Neos.ContentGraph.PostgreSQLAdapter/src/Domain/Projection/HypergraphProjection.php index cd10e4f088d..75b373c9c22 100644 --- a/Neos.ContentGraph.PostgreSQLAdapter/src/Domain/Projection/HypergraphProjection.php +++ b/Neos.ContentGraph.PostgreSQLAdapter/src/Domain/Projection/HypergraphProjection.php @@ -26,7 +26,7 @@ use Neos\ContentGraph\PostgreSQLAdapter\Domain\Projection\Feature\NodeVariation; use Neos\ContentGraph\PostgreSQLAdapter\Domain\Projection\Feature\SubtreeTagging; use Neos\ContentGraph\PostgreSQLAdapter\Domain\Projection\SchemaBuilder\HypergraphSchemaBuilder; -use Neos\ContentRepository\Core\ContentGraphReadModelInterface; +use Neos\ContentRepository\Core\Projection\ContentGraph\ContentGraphReadModelInterface; use Neos\ContentRepository\Core\EventStore\EventInterface; use Neos\ContentRepository\Core\Feature\ContentStreamForking\Event\ContentStreamWasForked; use Neos\ContentRepository\Core\Feature\NodeCreation\Event\NodeAggregateWithNodeWasCreated; @@ -45,7 +45,7 @@ use Neos\ContentRepository\Core\Infrastructure\DbalSchemaDiff; use Neos\ContentRepository\Core\Projection\CheckpointStorageStatusType; use Neos\ContentRepository\Core\Projection\ProjectionStatus; -use Neos\ContentRepository\Core\Projection\ContentGraphProjectionInterface; +use Neos\ContentRepository\Core\Projection\ContentGraph\ContentGraphProjectionInterface; use Neos\EventStore\Model\Event\SequenceNumber; use Neos\EventStore\Model\EventEnvelope; diff --git a/Neos.ContentGraph.PostgreSQLAdapter/src/HypergraphProjectionFactory.php b/Neos.ContentGraph.PostgreSQLAdapter/src/HypergraphProjectionFactory.php index 095d42561cd..0839a5aa5d9 100644 --- a/Neos.ContentGraph.PostgreSQLAdapter/src/HypergraphProjectionFactory.php +++ b/Neos.ContentGraph.PostgreSQLAdapter/src/HypergraphProjectionFactory.php @@ -8,7 +8,7 @@ use Neos\ContentGraph\PostgreSQLAdapter\Domain\Projection\HypergraphProjection; use Neos\ContentGraph\PostgreSQLAdapter\Domain\Repository\NodeFactory; use Neos\ContentRepository\Core\Factory\ProjectionFactoryDependencies; -use Neos\ContentRepository\Core\Projection\ContentRepositoryProjectionFactoryInterface; +use Neos\ContentRepository\Core\Projection\ContentGraph\ContentRepositoryProjectionFactoryInterface; use Neos\ContentRepository\Core\SharedModel\ContentRepository\ContentRepositoryId; /** diff --git a/Neos.ContentRepository.Core/Classes/CommandHandlingDependencies.php b/Neos.ContentRepository.Core/Classes/CommandHandlingDependencies.php index fc12b4e899c..d1ad6b75be6 100644 --- a/Neos.ContentRepository.Core/Classes/CommandHandlingDependencies.php +++ b/Neos.ContentRepository.Core/Classes/CommandHandlingDependencies.php @@ -16,6 +16,7 @@ use Neos\ContentRepository\Core\CommandHandler\CommandInterface; use Neos\ContentRepository\Core\Projection\ContentGraph\ContentGraphInterface; +use Neos\ContentRepository\Core\Projection\ContentGraph\ContentGraphReadModelInterface; use Neos\ContentRepository\Core\SharedModel\Workspace\Workspace; use Neos\ContentRepository\Core\SharedModel\Exception\WorkspaceDoesNotExist; use Neos\ContentRepository\Core\SharedModel\Workspace\ContentStreamId; diff --git a/Neos.ContentRepository.Core/Classes/ContentRepository.php b/Neos.ContentRepository.Core/Classes/ContentRepository.php index 3641803d3cb..d00e4b07893 100644 --- a/Neos.ContentRepository.Core/Classes/ContentRepository.php +++ b/Neos.ContentRepository.Core/Classes/ContentRepository.php @@ -29,7 +29,8 @@ use Neos\ContentRepository\Core\Projection\CatchUp; use Neos\ContentRepository\Core\Projection\CatchUpOptions; use Neos\ContentRepository\Core\Projection\ContentGraph\ContentGraphInterface; -use Neos\ContentRepository\Core\Projection\ContentGraphProjectionInterface; +use Neos\ContentRepository\Core\Projection\ContentGraph\ContentGraphReadModelInterface; +use Neos\ContentRepository\Core\Projection\ContentGraph\ContentGraphProjectionInterface; use Neos\ContentRepository\Core\Projection\ProjectionInterface; use Neos\ContentRepository\Core\Projection\ProjectionsAndCatchUpHooks; use Neos\ContentRepository\Core\Projection\ProjectionStateInterface; diff --git a/Neos.ContentRepository.Core/Classes/Factory/ProjectionsAndCatchUpHooksFactory.php b/Neos.ContentRepository.Core/Classes/Factory/ProjectionsAndCatchUpHooksFactory.php index f684806f73a..32bda18b771 100644 --- a/Neos.ContentRepository.Core/Classes/Factory/ProjectionsAndCatchUpHooksFactory.php +++ b/Neos.ContentRepository.Core/Classes/Factory/ProjectionsAndCatchUpHooksFactory.php @@ -11,7 +11,7 @@ use Neos\ContentRepository\Core\Projection\Projections; use Neos\ContentRepository\Core\Projection\ProjectionsAndCatchUpHooks; use Neos\ContentRepository\Core\Projection\ProjectionStateInterface; -use Neos\ContentRepository\Core\Projection\ContentGraphProjectionInterface; +use Neos\ContentRepository\Core\Projection\ContentGraph\ContentGraphProjectionInterface; /** * @api for custom framework integrations, not for users of the CR diff --git a/Neos.ContentRepository.Core/Classes/Projection/ContentGraphProjectionInterface.php b/Neos.ContentRepository.Core/Classes/Projection/ContentGraph/ContentGraphProjectionInterface.php similarity index 50% rename from Neos.ContentRepository.Core/Classes/Projection/ContentGraphProjectionInterface.php rename to Neos.ContentRepository.Core/Classes/Projection/ContentGraph/ContentGraphProjectionInterface.php index d51e37f4481..fca250fd797 100644 --- a/Neos.ContentRepository.Core/Classes/Projection/ContentGraphProjectionInterface.php +++ b/Neos.ContentRepository.Core/Classes/Projection/ContentGraph/ContentGraphProjectionInterface.php @@ -2,13 +2,13 @@ declare(strict_types=1); -namespace Neos\ContentRepository\Core\Projection; +namespace Neos\ContentRepository\Core\Projection\ContentGraph; -use Neos\ContentRepository\Core\ContentGraphReadModelInterface; +use Neos\ContentRepository\Core\Projection\ProjectionInterface; /** * @extends ProjectionInterface - * @api for creating a custom content repository graph and workspace implementation, **not for users of the CR** + * @api for creating a custom content repository graph projection implementation, **not for users of the CR** */ interface ContentGraphProjectionInterface extends ProjectionInterface { diff --git a/Neos.ContentRepository.Core/Classes/ContentGraphReadModelInterface.php b/Neos.ContentRepository.Core/Classes/Projection/ContentGraph/ContentGraphReadModelInterface.php similarity index 86% rename from Neos.ContentRepository.Core/Classes/ContentGraphReadModelInterface.php rename to Neos.ContentRepository.Core/Classes/Projection/ContentGraph/ContentGraphReadModelInterface.php index 47660c4cd4f..5902b8aba00 100644 --- a/Neos.ContentRepository.Core/Classes/ContentGraphReadModelInterface.php +++ b/Neos.ContentRepository.Core/Classes/Projection/ContentGraph/ContentGraphReadModelInterface.php @@ -12,9 +12,8 @@ declare(strict_types=1); -namespace Neos\ContentRepository\Core; +namespace Neos\ContentRepository\Core\Projection\ContentGraph; -use Neos\ContentRepository\Core\Projection\ContentGraph\ContentGraphInterface; use Neos\ContentRepository\Core\Projection\ProjectionStateInterface; use Neos\ContentRepository\Core\SharedModel\Workspace\ContentStream; use Neos\ContentRepository\Core\SharedModel\Workspace\ContentStreamId; @@ -24,7 +23,7 @@ use Neos\ContentRepository\Core\SharedModel\Workspace\Workspaces; /** - * @api for creating a custom content repository graph and workspace implementation, **not for users of the CR** + * @api for creating a custom content repository graph projection implementation, **not for users of the CR** */ interface ContentGraphReadModelInterface extends ProjectionStateInterface { diff --git a/Neos.ContentRepository.Core/Classes/Projection/ContentRepositoryProjectionFactoryInterface.php b/Neos.ContentRepository.Core/Classes/Projection/ContentGraph/ContentRepositoryProjectionFactoryInterface.php similarity index 67% rename from Neos.ContentRepository.Core/Classes/Projection/ContentRepositoryProjectionFactoryInterface.php rename to Neos.ContentRepository.Core/Classes/Projection/ContentGraph/ContentRepositoryProjectionFactoryInterface.php index 9fda7349906..ad18ea0ca4d 100644 --- a/Neos.ContentRepository.Core/Classes/Projection/ContentRepositoryProjectionFactoryInterface.php +++ b/Neos.ContentRepository.Core/Classes/Projection/ContentGraph/ContentRepositoryProjectionFactoryInterface.php @@ -2,13 +2,14 @@ declare(strict_types=1); -namespace Neos\ContentRepository\Core\Projection; +namespace Neos\ContentRepository\Core\Projection\ContentGraph; use Neos\ContentRepository\Core\Factory\ProjectionFactoryDependencies; +use Neos\ContentRepository\Core\Projection\ProjectionFactoryInterface; /** - * @api * @extends ProjectionFactoryInterface + * @api for creating a custom content repository graph projection implementation, **not for users of the CR** */ interface ContentRepositoryProjectionFactoryInterface extends ProjectionFactoryInterface { diff --git a/Neos.ContentRepository.Core/Classes/Projection/ProjectionsAndCatchUpHooks.php b/Neos.ContentRepository.Core/Classes/Projection/ProjectionsAndCatchUpHooks.php index c591d538637..255e59b7600 100644 --- a/Neos.ContentRepository.Core/Classes/Projection/ProjectionsAndCatchUpHooks.php +++ b/Neos.ContentRepository.Core/Classes/Projection/ProjectionsAndCatchUpHooks.php @@ -4,6 +4,8 @@ namespace Neos\ContentRepository\Core\Projection; +use Neos\ContentRepository\Core\Projection\ContentGraph\ContentGraphProjectionInterface; + /** * @internal */ diff --git a/Neos.ContentRepository.TestSuite/Classes/Behavior/Features/Bootstrap/CRTestSuiteTrait.php b/Neos.ContentRepository.TestSuite/Classes/Behavior/Features/Bootstrap/CRTestSuiteTrait.php index dd4f30ec4c1..0384232e778 100644 --- a/Neos.ContentRepository.TestSuite/Classes/Behavior/Features/Bootstrap/CRTestSuiteTrait.php +++ b/Neos.ContentRepository.TestSuite/Classes/Behavior/Features/Bootstrap/CRTestSuiteTrait.php @@ -16,7 +16,7 @@ use Behat\Behat\Hook\Scope\BeforeScenarioScope; use Behat\Gherkin\Node\TableNode; -use Neos\ContentRepository\Core\ContentGraphReadModelInterface; +use Neos\ContentRepository\Core\Projection\ContentGraph\ContentGraphReadModelInterface; use Neos\ContentRepository\Core\Factory\ContentRepositoryServiceFactoryDependencies; use Neos\ContentRepository\Core\Factory\ContentRepositoryServiceFactoryInterface; use Neos\ContentRepository\Core\Factory\ContentRepositoryServiceInterface; diff --git a/Neos.ContentRepositoryRegistry/Classes/ContentRepositoryRegistry.php b/Neos.ContentRepositoryRegistry/Classes/ContentRepositoryRegistry.php index a734afa8143..15481a6a7c3 100644 --- a/Neos.ContentRepositoryRegistry/Classes/ContentRepositoryRegistry.php +++ b/Neos.ContentRepositoryRegistry/Classes/ContentRepositoryRegistry.php @@ -14,7 +14,7 @@ use Neos\ContentRepository\Core\Projection\CatchUpHookFactoryInterface; use Neos\ContentRepository\Core\Projection\ContentGraph\ContentSubgraphInterface; use Neos\ContentRepository\Core\Projection\ContentGraph\Node; -use Neos\ContentRepository\Core\Projection\ContentRepositoryProjectionFactoryInterface; +use Neos\ContentRepository\Core\Projection\ContentGraph\ContentRepositoryProjectionFactoryInterface; use Neos\ContentRepository\Core\Projection\ProjectionCatchUpTriggerInterface; use Neos\ContentRepository\Core\Projection\ProjectionFactoryInterface; use Neos\ContentRepository\Core\Projection\ProjectionInterface; From b2b52cfc014d8311c769819a72da04648c811c64 Mon Sep 17 00:00:00 2001 From: mhsdesign <85400359+mhsdesign@users.noreply.github.com> Date: Tue, 22 Oct 2024 11:31:40 +0200 Subject: [PATCH 11/12] TASK: Rename `contentRepositoryProjection` to `contentGraphProjection` --- .github/workflows/build.yml | 2 +- .../Configuration/Settings.yaml | 2 +- .../Configuration/Testing/Behat/Postgres/Settings.yaml | 2 +- .../neos-in-docker/Configuration/Testing/Behat/Settings.yaml | 2 +- .../Classes/ContentRepositoryRegistry.php | 4 ++-- Neos.ContentRepositoryRegistry/Configuration/Settings.yaml | 2 +- .../Configuration/Settings.ContentRepositoryRegistry.yaml | 2 +- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 5f0b21a33d6..83f1baadc62 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -182,7 +182,7 @@ jobs: # We enable the race condition tracker presets: 'default': - contentRepositoryProjection: + contentGraphProjection: catchUpHooks: 'Neos.ContentRepository.BehavioralTests:RaceConditionTracker': factoryObjectName: Neos\ContentRepository\BehavioralTests\ProjectionRaceConditionTester\RaceTrackerCatchUpHookFactory diff --git a/Neos.ContentRepository.BehavioralTests/Configuration/Settings.yaml b/Neos.ContentRepository.BehavioralTests/Configuration/Settings.yaml index d33e7ec2839..d684f0d8326 100644 --- a/Neos.ContentRepository.BehavioralTests/Configuration/Settings.yaml +++ b/Neos.ContentRepository.BehavioralTests/Configuration/Settings.yaml @@ -5,7 +5,7 @@ Neos: #ContentRepositoryRegistry: # presets: # 'default': - # contentRepositoryProjection: + # contentGraphProjection: # catchUpHooks: # 'Neos.ContentRepository.BehavioralTests:RaceConditionTracker': # factoryObjectName: Neos\ContentRepository\BehavioralTests\ProjectionRaceConditionTester\RaceTrackerCatchUpHookFactory diff --git a/Neos.ContentRepository.BehavioralTests/Configuration/Testing/Behat/Postgres/Settings.yaml b/Neos.ContentRepository.BehavioralTests/Configuration/Testing/Behat/Postgres/Settings.yaml index ea990a27050..5a7694823b5 100644 --- a/Neos.ContentRepository.BehavioralTests/Configuration/Testing/Behat/Postgres/Settings.yaml +++ b/Neos.ContentRepository.BehavioralTests/Configuration/Testing/Behat/Postgres/Settings.yaml @@ -2,6 +2,6 @@ Neos: ContentRepositoryRegistry: presets: 'default': - contentRepositoryProjection: + contentGraphProjection: factoryObjectName: Neos\ContentGraph\PostgreSQLAdapter\HypergraphProjectionFactory diff --git a/Neos.ContentRepository.BehavioralTests/deployment/neos-in-docker/Configuration/Testing/Behat/Settings.yaml b/Neos.ContentRepository.BehavioralTests/deployment/neos-in-docker/Configuration/Testing/Behat/Settings.yaml index db8932adcb7..b132f2c6b39 100644 --- a/Neos.ContentRepository.BehavioralTests/deployment/neos-in-docker/Configuration/Testing/Behat/Settings.yaml +++ b/Neos.ContentRepository.BehavioralTests/deployment/neos-in-docker/Configuration/Testing/Behat/Settings.yaml @@ -28,7 +28,7 @@ Neos: # We enable the race condition tracker. For details on how this works, see RaceTrackerCatchUpHook.php presets: 'default': - contentRepositoryProjection: + contentGraphProjection: catchUpHooks: 'Neos.ContentRepository.BehavioralTests:RaceConditionTracker': factoryObjectName: Neos\ContentRepository\BehavioralTests\ProjectionRaceConditionTester\RaceTrackerCatchUpHookFactory diff --git a/Neos.ContentRepositoryRegistry/Classes/ContentRepositoryRegistry.php b/Neos.ContentRepositoryRegistry/Classes/ContentRepositoryRegistry.php index 15481a6a7c3..6604ad498cf 100644 --- a/Neos.ContentRepositoryRegistry/Classes/ContentRepositoryRegistry.php +++ b/Neos.ContentRepositoryRegistry/Classes/ContentRepositoryRegistry.php @@ -245,10 +245,10 @@ private function buildPropertySerializer(ContentRepositoryId $contentRepositoryI /** @param array $contentRepositorySettings */ private function buildProjectionsFactory(ContentRepositoryId $contentRepositoryId, array $contentRepositorySettings): ProjectionsAndCatchUpHooksFactory { - (is_array($contentRepositorySettings['contentRepositoryProjection'] ?? null)) || throw InvalidConfigurationException::fromMessage('Content repository "%s" does not have the contentRepositoryProjection configured, or the value is no array.', $contentRepositoryId->value); + (is_array($contentRepositorySettings['contentGraphProjection'] ?? null)) || throw InvalidConfigurationException::fromMessage('Content repository "%s" does not have the contentGraphProjection configured, or the value is no array.', $contentRepositoryId->value); (is_array($contentRepositorySettings['projections'] ?? [])) || throw InvalidConfigurationException::fromMessage('Content repository "%s" expects projections configured as array.', $contentRepositoryId->value); $projectionsFactory = new ProjectionsAndCatchUpHooksFactory(); - $this->registerProjection($contentRepositorySettings['contentRepositoryProjection'], $projectionsFactory, ContentRepositoryProjectionFactoryInterface::class, 'contentRepositoryProjection', $contentRepositoryId); + $this->registerProjection($contentRepositorySettings['contentGraphProjection'], $projectionsFactory, ContentRepositoryProjectionFactoryInterface::class, 'contentGraphProjection', $contentRepositoryId); foreach ($contentRepositorySettings['projections'] as $projectionName => $projectionOptions) { if ($projectionOptions === null) { continue; diff --git a/Neos.ContentRepositoryRegistry/Configuration/Settings.yaml b/Neos.ContentRepositoryRegistry/Configuration/Settings.yaml index 5597988b00d..87e8aeaffe5 100644 --- a/Neos.ContentRepositoryRegistry/Configuration/Settings.yaml +++ b/Neos.ContentRepositoryRegistry/Configuration/Settings.yaml @@ -68,7 +68,7 @@ Neos: ProxyAwareObjectNormalizer: className: Neos\ContentRepositoryRegistry\Infrastructure\Property\Normalizer\ProxyAwareObjectNormalizer - contentRepositoryProjection: + contentGraphProjection: # NOTE: This introduces a soft-dependency to the neos/contentgraph-doctrinedbaladapter package, but it can be overridden when a different adapter is used factoryObjectName: Neos\ContentGraph\DoctrineDbalAdapter\DoctrineDbalContentGraphProjectionFactory diff --git a/Neos.Neos/Configuration/Settings.ContentRepositoryRegistry.yaml b/Neos.Neos/Configuration/Settings.ContentRepositoryRegistry.yaml index d139c46112a..d7d0bc7c720 100644 --- a/Neos.Neos/Configuration/Settings.ContentRepositoryRegistry.yaml +++ b/Neos.Neos/Configuration/Settings.ContentRepositoryRegistry.yaml @@ -6,7 +6,7 @@ Neos: userIdProvider: factoryObjectName: Neos\Neos\UserIdProvider\UserIdProviderFactory - contentRepositoryProjection: + contentGraphProjection: catchUpHooks: 'Neos.Neos:FlushContentCache': factoryObjectName: Neos\Neos\Fusion\Cache\GraphProjectorCatchUpHookForCacheFlushingFactory From 17af312e5482300aafdb40cdd8cfbc82f6cfe72b Mon Sep 17 00:00:00 2001 From: mhsdesign <85400359+mhsdesign@users.noreply.github.com> Date: Tue, 22 Oct 2024 13:46:41 +0200 Subject: [PATCH 12/12] TASK: Simplify cr registry projection building and rename factory --- ...trineDbalContentGraphProjectionFactory.php | 4 +- .../src/HypergraphProjectionFactory.php | 4 +- .../Classes/ContentRepository.php | 2 +- .../ProjectionsAndCatchUpHooksFactory.php | 3 ++ ...ontentGraphProjectionFactoryInterface.php} | 2 +- .../Classes/Projection/ProjectionStatuses.php | 7 +-- .../Classes/ContentRepositoryRegistry.php | 46 ++++++++++++------- 7 files changed, 41 insertions(+), 27 deletions(-) rename Neos.ContentRepository.Core/Classes/Projection/ContentGraph/{ContentRepositoryProjectionFactoryInterface.php => ContentGraphProjectionFactoryInterface.php} (88%) diff --git a/Neos.ContentGraph.DoctrineDbalAdapter/src/DoctrineDbalContentGraphProjectionFactory.php b/Neos.ContentGraph.DoctrineDbalAdapter/src/DoctrineDbalContentGraphProjectionFactory.php index 01437eb88f4..a5c4d6ae25e 100644 --- a/Neos.ContentGraph.DoctrineDbalAdapter/src/DoctrineDbalContentGraphProjectionFactory.php +++ b/Neos.ContentGraph.DoctrineDbalAdapter/src/DoctrineDbalContentGraphProjectionFactory.php @@ -9,14 +9,14 @@ use Neos\ContentGraph\DoctrineDbalAdapter\Domain\Repository\NodeFactory; use Neos\ContentGraph\DoctrineDbalAdapter\Domain\Repository\ProjectionContentGraph; use Neos\ContentRepository\Core\Factory\ProjectionFactoryDependencies; -use Neos\ContentRepository\Core\Projection\ContentGraph\ContentRepositoryProjectionFactoryInterface; +use Neos\ContentRepository\Core\Projection\ContentGraph\ContentGraphProjectionFactoryInterface; /** * Use this class as ProjectionFactory in your configuration to construct a content graph * * @api */ -final class DoctrineDbalContentGraphProjectionFactory implements ContentRepositoryProjectionFactoryInterface +final class DoctrineDbalContentGraphProjectionFactory implements ContentGraphProjectionFactoryInterface { public function __construct( private readonly Connection $dbal, diff --git a/Neos.ContentGraph.PostgreSQLAdapter/src/HypergraphProjectionFactory.php b/Neos.ContentGraph.PostgreSQLAdapter/src/HypergraphProjectionFactory.php index 0839a5aa5d9..3d3c002c094 100644 --- a/Neos.ContentGraph.PostgreSQLAdapter/src/HypergraphProjectionFactory.php +++ b/Neos.ContentGraph.PostgreSQLAdapter/src/HypergraphProjectionFactory.php @@ -8,13 +8,13 @@ use Neos\ContentGraph\PostgreSQLAdapter\Domain\Projection\HypergraphProjection; use Neos\ContentGraph\PostgreSQLAdapter\Domain\Repository\NodeFactory; use Neos\ContentRepository\Core\Factory\ProjectionFactoryDependencies; -use Neos\ContentRepository\Core\Projection\ContentGraph\ContentRepositoryProjectionFactoryInterface; +use Neos\ContentRepository\Core\Projection\ContentGraph\ContentGraphProjectionFactoryInterface; use Neos\ContentRepository\Core\SharedModel\ContentRepository\ContentRepositoryId; /** * @api */ -final class HypergraphProjectionFactory implements ContentRepositoryProjectionFactoryInterface +final class HypergraphProjectionFactory implements ContentGraphProjectionFactoryInterface { public function __construct( private readonly Connection $dbal, diff --git a/Neos.ContentRepository.Core/Classes/ContentRepository.php b/Neos.ContentRepository.Core/Classes/ContentRepository.php index d00e4b07893..25641eb1217 100644 --- a/Neos.ContentRepository.Core/Classes/ContentRepository.php +++ b/Neos.ContentRepository.Core/Classes/ContentRepository.php @@ -217,7 +217,7 @@ public function setUp(): void public function status(): ContentRepositoryStatus { - $projectionStatuses = ProjectionStatuses::create(); + $projectionStatuses = ProjectionStatuses::createEmpty(); foreach ($this->projectionsAndCatchUpHooks->projections as $projectionClassName => $projection) { $projectionStatuses = $projectionStatuses->with($projectionClassName, $projection->status()); } diff --git a/Neos.ContentRepository.Core/Classes/Factory/ProjectionsAndCatchUpHooksFactory.php b/Neos.ContentRepository.Core/Classes/Factory/ProjectionsAndCatchUpHooksFactory.php index 32bda18b771..cd369a87a6e 100644 --- a/Neos.ContentRepository.Core/Classes/Factory/ProjectionsAndCatchUpHooksFactory.php +++ b/Neos.ContentRepository.Core/Classes/Factory/ProjectionsAndCatchUpHooksFactory.php @@ -74,6 +74,9 @@ public function build(ProjectionFactoryDependencies $projectionFactoryDependenci ); $catchUpHookFactoriesByProjectionClassName[$projection::class] = $catchUpHookFactories; if ($projection instanceof ContentGraphProjectionInterface) { + if ($contentGraphProjection !== null) { + throw new \RuntimeException(sprintf('Content repository requires exactly one %s to be registered.', ContentGraphProjectionInterface::class)); + } $contentGraphProjection = $projection; } else { $projectionsArray[] = $projection; diff --git a/Neos.ContentRepository.Core/Classes/Projection/ContentGraph/ContentRepositoryProjectionFactoryInterface.php b/Neos.ContentRepository.Core/Classes/Projection/ContentGraph/ContentGraphProjectionFactoryInterface.php similarity index 88% rename from Neos.ContentRepository.Core/Classes/Projection/ContentGraph/ContentRepositoryProjectionFactoryInterface.php rename to Neos.ContentRepository.Core/Classes/Projection/ContentGraph/ContentGraphProjectionFactoryInterface.php index ad18ea0ca4d..a385d454e76 100644 --- a/Neos.ContentRepository.Core/Classes/Projection/ContentGraph/ContentRepositoryProjectionFactoryInterface.php +++ b/Neos.ContentRepository.Core/Classes/Projection/ContentGraph/ContentGraphProjectionFactoryInterface.php @@ -11,7 +11,7 @@ * @extends ProjectionFactoryInterface * @api for creating a custom content repository graph projection implementation, **not for users of the CR** */ -interface ContentRepositoryProjectionFactoryInterface extends ProjectionFactoryInterface +interface ContentGraphProjectionFactoryInterface extends ProjectionFactoryInterface { /** * @param array $options diff --git a/Neos.ContentRepository.Core/Classes/Projection/ProjectionStatuses.php b/Neos.ContentRepository.Core/Classes/Projection/ProjectionStatuses.php index 347abc0de6d..6acaaadc83c 100644 --- a/Neos.ContentRepository.Core/Classes/Projection/ProjectionStatuses.php +++ b/Neos.ContentRepository.Core/Classes/Projection/ProjectionStatuses.php @@ -18,12 +18,9 @@ private function __construct( ) { } - /** - * @param array>, ProjectionStatus> $statuses - */ - public static function create(array $statuses = []): self + public static function createEmpty(): self { - return new self($statuses); + return new self([]); } /** diff --git a/Neos.ContentRepositoryRegistry/Classes/ContentRepositoryRegistry.php b/Neos.ContentRepositoryRegistry/Classes/ContentRepositoryRegistry.php index 6604ad498cf..97ba7730599 100644 --- a/Neos.ContentRepositoryRegistry/Classes/ContentRepositoryRegistry.php +++ b/Neos.ContentRepositoryRegistry/Classes/ContentRepositoryRegistry.php @@ -14,7 +14,7 @@ use Neos\ContentRepository\Core\Projection\CatchUpHookFactoryInterface; use Neos\ContentRepository\Core\Projection\ContentGraph\ContentSubgraphInterface; use Neos\ContentRepository\Core\Projection\ContentGraph\Node; -use Neos\ContentRepository\Core\Projection\ContentGraph\ContentRepositoryProjectionFactoryInterface; +use Neos\ContentRepository\Core\Projection\ContentGraph\ContentGraphProjectionFactoryInterface; use Neos\ContentRepository\Core\Projection\ProjectionCatchUpTriggerInterface; use Neos\ContentRepository\Core\Projection\ProjectionFactoryInterface; use Neos\ContentRepository\Core\Projection\ProjectionInterface; @@ -245,30 +245,44 @@ private function buildPropertySerializer(ContentRepositoryId $contentRepositoryI /** @param array $contentRepositorySettings */ private function buildProjectionsFactory(ContentRepositoryId $contentRepositoryId, array $contentRepositorySettings): ProjectionsAndCatchUpHooksFactory { - (is_array($contentRepositorySettings['contentGraphProjection'] ?? null)) || throw InvalidConfigurationException::fromMessage('Content repository "%s" does not have the contentGraphProjection configured, or the value is no array.', $contentRepositoryId->value); + $projectionsAndCatchUpHooksFactory = new ProjectionsAndCatchUpHooksFactory(); + + // content graph projection: + if (!isset($contentRepositorySettings['contentGraphProjection']['factoryObjectName'])) { + throw InvalidConfigurationException::fromMessage('Content repository "%s" does not have the contentGraphProjection.factoryObjectName configured.', $contentRepositoryId->value); + } + + $projectionFactory = $this->objectManager->get($contentRepositorySettings['contentGraphProjection']['factoryObjectName']); + if (!$projectionFactory instanceof ContentGraphProjectionFactoryInterface) { + throw InvalidConfigurationException::fromMessage('Projection factory object name of contentGraphProjection (content repository "%s") is not an instance of %s but %s.', $contentRepositoryId->value, ContentGraphProjectionFactoryInterface::class, get_debug_type($projectionFactory)); + } + $projectionsAndCatchUpHooksFactory->registerFactory($projectionFactory, $contentRepositorySettings['contentGraphProjection']['options'] ?? []); + + $this->registerCatchupHookForProjection($contentRepositorySettings['contentGraphProjection'], $projectionsAndCatchUpHooksFactory, $projectionFactory, 'contentGraphProjection', $contentRepositoryId); + + // additional projections: (is_array($contentRepositorySettings['projections'] ?? [])) || throw InvalidConfigurationException::fromMessage('Content repository "%s" expects projections configured as array.', $contentRepositoryId->value); - $projectionsFactory = new ProjectionsAndCatchUpHooksFactory(); - $this->registerProjection($contentRepositorySettings['contentGraphProjection'], $projectionsFactory, ContentRepositoryProjectionFactoryInterface::class, 'contentGraphProjection', $contentRepositoryId); - foreach ($contentRepositorySettings['projections'] as $projectionName => $projectionOptions) { + foreach ($contentRepositorySettings['projections'] ?? [] as $projectionName => $projectionOptions) { if ($projectionOptions === null) { continue; } - $this->registerProjection($projectionOptions, $projectionsFactory, ProjectionFactoryInterface::class, $projectionName, $contentRepositoryId); + (is_array($projectionOptions)) || throw InvalidConfigurationException::fromMessage('Projection "%s" (content repository "%s") must be configured as array got %s', $projectionName, $contentRepositoryId->value, get_debug_type($projectionOptions)); + $projectionFactory = isset($projectionOptions['factoryObjectName']) ? $this->objectManager->get($projectionOptions['factoryObjectName']) : null; + if (!$projectionFactory instanceof ProjectionFactoryInterface) { + throw InvalidConfigurationException::fromMessage('Projection factory object name for projection "%s" (content repository "%s") is not an instance of %s but %s.', $projectionName, $contentRepositoryId->value, ProjectionFactoryInterface::class, get_debug_type($projectionFactory)); + } + $projectionsAndCatchUpHooksFactory->registerFactory($projectionFactory, $projectionOptions['options'] ?? []); + + $this->registerCatchupHookForProjection($projectionOptions, $projectionsAndCatchUpHooksFactory, $projectionFactory, $projectionName, $contentRepositoryId); } - return $projectionsFactory; + return $projectionsAndCatchUpHooksFactory; } /** - * @param class-string>> $expectedProjectionFactory + * @param ProjectionFactoryInterface> $projectionFactory */ - private function registerProjection(mixed $projectionOptions, ProjectionsAndCatchUpHooksFactory $projectionsFactory, string $expectedProjectionFactory, string $projectionName, ContentRepositoryId $contentRepositoryId): void + private function registerCatchupHookForProjection(mixed $projectionOptions, ProjectionsAndCatchUpHooksFactory $projectionsAndCatchUpHooksFactory, ProjectionFactoryInterface $projectionFactory, string $projectionName, ContentRepositoryId $contentRepositoryId): void { - (is_array($projectionOptions)) || throw InvalidConfigurationException::fromMessage('Projection "%s" (content repository "%s") must be configured as array got %s', $projectionName, $contentRepositoryId->value, get_debug_type($projectionOptions)); - $projectionFactory = isset($projectionOptions['factoryObjectName']) ? $this->objectManager->get($projectionOptions['factoryObjectName']) : null; - if (!$projectionFactory instanceof $expectedProjectionFactory) { - throw InvalidConfigurationException::fromMessage('Projection factory object name for projection "%s" (content repository "%s") is not an instance of %s but %s.', $projectionName, $contentRepositoryId->value, $expectedProjectionFactory, get_debug_type($projectionFactory)); - } - $projectionsFactory->registerFactory($projectionFactory, $projectionOptions['options'] ?? []); foreach (($projectionOptions['catchUpHooks'] ?? []) as $catchUpHookOptions) { if ($catchUpHookOptions === null) { continue; @@ -277,7 +291,7 @@ private function registerProjection(mixed $projectionOptions, ProjectionsAndCatc if (!$catchUpHookFactory instanceof CatchUpHookFactoryInterface) { throw InvalidConfigurationException::fromMessage('CatchUpHook factory object name for projection "%s" (content repository "%s") is not an instance of %s but %s', $projectionName, $contentRepositoryId->value, CatchUpHookFactoryInterface::class, get_debug_type($catchUpHookFactory)); } - $projectionsFactory->registerCatchUpHookFactory($projectionFactory, $catchUpHookFactory); + $projectionsAndCatchUpHooksFactory->registerCatchUpHookFactory($projectionFactory, $catchUpHookFactory); } }