diff options
Diffstat (limited to 'engine/lib/upgrade.php')
| -rw-r--r-- | engine/lib/upgrade.php | 189 |
1 files changed, 152 insertions, 37 deletions
diff --git a/engine/lib/upgrade.php b/engine/lib/upgrade.php index 85810956b..158ec9ec1 100644 --- a/engine/lib/upgrade.php +++ b/engine/lib/upgrade.php @@ -14,21 +14,23 @@ * @param bool $quiet Suppress errors. Don't use this. * * @return bool + * @access private */ function upgrade_code($version, $quiet = FALSE) { + // do not remove - upgrade scripts depend on this global $CONFIG; - + $version = (int) $version; $upgrade_path = elgg_get_config('path') . 'engine/lib/upgrades/'; - $processed_upgrades = unserialize(datalist_get('processed_upgrades')); - // the day we started the new upgrade names - $upgrade_epoch = 2011021700; + $processed_upgrades = elgg_get_processed_upgrades(); + // upgrading from 1.7 to 1.8. Need to bootstrap. if (!$processed_upgrades) { - $processed_upgrades = array(); - } + elgg_upgrade_bootstrap_17_to_18(); - $upgrades = array(); + // grab accurate processed upgrades + $processed_upgrades = elgg_get_processed_upgrades(); + } $upgrade_files = elgg_get_upgrade_files($upgrade_path); @@ -36,23 +38,7 @@ function upgrade_code($version, $quiet = FALSE) { return false; } - // if before the new upgrade system, run through all upgrades and check - // version number. After the upgrade epoch, pull run upgrades from db - if ($version < $upgrade_epoch) { - foreach ($upgrade_files as $upgrade_file) { - $upgrade_version = elgg_get_upgrade_file_version($upgrade_file); - - if ($version < $upgrade_version) { - $upgrades[] = $upgrade_file; - } else { - // set this upgrade as processed so that we don't run it again - $processed_upgrades[] = $upgrade_file; - } - } - } else { - // add any upgrades that haven't been run to the upgrades list - $upgrades = elgg_get_unprocessed_upgrades($upgrade_files, $processed_upgrades); - } + $upgrades = elgg_get_unprocessed_upgrades($upgrade_files, $processed_upgrades); // Sort and execute sort($upgrades); @@ -67,7 +53,7 @@ function upgrade_code($version, $quiet = FALSE) { try { if (!@include("$upgrade_path/$upgrade")) { $success = false; - error_log($e->getmessage()); + error_log("Could not include $upgrade_path/$upgrade"); } } catch (Exception $e) { $success = false; @@ -76,6 +62,7 @@ function upgrade_code($version, $quiet = FALSE) { } else { if (!include("$upgrade_path/$upgrade")) { $success = false; + error_log("Could not include $upgrade_path/$upgrade"); } } @@ -84,13 +71,12 @@ function upgrade_code($version, $quiet = FALSE) { $processed_upgrades[] = $upgrade; // don't set the version to a lower number in instances where an upgrade - // has been merged from a lower version + // has been merged from a lower version of Elgg if ($upgrade_version > $version) { datalist_set('version', $upgrade_version); } - $processed_upgrades = array_unique($processed_upgrades); - datalist_set('processed_upgrades', serialize($processed_upgrades)); + elgg_set_processed_upgrades($processed_upgrades); } else { return false; } @@ -100,11 +86,37 @@ function upgrade_code($version, $quiet = FALSE) { } /** + * Saves the processed upgrades to a dataset. + * + * @param array $processed_upgrades An array of processed upgrade filenames + * (not the path, just the file) + * @return bool + * @access private + */ +function elgg_set_processed_upgrades(array $processed_upgrades) { + $processed_upgrades = array_unique($processed_upgrades); + return datalist_set('processed_upgrades', serialize($processed_upgrades)); +} + +/** + * Gets a list of processes upgrades + * + * @return mixed Array of processed upgrade filenames or false + * @access private + */ +function elgg_get_processed_upgrades() { + $upgrades = datalist_get('processed_upgrades'); + $unserialized = unserialize($upgrades); + return $unserialized; +} + +/** * Returns the version of the upgrade filename. * * @param string $filename The upgrade filename. No full path. * @return int|false - * @since 1.8 + * @since 1.8.0 + * @access private */ function elgg_get_upgrade_file_version($filename) { preg_match('/^([0-9]{10})([\.a-z0-9-_]+)?\.(php)$/i', $filename, $matches); @@ -121,6 +133,7 @@ function elgg_get_upgrade_file_version($filename) { * * @param string $upgrade_path The up * @return array|false + * @access private */ function elgg_get_upgrade_files($upgrade_path = null) { if (!$upgrade_path) { @@ -153,7 +166,7 @@ function elgg_get_upgrade_files($upgrade_path = null) { } /** - * Get the current version information + * Get the current Elgg version information * * @param bool $humanreadable Whether to return a human readable version (default: false) * @@ -162,13 +175,18 @@ function elgg_get_upgrade_files($upgrade_path = null) { function get_version($humanreadable = false) { global $CONFIG; + static $version, $release; + if (isset($CONFIG->path)) { - if (include($CONFIG->path . "version.php")) { - return (!$humanreadable) ? $version : $release; + if (!isset($version) || !isset($release)) { + if (!include($CONFIG->path . "version.php")) { + return false; + } } + return (!$humanreadable) ? $version : $release; } - return FALSE; + return false; } /** @@ -177,7 +195,8 @@ function get_version($humanreadable = false) { * @param null|array $upgrade_files Optional upgrade files * @param null|array $processed_upgrades Optional processed upgrades * - * @return array() + * @return array + * @access private */ function elgg_get_unprocessed_upgrades($upgrade_files = null, $processed_upgrades = null) { if ($upgrade_files === null) { @@ -198,7 +217,8 @@ function elgg_get_unprocessed_upgrades($upgrade_files = null, $processed_upgrade /** * Determines whether or not the database needs to be upgraded. * - * @return true|false Depending on whether or not the db version matches the code version + * @return bool Depending on whether or not the db version matches the code version + * @access private */ function version_upgrade_check() { $dbversion = (int) datalist_get('version'); @@ -215,7 +235,7 @@ function version_upgrade_check() { * Upgrades Elgg Database and code * * @return bool - * + * @access private */ function version_upgrade() { // It's possible large upgrades could exceed the max execution time. @@ -225,7 +245,7 @@ function version_upgrade() { // No version number? Oh snap...this is an upgrade from a clean installation < 1.7. // Run all upgrades without error reporting and hope for the best. - // See http://trac.elgg.org/elgg/ticket/1432 for more. + // See https://github.com/elgg/elgg/issues/1432 for more. $quiet = !$dbversion; // Note: Database upgrades are deprecated as of 1.8. Use code upgrades. See #1433 @@ -248,3 +268,98 @@ function version_upgrade() { return false; } + +/** + * Boot straps into 1.8 upgrade system from 1.7 + * + * This runs all the 1.7 upgrades, then sets the processed_upgrades to all existing 1.7 upgrades. + * Control is then passed back to the main upgrade function which detects and runs the + * 1.8 upgrades, regardless of filename convention. + * + * @return bool + * @access private + */ +function elgg_upgrade_bootstrap_17_to_18() { + $db_version = (int) datalist_get('version'); + + // the 1.8 upgrades before the upgrade system change that are interspersed with 1.7 upgrades. + $upgrades_18 = array( + '2010111501.php', + '2010121601.php', + '2010121602.php', + '2010121701.php', + '2010123101.php', + '2011010101.php', + ); + + $upgrade_files = elgg_get_upgrade_files(); + $processed_upgrades = array(); + + foreach ($upgrade_files as $upgrade_file) { + // ignore if not in 1.7 format or if it's a 1.8 upgrade + if (in_array($upgrade_file, $upgrades_18) || !preg_match("/[0-9]{10}\.php/", $upgrade_file)) { + continue; + } + + $upgrade_version = elgg_get_upgrade_file_version($upgrade_file); + + // this has already been run in a previous 1.7.X -> 1.7.X upgrade + if ($upgrade_version < $db_version) { + $processed_upgrades[] = $upgrade_file; + } + } + + return elgg_set_processed_upgrades($processed_upgrades); +} + +/** + * Creates a table {prefix}upgrade_lock that is used as a mutex for upgrades. + * + * @see _elgg_upgrade_lock() + * + * @return bool + * @access private + */ +function _elgg_upgrade_lock() { + global $CONFIG; + + if (!_elgg_upgrade_is_locked()) { + // lock it + insert_data("create table {$CONFIG->dbprefix}upgrade_lock (id INT)"); + elgg_log('Locked for upgrade.', 'NOTICE'); + return true; + } + + elgg_log('Cannot lock for upgrade: already locked.', 'WARNING'); + return false; +} + +/** + * Unlocks upgrade. + * + * @see _elgg_upgrade_lock() + * + * @access private + */ +function _elgg_upgrade_unlock() { + global $CONFIG; + delete_data("drop table {$CONFIG->dbprefix}upgrade_lock"); + elgg_log('Upgrade unlocked.', 'NOTICE'); +} + +/** + * Checks if upgrade is locked + * + * @return bool + * @access private + */ +function _elgg_upgrade_is_locked() { + global $CONFIG; + + $is_locked = count(get_data("show tables like '{$CONFIG->dbprefix}upgrade_lock'")); + + // @todo why? + _elgg_invalidate_query_cache(); + + return $is_locked; +} |
