Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
mhsdesign committed Feb 20, 2024
1 parent 8b6b9a9 commit 8dfe476
Show file tree
Hide file tree
Showing 10 changed files with 50 additions and 51 deletions.
Expand Up @@ -164,7 +164,7 @@ protected function requireRootNodeTypeToBeUnoccupied(
protected function requireTetheredDescendantNodeTypesToExist(NodeType $nodeType): void
{
// this getter throws if any of the child nodeTypes doesnt exist!
$tetheredNodeTypes = $this->getNodeTypeManager()->getTetheredNodesConfigurationForNodeType($nodeType);
$tetheredNodeTypes = $this->getNodeTypeManager()->getTetheredNodesConfigurationForNodeType($nodeType->name);
foreach ($tetheredNodeTypes as $tetheredNodeType) {
$this->requireTetheredDescendantNodeTypesToExist($tetheredNodeType);
}
Expand All @@ -176,7 +176,7 @@ protected function requireTetheredDescendantNodeTypesToExist(NodeType $nodeType)
*/
protected function requireTetheredDescendantNodeTypesToNotBeOfTypeRoot(NodeType $nodeType): void
{
foreach ($this->getNodeTypeManager()->getTetheredNodesConfigurationForNodeType($nodeType) as $tetheredChildNodeType) {
foreach ($this->getNodeTypeManager()->getTetheredNodesConfigurationForNodeType($nodeType->name) as $tetheredChildNodeType) {
if ($tetheredChildNodeType->isOfType(NodeTypeName::ROOT_NODE_TYPE_NAME)) {
throw new NodeTypeIsOfTypeRoot(
'Node type "' . $nodeType->name->value . '" for tethered descendant is of type root.',
Expand Down Expand Up @@ -299,11 +299,11 @@ protected function requireNodeTypeConstraintsImposedByParentToBeMet(
if (
$nodeName
&& $parentsNodeType->hasTetheredNode($nodeName)
&& !$this->getNodeTypeManager()->getTypeOfTetheredNode($parentsNodeType, $nodeName)->name->equals($nodeType->name)
&& !$this->getNodeTypeManager()->getTypeOfTetheredNode($parentsNodeType->name, $nodeName)->name->equals($nodeType->name)
) {
throw new NodeConstraintException(
'Node type "' . $nodeType->name->value . '" does not match configured "'
. $this->getNodeTypeManager()->getTypeOfTetheredNode($parentsNodeType, $nodeName)->name->value
. $this->getNodeTypeManager()->getTypeOfTetheredNode($parentsNodeType->name, $nodeName)->name->value
. '" for auto created child nodes for parent type "' . $parentsNodeType->name->value
. '" with name "' . $nodeName->value . '"'
);
Expand All @@ -322,7 +322,7 @@ protected function areNodeTypeConstraintsImposedByParentValid(
if (
$nodeName
&& $parentsNodeType->hasTetheredNode($nodeName)
&& !$this->getNodeTypeManager()->getTypeOfTetheredNode($parentsNodeType, $nodeName)->name->equals($nodeType->name)
&& !$this->getNodeTypeManager()->getTypeOfTetheredNode($parentsNodeType->name, $nodeName)->name->equals($nodeType->name)
) {
return false;
}
Expand Down Expand Up @@ -360,7 +360,7 @@ protected function areNodeTypeConstraintsImposedByGrandparentValid(
if (
$parentNodeName
&& $grandParentsNodeType->hasTetheredNode($parentNodeName)
&& !$this->getNodeTypeManager()->isNodeTypeAllowedAsChildToTetheredNode($grandParentsNodeType, $parentNodeName, $nodeType)
&& !$this->getNodeTypeManager()->isNodeTypeAllowedAsChildToTetheredNode($grandParentsNodeType->name, $parentNodeName, $nodeType->name)
) {
return false;
}
Expand Down
Expand Up @@ -212,7 +212,7 @@ protected function checkConstraintsImposedByAncestors(
if (
$nodeAggregate->nodeName
&& $parentsNodeType->hasTetheredNode($nodeAggregate->nodeName)
&& $this->nodeTypeManager->getTypeOfTetheredNode($parentsNodeType, $nodeAggregate->nodeName)->name
&& $this->nodeTypeManager->getTypeOfTetheredNode($parentsNodeType->name, $nodeAggregate->nodeName)->name
!== $command->newNodeTypeName->value
) {
throw new NodeConstraintException(
Expand All @@ -234,9 +234,9 @@ protected function checkConstraintsImposedByAncestors(
$parentAggregate->nodeName
&& $grandParentsNodeType->hasTetheredNode($parentAggregate->nodeName)
&& !$this->nodeTypeManager->isNodeTypeAllowedAsChildToTetheredNode(
$grandParentsNodeType,
$grandParentsNodeType->name,
$parentAggregate->nodeName,
$newNodeType
$newNodeType->name
)
) {
throw new NodeConstraintException(
Expand Down
Expand Up @@ -128,7 +128,7 @@ private static function createNodeAggregateIdsForNodeType(
?string $pathPrefix = null
): array {
$nodeAggregateIds = [];
foreach ($nodeTypeManager->getTetheredNodesConfigurationForNodeType($nodeTypeManager->getNodeType($nodeTypeName)) as $nodeName => $childNodeType) {
foreach ($nodeTypeManager->getTetheredNodesConfigurationForNodeType($nodeTypeName) as $nodeName => $childNodeType) {
$path = $pathPrefix ? $pathPrefix . '/' . $nodeName : $nodeName;
$nodeAggregateIds[$path] = NodeAggregateId::create();
$nodeAggregateIds = array_merge(
Expand Down
Expand Up @@ -235,7 +235,7 @@ private function handleCreateNodeAggregateWithNodeAndSerializedProperties(

array_push($events, ...iterator_to_array($this->handleTetheredChildNodes(
$command,
$nodeType,
$command->nodeTypeName,
$coveredDimensionSpacePoints,
$command->nodeAggregateId,
$descendantNodeAggregateIds,
Expand Down Expand Up @@ -276,17 +276,16 @@ private function createRegularWithNode(
*/
private function handleTetheredChildNodes(
CreateNodeAggregateWithNodeAndSerializedProperties $command,
NodeType $nodeType,
NodeTypeName $nodeTypeName,
DimensionSpacePointSet $coveredDimensionSpacePoints,
NodeAggregateId $parentNodeAggregateId,
NodeAggregateIdsByNodePaths $nodeAggregateIds,
?NodePath $nodePath,
ContentRepository $contentRepository,
): Events {
$events = [];
foreach ($this->getNodeTypeManager()->getTetheredNodesConfigurationForNodeType($nodeType) as $rawNodeName => $childNodeType) {
assert($childNodeType instanceof NodeType);
$nodeName = NodeName::fromString($rawNodeName);
foreach ($this->getNodeTypeManager()->getTetheredNodesConfigurationForNodeType($nodeTypeName) as $nodeNameString => $childNodeType) {
$nodeName = NodeName::fromString($nodeNameString);
$childNodePath = $nodePath
? $nodePath->appendPathSegment($nodeName)
: NodePath::fromString($nodeName->value);
Expand All @@ -307,7 +306,7 @@ private function handleTetheredChildNodes(

array_push($events, ...iterator_to_array($this->handleTetheredChildNodes(
$command,
$childNodeType,
$childNodeType->name,
$coveredDimensionSpacePoints,
$childNodeAggregateId,
$nodeAggregateIds,
Expand Down
Expand Up @@ -27,6 +27,7 @@
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\NodeTypeName;
use Neos\ContentRepository\Core\Projection\ContentGraph\Node;
use Neos\ContentRepository\Core\Projection\ContentGraph\NodeAggregate;
use Neos\ContentRepository\Core\Projection\ContentGraph\NodePath;
Expand Down Expand Up @@ -153,7 +154,7 @@ private function handleChangeNodeAggregateType(
* Preparation - make the command fully deterministic in case of rebase
**************/
$descendantNodeAggregateIds = $command->tetheredDescendantNodeAggregateIds->completeForNodeOfType(
$newNodeType->name,
$command->newNodeTypeName,
$this->nodeTypeManager
);
// Write the auto-created descendant node aggregate ids back to the command;
Expand All @@ -180,13 +181,13 @@ private function handleChangeNodeAggregateType(
)));
array_push($events, ...iterator_to_array($this->deleteObsoleteTetheredNodesWhenChangingNodeType(
$nodeAggregate,
$newNodeType,
$command->newNodeTypeName,
$contentRepository
)));
}

// new tethered child nodes
$expectedTetheredNodes = $this->getNodeTypeManager()->getTetheredNodesConfigurationForNodeType($newNodeType);
$expectedTetheredNodes = $this->getNodeTypeManager()->getTetheredNodesConfigurationForNodeType($command->newNodeTypeName);
foreach ($nodeAggregate->getNodes() as $node) {
assert($node instanceof Node);
foreach ($expectedTetheredNodes as $serializedTetheredNodeName => $expectedTetheredNodeType) {
Expand Down Expand Up @@ -364,10 +365,10 @@ private function deleteDisallowedNodesWhenChangingNodeType(

private function deleteObsoleteTetheredNodesWhenChangingNodeType(
NodeAggregate $nodeAggregate,
NodeType $newNodeType,
NodeTypeName $newNodeTypeName,
ContentRepository $contentRepository
): Events {
$expectedTetheredNodes = $this->getNodeTypeManager()->getTetheredNodesConfigurationForNodeType($newNodeType);
$expectedTetheredNodes = $this->getNodeTypeManager()->getTetheredNodesConfigurationForNodeType($newNodeTypeName);

$events = [];
// find disallowed tethered nodes
Expand Down
Expand Up @@ -102,7 +102,7 @@ private function handleCreateRootNodeAggregateWithNode(
foreach ($this->getInterDimensionalVariationGraph()->getRootGeneralizations() as $rootGeneralization) {
array_push($events, ...iterator_to_array($this->handleTetheredRootChildNodes(
$command,
$nodeType,
$command->nodeTypeName,
OriginDimensionSpacePoint::fromDimensionSpacePoint($rootGeneralization),
$this->getInterDimensionalVariationGraph()->getSpecializationSet($rootGeneralization, true),
$command->nodeAggregateId,
Expand Down Expand Up @@ -183,7 +183,7 @@ private function handleUpdateRootNodeAggregateDimensions(
*/
private function handleTetheredRootChildNodes(
CreateRootNodeAggregateWithNode $command,
NodeType $nodeType,
NodeTypeName $nodeTypeName,
OriginDimensionSpacePoint $originDimensionSpacePoint,
DimensionSpacePointSet $coveredDimensionSpacePoints,
NodeAggregateId $parentNodeAggregateId,
Expand All @@ -192,9 +192,8 @@ private function handleTetheredRootChildNodes(
ContentRepository $contentRepository,
): Events {
$events = [];
foreach ($this->getNodeTypeManager()->getTetheredNodesConfigurationForNodeType($nodeType) as $rawNodeName => $childNodeType) {
assert($childNodeType instanceof NodeType);
$nodeName = NodeName::fromString($rawNodeName);
foreach ($this->getNodeTypeManager()->getTetheredNodesConfigurationForNodeType($nodeTypeName) as $nodeNameString => $childNodeType) {
$nodeName = NodeName::fromString($nodeNameString);
$childNodePath = $nodePath
? $nodePath->appendPathSegment($nodeName)
: NodePath::fromString($nodeName->value);
Expand All @@ -216,7 +215,7 @@ private function handleTetheredRootChildNodes(

array_push($events, ...iterator_to_array($this->handleTetheredRootChildNodes(
$command,
$childNodeType,
$childNodeType->name,
$originDimensionSpacePoint,
$coveredDimensionSpacePoints,
$childNodeAggregateId,
Expand Down
26 changes: 14 additions & 12 deletions Neos.ContentRepository.Core/Classes/NodeType/NodeTypeManager.php
Expand Up @@ -199,14 +199,14 @@ public function overrideNodeTypes(array $completeNodeTypeConfiguration): void
}

/**
* @param NodeType $nodeType
* @param NodeTypeName $nodeTypeName
* @param NodeName $tetheredNodeName
* @return NodeType
*@throws TetheredNodeNotConfigured if the requested tethered node is not configured. Check via {@see NodeType::hasTetheredNode()}.
*/
public function getTypeOfTetheredNode(NodeType $nodeType, NodeName $tetheredNodeName): NodeType
public function getTypeOfTetheredNode(NodeTypeName $nodeTypeName, NodeName $tetheredNodeName): NodeType
{
$nameOfTetheredNode = $nodeType->getNodeTypeNameOfTetheredNode($tetheredNodeName);
$nameOfTetheredNode = $this->getNodeType($nodeTypeName)->getNodeTypeNameOfTetheredNode($tetheredNodeName);
return $this->getNodeType($nameOfTetheredNode);
}

Expand All @@ -216,9 +216,9 @@ public function getTypeOfTetheredNode(NodeType $nodeType, NodeName $tetheredNode
* @return array<string,NodeType> the key of this array is the name of the child, and the value its NodeType.
* @api
*/
public function getTetheredNodesConfigurationForNodeType(NodeType $nodeType): array
public function getTetheredNodesConfigurationForNodeType(NodeTypeName $nodeTypeName): array
{
$childNodeConfiguration = $nodeType->getConfiguration('childNodes');
$childNodeConfiguration = $this->getNodeType($nodeTypeName)->getConfiguration('childNodes');
$autoCreatedChildNodes = [];
foreach ($childNodeConfiguration ?? [] as $childNodeName => $configurationForChildNode) {
if (isset($configurationForChildNode['type'])) {
Expand All @@ -234,21 +234,21 @@ public function getTetheredNodesConfigurationForNodeType(NodeType $nodeType): ar
*
* Only allowed to be called if $tetheredNodeName is actually tethered.
*
* @param NodeType $parentNodeType The NodeType to check constraints based on.
* @param NodeTypeName $parentNodeTypeName The NodeType to check constraints based on.
* @param NodeName $tetheredNodeName The name of a configured tethered node of this NodeType
* @param NodeType $nodeType The NodeType to check constraints for.
* @param NodeTypeName $nodeTypeName The NodeType to check constraints for.
* @return bool true if the $nodeType is allowed as grandchild node, false otherwise.
* @throws \InvalidArgumentException if the requested tethered node is not configured in the parent NodeType. Check via {@see NodeType::hasTetheredNode()}.
*/
public function isNodeTypeAllowedAsChildToTetheredNode(NodeType $parentNodeType, NodeName $tetheredNodeName, NodeType $nodeType): bool
public function isNodeTypeAllowedAsChildToTetheredNode(NodeTypeName $parentNodeTypeName, NodeName $tetheredNodeName, NodeTypeName $nodeTypeName): bool
{
try {
$typeOfTetheredNode = $this->getTypeOfTetheredNode($parentNodeType, $tetheredNodeName);
$typeOfTetheredNode = $this->getTypeOfTetheredNode($parentNodeTypeName, $tetheredNodeName);
} catch (TetheredNodeNotConfigured $exception) {
throw new \InvalidArgumentException(
sprintf(
'Cannot determine if grandchild is allowed in %s. Because the given child node name "%s" is not auto-created.',
$parentNodeType->name->value,
$parentNodeTypeName->value,
$tetheredNodeName->value
),
1403858395,
Expand All @@ -261,15 +261,17 @@ public function isNodeTypeAllowedAsChildToTetheredNode(NodeType $parentNodeType,

// Constraints configured at the childNode configuration of the parent.
try {
$childNodeConstraintConfiguration = $parentNodeType->getConfiguration('childNodes.' . $tetheredNodeName->value . '.constraints.nodeTypes') ?? [];
$childNodeConstraintConfiguration = $this->getNodeType($parentNodeTypeName)->getConfiguration('childNodes.' . $tetheredNodeName->value . '.constraints.nodeTypes') ?? [];
} catch (PropertyNotAccessibleException $exception) {
// We ignore this because the configuration might just not have any constraints, if the childNode was not configured the exception above would have been thrown.
$childNodeConstraintConfiguration = [];
}

$constraints = Arrays::arrayMergeRecursiveOverrule($constraints, $childNodeConstraintConfiguration);

return ConstraintCheck::create($constraints)->isNodeTypeAllowed($nodeType);
return ConstraintCheck::create($constraints)->isNodeTypeAllowed(
$this->getNodeType($nodeTypeName)
);
}

/**
Expand Down
Expand Up @@ -73,19 +73,17 @@ public function findAdjustmentsForNodeType(NodeTypeName $nodeTypeName): \Generat
}

$allowedByGrandparent = false;
$grandparentNodeType = null;
if (
$parentNode !== null
&& $grandparentNode !== null
&& $parentNode->classification->isTethered()
&& !is_null($parentNode->nodeName)
) {
$grandparentNodeType = $this->nodeTypeManager->hasNodeType($grandparentNode->nodeTypeName) ? $this->nodeTypeManager->getNodeType($grandparentNode->nodeTypeName) : null;
if ($grandparentNodeType !== null) {
if ($this->nodeTypeManager->hasNodeType($grandparentNode->nodeTypeName)) {
$allowedByGrandparent = $this->nodeTypeManager->isNodeTypeAllowedAsChildToTetheredNode(
$grandparentNodeType,
$grandparentNode->nodeTypeName,
$parentNode->nodeName,
$nodeType
$nodeAggregate->nodeTypeName
);
}
}
Expand All @@ -102,9 +100,9 @@ public function findAdjustmentsForNodeType(NodeTypeName $nodeTypeName): \Generat
and the grandparent node type "%s" is not allowing grandchildren of type "%s".
Thus, the node is invalid at this location and should be removed.
',
$parentNodeType !== null ? $parentNodeType->name->value : '',
$parentNode?->nodeTypeName->value ?? '',
$node->nodeTypeName->value,
$grandparentNodeType !== null ? $grandparentNodeType->name->value : '',
$grandparentNode?->nodeTypeName->value ?? '',
$node->nodeTypeName->value,
);

Expand Down
Expand Up @@ -54,7 +54,7 @@ public function findAdjustmentsForNodeType(NodeTypeName $nodeTypeName): \Generat
return;
}
$nodeType = $this->nodeTypeManager->getNodeType($nodeTypeName);
$expectedTetheredNodes = $this->nodeTypeManager->getTetheredNodesConfigurationForNodeType($nodeType);
$expectedTetheredNodes = $this->nodeTypeManager->getTetheredNodesConfigurationForNodeType($nodeTypeName);

foreach ($this->projectedNodeIterator->nodeAggregatesOfType($nodeTypeName) as $nodeAggregate) {
// find missing tethered nodes
Expand Down

0 comments on commit 8dfe476

Please sign in to comment.