Index: branches/5.1.x/core/install.php
===================================================================
diff -u -N -r13773 -r13780
--- branches/5.1.x/core/install.php (.../install.php) (revision 13773)
+++ branches/5.1.x/core/install.php (.../install.php) (revision 13780)
@@ -1,6 +1,6 @@
Array ('check_paths', 'clean_db', 'db_config', 'select_license', /*'download_license',*/ 'select_domain', 'root_password', 'choose_modules', 'post_config', 'select_theme', 'security', 'finish'),
'already_installed' => Array ('check_paths', 'install_setup'),
- 'upgrade' => Array ('check_paths', 'install_setup', 'upgrade_modules', 'security', 'finish'),
+ 'upgrade' => Array ('check_paths', 'install_setup', 'upgrade_modules', 'skin_upgrade', 'security', 'finish'),
'update_license' => Array ('check_paths', 'install_setup', 'select_license', /*'download_license',*/ 'select_domain', 'security', 'finish'),
'db_reconfig' => Array ('check_paths', 'install_setup', 'db_reconfig', 'security', 'finish'),
'fix_paths' => Array ('check_paths', 'install_setup', 'fix_paths', 'security', 'finish'),
@@ -128,6 +128,20 @@
var $LastQueryNum = 0;
/**
+ * Dependencies, that should be used in upgrade process
+ *
+ * @var Array
+ */
+ var $upgradeDepencies = Array ();
+
+ /**
+ * Log of upgrade - list of upgraded modules and their versions
+ *
+ * @var Array
+ */
+ var $upgradeLog = Array ();
+
+ /**
* Common tools required for installation process
*
* @var kInstallToolkit
@@ -312,6 +326,13 @@
}
break;
+ case 'skin_upgrade':
+ if ($this->Application->RecallVar('SkinUpgradeLog') === false) {
+ // no errors during skin upgrade -> skip this step
+ $this->currentStep = $this->GetNextStep();
+ }
+ break;
+
case 'install_setup':
$next_preset = $this->Application->GetVar('next_preset');
if ($next_preset !== false) {
@@ -838,51 +859,71 @@
case 'upgrade_modules':
// get installed modules from db and compare their versions to upgrade script
$modules = $this->Application->GetVar('modules');
+
if ($modules) {
$upgrade_data = $this->GetUpgradableModules();
+ $start_from_query = $this->Application->GetVar('start_from_query');
+ $this->upgradeDepencies = $this->getUpgradeDependencies($modules, $upgrade_data);
- $start_from_module = $this->GetVar('continue_from_module');
- $start_from_query = $this->GetVar('continue_from_query');
- if (!$start_from_query) $start_from_query = 0;
- foreach ($modules as $module_name) {
- if ($start_from_module && $module_name != $start_from_module) {
- continue;
+ if ($start_from_query !== false) {
+ $this->upgradeLog = unserialize( $this->Application->RecallVar('UpgradeLog') );
+ }
+ else {
+ $start_from_query = 0;
+ $this->upgradeLog = Array ('ModuleVersions' => Array ());
+
+ // remember each module version, before upgrade scripts are executed
+ foreach ($modules as $module_name) {
+ $module_info = $upgrade_data[$module_name];
+ $this->upgradeLog['ModuleVersions'][$module_name] = $module_info['FromVersion'];
}
- else {
- $start_from_module = false; //otherwise it will skip all modules after the one we start with!
- }
- $module_info = $upgrade_data[$module_name];
- $upgrades_file = sprintf(UPGRADES_FILE, $module_info['Path'], 'sql');
- $sqls = file_get_contents($upgrades_file);
- $version_mark = preg_replace('/(\(.*?\))/', $module_info['FromVersion'], VERSION_MARK);
+ $this->Application->RemoveVar('UpgradeLog');
+ }
- // get only sqls from next (relative to current) version to end of file
- $start_pos = strpos($sqls, $version_mark);
- $sqls = substr($sqls, $start_pos);
+ // 1. perform "php before", "sql", "php after" upgrades
+ foreach ($modules as $module_name) {
+ $module_info = $upgrade_data[$module_name];
- preg_match_all('/'.VERSION_MARK.'/s', $sqls, $regs);
+ /*echo '
Upgrading "' . $module_info['Name'] . '" to "' . $module_info['ToVersion'] . '"
' . "\n";
+ flush();*/
- if (!$start_from_module) {
- $this->RunUpgrades($module_info['Path'], $regs[1], 'before');
- }
- if (!$this->toolkit->RunSQLText($sqls, null, null, $start_from_query)) {
- $this->errorMessage .= '';
- $this->errorMessage .= '';
- $this->errorMessage .= '
Click Continue button below to skip this query and go further
';
+ if (!$this->RunUpgrade($module_info['Name'], $module_info['ToVersion'], $upgrade_data, $start_from_query)) {
+ $this->Application->StoreVar('UpgradeLog', serialize($this->upgradeLog));
$this->Done();
}
- $start_from_query = 0; // so that next module start from the beggining
+ // restore upgradable module version (makes sense after sql error processing)
+ $upgrade_data[$module_name]['FromVersion'] = $this->upgradeLog['ModuleVersions'][$module_name];
+ }
+
+ // 2. import language pack, perform "languagepack" upgrade for all upgraded versions
+ foreach ($modules as $module_name) {
+ $module_info = $upgrade_data[$module_name];
+ $sqls =& $this->getUpgradeQueriesFromVersion($module_info['Path'], $module_info['FromVersion']);
+ preg_match_all('/' . VERSION_MARK . '/s', $sqls, $regs);
+
+ // import module language pack
$this->toolkit->ImportLanguage('/' . $module_info['Path'] . 'install/english', true);
- $this->RunUpgrades($module_info['Path'], $regs[1], 'after'); // upgrade script could operate resulting language pack
- // after upgrade sqls are executed update version and upgrade language pack
- $this->toolkit->SetModuleVersion($module_name, false, $module_info['ToVersion']);
+ // perform advanced language pack upgrade
+ foreach ($regs[1] as $version) {
+ $this->RunUpgradeScript($module_info['Path'], $version, 'languagepack');
+ }
}
- // for now we set "In-Portal" module version to "Core" module version (during upgrade)
+ // 3. upgrade admin skin
if (in_array('core', $modules)) {
+ $skin_upgrade_log = $this->toolkit->upgradeSkin($upgrade_data['core']);
+
+ if ($skin_upgrade_log === true) {
+ $this->Application->RemoveVar('SkinUpgradeLog');
+ }
+ else {
+ $this->Application->StoreVar('SkinUpgradeLog', serialize($skin_upgrade_log));
+ }
+
+ // for now we set "In-Portal" module version to "Core" module version (during upgrade)
$this->toolkit->SetModuleVersion('In-Portal', false, $upgrade_data['core']['ToVersion']);
}
}
@@ -934,40 +975,187 @@
}
}
+ function getUpgradeDependencies($modules, &$upgrade_data)
+ {
+ $dependencies = Array ();
+
+ foreach ($modules as $module_name) {
+ $module_info = $upgrade_data[$module_name];
+ $upgrade_object =& $this->getUpgradeObject($module_info['Path']);
+
+ if (!is_object($upgrade_object)) {
+ continue;
+ }
+
+ foreach ($upgrade_object->dependencies as $dependent_version => $version_dependencies) {
+ if (!$version_dependencies) {
+ // module is independent -> skip
+ continue;
+ }
+
+ list ($parent_name, $parent_version) = each($version_dependencies);
+
+ if (!array_key_exists($parent_name, $dependencies)) {
+ // parent module
+ $dependencies[$parent_name] = Array ();
+ }
+
+ if (!array_key_exists($parent_version, $dependencies[$parent_name])) {
+ // parent module versions, that are required by other module versions
+ $dependencies[$parent_name][$parent_version] = Array ();
+ }
+
+ $dependencies[$parent_name][$parent_version][] = Array ($module_info['Name'] => $dependent_version);
+ }
+ }
+
+ return $dependencies;
+ }
+
/**
+ * Returns database queries, that should be executed to perform upgrade from given to lastest version of given module path
+ *
+ * @param string $module_path
+ * @param string $from_version
+ * @return string
+ */
+ function &getUpgradeQueriesFromVersion($module_path, $from_version)
+ {
+ $upgrades_file = sprintf(UPGRADES_FILE, $module_path, 'sql');
+
+ $sqls = file_get_contents($upgrades_file);
+ $version_mark = preg_replace('/(\(.*?\))/', $from_version, VERSION_MARK);
+
+ // get only sqls from next (relative to current) version to end of file
+ $start_pos = strpos($sqls, $version_mark);
+ $sqls = substr($sqls, $start_pos);
+
+ return $sqls;
+ }
+
+ function RunUpgrade($module_name, $to_version, &$upgrade_data, &$start_from_query = 0)
+ {
+ $module_info = $upgrade_data[ strtolower($module_name) ];
+
+ $sqls =& $this->getUpgradeQueriesFromVersion($module_info['Path'], $module_info['FromVersion']);
+ preg_match_all('/(' . VERSION_MARK . ')/s', $sqls, $matches, PREG_SET_ORDER + PREG_OFFSET_CAPTURE);
+
+ foreach ($matches as $index => $match) {
+ // upgrade version
+ $version = $match[2][0];
+
+ if ($this->toolkit->ConvertModuleVersion($version) > $this->toolkit->ConvertModuleVersion($to_version)) {
+ // only upgrade to $to_version, not further
+ break;
+ }
+
+ if (!in_array($module_name . ':' . $version, $this->upgradeLog)) {
+ if ($this->Application->isDebugMode()) {
+ $this->Application->Debugger->appendHTML('Upgrading "' . $module_name . '" to "' . $version . '" version: BEGIN.');
+ }
+
+ /*echo 'Upgrading "' . $module_name . '" to "' . $version . '".
' . "\n";
+ flush();*/
+
+ // don't upgrade same version twice
+ $start_pos = $match[0][1] + strlen($match[0][0]);
+ $end_pos = array_key_exists($index + 1, $matches) ? $matches[$index + 1][0][1] : mb_strlen($sqls);
+ $version_sqls = substr($sqls, $start_pos, $end_pos - $start_pos);
+
+ if ($start_from_query == 0) {
+ $this->RunUpgradeScript($module_info['Path'], $version, 'before');
+ }
+
+ if (!$this->toolkit->RunSQLText($version_sqls, null, null, $start_from_query)) {
+ $this->errorMessage .= '';
+ $this->errorMessage .= '
Module "' . $module_name . '" upgrade to "' . $version . '" failed.';
+ $this->errorMessage .= '
Click Continue button below to skip this query and go further
';
+
+ return false;
+ }
+ else {
+ // reset query counter, when all queries were processed
+ $start_from_query = 0;
+ }
+
+ $this->RunUpgradeScript($module_info['Path'], $version, 'after');
+
+ if ($this->Application->isDebugMode()) {
+ $this->Application->Debugger->appendHTML('Upgrading "' . $module_name . '" to "' . $version . '" version: END.');
+ }
+
+ // remember, that we've already upgraded given version
+ $this->upgradeLog[] = $module_name . ':' . $version;
+ }
+
+ if (array_key_exists($module_name, $this->upgradeDepencies) && array_key_exists($version, $this->upgradeDepencies[$module_name])) {
+ foreach ($this->upgradeDepencies[$module_name][$version] as $dependency_info) {
+ list ($dependent_module, $dependent_version) = each($dependency_info);
+
+ if (!$this->RunUpgrade($dependent_module, $dependent_version, $upgrade_data, $start_from_query)) {
+ return false;
+ }
+ }
+ }
+
+ // only mark module as updated, when all it's dependent modules are upgraded
+ $this->toolkit->SetModuleVersion($module_name, false, $version);
+ }
+
+ return true;
+ }
+
+ /**
* Run upgrade PHP scripts for module with specified path
*
* @param string $module_path
- * @param Array $versions
- * @param string $mode upgrade mode = {before,after}
+ * @param Array $version
+ * @param string $mode upgrade mode = {before,after,languagepack}
*/
- function RunUpgrades($module_path, $versions, $mode)
+ function RunUpgradeScript($module_path, $version, $mode)
{
- static $upgrade_classes = Array ();
+ $upgrade_object =& $this->getUpgradeObject($module_path);
- $upgrades_file = sprintf(UPGRADES_FILE, $module_path, 'php');
- if (!file_exists($upgrades_file) || !$versions) {
+ if (!is_object($upgrade_object)) {
return ;
}
+ $upgrade_method = 'Upgrade_' . str_replace(Array ('.', '-'), '_', $version);
+
+ if (method_exists($upgrade_object, $upgrade_method)) {
+ $upgrade_object->$upgrade_method($mode);
+ }
+ }
+
+ /**
+ * Returns upgrade class for given module path
+ *
+ * @param string $module_path
+ * @return kUpgradeHelper
+ */
+ function &getUpgradeObject($module_path)
+ {
+ static $upgrade_classes = Array ();
+ $upgrades_file = sprintf(UPGRADES_FILE, $module_path, 'php');
+
+ if (!file_exists($upgrades_file)) {
+ $false = false;
+ return $false;
+ }
+
if (!isset($upgrade_classes[$module_path])) {
- // save class name, because 2nd time
- // (in after call $upgrade_class variable will not be present)
+ require_once(FULL_PATH . REL_PATH . '/install/upgrade_helper.php');
+
+ // save class name, because 2nd time (in after call)
+ // $upgrade_class variable will not be present
include_once $upgrades_file;
$upgrade_classes[$module_path] = $upgrade_class;
}
$upgrade_object = new $upgrade_classes[$module_path]();
- if (method_exists($upgrade_object, 'setToolkit')) {
- $upgrade_object->setToolkit($this->toolkit);
- }
+ $upgrade_object->setToolkit($this->toolkit);
- foreach ($versions as $version) {
- $upgrade_method = 'Upgrade_'.str_replace(Array ('.', '-'), '_', $version);
- if (method_exists($upgrade_object, $upgrade_method)) {
- $upgrade_object->$upgrade_method($mode);
- }
- }
+ return $upgrade_object;
}
/**