diff --git a/lib/moodlelib.php b/lib/moodlelib.php index 7532952f55c..b0f51149c83 100644 --- a/lib/moodlelib.php +++ b/lib/moodlelib.php @@ -7801,7 +7801,14 @@ function get_plugin_list_with_function($plugintype, $function, $file = 'lib.php' $filepath = $allplugins[$pluginname] . DIRECTORY_SEPARATOR . $file; if (file_exists($filepath)) { include_once($filepath); - $pluginfunctions[$plugintype . '_' . $pluginname] = $functionname; + + // Now that the file is loaded, we must verify the function still exists. + if (function_exists($functionname)) { + $pluginfunctions[$plugintype . '_' . $pluginname] = $functionname; + } else { + // Invalidate the cache for next run. + \cache_helper::invalidate_by_definition('core', 'plugin_functions'); + } } } } @@ -7834,6 +7841,7 @@ function get_plugins_with_function($function, $file = 'lib.php', $include = true // Clearning the filename as cache_helper::hash_key only allows a-zA-Z0-9_. $key = $function . '_' . clean_param($file, PARAM_ALPHA); $pluginfunctions = $cache->get($key); + $dirty = false; // Use the plugin manager to check that plugins are currently installed. $pluginmanager = \core_plugin_manager::instance(); @@ -7848,14 +7856,14 @@ function get_plugins_with_function($function, $file = 'lib.php', $include = true foreach ($plugins as $plugin => $function) { if (!isset($installedplugins[$plugin])) { // Plugin code is still present on disk but it is not installed. - unset($pluginfunctions[$plugintype][$plugin]); - continue; + $dirty = true; + break 2; } // Cache might be out of sync with the codebase, skip the plugin if it is not available. if (empty($allplugins[$plugin])) { - unset($pluginfunctions[$plugintype][$plugin]); - continue; + $dirty = true; + break 2; } $fileexists = file_exists($allplugins[$plugin] . DIRECTORY_SEPARATOR . $file); @@ -7864,11 +7872,22 @@ function get_plugins_with_function($function, $file = 'lib.php', $include = true include_once($allplugins[$plugin] . DIRECTORY_SEPARATOR . $file); } else if (!$fileexists) { // If the file is not available any more it should not be returned. - unset($pluginfunctions[$plugintype][$plugin]); + $dirty = true; + break 2; + } + + // Check if the function still exists in the file. + if ($include && !function_exists($function)) { + $dirty = true; + break 2; } } } - return $pluginfunctions; + + // If the cache is dirty, we should fall through and let it rebuild. + if (!$dirty) { + return $pluginfunctions; + } } $pluginfunctions = array();