diff --git a/Neos.ContentRepositoryRegistry/Classes/Command/CrCommandController.php b/Neos.ContentRepositoryRegistry/Classes/Command/CrCommandController.php index c3704829d7b..cc172ed1667 100644 --- a/Neos.ContentRepositoryRegistry/Classes/Command/CrCommandController.php +++ b/Neos.ContentRepositoryRegistry/Classes/Command/CrCommandController.php @@ -8,6 +8,8 @@ use Neos\ContentRepository\Core\Service\ContentStreamPrunerFactory; use Neos\ContentRepository\Core\Service\WorkspaceMaintenanceServiceFactory; use Neos\ContentRepository\Core\SharedModel\ContentRepository\ContentRepositoryId; +use Neos\ContentRepository\Core\SharedModel\Exception\RootNodeAggregateDoesNotExist; +use Neos\ContentRepository\Core\SharedModel\Exception\WorkspaceDoesNotExist; use Neos\ContentRepository\Core\SharedModel\Workspace\WorkspaceName; use Neos\ContentRepositoryRegistry\ContentRepositoryRegistry; use Neos\ContentRepositoryRegistry\Exception\InvalidConfigurationException; @@ -15,6 +17,7 @@ use Neos\EventStore\Model\Event\SequenceNumber; use Neos\EventStore\Model\EventStore\StatusType; use Neos\Flow\Cli\CommandController; +use Neos\Neos\Domain\Service\NodeTypeNameFactory; use Symfony\Component\Console\Helper\ProgressBar; use Symfony\Component\Console\Output\ConsoleOutput; use Neos\Flow\Persistence\Doctrine\Exception\DatabaseException; @@ -251,10 +254,11 @@ public function pruneCommand(string $contentRepository = 'default', bool $force $this->outputLine('Done.'); } - public function listCommand() + /** + * @param bool $verbose shows additional internal output regarding content-streams and nodes in the projection + */ + public function listCommand(bool $verbose = false): void { - $rows = []; - /** @var list $sites */ $sites = []; try { @@ -264,6 +268,7 @@ public function listCommand() $this->outputLine('Site repository is not accessible.'); } + $rows = []; foreach ($this->contentRepositoryRegistry->getContentRepositoryIds() as $contentRepositoryId) { $contentRepository = null; try { @@ -272,12 +277,46 @@ public function listCommand() $this->outputLine('Content repository %s is not well configures: %s.', [$contentRepositoryId->value, $exception->getMessage()]); } + + $liveContentGraph = null; + try { + $liveContentGraph = $contentRepository->getContentGraph(WorkspaceName::forLive()); + } catch (WorkspaceDoesNotExist) { + $this->outputLine('Live workspace in content repository %s not existing.', [$contentRepositoryId->value]); + } + + $siteNodes = []; + // todo wrap in catch runtime exception + if ($liveContentGraph && $verbose) { + $sitesAggregate = null; + try { + $sitesAggregate = $liveContentGraph->findRootNodeAggregateByType(NodeTypeNameFactory::forSites()); + } catch (RootNodeAggregateDoesNotExist) { + $this->outputLine('Sites root node does not exist in content repository %s.', [$contentRepositoryId->value]); + } + + if ($sitesAggregate) { + $siteNodeAggregates = $liveContentGraph->findChildNodeAggregates($sitesAggregate->nodeAggregateId); + foreach ($siteNodeAggregates as $siteNodeAggregate) { + $siteNodes[] = $siteNodeAggregate->nodeName->value; + } + } + } + $configuredSites = []; foreach ($sites as $site) { if (!$site->getConfiguration()->contentRepositoryId->equals($contentRepositoryId)) { continue; } - $configuredSites[] = $site->getName(); + $configuredSites[] = $site->getNodeName()->value; + } + + if ($verbose) { + $connectedSites = array_intersect($configuredSites, $siteNodes); + $unconnectedSiteNodes = array_diff($configuredSites, $siteNodes); + $sitesString = ltrim((join(', ', $connectedSites) . ($unconnectedSiteNodes ? (', (detached: ' . join(', ', $unconnectedSiteNodes) . ')') : '')), ' ,') ?: '-'; + } else { + $sitesString = join(', ', $configuredSites) ?: '-'; } $statusString = '-'; @@ -289,34 +328,37 @@ public function listCommand() $statusString = $contentRepository->status()->isOk() ? 'okay' : 'not okay'; try { - $workspacesString = sprintf('%d entries', count($contentRepository->getWorkspaceFinder()->findAll())); - } catch (\Throwable $e) { + $workspacesString = sprintf('%d found', count($contentRepository->getWorkspaceFinder()->findAll())); + } catch (\RuntimeException $e) { $this->outputLine('WorkspaceFinder of %s not functional: %s.', [$contentRepositoryId->value, $e->getMessage()]); } - try { - $contentStreamsString = sprintf('%d entries', iterator_count($contentRepository->getContentStreamFinder()->findAllIds())); - } catch (\Throwable $e) { - $this->outputLine('ContentStreamFinder of %s not functional: %s.', [$contentRepositoryId->value, $e->getMessage()]); - } - - try { - $nodesString = sprintf('%d entries', $contentRepository->getContentGraph(WorkspaceName::forLive())->countNodes()); - } catch (\RuntimeException $e) { - $this->outputLine('ContentGraph of %s not functional: %s.', [$contentRepositoryId->value, $e->getMessage()]); + if ($verbose) { + try { + $contentStreamsString = sprintf('%d found', iterator_count($contentRepository->getContentStreamFinder()->findAllIds())); + } catch (\RuntimeException $e) { + $this->outputLine('ContentStreamFinder of %s not functional: %s.', [$contentRepositoryId->value, $e->getMessage()]); + } + + try { + if ($liveContentGraph) { + $nodesString = sprintf('%d found', $liveContentGraph->countNodes()); + } + } catch (\RuntimeException $e) { + $this->outputLine('ContentGraph of %s not functional: %s.', [$contentRepositoryId->value, $e->getMessage()]); + } } } $rows[] = [ $contentRepositoryId->value, $statusString, - join(', ', $configuredSites) ?: '-', + $sitesString, $workspacesString, - $contentStreamsString, - $nodesString + ...($verbose ? [$contentStreamsString, $nodesString] : []) ]; } - $this->output->outputTable($rows, ['Identifier', 'Status', 'Sites', 'Workspaces', 'Contentstreams', 'Nodes']); + $this->output->outputTable($rows, ['Identifier', 'Status', 'Sites', 'Workspaces', ...($verbose ? ['Contentstreams', 'Nodes'] : [])]); } }