TYPO3  7.6
scheduler/Classes/Task/AbstractTask.php
Go to the documentation of this file.
1 <?php
2 namespace TYPO3\CMS\Scheduler\Task;
3 
4 /*
5  * This file is part of the TYPO3 CMS project.
6  *
7  * It is free software; you can redistribute it and/or modify it under
8  * the terms of the GNU General Public License, either version 2
9  * of the License, or any later version.
10  *
11  * For the full copyright and license information, please read the
12  * LICENSE.txt file that was distributed with this source code.
13  *
14  * The TYPO3 project - inspiring people to share!
15  */
16 
22 abstract class AbstractTask
23 {
29  protected $scheduler;
30 
36  protected $taskUid;
37 
43  protected $disabled = false;
44 
50  protected $execution;
51 
57  protected $executionTime = 0;
58 
64  protected $description = '';
65 
71  protected $taskGroup;
72 
76  public function __construct()
77  {
78  $this->setScheduler();
79  $this->execution = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Scheduler\Execution::class);
80  }
81 
91  abstract public function execute();
92 
101  public function getAdditionalInformation()
102  {
103  return '';
104  }
105 
112  public function setTaskUid($id)
113  {
114  $this->taskUid = (int)$id;
115  }
116 
122  public function getTaskUid()
123  {
124  return $this->taskUid;
125  }
126 
132  public function getTaskTitle()
133  {
134  return $GLOBALS['LANG']->sL($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['scheduler']['tasks'][get_class($this)]['title']);
135  }
136 
142  public function getTaskDescription()
143  {
144  return $GLOBALS['LANG']->sL($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['scheduler']['tasks'][get_class($this)]['description']);
145  }
146 
152  public function getTaskClassName()
153  {
154  return get_class($this);
155  }
156 
162  public function isDisabled()
163  {
164  return $this->disabled;
165  }
166 
173  public function setDisabled($flag)
174  {
175  if ($flag) {
176  $this->disabled = true;
177  } else {
178  $this->disabled = false;
179  }
180  }
181 
188  public function setExecutionTime($timestamp)
189  {
190  $this->executionTime = (int)$timestamp;
191  }
192 
198  public function getTaskGroup()
199  {
200  return $this->taskGroup;
201  }
202 
209  public function setTaskGroup($taskGroup)
210  {
211  $this->taskGroup = (int)$taskGroup;
212  }
213 
219  public function getExecutionTime()
220  {
221  return $this->executionTime;
222  }
223 
230  public function setDescription($description)
231  {
232  $this->description = $description;
233  }
234 
240  public function getDescription()
241  {
242  return $this->description;
243  }
244 
250  public function setScheduler()
251  {
252  $this->scheduler = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Scheduler\Scheduler::class);
253  }
254 
262  public function unsetScheduler()
263  {
264  unset($this->scheduler);
265  }
266 
272  public function registerSingleExecution($timestamp)
273  {
275  $execution = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Scheduler\Execution::class);
276  $execution->setStart($timestamp);
277  $execution->setInterval(0);
278  $execution->setEnd($timestamp);
279  $execution->setCronCmd('');
280  $execution->setMultiple(0);
281  $execution->setIsNewSingleExecution(true);
282  // Replace existing execution object
283  $this->execution = $execution;
284  }
285 
296  public function registerRecurringExecution($start, $interval, $end = 0, $multiple = false, $cron_cmd = '')
297  {
299  $execution = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Scheduler\Execution::class);
300  // Set general values
301  $execution->setStart($start);
302  $execution->setEnd($end);
303  $execution->setMultiple($multiple);
304  if (empty($cron_cmd)) {
305  // Use interval
306  $execution->setInterval($interval);
307  $execution->setCronCmd('');
308  } else {
309  // Use cron syntax
310  $execution->setInterval(0);
311  $execution->setCronCmd($cron_cmd);
312  }
313  // Replace existing execution object
314  $this->execution = $execution;
315  }
316 
322  public function setExecution(\TYPO3\CMS\Scheduler\Execution $execution)
323  {
324  $this->execution = $execution;
325  }
326 
332  public function getExecution()
333  {
334  return $this->execution;
335  }
336 
342  public function getNextDueExecution()
343  {
344  // NOTE: this call may throw an exception, but we let it bubble up
345  return $this->execution->getNextExecution();
346  }
347 
354  {
355  return $this->execution->getMultiple();
356  }
357 
363  public function isExecutionRunning()
364  {
365  $isRunning = false;
366  $queryArr = array(
367  'SELECT' => 'serialized_executions',
368  'FROM' => 'tx_scheduler_task',
369  'WHERE' => 'uid = ' . $this->taskUid,
370  'LIMIT' => 1
371  );
372  $res = $GLOBALS['TYPO3_DB']->exec_SELECT_queryArray($queryArr);
373  if ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
374  if (!empty($row['serialized_executions'])) {
375  $isRunning = true;
376  }
377  }
378  $GLOBALS['TYPO3_DB']->sql_free_result($res);
379  return $isRunning;
380  }
381 
388  public function markExecution()
389  {
390  $queryArr = array(
391  'SELECT' => 'serialized_executions',
392  'FROM' => 'tx_scheduler_task',
393  'WHERE' => 'uid = ' . $this->taskUid,
394  'LIMIT' => 1
395  );
396  $res = $GLOBALS['TYPO3_DB']->exec_SELECT_queryArray($queryArr);
397  $runningExecutions = array();
398  if ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
399  if ($row['serialized_executions'] !== '') {
400  $runningExecutions = unserialize($row['serialized_executions']);
401  }
402  }
403  $GLOBALS['TYPO3_DB']->sql_free_result($res);
404  // Count the number of existing executions and use that number as a key
405  // (we need to know that number, because it is returned at the end of the method)
406  $numExecutions = count($runningExecutions);
407  $runningExecutions[$numExecutions] = time();
408  // Define the context in which the script is running
409  $context = 'BE';
410  if (TYPO3_REQUESTTYPE & TYPO3_REQUESTTYPE_CLI) {
411  $context = 'CLI';
412  }
413  $GLOBALS['TYPO3_DB']->exec_UPDATEquery('tx_scheduler_task', 'uid = ' . $this->taskUid, array(
414  'serialized_executions' => serialize($runningExecutions),
415  'lastexecution_time' => time(),
416  'lastexecution_context' => $context
417  ));
418  return $numExecutions;
419  }
420 
428  public function unmarkExecution($executionID, \Exception $failure = null)
429  {
430  // Get the executions for the task
431  $queryArr = array(
432  'SELECT' => 'serialized_executions',
433  'FROM' => 'tx_scheduler_task',
434  'WHERE' => 'uid = ' . $this->taskUid,
435  'LIMIT' => 1
436  );
437  $res = $GLOBALS['TYPO3_DB']->exec_SELECT_queryArray($queryArr);
438  if ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
439  if ($row['serialized_executions'] !== '') {
440  $runningExecutions = unserialize($row['serialized_executions']);
441  // Remove the selected execution
442  unset($runningExecutions[$executionID]);
443  if (!empty($runningExecutions)) {
444  // Re-serialize the updated executions list (if necessary)
445  $runningExecutionsSerialized = serialize($runningExecutions);
446  } else {
447  $runningExecutionsSerialized = '';
448  }
449  if ($failure instanceof \Exception) {
450  // Log failed execution
451  $logMessage = 'Task failed to execute successfully. Class: ' . get_class($this) . ', UID: ' . $this->taskUid . '. ' . $failure->getMessage();
452  $this->scheduler->log($logMessage, 1, $failure->getCode());
453  // Do not serialize the complete exception or the trace, this can lead to huge strings > 50MB
454  $failureString = serialize(array(
455  'code' => $failure->getCode(),
456  'message' => $failure->getMessage(),
457  'file' => $failure->getFile(),
458  'line' => $failure->getLine(),
459  'traceString' => $failure->getTraceAsString(),
460  ));
461  } else {
462  $failureString = '';
463  }
464  // Save the updated executions list
465  $GLOBALS['TYPO3_DB']->exec_UPDATEquery('tx_scheduler_task', 'uid = ' . $this->taskUid, array(
466  'serialized_executions' => $runningExecutionsSerialized,
467  'lastexecution_failure' => $failureString
468  ));
469  }
470  }
471  $GLOBALS['TYPO3_DB']->sql_free_result($res);
472  }
473 
479  public function unmarkAllExecutions()
480  {
481  // Set the serialized executions field to empty
482  $result = $GLOBALS['TYPO3_DB']->exec_UPDATEquery('tx_scheduler_task', 'uid = ' . $this->taskUid, array(
483  'serialized_executions' => ''
484  ));
485  return $result;
486  }
487 
493  public function save()
494  {
495  return $this->scheduler->saveTask($this);
496  }
497 
504  public function stop()
505  {
506  $this->execution = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Scheduler\Execution::class);
507  }
508 
514  public function remove()
515  {
516  $this->scheduler->removeTask($this);
517  }
518 }