‪TYPO3CMS  10.4
SchedulerCommand.php
Go to the documentation of this file.
1 <?php
2 
3 /*
4  * This file is part of the TYPO3 CMS project.
5  *
6  * It is free software; you can redistribute it and/or modify it under
7  * the terms of the GNU General Public License, either version 2
8  * of the License, or any later version.
9  *
10  * For the full copyright and license information, please read the
11  * LICENSE.txt file that was distributed with this source code.
12  *
13  * The TYPO3 project - inspiring people to share!
14  */
15 
17 
18 use Symfony\Component\Console\Command\Command;
19 use Symfony\Component\Console\Input\InputInterface;
20 use Symfony\Component\Console\Input\InputOption;
21 use Symfony\Component\Console\Output\OutputInterface;
22 use Symfony\Component\Console\Style\SymfonyStyle;
27 
31 class ‪SchedulerCommand extends Command
32 {
36  protected ‪$hasTask = true;
37 
41  protected ‪$scheduler;
42 
46  protected ‪$io;
47 
53  protected ‪$overwrittenTaskList;
54 
60  protected ‪$stopTasks = false;
61 
65  protected ‪$forceExecution;
66 
70  public function ‪configure()
71  {
72  $this
73  ->setDescription('Start the TYPO3 Scheduler from the command line.')
74  ->setHelp('If no parameter is given, the scheduler executes any tasks that are overdue to run.
75 Call it like this: typo3/sysext/core/bin/typo3 scheduler:run --task=13 -f')
76  ->addOption(
77  'task',
78  'i',
79  InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY,
80  'UID of a specific task. Can be provided multiple times to execute multiple tasks sequentially.'
81  )
82  ->addOption(
83  'force',
84  'f',
85  InputOption::VALUE_NONE,
86  'Force execution of the task which is passed with --task option'
87  )
88  ->addOption(
89  'stop',
90  's',
91  InputOption::VALUE_NONE,
92  'Stop the task which is passed with --task option'
93  );
94  }
95 
103  public function ‪execute(InputInterface $input, OutputInterface ‪$output)
104  {
105  $this->io = new SymfonyStyle($input, ‪$output);
106 
107  // Make sure the _cli_ user is loaded
109 
110  $this->scheduler = GeneralUtility::makeInstance(Scheduler::class);
111 
112  ‪$overwrittenTaskList = $input->getOption('task');
113  if (‪$overwrittenTaskList !== []) {
114  $this->overwrittenTaskList = ‪$overwrittenTaskList;
115  }
116 
117  $this->forceExecution = (bool)$input->getOption('force');
118  $this->stopTasks = $this->‪shouldStopTasks((bool)$input->getOption('stop'));
119  $this->‪loopTasks();
120  return 0;
121  }
122 
131  protected function ‪shouldStopTasks(bool $stopOption): bool
132  {
133  if (!$stopOption) {
134  return false;
135  }
136 
137  if ($this->overwrittenTaskList !== []) {
138  return true;
139  }
140 
141  if ($this->io->isVerbose()) {
142  $this->io->warning('Stopping tasks is only possible when the --task option is provided.');
143  }
144  return false;
145  }
146 
152  protected function ‪stopTask(‪AbstractTask $task)
153  {
154  $task->‪unmarkAllExecutions();
155 
156  if ($this->io->isVeryVerbose()) {
157  $this->io->writeln(sprintf('Task #%d was stopped', $task->‪getTaskUid()));
158  }
159  }
160 
167  protected function ‪getTask(int $taskUid)
168  {
169  $force = $this->stopTasks || ‪$this->forceExecution;
170  if ($force) {
171  return $this->scheduler->fetchTask($taskUid);
172  }
173 
174  $whereClause = 'uid = ' . (int)$taskUid . ' AND nextexecution != 0 AND nextexecution <= ' . ‪$GLOBALS['EXEC_TIME'];
175  [$task] = $this->scheduler->fetchTasksWithCondition($whereClause);
176  return $task;
177  }
178 
182  protected function ‪loopTasks()
183  {
184  do {
185  // Try getting the next task and execute it
186  // If there are no more tasks to execute, an exception is thrown by \TYPO3\CMS\Scheduler\Scheduler::fetchTask()
187  try {
188  $task = $this->‪fetchNextTask();
189  try {
190  $this->‪executeOrStopTask($task);
191  } catch (\Exception $e) {
192  if ($this->io->isVerbose()) {
193  $this->io->warning($e->getMessage());
194  }
195  // We ignore any exception that may have been thrown during execution,
196  // as this is a background process.
197  // The exception message has been recorded to the database anyway
198  continue;
199  }
200  } catch (\OutOfBoundsException $e) {
201  if ($this->io->isVeryVerbose()) {
202  $this->io->writeln($e->getMessage());
203  }
204  $this->hasTask = !empty($this->overwrittenTaskList);
205  } catch (\UnexpectedValueException $e) {
206  if ($this->io->isVerbose()) {
207  $this->io->warning($e->getMessage());
208  }
209  continue;
210  }
211  } while ($this->hasTask);
212  // Record the run in the system registry
213  $this->scheduler->recordLastRun();
214  }
215 
226  protected function ‪fetchNextTask(): AbstractTask
227  {
228  if ($this->overwrittenTaskList === null) {
229  return $this->scheduler->fetchTask();
230  }
231 
232  if (count($this->overwrittenTaskList) === 0) {
233  throw new \OutOfBoundsException('No more tasks to execute', 1547675594);
234  }
235 
236  $taskUid = (int)array_shift($this->overwrittenTaskList);
237  $task = $this->‪getTask($taskUid);
238  if (!$this->scheduler->isValidTaskObject($task)) {
239  throw new \UnexpectedValueException(
240  sprintf('The task #%d is not scheduled for execution or does not exist.', $taskUid),
241  1547675557
242  );
243  }
244  return $task;
245  }
246 
252  protected function ‪executeOrStopTask(‪AbstractTask $task): void
253  {
254  if ($this->stopTasks) {
255  $this->‪stopTask($task);
256  return;
257  }
258 
259  $this->scheduler->executeTask($task);
260  if ($this->io->isVeryVerbose()) {
261  $this->io->writeln(sprintf('Task #%d was executed', $task->‪getTaskUid()));
262  }
263  }
264 }
‪TYPO3\CMS\Scheduler\Command\SchedulerCommand\execute
‪int execute(InputInterface $input, OutputInterface $output)
Definition: SchedulerCommand.php:97
‪TYPO3\CMS\Scheduler\Command\SchedulerCommand\loopTasks
‪loopTasks()
Definition: SchedulerCommand.php:176
‪TYPO3\CMS\Scheduler\Command\SchedulerCommand
Definition: SchedulerCommand.php:32
‪TYPO3\CMS\Scheduler\Task\AbstractTask\getTaskUid
‪int getTaskUid()
Definition: AbstractTask.php:138
‪TYPO3\CMS\Scheduler\Command\SchedulerCommand\shouldStopTasks
‪bool shouldStopTasks(bool $stopOption)
Definition: SchedulerCommand.php:125
‪TYPO3\CMS\Scheduler\Command\SchedulerCommand\stopTask
‪stopTask(AbstractTask $task)
Definition: SchedulerCommand.php:146
‪TYPO3\CMS\Scheduler\Command
Definition: SchedulerCommand.php:16
‪TYPO3\CMS\Scheduler\Command\SchedulerCommand\executeOrStopTask
‪executeOrStopTask(AbstractTask $task)
Definition: SchedulerCommand.php:246
‪TYPO3\CMS\Core\Core\Bootstrap\initializeBackendAuthentication
‪static initializeBackendAuthentication($proceedIfNoUserIsLoggedIn=false)
Definition: Bootstrap.php:607
‪TYPO3\CMS\Scheduler\Command\SchedulerCommand\configure
‪configure()
Definition: SchedulerCommand.php:64
‪TYPO3\CMS\Scheduler\Command\SchedulerCommand\$overwrittenTaskList
‪int[] array null $overwrittenTaskList
Definition: SchedulerCommand.php:49
‪TYPO3\CMS\Scheduler\Command\SchedulerCommand\fetchNextTask
‪AbstractTask fetchNextTask()
Definition: SchedulerCommand.php:220
‪TYPO3\CMS\Scheduler\Task\AbstractTask
Definition: AbstractTask.php:35
‪TYPO3\CMS\Scheduler\Scheduler
Definition: Scheduler.php:36
‪TYPO3\CMS\Scheduler\Command\SchedulerCommand\getTask
‪AbstractTask getTask(int $taskUid)
Definition: SchedulerCommand.php:161
‪TYPO3\CMS\Scheduler\Command\SchedulerCommand\$stopTasks
‪bool $stopTasks
Definition: SchedulerCommand.php:55
‪TYPO3\CMS\Scheduler\Command\SchedulerCommand\$forceExecution
‪bool $forceExecution
Definition: SchedulerCommand.php:59
‪TYPO3\CMS\Scheduler\Command\SchedulerCommand\$io
‪SymfonyStyle $io
Definition: SchedulerCommand.php:43
‪$output
‪$output
Definition: annotationChecker.php:119
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:5
‪TYPO3\CMS\Core\Core\Bootstrap
Definition: Bootstrap.php:66
‪TYPO3\CMS\Scheduler\Command\SchedulerCommand\$hasTask
‪bool $hasTask
Definition: SchedulerCommand.php:35
‪TYPO3\CMS\Scheduler\Task\AbstractTask\unmarkAllExecutions
‪bool unmarkAllExecutions()
Definition: AbstractTask.php:533
‪TYPO3\CMS\Scheduler\Command\SchedulerCommand\$scheduler
‪Scheduler $scheduler
Definition: SchedulerCommand.php:39
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:46