diff --git a/Neos.ContentGraph.DoctrineDbalAdapter/src/Domain/Repository/NodeFactory.php b/Neos.ContentGraph.DoctrineDbalAdapter/src/Domain/Repository/NodeFactory.php index c93abc75f93..3ed3f69d474 100644 --- a/Neos.ContentGraph.DoctrineDbalAdapter/src/Domain/Repository/NodeFactory.php +++ b/Neos.ContentGraph.DoctrineDbalAdapter/src/Domain/Repository/NodeFactory.php @@ -152,7 +152,7 @@ public function mapNodeRowsToNodeAggregate( $rawNodeName = ''; $rawNodeAggregateClassification = ''; $occupiedDimensionSpacePoints = []; - $nodesByOccupiedDimensionSpacePoints = []; + $nodesByOccupiedDimensionSpacePoint = []; $coveredDimensionSpacePoints = []; $nodesByCoveredDimensionSpacePoints = []; $coverageByOccupants = []; @@ -164,9 +164,9 @@ public function mapNodeRowsToNodeAggregate( $occupiedDimensionSpacePoint = OriginDimensionSpacePoint::fromJsonString( $nodeRow['origindimensionspacepoint'] ); - if (!isset($nodesByOccupiedDimensionSpacePoints[$occupiedDimensionSpacePoint->hash])) { + if (!isset($nodesByOccupiedDimensionSpacePoint[$occupiedDimensionSpacePoint->hash])) { // ... so we handle occupation exactly once ... - $nodesByOccupiedDimensionSpacePoints[$occupiedDimensionSpacePoint->hash] = $this->mapNodeRowToNode( + $nodesByOccupiedDimensionSpacePoint[$occupiedDimensionSpacePoint->hash] = $this->mapNodeRowToNode( $nodeRow, $occupiedDimensionSpacePoint->toDimensionSpacePoint(), $visibilityConstraints @@ -187,7 +187,7 @@ public function mapNodeRowsToNodeAggregate( = $coveredDimensionSpacePoint; $occupationByCovering[$coveredDimensionSpacePoint->hash] = $occupiedDimensionSpacePoint; $nodesByCoveredDimensionSpacePoints[$coveredDimensionSpacePoint->hash] - = $nodesByOccupiedDimensionSpacePoints[$occupiedDimensionSpacePoint->hash]; + = $nodesByOccupiedDimensionSpacePoint[$occupiedDimensionSpacePoint->hash]; // ... as we do for disabling if (isset($nodeRow['disableddimensionspacepointhash'])) { $disabledDimensionSpacePoints[$coveredDimensionSpacePoint->hash] = $coveredDimensionSpacePoint; @@ -197,8 +197,9 @@ public function mapNodeRowsToNodeAggregate( ksort($coveredDimensionSpacePoints); ksort($disabledDimensionSpacePoints); - /** @var Node $primaryNode a nodeAggregate only exists if it at least contains one node. */ - $primaryNode = current($nodesByOccupiedDimensionSpacePoints); + // a nodeAggregate only exists if it at least contains one node + assert($nodesByOccupiedDimensionSpacePoint !== []); + $primaryNode = current($nodesByOccupiedDimensionSpacePoint); return new NodeAggregate( $primaryNode->subgraphIdentity->contentStreamId, @@ -207,7 +208,7 @@ public function mapNodeRowsToNodeAggregate( NodeTypeName::fromString($rawNodeTypeName), $rawNodeName ? NodeName::fromString($rawNodeName) : null, new OriginDimensionSpacePointSet($occupiedDimensionSpacePoints), - $nodesByOccupiedDimensionSpacePoints, + $nodesByOccupiedDimensionSpacePoint, CoverageByOrigin::fromArray($coverageByOccupants), new DimensionSpacePointSet($coveredDimensionSpacePoints), $nodesByCoveredDimensionSpacePoints, diff --git a/Neos.ContentRepository.Core/Classes/Feature/Common/TetheredNodeInternals.php b/Neos.ContentRepository.Core/Classes/Feature/Common/TetheredNodeInternals.php index ba8ff204f27..04558ab3b90 100644 --- a/Neos.ContentRepository.Core/Classes/Feature/Common/TetheredNodeInternals.php +++ b/Neos.ContentRepository.Core/Classes/Feature/Common/TetheredNodeInternals.php @@ -133,12 +133,7 @@ protected function createEventsForMissingTetheredNode( ); } - $childNodeSource = null; - foreach ($childNodeAggregate->getNodes() as $node) { - $childNodeSource = $node; - break; - } - /** @var Node $childNodeSource Node aggregates are never empty */ + $childNodeSource = $childNodeAggregate->getSingleNodeIndependentOfItsDimension(); return $this->createEventsForVariations( $parentNodeAggregate->contentStreamId, $childNodeSource->originDimensionSpacePoint, diff --git a/Neos.ContentRepository.Core/Classes/Projection/ContentGraph/NodeAggregate.php b/Neos.ContentRepository.Core/Classes/Projection/ContentGraph/NodeAggregate.php index e17410810c6..2f5a4cb0a7e 100644 --- a/Neos.ContentRepository.Core/Classes/Projection/ContentGraph/NodeAggregate.php +++ b/Neos.ContentRepository.Core/Classes/Projection/ContentGraph/NodeAggregate.php @@ -50,6 +50,20 @@ */ final class NodeAggregate { + /** + * @param ContentStreamId $contentStreamId + * @param NodeAggregateId $nodeAggregateId + * @param NodeAggregateClassification $classification + * @param NodeTypeName $nodeTypeName + * @param NodeName|null $nodeName + * @param OriginDimensionSpacePointSet $occupiedDimensionSpacePoints + * @param non-empty-array $nodesByOccupiedDimensionSpacePoint At least one node will be occupied. + * @param CoverageByOrigin $coverageByOccupant + * @param DimensionSpacePointSet $coveredDimensionSpacePoints At least one node will be covered. + * @param non-empty-array $nodesByCoveredDimensionSpacePoint + * @param OriginByCoverage $occupationByCovered + * @param DimensionSpacePointSet $disabledDimensionSpacePoints The dimension space point set this node aggregate disables. This is *not* necessarily the set it is disabled in, since that is determined by its ancestors + */ public function __construct( public readonly ContentStreamId $contentStreamId, public readonly NodeAggregateId $nodeAggregateId, @@ -57,19 +71,16 @@ public function __construct( public readonly NodeTypeName $nodeTypeName, public readonly ?NodeName $nodeName, public readonly OriginDimensionSpacePointSet $occupiedDimensionSpacePoints, - /** @var array */ private readonly array $nodesByOccupiedDimensionSpacePoint, private readonly CoverageByOrigin $coverageByOccupant, public readonly DimensionSpacePointSet $coveredDimensionSpacePoints, - /** @var array */ private readonly array $nodesByCoveredDimensionSpacePoint, private readonly OriginByCoverage $occupationByCovered, - /** - * The dimension space point set this node aggregate disables. - * This is *not* necessarily the set it is disabled in, since that is determined by its ancestors - */ public readonly DimensionSpacePointSet $disabledDimensionSpacePoints ) { + // this nodeAggregate can only exist if it at least contains one node. + assert($this->nodesByOccupiedDimensionSpacePoint !== []); + assert($this->nodesByCoveredDimensionSpacePoint !== []); } public function occupiesDimensionSpacePoint(OriginDimensionSpacePoint $originDimensionSpacePoint): bool @@ -87,6 +98,11 @@ public function getNodes(): iterable return array_values($this->nodesByOccupiedDimensionSpacePoint); } + public function getSingleNodeIndependentOfItsDimension(): Node + { + return current($this->nodesByOccupiedDimensionSpacePoint); + } + public function getNodeByOccupiedDimensionSpacePoint( OriginDimensionSpacePoint $occupiedDimensionSpacePoint ): Node {