aboutsummaryrefslogtreecommitdiff
path: root/cli
diff options
context:
space:
mode:
authorJan-Hendrik Willms <tleilax+studip@gmail.com>2023-04-05 06:53:05 +0000
committerJan-Hendrik Willms <tleilax+studip@gmail.com>2023-04-05 06:53:05 +0000
commit9575bfa6adb2965735ade3f2cfccb1459434f698 (patch)
tree8077fd0f9fd62a87dc541945ce58dd89d24dd2c4 /cli
parent16774189c45ac431c73de3f4d5f159a6a570a92c (diff)
make cli command "cronjobs:execute" interactive, fixes #2501
Closes #2501 Merge request studip/studip!1692
Diffstat (limited to 'cli')
-rw-r--r--cli/Commands/Cronjobs/CronjobExecute.php109
-rw-r--r--cli/Commands/Cronjobs/CronjobList.php2
2 files changed, 101 insertions, 10 deletions
diff --git a/cli/Commands/Cronjobs/CronjobExecute.php b/cli/Commands/Cronjobs/CronjobExecute.php
index 23592a1..d4789ea 100644
--- a/cli/Commands/Cronjobs/CronjobExecute.php
+++ b/cli/Commands/Cronjobs/CronjobExecute.php
@@ -5,7 +5,11 @@ namespace Studip\Cli\Commands\Cronjobs;
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\Question\ChoiceQuestion;
+use Symfony\Component\Console\Question\ConfirmationQuestion;
+use Symfony\Component\Console\Question\Question;
class CronjobExecute extends Command
{
@@ -15,28 +19,115 @@ class CronjobExecute extends Command
{
$this->setDescription('Execute cronjob task.');
$this->setHelp('This command will execute a cronjob task.');
- $this->addArgument('task_id', InputArgument::REQUIRED, 'Id of the desired cron job');
+
+ $this->addArgument(
+ 'task_id',
+ InputArgument::OPTIONAL,
+ 'Id of the desired cron job'
+ );
+
+ $this->addOption(
+ 'input',
+ 'i',
+ InputOption::VALUE_NONE,
+ 'Interactively input values (defaults to true if no task_id is given)'
+ );
}
protected function execute(InputInterface $input, OutputInterface $output): int
{
+ $helper = $this->getHelper('question');
$task_id = $input->getArgument('task_id');
+
+ $input_values = $task_id === null || $input->getOption('input');
+
+ if ($task_id === null) {
+ $question = new ChoiceQuestion(
+ "\nWhich cronjob should be executed:\n",
+ $this->getCronjobTaskList()
+ );
+ $task_id = $helper->ask($input, $output, $question);
+ }
+
$task = \CronjobTask::find($task_id);
if (!$task) {
$output->writeln('<error>Unknown task id</error>');
return Command::FAILURE;
}
- if (!file_exists($GLOBALS['STUDIP_BASE_PATH'] . '/' . $task->filename)) {
- $output->writeln(sprintf('<error>Invalid task, unknown filename %s</error>', $task->filename));
+ if (!$task->valid) {
+ $output->writeln(sprintf(
+ '<error>Invalid task, unknown filename %s or invalid class %s</error>',
+ $task->filename,
+ $task->class
+ ));
return Command::FAILURE;
}
- require_once $GLOBALS['STUDIP_BASE_PATH'] . '/' . $task->filename;
- if (!class_exists('\\' . $task->class)) {
- fwrite(STDOUT, 'Invalid task, unknown class "' . $task->class . '"' . PHP_EOL);
- $output->writeln(sprintf('<error>Invalid task, unknown class %s</error>', $task->class));
- return Command::FAILURE;
+
+ $parameters = $this->getDefaultTaskParameters($task);
+
+ if ($input_values && count($parameters) > 0) {
+ $output->writeln("\nParameters:\n");
+
+ foreach ($task->parameters as $key => $definition) {
+ $description = trim($definition['description'], ' ?');
+ $default = trim(json_encode($definition['default'] ?? null), "'");
+ $label = " > {$description} [<comment>{$default}</comment>] : ";
+
+ if ($definition['type'] === 'boolean') {
+ $question = new ConfirmationQuestion(
+ $label,
+ $definition['default'],
+ '/^(y|j|1)/i'
+ );
+ } elseif ($definition['type'] === 'select' && !empty($definition['values'])) {
+ $question = new ChoiceQuestion(
+ $label,
+ $definition['values']
+ );
+ } else {
+ $question = new Question(
+ $label,
+ $definition['default']
+ );
+ if ($definition['type'] === 'integer') {
+ $question->setNormalizer(function ($value) {
+ return $value ? trim($value) : '';
+ })->setValidator(function ($value): int {
+ if (strlen($value) && !ctype_digit($value)) {
+ throw new \RuntimeException('Number is invalid.');
+ }
+ return $value;
+ });
+ }
+ }
+ $parameters[$key] = $helper->ask($input, $output, $question);
+ }
}
- $task->engage('');
+
+ $task->engage('', $parameters);
+
return Command::SUCCESS;
}
+
+ protected function getCronjobTaskList(): array
+ {
+ $result = [];
+ \CronjobTask::findEachBySQL(
+ function (\CronjobTask $task) use (&$result): void
+ {
+ $result[$task->id] = $task->name;
+ },
+ '1'
+ );
+ return $result;
+ }
+
+ private function getDefaultTaskParameters(\CronjobTask $task): array
+ {
+ $parameters = [];
+ foreach ($task->parameters as $key => $definition) {
+ $parameters[$key] = $definition['default'] ?? null;
+ }
+ return $parameters;
+ }
}
diff --git a/cli/Commands/Cronjobs/CronjobList.php b/cli/Commands/Cronjobs/CronjobList.php
index 4afa637..3506276 100644
--- a/cli/Commands/Cronjobs/CronjobList.php
+++ b/cli/Commands/Cronjobs/CronjobList.php
@@ -27,7 +27,7 @@ class CronjobList extends Command
$table->setStyle('compact');
$table->setHeaders(['Task-ID', 'Description']);
foreach ($tasks as $task) {
- if (!class_exists($task->class)) {
+ if (!$task->valid) {
continue;
}
$description = call_user_func(['\\' . $task->class, 'getDescription']);