/**
* Performs checks for disallowed child nodes according to the node's auto-create configuration and constraints
* and removes them if found.
*
* @param string $workspaceName
* @param boolean $dryRun Simulate?
* @return void
*/
protected function removeDisallowedChildNodes($workspaceName, $dryRun)
{
$this->output->outputLine('Checking for disallowed child nodes ...');
/** @var \Doctrine\ORM\QueryBuilder $queryBuilder */
$queryBuilder = $this->entityManager->createQueryBuilder();
/** @var \Neos\ContentRepository\Domain\Model\Workspace $workspace */
$workspace = $this->workspaceRepository->findByIdentifier($workspaceName);
$nodes = array();
$nodeExceptionCount = 0;
$removeDisallowedChildNodes = function (NodeInterface $node) use(&$removeDisallowedChildNodes, &$nodes, &$nodeExceptionCount, $queryBuilder) {
try {
foreach ($node->getChildNodes() as $childNode) {
/** @var $childNode NodeInterface */
if (!$childNode->isAutoCreated() && !$node->isNodeTypeAllowedAsChildNode($childNode->getNodeType())) {
$nodes[] = $childNode;
$parent = $node->isAutoCreated() ? $node->getParent() : $node;
$this->output->outputLine('Found disallowed node named "%s" (%s) in "%s", child of node "%s" (%s)', array($childNode->getName(), $childNode->getNodeType()->getName(), $childNode->getPath(), $parent->getName(), $parent->getNodeType()->getName()));
} else {
$removeDisallowedChildNodes($childNode);
}
}
} catch (\Exception $e) {
$nodeExceptionCount++;
}
};
// TODO: Performance could be improved by a search for all child node data instead of looping over all contexts
foreach ($this->contentDimensionCombinator->getAllAllowedCombinations() as $dimensionConfiguration) {
$context = $this->createContext($workspace->getName(), $dimensionConfiguration);
$removeDisallowedChildNodes($context->getRootNode());
$context->getFirstLevelNodeCache()->flush();
$this->nodeFactory->reset();
}
$disallowedChildNodesCount = count($nodes);
if ($disallowedChildNodesCount > 0) {
$this->output->outputLine();
if (!$dryRun) {
$self = $this;
$this->askBeforeExecutingTask('Do you want to remove all disallowed child nodes?', function () use($self, $nodes, $disallowedChildNodesCount, $workspaceName) {
foreach ($nodes as $node) {
$self->removeNodeAndChildNodesInWorkspaceByPath($node->getPath(), $workspaceName);
}
$self->output->outputLine('Removed %s disallowed node%s.', array($disallowedChildNodesCount, $disallowedChildNodesCount > 1 ? 's' : ''));
});
} else {
$this->output->outputLine('Found %s disallowed node%s to be removed.', array($disallowedChildNodesCount, $disallowedChildNodesCount > 1 ? 's' : ''));
}
if ($nodeExceptionCount > 0) {
$this->output->outputLine();
$this->output->outputLine('%s error%s occurred during child node traversing.', array($nodeExceptionCount, $nodeExceptionCount > 1 ? 's' : ''));
}
$this->output->outputLine();
}
}