Index: branches/unlabeled/unlabeled-1.2.2/core/install/steps_db.xml =================================================================== diff -u -r6786 -r7525 --- branches/unlabeled/unlabeled-1.2.2/core/install/steps_db.xml (.../steps_db.xml) (revision 6786) +++ branches/unlabeled/unlabeled-1.2.2/core/install/steps_db.xml (.../steps_db.xml) (revision 7525) @@ -40,4 +40,7 @@ For example, if you moved them from one folder to another. It will update all settings and ensure the program is operational at the new location.

]]> + + + \ No newline at end of file Index: branches/unlabeled/unlabeled-1.1.2/core/install/incs/img/icon_warning.gif =================================================================== diff -u Binary files differ Index: branches/unlabeled/unlabeled-1.1.2/core/install/step_templates/install_setup.tpl =================================================================== diff -u -r6734 -r7525 --- branches/unlabeled/unlabeled-1.1.2/core/install/step_templates/install_setup.tpl (.../install_setup.tpl) (revision 6734) +++ branches/unlabeled/unlabeled-1.1.2/core/install/step_templates/install_setup.tpl (.../install_setup.tpl) (revision 7525) @@ -8,15 +8,15 @@ Username*: - + Password*: - + @@ -25,25 +25,30 @@ ?> - + 'Upgrade In-Portal', - 1 => 'Clean out the In-Portal database and reinstall', - 4 => 'Clean out the In-Portal database and reinstall from backup', - 2 => 'Install to a new database', - 3 => 'Update License Information', - 5 => 'Change Database Configuration', - 7 => 'Fix Paths', + 'upgrade' => 'Upgrade In-Portal', + 1 => 'Clean out the In-Portal database and reinstall', + 4 => 'Clean out the In-Portal database and reinstall from backup', + 2 => 'Install to a new database', + 3 => 'Update License Information', + 'db_reconfig' => 'Change Database Configuration', + 'fix_paths' => 'Fix Paths', ); + $upgradable_modules = $this->GetUpgradableModules(); + if (!$upgradable_modules) { + unset($options['upgrade']); + } + $td_class = 'table_color1'; foreach ($options as $option_key => $option_title) { - $checked = $this->GetVar('inp_opt') == $option_key ? ' checked' : ''; + $checked = $this->GetVar('next_preset') == $option_key ? ' checked' : ''; echo sprintf($option_tpl, $option_key, $checked, $option_title, $td_class); $td_class = ($td_class == 'table_color1') ? 'table_color2' : 'table_color1'; } Index: branches/unlabeled/unlabeled-1.6.2/core/install.php =================================================================== diff -u -r7471 -r7525 --- branches/unlabeled/unlabeled-1.6.2/core/install.php (.../install.php) (revision 7471) +++ branches/unlabeled/unlabeled-1.6.2/core/install.php (.../install.php) (revision 7525) @@ -7,6 +7,12 @@ define('FULL_PATH', realpath(dirname(__FILE__).'/..') ); define('REL_PATH', '/core'); + /** + * Upgrade sqls are located using this mask + * + */ + define('UPGRADES_FILE', FULL_PATH.'/%sinstall/upgrades.sql'); + // print_pre($_POST); $install_engine = new kInstallator(); @@ -73,20 +79,26 @@ 'fresh_install' => Array ('check_paths', 'db_config', 'root_password', 'choose_modules', 'finish'), 'already_installed' => Array ('install_setup'), - 'upgrade' => Array ('install_setup',/* ..., */ 'finish'), + 'upgrade' => Array ('install_setup', 'upgrade_modules', /* ..., */ 'finish'), 'db_reconfig' => Array ('install_setup',/* ..., */ 'finish'), 'fix_paths' => Array ('install_setup',/* ..., */ 'finish'), ); /** + * Steps, that doesn't required admin to be logged-in to proceed + * + * @var Array + */ + var $skipLoginSteps = Array ('root_password', 'choose_modules', 'finish', -1); + + /** * Steps, on which kApplication should not be initialized, because of missing correct db table structure * * @var Array */ + var $skipApplicationSteps = Array ('check_paths', 'db_config'/*, 'install_setup'*/); // remove install_setup when application will work separately from install - var $skipApplicationSteps = Array ('check_paths', 'db_config', 'install_setup'); // remove install_setup when application will work separately from install - /** * Folders that should be writeable to continue installation * @@ -131,17 +143,24 @@ $this->currentStep = $this->GetVar('step'); + // can't check login on steps where no application present anyways :) + $this->skipLoginSteps = array_unique(array_merge($this->skipLoginSteps, $this->skipApplicationSteps)); + $this->SelectPreset(); if (!$this->currentStep) { - // first step of current preset - reset($this->steps[$this->stepsPreset]); - $this->currentStep = current($this->steps[$this->stepsPreset]); + $this->SetFirstStep(); // sets first step of current preset } $this->InitStep(); } + function SetFirstStep() + { + reset($this->steps[$this->stepsPreset]); + $this->currentStep = current($this->steps[$this->stepsPreset]); + } + /** * Selects preset to proceed based on various criteria * @@ -153,8 +172,12 @@ // only at installation first step $status = $this->CheckDatabase(false); if ($status && $this->AlreadyInstalled()) { - $preset = 'already_installed'; - $this->currentStep = ''; + // if already installed, then all future actions need login to work + $this->skipLoginSteps = Array (-1); + if (!$preset) { + $preset = 'already_installed'; + $this->currentStep = ''; + } } } if ($preset === false) { @@ -163,7 +186,7 @@ $this->stepsPreset = $preset; } - + function GetVar($name) { return isset($_REQUEST[$name]) ? $_REQUEST[$name] : false; @@ -175,8 +198,17 @@ */ function InitStep() { - $this->InitApplication(); + $require_login = !in_array($this->currentStep, $this->skipLoginSteps); + $this->InitApplication($require_login); + if ($require_login) { + // step require login to proceed + if (!$this->Application->LoggedIn()) { + $this->stepsPreset = 'already_installed'; + $this->SetFirstStep(); + } + } + switch ($this->currentStep) { case 'check_paths': foreach ($this->writeableFolders as $folder_path) { @@ -217,30 +249,43 @@ } break; - case 'install_setup': - if ($this->stepsPreset == 'already_installed') { - // if preset was not choosen, then raise error - $this->errorMessage = 'Please select action to perform'; + case 'upgrade_modules': + // get installed modules from db and compare their versions to upgrade script + $modules = $this->GetUpgradableModules(); + if (!$modules) { + $this->currentStep = $this->GetNextStep(); } - else { - // if preset was choosen, then check root password entered - $user_name = $this->GetVar('user_name'); - $user_password = $this->GetVar('user_password'); - - if ($user_name == 'root') { - $sql = 'SELECT VariableValue - FROM '.$this->systemConfig['Database']['TablePrefix'].' - WHERE VariableName = "RootPass"'; - $root_password = $this->Conn->GetOne($sql); - $user_password = md5( md5($user_password) . 'b38'); - if ($user_password != $root_password) { - $this->errorMessage = 'Invalid User Name or Password. If you don\'t know your username or password, contact Intechnic Support'; + break; + + case 'install_setup': + $next_preset = $this->Application->GetVar('next_preset'); + if ($next_preset !== false && $this->Application->GetVar('login') == 'root') { + // option was choosen, then verify password & login user + $login_event = new kEvent('u.current:OnLogin'); + $this->Application->HandleEvent($login_event); + + if ($login_event->status == erSUCCESS) { + // login succeeded + + if (!isset($this->steps[$next_preset])) { + $this->errorMessage = 'Preset "'.$next_preset.'" not yet implemented'; } + else { + $this->stepsPreset = $next_preset; + } } else { - $this->errorMessage = 'By now only login using "root" username is supported'; + // login failed + $user =& $this->Application->recallObject('u.current'); + /* @var $user UsersItem */ + + $this->errorMessage = $user->GetErrorMsg('ValidateLogin').'. If you don\'t know your username or password, contact Intechnic Support'; } } + else { + // if preset was not choosen, then raise error + $this->errorMessage = 'Please select action to perform'; + } break; } @@ -341,13 +386,14 @@ case 'choose_modules': // run module install scripts $modules = $this->Application->GetVar('modules'); - foreach ($modules as $module) { - $install_file = MODULES_PATH.'/'.$module.'/install.php'; - if (file_exists($install_file)) { - include_once($install_file); + if ($modules) { + foreach ($modules as $module) { + $install_file = MODULES_PATH.'/'.$module.'/install.php'; + if (file_exists($install_file)) { + include_once($install_file); + } } } - // scan themes $themes_helper =& $this->Application->recallObject('ThemesHelper'); /* @var $themes_helper kThemesHelper */ @@ -362,8 +408,50 @@ $updater->OneStepRun(); break; + + 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(); + + foreach ($modules as $module_name) { + $module_info = $upgrade_data[$module_name]; + $upgrades_file = sprintf(UPGRADES_FILE, $module_info['Path']); + + $sqls = file_get_contents($upgrades_file); + $version_mark = '# ===== v '.$module_info['FromVersion'].' ====='; + + $start_pos = strpos($sqls, $version_mark); + $sqls = substr($sqls, $start_pos); + $this->RunSQLText($sqls); + + // after upgrade sqls are executed update version + $sql = 'UPDATE '.TABLE_PREFIX.'Modules + SET Version = "'.$module_info['ToVersion'].'" + WHERE Name = "'.$module_name.'"'; + $this->Conn->Query($sql); + } + } + else { + $this->errorMessage = 'Please select module(-s) to upgrade'; + } + break; + case 'finish': - $this->Conn->Query('INSERT INTO '.TABLE_PREFIX.'ConfigurationValues (VariableName, VariableValue) VALUE (\'InstallFinished\', 1)'); + // delete cache + $sql = 'DELETE FROM '.TABLE_PREFIX.'Cache + WHERE VarName IN ("config_files","configs_parsed","sections_parsed")'; + $this->Conn->Query($sql); + + // set installation finished mark + if ($this->Application->ConfigValue('InstallFinished') === false) { + $fields_hash = Array ( + 'VariableName' => 'InstallFinished', + 'VariableValue' => 1, + ); + $this->Conn->doInsert($fields_hash, TABLE_PREFIX.'ConfigurationValues'); + } break; } @@ -397,11 +485,16 @@ $this->Conn->Query($sql); } - function InitApplication() + /** + * Initialize kApplication + * + * @param bool $force initialize in any case + */ + function InitApplication($force = false) { - if (!in_array($this->currentStep, $this->skipApplicationSteps) && !isset($this->Application)) { + if (($force || !in_array($this->currentStep, $this->skipApplicationSteps)) && !isset($this->Application)) { // step is allowed for application usage & it was not initialized in previous step - global $debugger; + global $start, $debugger, $dbg_options; include_once(FULL_PATH.'/core/kernel/startup.php'); $this->Application =& kApplication::Instance(); @@ -425,7 +518,7 @@ if (isset($this->Application)) { $this->Application->Done(); - echo 'SID: ['.$this->Application->GetSID().']
'; +// echo 'SID: ['.$this->Application->GetSID().']
'; } exit; @@ -545,14 +638,32 @@ return $all_found; } + /** + * Runs SQLs from file + * + * @param string $filename + * @param mixed $replace_from + * @param mixed $replace_to + */ function RunSQL($filename, $replace_from = null, $replace_to = null) { if (!file_exists(FULL_PATH.$filename)) { return ; } $sqls = file_get_contents(FULL_PATH.$filename); + $this->RunSQLText($sqls, $replace_from, $replace_to); + } + /** + * Runs SQLs from string + * + * @param string $sqls + * @param mixed $replace_from + * @param mixed $replace_to + */ + function RunSQLText(&$sqls, $replace_from = null, $replace_to = null) + { $table_prefix = $this->systemConfig['Database']['TablePrefix']; // add prefix to all tables @@ -568,13 +679,15 @@ // replace something additionally, e.g. module root category $sqls = str_replace($replace_from, $replace_to, $sqls); } - + + $sqls = str_replace("\r\n", "\n", $sqls); // convert to linux line endings + $sqls = preg_replace("/#(.*?)\n/", '', $sqls); // remove all comments $sqls = explode(";\n", $sqls); foreach ($sqls as $sql) { $sql = trim($sql); - if (!$sql || substr($sql, 0, 1) == '#') { - continue; // usually last line || comment + if (!$sql) { + continue; // usually last line } $this->Conn->Query($sql); if ($this->Conn->getErrorCode() != 0) { @@ -584,7 +697,7 @@ } } } - + function ImportLanguage($lang_file) { $lang_file = FULL_PATH.$lang_file.'.lang'; @@ -627,6 +740,69 @@ } /** + * Converts module version in format X.Y.Z to signle integer + * + * @param string $version + * @return int + */ + function ConvertModuleVersion($version) + { + $parts = explode('.', $version); + + $bin = ''; + foreach ($parts as $part) { + $bin .= str_pad(decbin($part), 8, '0', STR_PAD_LEFT); + } + + return bindec($bin); + } + + /** + * Returns list of modules, that can be upgraded + * + */ + function GetUpgradableModules() + { + $ret = Array (); + + foreach ($this->Application->ModuleInfo as $module_name => $module_info) { + $upgrades_file = sprintf(UPGRADES_FILE, $module_info['Path']); + if (!file_exists($upgrades_file)) { + // no upgrade file + continue; + } + + $sqls = file_get_contents($upgrades_file); + $versions_found = preg_match_all('/# ===== v ([\d]+\.[\d]+\.[\d]+) =====/s', $sqls, $regs); + if (!$versions_found) { + // upgrades file doesn't contain version definitions + continue; + } + + $to_version = end($regs[1]); + $this_version = $this->ConvertModuleVersion($module_info['Version']); + if ($this->ConvertModuleVersion($to_version) > $this_version) { + // destination version is greather then current + foreach ($regs[1] as $version) { + if ($this->ConvertModuleVersion($version) > $this_version) { + $from_version = $version; + break; + } + } + + $version_info = Array ( + 'FromVersion' => $from_version, + 'ToVersion' => $to_version, + ); + + $ret[$module_name] = array_merge_recursive2($module_info, $version_info); + } + } + + return $ret; + } + + /** * Returns content to show for current step * * @return string Index: branches/unlabeled/unlabeled-1.2.2/core/install/incs/install.tpl =================================================================== diff -u -r6786 -r7525 --- branches/unlabeled/unlabeled-1.2.2/core/install/incs/install.tpl (.../install.tpl) (revision 6786) +++ branches/unlabeled/unlabeled-1.2.2/core/install/incs/install.tpl (.../install.tpl) (revision 7525) @@ -23,7 +23,7 @@   blocks - In-Portal Version GetModuleVersion('In-Portal'); ?>: English US + In-Portal Version GetModuleVersion('Core'); ?>: English US blocks2

