diff --git a/Neos.ContentGraph.DoctrineDbalAdapter/src/Domain/Repository/ContentSubgraph.php b/Neos.ContentGraph.DoctrineDbalAdapter/src/Domain/Repository/ContentSubgraph.php index 747a627c08d..295895505ab 100644 --- a/Neos.ContentGraph.DoctrineDbalAdapter/src/Domain/Repository/ContentSubgraph.php +++ b/Neos.ContentGraph.DoctrineDbalAdapter/src/Domain/Repository/ContentSubgraph.php @@ -229,6 +229,11 @@ public function findNodeByAbsolutePath(AbsoluteNodePath $path): ?Node : null; } + /** + * Find a single child node by its name + * + * @return Node|null the node that is connected to its parent with the specified $nodeName, or NULL if no matching node exists or the parent node is not accessible + */ private function findChildNodeConnectedThroughEdgeName(NodeAggregateId $parentNodeAggregateId, NodeName $nodeName): ?Node { $queryBuilder = $this->createQueryBuilder() diff --git a/Neos.ContentGraph.PostgreSQLAdapter/src/Domain/Repository/ContentSubhypergraph.php b/Neos.ContentGraph.PostgreSQLAdapter/src/Domain/Repository/ContentSubhypergraph.php index 22e11906c46..57ce5ccf93c 100644 --- a/Neos.ContentGraph.PostgreSQLAdapter/src/Domain/Repository/ContentSubhypergraph.php +++ b/Neos.ContentGraph.PostgreSQLAdapter/src/Domain/Repository/ContentSubhypergraph.php @@ -519,7 +519,7 @@ private function findNodeByPathFromStartingNode(NodePath $path, Node $startingNo $currentNode = $startingNode; foreach ($path->getParts() as $edgeName) { // id exists here :) - $currentNode = $this->findChildNodeByNodeName($currentNode->nodeAggregateId, $edgeName); + $currentNode = $this->findChildNodeConnectedThroughEdgeName($currentNode->nodeAggregateId, $edgeName); if ($currentNode === null) { return null; } diff --git a/Neos.ContentRepository.Core/Classes/Projection/ContentGraph/ContentGraphWithRuntimeCaches/ContentSubgraphWithRuntimeCaches.php b/Neos.ContentRepository.Core/Classes/Projection/ContentGraph/ContentGraphWithRuntimeCaches/ContentSubgraphWithRuntimeCaches.php index 7d572302090..c3c82e5e609 100644 --- a/Neos.ContentRepository.Core/Classes/Projection/ContentGraph/ContentGraphWithRuntimeCaches/ContentSubgraphWithRuntimeCaches.php +++ b/Neos.ContentRepository.Core/Classes/Projection/ContentGraph/ContentGraphWithRuntimeCaches/ContentSubgraphWithRuntimeCaches.php @@ -165,23 +165,46 @@ public function findParentNode(NodeAggregateId $childNodeAggregateId): ?Node public function findNodeByPath(NodePath $path, NodeAggregateId $startingNodeAggregateId): ?Node { - // TODO implement runtime caches - return $this->wrappedContentSubgraph->findNodeByPath($path, $startingNodeAggregateId); + // this implementation is copied from the DoctrineAdapter to make it cache-able + $startingNode = $this->findNodeById($startingNodeAggregateId); + + return $startingNode + ? $this->findNodeByPathFromStartingNode($path, $startingNode) + : null; } public function findNodeByAbsolutePath(AbsoluteNodePath $path): ?Node { - // TODO implement runtime caches - return $this->wrappedContentSubgraph->findNodeByAbsolutePath($path); + // this implementation is copied from the DoctrineAdapter to make it cache-able + $startingNode = $this->findRootNodeByType($path->rootNodeTypeName); + + return $startingNode + ? $this->findNodeByPathFromStartingNode($path->path, $startingNode) + : null; + } + + private function findNodeByPathFromStartingNode(NodePath $path, Node $startingNode): ?Node + { + $currentNode = $startingNode; + + foreach ($path->getParts() as $edgeName) { + $currentNode = $this->findChildNodeConnectedThroughEdgeName($currentNode->nodeAggregateId, $edgeName); + if ($currentNode === null) { + return null; + } + } + return $currentNode; } - public function findChildNodeByNodeName(NodeAggregateId $parentNodeAggregateId, NodeName $nodeName): ?Node + private function findChildNodeConnectedThroughEdgeName(NodeAggregateId $parentNodeAggregateId, NodeName $nodeName): ?Node { $namedChildNodeCache = $this->inMemoryCache->getNamedChildNodeByNodeIdCache(); if ($namedChildNodeCache->contains($parentNodeAggregateId, $nodeName)) { return $namedChildNodeCache->get($parentNodeAggregateId, $nodeName); } - $node = $this->wrappedContentSubgraph->findChildNodeByNodeName($parentNodeAggregateId, $nodeName); + // naturally we would want to call $wrappedContentSubgraph->findChildNodeConnectedThroughEdgeName here, + // but this is not part of the interface and private. Calling find by path with a single segment does the same + $node = $this->wrappedContentSubgraph->findNodeByPath(NodePath::fromNodeNames($nodeName), $parentNodeAggregateId); if ($node === null) { return null; } diff --git a/Neos.ContentRepository.Core/Classes/Projection/ContentGraph/ContentSubgraphInterface.php b/Neos.ContentRepository.Core/Classes/Projection/ContentGraph/ContentSubgraphInterface.php index 84422e63831..df6259c3858 100644 --- a/Neos.ContentRepository.Core/Classes/Projection/ContentGraph/ContentSubgraphInterface.php +++ b/Neos.ContentRepository.Core/Classes/Projection/ContentGraph/ContentSubgraphInterface.php @@ -100,13 +100,6 @@ public function findSucceedingSiblingNodes(NodeAggregateId $siblingNodeAggregate */ public function findPrecedingSiblingNodes(NodeAggregateId $siblingNodeAggregateId, Filter\FindPrecedingSiblingNodesFilter $filter): Nodes; - /** - * Find a single child node by its name - * - * @return Node|null the node that is connected to its parent with the specified $nodeName, or NULL if no matching node exists or the parent node is not accessible - */ - public function findChildNodeByNodeName(NodeAggregateId $parentNodeAggregateId, NodeName $nodeName): ?Node; - /** * Recursively find all nodes above the $entryNodeAggregateId that match the specified $filter and return them as a flat list */