diff --git a/lib/classes/component.php b/lib/classes/component.php index 744a26b1e51..e7f3eb4b324 100644 --- a/lib/classes/component.php +++ b/lib/classes/component.php @@ -306,17 +306,7 @@ class core_component { if (is_readable($cachefile)) { $cache = false; include($cachefile); - if (!is_array($cache)) { - // Something is very wrong. - } else if (!isset($cache['version'])) { - // Something is very wrong. - } else if ((float) $cache['version'] !== (float) self::fetch_core_version()) { - // Outdated cache. We trigger an error log to track an eventual repetitive failure of float comparison. - error_log('Resetting core_component cache after core upgrade to version ' . self::fetch_core_version()); - } else if ($cache['plugintypes']['mod'] !== "$CFG->dirroot/mod") { - // phpcs:ignore moodle.Commenting.InlineComment.NotCapital - // $CFG->dirroot was changed. - } else { + if (is_array($cache) && self::is_cache_valid($cache)) { // The cache looks ok, let's use it. self::$plugintypes = $cache['plugintypes']; self::$plugins = $cache['plugins']; @@ -367,6 +357,53 @@ class core_component { } } + /** + * Check whether the cache content in the supplied cache is valid. + * + * @param array $cache The content being loaded + * @return bool Whether it is valid + */ + protected static function is_cache_valid(array $cache): bool { + global $CFG; + + if (!isset($cache['version'])) { + // Something is very wrong. + return false; + } + + if ((float) $cache['version'] !== (float) self::fetch_core_version()) { + // Outdated cache. We trigger an error log to track an eventual repetitive failure of float comparison. + error_log('Resetting core_component cache after core upgrade to version ' . self::fetch_core_version()); + return false; + } + + if ($cache['plugintypes']['mod'] !== "$CFG->dirroot/mod") { + // phpcs:ignore moodle.Commenting.InlineComment.NotCapital + // $CFG->dirroot was changed. + return false; + } + + // Check for key classes which block access to the upgrade in some way. + // Note: This list should be kept _extremely_ minimal and generally + // when adding a newly discovered classes older ones should be removed. + // Always keep moodle_exception in place. + $keyclasses = [ + \core\exception\moodle_exception::class, + \core\output\bootstrap_renderer::class, + ]; + foreach ($keyclasses as $classname) { + if (!array_key_exists($classname, $cache['classmap'])) { + // The cache is missing some key classes. This is likely before the upgrade has run. + error_log( + "The '{$classname}' class was not found in the component class cache. Resetting the classmap.", + ); + return false; + } + } + + return true; + } + /** * Are we in developer debug mode? * diff --git a/lib/classes/hook/manager.php b/lib/classes/hook/manager.php index a7a027b7c72..fc3e748a47e 100644 --- a/lib/classes/hook/manager.php +++ b/lib/classes/hook/manager.php @@ -184,9 +184,6 @@ final class manager implements return $hookclassname::get_deprecated_plugin_callbacks(); } - // Ensure that the replaces_callbacks attribute is loaded. - // TODO MDL-81134 Remove after LTS+1. - require_once(dirname(__DIR__) . '/attribute/hook/replaces_callbacks.php'); if ($replaces = attribute_helper::instance($hookclassname, \core\attribute\hook\replaces_callbacks::class)) { return $replaces->callbacks; } diff --git a/lib/outputrenderers.php b/lib/outputrenderers.php index 2093bb5da1f..918db5ec79d 100644 --- a/lib/outputrenderers.php +++ b/lib/outputrenderers.php @@ -657,11 +657,6 @@ class core_renderer extends renderer_base { public function htmlattributes() { $return = get_html_lang(true); - // Ensure that the callback exists prior to cache purge. - // This is a critical page path. - // TODO MDL-81134 Remove after LTS+1. - require_once(__DIR__ . '/classes/hook/output/before_html_attributes.php'); - $hook = new before_html_attributes($this); if ($this->page->theme->doctype !== 'html5') { @@ -809,11 +804,6 @@ class core_renderer extends renderer_base { $output .= "\n".$CFG->additionalhtmltopofbody; } - // Ensure that the callback exists prior to cache purge. - // This is a critical page path. - // TODO MDL-81134 Remove after LTS+1. - require_once(__DIR__ . '/classes/hook/output/before_standard_top_of_body_html_generation.php'); - // Allow components to add content to the top of the body. $hook = new before_standard_top_of_body_html_generation($this, $output); $hook->process_legacy_callbacks(); @@ -875,11 +865,6 @@ class core_renderer extends renderer_base { return ''; } - // Ensure that the callback exists prior to cache purge. - // This is a critical page path. - // TODO MDL-81134 Remove after LTS+1. - require_once(__DIR__ . '/classes/hook/output/before_standard_footer_html_generation.php'); - $hook = new before_standard_footer_html_generation($this); $hook->process_legacy_callbacks(); di::get(hook_manager::class)->dispatch($hook); @@ -1106,11 +1091,6 @@ class core_renderer extends renderer_base { public function standard_after_main_region_html() { global $CFG; - // Ensure that the callback exists prior to cache purge. - // This is a critical page path. - // TODO MDL-81134 Remove after LTS+1. - require_once(__DIR__ . '/classes/hook/output/after_standard_main_region_html_generation.php'); - $hook = new after_standard_main_region_html_generation($this); if ($this->page->pagelayout !== 'embedded' && !empty($CFG->additionalhtmlbottomofbody)) { @@ -1356,11 +1336,6 @@ class core_renderer extends renderer_base { public function header() { global $USER, $CFG, $SESSION; - // Ensure that the callback exists prior to cache purge. - // This is a critical page path. - // TODO MDL-81134 Remove after LTS+1. - require_once(__DIR__ . '/classes/hook/output/before_http_headers.php'); - $hook = new before_http_headers($this); $hook->process_legacy_callbacks(); di::get(hook_manager::class)->dispatch($hook); @@ -1481,11 +1456,6 @@ class core_renderer extends renderer_base { public function footer() { global $CFG, $DB, $PERF; - // Ensure that the callback exists prior to cache purge. - // This is a critical page path. - // TODO MDL-81134 Remove after LTS+1. - require_once(__DIR__ . '/classes/hook/output/before_footer_html_generation.php'); - $hook = new before_footer_html_generation($this); $hook->process_legacy_callbacks(); di::get(hook_manager::class)->dispatch($hook); diff --git a/lib/setup.php b/lib/setup.php index c0cf3891d1c..9c3fb46124e 100644 --- a/lib/setup.php +++ b/lib/setup.php @@ -620,10 +620,6 @@ if (defined('ABORT_AFTER_CONFIG')) { require_once($CFG->libdir .'/setuplib.php'); // Functions that MUST be loaded first. -// TODO MDL-81933 Remove after Moodle 4.5 release. -require_once($CFG->libdir . '/classes/exception/moodle_exception.php'); // Required by some other legacy libraries. -require_once($CFG->libdir . '/classes/output/bootstrap_renderer.php'); // Required by some other legacy libraries. - // Load up standard libraries. require_once($CFG->libdir .'/filterlib.php'); // Functions for filtering test as it is output. require_once($CFG->libdir .'/ajax/ajaxlib.php'); // Functions for managing our use of JavaScript and YUI.