From 36488dcab89a60b67df8ecb9e2ce9b5de777c0ea Mon Sep 17 00:00:00 2001 From: Andrew Nicols Date: Mon, 3 Nov 2025 09:12:07 +0800 Subject: [PATCH] MDL-87046 core: Update namespace of shutdown manager --- public/admin/tool/dbtransfer/locallib.php | 2 +- public/admin/tool/log/classes/log/manager.php | 2 +- .../tool/monitor/classes/eventobservers.php | 2 +- .../backup/cc/cc_lib/gral_lib/cssparser.php | 2 +- public/cache/stores/redis/lib.php | 3 +- .../converter/unoconv/classes/converter.php | 2 +- public/lib/classes/local/cli/shutdown.php | 15 +-------- .../classes/lock/db_record_lock_factory.php | 2 +- .../lib/classes/lock/mysql_lock_factory.php | 2 +- .../classes/lock/postgres_lock_factory.php | 2 +- .../classes/navigation/navigation_cache.php | 4 +-- public/lib/classes/session/manager.php | 2 +- public/lib/classes/shutdown_manager.php | 31 ++++++++++++------- public/lib/classes/task/logmanager.php | 2 +- public/lib/classes/task/manager.php | 4 +-- public/lib/filelib.php | 2 +- public/lib/setup.php | 4 +-- public/lib/setuplib.php | 2 +- public/lib/tests/task/manager_test.php | 4 +-- 19 files changed, 43 insertions(+), 46 deletions(-) diff --git a/public/admin/tool/dbtransfer/locallib.php b/public/admin/tool/dbtransfer/locallib.php index e4a417f1204..c74abd32528 100644 --- a/public/admin/tool/dbtransfer/locallib.php +++ b/public/admin/tool/dbtransfer/locallib.php @@ -160,7 +160,7 @@ function tool_dbtransfer_get_drivers() { function tool_dbtransfer_create_maintenance_file() { global $CFG; - core_shutdown_manager::register_function('tool_dbtransfer_maintenance_callback'); + \core\shutdown_manager::register_function('tool_dbtransfer_maintenance_callback'); $options = new stdClass(); $options->trusted = false; diff --git a/public/admin/tool/log/classes/log/manager.php b/public/admin/tool/log/classes/log/manager.php index a65aefd8c3f..d777783053a 100644 --- a/public/admin/tool/log/classes/log/manager.php +++ b/public/admin/tool/log/classes/log/manager.php @@ -50,7 +50,7 @@ class manager implements \core\log\manager { $this->writers = array(); // Register shutdown handler - this may be useful for buffering, file handle closing, etc. - \core_shutdown_manager::register_function(array($this, 'dispose')); + \core\shutdown_manager::register_function([$this, 'dispose']); $plugins = get_config('tool_log', 'enabled_stores'); if (empty($plugins)) { diff --git a/public/admin/tool/monitor/classes/eventobservers.php b/public/admin/tool/monitor/classes/eventobservers.php index bc9a0fae3e0..dea48622f85 100644 --- a/public/admin/tool/monitor/classes/eventobservers.php +++ b/public/admin/tool/monitor/classes/eventobservers.php @@ -78,7 +78,7 @@ class eventobservers { if (empty(self::$instance)) { self::$instance = new static(); // Register shutdown handler - this is useful for buffering, processing events, etc. - \core_shutdown_manager::register_function(array(self::$instance, 'process_buffer')); + \core\shutdown_manager::register_function([self::$instance, 'process_buffer']); } self::$instance->buffer_event($event); diff --git a/public/backup/cc/cc_lib/gral_lib/cssparser.php b/public/backup/cc/cc_lib/gral_lib/cssparser.php index fc2e3049947..43c459628dc 100644 --- a/public/backup/cc/cc_lib/gral_lib/cssparser.php +++ b/public/backup/cc/cc_lib/gral_lib/cssparser.php @@ -20,7 +20,7 @@ class cssparser { public function __construct($html = true) { // Register "destructor" - core_shutdown_manager::register_function(array(&$this, "finalize")); + \core\shutdown_manager::register_function([&$this, "finalize"]); $this->html = ($html != false); $this->Clear(); } diff --git a/public/cache/stores/redis/lib.php b/public/cache/stores/redis/lib.php index 769303ffd0a..d39f77b6ee0 100644 --- a/public/cache/stores/redis/lib.php +++ b/public/cache/stores/redis/lib.php @@ -22,6 +22,7 @@ use core_cache\searchable_cache_interface; use core_cache\store; use core\clock; use core\di; +use core\shutdown_manager; /** * Redis Cache Store @@ -689,7 +690,7 @@ class cachestore_redis extends store implements // If we haven't got it already, better register a shutdown function. if ($this->currentlocks === null) { - core_shutdown_manager::register_function([$this, 'shutdown_release_locks']); + shutdown_manager::register_function([$this, 'shutdown_release_locks']); $this->currentlocks = []; } diff --git a/public/files/converter/unoconv/classes/converter.php b/public/files/converter/unoconv/classes/converter.php index f07a90c3b04..c6c8dd50707 100644 --- a/public/files/converter/unoconv/classes/converter.php +++ b/public/files/converter/unoconv/classes/converter.php @@ -117,7 +117,7 @@ class converter implements \core_files\converter_interface { // Copy the file to the tmp dir. $uniqdir = make_unique_writable_directory(make_temp_directory('core_file/conversions')); - \core_shutdown_manager::register_function('remove_dir', array($uniqdir)); + \core\shutdown_manager::register_function('remove_dir', [$uniqdir]); $localfilename = $file->get_id() . '.' . $fromformat; $filename = $uniqdir . '/' . $localfilename; diff --git a/public/lib/classes/local/cli/shutdown.php b/public/lib/classes/local/cli/shutdown.php index 93f295cfd11..9f48f88d573 100644 --- a/public/lib/classes/local/cli/shutdown.php +++ b/public/lib/classes/local/cli/shutdown.php @@ -14,18 +14,8 @@ // You should have received a copy of the GNU General Public License // along with Moodle. If not, see . -/** - * CLI script shutdown helper class. - * - * @package core - * @copyright 2019 Brendan Heywood - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - namespace core\local\cli; -defined('MOODLE_INTERNAL') || die(); - /** * CLI script shutdown helper class. * @@ -34,7 +24,6 @@ defined('MOODLE_INTERNAL') || die(); * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class shutdown { - /** @var bool Should we exit gracefully at the next opportunity? */ protected static $cligracefulexit = false; @@ -44,7 +33,7 @@ class shutdown { * @return void */ public static function script_supports_graceful_exit(): void { - \core_shutdown_manager::register_signal_handler('\core\local\cli\shutdown::signal_handler'); + \core\shutdown_manager::register_signal_handler('\core\local\cli\shutdown::signal_handler'); } /** @@ -66,7 +55,6 @@ class shutdown { * @return bool true if we should exit */ public static function signal_handler(int $signo): bool { - if (self::$cligracefulexit) { cli_heading(get_string('cliexitnow', 'admin')); return true; @@ -78,4 +66,3 @@ class shutdown { } } - diff --git a/public/lib/classes/lock/db_record_lock_factory.php b/public/lib/classes/lock/db_record_lock_factory.php index 08ff76c8bca..09f49e57199 100644 --- a/public/lib/classes/lock/db_record_lock_factory.php +++ b/public/lib/classes/lock/db_record_lock_factory.php @@ -60,7 +60,7 @@ class db_record_lock_factory implements lock_factory { // Save a reference to the global $DB so it will not be released while we still have open locks. $this->db = $DB; - \core_shutdown_manager::register_function(array($this, 'auto_release')); + \core\shutdown_manager::register_function([$this, 'auto_release']); } /** diff --git a/public/lib/classes/lock/mysql_lock_factory.php b/public/lib/classes/lock/mysql_lock_factory.php index 7f2f6f566c6..05bae73f91a 100644 --- a/public/lib/classes/lock/mysql_lock_factory.php +++ b/public/lib/classes/lock/mysql_lock_factory.php @@ -63,7 +63,7 @@ class mysql_lock_factory implements lock_factory { // Save a reference to the global $DB so it will not be released while we still have open locks. $this->db = $DB; - \core_shutdown_manager::register_function([$this, 'auto_release']); + \core\shutdown_manager::register_function([$this, 'auto_release']); } /** diff --git a/public/lib/classes/lock/postgres_lock_factory.php b/public/lib/classes/lock/postgres_lock_factory.php index 1ec55e9487c..4c00f5bffd2 100644 --- a/public/lib/classes/lock/postgres_lock_factory.php +++ b/public/lib/classes/lock/postgres_lock_factory.php @@ -85,7 +85,7 @@ class postgres_lock_factory implements lock_factory { // Save a reference to the global $DB so it will not be released while we still have open locks. $this->db = $DB; - \core_shutdown_manager::register_function(array($this, 'auto_release')); + \core\shutdown_manager::register_function([$this, 'auto_release']); } /** diff --git a/public/lib/classes/navigation/navigation_cache.php b/public/lib/classes/navigation/navigation_cache.php index db69ecbda12..9c23aaa1330 100644 --- a/public/lib/classes/navigation/navigation_cache.php +++ b/public/lib/classes/navigation/navigation_cache.php @@ -18,7 +18,7 @@ namespace core\navigation; use core_cache\cache; use core_cache\session_cache; -use core_shutdown_manager; +use core\shutdown_manager; /** * The navigation_cache class is used for global and settings navigation data. @@ -175,7 +175,7 @@ class navigation_cache { public function volatile($setting = true) { if (self::$volatilecaches === null) { self::$volatilecaches = []; - core_shutdown_manager::register_function(['navigation_cache', 'destroy_volatile_caches']); + shutdown_manager::register_function(['navigation_cache', 'destroy_volatile_caches']); } if ($setting) { diff --git a/public/lib/classes/session/manager.php b/public/lib/classes/session/manager.php index dc803f2b487..aa5ef496f45 100644 --- a/public/lib/classes/session/manager.php +++ b/public/lib/classes/session/manager.php @@ -722,7 +722,7 @@ class manager { // If debugging, take a snapshot of session at close and compare on shutdown to detect any accidental mutations. if (debugging()) { self::$sessionatclose = (array) $_SESSION['SESSION']; - \core_shutdown_manager::register_function('\core\session\manager::check_mutated_closed_session'); + \core\shutdown_manager::register_function('\core\session\manager::check_mutated_closed_session'); } if (!$requireslock || !self::$requireslockdebug) { diff --git a/public/lib/classes/shutdown_manager.php b/public/lib/classes/shutdown_manager.php index 2d6a01fda18..071700fc355 100644 --- a/public/lib/classes/shutdown_manager.php +++ b/public/lib/classes/shutdown_manager.php @@ -14,6 +14,10 @@ // You should have received a copy of the GNU General Public License // along with Moodle. If not, see . +namespace core; + +use Throwable; + /** * Shutdown management class. * @@ -21,13 +25,13 @@ * @copyright 2013 Petr Skoda {@link http://skodak.org} * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -class core_shutdown_manager { +class shutdown_manager { /** @var array list of custom callbacks */ - protected static $callbacks = []; + protected static array $callbacks = []; /** @var array list of custom signal callbacks */ - protected static $signalcallbacks = []; + protected static array $signalcallbacks = []; /** @var bool is this manager already registered? */ - protected static $registered = false; + protected static bool $registered = false; /** @var array A list of pcntl handlers */ protected static array $pcntlhandlers = []; @@ -37,7 +41,7 @@ class core_shutdown_manager { * * Note: This method should _only_ be called from lib/setup.php. */ - public static function initialize() { + public static function initialize(): void { if (self::$registered) { debugging('Shutdown manager is already initialised!'); return; @@ -77,7 +81,7 @@ class core_shutdown_manager { * * @param int $signo The signal being handled */ - public static function signal_handler(int $signo) { + public static function signal_handler(int $signo): void { // Note: There is no need to manually call the shutdown handler. // The fact that we are calling exit() in this script means that the standard shutdown handling is performed // anyway. @@ -99,7 +103,7 @@ class core_shutdown_manager { default: // The signal handler was called with a signal it was not expecting. // We should exit and complain. - echo "Warning: \core_shutdown_manager::signal_handler() was called with an unexpected signal ({$signo}).\n"; + echo "Warning: \core\shutdown_manager::signal_handler() was called with an unexpected signal ({$signo}).\n"; $exitcode = 1; } @@ -134,7 +138,7 @@ class core_shutdown_manager { * @param array $params * @return void */ - public static function register_signal_handler($callback, ?array $params = null): void { + public static function register_signal_handler(callable $callback, ?array $params = null): void { if (!is_callable($callback)) { // phpcs:ignore moodle.PHP.ForbiddenFunctions.FoundWithAlternative error_log('Invalid custom signal function detected ' . var_export($callback, true)); // phpcs:ignore @@ -149,7 +153,7 @@ class core_shutdown_manager { * @param array $params * @return void */ - public static function register_function($callback, ?array $params = null): void { + public static function register_function(callable $callback, ?array $params = null): void { if (!is_callable($callback)) { // phpcs:ignore moodle.PHP.ForbiddenFunctions.FoundWithAlternative error_log('Invalid custom shutdown function detected '.var_export($callback, true)); // phpcs:ignore @@ -162,7 +166,7 @@ class core_shutdown_manager { * * Note: DO NOT call this method directly. It will be called automatically on shutdown. */ - public static function shutdown_handler() { + public static function shutdown_handler(): void { global $DB; // In case we caught an out of memory shutdown we increase memory limit to unlimited, so we can gracefully shut down. @@ -219,7 +223,7 @@ class core_shutdown_manager { /** * Standard shutdown sequence. */ - protected static function request_shutdown() { + protected static function request_shutdown(): void { global $CFG, $OUTPUT, $PERF; // Help apache server if possible. @@ -281,3 +285,8 @@ class core_shutdown_manager { } } } + +// Alias this class to the old name. +// This file will be autoloaded by the legacyclasses autoload system. +// In future all uses of this class will be corrected and the legacy references will be removed. +class_alias(shutdown_manager::class, \core_shutdown_manager::class); diff --git a/public/lib/classes/task/logmanager.php b/public/lib/classes/task/logmanager.php index 7f43282bbad..d8b5becfa39 100644 --- a/public/lib/classes/task/logmanager.php +++ b/public/lib/classes/task/logmanager.php @@ -96,7 +96,7 @@ class logmanager { // We register a shutdown handler to ensure that logs causing any failures are correctly disposed of. // Note: This must happen before the per-request directory is requested because the shutdown handler deletes the logfile. if (!self::$tasklogregistered) { - \core_shutdown_manager::register_function(function() { + \core\shutdown_manager::register_function(function (): void { // These will only actually do anything if capturing is current active when the thread ended, which // constitutes a failure. \core\task\logmanager::finalise_log(true); diff --git a/public/lib/classes/task/manager.php b/public/lib/classes/task/manager.php index 4ab7d573231..2190a0c8625 100644 --- a/public/lib/classes/task/manager.php +++ b/public/lib/classes/task/manager.php @@ -26,7 +26,7 @@ namespace core\task; use core\lock\lock; use core\lock\lock_factory; -use core_shutdown_manager; +use core\shutdown_manager; define('CORE_TASK_TASKS_FILENAME', 'db/tasks.php'); /** @@ -1120,7 +1120,7 @@ class manager { // Add \core\task\manager::fail_running_task to shutdown manager, so we can ensure running tasks fail on shutdown. if (!self::$registeredshutdownhandler) { - core_shutdown_manager::register_function('\core\task\manager::fail_running_task'); + shutdown_manager::register_function('\core\task\manager::fail_running_task'); self::$registeredshutdownhandler = true; } diff --git a/public/lib/filelib.php b/public/lib/filelib.php index c33e5953aa7..079671b13d7 100644 --- a/public/lib/filelib.php +++ b/public/lib/filelib.php @@ -2363,7 +2363,7 @@ function send_temp_file($path, $filename, $pathisstring=false) { throw new \moodle_exception('filenotfound', 'error', $CFG->wwwroot.'/'); } // executed after normal finish or abort - core_shutdown_manager::register_function('send_temp_file_finished', array($path)); + \core\shutdown_manager::register_function('send_temp_file_finished', [$path]); } // if user is using IE, urlencode the filename so that multibyte file name will show up correctly on popup diff --git a/public/lib/setup.php b/public/lib/setup.php index 575bd41eb03..b4be875479e 100644 --- a/public/lib/setup.php +++ b/public/lib/setup.php @@ -779,7 +779,7 @@ if (!isset($CFG->debugdisplay)) { } // Register our shutdown manager, do NOT use register_shutdown_function(). -core_shutdown_manager::initialize(); +\core\shutdown_manager::initialize(); // Verify upgrade is not running unless we are in a script that needs to execute in any case if (!defined('NO_UPGRADE_CHECK') and isset($CFG->upgraderunning)) { @@ -1187,7 +1187,7 @@ if (isset($CFG->maintenance_later) and $CFG->maintenance_later <= time()) { // Add behat_shutdown_function to shutdown manager, so we can capture php errors, // but not necessary for behat CLI command as it's being captured by behat process. if (defined('BEHAT_SITE_RUNNING') && !defined('BEHAT_TEST')) { - core_shutdown_manager::register_function('behat_shutdown_function'); + \core\shutdown_manager::register_function('behat_shutdown_function'); } // note: we can not block non utf-8 installations here, because empty mysql database diff --git a/public/lib/setuplib.php b/public/lib/setuplib.php index 7aac6bf295e..cb20ed62eca 100644 --- a/public/lib/setuplib.php +++ b/public/lib/setuplib.php @@ -1416,7 +1416,7 @@ function get_request_storage_directory($exceptiononerror = true, bool $forcecrea if ($dir = make_unique_writable_directory($basedir, $exceptiononerror)) { // Register a shutdown handler to remove the directory. - \core_shutdown_manager::register_function('remove_dir', [$dir]); + \core\shutdown_manager::register_function('remove_dir', [$dir]); } $requestdir = $dir; diff --git a/public/lib/tests/task/manager_test.php b/public/lib/tests/task/manager_test.php index 9d2bb429e75..885bc48cd80 100644 --- a/public/lib/tests/task/manager_test.php +++ b/public/lib/tests/task/manager_test.php @@ -260,7 +260,7 @@ final class manager_test extends \advanced_testcase { self::assertEmpty(manager::get_failed_adhoc_tasks()); // Trigger shutdown handler. - \core_shutdown_manager::shutdown_handler(); + \core\shutdown_manager::shutdown_handler(); $failedtasks = manager::get_failed_adhoc_tasks(); @@ -292,7 +292,7 @@ final class manager_test extends \advanced_testcase { $this->assertCount(1, $running); // Trigger shutdown handler. - \core_shutdown_manager::shutdown_handler(); + \core\shutdown_manager::shutdown_handler(); $running = manager::get_running_tasks(); $this->assertCount(0, $running);