public function removeBrokenEntityReferences($workspaceName, $dryRun)
{
$this->output->outputLine('Checking for broken entity references ...');
/** @var \Neos\ContentRepository\Domain\Model\Workspace $workspace */
$workspace = $this->workspaceRepository->findByIdentifier($workspaceName);
$nodeTypesWithEntityReferences = array();
foreach ($this->nodeTypeManager->getNodeTypes() as $nodeType) {
/** @var NodeType $nodeType */
foreach (array_keys($nodeType->getProperties()) as $propertyName) {
$propertyType = $nodeType->getPropertyType($propertyName);
if (strpos($propertyType, '\\') !== false) {
if (!isset($nodeTypesWithEntityReferences[$nodeType->getName()])) {
$nodeTypesWithEntityReferences[$nodeType->getName()] = array();
}
$nodeTypesWithEntityReferences[$nodeType->getName()][$propertyName] = $propertyType;
}
}
}
$nodesWithBrokenEntityReferences = array();
$brokenReferencesCount = 0;
foreach ($nodeTypesWithEntityReferences as $nodeTypeName => $properties) {
$nodeDatas = $this->nodeDataRepository->findByParentAndNodeTypeRecursively('/', $nodeTypeName, $workspace);
foreach ($nodeDatas as $nodeData) {
/** @var NodeData $nodeData */
foreach ($properties as $propertyName => $propertyType) {
$propertyValue = $nodeData->getProperty($propertyName);
$convertedProperty = null;
if (is_object($propertyValue)) {
$convertedProperty = $propertyValue;
}
if (is_string($propertyValue) && strlen($propertyValue) === 36) {
$convertedProperty = $this->propertyMapper->convert($propertyValue, $propertyType);
if ($convertedProperty === null) {
$nodesWithBrokenEntityReferences[$nodeData->getIdentifier()][$propertyName] = $nodeData;
$this->output->outputLine('Broken reference in "%s", property "%s" (%s) referring to %s.', array($nodeData->getPath(), $nodeData->getIdentifier(), $propertyName, $propertyType, $propertyValue));
$brokenReferencesCount++;
}
}
if ($convertedProperty instanceof Proxy) {
try {
$convertedProperty->__load();
} catch (EntityNotFoundException $e) {
$nodesWithBrokenEntityReferences[$nodeData->getIdentifier()][$propertyName] = $nodeData;
$this->output->outputLine('Broken reference in "%s", property "%s" (%s) referring to %s.', array($nodeData->getPath(), $nodeData->getIdentifier(), $propertyName, $propertyType, $propertyValue));
$brokenReferencesCount++;
}
}
}
}
}
if ($brokenReferencesCount > 0) {
$this->output->outputLine();
if (!$dryRun) {
$self = $this;
$this->askBeforeExecutingTask('Do you want to remove the broken entity references?', function () use($self, $nodesWithBrokenEntityReferences, $brokenReferencesCount, $workspaceName, $dryRun) {
foreach ($nodesWithBrokenEntityReferences as $nodeIdentifier => $properties) {
foreach ($properties as $propertyName => $nodeData) {
/** @var NodeData $nodeData */
$nodeData->setProperty($propertyName, null);
}
}
$self->output->outputLine('Removed %s broken entity reference%s.', array($brokenReferencesCount, $brokenReferencesCount > 1 ? 's' : ''));
});
} else {
$this->output->outputLine('Found %s broken entity reference%s to be removed.', array($brokenReferencesCount, $brokenReferencesCount > 1 ? 's' : ''));
}
$this->output->outputLine();
$this->persistenceManager->persistAll();
}
}