diff --git a/lib/classes/task/manager.php b/lib/classes/task/manager.php index d1121728505..17313e0faee 100644 --- a/lib/classes/task/manager.php +++ b/lib/classes/task/manager.php @@ -93,12 +93,18 @@ class manager { $tasks = self::load_default_scheduled_tasks_for_component($componentname); $tasklocks = array(); - foreach ($tasks as $task) { + foreach ($tasks as $taskid => $task) { $classname = get_class($task); if (strpos($classname, '\\') !== 0) { $classname = '\\' . $classname; } + // If there is an existing task with a custom schedule, do not override it. + $currenttask = self::get_scheduled_task($classname); + if ($currenttask && $currenttask->is_customised()) { + $tasks[$taskid] = $currenttask; + } + if (!$lock = $cronlockfactory->get_lock($classname, 10, 60)) { // Could not get all the locks required - release all locks and fail. foreach ($tasklocks as $tasklock) { @@ -330,7 +336,7 @@ class manager { $tasks = array(); // We are just reading - so no locks required. - $records = $DB->get_records('task_scheduled', array('componentname' => $componentname), 'classname', '*', IGNORE_MISSING); + $records = $DB->get_records('task_scheduled', array('component' => $componentname), 'classname', '*', IGNORE_MISSING); foreach ($records as $record) { $task = self::scheduled_task_from_record($record); // Safety check in case the task in the DB does not match a real class (maybe something was uninstalled). diff --git a/lib/tests/scheduled_task_test.php b/lib/tests/scheduled_task_test.php index 599c5010082..27b401a37bb 100644 --- a/lib/tests/scheduled_task_test.php +++ b/lib/tests/scheduled_task_test.php @@ -157,6 +157,45 @@ class core_scheduled_task_testcase extends advanced_testcase { date_default_timezone_set($currenttimezonephp); } + public function test_reset_scheduled_tasks_for_component() { + global $DB; + + $this->resetAfterTest(true); + // Remember the defaults. + $defaulttasks = \core\task\manager::load_scheduled_tasks_for_component('moodle'); + $initcount = count($defaulttasks); + // Customise a task. + $firsttask = reset($defaulttasks); + $firsttask->set_minute('1'); + $firsttask->set_hour('2'); + $firsttask->set_month('3'); + $firsttask->set_day_of_week('4'); + $firsttask->set_day('5'); + $firsttask->set_customised('1'); + \core\task\manager::configure_scheduled_task($firsttask); + $firsttaskrecord = \core\task\manager::record_from_scheduled_task($firsttask); + // We reset this field, because we do not want to compare it. + $firsttaskrecord->nextruntime = '0'; + + // Now call reset on all the tasks. + \core\task\manager::reset_scheduled_tasks_for_component('moodle'); + + // Load the tasks again. + $defaulttasks = \core\task\manager::load_scheduled_tasks_for_component('moodle'); + $finalcount = count($defaulttasks); + // Compare the first task. + $newfirsttask = reset($defaulttasks); + $newfirsttaskrecord = \core\task\manager::record_from_scheduled_task($newfirsttask); + // We reset this field, because we do not want to compare it. + $newfirsttaskrecord->nextruntime = '0'; + + // Assert a customised task was not altered by reset. + $this->assertEquals($firsttaskrecord, $newfirsttaskrecord); + + // Assert we have the same number of tasks. + $this->assertEquals($initcount, $finalcount); + } + public function test_get_next_scheduled_task() { global $DB;