From cd305dc26b0425cc8fcfe3e6733cdef5cf3df22b Mon Sep 17 00:00:00 2001 From: Andrew Nicols Date: Wed, 2 May 2018 11:40:08 +0800 Subject: [PATCH] MDL-61800 task: Reset the OUTPUT and PAGE on execution --- lib/cronlib.php | 45 +++++++++++++++++++++++++++++++++++++++++++++ lib/upgrade.txt | 1 + 2 files changed, 46 insertions(+) diff --git a/lib/cronlib.php b/lib/cronlib.php index 4ce1c698836..589af74503f 100644 --- a/lib/cronlib.php +++ b/lib/cronlib.php @@ -101,6 +101,7 @@ function cron_run_inner_scheduled_task(\core\task\task_base $task) { $pretime = microtime(1); try { get_mailer('buffer'); + cron_prepare_core_renderer(); $task->execute(); if ($DB->is_transaction_started()) { throw new coding_exception("Task left transaction open"); @@ -130,6 +131,8 @@ function cron_run_inner_scheduled_task(\core\task\task_base $task) { mtrace(format_backtrace($e->getTrace(), true)); } \core\task\manager::scheduled_task_failed($task); + } finally { + cron_prepare_core_renderer(true); } get_mailer('close'); } @@ -178,6 +181,7 @@ function cron_run_inner_adhoc_task(\core\task\adhoc_task $task) { try { get_mailer('buffer'); + cron_prepare_core_renderer(); $task->execute(); if ($DB->is_transaction_started()) { throw new coding_exception("Task left transaction open"); @@ -210,6 +214,7 @@ function cron_run_inner_adhoc_task(\core\task\adhoc_task $task) { } finally { // Reset back to the standard admin user. cron_setup_user(); + cron_prepare_core_renderer(true); } get_mailer('close'); } @@ -433,3 +438,43 @@ function cron_bc_hack_plugin_functions($plugintype, $plugins) { return $plugins; } + +/** + * Prepare the output renderer for the cron run. + * + * This involves creating a new $PAGE, and $OUTPUT fresh for each task and prevents any one task from influencing + * any other. + * + * @param bool $restore Whether to restore the original PAGE and OUTPUT + */ +function cron_prepare_core_renderer($restore = false) { + global $OUTPUT, $PAGE; + + // Store the original PAGE and OUTPUT values so that they can be reset at a later point to the original. + // This should not normally be required, but may be used in places such as the scheduled task tool's "Run now" + // functionality. + static $page = null; + static $output = null; + + if (null === $page) { + $page = $PAGE; + } + + if (null === $output) { + $output = $OUTPUT; + } + + if (!empty($restore)) { + $PAGE = $page; + $page = null; + + $OUTPUT = $output; + $output = null; + } else { + // Setup a new General renderer. + // Cron tasks may produce output to be used in web, so we must use the appropriate renderer target. + // This allows correct use of templates, etc. + $PAGE = new \moodle_page(); + $OUTPUT = new \core_renderer($PAGE, RENDERER_TARGET_GENERAL); + } +} diff --git a/lib/upgrade.txt b/lib/upgrade.txt index c569cf603b0..54f8dec8964 100644 --- a/lib/upgrade.txt +++ b/lib/upgrade.txt @@ -3,6 +3,7 @@ information provided here is intended especially for developers. === 3.5 === +* The cron runner now sets up a fresh PAGE and OUTPUT between each task. * The core_renderer methods notify_problem(), notify_success(), notify_message() and notify_redirect() that were deprecated in Moodle 3.1 have been removed. Use \core\notification::add(), or \core\output\notification as required. * The maximum supported precision (the total number of digits) for XMLDB_TYPE_NUMBER ("number") fields raised from 20 to