TYPO3 CMS  TYPO3_7-6
AbstractTask.php
Go to the documentation of this file.
1 <?php
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 {
24  const TYPE_SINGLE = 1;
25  const TYPE_RECURRING = 2;
26 
32  protected $scheduler;
33 
39  protected $taskUid;
40 
46  protected $disabled = false;
47 
53  protected $execution;
54 
60  protected $executionTime = 0;
61 
67  protected $description = '';
68 
74  protected $taskGroup;
75 
79  public function __construct()
80  {
81  $this->setScheduler();
82  $this->execution = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Scheduler\Execution::class);
83  }
84 
94  abstract public function execute();
95 
104  public function getAdditionalInformation()
105  {
106  return '';
107  }
108 
115  public function setTaskUid($id)
116  {
117  $this->taskUid = (int)$id;
118  }
119 
125  public function getTaskUid()
126  {
127  return $this->taskUid;
128  }
129 
135  public function getTaskTitle()
136  {
137  return $GLOBALS['LANG']->sL($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['scheduler']['tasks'][get_class($this)]['title']);
138  }
139 
145  public function getTaskDescription()
146  {
147  return $GLOBALS['LANG']->sL($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['scheduler']['tasks'][get_class($this)]['description']);
148  }
149 
155  public function getTaskClassName()
156  {
157  return get_class($this);
158  }
159 
165  public function isDisabled()
166  {
167  return $this->disabled;
168  }
169 
176  public function setDisabled($flag)
177  {
178  if ($flag) {
179  $this->disabled = true;
180  } else {
181  $this->disabled = false;
182  }
183  }
184 
191  public function setExecutionTime($timestamp)
192  {
193  $this->executionTime = (int)$timestamp;
194  }
195 
201  public function getTaskGroup()
202  {
203  return $this->taskGroup;
204  }
205 
212  public function setTaskGroup($taskGroup)
213  {
214  $this->taskGroup = (int)$taskGroup;
215  }
216 
222  public function getExecutionTime()
223  {
224  return $this->executionTime;
225  }
226 
233  public function setDescription($description)
234  {
235  $this->description = $description;
236  }
237 
243  public function getDescription()
244  {
245  return $this->description;
246  }
247 
253  public function setScheduler()
254  {
255  $this->scheduler = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Scheduler\Scheduler::class);
256  }
257 
265  public function unsetScheduler()
266  {
267  unset($this->scheduler);
268  }
269 
275  public function registerSingleExecution($timestamp)
276  {
279  $execution->setStart($timestamp);
280  $execution->setInterval(0);
281  $execution->setEnd($timestamp);
282  $execution->setCronCmd('');
283  $execution->setMultiple(0);
284  $execution->setIsNewSingleExecution(true);
285  // Replace existing execution object
286  $this->execution = $execution;
287  }
288 
299  public function registerRecurringExecution($start, $interval, $end = 0, $multiple = false, $cron_cmd = '')
300  {
303  // Set general values
304  $execution->setStart($start);
305  $execution->setEnd($end);
306  $execution->setMultiple($multiple);
307  if (empty($cron_cmd)) {
308  // Use interval
309  $execution->setInterval($interval);
310  $execution->setCronCmd('');
311  } else {
312  // Use cron syntax
313  $execution->setInterval(0);
314  $execution->setCronCmd($cron_cmd);
315  }
316  // Replace existing execution object
317  $this->execution = $execution;
318  }
319 
326  {
327  $this->execution = $execution;
328  }
329 
335  public function getExecution()
336  {
337  return $this->execution;
338  }
339 
345  public function getNextDueExecution()
346  {
347  // NOTE: this call may throw an exception, but we let it bubble up
348  return $this->execution->getNextExecution();
349  }
350 
357  {
358  return $this->execution->getMultiple();
359  }
360 
366  public function isExecutionRunning()
367  {
368  $isRunning = false;
369  $queryArr = [
370  'SELECT' => 'serialized_executions',
371  'FROM' => 'tx_scheduler_task',
372  'WHERE' => 'uid = ' . $this->taskUid,
373  'LIMIT' => 1
374  ];
375  $res = $GLOBALS['TYPO3_DB']->exec_SELECT_queryArray($queryArr);
376  if ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
377  if (!empty($row['serialized_executions'])) {
378  $isRunning = true;
379  }
380  }
381  $GLOBALS['TYPO3_DB']->sql_free_result($res);
382  return $isRunning;
383  }
384 
391  public function markExecution()
392  {
393  $queryArr = [
394  'SELECT' => 'serialized_executions',
395  'FROM' => 'tx_scheduler_task',
396  'WHERE' => 'uid = ' . $this->taskUid,
397  'LIMIT' => 1
398  ];
399  $res = $GLOBALS['TYPO3_DB']->exec_SELECT_queryArray($queryArr);
400  $runningExecutions = [];
401  if ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
402  if (!empty($row['serialized_executions'])) {
403  $runningExecutions = unserialize($row['serialized_executions']);
404  }
405  }
406  $GLOBALS['TYPO3_DB']->sql_free_result($res);
407  // Count the number of existing executions and use that number as a key
408  // (we need to know that number, because it is returned at the end of the method)
409  $numExecutions = count($runningExecutions);
410  $runningExecutions[$numExecutions] = time();
411  // Define the context in which the script is running
412  $context = 'BE';
413  if (TYPO3_REQUESTTYPE & TYPO3_REQUESTTYPE_CLI) {
414  $context = 'CLI';
415  }
416  $GLOBALS['TYPO3_DB']->exec_UPDATEquery('tx_scheduler_task', 'uid = ' . $this->taskUid, [
417  'serialized_executions' => serialize($runningExecutions),
418  'lastexecution_time' => time(),
419  'lastexecution_context' => $context
420  ]);
421  return $numExecutions;
422  }
423 
431  public function unmarkExecution($executionID, \Exception $failure = null)
432  {
433  // Get the executions for the task
434  $queryArr = [
435  'SELECT' => 'serialized_executions',
436  'FROM' => 'tx_scheduler_task',
437  'WHERE' => 'uid = ' . $this->taskUid,
438  'LIMIT' => 1
439  ];
440  $res = $GLOBALS['TYPO3_DB']->exec_SELECT_queryArray($queryArr);
441  if ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
442  if ($row['serialized_executions'] !== '') {
443  $runningExecutions = unserialize($row['serialized_executions']);
444  // Remove the selected execution
445  unset($runningExecutions[$executionID]);
446  if (!empty($runningExecutions)) {
447  // Re-serialize the updated executions list (if necessary)
448  $runningExecutionsSerialized = serialize($runningExecutions);
449  } else {
450  $runningExecutionsSerialized = '';
451  }
452  if ($failure instanceof \Exception) {
453  // Log failed execution
454  $logMessage = 'Task failed to execute successfully. Class: ' . get_class($this)
455  . ', UID: ' . $this->taskUid . ', Code: ' . $failure->getCode() . ', ' . $failure->getMessage();
456  $this->scheduler->log($logMessage, 1);
457  // Do not serialize the complete exception or the trace, this can lead to huge strings > 50MB
458  $failureString = serialize([
459  'code' => $failure->getCode(),
460  'message' => $failure->getMessage(),
461  'file' => $failure->getFile(),
462  'line' => $failure->getLine(),
463  'traceString' => $failure->getTraceAsString(),
464  ]);
465  } else {
466  $failureString = '';
467  }
468  // Save the updated executions list
469  $GLOBALS['TYPO3_DB']->exec_UPDATEquery('tx_scheduler_task', 'uid = ' . $this->taskUid, [
470  'serialized_executions' => $runningExecutionsSerialized,
471  'lastexecution_failure' => $failureString
472  ]);
473  }
474  }
475  $GLOBALS['TYPO3_DB']->sql_free_result($res);
476  }
477 
483  public function unmarkAllExecutions()
484  {
485  // Set the serialized executions field to empty
486  $result = $GLOBALS['TYPO3_DB']->exec_UPDATEquery('tx_scheduler_task', 'uid = ' . $this->taskUid, [
487  'serialized_executions' => ''
488  ]);
489  return $result;
490  }
491 
497  public function save()
498  {
499  return $this->scheduler->saveTask($this);
500  }
501 
508  public function stop()
509  {
510  $this->execution = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Scheduler\Execution::class);
511  }
512 
518  public function remove()
519  {
520  $this->scheduler->removeTask($this);
521  }
522 
529  public function getType()
530  {
531  if (!empty($this->getExecution()->getInterval()) || !empty($this->getExecution()->getCronCmd())) {
532  return self::TYPE_RECURRING;
533  }
534  return self::TYPE_SINGLE;
535  }
536 }
unmarkExecution($executionID, \Exception $failure=null)
if(TYPO3_MODE==='BE') $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tsfebeuserauth.php']['frontendEditingController']['default']
setExecution(\TYPO3\CMS\Scheduler\Execution $execution)