‪TYPO3CMS  ‪main
SchedulerExecuteCommand.php
Go to the documentation of this file.
1 <?php
2 
3 declare(strict_types=1);
4 
5 /*
6  * This file is part of the TYPO3 CMS project.
7  *
8  * It is free software; you can redistribute it and/or modify it under
9  * the terms of the GNU General Public License, either version 2
10  * of the License, or any later version.
11  *
12  * For the full copyright and license information, please read the
13  * LICENSE.txt file that was distributed with this source code.
14  *
15  * The TYPO3 project - inspiring people to share!
16  */
17 
19 
20 use Symfony\Component\Console\Command\Command;
21 use Symfony\Component\Console\Helper\QuestionHelper;
22 use Symfony\Component\Console\Input\InputInterface;
23 use Symfony\Component\Console\Input\InputOption;
24 use Symfony\Component\Console\Output\OutputInterface;
25 use Symfony\Component\Console\Question\ChoiceQuestion;
26 use Symfony\Component\Console\Style\SymfonyStyle;
34 
38 class ‪SchedulerExecuteCommand extends Command
39 {
40  protected SymfonyStyle ‪$io;
41 
42  public function ‪__construct(
43  protected readonly ‪Context $context,
44  protected readonly ‪SchedulerTaskRepository $taskRepository,
45  protected ‪Scheduler $scheduler,
46  ) {
47  parent::__construct();
48  }
49 
50  public function ‪configure()
51  {
52  $this
53  ->addOption(
54  'task',
55  't',
56  InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY,
57  'Execute tasks by given id. To run all tasks of a group prefix the group id with "g:", e.g. "g:1"',
58  );
59  }
60 
61  public function ‪execute(InputInterface $input, OutputInterface ‪$output): int
62  {
63  // Make sure the _cli_ user is loaded
65  $this->io = new SymfonyStyle($input, ‪$output);
66 
67  if (count($input->getOption('task')) > 0) {
68  $taskGroups = $this->taskRepository->getGroupedTasks()['taskGroupsWithTasks'];
69  $tasksToRun = $this->‪getTasksToRun($taskGroups, $input->getOption('task'));
70  $this->‪runTasks($tasksToRun, $taskGroups);
71 
72  return Command::SUCCESS;
73  }
74 
75  $this->‪askForTasksAndRun($input, ‪$output);
76  return Command::SUCCESS;
77  }
78 
79  private function ‪askForTasksAndRun(InputInterface $input, OutputInterface ‪$output): void
80  {
82  $questionHelper = $this->getHelper('question');
83  $taskGroups = $this->taskRepository->getGroupedTasks()['taskGroupsWithTasks'];
84  $selectableTasks = $this->‪getSelectableTasks($taskGroups);
85  if ($selectableTasks === []) {
86  $this->io->note('No tasks available.');
87  return;
88  }
89 
90  $tasksToRunQuestion = new ChoiceQuestion('Run tasks (comma seperated list): ', $selectableTasks);
91  $tasksToRunQuestion->setAutocompleterValues(array_keys($selectableTasks));
92  $tasksToRunQuestion->setMultiselect(true);
93  $tasksToRun = $questionHelper->ask($input, ‪$output, $tasksToRunQuestion);
94 
95  $this->‪runTasks($tasksToRun, $taskGroups);
96  }
97 
98  private function ‪runTasks($selectedTasks, $taskGroups): void
99  {
100  $taskUids = $this->‪getTaskUidsFromSelection($selectedTasks, $taskGroups);
101  ksort($taskUids);
102  $numLength = strlen((string)array_reverse($taskUids)[0]);
103 
104  foreach ($taskUids as $taskUid) {
105  try {
106  ‪$uid = (int)$taskUid;
107  $task = $this->taskRepository->findByUid(‪$uid);
108  $additionalInformation = $task->getAdditionalInformation() === '' ? '' : ' (' . $task->getAdditionalInformation() . ')';
109  $space = str_repeat(' ', $numLength - strlen((string)$task->getTaskUid()));
110  $this->io->writeln('[ <fg=green>TASK:' . $task->getTaskUid() . $space . '</> ] Running "' . $task->getTaskTitle() . $additionalInformation . '"');
111  $this->scheduler->executeTask($task);
112  } catch (\Throwable $exception) {
113  $this->io->writeln($exception->getMessage());
114  }
115  }
116  }
117 
118  private function ‪getTaskUidsFromSelection(array $list, array $groups): array
119  {
120  $taskUids = [];
121  foreach ($list as ‪$uid) {
122  [$keyword, $group] = [...explode(':', (string)‪$uid), null];
123  if ($keyword === 'g') {
124  if (!array_key_exists($group, $groups)) {
125  throw new \InvalidArgumentException('Group with id "' . $group . '" does not exist.', 1679683415);
126  }
127  $taskUidsInGroup = array_column($groups[$group]['tasks'], 'uid');
128  $taskUids += $taskUidsInGroup;
129  } else {
130  $taskUids[] = ‪$uid;
131  }
132  }
133  return $taskUids;
134  }
135 
137  {
138  return GeneralUtility::makeInstance(LanguageServiceFactory::class)->create('default');
139  }
140 
141  private function ‪getTasksToRun(array $taskGroups, array $taskList): array
142  {
143  $taskUids = array_unique($this->‪getTaskUidsFromSelection($taskList, $taskGroups));
144  foreach ($taskUids as $taskUid) {
145  // This will throw an exception if the task uid was not found and print it to the console.
146  $this->taskRepository->findByUid((int)$taskUid);
147  }
148  return $taskUids;
149  }
150 
151  protected function ‪getSelectableTasks(mixed $taskGroups): array
152  {
153  $selectableTasks = [];
154  foreach ($taskGroups as ‪$uid => $group) {
155  $groupLabel = ($group['groupName'] ?? $this->‪getLanguageService()->sL('LLL:EXT:scheduler/Resources/Private/Language/locallang.xlf:label.noGroup'));
156  $selectableTasks['g:' . ‪$uid] = '<fg=yellow>' . $groupLabel . '</>';
157 
158  foreach ($group['tasks'] as $task) {
159  $additionalInformation = $task['additionalInformation'] === '' ? '' : '(' . $task['additionalInformation'] . ')';
160  $selectableTasks[$task['uid']] = $task['classTitle'] . $additionalInformation;
161  }
162  }
163  return $selectableTasks;
164  }
165 }
‪TYPO3\CMS\Core\Localization\LanguageServiceFactory
Definition: LanguageServiceFactory.php:25
‪TYPO3\CMS\Scheduler\Command\SchedulerExecuteCommand\getTasksToRun
‪getTasksToRun(array $taskGroups, array $taskList)
Definition: SchedulerExecuteCommand.php:141
‪TYPO3\CMS\Scheduler\Command\SchedulerExecuteCommand\__construct
‪__construct(protected readonly Context $context, protected readonly SchedulerTaskRepository $taskRepository, protected Scheduler $scheduler,)
Definition: SchedulerExecuteCommand.php:42
‪TYPO3\CMS\Scheduler\Command\SchedulerExecuteCommand\getLanguageService
‪getLanguageService()
Definition: SchedulerExecuteCommand.php:136
‪TYPO3\CMS\Scheduler\Command\SchedulerExecuteCommand\askForTasksAndRun
‪askForTasksAndRun(InputInterface $input, OutputInterface $output)
Definition: SchedulerExecuteCommand.php:79
‪TYPO3\CMS\Scheduler\Domain\Repository\SchedulerTaskRepository
Definition: SchedulerTaskRepository.php:36
‪TYPO3\CMS\Scheduler\Command\SchedulerExecuteCommand\getTaskUidsFromSelection
‪getTaskUidsFromSelection(array $list, array $groups)
Definition: SchedulerExecuteCommand.php:118
‪TYPO3\CMS\Scheduler\Command
Definition: SchedulerCommand.php:16
‪TYPO3\CMS\Core\Context\Context
Definition: Context.php:54
‪TYPO3\CMS\Scheduler\Command\SchedulerExecuteCommand\getSelectableTasks
‪getSelectableTasks(mixed $taskGroups)
Definition: SchedulerExecuteCommand.php:151
‪TYPO3\CMS\Scheduler\Command\SchedulerExecuteCommand\configure
‪configure()
Definition: SchedulerExecuteCommand.php:50
‪TYPO3\CMS\Scheduler\Command\SchedulerExecuteCommand\runTasks
‪runTasks($selectedTasks, $taskGroups)
Definition: SchedulerExecuteCommand.php:98
‪TYPO3\CMS\Scheduler\Command\SchedulerExecuteCommand\$io
‪SymfonyStyle $io
Definition: SchedulerExecuteCommand.php:40
‪TYPO3\CMS\Scheduler\Scheduler
Definition: Scheduler.php:34
‪$output
‪$output
Definition: annotationChecker.php:114
‪TYPO3\CMS\Scheduler\Command\SchedulerExecuteCommand\execute
‪execute(InputInterface $input, OutputInterface $output)
Definition: SchedulerExecuteCommand.php:61
‪TYPO3\CMS\Webhooks\Message\$uid
‪identifier readonly int $uid
Definition: PageModificationMessage.php:35
‪TYPO3\CMS\Core\Core\Bootstrap
Definition: Bootstrap.php:62
‪TYPO3\CMS\Core\Localization\LanguageService
Definition: LanguageService.php:46
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:52
‪TYPO3\CMS\Scheduler\Command\SchedulerExecuteCommand
Definition: SchedulerExecuteCommand.php:39
‪TYPO3\CMS\Core\Core\Bootstrap\initializeBackendAuthentication
‪static initializeBackendAuthentication()
Definition: Bootstrap.php:527