/** * 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(); } }