diff --git a/Neos.ContentGraph.DoctrineDbalAdapter/src/Domain/Repository/ContentGraph.php b/Neos.ContentGraph.DoctrineDbalAdapter/src/Domain/Repository/ContentGraph.php index 3ce6f4b36ac..b31c8e424ee 100644 --- a/Neos.ContentGraph.DoctrineDbalAdapter/src/Domain/Repository/ContentGraph.php +++ b/Neos.ContentGraph.DoctrineDbalAdapter/src/Domain/Repository/ContentGraph.php @@ -152,7 +152,7 @@ public function findRootNodeAggregates( ->andWhere('n.nodetypename = :nodeTypeName') ->setParameter('nodeTypeName', $filter->nodeTypeName->value); } - return NodeAggregates::fromArray(iterator_to_array($this->mapQueryBuilderToNodeAggregates($queryBuilder))); + return NodeAggregates::fromArray(iterator_to_array($this->mapQueryBuilderToNodeAggregates($queryBuilder, $contentStreamId))); } public function findNodeAggregatesByType( @@ -169,7 +169,7 @@ public function findNodeAggregatesByType( 'contentStreamId' => $contentStreamId->value, 'nodeTypeName' => $nodeTypeName->value, ]); - return $this->mapQueryBuilderToNodeAggregates($queryBuilder); + return $this->mapQueryBuilderToNodeAggregates($queryBuilder, $contentStreamId); } public function findNodeAggregateById( @@ -189,6 +189,7 @@ public function findNodeAggregateById( return $this->nodeFactory->mapNodeRowsToNodeAggregate( $this->fetchRows($queryBuilder), + $contentStreamId, VisibilityConstraints::withoutRestrictions() ); } @@ -214,7 +215,7 @@ public function findParentNodeAggregates( 'contentStreamId' => $contentStreamId->value ]); - return $this->mapQueryBuilderToNodeAggregates($queryBuilder); + return $this->mapQueryBuilderToNodeAggregates($queryBuilder, $contentStreamId); } public function findParentNodeAggregateByChildOriginDimensionSpacePoint( @@ -246,6 +247,7 @@ public function findParentNodeAggregateByChildOriginDimensionSpacePoint( return $this->nodeFactory->mapNodeRowsToNodeAggregate( $this->fetchRows($queryBuilder), + $contentStreamId, VisibilityConstraints::withoutRestrictions() ); } @@ -258,7 +260,7 @@ public function findChildNodeAggregates( NodeAggregateId $parentNodeAggregateId ): iterable { $queryBuilder = $this->buildChildNodeAggregateQuery($parentNodeAggregateId, $contentStreamId); - return $this->mapQueryBuilderToNodeAggregates($queryBuilder); + return $this->mapQueryBuilderToNodeAggregates($queryBuilder, $contentStreamId); } /** @@ -272,7 +274,7 @@ public function findChildNodeAggregatesByName( $queryBuilder = $this->buildChildNodeAggregateQuery($parentNodeAggregateId, $contentStreamId) ->andWhere('ch.name = :relationName') ->setParameter('relationName', $name->value); - return $this->mapQueryBuilderToNodeAggregates($queryBuilder); + return $this->mapQueryBuilderToNodeAggregates($queryBuilder, $contentStreamId); } /** @@ -285,7 +287,7 @@ public function findTetheredChildNodeAggregates( $queryBuilder = $this->buildChildNodeAggregateQuery($parentNodeAggregateId, $contentStreamId) ->andWhere('cn.classification = :tetheredClassification') ->setParameter('tetheredClassification', NodeAggregateClassification::CLASSIFICATION_TETHERED->value); - return $this->mapQueryBuilderToNodeAggregates($queryBuilder); + return $this->mapQueryBuilderToNodeAggregates($queryBuilder, $contentStreamId); } /** @@ -390,10 +392,11 @@ private function createQueryBuilder(): QueryBuilder * @param QueryBuilder $queryBuilder * @return iterable */ - private function mapQueryBuilderToNodeAggregates(QueryBuilder $queryBuilder): iterable + private function mapQueryBuilderToNodeAggregates(QueryBuilder $queryBuilder, ContentStreamId $contentStreamId): iterable { return $this->nodeFactory->mapNodeRowsToNodeAggregates( $this->fetchRows($queryBuilder), + $contentStreamId, VisibilityConstraints::withoutRestrictions() ); } diff --git a/Neos.ContentGraph.DoctrineDbalAdapter/src/Domain/Repository/ContentSubgraph.php b/Neos.ContentGraph.DoctrineDbalAdapter/src/Domain/Repository/ContentSubgraph.php index 420e8e4a43a..64f3b322762 100644 --- a/Neos.ContentGraph.DoctrineDbalAdapter/src/Domain/Repository/ContentSubgraph.php +++ b/Neos.ContentGraph.DoctrineDbalAdapter/src/Domain/Repository/ContentSubgraph.php @@ -169,7 +169,7 @@ public function countBackReferences(NodeAggregateId $nodeAggregateId, CountBackR public function findNodeById(NodeAggregateId $nodeAggregateId): ?Node { $queryBuilder = $this->createQueryBuilder() - ->select('n.*, h.name, h.subtreetags, h.contentstreamid') + ->select('n.*, h.name, h.subtreetags') ->from($this->tableNamePrefix . '_node', 'n') ->innerJoin('n', $this->tableNamePrefix . '_hierarchyrelation', 'h', 'h.childnodeanchor = n.relationanchorpoint') ->where('n.nodeaggregateid = :nodeAggregateId')->setParameter('nodeAggregateId', $nodeAggregateId->value) @@ -182,7 +182,7 @@ public function findNodeById(NodeAggregateId $nodeAggregateId): ?Node public function findRootNodeByType(NodeTypeName $nodeTypeName): ?Node { $queryBuilder = $this->createQueryBuilder() - ->select('n.*, h.name, h.subtreetags, h.contentstreamid') + ->select('n.*, h.name, h.subtreetags') ->from($this->tableNamePrefix . '_node', 'n') ->innerJoin('n', $this->tableNamePrefix . '_hierarchyrelation', 'h', 'h.childnodeanchor = n.relationanchorpoint') ->where('n.nodetypename = :nodeTypeName')->setParameter('nodeTypeName', $nodeTypeName->value) @@ -197,7 +197,7 @@ public function findRootNodeByType(NodeTypeName $nodeTypeName): ?Node public function findParentNode(NodeAggregateId $childNodeAggregateId): ?Node { $queryBuilder = $this->createQueryBuilder() - ->select('pn.*, ch.name, ch.subtreetags, ph.contentstreamid') + ->select('pn.*, ch.name, ch.subtreetags') ->from($this->tableNamePrefix . '_node', 'pn') ->innerJoin('pn', $this->tableNamePrefix . '_hierarchyrelation', 'ph', 'ph.parentnodeanchor = pn.relationanchorpoint') ->innerJoin('pn', $this->tableNamePrefix . '_node', 'cn', 'cn.relationanchorpoint = ph.childnodeanchor') @@ -239,7 +239,7 @@ public function findNodeByAbsolutePath(AbsoluteNodePath $path): ?Node private function findChildNodeConnectedThroughEdgeName(NodeAggregateId $parentNodeAggregateId, NodeName $nodeName): ?Node { $queryBuilder = $this->createQueryBuilder() - ->select('cn.*, h.name, h.subtreetags, h.contentstreamid') + ->select('cn.*, h.name, h.subtreetags') ->from($this->tableNamePrefix . '_node', 'pn') ->innerJoin('pn', $this->tableNamePrefix . '_hierarchyrelation', 'h', 'h.parentnodeanchor = pn.relationanchorpoint') ->innerJoin('pn', $this->tableNamePrefix . '_node', 'cn', 'cn.relationanchorpoint = h.childnodeanchor') @@ -290,7 +290,7 @@ public function findSubtree(NodeAggregateId $entryNodeAggregateId, FindSubtreeFi { $queryBuilderInitial = $this->createQueryBuilder() // @see https://mariadb.com/kb/en/library/recursive-common-table-expressions-overview/#cast-to-avoid-data-truncation - ->select('n.*, h.name, h.subtreetags, h.contentstreamid, CAST("ROOT" AS CHAR(50)) AS parentNodeAggregateId, 0 AS level, 0 AS position') + ->select('n.*, h.name, h.subtreetags, CAST("ROOT" AS CHAR(50)) AS parentNodeAggregateId, 0 AS level, 0 AS position') ->from($this->tableNamePrefix . '_node', 'n') ->innerJoin('n', $this->tableNamePrefix . '_hierarchyrelation', 'h', 'h.childnodeanchor = n.relationanchorpoint') ->where('h.contentstreamid = :contentStreamId') @@ -299,7 +299,7 @@ public function findSubtree(NodeAggregateId $entryNodeAggregateId, FindSubtreeFi $this->addSubtreeTagConstraints($queryBuilderInitial); $queryBuilderRecursive = $this->createQueryBuilder() - ->select('c.*, h.name, h.subtreetags, h.contentstreamid, p.nodeaggregateid AS parentNodeAggregateId, p.level + 1 AS level, h.position') + ->select('c.*, h.name, h.subtreetags, p.nodeaggregateid AS parentNodeAggregateId, p.level + 1 AS level, h.position') ->from('tree', 'p') ->innerJoin('p', $this->tableNamePrefix . '_hierarchyrelation', 'h', 'h.parentnodeanchor = p.relationanchorpoint') ->innerJoin('p', $this->tableNamePrefix . '_node', 'c', 'c.relationanchorpoint = h.childnodeanchor') @@ -328,7 +328,7 @@ public function findSubtree(NodeAggregateId $entryNodeAggregateId, FindSubtreeFi foreach (array_reverse($result) as $nodeData) { $nodeAggregateId = $nodeData['nodeaggregateid']; $parentNodeAggregateId = $nodeData['parentNodeAggregateId']; - $node = $this->nodeFactory->mapNodeRowToNode($nodeData, $this->dimensionSpacePoint, $this->visibilityConstraints); + $node = $this->nodeFactory->mapNodeRowToNode($nodeData, $this->contentStreamId, $this->dimensionSpacePoint, $this->visibilityConstraints); $subtree = new Subtree((int)$nodeData['level'], $node, array_key_exists($nodeAggregateId, $subtreesByParentNodeId) ? array_reverse($subtreesByParentNodeId[$nodeAggregateId]) : []); if ($subtree->level === 0) { return $subtree; @@ -357,6 +357,7 @@ public function findAncestorNodes(NodeAggregateId $entryNodeAggregateId, FindAnc return $this->nodeFactory->mapNodeRowsToNodes( $nodeRows, + $this->contentStreamId, $this->dimensionSpacePoint, $this->visibilityConstraints ); @@ -381,7 +382,7 @@ public function countAncestorNodes(NodeAggregateId $entryNodeAggregateId, CountA public function findClosestNode(NodeAggregateId $entryNodeAggregateId, FindClosestNodeFilter $filter): ?Node { $queryBuilderInitial = $this->createQueryBuilder() - ->select('n.*, ph.name, ph.subtreetags, ph.contentstreamid, ph.parentnodeanchor') + ->select('n.*, ph.name, ph.subtreetags, ph.parentnodeanchor') ->from($this->tableNamePrefix . '_node', 'n') // we need to join with the hierarchy relation, because we need the node name. ->innerJoin('n', $this->tableNamePrefix . '_hierarchyrelation', 'ph', 'n.relationanchorpoint = ph.childnodeanchor') @@ -391,7 +392,7 @@ public function findClosestNode(NodeAggregateId $entryNodeAggregateId, FindClose $this->addSubtreeTagConstraints($queryBuilderInitial, 'ph'); $queryBuilderRecursive = $this->createQueryBuilder() - ->select('pn.*, h.name, h.subtreetags, h.contentstreamid, h.parentnodeanchor') + ->select('pn.*, h.name, h.subtreetags, h.parentnodeanchor') ->from('ancestry', 'cn') ->innerJoin('cn', $this->tableNamePrefix . '_node', 'pn', 'pn.relationanchorpoint = cn.parentnodeanchor') ->innerJoin('pn', $this->tableNamePrefix . '_hierarchyrelation', 'h', 'h.childnodeanchor = pn.relationanchorpoint') @@ -417,6 +418,7 @@ public function findClosestNode(NodeAggregateId $entryNodeAggregateId, FindClose ); return $this->nodeFactory->mapNodeRowsToNodes( $nodeRows, + $this->contentStreamId, $this->dimensionSpacePoint, $this->visibilityConstraints )->first(); @@ -433,7 +435,7 @@ public function findDescendantNodes(NodeAggregateId $entryNodeAggregateId, FindD } $queryBuilderCte->addOrderBy('level')->addOrderBy('position'); $nodeRows = $this->fetchCteResults($queryBuilderInitial, $queryBuilderRecursive, $queryBuilderCte, 'tree'); - return $this->nodeFactory->mapNodeRowsToNodes($nodeRows, $this->dimensionSpacePoint, $this->visibilityConstraints); + return $this->nodeFactory->mapNodeRowsToNodes($nodeRows, $this->contentStreamId, $this->dimensionSpacePoint, $this->visibilityConstraints); } public function countDescendantNodes(NodeAggregateId $entryNodeAggregateId, CountDescendantNodesFilter $filter): int @@ -600,7 +602,7 @@ private function searchPropertyValueStatement(QueryBuilder $queryBuilder, Proper private function buildChildNodesQuery(NodeAggregateId $parentNodeAggregateId, FindChildNodesFilter|CountChildNodesFilter $filter): QueryBuilder { $queryBuilder = $this->createQueryBuilder() - ->select('n.*, h.name, h.subtreetags, h.contentstreamid') + ->select('n.*, h.name, h.subtreetags') ->from($this->tableNamePrefix . '_node', 'pn') ->innerJoin('pn', $this->tableNamePrefix . '_hierarchyrelation', 'h', 'h.parentnodeanchor = pn.relationanchorpoint') ->innerJoin('pn', $this->tableNamePrefix . '_node', 'n', 'h.childnodeanchor = n.relationanchorpoint') @@ -625,7 +627,7 @@ private function buildReferencesQuery(bool $backReferences, NodeAggregateId $nod $sourceTablePrefix = $backReferences ? 'd' : 's'; $destinationTablePrefix = $backReferences ? 's' : 'd'; $queryBuilder = $this->createQueryBuilder() - ->select("{$destinationTablePrefix}n.*, {$destinationTablePrefix}h.name, {$destinationTablePrefix}h.subtreetags, {$destinationTablePrefix}h.contentstreamid, r.name AS referencename, r.properties AS referenceproperties") + ->select("{$destinationTablePrefix}n.*, {$destinationTablePrefix}h.name, {$destinationTablePrefix}h.subtreetags, r.name AS referencename, r.properties AS referenceproperties") ->from($this->tableNamePrefix . '_hierarchyrelation', 'sh') ->innerJoin('sh', $this->tableNamePrefix . '_node', 'sn', 'sn.relationanchorpoint = sh.childnodeanchor') ->innerJoin('sh', $this->tableNamePrefix . '_referencerelation', 'r', 'r.nodeanchorpoint = sn.relationanchorpoint') @@ -693,7 +695,7 @@ private function buildSiblingsQuery(bool $preceding, NodeAggregateId $siblingNod ->andWhere('sh.dimensionspacepointhash = :dimensionSpacePointHash'); $queryBuilder = $this->createQueryBuilder() - ->select('n.*, h.name, h.subtreetags, h.contentstreamid') + ->select('n.*, h.name, h.subtreetags') ->from($this->tableNamePrefix . '_node', 'n') ->innerJoin('n', $this->tableNamePrefix . '_hierarchyrelation', 'h', 'h.childnodeanchor = n.relationanchorpoint') ->where('h.contentstreamid = :contentStreamId')->setParameter('contentStreamId', $this->contentStreamId->value) @@ -725,7 +727,7 @@ private function buildSiblingsQuery(bool $preceding, NodeAggregateId $siblingNod private function buildAncestorNodesQueries(NodeAggregateId $entryNodeAggregateId, FindAncestorNodesFilter|CountAncestorNodesFilter|FindClosestNodeFilter $filter): array { $queryBuilderInitial = $this->createQueryBuilder() - ->select('n.*, ph.name, ph.subtreetags, ph.contentstreamid, ph.parentnodeanchor') + ->select('n.*, ph.name, ph.subtreetags, ph.parentnodeanchor') ->from($this->tableNamePrefix . '_node', 'n') // we need to join with the hierarchy relation, because we need the node name. ->innerJoin('n', $this->tableNamePrefix . '_hierarchyrelation', 'ch', 'ch.parentnodeanchor = n.relationanchorpoint') @@ -740,7 +742,7 @@ private function buildAncestorNodesQueries(NodeAggregateId $entryNodeAggregateId $this->addSubtreeTagConstraints($queryBuilderInitial, 'ch'); $queryBuilderRecursive = $this->createQueryBuilder() - ->select('pn.*, h.name, h.subtreetags, h.contentstreamid, h.parentnodeanchor') + ->select('pn.*, h.name, h.subtreetags, h.parentnodeanchor') ->from('ancestry', 'cn') ->innerJoin('cn', $this->tableNamePrefix . '_node', 'pn', 'pn.relationanchorpoint = cn.parentnodeanchor') ->innerJoin('pn', $this->tableNamePrefix . '_hierarchyrelation', 'h', 'h.childnodeanchor = pn.relationanchorpoint') @@ -767,7 +769,7 @@ private function buildDescendantNodesQueries(NodeAggregateId $entryNodeAggregate { $queryBuilderInitial = $this->createQueryBuilder() // @see https://mariadb.com/kb/en/library/recursive-common-table-expressions-overview/#cast-to-avoid-data-truncation - ->select('n.*, h.name, h.subtreetags, h.contentstreamid, CAST("ROOT" AS CHAR(50)) AS parentNodeAggregateId, 0 AS level, 0 AS position') + ->select('n.*, h.name, h.subtreetags, CAST("ROOT" AS CHAR(50)) AS parentNodeAggregateId, 0 AS level, 0 AS position') ->from($this->tableNamePrefix . '_node', 'n') // we need to join with the hierarchy relation, because we need the node name. ->innerJoin('n', $this->tableNamePrefix . '_hierarchyrelation', 'h', 'h.childnodeanchor = n.relationanchorpoint') @@ -781,7 +783,7 @@ private function buildDescendantNodesQueries(NodeAggregateId $entryNodeAggregate $this->addSubtreeTagConstraints($queryBuilderInitial); $queryBuilderRecursive = $this->createQueryBuilder() - ->select('cn.*, h.name, h.subtreetags, h.contentstreamid, pn.nodeaggregateid AS parentNodeAggregateId, pn.level + 1 AS level, h.position') + ->select('cn.*, h.name, h.subtreetags, pn.nodeaggregateid AS parentNodeAggregateId, pn.level + 1 AS level, h.position') ->from('tree', 'pn') ->innerJoin('pn', $this->tableNamePrefix . '_hierarchyrelation', 'h', 'h.parentnodeanchor = pn.relationanchorpoint') ->innerJoin('pn', $this->tableNamePrefix . '_node', 'cn', 'cn.relationanchorpoint = h.childnodeanchor') @@ -861,6 +863,7 @@ private function fetchNode(QueryBuilder $queryBuilder): ?Node } return $this->nodeFactory->mapNodeRowToNode( $nodeRow, + $this->contentStreamId, $this->dimensionSpacePoint, $this->visibilityConstraints ); @@ -873,7 +876,7 @@ private function fetchNodes(QueryBuilder $queryBuilder): Nodes } catch (DbalDriverException | DbalException $e) { throw new \RuntimeException(sprintf('Failed to fetch nodes: %s', $e->getMessage()), 1678292896, $e); } - return $this->nodeFactory->mapNodeRowsToNodes($nodeRows, $this->dimensionSpacePoint, $this->visibilityConstraints); + return $this->nodeFactory->mapNodeRowsToNodes($nodeRows, $this->contentStreamId, $this->dimensionSpacePoint, $this->visibilityConstraints); } private function fetchCount(QueryBuilder $queryBuilder): int @@ -892,7 +895,7 @@ private function fetchReferences(QueryBuilder $queryBuilder): References } catch (DbalDriverException | DbalException $e) { throw new \RuntimeException(sprintf('Failed to fetch references: %s', $e->getMessage()), 1678364944, $e); } - return $this->nodeFactory->mapReferenceRowsToReferences($referenceRows, $this->dimensionSpacePoint, $this->visibilityConstraints); + return $this->nodeFactory->mapReferenceRowsToReferences($referenceRows, $this->contentStreamId, $this->dimensionSpacePoint, $this->visibilityConstraints); } /** diff --git a/Neos.ContentGraph.DoctrineDbalAdapter/src/Domain/Repository/NodeFactory.php b/Neos.ContentGraph.DoctrineDbalAdapter/src/Domain/Repository/NodeFactory.php index 86d5a2c663b..ff629bc8732 100644 --- a/Neos.ContentGraph.DoctrineDbalAdapter/src/Domain/Repository/NodeFactory.php +++ b/Neos.ContentGraph.DoctrineDbalAdapter/src/Domain/Repository/NodeFactory.php @@ -64,6 +64,7 @@ public function __construct( */ public function mapNodeRowToNode( array $nodeRow, + ContentStreamId $contentStreamId, DimensionSpacePoint $dimensionSpacePoint, VisibilityConstraints $visibilityConstraints ): Node { @@ -74,7 +75,7 @@ public function mapNodeRowToNode( return Node::create( ContentSubgraphIdentity::create( $this->contentRepositoryId, - ContentStreamId::fromString($nodeRow['contentstreamid']), + $contentStreamId, $dimensionSpacePoint, $visibilityConstraints ), @@ -98,10 +99,10 @@ public function mapNodeRowToNode( /** * @param array> $nodeRows */ - public function mapNodeRowsToNodes(array $nodeRows, DimensionSpacePoint $dimensionSpacePoint, VisibilityConstraints $visibilityConstraints): Nodes + public function mapNodeRowsToNodes(array $nodeRows, ContentStreamId $contentStreamId, DimensionSpacePoint $dimensionSpacePoint, VisibilityConstraints $visibilityConstraints): Nodes { return Nodes::fromArray( - array_map(fn (array $nodeRow) => $this->mapNodeRowToNode($nodeRow, $dimensionSpacePoint, $visibilityConstraints), $nodeRows) + array_map(fn (array $nodeRow) => $this->mapNodeRowToNode($nodeRow, $contentStreamId, $dimensionSpacePoint, $visibilityConstraints), $nodeRows) ); } @@ -118,6 +119,7 @@ public function createPropertyCollectionFromJsonString(string $jsonString): Prop */ public function mapReferenceRowsToReferences( array $nodeRows, + ContentStreamId $contentStreamId, DimensionSpacePoint $dimensionSpacePoint, VisibilityConstraints $visibilityConstraints ): References { @@ -125,6 +127,7 @@ public function mapReferenceRowsToReferences( foreach ($nodeRows as $nodeRow) { $node = $this->mapNodeRowToNode( $nodeRow, + $contentStreamId, $dimensionSpacePoint, $visibilityConstraints ); @@ -146,6 +149,7 @@ public function mapReferenceRowsToReferences( */ public function mapNodeRowsToNodeAggregate( array $nodeRows, + ContentStreamId $contentStreamId, VisibilityConstraints $visibilityConstraints ): ?NodeAggregate { if (empty($nodeRows)) { @@ -173,6 +177,7 @@ public function mapNodeRowsToNodeAggregate( // ... so we handle occupation exactly once ... $nodesByOccupiedDimensionSpacePoints[$occupiedDimensionSpacePoint->hash] = $this->mapNodeRowToNode( $nodeRow, + $contentStreamId, $occupiedDimensionSpacePoint->toDimensionSpacePoint(), $visibilityConstraints ); @@ -227,6 +232,7 @@ public function mapNodeRowsToNodeAggregate( */ public function mapNodeRowsToNodeAggregates( iterable $nodeRows, + ContentStreamId $contentStreamId, VisibilityConstraints $visibilityConstraints ): iterable { $nodeTypeNames = []; @@ -254,6 +260,7 @@ public function mapNodeRowsToNodeAggregates( $nodesByOccupiedDimensionSpacePointsByNodeAggregate [$rawNodeAggregateId][$occupiedDimensionSpacePoint->hash] = $this->mapNodeRowToNode( $nodeRow, + $contentStreamId, $occupiedDimensionSpacePoint->toDimensionSpacePoint(), $visibilityConstraints );