From 9ad6b706b5c141ce256f11e04cca69d545ec582b Mon Sep 17 00:00:00 2001 From: mhsdesign <85400359+mhsdesign@users.noreply.github.com> Date: Tue, 14 May 2024 21:07:07 +0200 Subject: [PATCH] TASK: Remove `NodeTypeManager::getTetheredNodesConfigurationForNodeType()` Previously known as `NodeType::getAutoCreatedChildNodes` --- .../Feature/Common/ConstraintChecks.php | 12 ++++---- .../Feature/Common/TetheredNodeInternals.php | 28 +++++++++--------- .../Dto/NodeAggregateIdsByNodePaths.php | 11 +++++-- .../Feature/NodeCreation/NodeCreation.php | 23 ++++++++------- .../Feature/NodeTypeChange/NodeTypeChange.php | 29 +++++++------------ .../RootNodeCreation/RootNodeHandling.php | 18 ++++++------ .../Classes/NodeType/NodeTypeManager.php | 18 ------------ .../NodeType/TetheredNodeTypeDefinitions.php | 2 +- 8 files changed, 63 insertions(+), 78 deletions(-) diff --git a/Neos.ContentRepository.Core/Classes/Feature/Common/ConstraintChecks.php b/Neos.ContentRepository.Core/Classes/Feature/Common/ConstraintChecks.php index a57d8688b01..6514d818b4a 100644 --- a/Neos.ContentRepository.Core/Classes/Feature/Common/ConstraintChecks.php +++ b/Neos.ContentRepository.Core/Classes/Feature/Common/ConstraintChecks.php @@ -172,14 +172,13 @@ protected function requireRootNodeTypeToBeUnoccupied( /** * @param NodeType $nodeType - * @throws NodeTypeNotFoundException the configured child nodeType doesnt exist + * @throws NodeTypeNotFound the configured child nodeType doesnt exist */ protected function requireTetheredDescendantNodeTypesToExist(NodeType $nodeType): void { - // this getter throws if any of the child nodeTypes doesnt exist! - $tetheredNodeTypes = $this->getNodeTypeManager()->getTetheredNodesConfigurationForNodeType($nodeType->name); - foreach ($tetheredNodeTypes as $tetheredNodeType) { - $this->requireTetheredDescendantNodeTypesToExist($tetheredNodeType); + foreach ($nodeType->tetheredNodeTypeDefinitions as $tetheredNodeTypeDefinition) { + $nodeType = $this->requireNodeType($tetheredNodeTypeDefinition->nodeTypeName); + $this->requireTetheredDescendantNodeTypesToExist($nodeType); } } @@ -189,7 +188,8 @@ protected function requireTetheredDescendantNodeTypesToExist(NodeType $nodeType) */ protected function requireTetheredDescendantNodeTypesToNotBeOfTypeRoot(NodeType $nodeType): void { - foreach ($this->getNodeTypeManager()->getTetheredNodesConfigurationForNodeType($nodeType->name) as $tetheredChildNodeType) { + foreach ($nodeType->tetheredNodeTypeDefinitions as $tetheredNodeTypeDefinition) { + $tetheredChildNodeType = $this->requireNodeType($tetheredNodeTypeDefinition->nodeTypeName); if ($tetheredChildNodeType->isOfType(NodeTypeName::ROOT_NODE_TYPE_NAME)) { throw new NodeTypeIsOfTypeRoot( 'Node type "' . $nodeType->name->value . '" for tethered descendant is of type root.', diff --git a/Neos.ContentRepository.Core/Classes/Feature/Common/TetheredNodeInternals.php b/Neos.ContentRepository.Core/Classes/Feature/Common/TetheredNodeInternals.php index c99412cd353..36f27b2e80a 100644 --- a/Neos.ContentRepository.Core/Classes/Feature/Common/TetheredNodeInternals.php +++ b/Neos.ContentRepository.Core/Classes/Feature/Common/TetheredNodeInternals.php @@ -20,15 +20,13 @@ use Neos\ContentRepository\Core\Feature\NodeModification\Dto\SerializedPropertyValues; use Neos\ContentRepository\Core\Feature\NodeVariation\Event\NodePeerVariantWasCreated; use Neos\ContentRepository\Core\Infrastructure\Property\PropertyConverter; -use Neos\ContentRepository\Core\NodeType\NodeType; use Neos\ContentRepository\Core\NodeType\NodeTypeName; +use Neos\ContentRepository\Core\NodeType\TetheredNodeTypeDefinition; use Neos\ContentRepository\Core\Projection\ContentGraph\ContentGraphInterface; use Neos\ContentRepository\Core\Projection\ContentGraph\Node; use Neos\ContentRepository\Core\Projection\ContentGraph\NodeAggregate; use Neos\ContentRepository\Core\SharedModel\Node\NodeAggregateClassification; use Neos\ContentRepository\Core\SharedModel\Node\NodeAggregateId; -use Neos\ContentRepository\Core\SharedModel\Node\NodeName; -use Neos\ContentRepository\Core\SharedModel\Workspace\ContentStreamId; /** * @internal implementation details of command handlers @@ -58,15 +56,19 @@ protected function createEventsForMissingTetheredNode( ContentGraphInterface $contentGraph, NodeAggregate $parentNodeAggregate, OriginDimensionSpacePoint $originDimensionSpacePoint, - NodeName $tetheredNodeName, - ?NodeAggregateId $tetheredNodeAggregateId, - NodeType $expectedTetheredNodeType + TetheredNodeTypeDefinition $tetheredNodeTypeDefinition, + ?NodeAggregateId $tetheredNodeAggregateId ): Events { $childNodeAggregate = $contentGraph->findChildNodeAggregateByName( $parentNodeAggregate->nodeAggregateId, - $tetheredNodeName + $tetheredNodeTypeDefinition->name ); + $expectedTetheredNodeType = $this->nodeTypeManager->getNodeType($tetheredNodeTypeDefinition->nodeTypeName); + $defaultProperties = $expectedTetheredNodeType + ? SerializedPropertyValues::defaultFromNodeType($expectedTetheredNodeType, $this->getPropertyConverter()) + : SerializedPropertyValues::createEmpty(); + if ($childNodeAggregate === null) { // there is no tethered child node aggregate already; let's create it! $nodeType = $this->nodeTypeManager->getNodeType($parentNodeAggregate->nodeTypeName); @@ -91,14 +93,14 @@ protected function createEventsForMissingTetheredNode( $events[] = new NodeAggregateWithNodeWasCreated( $parentNodeAggregate->contentStreamId, $tetheredNodeAggregateId, - $expectedTetheredNodeType->name, + $tetheredNodeTypeDefinition->nodeTypeName, $rootGeneralizationOrigin, InterdimensionalSiblings::fromDimensionSpacePointSetWithoutSucceedingSiblings( $this->getInterDimensionalVariationGraph()->getSpecializationSet($rootGeneralization) ), $parentNodeAggregate->nodeAggregateId, - $tetheredNodeName, - SerializedPropertyValues::defaultFromNodeType($expectedTetheredNodeType, $this->getPropertyConverter()), + $tetheredNodeTypeDefinition->name, + $defaultProperties, NodeAggregateClassification::CLASSIFICATION_TETHERED, ); $creationOriginDimensionSpacePoint = $rootGeneralizationOrigin; @@ -110,14 +112,14 @@ protected function createEventsForMissingTetheredNode( new NodeAggregateWithNodeWasCreated( $parentNodeAggregate->contentStreamId, $tetheredNodeAggregateId ?: NodeAggregateId::create(), - $expectedTetheredNodeType->name, + $tetheredNodeTypeDefinition->nodeTypeName, $originDimensionSpacePoint, InterdimensionalSiblings::fromDimensionSpacePointSetWithoutSucceedingSiblings( $parentNodeAggregate->getCoverageByOccupant($originDimensionSpacePoint) ), $parentNodeAggregate->nodeAggregateId, - $tetheredNodeName, - SerializedPropertyValues::defaultFromNodeType($expectedTetheredNodeType, $this->getPropertyConverter()), + $tetheredNodeTypeDefinition->name, + $defaultProperties, NodeAggregateClassification::CLASSIFICATION_TETHERED, ) ); diff --git a/Neos.ContentRepository.Core/Classes/Feature/NodeCreation/Dto/NodeAggregateIdsByNodePaths.php b/Neos.ContentRepository.Core/Classes/Feature/NodeCreation/Dto/NodeAggregateIdsByNodePaths.php index d5eda29f1d9..083a4cfb607 100644 --- a/Neos.ContentRepository.Core/Classes/Feature/NodeCreation/Dto/NodeAggregateIdsByNodePaths.php +++ b/Neos.ContentRepository.Core/Classes/Feature/NodeCreation/Dto/NodeAggregateIdsByNodePaths.php @@ -18,6 +18,7 @@ use Neos\ContentRepository\Core\NodeType\NodeTypeManager; use Neos\ContentRepository\Core\NodeType\NodeTypeName; use Neos\ContentRepository\Core\Projection\ContentGraph\NodePath; +use Neos\ContentRepository\Core\SharedModel\Exception\NodeTypeNotFound; use Neos\ContentRepository\Core\SharedModel\Node\NodeAggregateId; /** @@ -128,12 +129,16 @@ private static function createNodeAggregateIdsForNodeType( ?string $pathPrefix = null ): array { $nodeAggregateIds = []; - foreach ($nodeTypeManager->getTetheredNodesConfigurationForNodeType($nodeTypeName) as $nodeName => $childNodeType) { - $path = $pathPrefix ? $pathPrefix . '/' . $nodeName : $nodeName; + $nodeType = $nodeTypeManager->getNodeType($nodeTypeName); + if (!$nodeType) { + throw new NodeTypeNotFound(sprintf('Cannot build NodeAggregateIdsByNodePaths because NodeType %s does not exist.', $nodeTypeName->value), 1715711379); + } + foreach ($nodeType->tetheredNodeTypeDefinitions as $tetheredNodeTypeDefinition) { + $path = $pathPrefix ? $pathPrefix . '/' . $tetheredNodeTypeDefinition->name->value : $tetheredNodeTypeDefinition->name->value; $nodeAggregateIds[$path] = NodeAggregateId::create(); $nodeAggregateIds = array_merge( $nodeAggregateIds, - self::createNodeAggregateIdsForNodeType($childNodeType->name, $nodeTypeManager, $path) + self::createNodeAggregateIdsForNodeType($tetheredNodeTypeDefinition->nodeTypeName, $nodeTypeManager, $path) ); } diff --git a/Neos.ContentRepository.Core/Classes/Feature/NodeCreation/NodeCreation.php b/Neos.ContentRepository.Core/Classes/Feature/NodeCreation/NodeCreation.php index 6e8666fa09e..38fb29ef5a3 100644 --- a/Neos.ContentRepository.Core/Classes/Feature/NodeCreation/NodeCreation.php +++ b/Neos.ContentRepository.Core/Classes/Feature/NodeCreation/NodeCreation.php @@ -209,7 +209,7 @@ private function handleCreateNodeAggregateWithNodeAndSerializedProperties( array_push($events, ...iterator_to_array($this->handleTetheredChildNodes( $command, $contentGraph, - $command->nodeTypeName, + $nodeType, $coveredDimensionSpacePoints, $command->nodeAggregateId, $descendantNodeAggregateIds, @@ -257,30 +257,33 @@ private function createRegularWithNode( private function handleTetheredChildNodes( CreateNodeAggregateWithNodeAndSerializedProperties $command, ContentGraphInterface $contentGraph, - NodeTypeName $nodeTypeName, + NodeType $nodeType, DimensionSpacePointSet $coveredDimensionSpacePoints, NodeAggregateId $parentNodeAggregateId, NodeAggregateIdsByNodePaths $nodeAggregateIds, ?NodePath $nodePath ): Events { $events = []; - foreach ($this->getNodeTypeManager()->getTetheredNodesConfigurationForNodeType($nodeTypeName) as $nodeNameString => $childNodeType) { - $nodeName = NodeName::fromString($nodeNameString); + foreach ($nodeType->tetheredNodeTypeDefinitions as $tetheredNodeTypeDefinition) { + $childNodeType = $this->requireNodeType($tetheredNodeTypeDefinition->nodeTypeName); $childNodePath = $nodePath - ? $nodePath->appendPathSegment($nodeName) - : NodePath::fromString($nodeName->value); + ? $nodePath->appendPathSegment($tetheredNodeTypeDefinition->name) + : NodePath::fromString($tetheredNodeTypeDefinition->name->value); $childNodeAggregateId = $nodeAggregateIds->getNodeAggregateId($childNodePath) ?? NodeAggregateId::create(); - $initialPropertyValues = SerializedPropertyValues::defaultFromNodeType($childNodeType, $this->getPropertyConverter()); + $initialPropertyValues = SerializedPropertyValues::defaultFromNodeType( + $childNodeType, + $this->getPropertyConverter() + ); $events[] = new NodeAggregateWithNodeWasCreated( $contentGraph->getContentStreamId(), $childNodeAggregateId, - $childNodeType->name, + $tetheredNodeTypeDefinition->nodeTypeName, $command->originDimensionSpacePoint, InterdimensionalSiblings::fromDimensionSpacePointSetWithoutSucceedingSiblings($coveredDimensionSpacePoints), $parentNodeAggregateId, - $nodeName, + $tetheredNodeTypeDefinition->name, $initialPropertyValues, NodeAggregateClassification::CLASSIFICATION_TETHERED, ); @@ -288,7 +291,7 @@ private function handleTetheredChildNodes( array_push($events, ...iterator_to_array($this->handleTetheredChildNodes( $command, $contentGraph, - $childNodeType->name, + $childNodeType, $coveredDimensionSpacePoints, $childNodeAggregateId, $nodeAggregateIds, diff --git a/Neos.ContentRepository.Core/Classes/Feature/NodeTypeChange/NodeTypeChange.php b/Neos.ContentRepository.Core/Classes/Feature/NodeTypeChange/NodeTypeChange.php index 16219eb7160..72c20f0d7fc 100644 --- a/Neos.ContentRepository.Core/Classes/Feature/NodeTypeChange/NodeTypeChange.php +++ b/Neos.ContentRepository.Core/Classes/Feature/NodeTypeChange/NodeTypeChange.php @@ -28,8 +28,8 @@ use Neos\ContentRepository\Core\Feature\NodeTypeChange\Event\NodeAggregateTypeWasChanged; use Neos\ContentRepository\Core\NodeType\NodeType; use Neos\ContentRepository\Core\NodeType\NodeTypeManager; +use Neos\ContentRepository\Core\NodeType\TetheredNodeTypeDefinition; use Neos\ContentRepository\Core\Projection\ContentGraph\ContentGraphInterface; -use Neos\ContentRepository\Core\NodeType\NodeTypeName; use Neos\ContentRepository\Core\Projection\ContentGraph\Node; use Neos\ContentRepository\Core\Projection\ContentGraph\NodeAggregate; use Neos\ContentRepository\Core\Projection\ContentGraph\NodePath; @@ -90,9 +90,8 @@ abstract protected function createEventsForMissingTetheredNode( ContentGraphInterface $contentGraph, NodeAggregate $parentNodeAggregate, OriginDimensionSpacePoint $originDimensionSpacePoint, - NodeName $tetheredNodeName, - NodeAggregateId $tetheredNodeAggregateId, - NodeType $expectedTetheredNodeType + TetheredNodeTypeDefinition $tetheredNodeTypeDefinition, + NodeAggregateId $tetheredNodeAggregateId ): Events; /** @@ -177,36 +176,32 @@ private function handleChangeNodeAggregateType( array_push($events, ...iterator_to_array($this->deleteObsoleteTetheredNodesWhenChangingNodeType( $contentGraph, $nodeAggregate, - $command->newNodeTypeName + $newNodeType ))); } // new tethered child nodes - $expectedTetheredNodes = $this->getNodeTypeManager()->getTetheredNodesConfigurationForNodeType($command->newNodeTypeName); foreach ($nodeAggregate->getNodes() as $node) { assert($node instanceof Node); - foreach ($expectedTetheredNodes as $serializedTetheredNodeName => $expectedTetheredNodeType) { - $tetheredNodeName = NodeName::fromString($serializedTetheredNodeName); - + foreach ($newNodeType->tetheredNodeTypeDefinitions as $tetheredNodeTypeDefinition) { $tetheredNode = $contentGraph->getSubgraph( $node->originDimensionSpacePoint->toDimensionSpacePoint(), VisibilityConstraints::withoutRestrictions() )->findNodeByPath( - $tetheredNodeName, + $tetheredNodeTypeDefinition->name, $node->nodeAggregateId, ); if ($tetheredNode === null) { $tetheredNodeAggregateId = $command->tetheredDescendantNodeAggregateIds - ->getNodeAggregateId(NodePath::fromString($tetheredNodeName->value)) + ->getNodeAggregateId(NodePath::fromNodeNames($tetheredNodeTypeDefinition->name)) ?: NodeAggregateId::create(); array_push($events, ...iterator_to_array($this->createEventsForMissingTetheredNode( $contentGraph, $nodeAggregate, $node->originDimensionSpacePoint, - $tetheredNodeName, - $tetheredNodeAggregateId, - $expectedTetheredNodeType + $tetheredNodeTypeDefinition, + $tetheredNodeAggregateId ))); } } @@ -348,17 +343,15 @@ private function deleteDisallowedNodesWhenChangingNodeType( private function deleteObsoleteTetheredNodesWhenChangingNodeType( ContentGraphInterface $contentGraph, NodeAggregate $nodeAggregate, - NodeTypeName $newNodeTypeName + NodeType $newNodeType ): Events { - $expectedTetheredNodes = $this->getNodeTypeManager()->getTetheredNodesConfigurationForNodeType($newNodeTypeName); - $events = []; // find disallowed tethered nodes $tetheredNodeAggregates = $contentGraph->findTetheredChildNodeAggregates($nodeAggregate->nodeAggregateId); foreach ($tetheredNodeAggregates as $tetheredNodeAggregate) { /* @var $tetheredNodeAggregate NodeAggregate */ - if ($tetheredNodeAggregate->nodeName !== null && !isset($expectedTetheredNodes[$tetheredNodeAggregate->nodeName->value])) { + if ($tetheredNodeAggregate->nodeName !== null && !$newNodeType->tetheredNodeTypeDefinitions->contain($tetheredNodeAggregate->nodeName)) { // this aggregate (or parts thereof) are DISALLOWED according to constraints. // We now need to find out which edges we need to remove, $dimensionSpacePointsToBeRemoved = $this->findDimensionSpacePointsConnectingParentAndChildAggregate( diff --git a/Neos.ContentRepository.Core/Classes/Feature/RootNodeCreation/RootNodeHandling.php b/Neos.ContentRepository.Core/Classes/Feature/RootNodeCreation/RootNodeHandling.php index ab6f0a1b9a5..da442c82b68 100644 --- a/Neos.ContentRepository.Core/Classes/Feature/RootNodeCreation/RootNodeHandling.php +++ b/Neos.ContentRepository.Core/Classes/Feature/RootNodeCreation/RootNodeHandling.php @@ -105,7 +105,7 @@ private function handleCreateRootNodeAggregateWithNode( foreach ($this->getInterDimensionalVariationGraph()->getRootGeneralizations() as $rootGeneralization) { array_push($events, ...iterator_to_array($this->handleTetheredRootChildNodes( $contentGraph->getContentStreamId(), - $command->nodeTypeName, + $nodeType, OriginDimensionSpacePoint::fromDimensionSpacePoint($rootGeneralization), $this->getInterDimensionalVariationGraph()->getSpecializationSet($rootGeneralization, true), $command->nodeAggregateId, @@ -184,7 +184,7 @@ private function handleUpdateRootNodeAggregateDimensions( */ private function handleTetheredRootChildNodes( ContentStreamId $contentStreamId, - NodeTypeName $nodeTypeName, + NodeType $nodeType, OriginDimensionSpacePoint $originDimensionSpacePoint, DimensionSpacePointSet $coveredDimensionSpacePoints, NodeAggregateId $parentNodeAggregateId, @@ -192,11 +192,11 @@ private function handleTetheredRootChildNodes( ?NodePath $nodePath ): Events { $events = []; - foreach ($this->getNodeTypeManager()->getTetheredNodesConfigurationForNodeType($nodeTypeName) as $nodeNameString => $childNodeType) { - $nodeName = NodeName::fromString($nodeNameString); + foreach ($nodeType->tetheredNodeTypeDefinitions as $tetheredNodeTypeDefinition) { + $childNodeType = $this->requireNodeType($tetheredNodeTypeDefinition->nodeTypeName); $childNodePath = $nodePath - ? $nodePath->appendPathSegment($nodeName) - : NodePath::fromString($nodeName->value); + ? $nodePath->appendPathSegment($tetheredNodeTypeDefinition->name) + : NodePath::fromNodeNames($tetheredNodeTypeDefinition->name); $childNodeAggregateId = $nodeAggregateIdsByNodePath->getNodeAggregateId($childNodePath) ?? NodeAggregateId::create(); $initialPropertyValues = SerializedPropertyValues::defaultFromNodeType($childNodeType, $this->getPropertyConverter()); @@ -204,17 +204,17 @@ private function handleTetheredRootChildNodes( $events[] = $this->createTetheredWithNodeForRoot( $contentStreamId, $childNodeAggregateId, - $childNodeType->name, + $tetheredNodeTypeDefinition->nodeTypeName, $originDimensionSpacePoint, $coveredDimensionSpacePoints, $parentNodeAggregateId, - $nodeName, + $tetheredNodeTypeDefinition->name, $initialPropertyValues ); array_push($events, ...iterator_to_array($this->handleTetheredRootChildNodes( $contentStreamId, - $childNodeType->name, + $childNodeType, $originDimensionSpacePoint, $coveredDimensionSpacePoints, $childNodeAggregateId, diff --git a/Neos.ContentRepository.Core/Classes/NodeType/NodeTypeManager.php b/Neos.ContentRepository.Core/Classes/NodeType/NodeTypeManager.php index a099ba73665..7e28e0d5bd3 100644 --- a/Neos.ContentRepository.Core/Classes/NodeType/NodeTypeManager.php +++ b/Neos.ContentRepository.Core/Classes/NodeType/NodeTypeManager.php @@ -189,24 +189,6 @@ public function overrideNodeTypes(array $completeNodeTypeConfiguration): void } } - /** - * Return an array with child nodes which should be automatically created - * Return an array with child nodes which should be automatically created - * - * @return array the key of this array is the name of the child, and the value its NodeType. - */ - public function getTetheredNodesConfigurationForNodeType(NodeTypeName $nodeTypeName): array - { - $childNodeConfiguration = $this->requireNodeType($nodeTypeName)->getConfiguration('childNodes'); - $autoCreatedChildNodes = []; - foreach ($childNodeConfiguration ?? [] as $childNodeName => $configurationForChildNode) { - if (isset($configurationForChildNode['type'])) { - $autoCreatedChildNodes[NodeName::transliterateFromString($childNodeName)->value] = $this->requireNodeType($configurationForChildNode['type']); - } - } - return $autoCreatedChildNodes; - } - /** * Checks if the given $nodeTypeNameToCheck is allowed as a childNode of the given $tetheredNodeName. * diff --git a/Neos.ContentRepository.Core/Classes/NodeType/TetheredNodeTypeDefinitions.php b/Neos.ContentRepository.Core/Classes/NodeType/TetheredNodeTypeDefinitions.php index 5f8f8a1e682..17ba4edfc28 100644 --- a/Neos.ContentRepository.Core/Classes/NodeType/TetheredNodeTypeDefinitions.php +++ b/Neos.ContentRepository.Core/Classes/NodeType/TetheredNodeTypeDefinitions.php @@ -65,7 +65,7 @@ public function get(NodeName|string $nodeName): ?TetheredNodeTypeDefinition public function getIterator(): \Traversable { - return yield from $this->tetheredNodeTypeDefinitions; + yield from $this->tetheredNodeTypeDefinitions; } /**