addOption('log', null, InputOption::VALUE_NONE, 'Zusätzlich die letzten Protokollzeilen.'); } protected function execute(InputInterface $input, OutputInterface $output): int { $io = new SymfonyStyle($input, $output); // Erst der Abgleich (er legt fehlende Zeilen an und schreibt die Zustandsdatei neu), dann // die Auskunft daraus - sonst zeigt der erste Aufruf nach einem Update einen Zeitpunkt, // der eine Sekunde spaeter schon nicht mehr stimmt. $tasks = $this->scheduler->overview(); $state = $this->scheduler->fastState(); $io->writeln(sprintf( 'Auslöser: Besuch %s, Verwaltung %s. Konsole und URL-Cron laufen immer.', $state['traffic'] ? 'an' : 'aus', $state['admin'] ? 'an' : 'aus', )); $io->writeln(sprintf( 'Jetzt ist %s UTC; das nächste Mal steht %s an.', gmdate('Y-m-d H:i:s'), null === $state['next'] ? 'unbekannt' : gmdate('Y-m-d H:i:s', $state['next']), )); $rows = []; foreach ($tasks as $task) { $rows[] = [ $task['name'], $task['enabled'] ? ($task['due'] ? 'fällig' : 'an') : 'aus', $this->minutes($task['interval']), $task['next'], $task['running'] ? 'läuft' : ($task['status'] ?? '–'), mb_substr($task['message'], 0, 60), ]; } if ([] === $rows) { $io->warning('Keine Aufgaben. Fehlt die Migration? `php vendor/bin/doctrine-migrations migrate`'); } else { $io->table(['Name', 'Zustand', 'Abstand', 'Nächster Lauf (UTC)', 'Zuletzt', 'Meldung'], $rows); } if ($input->getOption('log')) { $io->section('Protokoll'); $lines = $this->scheduler->protocol(30); $io->writeln([] === $lines ? 'Noch nichts protokolliert.' : $lines); } return Command::SUCCESS; } private function minutes(int $seconds): string { return $seconds >= 86400 && 0 === $seconds % 86400 ? sprintf('%d Tag(e)', intdiv($seconds, 86400)) : sprintf('%d Min.', max(1, intdiv($seconds, 60))); } }