‪TYPO3CMS  11.5
AbstractTask.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 Psr\Log\LoggerAwareInterface;
19 use Psr\Log\LoggerAwareTrait;
28 
34 abstract class ‪AbstractTask implements LoggerAwareInterface
35 {
36  use LoggerAwareTrait;
37 
38  public const ‪TYPE_SINGLE = 1;
39  public const ‪TYPE_RECURRING = 2;
40 
46  protected ‪$scheduler;
47 
53  protected ‪$taskUid;
54 
60  protected ‪$disabled = false;
61 
67  protected ‪$runOnNextCronJob = false;
68 
74  protected ‪$execution;
75 
81  protected ‪$executionTime = 0;
82 
88  protected ‪$description = '';
89 
95  protected ‪$taskGroup = 0;
96 
100  public function ‪__construct()
101  {
102  // Using makeInstance instead of setScheduler() here as the logger is injected due to LoggerAwareTrait
103  $this->scheduler = GeneralUtility::makeInstance(Scheduler::class);
104  $this->execution = GeneralUtility::makeInstance(Execution::class);
105  }
106 
116  abstract public function ‪execute();
117 
126  public function ‪getAdditionalInformation()
127  {
128  return '';
129  }
130 
136  public function ‪setTaskUid($id)
137  {
138  $this->taskUid = (int)$id;
139  }
140 
146  public function ‪getTaskUid()
147  {
149  }
150 
156  public function ‪getTaskTitle()
157  {
158  return $this->‪getLanguageService()->‪sL(‪$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['scheduler']['tasks'][static::class]['title']);
159  }
160 
166  public function ‪getTaskDescription()
167  {
168  return $this->‪getLanguageService()->‪sL(‪$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['scheduler']['tasks'][static::class]['description']);
169  }
170 
176  public function ‪getTaskClassName()
177  {
178  return static::class;
179  }
180 
186  public function ‪isDisabled()
187  {
189  }
190 
196  public function ‪setDisabled($flag)
197  {
198  if ($flag) {
199  $this->disabled = true;
200  } else {
201  $this->disabled = false;
202  }
203  }
204 
210  public function ‪setRunOnNextCronJob($flag)
211  {
212  $this->runOnNextCronJob = $flag;
213  }
214 
220  public function ‪getRunOnNextCronJob()
221  {
223  }
224 
230  public function ‪setExecutionTime($timestamp)
231  {
232  $this->executionTime = (int)$timestamp;
233  }
234 
240  public function ‪getTaskGroup()
241  {
243  }
244 
250  public function ‪setTaskGroup(‪$taskGroup)
251  {
252  $this->taskGroup = (int)‪$taskGroup;
253  }
254 
260  public function ‪getExecutionTime()
261  {
263  }
264 
270  public function ‪setDescription(‪$description)
271  {
272  $this->description = ‪$description;
273  }
274 
280  public function ‪getDescription()
281  {
282  return ‪$this->description;
283  }
284 
289  public function ‪setScheduler()
290  {
291  $this->scheduler = GeneralUtility::makeInstance(Scheduler::class);
292  $this->logger = GeneralUtility::makeInstance(LogManager::class)->getLogger(__CLASS__);
293  }
294 
301  public function ‪unsetScheduler()
302  {
303  $this->scheduler = null;
304  unset($this->logger);
305  }
306 
312  public function ‪registerSingleExecution($timestamp)
313  {
314  ‪$execution = GeneralUtility::makeInstance(Execution::class);
315  ‪$execution->‪setStart($timestamp);
317  ‪$execution->‪setEnd($timestamp);
321  // Replace existing execution object
322  $this->execution = ‪$execution;
323  }
324 
334  public function ‪registerRecurringExecution($start, $interval, $end = 0, $multiple = false, $cron_cmd = '')
335  {
336  ‪$execution = GeneralUtility::makeInstance(Execution::class);
337  // Set general values
338  ‪$execution->‪setStart($start);
339  ‪$execution->‪setEnd($end);
340  ‪$execution->‪setMultiple($multiple);
341  if (empty($cron_cmd)) {
342  // Use interval
343  ‪$execution->‪setInterval($interval);
345  } else {
346  // Use cron syntax
348  ‪$execution->‪setCronCmd($cron_cmd);
349  }
350  // Replace existing execution object
351  $this->execution = ‪$execution;
352  }
353 
360  {
361  $this->execution = ‪$execution;
362  }
363 
369  public function ‪getExecution()
370  {
372  }
373 
379  public function ‪getNextDueExecution()
380  {
381  // NOTE: this call may throw an exception, but we let it bubble up
382  return $this->execution->getNextExecution();
383  }
384 
390  public function ‪areMultipleExecutionsAllowed()
391  {
392  return $this->execution->getMultiple();
393  }
394 
400  public function ‪isExecutionRunning()
401  {
402  $isRunning = false;
403  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
404  ->getQueryBuilderForTable('tx_scheduler_task');
405  $row = $queryBuilder
406  ->select('serialized_executions')
407  ->from('tx_scheduler_task')
408  ->where(
409  $queryBuilder->expr()->eq('uid', $queryBuilder->createNamedParameter($this->taskUid, ‪Connection::PARAM_INT))
410  )
411  ->executeQuery()
412  ->fetchAssociative();
413 
414  if ($row && !empty($row['serialized_executions'])) {
415  $isRunning = true;
416  }
417  return $isRunning;
418  }
419 
426  public function ‪markExecution()
427  {
428  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
429  ->getQueryBuilderForTable('tx_scheduler_task');
430 
431  $row = $queryBuilder
432  ->select('serialized_executions')
433  ->from('tx_scheduler_task')
434  ->where(
435  $queryBuilder->expr()->eq('uid', $queryBuilder->createNamedParameter($this->taskUid, ‪Connection::PARAM_INT))
436  )
437  ->executeQuery()
438  ->fetchAssociative();
439 
440  $runningExecutions = [];
441  if ($row && !empty($row['serialized_executions'])) {
442  $runningExecutions = unserialize($row['serialized_executions']);
443  }
444  // Count the number of existing executions and use that number as a key
445  // (we need to know that number, because it is returned at the end of the method)
446  $numExecutions = count($runningExecutions);
447  $runningExecutions[$numExecutions] = time();
448  GeneralUtility::makeInstance(ConnectionPool::class)
449  ->getConnectionForTable('tx_scheduler_task')
450  ->update(
451  'tx_scheduler_task',
452  [
453  'serialized_executions' => serialize($runningExecutions),
454  'lastexecution_time' => time(),
455  // Define the context in which the script is running
456  'lastexecution_context' => ‪Environment::isCli() ? 'CLI' : 'BE',
457  ],
458  [
459  'uid' => $this->taskUid,
460  ],
461  [
462  'serialized_executions' => ‪Connection::PARAM_LOB,
463  ]
464  );
465  return $numExecutions;
466  }
467 
474  public function ‪unmarkExecution($executionID, \Throwable $e = null)
475  {
476  // Get the executions for the task
477  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
478  ->getQueryBuilderForTable('tx_scheduler_task');
479 
480  $row = $queryBuilder
481  ->select('serialized_executions')
482  ->from('tx_scheduler_task')
483  ->where(
484  $queryBuilder->expr()->eq('uid', $queryBuilder->createNamedParameter($this->taskUid, ‪Connection::PARAM_INT))
485  )
486  ->executeQuery()
487  ->fetchAssociative();
488 
489  if ($row && $row['serialized_executions'] !== '') {
490  $runningExecutions = unserialize($row['serialized_executions']);
491  // Remove the selected execution
492  unset($runningExecutions[$executionID]);
493  if (!empty($runningExecutions)) {
494  // Re-serialize the updated executions list (if necessary)
495  $runningExecutionsSerialized = serialize($runningExecutions);
496  } else {
497  $runningExecutionsSerialized = '';
498  }
499  if ($e instanceof \Throwable) {
500  // Log failed execution
501  $this->logger->error('Task failed to execute successfully. Class: {class}, UID: {uid}', [
502  'class' => __CLASS__,
503  'uid' => $this->taskUid,
504  'exception' => $e,
505  ]);
506  // Do not serialize the complete exception or the trace, this can lead to huge strings > 50MB
507  $failureString = serialize([
508  'code' => $e->getCode(),
509  'message' => $e->getMessage(),
510  'file' => $e->getFile(),
511  'line' => $e->getLine(),
512  'traceString' => $e->getTraceAsString(),
513  ]);
514  } else {
515  $failureString = '';
516  }
517  // Save the updated executions list
518  GeneralUtility::makeInstance(ConnectionPool::class)
519  ->getConnectionForTable('tx_scheduler_task')
520  ->update(
521  'tx_scheduler_task',
522  [
523  'serialized_executions' => $runningExecutionsSerialized,
524  'lastexecution_failure' => $failureString,
525  ],
526  [
527  'uid' => $this->taskUid,
528  ],
529  [
530  'serialized_executions' => ‪Connection::PARAM_LOB,
531  ]
532  );
533  }
534  }
535 
541  public function ‪unmarkAllExecutions()
542  {
543  // Set the serialized executions field to empty
544  $result = GeneralUtility::makeInstance(ConnectionPool::class)
545  ->getConnectionForTable('tx_scheduler_task')
546  ->update(
547  'tx_scheduler_task',
548  [
549  'serialized_executions' => '',
550  ],
551  [
552  'uid' => $this->taskUid,
553  ],
554  [
555  'serialized_executions' => ‪Connection::PARAM_LOB,
556  ]
557  );
558  return (bool)$result;
559  }
560 
566  public function ‪save()
567  {
568  return $this->scheduler->saveTask($this);
569  }
570 
575  public function ‪stop()
576  {
577  $this->execution = GeneralUtility::makeInstance(Execution::class);
578  }
579 
583  public function remove()
584  {
585  $this->scheduler->removeTask($this);
586  }
587 
594  public function ‪getType()
595  {
596  if (!empty($this->‪getExecution()->getInterval()) || !empty($this->‪getExecution()->getCronCmd())) {
598  }
599  return ‪self::TYPE_SINGLE;
600  }
601 
605  protected function ‪logException(\Exception $e)
606  {
607  $this->logger->error('A Task Exception was captured.', ['exception' => $e]);
608  }
609 
613  protected function ‪getLanguageService(): ?‪LanguageService
614  {
615  return ‪$GLOBALS['LANG'] ?? null;
616  }
617 }
‪TYPO3\CMS\Scheduler\Task\AbstractTask\$scheduler
‪TYPO3 CMS Scheduler Scheduler null $scheduler
Definition: AbstractTask.php:45
‪TYPO3\CMS\Scheduler\Execution\setStart
‪setStart($start)
Definition: Execution.php:73
‪TYPO3\CMS\Core\Database\Connection\PARAM_INT
‪const PARAM_INT
Definition: Connection.php:49
‪TYPO3\CMS\Scheduler\Task\AbstractTask\save
‪bool save()
Definition: AbstractTask.php:558
‪TYPO3\CMS\Scheduler\Task\AbstractTask\getTaskUid
‪int getTaskUid()
Definition: AbstractTask.php:138
‪TYPO3\CMS\Scheduler\Task\AbstractTask\getRunOnNextCronJob
‪bool getRunOnNextCronJob()
Definition: AbstractTask.php:212
‪TYPO3\CMS\Scheduler\Task\AbstractTask\setTaskUid
‪setTaskUid($id)
Definition: AbstractTask.php:128
‪TYPO3\CMS\Scheduler\Execution\setCronCmd
‪setCronCmd($cmd)
Definition: Execution.php:153
‪TYPO3\CMS\Scheduler\Execution\setIsNewSingleExecution
‪setIsNewSingleExecution($isNewSingleExecution)
Definition: Execution.php:180
‪TYPO3\CMS\Scheduler\Task\AbstractTask\getExecution
‪Execution getExecution()
Definition: AbstractTask.php:361
‪TYPO3\CMS\Scheduler\Task
Definition: AbstractTask.php:16
‪TYPO3\CMS\Scheduler\Task\AbstractTask\setRunOnNextCronJob
‪setRunOnNextCronJob($flag)
Definition: AbstractTask.php:202
‪TYPO3\CMS\Scheduler\Task\AbstractTask\setDisabled
‪setDisabled($flag)
Definition: AbstractTask.php:188
‪TYPO3\CMS\Scheduler\Task\AbstractTask\getType
‪int getType()
Definition: AbstractTask.php:586
‪TYPO3\CMS\Scheduler\Task\AbstractTask\getTaskTitle
‪string getTaskTitle()
Definition: AbstractTask.php:148
‪TYPO3\CMS\Core\Localization\LanguageService\sL
‪string sL($input)
Definition: LanguageService.php:161
‪TYPO3\CMS\Scheduler\Task\AbstractTask\getNextDueExecution
‪int getNextDueExecution()
Definition: AbstractTask.php:371
‪TYPO3\CMS\Scheduler\Task\AbstractTask\$executionTime
‪int $executionTime
Definition: AbstractTask.php:75
‪TYPO3\CMS\Scheduler\Task\AbstractTask\$execution
‪Execution $execution
Definition: AbstractTask.php:69
‪TYPO3\CMS\Scheduler\Task\AbstractTask\getTaskClassName
‪string getTaskClassName()
Definition: AbstractTask.php:168
‪TYPO3\CMS\Scheduler\Task\AbstractTask\getLanguageService
‪LanguageService null getLanguageService()
Definition: AbstractTask.php:605
‪TYPO3\CMS\Scheduler\Task\AbstractTask\getAdditionalInformation
‪string getAdditionalInformation()
Definition: AbstractTask.php:118
‪TYPO3\CMS\Scheduler\Task\AbstractTask\setScheduler
‪setScheduler()
Definition: AbstractTask.php:281
‪TYPO3\CMS\Scheduler\Task\AbstractTask\$taskGroup
‪int $taskGroup
Definition: AbstractTask.php:87
‪TYPO3\CMS\Scheduler\Task\AbstractTask
Definition: AbstractTask.php:35
‪TYPO3\CMS\Scheduler\Execution
Definition: Execution.php:26
‪TYPO3\CMS\Scheduler\Task\AbstractTask\registerSingleExecution
‪registerSingleExecution($timestamp)
Definition: AbstractTask.php:304
‪TYPO3\CMS\Scheduler\Scheduler
Definition: Scheduler.php:33
‪TYPO3\CMS\Scheduler\Execution\setInterval
‪setInterval($interval)
Definition: Execution.php:113
‪TYPO3\CMS\Scheduler\Task\AbstractTask\logException
‪logException(\Exception $e)
Definition: AbstractTask.php:597
‪TYPO3\CMS\Scheduler\Task\AbstractTask\isDisabled
‪bool isDisabled()
Definition: AbstractTask.php:178
‪TYPO3\CMS\Scheduler\Task\AbstractTask\setDescription
‪setDescription($description)
Definition: AbstractTask.php:262
‪TYPO3\CMS\Scheduler\Task\AbstractTask\areMultipleExecutionsAllowed
‪bool areMultipleExecutionsAllowed()
Definition: AbstractTask.php:382
‪TYPO3\CMS\Scheduler\Task\AbstractTask\getExecutionTime
‪int getExecutionTime()
Definition: AbstractTask.php:252
‪TYPO3\CMS\Scheduler\Execution\setEnd
‪setEnd($end)
Definition: Execution.php:93
‪TYPO3\CMS\Scheduler\Task\AbstractTask\$runOnNextCronJob
‪bool $runOnNextCronJob
Definition: AbstractTask.php:63
‪TYPO3\CMS\Scheduler\Task\AbstractTask\$description
‪string $description
Definition: AbstractTask.php:81
‪TYPO3\CMS\Scheduler\Task\AbstractTask\TYPE_RECURRING
‪const TYPE_RECURRING
Definition: AbstractTask.php:39
‪TYPO3\CMS\Core\Database\Connection
Definition: Connection.php:38
‪TYPO3\CMS\Scheduler\Task\AbstractTask\stop
‪stop()
Definition: AbstractTask.php:567
‪TYPO3\CMS\Scheduler\Task\AbstractTask\execute
‪bool execute()
‪TYPO3\CMS\Scheduler\Task\AbstractTask\isExecutionRunning
‪bool isExecutionRunning()
Definition: AbstractTask.php:392
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:25
‪TYPO3\CMS\Scheduler\Task\AbstractTask\TYPE_SINGLE
‪const TYPE_SINGLE
Definition: AbstractTask.php:38
‪TYPO3\CMS\Scheduler\Task\AbstractTask\markExecution
‪int markExecution()
Definition: AbstractTask.php:418
‪TYPO3\CMS\Core\Log\LogManager
Definition: LogManager.php:33
‪TYPO3\CMS\Core\Core\Environment
Definition: Environment.php:43
‪TYPO3\CMS\Scheduler\Task\AbstractTask\__construct
‪__construct()
Definition: AbstractTask.php:92
‪TYPO3\CMS\Scheduler\Task\AbstractTask\registerRecurringExecution
‪registerRecurringExecution($start, $interval, $end=0, $multiple=false, $cron_cmd='')
Definition: AbstractTask.php:326
‪TYPO3\CMS\Scheduler\Task\AbstractTask\$disabled
‪bool $disabled
Definition: AbstractTask.php:57
‪TYPO3\CMS\Scheduler\Task\AbstractTask\unmarkAllExecutions
‪bool unmarkAllExecutions()
Definition: AbstractTask.php:533
‪TYPO3\CMS\Core\Localization\LanguageService
Definition: LanguageService.php:42
‪TYPO3\CMS\Scheduler\Task\AbstractTask\getTaskGroup
‪int getTaskGroup()
Definition: AbstractTask.php:232
‪TYPO3\CMS\Core\Database\ConnectionPool
Definition: ConnectionPool.php:46
‪TYPO3\CMS\Scheduler\Task\AbstractTask\getDescription
‪string getDescription()
Definition: AbstractTask.php:272
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:50
‪TYPO3\CMS\Scheduler\Task\AbstractTask\setExecution
‪setExecution(Execution $execution)
Definition: AbstractTask.php:351
‪TYPO3\CMS\Scheduler\Execution\setMultiple
‪setMultiple($multiple)
Definition: Execution.php:133
‪TYPO3\CMS\Core\Core\Environment\isCli
‪static bool isCli()
Definition: Environment.php:162
‪TYPO3\CMS\Scheduler\Task\AbstractTask\unsetScheduler
‪unsetScheduler()
Definition: AbstractTask.php:293
‪TYPO3\CMS\Scheduler\Task\AbstractTask\$taskUid
‪int $taskUid
Definition: AbstractTask.php:51
‪TYPO3\CMS\Scheduler\Task\AbstractTask\setTaskGroup
‪setTaskGroup($taskGroup)
Definition: AbstractTask.php:242
‪TYPO3\CMS\Scheduler\Task\AbstractTask\unmarkExecution
‪unmarkExecution($executionID, \Throwable $e=null)
Definition: AbstractTask.php:466
‪TYPO3\CMS\Scheduler\Task\AbstractTask\getTaskDescription
‪string getTaskDescription()
Definition: AbstractTask.php:158
‪TYPO3\CMS\Scheduler\Task\AbstractTask\setExecutionTime
‪setExecutionTime($timestamp)
Definition: AbstractTask.php:222
‪TYPO3\CMS\Core\Database\Connection\PARAM_LOB
‪const PARAM_LOB
Definition: Connection.php:59