Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save skurfuerst/beb644cc81af76eca7a321bb00dc07ee to your computer and use it in GitHub Desktop.
Save skurfuerst/beb644cc81af76eca7a321bb00dc07ee to your computer and use it in GitHub Desktop.
Make Nodes Unique
<?php
namespace My\Package\Command;
use Neos\ContentRepository\Domain\Model\NodeInterface;
use Neos\ContentRepository\Domain\Service\ContextFactoryInterface;
use Neos\ContentRepository\Domain\Service\NodeServiceInterface;
use Neos\Flow\Cli\CommandController;
use Neos\Flow\Annotations as Flow;
class NodeNameUniquenessMigrationCommandController extends CommandController
{
/**
* @Flow\Inject
* @var ContextFactoryInterface
*/
protected $contextFactory;
/**
* @Flow\Inject
* @var NodeServiceInterface
*/
protected $nodeService;
/**
* @param string $contentDimension
* @param string $contentDimensionValue
*/
public function fixCommand($contentDimension = null, $contentDimensionValue = null)
{
$contextProperties = [
'workspaceName' => 'live',
'invisibleContentShown' => true,
'inaccessibleContentShown' => true,
'removedContentShown' => true
];
if ($contentDimension && $contentDimensionValue) {
$this->outputLine('!!! Multilanguage case: ' . $contentDimension . ' - ' . $contentDimensionValue);
$contextProperties['dimensions'] = [
$contentDimension => [$contentDimensionValue]
];
$contextProperties['targetDimensions'] = [
$contentDimension => $contentDimensionValue
];
} else {
$this->outputLine('Single-Dimension Case');
}
$context = $this->contextFactory->create($contextProperties);
$rootNode = $context->getNode('/')->getNode('sites/oekokiste-site');
// We fill this list incrementally to store which node names we have already seen. If we found a seen node name, we start
// to rename.
$nodeNamesOfNonAutoCreatedChildNodes = [];
$this->traverseNodeTreeAndDetectNeededRenames($rootNode, $nodeNamesOfNonAutoCreatedChildNodes);
$this->outputLine('Done.');
}
protected function traverseNodeTreeAndDetectNeededRenames(NodeInterface $node, &$nodeNamesOfNonAutoCreatedChildNodes) {
// auto-created nodes (like "main" or "spalte-1") will have name collisions; so we ignore them
if (!$node->isAutoCreated()) {
if (array_key_exists($node->getName(), $nodeNamesOfNonAutoCreatedChildNodes)) {
$newNodeName = $this->nodeService->generateUniqueNodeName($node->getParentPath());
$this->outputLine('Duplicate: %s -> %s at path %s', [
$node->getName(),
$newNodeName,
$node->getPath()
]
);
// This updates the node names recursively - I always feared that some parts inside here
// would break when being called repeatedly; but it seems to work just fine. That
// was the biggest risk for me.
// Phew ;-)
$node->setName($newNodeName);
}
$nodeNamesOfNonAutoCreatedChildNodes[$node->getName()] = true;
}
// Traverse to all children.
// NOTE: $node->getChildNodes() works DESPITE having maybe renamed $node (and thus the children's paths as well).
// We're lucky today :-)
foreach ($node->getChildNodes() as $childNode) {
$this->traverseNodeTreeAndDetectNeededRenames($childNode, $nodeNamesOfNonAutoCreatedChildNodes);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment