From 12940405bcdf09dc78ac2655ed870a0a8978008e Mon Sep 17 00:00:00 2001 From: mhsdesign <85400359+mhsdesign@users.noreply.github.com> Date: Sat, 22 Jun 2024 11:06:59 +0200 Subject: [PATCH] TASK: Streamline `ContentGraph::findRootNodeAggregateByType` to be nullable like findRootNodeByType in the subgraph --- .../src/Domain/Repository/ContentGraph.php | 14 ++------- .../Domain/Repository/ContentHypergraph.php | 11 ++----- .../Feature/Common/ConstraintChecks.php | 6 +--- .../ContentGraph/ContentGraphInterface.php | 10 +----- .../Service/ContentRepositoryBootstrapper.php | 28 ++++++++--------- .../RootNodeAggregateDoesNotExist.php | 31 ------------------- .../Features/Bootstrap/CRTestSuiteTrait.php | 11 ++----- .../Module/Administration/SitesController.php | 9 +++--- .../Domain/Service/SiteNodeUtility.php | 4 +++ .../Domain/Service/SiteServiceInternals.php | 4 +++ .../Service/TimeableNodeVisibilityService.php | 5 +-- 11 files changed, 36 insertions(+), 97 deletions(-) delete mode 100644 Neos.ContentRepository.Core/Classes/SharedModel/Exception/RootNodeAggregateDoesNotExist.php diff --git a/Neos.ContentGraph.DoctrineDbalAdapter/src/Domain/Repository/ContentGraph.php b/Neos.ContentGraph.DoctrineDbalAdapter/src/Domain/Repository/ContentGraph.php index b006fa1019d..7fb3d8014d8 100644 --- a/Neos.ContentGraph.DoctrineDbalAdapter/src/Domain/Repository/ContentGraph.php +++ b/Neos.ContentGraph.DoctrineDbalAdapter/src/Domain/Repository/ContentGraph.php @@ -34,7 +34,6 @@ use Neos\ContentRepository\Core\Projection\ContentGraph\NodeAggregates; use Neos\ContentRepository\Core\Projection\ContentGraph\VisibilityConstraints; use Neos\ContentRepository\Core\SharedModel\ContentRepository\ContentRepositoryId; -use Neos\ContentRepository\Core\SharedModel\Exception\RootNodeAggregateDoesNotExist; use Neos\ContentRepository\Core\SharedModel\Node\NodeAggregateClassification; use Neos\ContentRepository\Core\SharedModel\Node\NodeAggregateId; use Neos\ContentRepository\Core\SharedModel\Node\NodeName; @@ -117,17 +116,15 @@ public function getSubgraph( return $this->subgraphs[$index]; } - /** - * @throws RootNodeAggregateDoesNotExist - */ public function findRootNodeAggregateByType( NodeTypeName $nodeTypeName - ): NodeAggregate { + ): ?NodeAggregate { $rootNodeAggregates = $this->findRootNodeAggregates( FindRootNodeAggregatesFilter::create(nodeTypeName: $nodeTypeName) ); if ($rootNodeAggregates->count() > 1) { + // todo drop this check as this is enforced by the write side? https://github.com/neos/neos-development-collection/pull/4339 $ids = []; foreach ($rootNodeAggregates as $rootNodeAggregate) { $ids[] = $rootNodeAggregate->nodeAggregateId->value; @@ -139,12 +136,7 @@ public function findRootNodeAggregateByType( )); } - $rootNodeAggregate = $rootNodeAggregates->first(); - if ($rootNodeAggregate === null) { - throw RootNodeAggregateDoesNotExist::butWasExpectedTo($nodeTypeName); - } - - return $rootNodeAggregate; + return $rootNodeAggregates->first(); } public function findRootNodeAggregates( diff --git a/Neos.ContentGraph.PostgreSQLAdapter/src/Domain/Repository/ContentHypergraph.php b/Neos.ContentGraph.PostgreSQLAdapter/src/Domain/Repository/ContentHypergraph.php index 25a70995cd5..424da43ae4d 100644 --- a/Neos.ContentGraph.PostgreSQLAdapter/src/Domain/Repository/ContentHypergraph.php +++ b/Neos.ContentGraph.PostgreSQLAdapter/src/Domain/Repository/ContentHypergraph.php @@ -30,7 +30,6 @@ use Neos\ContentRepository\Core\Projection\ContentGraph\NodeAggregates; use Neos\ContentRepository\Core\Projection\ContentGraph\VisibilityConstraints; use Neos\ContentRepository\Core\SharedModel\ContentRepository\ContentRepositoryId; -use Neos\ContentRepository\Core\SharedModel\Exception\RootNodeAggregateDoesNotExist; use Neos\ContentRepository\Core\SharedModel\Node\NodeAggregateId; use Neos\ContentRepository\Core\SharedModel\Node\NodeName; use Neos\ContentRepository\Core\SharedModel\Workspace\ContentStreamId; @@ -95,7 +94,7 @@ public function getSubgraph( public function findRootNodeAggregateByType( NodeTypeName $nodeTypeName - ): NodeAggregate { + ): ?NodeAggregate { $rootNodeAggregates = $this->findRootNodeAggregates( FindRootNodeAggregatesFilter::create(nodeTypeName: $nodeTypeName) ); @@ -112,13 +111,7 @@ public function findRootNodeAggregateByType( )); } - $rootNodeAggregate = $rootNodeAggregates->first(); - - if ($rootNodeAggregate === null) { - throw RootNodeAggregateDoesNotExist::butWasExpectedTo($nodeTypeName); - } - - return $rootNodeAggregate; + return $rootNodeAggregates->first(); } public function findRootNodeAggregates( diff --git a/Neos.ContentRepository.Core/Classes/Feature/Common/ConstraintChecks.php b/Neos.ContentRepository.Core/Classes/Feature/Common/ConstraintChecks.php index 94198dcf97d..9cb894f5d76 100644 --- a/Neos.ContentRepository.Core/Classes/Feature/Common/ConstraintChecks.php +++ b/Neos.ContentRepository.Core/Classes/Feature/Common/ConstraintChecks.php @@ -54,7 +54,6 @@ use Neos\ContentRepository\Core\SharedModel\Exception\NodeTypeNotFound; use Neos\ContentRepository\Core\SharedModel\Exception\PropertyCannotBeSet; 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; @@ -160,12 +159,9 @@ protected function requireRootNodeTypeToBeUnoccupied( ContentGraphInterface $contentGraph, NodeTypeName $nodeTypeName ): void { - try { - $contentGraph->findRootNodeAggregateByType($nodeTypeName); - } catch (RootNodeAggregateDoesNotExist $_) { + if ($contentGraph->findRootNodeAggregateByType($nodeTypeName) === null) { return; } - throw RootNodeAggregateTypeIsAlreadyOccupied::butWasExpectedNotTo($nodeTypeName); } diff --git a/Neos.ContentRepository.Core/Classes/Projection/ContentGraph/ContentGraphInterface.php b/Neos.ContentRepository.Core/Classes/Projection/ContentGraph/ContentGraphInterface.php index 6a5ef9a7948..c5757bbd64c 100644 --- a/Neos.ContentRepository.Core/Classes/Projection/ContentGraph/ContentGraphInterface.php +++ b/Neos.ContentRepository.Core/Classes/Projection/ContentGraph/ContentGraphInterface.php @@ -21,7 +21,6 @@ use Neos\ContentRepository\Core\Projection\ProjectionStateInterface; use Neos\ContentRepository\Core\SharedModel\ContentRepository\ContentRepositoryId; use Neos\ContentRepository\Core\SharedModel\Exception\NodeAggregatesTypeIsAmbiguous; -use Neos\ContentRepository\Core\SharedModel\Exception\RootNodeAggregateDoesNotExist; use Neos\ContentRepository\Core\SharedModel\Node\NodeAggregateId; use Neos\ContentRepository\Core\SharedModel\Node\NodeName; use Neos\ContentRepository\Core\SharedModel\Workspace\ContentStreamId; @@ -58,18 +57,11 @@ public function getSubgraph( ): ContentSubgraphInterface; /** - * Throws exception if no root aggregate found, because a Content Repository needs at least - * one root node to function. - * - * Also throws exceptions if multiple root node aggregates of the given $nodeTypeName were found, - * as this would lead to nondeterministic results in your code. - * - * @throws RootNodeAggregateDoesNotExist * @api */ public function findRootNodeAggregateByType( NodeTypeName $nodeTypeName - ): NodeAggregate; + ): ?NodeAggregate; /** * @api diff --git a/Neos.ContentRepository.Core/Classes/Service/ContentRepositoryBootstrapper.php b/Neos.ContentRepository.Core/Classes/Service/ContentRepositoryBootstrapper.php index b5b92e1858a..6bf18c6ea4a 100644 --- a/Neos.ContentRepository.Core/Classes/Service/ContentRepositoryBootstrapper.php +++ b/Neos.ContentRepository.Core/Classes/Service/ContentRepositoryBootstrapper.php @@ -62,27 +62,25 @@ public function getOrCreateLiveWorkspace(): Workspace } /** - * Retrieve the root Node Aggregate ID for the specified $contentStreamId + * Retrieve the root Node Aggregate ID for the specified $workspace * If no root node of the specified $rootNodeTypeName exist, it will be created */ public function getOrCreateRootNodeAggregate( Workspace $workspace, NodeTypeName $rootNodeTypeName ): NodeAggregateId { - try { - return $this->contentRepository->getContentGraph($workspace->workspaceName)->findRootNodeAggregateByType( - $rootNodeTypeName - )->nodeAggregateId; - - // TODO make this case more explicit - } catch (\Exception $exception) { - $rootNodeAggregateId = NodeAggregateId::create(); - $this->contentRepository->handle(CreateRootNodeAggregateWithNode::create( - $workspace->workspaceName, - $rootNodeAggregateId, - $rootNodeTypeName, - )); - return $rootNodeAggregateId; + $rootNodeAggregate = $this->contentRepository->getContentGraph($workspace->workspaceName)->findRootNodeAggregateByType( + $rootNodeTypeName + ); + if ($rootNodeAggregate) { + return $rootNodeAggregate->nodeAggregateId; } + $rootNodeAggregateId = NodeAggregateId::create(); + $this->contentRepository->handle(CreateRootNodeAggregateWithNode::create( + $workspace->workspaceName, + $rootNodeAggregateId, + $rootNodeTypeName, + )); + return $rootNodeAggregateId; } } diff --git a/Neos.ContentRepository.Core/Classes/SharedModel/Exception/RootNodeAggregateDoesNotExist.php b/Neos.ContentRepository.Core/Classes/SharedModel/Exception/RootNodeAggregateDoesNotExist.php deleted file mode 100644 index 5478b0b3f10..00000000000 --- a/Neos.ContentRepository.Core/Classes/SharedModel/Exception/RootNodeAggregateDoesNotExist.php +++ /dev/null @@ -1,31 +0,0 @@ -value, - 1687008819 - ); - } -} diff --git a/Neos.ContentRepository.TestSuite/Classes/Behavior/Features/Bootstrap/CRTestSuiteTrait.php b/Neos.ContentRepository.TestSuite/Classes/Behavior/Features/Bootstrap/CRTestSuiteTrait.php index 057edaa23b6..9f6ee29fce4 100644 --- a/Neos.ContentRepository.TestSuite/Classes/Behavior/Features/Bootstrap/CRTestSuiteTrait.php +++ b/Neos.ContentRepository.TestSuite/Classes/Behavior/Features/Bootstrap/CRTestSuiteTrait.php @@ -28,7 +28,6 @@ use Neos\ContentRepository\Core\Projection\Workspace\Workspace; use Neos\ContentRepository\Core\Service\ContentStreamPruner; use Neos\ContentRepository\Core\Service\ContentStreamPrunerFactory; -use Neos\ContentRepository\Core\SharedModel\Exception\RootNodeAggregateDoesNotExist; use Neos\ContentRepository\Core\SharedModel\Node\NodeAggregateId; use Neos\ContentRepository\Core\SharedModel\Workspace\ContentStreamId; use Neos\ContentRepository\Core\SharedModel\Workspace\ContentStreamState; @@ -241,13 +240,9 @@ protected function getRootNodeAggregateId(): ?NodeAggregateId return $this->currentRootNodeAggregateId; } - try { - return $this->currentContentRepository->getContentGraph($this->currentWorkspaceName)->findRootNodeAggregateByType( - NodeTypeName::fromString('Neos.Neos:Sites') - )->nodeAggregateId; - } catch (RootNodeAggregateDoesNotExist) { - return null; - } + return $this->currentContentRepository->getContentGraph($this->currentWorkspaceName)->findRootNodeAggregateByType( + NodeTypeName::fromString('Neos.Neos:Sites') + )->nodeAggregateId; } /** diff --git a/Neos.Neos/Classes/Controller/Module/Administration/SitesController.php b/Neos.Neos/Classes/Controller/Module/Administration/SitesController.php index 1c047fc9b4d..b22824d6dd7 100755 --- a/Neos.Neos/Classes/Controller/Module/Administration/SitesController.php +++ b/Neos.Neos/Classes/Controller/Module/Administration/SitesController.php @@ -184,11 +184,10 @@ public function updateSiteAction(Site $site, $newSiteNodeName) ); } - try { - $sitesNode = $contentRepository->getContentGraph($liveWorkspace->workspaceName)->findRootNodeAggregateByType( - NodeTypeNameFactory::forSites() - ); - } catch (\Exception $exception) { + $sitesNode = $contentRepository->getContentGraph($liveWorkspace->workspaceName)->findRootNodeAggregateByType( + NodeTypeNameFactory::forSites() + ); + if (!$sitesNode) { throw new \InvalidArgumentException( 'Cannot update a site without the sites note being present.', 1651958452 diff --git a/Neos.Neos/Classes/Domain/Service/SiteNodeUtility.php b/Neos.Neos/Classes/Domain/Service/SiteNodeUtility.php index 2a29f452c26..262d24e4461 100644 --- a/Neos.Neos/Classes/Domain/Service/SiteNodeUtility.php +++ b/Neos.Neos/Classes/Domain/Service/SiteNodeUtility.php @@ -68,6 +68,10 @@ public function findSiteNodeBySite( $rootNodeAggregate = $contentGraph->findRootNodeAggregateByType( NodeTypeNameFactory::forSites() ); + if (!$rootNodeAggregate) { + throw new \RuntimeException(sprintf('No sites root node found in content repository "%s", while fetching site node "%s"', $contentRepository->id->value, $site->getNodeName()), 1719046570); + } + $rootNode = $rootNodeAggregate->getNodeByCoveredDimensionSpacePoint($dimensionSpacePoint); $siteNode = $subgraph->findNodeByPath( diff --git a/Neos.Neos/Classes/Domain/Service/SiteServiceInternals.php b/Neos.Neos/Classes/Domain/Service/SiteServiceInternals.php index 7412d45e57a..e4b0c2ca29c 100644 --- a/Neos.Neos/Classes/Domain/Service/SiteServiceInternals.php +++ b/Neos.Neos/Classes/Domain/Service/SiteServiceInternals.php @@ -60,6 +60,10 @@ public function removeSiteNode(SiteNodeName $siteNodeName): void $sitesNodeAggregate = $contentGraph->findRootNodeAggregateByType( NodeTypeNameFactory::forSites() ); + if (!$sitesNodeAggregate) { + // nothing to prune, we could probably also return here directly? + continue; + } $siteNodeAggregate = $contentGraph->findChildNodeAggregateByName( $sitesNodeAggregate->nodeAggregateId, $siteNodeName->toNodeName() diff --git a/Neos.TimeableNodeVisibility/Classes/Service/TimeableNodeVisibilityService.php b/Neos.TimeableNodeVisibility/Classes/Service/TimeableNodeVisibilityService.php index e50fd2268ec..e486163553e 100644 --- a/Neos.TimeableNodeVisibility/Classes/Service/TimeableNodeVisibilityService.php +++ b/Neos.TimeableNodeVisibility/Classes/Service/TimeableNodeVisibilityService.php @@ -14,10 +14,7 @@ use Neos\ContentRepository\Core\Projection\ContentGraph\Filter\PropertyValue\Criteria\PropertyValueLessThanOrEqual; use Neos\ContentRepository\Core\Projection\ContentGraph\Node; use Neos\ContentRepository\Core\Projection\ContentGraph\VisibilityConstraints; -use Neos\ContentRepository\Core\Projection\Workspace\Workspace; use Neos\ContentRepository\Core\SharedModel\ContentRepository\ContentRepositoryId; -use Neos\ContentRepository\Core\SharedModel\Exception\RootNodeAggregateDoesNotExist; -use Neos\ContentRepository\Core\SharedModel\Exception\WorkspaceDoesNotExist; use Neos\ContentRepository\Core\SharedModel\Node\NodeVariantSelectionStrategy; use Neos\ContentRepository\Core\SharedModel\Node\PropertyName; use Neos\ContentRepository\Core\SharedModel\Workspace\WorkspaceName; @@ -101,7 +98,7 @@ private function getNodesWithExceededDates(ContentRepository $contentRepository, $sitesNodeTypeName = NodeTypeName::fromString('Neos.Neos:Sites'); $rootNode = $subgraph->findRootNodeByType($sitesNodeTypeName); if ($rootNode === null) { - throw RootNodeAggregateDoesNotExist::butWasExpectedTo($sitesNodeTypeName); + throw new \RuntimeException(sprintf('No sites root node found in content repository "%s"', $contentRepository->id->value), 1719047148); } $nodes = $subgraph->findDescendantNodes(