From aff329135b8abe7f50a52cee2c801038f6947c5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Mu=CC=88ller?= Date: Fri, 5 Apr 2024 09:19:54 +0200 Subject: [PATCH] FEATURE: ContentGraphAdapter for write side access The write side no longer uses any regular finders for checks but only accesses projection data via the new `ContentGraphAdapterInterface`. Fixes: #4973 --- .../Domain/Repository/ContentGraphAdapter.php | 123 +++++++++++ .../Repository/ContentGraphAdapterFactory.php | 27 +++ .../Classes/ContentRepository.php | 9 + .../Factory/ContentRepositoryFactory.php | 8 +- .../Feature/Common/ConstraintChecks.php | 91 ++++---- .../Common/ContentStreamIdOverride.php | 6 +- .../Feature/Common/NodeVariationInternals.php | 64 +++--- .../Feature/Common/TetheredNodeInternals.php | 16 +- .../ContentGraphAdapterFactoryInterface.php | 15 ++ .../Feature/ContentGraphAdapterInterface.php | 195 ++++++++++++++++++ .../Feature/ContentStreamCommandHandler.php | 82 ++++---- .../DimensionSpaceCommandHandler.php | 47 +++-- .../Feature/NodeAggregateCommandHandler.php | 70 +++---- .../Feature/NodeCreation/NodeCreation.php | 37 ++-- .../Feature/NodeDisabling/NodeDisabling.php | 20 +- .../NodeDuplicationCommandHandler.php | 30 +-- .../NodeModification/NodeModification.php | 24 +-- .../Classes/Feature/NodeMove/NodeMove.php | 177 ++++++++-------- .../NodeReferencing/NodeReferencing.php | 27 +-- .../Feature/NodeRemoval/NodeRemoval.php | 13 +- .../Feature/NodeRenaming/NodeRenaming.php | 14 +- .../Feature/NodeTypeChange/NodeTypeChange.php | 107 +++++----- .../Feature/NodeVariation/NodeVariation.php | 16 +- .../RootNodeCreation/RootNodeHandling.php | 32 ++- .../Feature/SubtreeTagging/SubtreeTagging.php | 13 +- .../Feature/WorkspaceCommandHandler.php | 66 +++--- .../ContentGraph/ContentGraphInterface.php | 60 ------ .../ContentStream/ContentStreamFinder.php | 38 ---- .../Adjustment/TetheredNodeAdjustments.php | 3 +- 29 files changed, 817 insertions(+), 613 deletions(-) create mode 100644 Neos.ContentGraph.DoctrineDbalAdapter/src/Domain/Repository/ContentGraphAdapter.php create mode 100644 Neos.ContentGraph.DoctrineDbalAdapter/src/Domain/Repository/ContentGraphAdapterFactory.php create mode 100644 Neos.ContentRepository.Core/Classes/Feature/ContentGraphAdapterFactoryInterface.php create mode 100644 Neos.ContentRepository.Core/Classes/Feature/ContentGraphAdapterInterface.php diff --git a/Neos.ContentGraph.DoctrineDbalAdapter/src/Domain/Repository/ContentGraphAdapter.php b/Neos.ContentGraph.DoctrineDbalAdapter/src/Domain/Repository/ContentGraphAdapter.php new file mode 100644 index 00000000000..0f3792ca314 --- /dev/null +++ b/Neos.ContentGraph.DoctrineDbalAdapter/src/Domain/Repository/ContentGraphAdapter.php @@ -0,0 +1,123 @@ +dbalConnection, $tableNamePrefix); + } +} diff --git a/Neos.ContentRepository.Core/Classes/ContentRepository.php b/Neos.ContentRepository.Core/Classes/ContentRepository.php index 180e9fd0066..8d92d142775 100644 --- a/Neos.ContentRepository.Core/Classes/ContentRepository.php +++ b/Neos.ContentRepository.Core/Classes/ContentRepository.php @@ -29,6 +29,7 @@ use Neos\ContentRepository\Core\NodeType\NodeTypeManager; use Neos\ContentRepository\Core\Projection\CatchUp; use Neos\ContentRepository\Core\Projection\CatchUpOptions; +use Neos\ContentRepository\Core\Feature\ContentGraphAdapterInterface; use Neos\ContentRepository\Core\Projection\ContentGraph\ContentGraphInterface; use Neos\ContentRepository\Core\Projection\ContentStream\ContentStreamFinder; use Neos\ContentRepository\Core\Projection\ProjectionInterface; @@ -258,4 +259,12 @@ public function getContentDimensionSource(): ContentDimensionSourceInterface { return $this->contentDimensionSource; } + + /** + * @internal + */ + public function getContentGraphAdapter(): ContentGraphAdapterInterface + { + return $this->getContentGraph(); + } } diff --git a/Neos.ContentRepository.Core/Classes/Factory/ContentRepositoryFactory.php b/Neos.ContentRepository.Core/Classes/Factory/ContentRepositoryFactory.php index b23f23851c0..312c26e4a77 100644 --- a/Neos.ContentRepository.Core/Classes/Factory/ContentRepositoryFactory.php +++ b/Neos.ContentRepository.Core/Classes/Factory/ContentRepositoryFactory.php @@ -21,6 +21,7 @@ use Neos\ContentRepository\Core\DimensionSpace\InterDimensionalVariationGraph; use Neos\ContentRepository\Core\EventStore\EventNormalizer; use Neos\ContentRepository\Core\EventStore\EventPersister; +use Neos\ContentRepository\Core\Feature\ContentGraphAdapterFactoryInterface; use Neos\ContentRepository\Core\Feature\ContentStreamCommandHandler; use Neos\ContentRepository\Core\Feature\DimensionSpaceAdjustment\DimensionSpaceCommandHandler; use Neos\ContentRepository\Core\Feature\NodeAggregateCommandHandler; @@ -56,6 +57,7 @@ public function __construct( private readonly ProjectionCatchUpTriggerInterface $projectionCatchUpTrigger, private readonly UserIdProviderInterface $userIdProvider, private readonly ClockInterface $clock, + private readonly ContentGraphAdapterFactoryInterface $contentGraphAdapterFactory, ) { $contentDimensionZookeeper = new ContentDimensionZookeeper($contentDimensionSource); $interDimensionalVariationGraph = new InterDimensionalVariationGraph( @@ -132,19 +134,23 @@ public function buildService( private function buildCommandBus(): CommandBus { if (!$this->commandBus) { + $contentGraphAdapter = $this->contentGraphAdapterFactory->build($this->projectionFactoryDependencies->contentRepositoryId); $this->commandBus = new CommandBus( new ContentStreamCommandHandler( + $contentGraphAdapter ), new WorkspaceCommandHandler( $this->buildEventPersister(), $this->projectionFactoryDependencies->eventStore, $this->projectionFactoryDependencies->eventNormalizer, + $contentGraphAdapter ), new NodeAggregateCommandHandler( $this->projectionFactoryDependencies->nodeTypeManager, $this->projectionFactoryDependencies->contentDimensionZookeeper, $this->projectionFactoryDependencies->interDimensionalVariationGraph, - $this->projectionFactoryDependencies->propertyConverter + $this->projectionFactoryDependencies->propertyConverter, + $contentGraphAdapter ), new DimensionSpaceCommandHandler( $this->projectionFactoryDependencies->contentDimensionZookeeper, diff --git a/Neos.ContentRepository.Core/Classes/Feature/Common/ConstraintChecks.php b/Neos.ContentRepository.Core/Classes/Feature/Common/ConstraintChecks.php index 6054ce5cc7c..140a34d146a 100644 --- a/Neos.ContentRepository.Core/Classes/Feature/Common/ConstraintChecks.php +++ b/Neos.ContentRepository.Core/Classes/Feature/Common/ConstraintChecks.php @@ -19,6 +19,7 @@ use Neos\ContentRepository\Core\DimensionSpace\DimensionSpacePointSet; use Neos\ContentRepository\Core\DimensionSpace\Exception\DimensionSpacePointNotFound; use Neos\ContentRepository\Core\DimensionSpace\OriginDimensionSpacePoint; +use Neos\ContentRepository\Core\Feature\ContentGraphAdapterInterface; use Neos\ContentRepository\Core\Feature\NodeModification\Dto\PropertyValuesToWrite; use Neos\ContentRepository\Core\Feature\NodeVariation\Exception\DimensionSpacePointIsAlreadyOccupied; use Neos\ContentRepository\Core\Infrastructure\Property\PropertyType; @@ -47,7 +48,6 @@ use Neos\ContentRepository\Core\SharedModel\Exception\NodeTypeNotFound; use Neos\ContentRepository\Core\SharedModel\Exception\NodeTypeNotFoundException; use Neos\ContentRepository\Core\SharedModel\Exception\ReferenceCannotBeSet; -use Neos\ContentRepository\Core\SharedModel\Exception\RootNodeAggregateDoesNotExist; use Neos\ContentRepository\Core\SharedModel\Exception\RootNodeAggregateTypeIsAlreadyOccupied; use Neos\ContentRepository\Core\SharedModel\Node\NodeAggregateId; use Neos\ContentRepository\Core\SharedModel\Node\NodeName; @@ -67,21 +67,23 @@ abstract protected function getNodeTypeManager(): NodeTypeManager; abstract protected function getAllowedDimensionSubspace(): DimensionSpacePointSet; + abstract protected function getContentGraphAdapter(): ContentGraphAdapterInterface; + /** * @throws ContentStreamDoesNotExistYet */ protected function requireContentStream( - WorkspaceName $workspaceName, - ContentRepository $contentRepository + WorkspaceName $workspaceName ): ContentStreamId { - $contentStreamId = ContentStreamIdOverride::resolveContentStreamIdForWorkspace($contentRepository, $workspaceName); - if (!$contentRepository->getContentStreamFinder()->hasContentStream($contentStreamId)) { + $contentGraphAdapter = $this->getContentGraphAdapter(); + $contentStreamId = ContentStreamIdOverride::resolveContentStreamIdForWorkspace($contentGraphAdapter, $workspaceName); + if (!$contentGraphAdapter->hasContentStream($contentStreamId)) { throw new ContentStreamDoesNotExistYet( 'Content stream "' . $contentStreamId->value . '" does not exist yet.', 1521386692 ); } - if ($contentRepository->getContentStreamFinder()->findStateForContentStream($contentStreamId) === ContentStreamState::STATE_CLOSED) { + if ($contentGraphAdapter->findStateForContentStream($contentStreamId) === ContentStreamState::STATE_CLOSED) { throw new ContentStreamIsClosed( 'Content stream "' . $contentStreamId->value . '" is closed.', 1710260081 @@ -149,17 +151,15 @@ protected function requireNodeTypeToNotBeOfTypeRoot(NodeType $nodeType): void protected function requireRootNodeTypeToBeUnoccupied( NodeTypeName $nodeTypeName, - ContentStreamId $contentStreamId, - ContentRepository $contentRepository + ContentStreamId $contentStreamId ): void { - try { - $rootNodeAggregate = $contentRepository->getContentGraph()->findRootNodeAggregateByType( - $contentStreamId, - $nodeTypeName - ); + $rootNodeAggregateExists = $this->getContentGraphAdapter()->rootNodeAggregateWithTypeExists( + $contentStreamId, + $nodeTypeName + ); + + if ($rootNodeAggregateExists) { throw RootNodeAggregateTypeIsAlreadyOccupied::butWasExpectedNotTo($nodeTypeName); - } catch (RootNodeAggregateDoesNotExist $exception) { - // all is well } } @@ -247,14 +247,12 @@ protected function requireConstraintsImposedByAncestorsAreMet( ContentStreamId $contentStreamId, NodeType $nodeType, ?NodeName $nodeName, - array $parentNodeAggregateIds, - ContentRepository $contentRepository + array $parentNodeAggregateIds ): void { foreach ($parentNodeAggregateIds as $parentNodeAggregateId) { $parentAggregate = $this->requireProjectedNodeAggregate( $contentStreamId, - $parentNodeAggregateId, - $contentRepository + $parentNodeAggregateId ); if (!$parentAggregate->classification->isTethered()) { try { @@ -266,9 +264,11 @@ protected function requireConstraintsImposedByAncestorsAreMet( } } + $workspace = $this->getContentGraphAdapter()->findWorkspaceByCurrentContentStreamId($contentStreamId); foreach ( - $contentRepository->getContentGraph()->findParentNodeAggregates( + $this->getContentGraphAdapter()->findParentNodeAggregates( $contentStreamId, + $workspace?->workspaceName, $parentNodeAggregateId ) as $grandParentNodeAggregate ) { @@ -383,11 +383,12 @@ protected function areNodeTypeConstraintsImposedByGrandparentValid( */ protected function requireProjectedNodeAggregate( ContentStreamId $contentStreamId, - NodeAggregateId $nodeAggregateId, - ContentRepository $contentRepository + NodeAggregateId $nodeAggregateId ): NodeAggregate { - $nodeAggregate = $contentRepository->getContentGraph()->findNodeAggregateById( + $workspace = $this->getContentGraphAdapter()->findWorkspaceByCurrentContentStreamId($contentStreamId); + $nodeAggregate = $this->getContentGraphAdapter()->findNodeAggregateById( $contentStreamId, + $workspace?->workspaceName, $nodeAggregateId ); @@ -407,11 +408,12 @@ protected function requireProjectedNodeAggregate( */ protected function requireProjectedNodeAggregateToNotExist( ContentStreamId $contentStreamId, - NodeAggregateId $nodeAggregateId, - ContentRepository $contentRepository + NodeAggregateId $nodeAggregateId ): void { - $nodeAggregate = $contentRepository->getContentGraph()->findNodeAggregateById( + $workspace = $this->getContentGraphAdapter()->findWorkspaceByCurrentContentStreamId($contentStreamId); + $nodeAggregate = $this->getContentGraphAdapter()->findNodeAggregateById( $contentStreamId, + $workspace?->workspaceName, $nodeAggregateId ); @@ -429,12 +431,13 @@ protected function requireProjectedNodeAggregateToNotExist( public function requireProjectedParentNodeAggregate( ContentStreamId $contentStreamId, NodeAggregateId $childNodeAggregateId, - OriginDimensionSpacePoint $childOriginDimensionSpacePoint, - ContentRepository $contentRepository + OriginDimensionSpacePoint $childOriginDimensionSpacePoint ): NodeAggregate { - $parentNodeAggregate = $contentRepository->getContentGraph() + $workspace = $this->getContentGraphAdapter()->findWorkspaceByCurrentContentStreamId($contentStreamId); + $parentNodeAggregate = $this->getContentGraphAdapter() ->findParentNodeAggregateByChildOriginDimensionSpacePoint( $contentStreamId, + $workspace?->workspaceName, $childNodeAggregateId, $childOriginDimensionSpacePoint ); @@ -516,8 +519,7 @@ protected function requireNodeAggregateToBeUntethered(NodeAggregate $nodeAggrega protected function requireNodeAggregateToNotBeDescendant( ContentStreamId $contentStreamId, NodeAggregate $nodeAggregate, - NodeAggregate $referenceNodeAggregate, - ContentRepository $contentRepository + NodeAggregate $referenceNodeAggregate ): void { if ($nodeAggregate->nodeAggregateId->equals($referenceNodeAggregate->nodeAggregateId)) { throw new NodeAggregateIsDescendant( @@ -526,17 +528,18 @@ protected function requireNodeAggregateToNotBeDescendant( 1554971124 ); } + $workspace = $this->getContentGraphAdapter()->findWorkspaceByCurrentContentStreamId($contentStreamId); foreach ( - $contentRepository->getContentGraph()->findChildNodeAggregates( + $this->getContentGraphAdapter()->findChildNodeAggregates( $contentStreamId, + $workspace?->workspaceName, $referenceNodeAggregate->nodeAggregateId ) as $childReferenceNodeAggregate ) { $this->requireNodeAggregateToNotBeDescendant( $contentStreamId, $nodeAggregate, - $childReferenceNodeAggregate, - $contentRepository + $childReferenceNodeAggregate ); } } @@ -549,13 +552,12 @@ protected function requireNodeNameToBeUnoccupied( ?NodeName $nodeName, NodeAggregateId $parentNodeAggregateId, OriginDimensionSpacePoint $parentOriginDimensionSpacePoint, - DimensionSpacePointSet $dimensionSpacePoints, - ContentRepository $contentRepository + DimensionSpacePointSet $dimensionSpacePoints ): void { if ($nodeName === null) { return; } - $dimensionSpacePointsOccupiedByChildNodeName = $contentRepository->getContentGraph() + $dimensionSpacePointsOccupiedByChildNodeName = $this->getContentGraphAdapter() ->getDimensionSpacePointsOccupiedByChildNodeName( $contentStreamId, $nodeName, @@ -579,14 +581,16 @@ protected function requireNodeNameToBeUncovered( ContentStreamId $contentStreamId, ?NodeName $nodeName, NodeAggregateId $parentNodeAggregateId, - DimensionSpacePointSet $dimensionSpacePointsToBeCovered, - ContentRepository $contentRepository + DimensionSpacePointSet $dimensionSpacePointsToBeCovered ): void { if ($nodeName === null) { return; } - $childNodeAggregates = $contentRepository->getContentGraph()->findChildNodeAggregatesByName( + $workspace = $this->getContentGraphAdapter()->findWorkspaceByCurrentContentStreamId($contentStreamId); + + $childNodeAggregates = $this->getContentGraphAdapter()->findChildNodeAggregatesByName( $contentStreamId, + $workspace?->workspaceName, $parentNodeAggregateId, $nodeName ); @@ -672,13 +676,10 @@ protected function validateReferenceProperties( } protected function getExpectedVersionOfContentStream( - ContentStreamId $contentStreamId, - ContentRepository $contentRepository + ContentStreamId $contentStreamId ): ExpectedVersion { return ExpectedVersion::fromVersion( - $contentRepository->getContentStreamFinder() - ->findVersionForContentStream($contentStreamId) - ->unwrap() + $this->getContentGraphAdapter()->findVersionForContentStream($contentStreamId)->unwrap() ); } } diff --git a/Neos.ContentRepository.Core/Classes/Feature/Common/ContentStreamIdOverride.php b/Neos.ContentRepository.Core/Classes/Feature/Common/ContentStreamIdOverride.php index 96bf09b3a80..c744382c595 100644 --- a/Neos.ContentRepository.Core/Classes/Feature/Common/ContentStreamIdOverride.php +++ b/Neos.ContentRepository.Core/Classes/Feature/Common/ContentStreamIdOverride.php @@ -14,7 +14,9 @@ namespace Neos\ContentRepository\Core\Feature\Common; +use Neos\ContentGraph\DoctrineDbalAdapter\Domain\Repository\ContentGraphAdapter; use Neos\ContentRepository\Core\ContentRepository; +use Neos\ContentRepository\Core\Feature\ContentGraphAdapterInterface; use Neos\ContentRepository\Core\Feature\WorkspaceCommandHandler; use Neos\ContentRepository\Core\SharedModel\Exception\ContentStreamDoesNotExistYet; use Neos\ContentRepository\Core\SharedModel\Workspace\ContentStreamId; @@ -50,10 +52,10 @@ public static function applyContentStreamIdToClosure(ContentStreamId $contentStr /** * @internal */ - public static function resolveContentStreamIdForWorkspace(ContentRepository $contentRepository, WorkspaceName $workspaceName): ContentStreamId + public static function resolveContentStreamIdForWorkspace(ContentGraphAdapterInterface $contentGraphAdapter, WorkspaceName $workspaceName): ContentStreamId { $contentStreamId = self::$contentStreamIdToUse - ?: $contentRepository->getWorkspaceFinder()->findOneByName($workspaceName)?->currentContentStreamId; + ?: $contentGraphAdapter->findWorkspaceByName($workspaceName)?->currentContentStreamId; if (!$contentStreamId) { throw new ContentStreamDoesNotExistYet( diff --git a/Neos.ContentRepository.Core/Classes/Feature/Common/NodeVariationInternals.php b/Neos.ContentRepository.Core/Classes/Feature/Common/NodeVariationInternals.php index 54b8d0a60e2..89b2882f002 100644 --- a/Neos.ContentRepository.Core/Classes/Feature/Common/NodeVariationInternals.php +++ b/Neos.ContentRepository.Core/Classes/Feature/Common/NodeVariationInternals.php @@ -14,12 +14,12 @@ namespace Neos\ContentRepository\Core\Feature\Common; -use Neos\ContentRepository\Core\ContentRepository; use Neos\ContentRepository\Core\DimensionSpace; use Neos\ContentRepository\Core\DimensionSpace\DimensionSpacePointSet; use Neos\ContentRepository\Core\DimensionSpace\OriginDimensionSpacePoint; use Neos\ContentRepository\Core\EventStore\EventInterface; use Neos\ContentRepository\Core\EventStore\Events; +use Neos\ContentRepository\Core\Feature\ContentGraphAdapterInterface; use Neos\ContentRepository\Core\Feature\NodeVariation\Event\NodeGeneralizationVariantWasCreated; use Neos\ContentRepository\Core\Feature\NodeVariation\Event\NodePeerVariantWasCreated; use Neos\ContentRepository\Core\Feature\NodeVariation\Event\NodeSpecializationVariantWasCreated; @@ -37,12 +37,13 @@ trait NodeVariationInternals { abstract protected function getInterDimensionalVariationGraph(): DimensionSpace\InterDimensionalVariationGraph; + abstract protected function getContentGraphAdapter(): ContentGraphAdapterInterface; + protected function createEventsForVariations( ContentStreamId $contentStreamId, OriginDimensionSpacePoint $sourceOrigin, OriginDimensionSpacePoint $targetOrigin, - NodeAggregate $nodeAggregate, - ContentRepository $contentRepository + NodeAggregate $nodeAggregate ): Events { return match ( $this->getInterDimensionalVariationGraph()->getVariantType( @@ -54,22 +55,19 @@ protected function createEventsForVariations( $contentStreamId, $sourceOrigin, $targetOrigin, - $nodeAggregate, - $contentRepository + $nodeAggregate ), DimensionSpace\VariantType::TYPE_GENERALIZATION => $this->handleCreateNodeGeneralizationVariant( $contentStreamId, $sourceOrigin, $targetOrigin, - $nodeAggregate, - $contentRepository + $nodeAggregate ), default => $this->handleCreateNodePeerVariant( $contentStreamId, $sourceOrigin, $targetOrigin, - $nodeAggregate, - $contentRepository + $nodeAggregate ), }; } @@ -78,8 +76,7 @@ protected function handleCreateNodeSpecializationVariant( ContentStreamId $contentStreamId, OriginDimensionSpacePoint $sourceOrigin, OriginDimensionSpacePoint $targetOrigin, - NodeAggregate $nodeAggregate, - ContentRepository $contentRepository + NodeAggregate $nodeAggregate ): Events { $specializationVisibility = $this->calculateEffectiveVisibility($targetOrigin, $nodeAggregate); $events = $this->collectNodeSpecializationVariantsThatWillHaveBeenCreated( @@ -88,8 +85,7 @@ protected function handleCreateNodeSpecializationVariant( $targetOrigin, $nodeAggregate, $specializationVisibility, - [], - $contentRepository + [] ); return Events::fromArray($events); @@ -105,9 +101,9 @@ protected function collectNodeSpecializationVariantsThatWillHaveBeenCreated( OriginDimensionSpacePoint $targetOrigin, NodeAggregate $nodeAggregate, DimensionSpacePointSet $specializationVisibility, - array $events, - ContentRepository $contentRepository + array $events ): array { + $workspace = $this->getContentGraphAdapter()->findWorkspaceByCurrentContentStreamId($contentStreamId); $events[] = new NodeSpecializationVariantWasCreated( $contentStreamId, $nodeAggregate->nodeAggregateId, @@ -123,8 +119,9 @@ protected function collectNodeSpecializationVariantsThatWillHaveBeenCreated( ); foreach ( - $contentRepository->getContentGraph()->findTetheredChildNodeAggregates( + $this->getContentGraphAdapter()->findTetheredChildNodeAggregates( $contentStreamId, + $workspace?->workspaceName, $nodeAggregate->nodeAggregateId ) as $tetheredChildNodeAggregate ) { @@ -134,8 +131,7 @@ protected function collectNodeSpecializationVariantsThatWillHaveBeenCreated( $targetOrigin, $tetheredChildNodeAggregate, $specializationVisibility, - $events, - $contentRepository + $events ); } @@ -146,8 +142,7 @@ protected function handleCreateNodeGeneralizationVariant( ContentStreamId $contentStreamId, OriginDimensionSpacePoint $sourceOrigin, OriginDimensionSpacePoint $targetOrigin, - NodeAggregate $nodeAggregate, - ContentRepository $contentRepository + NodeAggregate $nodeAggregate ): Events { $generalizationVisibility = $this->calculateEffectiveVisibility($targetOrigin, $nodeAggregate); $events = $this->collectNodeGeneralizationVariantsThatWillHaveBeenCreated( @@ -156,8 +151,7 @@ protected function handleCreateNodeGeneralizationVariant( $targetOrigin, $nodeAggregate, $generalizationVisibility, - [], - $contentRepository + [] ); return Events::fromArray($events); @@ -173,9 +167,9 @@ protected function collectNodeGeneralizationVariantsThatWillHaveBeenCreated( OriginDimensionSpacePoint $targetOrigin, NodeAggregate $nodeAggregate, DimensionSpacePointSet $generalizationVisibility, - array $events, - ContentRepository $contentRepository + array $events ): array { + $workspace = $this->getContentGraphAdapter()->findWorkspaceByCurrentContentStreamId($contentStreamId); $events[] = new NodeGeneralizationVariantWasCreated( $contentStreamId, $nodeAggregate->nodeAggregateId, @@ -191,8 +185,9 @@ protected function collectNodeGeneralizationVariantsThatWillHaveBeenCreated( ); foreach ( - $contentRepository->getContentGraph()->findTetheredChildNodeAggregates( + $this->getContentGraphAdapter()->findTetheredChildNodeAggregates( $contentStreamId, + $workspace?->workspaceName, $nodeAggregate->nodeAggregateId ) as $tetheredChildNodeAggregate ) { @@ -202,8 +197,7 @@ protected function collectNodeGeneralizationVariantsThatWillHaveBeenCreated( $targetOrigin, $tetheredChildNodeAggregate, $generalizationVisibility, - $events, - $contentRepository + $events ); } @@ -214,8 +208,7 @@ protected function handleCreateNodePeerVariant( ContentStreamId $contentStreamId, OriginDimensionSpacePoint $sourceOrigin, OriginDimensionSpacePoint $targetOrigin, - NodeAggregate $nodeAggregate, - ContentRepository $contentRepository + NodeAggregate $nodeAggregate ): Events { $peerVisibility = $this->calculateEffectiveVisibility($targetOrigin, $nodeAggregate); $events = $this->collectNodePeerVariantsThatWillHaveBeenCreated( @@ -224,8 +217,7 @@ protected function handleCreateNodePeerVariant( $targetOrigin, $nodeAggregate, $peerVisibility, - [], - $contentRepository + [] ); return Events::fromArray($events); @@ -241,9 +233,9 @@ protected function collectNodePeerVariantsThatWillHaveBeenCreated( OriginDimensionSpacePoint $targetOrigin, NodeAggregate $nodeAggregate, DimensionSpacePointSet $peerVisibility, - array $events, - ContentRepository $contentRepository + array $events ): array { + $workspace = $this->getContentGraphAdapter()->findWorkspaceByCurrentContentStreamId($contentStreamId); $events[] = new NodePeerVariantWasCreated( $contentStreamId, $nodeAggregate->nodeAggregateId, @@ -259,8 +251,9 @@ protected function collectNodePeerVariantsThatWillHaveBeenCreated( ); foreach ( - $contentRepository->getContentGraph()->findTetheredChildNodeAggregates( + $this->getContentGraphAdapter()->findTetheredChildNodeAggregates( $contentStreamId, + $workspace?->workspaceName, $nodeAggregate->nodeAggregateId ) as $tetheredChildNodeAggregate ) { @@ -270,8 +263,7 @@ protected function collectNodePeerVariantsThatWillHaveBeenCreated( $targetOrigin, $tetheredChildNodeAggregate, $peerVisibility, - $events, - $contentRepository + $events ); } diff --git a/Neos.ContentRepository.Core/Classes/Feature/Common/TetheredNodeInternals.php b/Neos.ContentRepository.Core/Classes/Feature/Common/TetheredNodeInternals.php index 5d2a01fce2d..4c4e7d55d2d 100644 --- a/Neos.ContentRepository.Core/Classes/Feature/Common/TetheredNodeInternals.php +++ b/Neos.ContentRepository.Core/Classes/Feature/Common/TetheredNodeInternals.php @@ -14,7 +14,6 @@ * source code. */ -use Neos\ContentRepository\Core\ContentRepository; use Neos\ContentRepository\Core\DimensionSpace\OriginDimensionSpacePoint; use Neos\ContentRepository\Core\EventStore\Events; use Neos\ContentRepository\Core\Feature\NodeCreation\Event\NodeAggregateWithNodeWasCreated; @@ -43,8 +42,7 @@ abstract protected function createEventsForVariations( ContentStreamId $contentStreamId, OriginDimensionSpacePoint $sourceOrigin, OriginDimensionSpacePoint $targetOrigin, - NodeAggregate $nodeAggregate, - ContentRepository $contentRepository + NodeAggregate $nodeAggregate ): Events; /** @@ -60,11 +58,14 @@ protected function createEventsForMissingTetheredNode( OriginDimensionSpacePoint $originDimensionSpacePoint, NodeName $tetheredNodeName, ?NodeAggregateId $tetheredNodeAggregateId, - NodeType $expectedTetheredNodeType, - ContentRepository $contentRepository + NodeType $expectedTetheredNodeType ): Events { - $childNodeAggregates = $contentRepository->getContentGraph()->findChildNodeAggregatesByName( + // TODO: We should probably just directly use the workspace AND contentStreamId from the $parentNodeAggregate + $workspace = $this->getContentGraphAdapter()->findWorkspaceByCurrentContentStreamId($parentNodeAggregate->contentStreamId); + + $childNodeAggregates = $this->getContentGraphAdapter()->findChildNodeAggregatesByName( $parentNodeAggregate->contentStreamId, + $workspace?->workspaceName, $parentNodeAggregate->nodeAggregateId, $tetheredNodeName ); @@ -152,8 +153,7 @@ protected function createEventsForMissingTetheredNode( $parentNodeAggregate->contentStreamId, $childNodeSource->originDimensionSpacePoint, $originDimensionSpacePoint, - $parentNodeAggregate, - $contentRepository + $parentNodeAggregate ); } else { throw new \RuntimeException( diff --git a/Neos.ContentRepository.Core/Classes/Feature/ContentGraphAdapterFactoryInterface.php b/Neos.ContentRepository.Core/Classes/Feature/ContentGraphAdapterFactoryInterface.php new file mode 100644 index 00000000000..3dc5897222f --- /dev/null +++ b/Neos.ContentRepository.Core/Classes/Feature/ContentGraphAdapterFactoryInterface.php @@ -0,0 +1,15 @@ + + */ + public function findParentNodeAggregates( + ContentStreamId $contentStreamId, + WorkspaceName $workspaceName, + NodeAggregateId $childNodeAggregateId + ): iterable; + + /** + * @throws NodeAggregatesTypeIsAmbiguous + */ + public function findNodeAggregateById( + ContentStreamId $contentStreamId, + WorkspaceName $workspaceName, + NodeAggregateId $nodeAggregateId + ): ?NodeAggregate; + + public function findParentNodeAggregateByChildOriginDimensionSpacePoint( + ContentStreamId $contentStreamId, + WorkspaceName $workspaceName, + NodeAggregateId $childNodeAggregateId, + OriginDimensionSpacePoint $childOriginDimensionSpacePoint + ): ?NodeAggregate; + + /** + * @return iterable + */ + public function findChildNodeAggregates( + ContentStreamId $contentStreamId, + WorkspaceName $workspaceName, + NodeAggregateId $parentNodeAggregateId + ): iterable; + + /** + * @return iterable + */ + public function findTetheredChildNodeAggregates( + ContentStreamId $contentStreamId, + WorkspaceName $workspaceName, + NodeAggregateId $parentNodeAggregateId + ): iterable; + + /** + */ + public function getDimensionSpacePointsOccupiedByChildNodeName( + ContentStreamId $contentStreamId, + NodeName $nodeName, + NodeAggregateId $parentNodeAggregateId, + OriginDimensionSpacePoint $parentNodeOriginDimensionSpacePoint, + DimensionSpacePointSet $dimensionSpacePointsToCheck + ): DimensionSpacePointSet; + + /** + * A node aggregate may have multiple child node aggregates with the same name + * as long as they do not share dimension space coverage + * + * @return iterable + */ + public function findChildNodeAggregatesByName( + ContentStreamId $contentStreamId, + WorkspaceName $workspaceName, + NodeAggregateId $parentNodeAggregateId, + NodeName $name + ): iterable; + + /* + * NODES, basically anything you would ask a subgraph + */ + + /** + * Does the subgraph with the provided identity contain any nodes + */ + public function subgraphContainsNodes( + ContentStreamId $contentStreamId, + DimensionSpacePoint $dimensionSpacePoint + ): bool; + + /** + * Finds a specified node within a "subgraph" + */ + public function findNodeInSubgraph( + ContentStreamId $contentStreamId, + WorkspaceName $workspaceName, + DimensionSpacePoint $coveredDimensionSpacePoint, + NodeAggregateId $nodeAggregateId + ): ?Node; + + public function findParentNodeInSubgraph( + ContentStreamId $contentStreamId, + WorkspaceName $workspaceName, + DimensionSpacePoint $coveredDimensionSpacePoint, + NodeAggregateId $childNodeAggregateId + ): ?Node; + + public function findChildNodeByNameInSubgraph( + ContentStreamId $contentStreamId, + WorkspaceName $workspaceName, + DimensionSpacePoint $coveredDimensionSpacePoint, + NodeAggregateId $parentNodeAggregateId, + NodeName $nodeNamex + ): ?Node; + + public function findPreceedingSiblingNodesInSubgraph( + ContentStreamId $contentStreamId, + WorkspaceName $workspaceName, + DimensionSpacePoint $coveredDimensionSpacePoint, + NodeAggregateId $startingSiblingNodeAggregateId + ): Nodes; + + public function findSuceedingSiblingNodesInSubgraph( + ContentStreamId $contentStreamId, + WorkspaceName $workspaceName, + DimensionSpacePoint $coveredDimensionSpacePoint, + NodeAggregateId $startingSiblingNodeAggregateId + ): Nodes; + + /* + * CONTENT STREAMS + */ + + public function hasContentStream( + ContentStreamId $contentStreamId + ): bool; + + public function findStateForContentStream( + ContentStreamId $contentStreamId + ): ?ContentStreamState; + + public function findVersionForContentStream( + ContentStreamId $contentStreamId + ): MaybeVersion; + + /* + * WORKSPACES + */ + + public function findWorkspaceByName( + WorkspaceName $workspaceName + ): ?Workspace; + + public function findWorkspaceByCurrentContentStreamId( + ContentStreamId $contentStreamId + ): ?Workspace; +} diff --git a/Neos.ContentRepository.Core/Classes/Feature/ContentStreamCommandHandler.php b/Neos.ContentRepository.Core/Classes/Feature/ContentStreamCommandHandler.php index 86fe2b2ac22..eac522851a3 100644 --- a/Neos.ContentRepository.Core/Classes/Feature/ContentStreamCommandHandler.php +++ b/Neos.ContentRepository.Core/Classes/Feature/ContentStreamCommandHandler.php @@ -44,6 +44,12 @@ */ final class ContentStreamCommandHandler implements CommandHandlerInterface { + + public function __construct( + protected readonly ContentGraphAdapterInterface $contentGraphAdapter + ) { + } + public function canHandle(CommandInterface $command): bool { return method_exists($this, 'handle' . (new \ReflectionClass($command))->getShortName()); @@ -52,11 +58,11 @@ public function canHandle(CommandInterface $command): bool public function handle(CommandInterface $command, ContentRepository $contentRepository): EventsToPublish { return match ($command::class) { - CreateContentStream::class => $this->handleCreateContentStream($command, $contentRepository), - CloseContentStream::class => $this->handleCloseContentStream($command, $contentRepository), - ReopenContentStream::class => $this->handleReopenContentStream($command, $contentRepository), - ForkContentStream::class => $this->handleForkContentStream($command, $contentRepository), - RemoveContentStream::class => $this->handleRemoveContentStream($command, $contentRepository), + CreateContentStream::class => $this->handleCreateContentStream($command), + CloseContentStream::class => $this->handleCloseContentStream($command), + ReopenContentStream::class => $this->handleReopenContentStream($command), + ForkContentStream::class => $this->handleForkContentStream($command), + RemoveContentStream::class => $this->handleRemoveContentStream($command), default => throw new \DomainException('Cannot handle commands of class ' . get_class($command), 1710408206), }; } @@ -65,10 +71,9 @@ public function handle(CommandInterface $command, ContentRepository $contentRepo * @throws ContentStreamAlreadyExists */ private function handleCreateContentStream( - CreateContentStream $command, - ContentRepository $contentRepository + CreateContentStream $command ): EventsToPublish { - $this->requireContentStreamToNotExistYet($command->contentStreamId, $contentRepository); + $this->requireContentStreamToNotExistYet($command->contentStreamId); $streamName = ContentStreamEventStreamName::fromContentStreamId($command->contentStreamId) ->getEventStreamName(); @@ -84,12 +89,11 @@ private function handleCreateContentStream( } private function handleCloseContentStream( - CloseContentStream $command, - ContentRepository $contentRepository + CloseContentStream $command ): EventsToPublish { - $this->requireContentStreamToExist($command->contentStreamId, $contentRepository); - $expectedVersion = $this->getExpectedVersionOfContentStream($command->contentStreamId, $contentRepository); - $this->requireContentStreamToNotBeClosed($command->contentStreamId, $contentRepository); + $this->requireContentStreamToExist($command->contentStreamId); + $expectedVersion = $this->getExpectedVersionOfContentStream($command->contentStreamId); + $this->requireContentStreamToNotBeClosed($command->contentStreamId); $streamName = ContentStreamEventStreamName::fromContentStreamId($command->contentStreamId)->getEventStreamName(); return new EventsToPublish( @@ -104,12 +108,11 @@ private function handleCloseContentStream( } private function handleReopenContentStream( - ReopenContentStream $command, - ContentRepository $contentRepository + ReopenContentStream $command ): EventsToPublish { - $this->requireContentStreamToExist($command->contentStreamId, $contentRepository); - $expectedVersion = $this->getExpectedVersionOfContentStream($command->contentStreamId, $contentRepository); - $this->requireContentStreamToBeClosed($command->contentStreamId, $contentRepository); + $this->requireContentStreamToExist($command->contentStreamId); + $expectedVersion = $this->getExpectedVersionOfContentStream($command->contentStreamId); + $this->requireContentStreamToBeClosed($command->contentStreamId); $streamName = ContentStreamEventStreamName::fromContentStreamId($command->contentStreamId)->getEventStreamName(); return new EventsToPublish( @@ -129,14 +132,13 @@ private function handleReopenContentStream( * @throws ContentStreamDoesNotExistYet */ private function handleForkContentStream( - ForkContentStream $command, - ContentRepository $contentRepository + ForkContentStream $command ): EventsToPublish { - $this->requireContentStreamToExist($command->sourceContentStreamId, $contentRepository); - $this->requireContentStreamToNotBeClosed($command->sourceContentStreamId, $contentRepository); - $this->requireContentStreamToNotExistYet($command->newContentStreamId, $contentRepository); + $this->requireContentStreamToExist($command->sourceContentStreamId); + $this->requireContentStreamToNotBeClosed($command->sourceContentStreamId); + $this->requireContentStreamToNotExistYet($command->newContentStreamId); - $sourceContentStreamVersion = $contentRepository->getContentStreamFinder() + $sourceContentStreamVersion = $this->contentGraphAdapter ->findVersionForContentStream($command->sourceContentStreamId); $streamName = ContentStreamEventStreamName::fromContentStreamId($command->newContentStreamId) @@ -157,11 +159,10 @@ private function handleForkContentStream( } private function handleRemoveContentStream( - RemoveContentStream $command, - ContentRepository $contentRepository + RemoveContentStream $command ): EventsToPublish { - $this->requireContentStreamToExist($command->contentStreamId, $contentRepository); - $expectedVersion = $this->getExpectedVersionOfContentStream($command->contentStreamId, $contentRepository); + $this->requireContentStreamToExist($command->contentStreamId); + $expectedVersion = $this->getExpectedVersionOfContentStream($command->contentStreamId); $streamName = ContentStreamEventStreamName::fromContentStreamId( $command->contentStreamId @@ -183,10 +184,9 @@ private function handleRemoveContentStream( * @throws ContentStreamAlreadyExists */ protected function requireContentStreamToNotExistYet( - ContentStreamId $contentStreamId, - ContentRepository $contentRepository + ContentStreamId $contentStreamId ): void { - if ($contentRepository->getContentStreamFinder()->hasContentStream($contentStreamId)) { + if ($this->contentGraphAdapter->hasContentStream($contentStreamId)) { throw new ContentStreamAlreadyExists( 'Content stream "' . $contentStreamId->value . '" already exists.', 1521386345 @@ -199,10 +199,9 @@ protected function requireContentStreamToNotExistYet( * @throws ContentStreamDoesNotExistYet */ protected function requireContentStreamToExist( - ContentStreamId $contentStreamId, - ContentRepository $contentRepository + ContentStreamId $contentStreamId ): void { - if (!$contentRepository->getContentStreamFinder()->hasContentStream($contentStreamId)) { + if (!$this->contentGraphAdapter->hasContentStream($contentStreamId)) { throw new ContentStreamDoesNotExistYet( 'Content stream "' . $contentStreamId->value . '" does not exist yet.', 1521386692 @@ -211,10 +210,9 @@ protected function requireContentStreamToExist( } protected function requireContentStreamToNotBeClosed( - ContentStreamId $contentStreamId, - ContentRepository $contentRepository + ContentStreamId $contentStreamId ): void { - if ($contentRepository->getContentStreamFinder()->findStateForContentStream($contentStreamId) === ContentStreamState::STATE_CLOSED) { + if ($this->contentGraphAdapter->findStateForContentStream($contentStreamId) === ContentStreamState::STATE_CLOSED) { throw new ContentStreamIsClosed( 'Content stream "' . $contentStreamId->value . '" is closed.', 1710260081 @@ -223,10 +221,9 @@ protected function requireContentStreamToNotBeClosed( } protected function requireContentStreamToBeClosed( - ContentStreamId $contentStreamId, - ContentRepository $contentRepository + ContentStreamId $contentStreamId ): void { - if ($contentRepository->getContentStreamFinder()->findStateForContentStream($contentStreamId) !== ContentStreamState::STATE_CLOSED) { + if ($this->contentGraphAdapter->findStateForContentStream($contentStreamId) !== ContentStreamState::STATE_CLOSED) { throw new ContentStreamIsNotClosed( 'Content stream "' . $contentStreamId->value . '" is not closed.', 1710405911 @@ -235,11 +232,10 @@ protected function requireContentStreamToBeClosed( } protected function getExpectedVersionOfContentStream( - ContentStreamId $contentStreamId, - ContentRepository $contentRepository + ContentStreamId $contentStreamId ): ExpectedVersion { return ExpectedVersion::fromVersion( - $contentRepository->getContentStreamFinder() + $this->contentGraphAdapter ->findVersionForContentStream($contentStreamId) ->unwrap() ); diff --git a/Neos.ContentRepository.Core/Classes/Feature/DimensionSpaceAdjustment/DimensionSpaceCommandHandler.php b/Neos.ContentRepository.Core/Classes/Feature/DimensionSpaceAdjustment/DimensionSpaceCommandHandler.php index ca0b66861b4..7b6a8030173 100644 --- a/Neos.ContentRepository.Core/Classes/Feature/DimensionSpaceAdjustment/DimensionSpaceCommandHandler.php +++ b/Neos.ContentRepository.Core/Classes/Feature/DimensionSpaceAdjustment/DimensionSpaceCommandHandler.php @@ -25,6 +25,7 @@ use Neos\ContentRepository\Core\DimensionSpace\VariantType; use Neos\ContentRepository\Core\EventStore\Events; use Neos\ContentRepository\Core\EventStore\EventsToPublish; +use Neos\ContentRepository\Core\Feature\ContentGraphAdapterInterface; use Neos\ContentRepository\Core\Feature\ContentStreamEventStreamName; use Neos\ContentRepository\Core\Feature\DimensionSpaceAdjustment\Command\AddDimensionShineThrough; use Neos\ContentRepository\Core\Feature\DimensionSpaceAdjustment\Command\MoveDimensionSpacePoint; @@ -46,6 +47,7 @@ public function __construct( private ContentDimensionZookeeper $contentDimensionZookeeper, private InterDimensionalVariationGraph $interDimensionalVariationGraph, + private ContentGraphAdapterInterface $contentGraphAdapter ) { } @@ -58,14 +60,13 @@ public function handle(CommandInterface $command, ContentRepository $contentRepo { /** @phpstan-ignore-next-line */ return match ($command::class) { - MoveDimensionSpacePoint::class => $this->handleMoveDimensionSpacePoint($command, $contentRepository), - AddDimensionShineThrough::class => $this->handleAddDimensionShineThrough($command, $contentRepository), + MoveDimensionSpacePoint::class => $this->handleMoveDimensionSpacePoint($command), + AddDimensionShineThrough::class => $this->handleAddDimensionShineThrough($command), }; } private function handleMoveDimensionSpacePoint( - MoveDimensionSpacePoint $command, - ContentRepository $contentRepository + MoveDimensionSpacePoint $command ): EventsToPublish { $contentStreamId = $this->requireContentStreamForWorkspaceName($command->workspaceName, $contentRepository); $streamName = ContentStreamEventStreamName::fromContentStreamId($contentStreamId) @@ -74,7 +75,7 @@ private function handleMoveDimensionSpacePoint( self::requireDimensionSpacePointToBeEmptyInContentStream( $command->target, $contentStreamId, - $contentRepository->getContentGraph() + $this->contentGraphAdapter ); $this->requireDimensionSpacePointToExist($command->target); @@ -92,8 +93,7 @@ private function handleMoveDimensionSpacePoint( } private function handleAddDimensionShineThrough( - AddDimensionShineThrough $command, - ContentRepository $contentRepository + AddDimensionShineThrough $command ): EventsToPublish { $contentStreamId = $this->requireContentStreamForWorkspaceName($command->workspaceName, $contentRepository); $streamName = ContentStreamEventStreamName::fromContentStreamId($contentStreamId) @@ -102,7 +102,7 @@ private function handleAddDimensionShineThrough( self::requireDimensionSpacePointToBeEmptyInContentStream( $command->target, $contentStreamId, - $contentRepository->getContentGraph() + $this->contentGraphAdapter ); $this->requireDimensionSpacePointToExist($command->target); @@ -135,14 +135,10 @@ protected function requireDimensionSpacePointToExist(DimensionSpacePoint $dimens private static function requireDimensionSpacePointToBeEmptyInContentStream( DimensionSpacePoint $dimensionSpacePoint, ContentStreamId $contentStreamId, - ContentGraphInterface $contentGraph + ContentGraphAdapterInterface $contentGraphAdapter ): void { - $subgraph = $contentGraph->getSubgraph( - $contentStreamId, - $dimensionSpacePoint, - VisibilityConstraints::withoutRestrictions() - ); - if ($subgraph->countNodes() > 0) { + $hasNodes = $contentGraphAdapter->subgraphContainsNodes($contentStreamId, $dimensionSpacePoint); + if ($hasNodes) { throw new DimensionSpacePointAlreadyExists(sprintf( 'the content stream %s already contained nodes in dimension space point %s - this is not allowed.', $contentStreamId->value, @@ -169,12 +165,11 @@ private function requireDimensionSpacePointToBeSpecialization( * @throws ContentStreamDoesNotExistYet */ protected function requireContentStreamForWorkspaceName( - WorkspaceName $workspaceName, - ContentRepository $contentRepository + WorkspaceName $workspaceName ): ContentStreamId { - $contentStreamId = $contentRepository->getWorkspaceFinder()->findOneByName($workspaceName) + $contentStreamId = $this->contentGraphAdapter->findWorkspaceByName($workspaceName) ?->currentContentStreamId; - if (!$contentStreamId || !$contentRepository->getContentStreamFinder()->hasContentStream($contentStreamId)) { + if (!$contentStreamId || !$this->contentGraphAdapter->hasContentStream($contentStreamId)) { throw new ContentStreamDoesNotExistYet( 'Content stream "' . $contentStreamId?->value . '" does not exist yet.', 1521386692 @@ -183,4 +178,18 @@ protected function requireContentStreamForWorkspaceName( return $contentStreamId; } + + /** + * @throws ContentStreamDoesNotExistYet + */ + protected function requireContentStream( + ContentStreamId $contentStreamId + ): void { + if (!$this->contentGraphAdapter->hasContentStream($contentStreamId)) { + throw new ContentStreamDoesNotExistYet( + 'Content stream "' . $contentStreamId->value . '" does not exist yet.', + 1521386692 + ); + } + } } diff --git a/Neos.ContentRepository.Core/Classes/Feature/NodeAggregateCommandHandler.php b/Neos.ContentRepository.Core/Classes/Feature/NodeAggregateCommandHandler.php index 27b49905cb6..2bf929c6dda 100644 --- a/Neos.ContentRepository.Core/Classes/Feature/NodeAggregateCommandHandler.php +++ b/Neos.ContentRepository.Core/Classes/Feature/NodeAggregateCommandHandler.php @@ -72,41 +72,20 @@ final class NodeAggregateCommandHandler implements CommandHandlerInterface use NodeVariation; use TetheredNodeInternals; - /** - * Used for constraint checks against the current outside configuration state of node types - */ - private NodeTypeManager $nodeTypeManager; - - /** - * Used for variation resolution from the current outside state of content dimensions - */ - private DimensionSpace\InterDimensionalVariationGraph $interDimensionalVariationGraph; - - /** - * Used for constraint checks against the current outside configuration state of content dimensions - */ - private DimensionSpace\ContentDimensionZookeeper $contentDimensionZookeeper; - - protected PropertyConverter $propertyConverter; - /** * can be disabled in {@see NodeAggregateCommandHandler::withoutAncestorNodeTypeConstraintChecks()} */ private bool $ancestorNodeTypeConstraintChecksEnabled = true; public function __construct( - NodeTypeManager $nodeTypeManager, - DimensionSpace\ContentDimensionZookeeper $contentDimensionZookeeper, - DimensionSpace\InterDimensionalVariationGraph $interDimensionalVariationGraph, - PropertyConverter $propertyConverter + private readonly NodeTypeManager $nodeTypeManager, + private readonly DimensionSpace\ContentDimensionZookeeper $contentDimensionZookeeper, + private readonly DimensionSpace\InterDimensionalVariationGraph $interDimensionalVariationGraph, + private readonly PropertyConverter $propertyConverter, + protected readonly ContentGraphAdapterInterface $contentGraphAdapter ) { - $this->nodeTypeManager = $nodeTypeManager; - $this->contentDimensionZookeeper = $contentDimensionZookeeper; - $this->interDimensionalVariationGraph = $interDimensionalVariationGraph; - $this->propertyConverter = $propertyConverter; } - public function canHandle(CommandInterface $command): bool { return method_exists($this, 'handle' . (new \ReflectionClass($command))->getShortName()); @@ -116,29 +95,29 @@ public function handle(CommandInterface $command, ContentRepository $contentRepo { /** @phpstan-ignore-next-line */ return match ($command::class) { - SetNodeProperties::class => $this->handleSetNodeProperties($command, $contentRepository), + SetNodeProperties::class => $this->handleSetNodeProperties($command), SetSerializedNodeProperties::class - => $this->handleSetSerializedNodeProperties($command, $contentRepository), - SetNodeReferences::class => $this->handleSetNodeReferences($command, $contentRepository), + => $this->handleSetSerializedNodeProperties($command), + SetNodeReferences::class => $this->handleSetNodeReferences($command), SetSerializedNodeReferences::class - => $this->handleSetSerializedNodeReferences($command, $contentRepository), - ChangeNodeAggregateType::class => $this->handleChangeNodeAggregateType($command, $contentRepository), - RemoveNodeAggregate::class => $this->handleRemoveNodeAggregate($command, $contentRepository), + => $this->handleSetSerializedNodeReferences($command), + ChangeNodeAggregateType::class => $this->handleChangeNodeAggregateType($command), + RemoveNodeAggregate::class => $this->handleRemoveNodeAggregate($command), CreateNodeAggregateWithNode::class - => $this->handleCreateNodeAggregateWithNode($command, $contentRepository), + => $this->handleCreateNodeAggregateWithNode($command), CreateNodeAggregateWithNodeAndSerializedProperties::class - => $this->handleCreateNodeAggregateWithNodeAndSerializedProperties($command, $contentRepository), - MoveNodeAggregate::class => $this->handleMoveNodeAggregate($command, $contentRepository), - CreateNodeVariant::class => $this->handleCreateNodeVariant($command, $contentRepository), + => $this->handleCreateNodeAggregateWithNodeAndSerializedProperties($command), + MoveNodeAggregate::class => $this->handleMoveNodeAggregate($command), + CreateNodeVariant::class => $this->handleCreateNodeVariant($command), CreateRootNodeAggregateWithNode::class - => $this->handleCreateRootNodeAggregateWithNode($command, $contentRepository), + => $this->handleCreateRootNodeAggregateWithNode($command), UpdateRootNodeAggregateDimensions::class - => $this->handleUpdateRootNodeAggregateDimensions($command, $contentRepository), - DisableNodeAggregate::class => $this->handleDisableNodeAggregate($command, $contentRepository), - EnableNodeAggregate::class => $this->handleEnableNodeAggregate($command, $contentRepository), - TagSubtree::class => $this->handleTagSubtree($command, $contentRepository), - UntagSubtree::class => $this->handleUntagSubtree($command, $contentRepository), - ChangeNodeAggregateName::class => $this->handleChangeNodeAggregateName($command, $contentRepository), + => $this->handleUpdateRootNodeAggregateDimensions($command), + DisableNodeAggregate::class => $this->handleDisableNodeAggregate($command), + EnableNodeAggregate::class => $this->handleEnableNodeAggregate($command), + TagSubtree::class => $this->handleTagSubtree($command), + UntagSubtree::class => $this->handleUntagSubtree($command), + ChangeNodeAggregateName::class => $this->handleChangeNodeAggregateName($command), }; } @@ -167,6 +146,11 @@ public function getPropertyConverter(): PropertyConverter return $this->propertyConverter; } + protected function getContentGraphAdapter(): ContentGraphAdapterInterface + { + return $this->contentGraphAdapter; + } + /** * Use this closure to run code with the Ancestor Node Type Checks disabled; e.g. * during imports. diff --git a/Neos.ContentRepository.Core/Classes/Feature/NodeCreation/NodeCreation.php b/Neos.ContentRepository.Core/Classes/Feature/NodeCreation/NodeCreation.php index c2f1ff8a42a..e2e389d0209 100644 --- a/Neos.ContentRepository.Core/Classes/Feature/NodeCreation/NodeCreation.php +++ b/Neos.ContentRepository.Core/Classes/Feature/NodeCreation/NodeCreation.php @@ -14,7 +14,6 @@ namespace Neos\ContentRepository\Core\Feature\NodeCreation; -use Neos\ContentRepository\Core\ContentRepository; use Neos\ContentRepository\Core\DimensionSpace; use Neos\ContentRepository\Core\DimensionSpace\DimensionSpacePointSet; use Neos\ContentRepository\Core\EventStore\Events; @@ -68,8 +67,7 @@ abstract protected function getPropertyConverter(): PropertyConverter; abstract protected function getNodeTypeManager(): NodeTypeManager; private function handleCreateNodeAggregateWithNode( - CreateNodeAggregateWithNode $command, - ContentRepository $contentRepository + CreateNodeAggregateWithNode $command ): EventsToPublish { $this->requireNodeType($command->nodeTypeName); $this->validateProperties($command->initialPropertyValues, $command->nodeTypeName); @@ -91,7 +89,7 @@ private function handleCreateNodeAggregateWithNode( $lowLevelCommand = $lowLevelCommand->withTetheredDescendantNodeAggregateIds($command->tetheredDescendantNodeAggregateIds); } - return $this->handleCreateNodeAggregateWithNodeAndSerializedProperties($lowLevelCommand, $contentRepository); + return $this->handleCreateNodeAggregateWithNodeAndSerializedProperties($lowLevelCommand); } private function validateProperties(?PropertyValuesToWrite $propertyValues, NodeTypeName $nodeTypeName): void @@ -128,11 +126,10 @@ private function validateProperties(?PropertyValuesToWrite $propertyValues, Node * @throws NodeTypeNotFoundException */ private function handleCreateNodeAggregateWithNodeAndSerializedProperties( - CreateNodeAggregateWithNodeAndSerializedProperties $command, - ContentRepository $contentRepository + CreateNodeAggregateWithNodeAndSerializedProperties $command ): EventsToPublish { - $contentStreamId = $this->requireContentStream($command->workspaceName, $contentRepository); - $expectedVersion = $this->getExpectedVersionOfContentStream($contentStreamId, $contentRepository); + $contentStreamId = $this->requireContentStream($command->workspaceName); + $expectedVersion = $this->getExpectedVersionOfContentStream($contentStreamId); $this->requireDimensionSpacePointToExist($command->originDimensionSpacePoint->toDimensionSpacePoint()); $nodeType = $this->requireNodeType($command->nodeTypeName); $this->requireNodeTypeToNotBeAbstract($nodeType); @@ -144,25 +141,21 @@ private function handleCreateNodeAggregateWithNodeAndSerializedProperties( $contentStreamId, $nodeType, $command->nodeName, - [$command->parentNodeAggregateId], - $contentRepository + [$command->parentNodeAggregateId] ); } $this->requireProjectedNodeAggregateToNotExist( $contentStreamId, - $command->nodeAggregateId, - $contentRepository + $command->nodeAggregateId ); $parentNodeAggregate = $this->requireProjectedNodeAggregate( $contentStreamId, - $command->parentNodeAggregateId, - $contentRepository + $command->parentNodeAggregateId ); if ($command->succeedingSiblingNodeAggregateId) { $this->requireProjectedNodeAggregate( $contentStreamId, - $command->succeedingSiblingNodeAggregateId, - $contentRepository + $command->succeedingSiblingNodeAggregateId ); } $this->requireNodeAggregateToCoverDimensionSpacePoint( @@ -181,8 +174,7 @@ private function handleCreateNodeAggregateWithNodeAndSerializedProperties( $command->nodeName, $command->parentNodeAggregateId, $command->originDimensionSpacePoint, - $coveredDimensionSpacePoints, - $contentRepository + $coveredDimensionSpacePoints ); } @@ -199,8 +191,7 @@ private function handleCreateNodeAggregateWithNodeAndSerializedProperties( ) { $this->requireProjectedNodeAggregateToNotExist( $contentStreamId, - $descendantNodeAggregateId, - $contentRepository + $descendantNodeAggregateId ); } @@ -224,7 +215,7 @@ private function handleCreateNodeAggregateWithNodeAndSerializedProperties( $coveredDimensionSpacePoints, $command->nodeAggregateId, $descendantNodeAggregateIds, - null, + null ))); return new EventsToPublish( @@ -274,7 +265,7 @@ private function handleTetheredChildNodes( DimensionSpacePointSet $coveredDimensionSpacePoints, NodeAggregateId $parentNodeAggregateId, NodeAggregateIdsByNodePaths $nodeAggregateIds, - ?NodePath $nodePath, + ?NodePath $nodePath ): Events { $events = []; foreach ($this->getNodeTypeManager()->getTetheredNodesConfigurationForNodeType($nodeType) as $rawNodeName => $childNodeType) { @@ -306,7 +297,7 @@ private function handleTetheredChildNodes( $coveredDimensionSpacePoints, $childNodeAggregateId, $nodeAggregateIds, - $childNodePath, + $childNodePath ))); } diff --git a/Neos.ContentRepository.Core/Classes/Feature/NodeDisabling/NodeDisabling.php b/Neos.ContentRepository.Core/Classes/Feature/NodeDisabling/NodeDisabling.php index eca096a52c7..1a35de7c522 100644 --- a/Neos.ContentRepository.Core/Classes/Feature/NodeDisabling/NodeDisabling.php +++ b/Neos.ContentRepository.Core/Classes/Feature/NodeDisabling/NodeDisabling.php @@ -45,16 +45,14 @@ abstract protected function getInterDimensionalVariationGraph(): DimensionSpace\ * @throws NodeAggregatesTypeIsAmbiguous */ private function handleDisableNodeAggregate( - DisableNodeAggregate $command, - ContentRepository $contentRepository + DisableNodeAggregate $command ): EventsToPublish { - $contentStreamId = $this->requireContentStream($command->workspaceName, $contentRepository); - $expectedVersion = $this->getExpectedVersionOfContentStream($contentStreamId, $contentRepository); + $contentStreamId = $this->requireContentStream($command->workspaceName); + $expectedVersion = $this->getExpectedVersionOfContentStream($contentStreamId); $this->requireDimensionSpacePointToExist($command->coveredDimensionSpacePoint); $nodeAggregate = $this->requireProjectedNodeAggregate( $contentStreamId, - $command->nodeAggregateId, - $contentRepository + $command->nodeAggregateId ); $this->requireNodeAggregateToCoverDimensionSpacePoint( $nodeAggregate, @@ -100,16 +98,14 @@ private function handleDisableNodeAggregate( * @throws NodeAggregatesTypeIsAmbiguous */ public function handleEnableNodeAggregate( - EnableNodeAggregate $command, - ContentRepository $contentRepository + EnableNodeAggregate $command ): EventsToPublish { - $contentStreamId = $this->requireContentStream($command->workspaceName, $contentRepository); - $expectedVersion = $this->getExpectedVersionOfContentStream($contentStreamId, $contentRepository); + $contentStreamId = $this->requireContentStream($command->workspaceName); + $expectedVersion = $this->getExpectedVersionOfContentStream($contentStreamId); $this->requireDimensionSpacePointToExist($command->coveredDimensionSpacePoint); $nodeAggregate = $this->requireProjectedNodeAggregate( $contentStreamId, - $command->nodeAggregateId, - $contentRepository + $command->nodeAggregateId ); $this->requireNodeAggregateToCoverDimensionSpacePoint( $nodeAggregate, diff --git a/Neos.ContentRepository.Core/Classes/Feature/NodeDuplication/NodeDuplicationCommandHandler.php b/Neos.ContentRepository.Core/Classes/Feature/NodeDuplication/NodeDuplicationCommandHandler.php index d88df293eab..fbf7176d8f2 100644 --- a/Neos.ContentRepository.Core/Classes/Feature/NodeDuplication/NodeDuplicationCommandHandler.php +++ b/Neos.ContentRepository.Core/Classes/Feature/NodeDuplication/NodeDuplicationCommandHandler.php @@ -71,7 +71,7 @@ public function handle(CommandInterface $command, ContentRepository $contentRepo { /** @phpstan-ignore-next-line */ return match ($command::class) { - CopyNodesRecursively::class => $this->handleCopyNodesRecursively($command, $contentRepository), + CopyNodesRecursively::class => $this->handleCopyNodesRecursively($command), }; } @@ -79,12 +79,11 @@ public function handle(CommandInterface $command, ContentRepository $contentRepo * @throws NodeConstraintException */ private function handleCopyNodesRecursively( - CopyNodesRecursively $command, - ContentRepository $contentRepository + CopyNodesRecursively $command ): EventsToPublish { // Basic constraints (Content Stream / Dimension Space Point / Node Type of to-be-inserted root node) - $contentStreamId = $this->requireContentStream($command->workspaceName, $contentRepository); - $expectedVersion = $this->getExpectedVersionOfContentStream($contentStreamId, $contentRepository); + $contentStreamId = $this->requireContentStream($command->workspaceName); + $expectedVersion = $this->getExpectedVersionOfContentStream($contentStreamId); $this->requireDimensionSpacePointToExist( $command->targetDimensionSpacePoint->toDimensionSpacePoint() ); @@ -98,28 +97,24 @@ private function handleCopyNodesRecursively( $contentStreamId, $nodeType, $command->targetNodeName, - [$command->targetParentNodeAggregateId], - $contentRepository + [$command->targetParentNodeAggregateId] ); // Constraint: The new nodeAggregateIds are not allowed to exist yet. $this->requireNewNodeAggregateIdsToNotExist( $contentStreamId, - $command->nodeAggregateIdMapping, - $contentRepository + $command->nodeAggregateIdMapping ); // Constraint: the parent node must exist in the command's DimensionSpacePoint as well $parentNodeAggregate = $this->requireProjectedNodeAggregate( $contentStreamId, - $command->targetParentNodeAggregateId, - $contentRepository + $command->targetParentNodeAggregateId ); if ($command->targetSucceedingSiblingNodeAggregateId) { $this->requireProjectedNodeAggregate( $contentStreamId, - $command->targetSucceedingSiblingNodeAggregateId, - $contentRepository + $command->targetSucceedingSiblingNodeAggregateId ); } $this->requireNodeAggregateToCoverDimensionSpacePoint( @@ -143,8 +138,7 @@ private function handleCopyNodesRecursively( $command->targetNodeName, $command->targetParentNodeAggregateId, $command->targetDimensionSpacePoint, - $coveredDimensionSpacePoints, - $contentRepository + $coveredDimensionSpacePoints ); } @@ -177,14 +171,12 @@ private function handleCopyNodesRecursively( private function requireNewNodeAggregateIdsToNotExist( ContentStreamId $contentStreamId, - Dto\NodeAggregateIdMapping $nodeAggregateIdMapping, - ContentRepository $contentRepository + Dto\NodeAggregateIdMapping $nodeAggregateIdMapping ): void { foreach ($nodeAggregateIdMapping->getAllNewNodeAggregateIds() as $nodeAggregateId) { $this->requireProjectedNodeAggregateToNotExist( $contentStreamId, - $nodeAggregateId, - $contentRepository + $nodeAggregateId ); } } diff --git a/Neos.ContentRepository.Core/Classes/Feature/NodeModification/NodeModification.php b/Neos.ContentRepository.Core/Classes/Feature/NodeModification/NodeModification.php index 49d71efa330..cf9fc4d541b 100644 --- a/Neos.ContentRepository.Core/Classes/Feature/NodeModification/NodeModification.php +++ b/Neos.ContentRepository.Core/Classes/Feature/NodeModification/NodeModification.php @@ -14,7 +14,6 @@ namespace Neos\ContentRepository\Core\Feature\NodeModification; -use Neos\ContentRepository\Core\ContentRepository; use Neos\ContentRepository\Core\EventStore\Events; use Neos\ContentRepository\Core\EventStore\EventsToPublish; use Neos\ContentRepository\Core\Feature\Common\NodeAggregateEventPublisher; @@ -40,20 +39,17 @@ abstract protected function requireNodeType(NodeTypeName $nodeTypeName): NodeTyp abstract protected function requireProjectedNodeAggregate( ContentStreamId $contentStreamId, - NodeAggregateId $nodeAggregateId, - ContentRepository $contentRepository + NodeAggregateId $nodeAggregateId ): NodeAggregate; private function handleSetNodeProperties( - SetNodeProperties $command, - ContentRepository $contentRepository + SetNodeProperties $command ): EventsToPublish { - $contentStreamId = $this->requireContentStream($command->workspaceName, $contentRepository); + $contentStreamId = $this->requireContentStream($command->workspaceName); $this->requireDimensionSpacePointToExist($command->originDimensionSpacePoint->toDimensionSpacePoint()); $nodeAggregate = $this->requireProjectedNodeAggregate( $contentStreamId, - $command->nodeAggregateId, - $contentRepository + $command->nodeAggregateId ); $this->requireNodeAggregateToNotBeRoot($nodeAggregate); $nodeTypeName = $nodeAggregate->nodeTypeName; @@ -71,20 +67,18 @@ private function handleSetNodeProperties( $command->propertyValues->getPropertiesToUnset() ); - return $this->handleSetSerializedNodeProperties($lowLevelCommand, $contentRepository); + return $this->handleSetSerializedNodeProperties($lowLevelCommand); } private function handleSetSerializedNodeProperties( - SetSerializedNodeProperties $command, - ContentRepository $contentRepository + SetSerializedNodeProperties $command ): EventsToPublish { - $contentStreamId = $this->requireContentStream($command->workspaceName, $contentRepository); - $expectedVersion = $this->getExpectedVersionOfContentStream($contentStreamId, $contentRepository); + $contentStreamId = $this->requireContentStream($command->workspaceName); + $expectedVersion = $this->getExpectedVersionOfContentStream($contentStreamId); // Check if node exists $nodeAggregate = $this->requireProjectedNodeAggregate( $contentStreamId, - $command->nodeAggregateId, - $contentRepository + $command->nodeAggregateId ); $nodeType = $this->requireNodeType($nodeAggregate->nodeTypeName); $this->requireNodeAggregateToOccupyDimensionSpacePoint($nodeAggregate, $command->originDimensionSpacePoint); diff --git a/Neos.ContentRepository.Core/Classes/Feature/NodeMove/NodeMove.php b/Neos.ContentRepository.Core/Classes/Feature/NodeMove/NodeMove.php index 9290dfdb872..78504e30814 100644 --- a/Neos.ContentRepository.Core/Classes/Feature/NodeMove/NodeMove.php +++ b/Neos.ContentRepository.Core/Classes/Feature/NodeMove/NodeMove.php @@ -32,6 +32,7 @@ use Neos\ContentRepository\Core\Feature\NodeMove\Dto\RelationDistributionStrategy; use Neos\ContentRepository\Core\Feature\NodeMove\Dto\SucceedingSiblingNodeMoveDestination; use Neos\ContentRepository\Core\Feature\NodeMove\Event\NodeAggregateWasMoved; +use Neos\ContentRepository\Core\Projection\ContentGraph\ContentSubgraphIdentity; use Neos\ContentRepository\Core\Projection\ContentGraph\ContentSubgraphInterface; use Neos\ContentRepository\Core\Projection\ContentGraph\Filter\FindPrecedingSiblingNodesFilter; use Neos\ContentRepository\Core\Projection\ContentGraph\Filter\FindSucceedingSiblingNodesFilter; @@ -46,6 +47,7 @@ use Neos\ContentRepository\Core\SharedModel\Exception\NodeAggregatesTypeIsAmbiguous; use Neos\ContentRepository\Core\SharedModel\Node\NodeAggregateId; use Neos\ContentRepository\Core\SharedModel\Workspace\ContentStreamId; +use Neos\ContentRepository\Core\SharedModel\Workspace\WorkspaceName; /** * @internal implementation detail of Command Handlers @@ -58,8 +60,7 @@ abstract protected function areAncestorNodeTypeConstraintChecksEnabled(): bool; abstract protected function requireProjectedNodeAggregate( ContentStreamId $contentStreamId, - NodeAggregateId $nodeAggregateId, - ContentRepository $contentRepository + NodeAggregateId $nodeAggregateId ): NodeAggregate; /** @@ -71,16 +72,14 @@ abstract protected function requireProjectedNodeAggregate( * @throws NodeAggregateIsDescendant */ private function handleMoveNodeAggregate( - MoveNodeAggregate $command, - ContentRepository $contentRepository + MoveNodeAggregate $command ): EventsToPublish { - $contentStreamId = $this->requireContentStream($command->workspaceName, $contentRepository); - $expectedVersion = $this->getExpectedVersionOfContentStream($contentStreamId, $contentRepository); + $contentStreamId = $this->requireContentStream($command->workspaceName); + $expectedVersion = $this->getExpectedVersionOfContentStream($contentStreamId); $this->requireDimensionSpacePointToExist($command->dimensionSpacePoint); $nodeAggregate = $this->requireProjectedNodeAggregate( $contentStreamId, - $command->nodeAggregateId, - $contentRepository + $command->nodeAggregateId ); $this->requireNodeAggregateToNotBeRoot($nodeAggregate); $this->requireNodeAggregateToBeUntethered($nodeAggregate); @@ -97,22 +96,19 @@ private function handleMoveNodeAggregate( $contentStreamId, $this->requireNodeType($nodeAggregate->nodeTypeName), $nodeAggregate->nodeName, - [$command->newParentNodeAggregateId], - $contentRepository + [$command->newParentNodeAggregateId] ); $this->requireNodeNameToBeUncovered( $contentStreamId, $nodeAggregate->nodeName, $command->newParentNodeAggregateId, - $affectedDimensionSpacePoints, - $contentRepository + $affectedDimensionSpacePoints ); $newParentNodeAggregate = $this->requireProjectedNodeAggregate( $contentStreamId, - $command->newParentNodeAggregateId, - $contentRepository + $command->newParentNodeAggregateId ); $this->requireNodeAggregateToCoverDimensionSpacePoints( @@ -123,23 +119,20 @@ private function handleMoveNodeAggregate( $this->requireNodeAggregateToNotBeDescendant( $contentStreamId, $newParentNodeAggregate, - $nodeAggregate, - $contentRepository + $nodeAggregate ); } if ($command->newPrecedingSiblingNodeAggregateId) { $this->requireProjectedNodeAggregate( $contentStreamId, - $command->newPrecedingSiblingNodeAggregateId, - $contentRepository + $command->newPrecedingSiblingNodeAggregateId ); } if ($command->newSucceedingSiblingNodeAggregateId) { $this->requireProjectedNodeAggregate( $contentStreamId, - $command->newSucceedingSiblingNodeAggregateId, - $contentRepository + $command->newSucceedingSiblingNodeAggregateId ); } @@ -155,8 +148,7 @@ private function handleMoveNodeAggregate( $command->newPrecedingSiblingNodeAggregateId, $command->newSucceedingSiblingNodeAggregateId, $movedNodeOrigin, - $affectedDimensionSpacePoints, - $contentRepository + $affectedDimensionSpacePoints ) ); } @@ -195,18 +187,18 @@ private function resolveNewParentAssignments( ContentStreamId $contentStreamId, /** The parent node aggregate's id*/ NodeAggregateId $parentId, - DimensionSpace\DimensionSpacePoint $coveredDimensionSpacePoint, - ContentRepository $contentRepository + DimensionSpace\DimensionSpacePoint $coveredDimensionSpacePoint ): CoverageNodeMoveMapping { - $contentSubgraph = $contentRepository->getContentGraph()->getSubgraph( + $workspace = $this->getContentGraphAdapter()->findWorkspaceByCurrentContentStreamId($contentStreamId); + $parentNode = $this->getContentGraphAdapter()->findNodeInSubgraph( $contentStreamId, + $workspace?->workspaceName, $coveredDimensionSpacePoint, - VisibilityConstraints::withoutRestrictions() + $parentId ); - $parentNode = $contentSubgraph->findNodeById($parentId); if ($parentNode === null) { throw new \InvalidArgumentException( - 'Parent ' . $parentId->value . ' not found in subgraph ' . json_encode($contentSubgraph), + sprintf('Parent ' . $parentId->value . ' not found in ontentstream "%s" and dimension space point "%s" ', $contentStreamId->value, json_encode($coveredDimensionSpacePoint)), 1667596931 ); } @@ -236,25 +228,31 @@ private function resolveAffectedDimensionSpacePointSet( }; } - private function findSibling( - ContentSubgraphInterface $contentSubgraph, - ?NodeAggregateId $parentId, - NodeAggregateId $siblingId - ): ?Node { - $siblingCandidate = $contentSubgraph->findNodeById($siblingId); - if ($parentId && $siblingCandidate) { - // If a parent node aggregate is explicitly given, all siblings must have this parent - $parent = $contentSubgraph->findParentNode($siblingId); - if (is_null($parent)) { - throw new \InvalidArgumentException( - 'Parent ' . $parentId->value . ' not found in subgraph ' . json_encode($contentSubgraph), - 1645366837 - ); - } - if ($parent->nodeAggregateId->equals($parentId)) { - return $siblingCandidate; - } - } else { + private function findSiblingWithin( + ContentStreamId $contentStreamId, + WorkspaceName $workspaceName, + DimensionSpace\DimensionSpacePoint $coveredDimensionSpacePoint, + NodeAggregateId $siblingId, + ?NodeAggregateId $parentId + ): ?Node + { + $siblingCandidate = $this->getContentGraphAdapter()->findNodeInSubgraph($contentStreamId, $workspaceName, $coveredDimensionSpacePoint, $siblingId); + if (!$siblingCandidate) { + return null; + } + + if (!$parentId) { + return $siblingCandidate; + } + + $parent = $this->getContentGraphAdapter()->findParentNodeInSubgraph($contentStreamId, $workspaceName, $coveredDimensionSpacePoint, $siblingId); + if (is_null($parent)) { + throw new \InvalidArgumentException( + 'Parent ' . $parentId->value . ' not found in subgraph ' . json_encode($contentSubgraph), + 1645366837 + ); + } + if ($parent->nodeAggregateId->equals($parentId)) { return $siblingCandidate; } @@ -266,21 +264,20 @@ private function resolveSucceedingSiblingFromOriginSiblings( ?NodeAggregateId $parentId, ?NodeAggregateId $precedingSiblingId, ?NodeAggregateId $succeedingSiblingId, - ContentSubgraphInterface $currentContentSubgraph, - ContentSubgraphInterface $originContentSubgraph + ContentStreamId $contentStreamId, + WorkspaceName $workspaceName, + DimensionSpace\DimensionSpacePoint $currentDimensionSpacePoint, + DimensionSpace\DimensionSpacePoint $originDimensionSpacePoint ): ?Node { $succeedingSibling = null; $precedingSiblingCandidates = iterator_to_array( $precedingSiblingId - ? $originContentSubgraph->findPrecedingSiblingNodes($precedingSiblingId, FindPrecedingSiblingNodesFilter::create()) + ? $this->getContentGraphAdapter()->findPreceedingSiblingNodesInSubgraph($contentStreamId, $workspaceName, $originDimensionSpacePoint, $precedingSiblingId) : Nodes::createEmpty() ); $succeedingSiblingCandidates = iterator_to_array( $succeedingSiblingId - ? $originContentSubgraph->findSucceedingSiblingNodes( - $succeedingSiblingId, - FindSucceedingSiblingNodesFilter::create() - ) + ? $this->getContentGraphAdapter()->findSuceedingSiblingNodesInSubgraph($contentStreamId, $workspaceName, $originDimensionSpacePoint, $succeedingSiblingId) : Nodes::createEmpty() ); /* @var $precedingSiblingCandidates Node[] */ @@ -292,10 +289,12 @@ private function resolveSucceedingSiblingFromOriginSiblings( if ($succeedingSiblingCandidates[$i]->nodeAggregateId->equals($nodeAggregateId)) { \array_splice($succeedingSiblingCandidates, $i, 1); } - $succeedingSibling = $this->findSibling( - $currentContentSubgraph, - $parentId, - $succeedingSiblingCandidates[$i]->nodeAggregateId + $succeedingSibling = $this->findSiblingWithin( + $contentStreamId, + $workspaceName, + $currentDimensionSpacePoint, + $succeedingSiblingCandidates[$i]->nodeAggregateId, + $parentId ); if ($succeedingSibling) { break; @@ -306,16 +305,16 @@ private function resolveSucceedingSiblingFromOriginSiblings( if ($precedingSiblingCandidates[$i]->nodeAggregateId->equals($nodeAggregateId)) { \array_splice($precedingSiblingCandidates, $i, 1); } - $precedingSibling = $this->findSibling( - $currentContentSubgraph, - $parentId, - $precedingSiblingCandidates[$i]->nodeAggregateId + $precedingSibling = $this->findSiblingWithin( + $contentStreamId, + $workspaceName, + $currentDimensionSpacePoint, + $precedingSiblingCandidates[$i]->nodeAggregateId, + $parentId ); if ($precedingSibling) { - $alternateSucceedingSiblings = $currentContentSubgraph->findSucceedingSiblingNodes( - $precedingSiblingId, - FindSucceedingSiblingNodesFilter::create(pagination: Pagination::fromLimitAndOffset(1, 0)), - ); + // TODO: I don't think implementing the same filtering as for the contentGraph is sensible here, so we are fetching all siblings while only interested in the next, maybe could become a more specialised method. + $alternateSucceedingSiblings = $this->getContentGraphAdapter()->findSuceedingSiblingNodesInSubgraph($contentStreamId, $workspaceName, $currentDimensionSpacePoint, $precedingSiblingId); if (count($alternateSucceedingSiblings) > 0) { $succeedingSibling = $alternateSucceedingSiblings->first(); break; @@ -341,39 +340,29 @@ private function resolveCoverageNodeMoveMappings( /** A dimension space point occupied by the node aggregate to be moved */ OriginDimensionSpacePoint $originDimensionSpacePoint, /** The dimension space points affected by the move operation */ - DimensionSpacePointSet $affectedDimensionSpacePoints, - ContentRepository $contentRepository + DimensionSpacePointSet $affectedDimensionSpacePoints ): CoverageNodeMoveMappings { /** @var CoverageNodeMoveMapping[] $coverageNodeMoveMappings */ $coverageNodeMoveMappings = []; + $workspace = $this->getContentGraphAdapter()->findWorkspaceByCurrentContentStreamId($contentStreamId); - $visibilityConstraints = VisibilityConstraints::withoutRestrictions(); - $originContentSubgraph = $contentRepository->getContentGraph()->getSubgraph( - $contentStreamId, - $originDimensionSpacePoint->toDimensionSpacePoint(), - $visibilityConstraints - ); foreach ( $nodeAggregate->getCoverageByOccupant($originDimensionSpacePoint) ->getIntersection($affectedDimensionSpacePoints) as $dimensionSpacePoint ) { - $contentSubgraph = $contentRepository->getContentGraph()->getSubgraph( - $contentStreamId, - $dimensionSpacePoint, - $visibilityConstraints - ); - $succeedingSibling = $succeedingSiblingId - ? $this->findSibling($contentSubgraph, $parentId, $succeedingSiblingId) + ? $this->findSiblingWithin($contentStreamId, $workspace?->workspaceName, $originDimensionSpacePoint->toDimensionSpacePoint(), $succeedingSiblingId, $parentId) : null; if (!$succeedingSibling) { $precedingSibling = $precedingSiblingId - ? $this->findSibling($contentSubgraph, $parentId, $precedingSiblingId) + ? $this->findSiblingWithin($contentStreamId, $workspace?->workspaceName, $originDimensionSpacePoint->toDimensionSpacePoint(), $precedingSiblingId, $parentId) : null; if ($precedingSiblingId && $precedingSibling) { - $alternateSucceedingSiblings = $contentSubgraph->findSucceedingSiblingNodes( - $precedingSiblingId, - FindSucceedingSiblingNodesFilter::create(pagination: Pagination::fromLimitAndOffset(1, 0)), + $alternateSucceedingSiblings = $this->getContentGraphAdapter()->findSuceedingSiblingNodesInSubgraph( + $contentStreamId, + $workspace?->workspaceName, + $dimensionSpacePoint, + $precedingSiblingId ); if (count($alternateSucceedingSiblings) > 0) { $succeedingSibling = $alternateSucceedingSiblings->first(); @@ -384,19 +373,20 @@ private function resolveCoverageNodeMoveMappings( $parentId, $precedingSiblingId, $succeedingSiblingId, - $contentSubgraph, - $originContentSubgraph + $contentStreamId, + $workspace?->workspaceName, + $dimensionSpacePoint, + $originDimensionSpacePoint->toDimensionSpacePoint() ); } } if ($succeedingSibling) { // for the event payload, we additionally need the parent of the succeeding sibling - $parentOfSucceedingSibling = $contentSubgraph->findParentNode($succeedingSibling->nodeAggregateId); + $parentOfSucceedingSibling = $this->getContentGraphAdapter()->findParentNodeInSubgraph($contentStreamId, $workspace?->workspaceName, $dimensionSpacePoint, $succeedingSibling->nodeAggregateId); if ($parentOfSucceedingSibling === null) { throw new \InvalidArgumentException( - 'Parent of succeeding sibling ' . $succeedingSibling->nodeAggregateId->value - . ' not found in subgraph ' . json_encode($contentSubgraph), + sprintf('Parent of succeeding sibling ' . $succeedingSibling->nodeAggregateId->value . ' not found in contentstream "%s" and dimension space point "%s" ', $contentStreamId->value, json_encode($dimensionSpacePoint)), 1667817639 ); } @@ -417,10 +407,10 @@ private function resolveCoverageNodeMoveMappings( if ($parentId === null) { // if parent ID is not given, use the parent of the original node, because we want to move // to the end of the sibling list. - $parentId = $contentSubgraph->findParentNode($nodeAggregate->nodeAggregateId)?->nodeAggregateId; + $parentId = $this->getContentGraphAdapter()->findParentNodeInSubgraph($contentStreamId, $workspace?->workspaceName, $dimensionSpacePoint, $nodeAggregate->nodeAggregateId)?->nodeAggregateId; if ($parentId === null) { throw new \InvalidArgumentException( - 'Parent ' . $parentId . ' not found in subgraph ' . json_encode($contentSubgraph), + sprintf('Parent ' . $parentId . ' not found in contentstream "%s" and dimension space point "%s" ', $contentStreamId->value, json_encode($dimensionSpacePoint)), 1667597013 ); } @@ -428,8 +418,7 @@ private function resolveCoverageNodeMoveMappings( $coverageNodeMoveMappings[] = $this->resolveNewParentAssignments( $contentStreamId, $parentId, - $dimensionSpacePoint, - $contentRepository + $dimensionSpacePoint ); } } diff --git a/Neos.ContentRepository.Core/Classes/Feature/NodeReferencing/NodeReferencing.php b/Neos.ContentRepository.Core/Classes/Feature/NodeReferencing/NodeReferencing.php index 7e82df8ef55..ae91a4b24a7 100644 --- a/Neos.ContentRepository.Core/Classes/Feature/NodeReferencing/NodeReferencing.php +++ b/Neos.ContentRepository.Core/Classes/Feature/NodeReferencing/NodeReferencing.php @@ -14,7 +14,6 @@ namespace Neos\ContentRepository\Core\Feature\NodeReferencing; -use Neos\ContentRepository\Core\ContentRepository; use Neos\ContentRepository\Core\EventStore\Events; use Neos\ContentRepository\Core\EventStore\EventsToPublish; use Neos\ContentRepository\Core\Feature\Common\ConstraintChecks; @@ -39,21 +38,18 @@ trait NodeReferencing abstract protected function requireProjectedNodeAggregate( ContentStreamId $contentStreamId, - NodeAggregateId $nodeAggregateId, - ContentRepository $contentRepository + NodeAggregateId $nodeAggregateId ): NodeAggregate; private function handleSetNodeReferences( - SetNodeReferences $command, - ContentRepository $contentRepository + SetNodeReferences $command ): EventsToPublish { - $contentStreamId = $this->requireContentStream($command->workspaceName, $contentRepository); + $contentStreamId = $this->requireContentStream($command->workspaceName); $this->requireDimensionSpacePointToExist($command->sourceOriginDimensionSpacePoint->toDimensionSpacePoint()); $sourceNodeAggregate = $this->requireProjectedNodeAggregate( $contentStreamId, - $command->sourceNodeAggregateId, - $contentRepository + $command->sourceNodeAggregateId ); $this->requireNodeAggregateToNotBeRoot($sourceNodeAggregate); $nodeTypeName = $sourceNodeAggregate->nodeTypeName; @@ -88,25 +84,23 @@ private function handleSetNodeReferences( )), ); - return $this->handleSetSerializedNodeReferences($lowLevelCommand, $contentRepository); + return $this->handleSetSerializedNodeReferences($lowLevelCommand); } /** * @throws \Neos\ContentRepository\Core\SharedModel\Exception\ContentStreamDoesNotExistYet */ private function handleSetSerializedNodeReferences( - SetSerializedNodeReferences $command, - ContentRepository $contentRepository + SetSerializedNodeReferences $command ): EventsToPublish { - $contentStreamId = $this->requireContentStream($command->workspaceName, $contentRepository); - $expectedVersion = $this->getExpectedVersionOfContentStream($contentStreamId, $contentRepository); + $contentStreamId = $this->requireContentStream($command->workspaceName); + $expectedVersion = $this->getExpectedVersionOfContentStream($contentStreamId); $this->requireDimensionSpacePointToExist( $command->sourceOriginDimensionSpacePoint->toDimensionSpacePoint() ); $sourceNodeAggregate = $this->requireProjectedNodeAggregate( $contentStreamId, - $command->sourceNodeAggregateId, - $contentRepository + $command->sourceNodeAggregateId ); $this->requireNodeAggregateToNotBeRoot($sourceNodeAggregate); $this->requireNodeAggregateToOccupyDimensionSpacePoint( @@ -119,8 +113,7 @@ private function handleSetSerializedNodeReferences( assert($reference instanceof SerializedNodeReference); $destinationNodeAggregate = $this->requireProjectedNodeAggregate( $contentStreamId, - $reference->targetNodeAggregateId, - $contentRepository + $reference->targetNodeAggregateId ); $this->requireNodeAggregateToNotBeRoot($destinationNodeAggregate); $this->requireNodeAggregateToCoverDimensionSpacePoint( diff --git a/Neos.ContentRepository.Core/Classes/Feature/NodeRemoval/NodeRemoval.php b/Neos.ContentRepository.Core/Classes/Feature/NodeRemoval/NodeRemoval.php index 446f7b58e45..dd3ce6db474 100644 --- a/Neos.ContentRepository.Core/Classes/Feature/NodeRemoval/NodeRemoval.php +++ b/Neos.ContentRepository.Core/Classes/Feature/NodeRemoval/NodeRemoval.php @@ -46,15 +46,13 @@ abstract protected function areAncestorNodeTypeConstraintChecksEnabled(): bool; * @throws DimensionSpacePointNotFound */ private function handleRemoveNodeAggregate( - RemoveNodeAggregate $command, - ContentRepository $contentRepository + RemoveNodeAggregate $command ): EventsToPublish { - $contentStreamId = $this->requireContentStream($command->workspaceName, $contentRepository); - $expectedVersion = $this->getExpectedVersionOfContentStream($contentStreamId, $contentRepository); + $contentStreamId = $this->requireContentStream($command->workspaceName); + $expectedVersion = $this->getExpectedVersionOfContentStream($contentStreamId); $nodeAggregate = $this->requireProjectedNodeAggregate( $contentStreamId, - $command->nodeAggregateId, - $contentRepository + $command->nodeAggregateId ); $this->requireDimensionSpacePointToExist($command->coveredDimensionSpacePoint); $this->requireNodeAggregateNotToBeTethered($nodeAggregate); @@ -65,8 +63,7 @@ private function handleRemoveNodeAggregate( if ($command->removalAttachmentPoint instanceof NodeAggregateId) { $this->requireProjectedNodeAggregate( $contentStreamId, - $command->removalAttachmentPoint, - $contentRepository + $command->removalAttachmentPoint ); } diff --git a/Neos.ContentRepository.Core/Classes/Feature/NodeRenaming/NodeRenaming.php b/Neos.ContentRepository.Core/Classes/Feature/NodeRenaming/NodeRenaming.php index 40403f523ba..7f3fb7f3797 100644 --- a/Neos.ContentRepository.Core/Classes/Feature/NodeRenaming/NodeRenaming.php +++ b/Neos.ContentRepository.Core/Classes/Feature/NodeRenaming/NodeRenaming.php @@ -30,26 +30,24 @@ trait NodeRenaming { use ConstraintChecks; - private function handleChangeNodeAggregateName(ChangeNodeAggregateName $command, ContentRepository $contentRepository): EventsToPublish + private function handleChangeNodeAggregateName(ChangeNodeAggregateName $command): EventsToPublish { - $contentStreamId = $this->requireContentStream($command->workspaceName, $contentRepository); - $expectedVersion = $this->getExpectedVersionOfContentStream($contentStreamId, $contentRepository); + $contentStreamId = $this->requireContentStream($command->workspaceName); + $expectedVersion = $this->getExpectedVersionOfContentStream($contentStreamId); $nodeAggregate = $this->requireProjectedNodeAggregate( $contentStreamId, - $command->nodeAggregateId, - $contentRepository + $command->nodeAggregateId ); $this->requireNodeAggregateToNotBeRoot($nodeAggregate, 'and Root Node Aggregates cannot be renamed'); $this->requireNodeAggregateToBeUntethered($nodeAggregate); - foreach ($contentRepository->getContentGraph()->findParentNodeAggregates($contentStreamId, $command->nodeAggregateId) as $parentNodeAggregate) { + foreach ($this->getContentGraphAdapter()->findParentNodeAggregates($contentStreamId, $command->workspaceName, $command->nodeAggregateId) as $parentNodeAggregate) { foreach ($parentNodeAggregate->occupiedDimensionSpacePoints as $occupiedParentDimensionSpacePoint) { $this->requireNodeNameToBeUnoccupied( $contentStreamId, $command->newNodeName, $parentNodeAggregate->nodeAggregateId, $occupiedParentDimensionSpacePoint, - $parentNodeAggregate->coveredDimensionSpacePoints, - $contentRepository + $parentNodeAggregate->coveredDimensionSpacePoints ); } } diff --git a/Neos.ContentRepository.Core/Classes/Feature/NodeTypeChange/NodeTypeChange.php b/Neos.ContentRepository.Core/Classes/Feature/NodeTypeChange/NodeTypeChange.php index 25e60f27449..a38d780b880 100644 --- a/Neos.ContentRepository.Core/Classes/Feature/NodeTypeChange/NodeTypeChange.php +++ b/Neos.ContentRepository.Core/Classes/Feature/NodeTypeChange/NodeTypeChange.php @@ -52,16 +52,14 @@ abstract protected function getNodeTypeManager(): NodeTypeManager; abstract protected function requireProjectedNodeAggregate( ContentStreamId $contentStreamId, - NodeAggregateId $nodeAggregateId, - ContentRepository $contentRepository + NodeAggregateId $nodeAggregateId ): NodeAggregate; abstract protected function requireConstraintsImposedByAncestorsAreMet( ContentStreamId $contentStreamId, NodeType $nodeType, ?NodeName $nodeName, - array $parentNodeAggregateIds, - ContentRepository $contentRepository + array $parentNodeAggregateIds ): void; abstract protected function requireNodeTypeConstraintsImposedByParentToBeMet( @@ -93,8 +91,7 @@ abstract protected function createEventsForMissingTetheredNode( OriginDimensionSpacePoint $originDimensionSpacePoint, NodeName $tetheredNodeName, NodeAggregateId $tetheredNodeAggregateId, - NodeType $expectedTetheredNodeType, - ContentRepository $contentRepository + NodeType $expectedTetheredNodeType ): Events; /** @@ -104,20 +101,18 @@ abstract protected function createEventsForMissingTetheredNode( * @throws NodeAggregatesTypeIsAmbiguous */ private function handleChangeNodeAggregateType( - ChangeNodeAggregateType $command, - ContentRepository $contentRepository + ChangeNodeAggregateType $command ): EventsToPublish { /************** * Constraint checks **************/ // existence of content stream, node type and node aggregate - $contentStreamId = $this->requireContentStream($command->workspaceName, $contentRepository); - $expectedVersion = $this->getExpectedVersionOfContentStream($contentStreamId, $contentRepository); + $contentStreamId = $this->requireContentStream($command->workspaceName); + $expectedVersion = $this->getExpectedVersionOfContentStream($contentStreamId); $newNodeType = $this->requireNodeType($command->newNodeTypeName); $nodeAggregate = $this->requireProjectedNodeAggregate( $contentStreamId, - $command->nodeAggregateId, - $contentRepository + $command->nodeAggregateId ); // node type detail checks @@ -125,9 +120,11 @@ private function handleChangeNodeAggregateType( $this->requireTetheredDescendantNodeTypesToExist($newNodeType); $this->requireTetheredDescendantNodeTypesToNotBeOfTypeRoot($newNodeType); + $workspace = $this->getContentGraphAdapter()->findWorkspaceByCurrentContentStreamId($nodeAggregate->contentStreamId); // the new node type must be allowed at this position in the tree - $parentNodeAggregates = $contentRepository->getContentGraph()->findParentNodeAggregates( + $parentNodeAggregates = $this->getContentGraphAdapter()->findParentNodeAggregates( $nodeAggregate->contentStreamId, + $workspace?->workspaceName, $nodeAggregate->nodeAggregateId ); foreach ($parentNodeAggregates as $parentNodeAggregate) { @@ -136,15 +133,14 @@ private function handleChangeNodeAggregateType( $contentStreamId, $newNodeType, $nodeAggregate->nodeName, - [$parentNodeAggregate->nodeAggregateId], - $contentRepository + [$parentNodeAggregate->nodeAggregateId] ); } /** @codingStandardsIgnoreStart */ match ($command->strategy) { NodeAggregateTypeChangeChildConstraintConflictResolutionStrategy::STRATEGY_HAPPY_PATH - => $this->requireConstraintsImposedByHappyPathStrategyAreMet($nodeAggregate, $newNodeType, $contentRepository), + => $this->requireConstraintsImposedByHappyPathStrategyAreMet($nodeAggregate, $newNodeType), NodeAggregateTypeChangeChildConstraintConflictResolutionStrategy::STRATEGY_DELETE => null }; /** @codingStandardsIgnoreStop */ @@ -175,13 +171,11 @@ private function handleChangeNodeAggregateType( if ($command->strategy === NodeAggregateTypeChangeChildConstraintConflictResolutionStrategy::STRATEGY_DELETE) { array_push($events, ...iterator_to_array($this->deleteDisallowedNodesWhenChangingNodeType( $nodeAggregate, - $newNodeType, - $contentRepository + $newNodeType ))); array_push($events, ...iterator_to_array($this->deleteObsoleteTetheredNodesWhenChangingNodeType( $nodeAggregate, - $newNodeType, - $contentRepository + $newNodeType ))); } @@ -189,18 +183,19 @@ private function handleChangeNodeAggregateType( $expectedTetheredNodes = $this->getNodeTypeManager()->getTetheredNodesConfigurationForNodeType($newNodeType); foreach ($nodeAggregate->getNodes() as $node) { assert($node instanceof Node); + $workspace = $this->getContentGraphAdapter()->findWorkspaceByCurrentContentStreamId($node->subgraphIdentity->contentStreamId); + foreach ($expectedTetheredNodes as $serializedTetheredNodeName => $expectedTetheredNodeType) { $tetheredNodeName = NodeName::fromString($serializedTetheredNodeName); - $subgraph = $contentRepository->getContentGraph()->getSubgraph( + $tetheredNode = $this->getContentGraphAdapter()->findChildNodeByNameInSubgraph( $node->subgraphIdentity->contentStreamId, + $workspace?->workspaceName, $node->originDimensionSpacePoint->toDimensionSpacePoint(), - VisibilityConstraints::withoutRestrictions() - ); - $tetheredNode = $subgraph->findNodeByPath( - $tetheredNodeName, - $node->nodeAggregateId + $node->nodeAggregateId, + $tetheredNodeName ); + if ($tetheredNode === null) { $tetheredNodeAggregateId = $command->tetheredDescendantNodeAggregateIds ->getNodeAggregateId(NodePath::fromString($tetheredNodeName->value)) @@ -210,8 +205,7 @@ private function handleChangeNodeAggregateType( $node->originDimensionSpacePoint, $tetheredNodeName, $tetheredNodeAggregateId, - $expectedTetheredNodeType, - $contentRepository + $expectedTetheredNodeType ))); } } @@ -235,13 +229,16 @@ private function handleChangeNodeAggregateType( */ private function requireConstraintsImposedByHappyPathStrategyAreMet( NodeAggregate $nodeAggregate, - NodeType $newNodeType, - ContentRepository $contentRepository + NodeType $newNodeType ): void { + // TODO: Use workspaceName from $nodeAggregate + $workspace = $this->getContentGraphAdapter()->findWorkspaceByCurrentContentStreamId($nodeAggregate->contentStreamId); + // if we have children, we need to check whether they are still allowed // after we changed the node type of the $nodeAggregate to $newNodeType. - $childNodeAggregates = $contentRepository->getContentGraph()->findChildNodeAggregates( + $childNodeAggregates = $this->getContentGraphAdapter()->findChildNodeAggregates( $nodeAggregate->contentStreamId, + $workspace?->workspaceName, $nodeAggregate->nodeAggregateId ); foreach ($childNodeAggregates as $childNodeAggregate) { @@ -257,10 +254,13 @@ private function requireConstraintsImposedByHappyPathStrategyAreMet( // we do not need to test for grandparents here, as we did not modify the grandparents. // Thus, if it was allowed before, it is allowed now. + // TODO: use workspaceName from $childNodeAggregate instead + $workspace = $this->getContentGraphAdapter()->findWorkspaceByCurrentContentStreamId($childNodeAggregate->contentStreamId); // additionally, we need to look one level down to the grandchildren as well // - as it could happen that these are affected by our constraint checks as well. - $grandchildNodeAggregates = $contentRepository->getContentGraph()->findChildNodeAggregates( + $grandchildNodeAggregates = $this->getContentGraphAdapter()->findChildNodeAggregates( $childNodeAggregate->contentStreamId, + $workspace?->workspaceName, $childNodeAggregate->nodeAggregateId ); foreach ($grandchildNodeAggregates as $grandchildNodeAggregate) { @@ -283,14 +283,18 @@ private function requireConstraintsImposedByHappyPathStrategyAreMet( */ private function deleteDisallowedNodesWhenChangingNodeType( NodeAggregate $nodeAggregate, - NodeType $newNodeType, - ContentRepository $contentRepository + NodeType $newNodeType ): Events { $events = []; + + // TODO: use workspaceName from $childNodeAggregate instead + $workspace = $this->getContentGraphAdapter()->findWorkspaceByCurrentContentStreamId($nodeAggregate->contentStreamId); + // if we have children, we need to check whether they are still allowed // after we changed the node type of the $nodeAggregate to $newNodeType. - $childNodeAggregates = $contentRepository->getContentGraph()->findChildNodeAggregates( + $childNodeAggregates = $this->getContentGraphAdapter()->findChildNodeAggregates( $nodeAggregate->contentStreamId, + $workspace?->workspaceName, $nodeAggregate->nodeAggregateId ); foreach ($childNodeAggregates as $childNodeAggregate) { @@ -309,8 +313,7 @@ private function deleteDisallowedNodesWhenChangingNodeType( // We now need to find out which edges we need to remove, $dimensionSpacePointsToBeRemoved = $this->findDimensionSpacePointsConnectingParentAndChildAggregate( $nodeAggregate, - $childNodeAggregate, - $contentRepository + $childNodeAggregate ); // AND REMOVE THEM $events[] = $this->removeNodeInDimensionSpacePointSet( @@ -322,10 +325,14 @@ private function deleteDisallowedNodesWhenChangingNodeType( // we do not need to test for grandparents here, as we did not modify the grandparents. // Thus, if it was allowed before, it is allowed now. + // TODO: use workspaceName from $childNodeAggregate instead + $workspace = $this->getContentGraphAdapter()->findWorkspaceByCurrentContentStreamId($childNodeAggregate->contentStreamId); + // additionally, we need to look one level down to the grandchildren as well // - as it could happen that these are affected by our constraint checks as well. - $grandchildNodeAggregates = $contentRepository->getContentGraph()->findChildNodeAggregates( + $grandchildNodeAggregates = $this->getContentGraphAdapter()->findChildNodeAggregates( $childNodeAggregate->contentStreamId, + $workspace?->workspaceName, $childNodeAggregate->nodeAggregateId ); foreach ($grandchildNodeAggregates as $grandchildNodeAggregate) { @@ -345,8 +352,7 @@ private function deleteDisallowedNodesWhenChangingNodeType( // We now need to find out which edges we need to remove, $dimensionSpacePointsToBeRemoved = $this->findDimensionSpacePointsConnectingParentAndChildAggregate( $childNodeAggregate, - $grandchildNodeAggregate, - $contentRepository + $grandchildNodeAggregate ); // AND REMOVE THEM $events[] = $this->removeNodeInDimensionSpacePointSet( @@ -362,15 +368,16 @@ private function deleteDisallowedNodesWhenChangingNodeType( private function deleteObsoleteTetheredNodesWhenChangingNodeType( NodeAggregate $nodeAggregate, - NodeType $newNodeType, - ContentRepository $contentRepository + NodeType $newNodeType ): Events { $expectedTetheredNodes = $this->getNodeTypeManager()->getTetheredNodesConfigurationForNodeType($newNodeType); $events = []; // find disallowed tethered nodes - $tetheredNodeAggregates = $contentRepository->getContentGraph()->findTetheredChildNodeAggregates( + $workspace = $this->getContentGraphAdapter()->findWorkspaceByCurrentContentStreamId($nodeAggregate->contentStreamId); + $tetheredNodeAggregates = $this->getContentGraphAdapter()->findTetheredChildNodeAggregates( $nodeAggregate->contentStreamId, + $workspace?->workspaceName, $nodeAggregate->nodeAggregateId ); @@ -381,8 +388,7 @@ private function deleteObsoleteTetheredNodesWhenChangingNodeType( // We now need to find out which edges we need to remove, $dimensionSpacePointsToBeRemoved = $this->findDimensionSpacePointsConnectingParentAndChildAggregate( $nodeAggregate, - $tetheredNodeAggregate, - $contentRepository + $tetheredNodeAggregate ); // AND REMOVE THEM $events[] = $this->removeNodeInDimensionSpacePointSet( @@ -420,17 +426,18 @@ private function deleteObsoleteTetheredNodesWhenChangingNodeType( */ private function findDimensionSpacePointsConnectingParentAndChildAggregate( NodeAggregate $parentNodeAggregate, - NodeAggregate $childNodeAggregate, - ContentRepository $contentRepository + NodeAggregate $childNodeAggregate ): DimensionSpacePointSet { $points = []; foreach ($childNodeAggregate->coveredDimensionSpacePoints as $coveredDimensionSpacePoint) { - $subgraph = $contentRepository->getContentGraph()->getSubgraph( + // TODO: Use child node workspaceName here instead + $workspace = $this->getContentGraphAdapter()->findWorkspaceByCurrentContentStreamId($childNodeAggregate->contentStreamId); + $parentNode = $this->getContentGraphAdapter()->findParentNodeInSubgraph( $childNodeAggregate->contentStreamId, + $workspace?->workspaceName, $coveredDimensionSpacePoint, - VisibilityConstraints::withoutRestrictions() + $childNodeAggregate->nodeAggregateId ); - $parentNode = $subgraph->findParentNode($childNodeAggregate->nodeAggregateId); if ( $parentNode && $parentNode->nodeAggregateId->equals($parentNodeAggregate->nodeAggregateId) diff --git a/Neos.ContentRepository.Core/Classes/Feature/NodeVariation/NodeVariation.php b/Neos.ContentRepository.Core/Classes/Feature/NodeVariation/NodeVariation.php index 7df4a3acb5b..6c2aca49977 100644 --- a/Neos.ContentRepository.Core/Classes/Feature/NodeVariation/NodeVariation.php +++ b/Neos.ContentRepository.Core/Classes/Feature/NodeVariation/NodeVariation.php @@ -47,15 +47,13 @@ trait NodeVariation * @throws NodeAggregateDoesCurrentlyNotCoverDimensionSpacePoint */ private function handleCreateNodeVariant( - CreateNodeVariant $command, - ContentRepository $contentRepository + CreateNodeVariant $command ): EventsToPublish { - $contentStreamId = $this->requireContentStream($command->workspaceName, $contentRepository); - $expectedVersion = $this->getExpectedVersionOfContentStream($contentStreamId, $contentRepository); + $contentStreamId = $this->requireContentStream($command->workspaceName); + $expectedVersion = $this->getExpectedVersionOfContentStream($contentStreamId); $nodeAggregate = $this->requireProjectedNodeAggregate( $contentStreamId, - $command->nodeAggregateId, - $contentRepository + $command->nodeAggregateId ); // we do this check first, because it gives a more meaningful error message on what you need to do. // we cannot use sentences with "." because the UI will only print the 1st sentence :/ @@ -68,8 +66,7 @@ private function handleCreateNodeVariant( $parentNodeAggregate = $this->requireProjectedParentNodeAggregate( $contentStreamId, $command->nodeAggregateId, - $command->sourceOrigin, - $contentRepository + $command->sourceOrigin ); $this->requireNodeAggregateToCoverDimensionSpacePoint( $parentNodeAggregate, @@ -80,8 +77,7 @@ private function handleCreateNodeVariant( $contentStreamId, $command->sourceOrigin, $command->targetOrigin, - $nodeAggregate, - $contentRepository + $nodeAggregate ); return new EventsToPublish( diff --git a/Neos.ContentRepository.Core/Classes/Feature/RootNodeCreation/RootNodeHandling.php b/Neos.ContentRepository.Core/Classes/Feature/RootNodeCreation/RootNodeHandling.php index 0fb102fe6ef..601484ed066 100644 --- a/Neos.ContentRepository.Core/Classes/Feature/RootNodeCreation/RootNodeHandling.php +++ b/Neos.ContentRepository.Core/Classes/Feature/RootNodeCreation/RootNodeHandling.php @@ -67,23 +67,20 @@ abstract protected function requireNodeTypeToBeOfTypeRoot(NodeType $nodeType): v * @throws NodeTypeIsNotOfTypeRoot */ private function handleCreateRootNodeAggregateWithNode( - CreateRootNodeAggregateWithNode $command, - ContentRepository $contentRepository + CreateRootNodeAggregateWithNode $command ): EventsToPublish { - $contentStreamId = $this->requireContentStream($command->workspaceName, $contentRepository); - $expectedVersion = $this->getExpectedVersionOfContentStream($contentStreamId, $contentRepository); + $contentStreamId = $this->requireContentStream($command->workspaceName); + $expectedVersion = $this->getExpectedVersionOfContentStream($contentStreamId); $this->requireProjectedNodeAggregateToNotExist( $contentStreamId, - $command->nodeAggregateId, - $contentRepository + $command->nodeAggregateId ); $nodeType = $this->requireNodeType($command->nodeTypeName); $this->requireNodeTypeToNotBeAbstract($nodeType); $this->requireNodeTypeToBeOfTypeRoot($nodeType); $this->requireRootNodeTypeToBeUnoccupied( $nodeType->name, - $contentStreamId, - $contentRepository + $contentStreamId ); $descendantNodeAggregateIds = $command->tetheredDescendantNodeAggregateIds->completeForNodeOfType( @@ -110,8 +107,7 @@ private function handleCreateRootNodeAggregateWithNode( $this->getInterDimensionalVariationGraph()->getSpecializationSet($rootGeneralization, true), $command->nodeAggregateId, $command->tetheredDescendantNodeAggregateIds, - null, - $contentRepository + null ))); } @@ -145,15 +141,13 @@ private function createRootWithNode( * @return EventsToPublish */ private function handleUpdateRootNodeAggregateDimensions( - UpdateRootNodeAggregateDimensions $command, - ContentRepository $contentRepository + UpdateRootNodeAggregateDimensions $command ): EventsToPublish { - $contentStreamId = $this->requireContentStream($command->workspaceName, $contentRepository); - $expectedVersion = $this->getExpectedVersionOfContentStream($contentStreamId, $contentRepository); + $contentStreamId = $this->requireContentStream($command->workspaceName); + $expectedVersion = $this->getExpectedVersionOfContentStream($contentStreamId); $nodeAggregate = $this->requireProjectedNodeAggregate( $contentStreamId, - $command->nodeAggregateId, - $contentRepository + $command->nodeAggregateId ); if (!$nodeAggregate->classification->isRoot()) { throw new NodeAggregateIsNotRoot('The node aggregate ' . $nodeAggregate->nodeAggregateId->value . ' is not classified as root, but should be for command UpdateRootNodeAggregateDimensions.', 1678647355); @@ -191,8 +185,7 @@ private function handleTetheredRootChildNodes( DimensionSpacePointSet $coveredDimensionSpacePoints, NodeAggregateId $parentNodeAggregateId, NodeAggregateIdsByNodePaths $nodeAggregateIdsByNodePath, - ?NodePath $nodePath, - ContentRepository $contentRepository, + ?NodePath $nodePath ): Events { $events = []; foreach ($this->getNodeTypeManager()->getTetheredNodesConfigurationForNodeType($nodeType) as $rawNodeName => $childNodeType) { @@ -223,8 +216,7 @@ private function handleTetheredRootChildNodes( $coveredDimensionSpacePoints, $childNodeAggregateId, $nodeAggregateIdsByNodePath, - $childNodePath, - $contentRepository + $childNodePath ))); } diff --git a/Neos.ContentRepository.Core/Classes/Feature/SubtreeTagging/SubtreeTagging.php b/Neos.ContentRepository.Core/Classes/Feature/SubtreeTagging/SubtreeTagging.php index 05f3c58248e..11007da966e 100644 --- a/Neos.ContentRepository.Core/Classes/Feature/SubtreeTagging/SubtreeTagging.php +++ b/Neos.ContentRepository.Core/Classes/Feature/SubtreeTagging/SubtreeTagging.php @@ -36,11 +36,11 @@ trait SubtreeTagging abstract protected function getInterDimensionalVariationGraph(): DimensionSpace\InterDimensionalVariationGraph; - private function handleTagSubtree(TagSubtree $command, ContentRepository $contentRepository): EventsToPublish + private function handleTagSubtree(TagSubtree $command): EventsToPublish { - $contentStreamId = $this->requireContentStream($command->workspaceName, $contentRepository); + $contentStreamId = $this->requireContentStream($command->workspaceName); $this->requireDimensionSpacePointToExist($command->coveredDimensionSpacePoint); - $nodeAggregate = $this->requireProjectedNodeAggregate($contentStreamId, $command->nodeAggregateId, $contentRepository); + $nodeAggregate = $this->requireProjectedNodeAggregate($contentStreamId, $command->nodeAggregateId); $this->requireNodeAggregateToCoverDimensionSpacePoint( $nodeAggregate, $command->coveredDimensionSpacePoint @@ -78,14 +78,13 @@ private function handleTagSubtree(TagSubtree $command, ContentRepository $conten ); } - public function handleUntagSubtree(UntagSubtree $command, ContentRepository $contentRepository): EventsToPublish + public function handleUntagSubtree(UntagSubtree $command): EventsToPublish { - $contentStreamId = $this->requireContentStream($command->workspaceName, $contentRepository); + $contentStreamId = $this->requireContentStream($command->workspaceName); $this->requireDimensionSpacePointToExist($command->coveredDimensionSpacePoint); $nodeAggregate = $this->requireProjectedNodeAggregate( $contentStreamId, - $command->nodeAggregateId, - $contentRepository + $command->nodeAggregateId ); $this->requireNodeAggregateToCoverDimensionSpacePoint( $nodeAggregate, diff --git a/Neos.ContentRepository.Core/Classes/Feature/WorkspaceCommandHandler.php b/Neos.ContentRepository.Core/Classes/Feature/WorkspaceCommandHandler.php index 34ce2ade5ff..e922dd04c01 100644 --- a/Neos.ContentRepository.Core/Classes/Feature/WorkspaceCommandHandler.php +++ b/Neos.ContentRepository.Core/Classes/Feature/WorkspaceCommandHandler.php @@ -88,6 +88,7 @@ public function __construct( private EventPersister $eventPersister, private EventStoreInterface $eventStore, private EventNormalizer $eventNormalizer, + private ContentGraphAdapterInterface $contentGraphAdapter ) { } @@ -101,7 +102,7 @@ public function handle(CommandInterface $command, ContentRepository $contentRepo /** @phpstan-ignore-next-line */ return match ($command::class) { CreateWorkspace::class => $this->handleCreateWorkspace($command, $contentRepository), - RenameWorkspace::class => $this->handleRenameWorkspace($command, $contentRepository), + RenameWorkspace::class => $this->handleRenameWorkspace($command), CreateRootWorkspace::class => $this->handleCreateRootWorkspace($command, $contentRepository), PublishWorkspace::class => $this->handlePublishWorkspace($command, $contentRepository), RebaseWorkspace::class => $this->handleRebaseWorkspace($command, $contentRepository), @@ -109,7 +110,7 @@ public function handle(CommandInterface $command, ContentRepository $contentRepo DiscardIndividualNodesFromWorkspace::class => $this->handleDiscardIndividualNodesFromWorkspace($command, $contentRepository), DiscardWorkspace::class => $this->handleDiscardWorkspace($command, $contentRepository), DeleteWorkspace::class => $this->handleDeleteWorkspace($command, $contentRepository), - ChangeWorkspaceOwner::class => $this->handleChangeWorkspaceOwner($command, $contentRepository), + ChangeWorkspaceOwner::class => $this->handleChangeWorkspaceOwner($command), ChangeBaseWorkspace::class => $this->handleChangeBaseWorkspace($command, $contentRepository), }; } @@ -124,7 +125,7 @@ private function handleCreateWorkspace( CreateWorkspace $command, ContentRepository $contentRepository, ): EventsToPublish { - $existingWorkspace = $contentRepository->getWorkspaceFinder()->findOneByName($command->workspaceName); + $existingWorkspace = $this->contentGraphAdapter->findWorkspaceByName($command->workspaceName); if ($existingWorkspace !== null) { throw new WorkspaceAlreadyExists(sprintf( 'The workspace %s already exists', @@ -132,7 +133,7 @@ private function handleCreateWorkspace( ), 1505830958921); } - $baseWorkspace = $contentRepository->getWorkspaceFinder()->findOneByName($command->baseWorkspaceName); + $baseWorkspace = $this->contentGraphAdapter->findWorkspaceByName($command->baseWorkspaceName); if ($baseWorkspace === null) { throw new BaseWorkspaceDoesNotExist(sprintf( 'The workspace %s (base workspace of %s) does not exist', @@ -170,9 +171,9 @@ private function handleCreateWorkspace( /** * @throws WorkspaceDoesNotExist */ - private function handleRenameWorkspace(RenameWorkspace $command, ContentRepository $contentRepository): EventsToPublish + private function handleRenameWorkspace(RenameWorkspace $command): EventsToPublish { - $this->requireWorkspace($command->workspaceName, $contentRepository); + $this->requireWorkspace($command->workspaceName); $events = Events::with( new WorkspaceWasRenamed( @@ -199,7 +200,7 @@ private function handleCreateRootWorkspace( CreateRootWorkspace $command, ContentRepository $contentRepository, ): EventsToPublish { - $existingWorkspace = $contentRepository->getWorkspaceFinder()->findOneByName($command->workspaceName); + $existingWorkspace = $this->contentGraphAdapter->findWorkspaceByName($command->workspaceName); if ($existingWorkspace !== null) { throw new WorkspaceAlreadyExists(sprintf( 'The workspace %s already exists', @@ -243,8 +244,8 @@ private function handlePublishWorkspace( PublishWorkspace $command, ContentRepository $contentRepository, ): EventsToPublish { - $workspace = $this->requireWorkspace($command->workspaceName, $contentRepository); - $baseWorkspace = $this->requireBaseWorkspace($workspace, $contentRepository); + $workspace = $this->requireWorkspace($command->workspaceName); + $baseWorkspace = $this->requireBaseWorkspace($workspace); $this->publishContentStream( $workspace->currentContentStreamId, @@ -357,8 +358,8 @@ private function handleRebaseWorkspace( RebaseWorkspace $command, ContentRepository $contentRepository, ): EventsToPublish { - $workspace = $this->requireWorkspace($command->workspaceName, $contentRepository); - $baseWorkspace = $this->requireBaseWorkspace($workspace, $contentRepository); + $workspace = $this->requireWorkspace($command->workspaceName); + $baseWorkspace = $this->requireBaseWorkspace($workspace); // 0) close old content stream $contentRepository->handle( @@ -486,13 +487,13 @@ private function handlePublishIndividualNodesFromWorkspace( PublishIndividualNodesFromWorkspace $command, ContentRepository $contentRepository, ): EventsToPublish { - $workspace = $this->requireWorkspace($command->workspaceName, $contentRepository); + $workspace = $this->requireWorkspace($command->workspaceName); $oldWorkspaceContentStreamId = $workspace->currentContentStreamId; - $oldWorkspaceContentStreamIdState = $contentRepository->getContentStreamFinder()->findStateForContentStream($oldWorkspaceContentStreamId); + $oldWorkspaceContentStreamIdState = $this->contentGraphAdapter->findStateForContentStream($oldWorkspaceContentStreamId); if ($oldWorkspaceContentStreamIdState === null) { throw new \DomainException('Cannot publish nodes on a workspace with a stateless content stream', 1710410114); } - $baseWorkspace = $this->requireBaseWorkspace($workspace, $contentRepository); + $baseWorkspace = $this->requireBaseWorkspace($workspace); // 1) close old content stream $contentRepository->handle( @@ -622,13 +623,13 @@ private function handleDiscardIndividualNodesFromWorkspace( DiscardIndividualNodesFromWorkspace $command, ContentRepository $contentRepository, ): EventsToPublish { - $workspace = $this->requireWorkspace($command->workspaceName, $contentRepository); + $workspace = $this->requireWorkspace($command->workspaceName); $oldWorkspaceContentStreamId = $workspace->currentContentStreamId; - $oldWorkspaceContentStreamIdState = $contentRepository->getContentStreamFinder()->findStateForContentStream($oldWorkspaceContentStreamId); + $oldWorkspaceContentStreamIdState = $this->contentGraphAdapter->findStateForContentStream($oldWorkspaceContentStreamId); if ($oldWorkspaceContentStreamIdState === null) { throw new \DomainException('Cannot discard nodes on a workspace with a stateless content stream', 1710408112); } - $baseWorkspace = $this->requireBaseWorkspace($workspace, $contentRepository); + $baseWorkspace = $this->requireBaseWorkspace($workspace); // 1) close old content stream $contentRepository->handle( @@ -765,8 +766,8 @@ private function handleDiscardWorkspace( DiscardWorkspace $command, ContentRepository $contentRepository, ): EventsToPublish { - $workspace = $this->requireWorkspace($command->workspaceName, $contentRepository); - $baseWorkspace = $this->requireBaseWorkspace($workspace, $contentRepository); + $workspace = $this->requireWorkspace($command->workspaceName); + $baseWorkspace = $this->requireBaseWorkspace($workspace); $newContentStream = $command->newContentStreamId; $contentRepository->handle( @@ -807,13 +808,13 @@ private function handleChangeBaseWorkspace( ChangeBaseWorkspace $command, ContentRepository $contentRepository, ): EventsToPublish { - $workspace = $this->requireWorkspace($command->workspaceName, $contentRepository); + $workspace = $this->requireWorkspace($command->workspaceName); $this->requireEmptyWorkspace($workspace); - $this->requireBaseWorkspace($workspace, $contentRepository); + $this->requireBaseWorkspace($workspace); - $baseWorkspace = $this->requireWorkspace($command->baseWorkspaceName, $contentRepository); + $baseWorkspace = $this->requireWorkspace($command->baseWorkspaceName); - $this->requireNonCircularRelationBetweenWorkspaces($workspace, $baseWorkspace, $contentRepository); + $this->requireNonCircularRelationBetweenWorkspaces($workspace, $baseWorkspace); $contentRepository->handle( ForkContentStream::create( @@ -845,7 +846,7 @@ private function handleDeleteWorkspace( DeleteWorkspace $command, ContentRepository $contentRepository, ): EventsToPublish { - $workspace = $this->requireWorkspace($command->workspaceName, $contentRepository); + $workspace = $this->requireWorkspace($command->workspaceName); $contentRepository->handle( RemoveContentStream::create( @@ -871,10 +872,9 @@ private function handleDeleteWorkspace( * @throws WorkspaceDoesNotExist */ private function handleChangeWorkspaceOwner( - ChangeWorkspaceOwner $command, - ContentRepository $contentRepository, + ChangeWorkspaceOwner $command ): EventsToPublish { - $this->requireWorkspace($command->workspaceName, $contentRepository); + $this->requireWorkspace($command->workspaceName); $events = Events::with( new WorkspaceOwnerWasChanged( @@ -894,9 +894,9 @@ private function handleChangeWorkspaceOwner( /** * @throws WorkspaceDoesNotExist */ - private function requireWorkspace(WorkspaceName $workspaceName, ContentRepository $contentRepository): Workspace + private function requireWorkspace(WorkspaceName $workspaceName): Workspace { - $workspace = $contentRepository->getWorkspaceFinder()->findOneByName($workspaceName); + $workspace = $this->contentGraphAdapter->findWorkspaceByName($workspaceName); if (is_null($workspace)) { throw WorkspaceDoesNotExist::butWasSupposedTo($workspaceName); } @@ -908,13 +908,13 @@ private function requireWorkspace(WorkspaceName $workspaceName, ContentRepositor * @throws WorkspaceHasNoBaseWorkspaceName * @throws BaseWorkspaceDoesNotExist */ - private function requireBaseWorkspace(Workspace $workspace, ContentRepository $contentRepository): Workspace + private function requireBaseWorkspace(Workspace $workspace): Workspace { if (is_null($workspace->baseWorkspaceName)) { throw WorkspaceHasNoBaseWorkspaceName::butWasSupposedTo($workspace->workspaceName); } - $baseWorkspace = $contentRepository->getWorkspaceFinder()->findOneByName($workspace->baseWorkspaceName); + $baseWorkspace = $this->contentGraphAdapter->findWorkspaceByName($workspace->baseWorkspaceName); if ($baseWorkspace === null) { throw BaseWorkspaceDoesNotExist::butWasSupposedTo($workspace->workspaceName); } @@ -926,7 +926,7 @@ private function requireBaseWorkspace(Workspace $workspace, ContentRepository $c * @throws BaseWorkspaceEqualsWorkspaceException * @throws CircularRelationBetweenWorkspacesException */ - private function requireNonCircularRelationBetweenWorkspaces(Workspace $workspace, Workspace $baseWorkspace, ContentRepository $contentRepository): void + private function requireNonCircularRelationBetweenWorkspaces(Workspace $workspace, Workspace $baseWorkspace): void { if ($workspace->workspaceName->equals($baseWorkspace->workspaceName)) { throw new BaseWorkspaceEqualsWorkspaceException(sprintf('The base workspace of the target must be different from the given workspace "%s".', $workspace->workspaceName->value)); @@ -937,7 +937,7 @@ private function requireNonCircularRelationBetweenWorkspaces(Workspace $workspac if ($workspace->workspaceName->equals($nextBaseWorkspace->baseWorkspaceName)) { throw new CircularRelationBetweenWorkspacesException(sprintf('The workspace "%s" is already on the path of the target workspace "%s".', $workspace->workspaceName->value, $baseWorkspace->workspaceName->value)); } - $nextBaseWorkspace = $contentRepository->getWorkspaceFinder()->findOneByName($nextBaseWorkspace->baseWorkspaceName); + $nextBaseWorkspace = $this->contentGraphAdapter->findWorkspaceByName($nextBaseWorkspace->baseWorkspaceName); } } diff --git a/Neos.ContentRepository.Core/Classes/Projection/ContentGraph/ContentGraphInterface.php b/Neos.ContentRepository.Core/Classes/Projection/ContentGraph/ContentGraphInterface.php index 4d8d7e4a4a7..bba5c64930e 100644 --- a/Neos.ContentRepository.Core/Classes/Projection/ContentGraph/ContentGraphInterface.php +++ b/Neos.ContentRepository.Core/Classes/Projection/ContentGraph/ContentGraphInterface.php @@ -94,66 +94,6 @@ public function findNodeAggregateById( */ public function findUsedNodeTypeNames(): iterable; - /** - * @internal only for consumption inside the Command Handler - */ - public function findParentNodeAggregateByChildOriginDimensionSpacePoint( - ContentStreamId $contentStreamId, - NodeAggregateId $childNodeAggregateId, - OriginDimensionSpacePoint $childOriginDimensionSpacePoint - ): ?NodeAggregate; - - /** - * @return iterable - * @internal only for consumption inside the Command Handler - */ - public function findParentNodeAggregates( - ContentStreamId $contentStreamId, - NodeAggregateId $childNodeAggregateId - ): iterable; - - /** - * @return iterable - * @internal only for consumption inside the Command Handler - */ - public function findChildNodeAggregates( - ContentStreamId $contentStreamId, - NodeAggregateId $parentNodeAggregateId - ): iterable; - - /** - * A node aggregate may have multiple child node aggregates with the same name - * as long as they do not share dimension space coverage - * - * @return iterable - * @internal only for consumption inside the Command Handler - */ - public function findChildNodeAggregatesByName( - ContentStreamId $contentStreamId, - NodeAggregateId $parentNodeAggregateId, - NodeName $name - ): iterable; - - /** - * @return iterable - * @internal only for consumption inside the Command Handler - */ - public function findTetheredChildNodeAggregates( - ContentStreamId $contentStreamId, - NodeAggregateId $parentNodeAggregateId - ): iterable; - - /** - * @internal only for consumption inside the Command Handler - */ - public function getDimensionSpacePointsOccupiedByChildNodeName( - ContentStreamId $contentStreamId, - NodeName $nodeName, - NodeAggregateId $parentNodeAggregateId, - OriginDimensionSpacePoint $parentNodeOriginDimensionSpacePoint, - DimensionSpacePointSet $dimensionSpacePointsToCheck - ): DimensionSpacePointSet; - /** * @internal only for consumption in testcases */ diff --git a/Neos.ContentRepository.Core/Classes/Projection/ContentStream/ContentStreamFinder.php b/Neos.ContentRepository.Core/Classes/Projection/ContentStream/ContentStreamFinder.php index 6bcc6a9b2b0..1933d357817 100644 --- a/Neos.ContentRepository.Core/Classes/Projection/ContentStream/ContentStreamFinder.php +++ b/Neos.ContentRepository.Core/Classes/Projection/ContentStream/ContentStreamFinder.php @@ -158,42 +158,4 @@ public function findUnusedAndRemovedContentStreams(): iterable )->fetchFirstColumn(); return array_map(ContentStreamId::fromString(...), $contentStreamIds); } - - public function findVersionForContentStream(ContentStreamId $contentStreamId): MaybeVersion - { - $connection = $this->client->getConnection(); - /* @var $state string|false */ - $version = $connection->executeQuery( - ' - SELECT version FROM ' . $this->tableName . ' - WHERE contentStreamId = :contentStreamId - ', - [ - 'contentStreamId' => $contentStreamId->value, - ] - )->fetchOne(); - - if ($version === false) { - return MaybeVersion::fromVersionOrNull(null); - } - - return MaybeVersion::fromVersionOrNull(Version::fromInteger($version)); - } - - public function hasContentStream(ContentStreamId $contentStreamId): bool - { - $connection = $this->client->getConnection(); - /* @var $state string|false */ - $version = $connection->executeQuery( - ' - SELECT version FROM ' . $this->tableName . ' - WHERE contentStreamId = :contentStreamId - ', - [ - 'contentStreamId' => $contentStreamId->value - ] - )->fetchOne(); - - return $version !== false; - } } diff --git a/Neos.ContentRepository.StructureAdjustment/src/Adjustment/TetheredNodeAdjustments.php b/Neos.ContentRepository.StructureAdjustment/src/Adjustment/TetheredNodeAdjustments.php index fcdc1104af6..2879e8ba84b 100644 --- a/Neos.ContentRepository.StructureAdjustment/src/Adjustment/TetheredNodeAdjustments.php +++ b/Neos.ContentRepository.StructureAdjustment/src/Adjustment/TetheredNodeAdjustments.php @@ -94,8 +94,7 @@ function () use ($nodeAggregate, $originDimensionSpacePoint, $tetheredNodeName, $originDimensionSpacePoint, $tetheredNodeName, null, - $expectedTetheredNodeType, - $this->contentRepository + $expectedTetheredNodeType ); $streamName = ContentStreamEventStreamName::fromContentStreamId($nodeAggregate->contentStreamId);