[TASK] Merge submodule fluid into core
[Packages/TYPO3.CMS.git] / typo3 / sysext / scheduler / Classes / Scheduler.php
index 05da6f5..d901210 100644 (file)
@@ -4,7 +4,7 @@ namespace TYPO3\CMS\Scheduler;
 /***************************************************************
  *  Copyright notice
  *
- *  (c) 2005 Christian Jul Jensen <julle@typo3.org>
+ *  (c) 2005-2013 Christian Jul Jensen <julle@typo3.org>
  *
  *  All rights reserved
  *
@@ -30,8 +30,6 @@ namespace TYPO3\CMS\Scheduler;
  *
  * @author     Fran├žois Suter <francois@typo3.org>
  * @author     Christian Jul Jensen <julle@typo3.org>
- * @package            TYPO3
- * @subpackage         tx_scheduler
  */
 class Scheduler implements \TYPO3\CMS\Core\SingletonInterface {
 
@@ -62,15 +60,14 @@ class Scheduler implements \TYPO3\CMS\Core\SingletonInterface {
        /**
         * Adds a task to the pool
         *
-        * @param \TYPO3\CMS\Scheduler\Task $task The object representing the task to add
+        * @param \TYPO3\CMS\Scheduler\Task\AbstractTask $task The object representing the task to add
         * @return boolean TRUE if the task was successfully added, FALSE otherwise
         */
-       public function addTask(\TYPO3\CMS\Scheduler\Task $task) {
+       public function addTask(\TYPO3\CMS\Scheduler\Task\AbstractTask $task) {
                $taskUid = $task->getTaskUid();
                if (empty($taskUid)) {
                        $fields = array(
                                'crdate' => $GLOBALS['EXEC_TIME'],
-                               'classname' => get_class($task),
                                'disable' => $task->isDisabled(),
                                'serialized_task_object' => 'RESERVED'
                        );
@@ -99,16 +96,17 @@ class Scheduler implements \TYPO3\CMS\Core\SingletonInterface {
                // Select all tasks with executions
                // NOTE: this cleanup is done for disabled tasks too,
                // to avoid leaving old executions lying around
-               $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('uid, classname, serialized_executions', 'tx_scheduler_task', 'serialized_executions <> \'\'');
+               $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('uid, serialized_executions, serialized_task_object', 'tx_scheduler_task', 'serialized_executions <> \'\'');
                $maxDuration = $this->extConf['maxLifetime'] * 60;
                while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
+                       $executions = array();
                        if ($serialized_executions = unserialize($row['serialized_executions'])) {
-                               $executions = array();
                                foreach ($serialized_executions as $task) {
                                        if ($tstamp - $task < $maxDuration) {
                                                $executions[] = $task;
                                        } else {
-                                               $logMessage = 'Removing logged execution, assuming that the process is dead. Execution of \'' . $row['classname'] . '\' (UID: ' . $row['uid'] . ') was started at ' . date('Y-m-d H:i:s', $task);
+                                               $task = unserialize($row['serialized_task_object']);
+                                               $logMessage = 'Removing logged execution, assuming that the process is dead. Execution of \'' . get_class($task) . '\' (UID: ' . $row['uid'] . ') was started at ' . date('Y-m-d H:i:s', $task);
                                                $this->log($logMessage);
                                        }
                                }
@@ -129,10 +127,10 @@ class Scheduler implements \TYPO3\CMS\Core\SingletonInterface {
         * This method executes the given task and properly marks and records that execution
         * It is expected to return FALSE if the task was barred from running or if it was not saved properly
         *
-        * @param \TYPO3\CMS\Scheduler\Task $task The task to execute
+        * @param \TYPO3\CMS\Scheduler\Task\AbstractTask $task The task to execute
         * @return boolean Whether the task was saved successfully to the database or not
         */
-       public function executeTask(\TYPO3\CMS\Scheduler\Task $task) {
+       public function executeTask(\TYPO3\CMS\Scheduler\Task\AbstractTask $task) {
                // Trigger the saving of the task, as this will calculate its next execution time
                // This should be calculated all the time, even if the execution is skipped
                // (in case it is skipped, this pushes back execution to the next possible date)
@@ -189,7 +187,7 @@ class Scheduler implements \TYPO3\CMS\Core\SingletonInterface {
                if ($type !== 'manual' && $type !== 'cli-by-id') {
                        $type = 'cron';
                }
-               /** @var \TYPO3\CMS\Core\Registry $registry */
+               /** @var $registry \TYPO3\CMS\Core\Registry */
                $registry = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Registry');
                $runInformation = array('start' => $GLOBALS['EXEC_TIME'], 'end' => time(), 'type' => $type);
                $registry->set('tx_scheduler', 'lastRun', $runInformation);
@@ -199,10 +197,10 @@ class Scheduler implements \TYPO3\CMS\Core\SingletonInterface {
         * Removes a task completely from the system.
         * TODO: find a way to actually kill the existing jobs
         *
-        * @param \TYPO3\CMS\Scheduler\Task $task The object representing the task to delete
+        * @param \TYPO3\CMS\Scheduler\Task\AbstractTask $task The object representing the task to delete
         * @return boolean TRUE if task was successfully deleted, FALSE otherwise
         */
-       public function removeTask(\TYPO3\CMS\Scheduler\Task $task) {
+       public function removeTask(\TYPO3\CMS\Scheduler\Task\AbstractTask $task) {
                $taskUid = $task->getTaskUid();
                if (!empty($taskUid)) {
                        $result = $GLOBALS['TYPO3_DB']->exec_DELETEquery('tx_scheduler_task', 'uid = ' . $taskUid);
@@ -218,10 +216,10 @@ class Scheduler implements \TYPO3\CMS\Core\SingletonInterface {
        /**
         * Updates a task in the pool
         *
-        * @param \TYPO3\CMS\Scheduler\Task $task Scheduler task object
+        * @param \TYPO3\CMS\Scheduler\Task\AbstractTask $task Scheduler task object
         * @return boolean False if submitted task was not of proper class
         */
-       public function saveTask(\TYPO3\CMS\Scheduler\Task $task) {
+       public function saveTask(\TYPO3\CMS\Scheduler\Task\AbstractTask $task) {
                $taskUid = $task->getTaskUid();
                if (!empty($taskUid)) {
                        try {
@@ -234,7 +232,6 @@ class Scheduler implements \TYPO3\CMS\Core\SingletonInterface {
                        $task->unsetScheduler();
                        $fields = array(
                                'nextexecution' => $executionTime,
-                               'classname' => get_class($task),
                                'disable' => $task->isDisabled(),
                                'serialized_task_object' => serialize($task)
                        );
@@ -254,7 +251,7 @@ class Scheduler implements \TYPO3\CMS\Core\SingletonInterface {
         * If there are no due tasks the method throws an exception.
         *
         * @param integer $uid Primary key of a task
-        * @return \TYPO3\CMS\Scheduler\Task The fetched task object
+        * @return \TYPO3\CMS\Scheduler\Task\AbstractTask The fetched task object
         */
        public function fetchTask($uid = 0) {
                // Define where clause
@@ -276,7 +273,7 @@ class Scheduler implements \TYPO3\CMS\Core\SingletonInterface {
                        throw new \OutOfBoundsException('No task', 1247827244);
                } else {
                        $row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res);
-                       /** @var $task \TYPO3\CMS\Scheduler\Task */
+                       /** @var $task \TYPO3\CMS\Scheduler\Task\AbstractTask */
                        $task = unserialize($row['serialized_task_object']);
                        if ($this->isValidTaskObject($task)) {
                                // The task is valid, return it
@@ -362,7 +359,7 @@ class Scheduler implements \TYPO3\CMS\Core\SingletonInterface {
         * @return boolean TRUE if object is a task, FALSE otherwise
         */
        public function isValidTaskObject($task) {
-               return $task instanceof \TYPO3\CMS\Scheduler\Task;
+               return $task instanceof \TYPO3\CMS\Scheduler\Task\AbstractTask;
        }
 
        /**
@@ -404,10 +401,15 @@ class Scheduler implements \TYPO3\CMS\Core\SingletonInterface {
                $tasks = $this->fetchTasksWithCondition('');
                $nextExecution = FALSE;
                foreach ($tasks as $task) {
-                       /** @var $task \TYPO3\CMS\Scheduler\Task */
-                       $tempNextExecution = $task->getNextDueExecution();
-                       if ($nextExecution === FALSE || $tempNextExecution < $nextExecution) {
-                               $nextExecution = $tempNextExecution;
+                       try {
+                               /** @var $task \TYPO3\CMS\Scheduler\Task\AbstractTask */
+                               $tempNextExecution = $task->getNextDueExecution();
+                               if ($nextExecution === FALSE || $tempNextExecution < $nextExecution) {
+                                       $nextExecution = $tempNextExecution;
+                               }
+                       } catch (\OutOfBoundsException $e) {
+                               // The event will not be executed again or has already ended - we don't have to consider it for
+                               // scheduling the next "at" run
                        }
                }
                if ($nextExecution !== FALSE) {
@@ -417,8 +419,8 @@ class Scheduler implements \TYPO3\CMS\Core\SingletonInterface {
                                $startTime = 'now+1minute';
                        }
                        $cliDispatchPath = PATH_site . 'typo3/cli_dispatch.phpsh';
+                       $currentLocale = setlocale(LC_CTYPE, 0);
                        if ($GLOBALS['TYPO3_CONF_VARS']['SYS']['UTF8filesystem']) {
-                               $currentLocale = setlocale(LC_CTYPE, 0);
                                setlocale(LC_CTYPE, $GLOBALS['TYPO3_CONF_VARS']['SYS']['systemLocale']);
                        }
                        $cmd = 'echo ' . escapeshellarg($cliDispatchPath) . ' scheduler | at ' . escapeshellarg($startTime) . ' 2>&1';