From c5701ce7d453396462e72963b7ac8a0a0fcdb842 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20S=CC=8Ckoda?= Date: Thu, 8 Aug 2013 21:11:18 +0200 Subject: [PATCH] MDL-41086 rework detection of necessary upgrades --- lib/classes/component.php | 52 +++++++++++++++++++++ lib/moodlelib.php | 89 +++--------------------------------- lib/phpunit/classes/util.php | 2 +- lib/testing/classes/util.php | 54 +--------------------- lib/upgradelib.php | 2 + 5 files changed, 64 insertions(+), 135 deletions(-) diff --git a/lib/classes/component.php b/lib/classes/component.php index 09a9205bf44..622152a382c 100644 --- a/lib/classes/component.php +++ b/lib/classes/component.php @@ -779,6 +779,58 @@ $cache = '.var_export($cache, true).'; return $return; } + /** + * Returns hash of all versions including core and all plugins. + * + * This is relatively slow and not fully cached, use with care! + * + * @return string sha1 hash + */ + public static function get_all_versions_hash() { + global $CFG; + + self::init(); + + $versions = array(); + + // Main version first. + $version = null; + include($CFG->dirroot.'/version.php'); + $versions['core'] = $version; + + // The problem here is tha the component cache might be stable, + // we want this to work also on frontpage without resetting the component cache. + $usecache = false; + if (CACHE_DISABLE_ALL or (defined('IGNORE_COMPONENT_CACHE') and IGNORE_COMPONENT_CACHE)) { + $usecache = true; + } + + // Now all plugins. + $plugintypes = core_component::get_plugin_types(); + foreach ($plugintypes as $type => $typedir) { + if ($usecache) { + $plugs = core_component::get_plugin_list($type); + } else { + $plugs = self::fetch_plugins($type, $typedir); + } + foreach ($plugs as $plug => $fullplug) { + if ($type === 'mod') { + $module = new stdClass(); + $module->version = null; + include($fullplug.'/version.php'); + $versions[$plug] = $module->version; + } else { + $plugin = new stdClass(); + $plugin->version = null; + @include($fullplug.'/version.php'); + $versions[$plug] = $plugin->version; + } + } + } + + return sha1(serialize($versions)); + } + /** * Invalidate opcode cache for given file, this is intended for * php files that are stored in dataroot. diff --git a/lib/moodlelib.php b/lib/moodlelib.php index 6267a593893..578cd100f56 100644 --- a/lib/moodlelib.php +++ b/lib/moodlelib.php @@ -8864,15 +8864,15 @@ function get_browser_version_classes() { } /** - * Determine if moodle installation requires update + * Determine if moodle installation requires update. * - * Checks version numbers of main code and all modules to see - * if there are any mismatches + * Checks version numbers of main code and all plugins to see + * if there are any mismatches. * * @return bool */ function moodle_needs_upgrading() { - global $CFG, $DB; + global $CFG; if (empty($CFG->version)) { return true; @@ -8882,88 +8882,13 @@ function moodle_needs_upgrading() { // these caches are not used during upgrade and they are purged after // every upgrade. - // Check the main version first. - $version = null; - include($CFG->dirroot.'/version.php'); // Defines $version and upgrades. - if ($version > $CFG->version) { + if (empty($CFG->allversionshash)) { return true; } - // Modules. - $mods = core_component::get_plugin_list('mod'); - $installed = $DB->get_records('modules', array(), '', 'name, version'); - foreach ($mods as $mod => $fullmod) { - if ($mod === 'NEWMODULE') { // Someone has unzipped the template, ignore it. - continue; - } - $module = new stdClass(); - $plugin = new stdClass(); - if (!is_readable($fullmod.'/version.php')) { - continue; - } - include($fullmod.'/version.php'); // Defines $module with version etc. - if (!isset($module->version) and isset($plugin->version)) { - $module = $plugin; - } - if (empty($installed[$mod])) { - return true; - } else if ($module->version > $installed[$mod]->version) { - return true; - } - } - unset($installed); + $hash = core_component::get_all_versions_hash(); - // Blocks. - $blocks = core_component::get_plugin_list('block'); - $installed = $DB->get_records('block', array(), '', 'name, version'); - require_once($CFG->dirroot.'/blocks/moodleblock.class.php'); - foreach ($blocks as $blockname => $fullblock) { - if ($blockname === 'NEWBLOCK') { // Someone has unzipped the template, ignore it. - continue; - } - if (!is_readable($fullblock.'/version.php')) { - continue; - } - $plugin = new stdClass(); - $plugin->version = null; - include($fullblock.'/version.php'); - if (empty($installed[$blockname])) { - return true; - } else if ($plugin->version > $installed[$blockname]->version) { - return true; - } - } - unset($installed); - - // Now the rest of plugins. - $plugintypes = core_component::get_plugin_types(); - unset($plugintypes['mod']); - unset($plugintypes['block']); - - $versions = $DB->get_records_menu('config_plugins', array('name' => 'version'), 'plugin', 'plugin, value'); - foreach ($plugintypes as $type => $unused) { - $plugs = core_component::get_plugin_list($type); - foreach ($plugs as $plug => $fullplug) { - $component = $type.'_'.$plug; - if (!is_readable($fullplug.'/version.php')) { - continue; - } - $plugin = new stdClass(); - include($fullplug.'/version.php'); // Defines $plugin with version etc. - if (array_key_exists($component, $versions)) { - $installedversion = $versions[$component]; - } else { - $installedversion = get_config($component, 'version'); - } - if (empty($installedversion)) { // New installation. - return true; - } else if ($installedversion < $plugin->version) { // Upgrade. - return true; - } - } - } - - return false; + return ($hash !== $CFG->allversionshash); } /** diff --git a/lib/phpunit/classes/util.php b/lib/phpunit/classes/util.php index e5e130a3adc..552e78aaca8 100644 --- a/lib/phpunit/classes/util.php +++ b/lib/phpunit/classes/util.php @@ -72,7 +72,7 @@ class phpunit_util extends testing_util { initialise_cfg(); return; } - if ($dbhash !== self::get_version_hash()) { + if ($dbhash !== core_component::get_all_versions_hash()) { // do not set CFG - the only way forward is to drop and reinstall return; } diff --git a/lib/testing/classes/util.php b/lib/testing/classes/util.php index 5cef5ea5ba0..fe30ecdbdf9 100644 --- a/lib/testing/classes/util.php +++ b/lib/testing/classes/util.php @@ -137,7 +137,7 @@ abstract class testing_util { return false; } - $hash = self::get_version_hash(); + $hash = core_component::get_all_versions_hash(); $oldhash = file_get_contents($datarootpath . '/versionshash.txt'); if ($hash !== $oldhash) { @@ -195,7 +195,7 @@ abstract class testing_util { global $CFG; $framework = self::get_framework(); - $hash = self::get_version_hash(); + $hash = core_component::get_all_versions_hash(); // add test db flag set_config($framework . 'test', $hash); @@ -669,54 +669,4 @@ abstract class testing_util { } } } - - /** - * Calculate unique version hash for all plugins and core. - * @static - * @return string sha1 hash - */ - public static function get_version_hash() { - global $CFG; - - if (self::$versionhash) { - return self::$versionhash; - } - - $versions = array(); - - // main version first - $version = null; - include($CFG->dirroot.'/version.php'); - $versions['core'] = $version; - - // modules - $mods = core_component::get_plugin_list('mod'); - ksort($mods); - foreach ($mods as $mod => $fullmod) { - $module = new stdClass(); - $module->version = null; - include($fullmod.'/version.php'); - $versions[$mod] = $module->version; - } - - // now the rest of plugins - $plugintypes = core_component::get_plugin_types(); - unset($plugintypes['mod']); - ksort($plugintypes); - foreach ($plugintypes as $type => $unused) { - $plugs = core_component::get_plugin_list($type); - ksort($plugs); - foreach ($plugs as $plug => $fullplug) { - $plugin = new stdClass(); - $plugin->version = null; - @include($fullplug.'/version.php'); - $versions[$plug] = $plugin->version; - } - } - - self::$versionhash = sha1(serialize($versions)); - - return self::$versionhash; - } - } diff --git a/lib/upgradelib.php b/lib/upgradelib.php index 1ce09beb3bd..f0fa0960121 100644 --- a/lib/upgradelib.php +++ b/lib/upgradelib.php @@ -1594,6 +1594,8 @@ function upgrade_noncore($verbose) { } // Update cache definitions. Involves scanning each plugin for any changes. cache_helper::update_definitions(); + // Mark the site as upgraded. + set_config('allversionshash', core_component::get_all_versions_hash()); } catch (Exception $ex) { upgrade_handle_exception($ex); }