Index: branches/unlabeled/unlabeled-1.1.2/core/install/upgrades.sql =================================================================== diff -u --- branches/unlabeled/unlabeled-1.1.2/core/install/upgrades.sql (revision 0) +++ branches/unlabeled/unlabeled-1.1.2/core/install/upgrades.sql (revision 7525) @@ -0,0 +1,13 @@ +# ===== v 3.0.10 ===== +SELECT * FROM Modules; +SELECT Name FROM Modules; + +# ===== v 4.0.1 ===== +ALTER TABLE Modules ADD COLUMN NotCool VARCHAR(255); + +# ===== v 4.0.12 ===== +# multiline +ALTER TABLE Modules ADD COLUMN SuperCool VARCHAR(255); + +# ===== v 4.0.15 ===== +UPDATE Modules SET Version = '4.0.5' WHERE Name = 'Core'; \ No newline at end of file Index: branches/unlabeled/unlabeled-1.1.2/core/install/step_templates/choose_modules.tpl =================================================================== diff -u -r6734 -r7525 --- branches/unlabeled/unlabeled-1.1.2/core/install/step_templates/choose_modules.tpl (.../choose_modules.tpl) (revision 6734) +++ branches/unlabeled/unlabeled-1.1.2/core/install/step_templates/choose_modules.tpl (.../choose_modules.tpl) (revision 7525) @@ -3,7 +3,12 @@ ?> - + + + + + +
+ + + + + + + +
+ + +GetUpgradableModules(); + foreach ($modules as $module_name => $module_params) { + $module_title = $module_name.' ('.$module_params['Version'].' to '.$module_params['ToVersion'].')'; + if ($this->Application->isDebugMode()) { + $module_title .= ' [from: '.$module_params['FromVersion'].']'; + } + echo sprintf($module_tpl, $module_name, $module_title); + } +?> + + + + Your data will be modified during the upgrade. We strongly recommend that you make a backup of your database. Proceed with the upgrade ? + + \ No newline at end of file Index: branches/unlabeled/unlabeled-1.6.2/core/units/general/helpers/modules.php =================================================================== diff -u -r7082 -r7525 --- branches/unlabeled/unlabeled-1.6.2/core/units/general/helpers/modules.php (.../modules.php) (revision 7082) +++ branches/unlabeled/unlabeled-1.6.2/core/units/general/helpers/modules.php (.../modules.php) (revision 7525) @@ -182,7 +182,7 @@ else { $modules = array_keys($this->Application->ModuleInfo); } - array_push($modules, 'Proj-base', 'Proj-CMS', 'Custom'); + array_push($modules, 'Core', 'Proj-base', 'Proj-CMS', 'Custom'); return $modules; }