addOption( 'group', 'g', InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, 'Show only groups with given uid', ) ->addOption( 'watch', 'w', InputOption::VALUE_OPTIONAL, 'Start watcher mode (polling)', ); } public function execute(InputInterface $input, OutputInterface $output): int { if (!$output instanceof ConsoleOutputInterface) { throw new \InvalidArgumentException('This command accepts only an instance of "ConsoleOutputInterface".', 1678645754); } // Make sure the _cli_ user is loaded Bootstrap::initializeBackendAuthentication(); $this->io = new SymfonyStyle($input, $output); $languageService = $this->getLanguageService(); $tableHeader = [ $languageService->sL('scheduler.messages:label.id'), $languageService->sL('scheduler.messages:task'), $languageService->sL('scheduler.messages:label.description'), $languageService->sL('scheduler.messages:label.frequency'), $languageService->sL('scheduler.messages:status'), ]; $tableSection = $output->section(); $tableBuffer = new BufferedOutput(OutputInterface::VERBOSITY_NORMAL, true); $table = new Table($tableBuffer); $table->setHeaders($tableHeader); $showGroups = $input->getOption('group'); $rows = $this->getTableRows($showGroups); $table->setRows($rows); $table->setColumnMaxWidth(1, 50); $table->setColumnMaxWidth(2, 50); $table->setColumnMaxWidth(4, 50); $table->render(); $bufferedData = $tableBuffer->fetch(); $tableSection->overwrite($bufferedData); $doWatch = $input->hasParameterOption('--watch') || $input->hasParameterOption('-w'); if ($doWatch) { $infoSection = $output->section(); $interval = (int)($input->getOption('watch') ?: 1); $infoSection->write('Watching tasks every ' . $interval . ' seconds, press CTRL+C to stop watching'); while (true) { // @phpstan-ignore while.alwaysTrue (intentional infinite loop for CLI watch mode, terminated by CTRL+C signal) sleep($interval); $this->updateTable($input, $table, $tableBuffer, $tableSection); } } return Command::SUCCESS; } private function getTableRows(array $groups = []): array { $tasks = $this->taskRepository->getGroupedTasks(); $languageService = $this->getLanguageService(); $rows = []; foreach ($tasks['taskGroupsWithTasks'] as $uid => $group) { if (!in_array($uid, $groups) && count($groups) > 0) { continue; } // Flag as disabled group $groupDisabledLabel = $group['hidden'] ? '' . $this->getLanguageService()->sL('scheduler.messages:status.disabled') . '' : ''; $groupLabel = ($group['groupName'] ?? $languageService->sL('scheduler.messages:label.noGroup')) . ' (id:' . $uid . ') ' . $groupDisabledLabel; $rows[] = [new TableSeparator(['colspan' => 5])]; $rows[] = [new TableCell('' . $groupLabel . '', ['colspan' => 5])]; $rows[] = [new TableSeparator(['colspan' => 5])]; foreach ($group['tasks'] as $task) { $progress = $task['progress'] ?? false; $taskStatus = []; /** @var TaskStatus $status */ foreach ($task['statuses'] as $status) { $color = match ($status->severity) { ContextualFeedbackSeverity::OK => 'green', ContextualFeedbackSeverity::INFO => 'blue', ContextualFeedbackSeverity::WARNING => 'yellow', ContextualFeedbackSeverity::ERROR => 'red', ContextualFeedbackSeverity::NOTICE => 'gray', }; $label = $languageService->sL($status->label); if ($status->type === 'running' && $progress) { $label .= ' (' . $progress . ')'; } // The console has no tooltip, so the more detailed message // (e.g. the failure reason) is shown inline instead. if ($status->message !== '') { $label .= ' (' . vsprintf($languageService->sL($status->message), $status->messageArguments) . ')'; } $taskStatus[] = '' . $label . ''; } $taskTitle = $task['fullTitle'] . (empty($task['additionalInformation']) ? '' : ' (' . $task['additionalInformation'] . ')'); $rows[] = [ $task['uid'], $taskTitle, $task['description'], $task['frequency'], implode(', ', $taskStatus), ]; } } return $rows; } private function getLanguageService(): LanguageService { return GeneralUtility::makeInstance(LanguageServiceFactory::class)->create('en'); } protected function updateTable(InputInterface $input, Table $table, BufferedOutput $buffer, ConsoleSectionOutput $tableSection): void { $tableSection->overwrite(''); $rows = $this->getTableRows($input->getOption('group')); $table->setRows($rows)->render(); $bufferedData = $buffer->fetch(); $tableSection->overwrite($bufferedData); } }