diff --git a/src/Command/MaintenanceModeCommand.php b/src/Command/MaintenanceModeCommand.php new file mode 100644 index 00000000..37f59af1 --- /dev/null +++ b/src/Command/MaintenanceModeCommand.php @@ -0,0 +1,141 @@ +. + */ + +declare(strict_types=1); + + +namespace App\Command; + +use App\Services\System\UpdateExecutor; +use Symfony\Component\Console\Attribute\AsCommand; +use Symfony\Component\Console\Command\Command; +use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Style\SymfonyStyle; + +#[AsCommand('partdb:maintenance_mode', 'Enable/disable maintenance mode and set a message')] +class MaintenanceModeCommand extends Command +{ + public function __construct( + private readonly UpdateExecutor $updateExecutor + ) { + parent::__construct(); + } + + protected function configure(): void + { + $this + ->setDefinition([ + new InputOption('enable', null, InputOption::VALUE_NONE, 'Enable maintenance mode'), + new InputOption('disable', null, InputOption::VALUE_NONE, 'Disable maintenance mode'), + new InputOption('status', null, InputOption::VALUE_NONE, 'Show current maintenance mode status'), + new InputOption('message', null, InputOption::VALUE_REQUIRED, 'Optional maintenance message (explicit option)'), + new InputArgument('message_arg', InputArgument::OPTIONAL, 'Optional maintenance message as a positional argument (preferred when writing message directly)') + ]); + } + + public function execute(InputInterface $input, OutputInterface $output): int + { + $io = new SymfonyStyle($input, $output); + + $enable = (bool)$input->getOption('enable'); + $disable = (bool)$input->getOption('disable'); + $status = (bool)$input->getOption('status'); + + // Accept message either via --message option or as positional argument + $optionMessage = $input->getOption('message'); + $argumentMessage = $input->getArgument('message_arg'); + + // Prefer explicit --message option, otherwise use positional argument if provided + $message = null; + if (is_string($optionMessage) && $optionMessage !== '') { + $message = $optionMessage; + } elseif (is_string($argumentMessage) && $argumentMessage !== '') { + $message = $argumentMessage; + } + + // If no action provided, show help + if (!$enable && !$disable && !$status) { + $io->text('Maintenance mode command. See usage below:'); + $this->printHelp($io); + return Command::SUCCESS; + } + + if ($enable && $disable) { + $io->error('Conflicting options: specify either --enable or --disable, not both.'); + return Command::FAILURE; + } + + try { + if ($status) { + if ($this->updateExecutor->isMaintenanceMode()) { + $info = $this->updateExecutor->getMaintenanceInfo(); + $reason = $info['reason'] ?? 'Unknown reason'; + $enabledAt = $info['enabled_at'] ?? 'Unknown time'; + + $io->success(sprintf('Maintenance mode is ENABLED (since %s).', $enabledAt)); + $io->text(sprintf('Reason: %s', $reason)); + } else { + $io->success('Maintenance mode is DISABLED.'); + } + + // If only status requested, exit + if (!$enable && !$disable) { + return Command::SUCCESS; + } + } + + if ($enable) { + // Use provided message or fallback to a default English message + $reason = is_string($message) && $message !== '' + ? $message + : 'The system is temporarily unavailable due to maintenance.'; + + $this->updateExecutor->enableMaintenanceMode($reason); + + $io->success(sprintf('Maintenance mode enabled. Reason: %s', $reason)); + } + + if ($disable) { + $this->updateExecutor->disableMaintenanceMode(); + $io->success('Maintenance mode disabled.'); + } + + return Command::SUCCESS; + } catch (\Throwable $e) { + $io->error(sprintf('Unexpected error: %s', $e->getMessage())); + return Command::FAILURE; + } + } + + private function printHelp(SymfonyStyle $io): void + { + $io->writeln(''); + $io->writeln('Usage:'); + $io->writeln(' php bin/console partdb:maintenance_mode --enable [--message="Maintenance message"]'); + $io->writeln(' php bin/console partdb:maintenance_mode --enable "Maintenance message"'); + $io->writeln(' php bin/console partdb:maintenance_mode --disable'); + $io->writeln(' php bin/console partdb:maintenance_mode --status'); + $io->writeln(''); + } + +} diff --git a/translations/messages.en.xlf b/translations/messages.en.xlf index 6cc1ad05..b6537a5f 100644 --- a/translations/messages.en.xlf +++ b/translations/messages.en.xlf @@ -14268,7 +14268,7 @@ Please note that this system is currently experimental, and the synonyms defined settings.ips.buerklin.help - Buerklin-API access limits: + Buerklin-API access limits: 100 requests/minute per IP address Buerklin-API Authentication server: 10 requests/minute per IP address