Index: branches/RC/core/install.php =================================================================== diff -u -N -r10509 -r10832 --- branches/RC/core/install.php (.../install.php) (revision 10509) +++ branches/RC/core/install.php (.../install.php) (revision 10832) @@ -7,20 +7,7 @@ define('FULL_PATH', realpath(dirname(__FILE__).'/..') ); define('REL_PATH', '/core'); - /** - * Upgrade sqls are located using this mask - * - */ - define('UPGRADES_FILE', FULL_PATH.'/%sinstall/upgrades.%s'); - - /** - * Format of version identificator in upgrade files - * - */ - define('VERSION_MARK', '# ===== v ([\d]+\.[\d]+\.[\d]+) ====='); - -// print_pre($_POST); - + // run installator $install_engine = new kInstallator(); $install_engine->Init(); $install_engine->Run(); @@ -43,26 +30,13 @@ var $Conn = null; /** - * Path to config.php - * - * @var string - */ - var $INIFile = ''; - - /** * XML file containing steps information * * @var string */ var $StepDBFile = ''; /** - * Parsed data from config.php - * - * @var Array - */ - var $systemConfig = Array (); - /** * Step name, that currently being processed * * @var string @@ -81,36 +55,51 @@ * * @var Array */ - var $steps = Array( - 'fresh_install' => Array ('check_paths', 'db_config', 'root_password', 'choose_modules', 'finish'), - 'already_installed' => Array ('install_setup'), + var $steps = Array ( + 'fresh_install' => Array ('check_paths', 'db_config', 'select_license', 'download_license', 'select_domain', 'root_password', 'choose_modules', 'post_config', 'select_theme', 'finish'), + 'already_installed' => Array ('check_paths', 'install_setup'), - 'upgrade' => Array ('install_setup', 'upgrade_modules', /* ..., */ 'finish'), - 'db_reconfig' => Array ('install_setup',/* ..., */ 'finish'), - 'fix_paths' => Array ('install_setup',/* ..., */ 'finish'), - ); + 'upgrade' => Array ('check_paths', 'install_setup', 'upgrade_modules', 'finish'), + 'update_license' => Array ('check_paths', 'install_setup', 'select_license', 'download_license', 'select_domain', 'finish'), + 'db_reconfig' => Array ('check_paths', 'install_setup', 'db_reconfig', 'finish'), + 'fix_paths' => Array ('check_paths', 'install_setup', 'fix_paths', 'finish'), + ); - /** * Steps, that doesn't required admin to be logged-in to proceed * * @var Array */ - var $skipLoginSteps = Array ('root_password', 'choose_modules', 'finish', -1); + var $skipLoginSteps = Array ('check_paths', 'select_license', 'download_license', 'select_domain', 'root_password', 'choose_modules', 'post_config', 'select_theme', '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', 'db_reconfig' /*, 'install_setup'*/); // remove install_setup when application will work separately from install /** - * Folders that should be writeable to continue installation + * Folders that should be writeable to continue installation. $1 - main writeable folder from config.php ("/system" by default) * * @var Array */ - var $writeableFolders = Array ('/system'); + var $writeableFolders = Array ( + '$1', + '$1/images', + '$1/images/resized', + '$1/images/pending', + '$1/images/pending/resized', + '$1/images/emoticons', // for "In-Bulletin" + '$1/images/manufacturers', // for "In-Commerce" + '$1/images/manufacturers/resized', // for "In-Commerce" + '$1/backupdata', + '$1/export', + '$1/stylesheets', + '$1/user_files', + '$1/cache', + '/themes', + ); /** * Contains last error message text @@ -129,31 +118,44 @@ /** * Holds number of last executed query in the SQL * - * @var unknown_type + * @var int */ var $LastQueryNum = 0; + /** + * Common tools required for installation process + * + * @var kInstallToolkit + */ + var $toolkit = null; + function Init() { - $this->INIFile = FULL_PATH.'/config.php'; + // connect toolkit required for module installations to installator and via versa + require_once FULL_PATH . REL_PATH . '/install/install_toolkit.php'; + $this->toolkit = new kInstallToolkit(); + $this->toolkit->setInstallator(&$this); + $this->StepDBFile = FULL_PATH.'/'.REL_PATH.'/install/steps_db.xml'; $base_path = rtrim(preg_replace('/'.preg_quote(rtrim(REL_PATH, '/'), '/').'$/', '', str_replace('\\', '/', dirname($_SERVER['PHP_SELF']))), '/'); $this->baseURL = 'http://'.$_SERVER['HTTP_HOST'].$base_path.'/core/install/'; set_error_handler( Array(&$this, 'ErrorHandler') ); - if (file_exists($this->INIFile)) { + if (file_exists($this->toolkit->INIFile)) { // if config.php found, then check his write permission too $this->writeableFolders[] = '/config.php'; } else { $this->writeableFolders[] = '/'; } - $this->systemConfig = $this->ParseConfig(true); - $this->systemConfig['Misc']['WriteablePath'] = '/system'; // for development purposes - $this->systemConfig['Misc']['Domain'] = $_SERVER['HTTP_HOST']; // for redirects from SSL mode + if (!$this->toolkit->getSystemConfig('Misc', 'WriteablePath')) { + // set global writable folder when such setting is missing + $this->toolkit->setSystemConfig('Misc', 'WriteablePath', '/system'); + } + $this->currentStep = $this->GetVar('step'); // can't check login on steps where no application present anyways :) @@ -181,12 +183,12 @@ function SelectPreset() { $preset = $this->GetVar('preset'); - if (file_exists($this->INIFile) && $this->systemConfig) { + if ($this->toolkit->systemConfigFound()) { // only at installation first step $status = $this->CheckDatabase(false); if ($status && $this->AlreadyInstalled()) { // if already installed, then all future actions need login to work - $this->skipLoginSteps = Array (-1); + $this->skipLoginSteps = Array ('check_paths', -1); if (!$preset) { $preset = 'already_installed'; $this->currentStep = ''; @@ -202,9 +204,14 @@ function GetVar($name) { - return isset($_REQUEST[$name]) ? $_REQUEST[$name] : false; + return array_key_exists($name, $_REQUEST) ? $_REQUEST[$name] : false; } + function SetVar($name, $value) + { + $_REQUEST[$name] = $value; + } + /** * Performs needed intialization of data, that step requires * @@ -218,42 +225,51 @@ // step require login to proceed if (!$this->Application->LoggedIn()) { $this->stepsPreset = 'already_installed'; - $this->SetFirstStep(); + $this->currentStep = 'install_setup'; // manually set 2nd step, because 'check_paths' step doesn't contain login form +// $this->SetFirstStep(); } } switch ($this->currentStep) { case 'check_paths': + $writeable_base = $this->toolkit->getSystemConfig('Misc', 'WriteablePath'); foreach ($this->writeableFolders as $folder_path) { - $file_path = FULL_PATH.$folder_path; - if (!is_writable($file_path)) { + $file_path = FULL_PATH . str_replace('$1', $writeable_base, $folder_path); + if (file_exists($file_path) && !is_writable($file_path)) { $this->errorMessage = 'Install cannot write to specified folder in the root directory of your installation'; break; } } break; case 'db_config': - $section_name = 'Database'; - $fields = Array ('DBType', 'DBHost', 'DBName', 'DBUser', 'DBUserPassword', 'DBCollation', 'TablePrefix'); + case 'db_reconfig': + $fields = Array ( + 'DBType', 'DBHost', 'DBName', 'DBUser', + 'DBUserPassword', 'DBCollation', 'TablePrefix' + ); - if (!isset($this->systemConfig[$section_name])) { - $this->systemConfig[$section_name] = Array (); - } - // set fields foreach ($fields as $field_name) { $submit_value = $this->GetVar($field_name); if ($submit_value !== false) { - $this->systemConfig[$section_name][$field_name] = $submit_value; + $this->toolkit->setSystemConfig('Database', $field_name, $submit_value); } - elseif (!isset($this->systemConfig[$section_name][$field_name])) { - $this->systemConfig[$section_name][$field_name] = ''; - } + /*else { + $this->toolkit->setSystemConfig('Database', $field_name, ''); + }*/ } break; + case 'download_license': + $license_source = $this->GetVar('license_source'); + if ($license_source !== false && $license_source != 1) { + // previous step was "Select License" and not "Download from Intechnic" option was selected + $this->currentStep = $this->GetNextStep(); + } + break; + case 'choose_modules': // if no modules found, then proceed to next step $modules = $this->ScanModules(); @@ -262,6 +278,18 @@ } break; + case 'select_theme': + if (count($this->toolkit->getThemes(true)) == 1) { + // only one theme -> set it as primary + $sql = 'UPDATE ' . $this->Application->getUnitOption('theme', 'TableName') . 'Theme + SET Enabled = 1, PrimaryTheme = 1 + LIMIT 1'; + $this->Conn->Query($sql); + + $this->currentStep = $this->GetNextStep(); + } + break; + case 'upgrade_modules': // get installed modules from db and compare their versions to upgrade script $modules = $this->GetUpgradableModules(); @@ -272,28 +300,55 @@ 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 ($next_preset !== false) { + if ($this->Application->GetVar('login') == 'root') { + // verify "root" user using configuration settings + $login_event = new kEvent('u.current:OnLogin'); + $this->Application->HandleEvent($login_event); - if ($login_event->status == erSUCCESS) { - // login succeeded + if ($login_event->status != erSUCCESS) { + $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 { + // non "root" user -> verify using licensing server + $url_params = Array ( + 'login=' . md5( $this->GetVar('login') ), + 'password=' . md5( $this->GetVar('password') ), + 'action=check', + 'license_code=' . base64_encode( $this->toolkit->getSystemConfig('Intechnic', 'LicenseCode') ), + 'version=' . '4.3.0',//$this->toolkit->GetMaxModuleVersion('In-Portal'), + 'domain=' . base64_encode($_SERVER['HTTP_HOST']), + ); + + $license_url = GET_LICENSE_URL . '?' . implode('&', $url_params); + $file_data = curl_post($license_url, '', null, 'GET'); + + if (substr($file_data, 0, 5) == 'Error') { + $this->errorMessage = substr($file_data, 6) . ' If you don\'t know your username or password, contact Intechnic Support'; + } + + if ($this->errorMessage == '') { + $user_id = -1; + $session =& $this->Application->recallObject('Session'); + $session->SetField('PortalUserId', $user_id); + $this->Application->SetVar('u.current_id', $user_id); + $this->Application->StoreVar('user_id', $user_id); + } + } + + if ($this->errorMessage == '') { + // processed with redirect to selected step preset if (!isset($this->steps[$next_preset])) { $this->errorMessage = 'Preset "'.$next_preset.'" not yet implemented'; } else { $this->stepsPreset = $next_preset; } } - else { - // 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 @@ -321,11 +376,12 @@ switch ($this->currentStep) { case 'db_config': + case 'db_reconfig': // 1. check if required fields are filled $section_name = 'Database'; $required_fields = Array ('DBType', 'DBHost', 'DBName', 'DBUser', 'DBCollation'); foreach ($required_fields as $required_field) { - if (!$this->systemConfig[$section_name][$required_field]) { + if (!$this->toolkit->getSystemConfig($section_name, $required_field)) { $status = false; $this->errorMessage = 'Please fill all required fields'; break; @@ -334,9 +390,21 @@ if (!$status) break; // 2. check permissions, that use have in this database - $status = $this->CheckDatabase(); + $status = $this->CheckDatabase(($this->currentStep == 'db_config') && !$this->GetVar('UseExistingSetup')); break; + case 'select_license': + if ($this->GetVar('license_source') == 2) { + // license from file -> file must be uploaded + $upload_error = $_FILES['license_file']['error']; + if ($upload_error != UPLOAD_ERR_OK) { + $this->errorMessage = 'Missing License File'; + } + + $status = $this->errorMessage == ''; + } + break; + case 'root_password': // check, that password & verify password match $password = $this->Application->GetVar('root_password'); @@ -351,6 +419,23 @@ $status = $this->errorMessage == ''; break; + + case 'choose_modules': + case 'upgrade_modules': + $modules = $this->Application->GetVar('modules'); + if (!$modules) { + $this->errorMessage = 'Please select module(-s) to ' . ($this->currentStep == 'choose_modules' ? 'install' : 'upgrade'); + } + + $found['In-Portal'] = in_array('kernel', $modules); + $found['Proj-Base'] = in_array('proj-base', $modules); + + if (!$found['In-Portal'] && !$found['Proj-Base']) { + $this->errorMessage = 'Please ' . ($modules ? 'also ' : '') . 'select "' . implode('" or "', array_keys($found)) . '" as interface module'; + } + + $status = $this->errorMessage == ''; + break; } return $status; @@ -369,44 +454,216 @@ switch ($this->currentStep) { case 'db_config': + case 'db_reconfig': // store db configuration $sql = 'SHOW COLLATION - LIKE \''.$this->systemConfig['Database']['DBCollation'].'\''; + LIKE \''.$this->toolkit->getSystemConfig('Database', 'DBCollation').'\''; $collation_info = $this->Conn->Query($sql); if ($collation_info) { - $this->systemConfig['Database']['DBCharset'] = $collation_info[0]['Charset']; + $this->toolkit->setSystemConfig('Database', 'DBCharset', $collation_info[0]['Charset']); // database is already connected, that's why set collation on the fly - $this->Conn->Query('SET NAMES \''.$this->systemConfig['Database']['DBCharset'].'\' COLLATE \''.$this->systemConfig['Database']['DBCollation'].'\''); + $this->Conn->Query('SET NAMES \''.$this->toolkit->getSystemConfig('Database', 'DBCharset').'\' COLLATE \''.$this->toolkit->getSystemConfig('Database', 'DBCollation').'\''); } - $this->SaveConfig(); + $this->toolkit->SaveConfig(); - // import base data into database - $this->RunSQL('/core/install/install_schema.sql'); - $this->RunSQL('/core/install/install_data.sql'); + if ($this->currentStep == 'db_config') { + if ($this->GetVar('UseExistingSetup')) { + // abort clean install and redirect to already_installed + $this->stepsPreset = 'already_installed'; + break; + } - // set module "Core" version after install (based on upgrade scripts) - $this->SetModuleVersion('Core'); + // import base data into new database, not for db_reconfig + $this->toolkit->RunSQL('/core/install/install_schema.sql'); + $this->toolkit->RunSQL('/core/install/install_data.sql'); + + // set module "Core" version after install (based on upgrade scripts) + $this->toolkit->SetModuleVersion('Core'); + } break; + case 'select_license': + $license_source = $this->GetVar('license_source'); + switch ($license_source) { + case 1: // Download from Intechnic + + break; + + case 2: // Upload License File + $file_data = array_map('trim', file($_FILES['license_file']['tmp_name'])); + if ((count($file_data) == 3) && $file_data[1]) { + $modules_helper =& $this->Application->recallObject('ModulesHelper'); + /* @var $modules_helper kModulesHelper */ + + if ($modules_helper->verifyLicense($file_data[1])) { + $this->toolkit->setSystemConfig('Intechnic', 'License', $file_data[1]); + $this->toolkit->setSystemConfig('Intechnic', 'LicenseCode', $file_data[2]); + $this->toolkit->SaveConfig(); + } + else { + $this->errorMessage = 'Invalid License File'; + } + } + else { + $this->errorMessage = 'Invalid License File'; + } + break; + + case 3: // Use Existing License + $license_hash = $this->toolkit->getSystemConfig('Intechnic', 'License'); + if ($license_hash) { + $modules_helper =& $this->Application->recallObject('ModulesHelper'); + /* @var $modules_helper kModulesHelper */ + + if (!$modules_helper->verifyLicense($license_hash)) { + $this->errorMessage = 'Invalid or corrupt license detected'; + } + } + else { + // happens, when browser's "Back" button is used + $this->errorMessage = 'Missing License File'; + } + break; + + case 4: // Skip License (Local Domain Installation) + if ($this->toolkit->sectionFound('Intechnic')) { + // remove any previous license information + $this->toolkit->setSystemConfig('Intechnic', 'License'); + $this->toolkit->setSystemConfig('Intechnic', 'LicenseCode'); + $this->toolkit->SaveConfig(); + } + break; + } + break; + + case 'download_license': + $license_login = $this->GetVar('login'); + $license_password = $this->GetVar('password'); + $license_id = $this->GetVar('licenses'); + + if (strlen($license_login) && strlen($license_password) && !$license_id) { + // Here we determine weather login is ok & check available licenses + $url_params = Array ( + 'login=' . md5($license_login), + 'password=' . md5($license_password), + 'version=' . $this->toolkit->GetMaxModuleVersion('In-Portal'), + 'domain=' . base64_encode($_SERVER['HTTP_HOST']), + ); + + $license_url = GET_LICENSE_URL . '?' . implode('&', $url_params); + $file_data = curl_post($license_url, '', null, 'GET'); + if (!$file_data) { + // error connecting to licensing server + $this->errorMessage = 'Unable to connect to the Intechnic server! Please try again later!'; + } + else { + if (substr($file_data, 0, 5) == 'Error') { + // after processing data server returned error + $this->errorMessage = substr($file_data, 6); + } + else { + // license received + if (substr($file_data, 0, 3) == 'SEL') { + // we have more, then one license -> let user choose + $this->SetVar('license_selection', base64_encode( substr($file_data, 4) )); // we received html with radio buttons with names "licenses" + $this->errorMessage = 'Please select which license to use'; + } + else { + // we have one license + $this->toolkit->processLicense($file_data); + } + } + } + } + else if (!$license_id) { + // licenses were not queried AND user/password missing + $this->errorMessage = 'Incorrect Username or Password. If you don\'t know your username or password, contact Intechnic Support'; + } + else { + // Here we download license + $url_params = Array ( + 'license_id=' . md5($license_id), + 'dlog=' . md5($license_login), + 'dpass=' . md5($license_password), + 'version=' . $this->toolkit->GetMaxModuleVersion('In-Portal'), + 'domain=' . base64_encode($_SERVER['HTTP_HOST']), + ); + + $license_url = GET_LICENSE_URL . '?' . implode('&', $url_params); + $file_data = curl_post($license_url, '', null, 'GET'); + + if (!$file_data) { + // error connecting to licensing server + $this->errorMessage = 'Unable to connect to the Intechnic server! Please try again later!'; + } + else { + if (substr($file_data, 0, 5) == 'Error') { + // after processing data server returned error + $this->errorMessage = substr($file_data, 6); + } + else { + $this->toolkit->processLicense($file_data); + } + } + } + break; + + case 'select_domain': + $modules_helper =& $this->Application->recallObject('ModulesHelper'); + /* @var $modules_helper kModulesHelper */ + + $license_hash = $this->toolkit->getSystemConfig('Intechnic', 'License'); + if ($license_hash) { + // when license present, then extract domain from it + $license_hash = base64_decode($license_hash); + list ( , , $license_keys) = $modules_helper->_ParseLicense($license_hash); + $license_domain = $license_keys[0]['domain']; + } + else { + // when license missing, then use current domain + $license_domain = $_SERVER['HTTP_HOST']; + } + + $domain = $this->GetVar('domain') == 1 ? $_SERVER['HTTP_HOST'] : str_replace(' ', '', $this->GetVar('other')); + + if ($domain != '') { + if (strstr($domain, $license_domain) || $modules_helper->_IsLocalSite($domain)) { + $this->toolkit->setSystemConfig('Intechnic', 'Domain', $domain); + $this->toolkit->SaveConfig(); + } + else { + $this->errorMessage = 'Domain name entered does not match domain name in the license!'; + } + } + else { + $this->errorMessage = 'Please enter valid domain!'; + } + break; + case 'root_password': // update root password in database $password = md5( md5($this->Application->GetVar('root_password')) . 'b38'); - $this->SetConfigValue('RootPass', $password); - // set Site_Path (for SSL & old in-portal code) - $this->SetConfigValue('Site_Path', BASE_PATH.'/'); + $config_values = Array ( + 'RootPass' => $password, + 'Site_Path' => BASE_PATH.'/', // set Site_Path (for SSL & old in-portal code) + 'Backup_Path' => FULL_PATH . $this->toolkit->getSystemConfig('Misc', 'WriteablePath') . '/backupdata', + 'Smtp_AdminMailFrom' => 'portal@' . $this->toolkit->getSystemConfig('Intechnic', 'Domain') + ); + $this->toolkit->saveConfigValues($config_values); + // import base language for core (english) - $this->ImportLanguage('/core/install/english'); + $this->toolkit->ImportLanguage('/core/install/english'); // set imported language as primary $lang =& $this->Application->recallObject('lang.-item', null, Array('skip_autoload' => true)); /* @var $lang LanguagesItem */ $lang->Load(1); // fresh install => ID=1 - $lang->setPrimary(); + $lang->setPrimary(true); // for Front-End break; case 'choose_modules': @@ -419,22 +676,57 @@ include_once($install_file); // set module version after install (based on upgrade scripts) - $this->SetModuleVersion($module); + $this->toolkit->SetModuleVersion($module); } } } - // scan themes - $this->Application->HandleEvent($themes_event, 'adm:OnRebuildThemes'); - $this->Conn->Query('UPDATE '.TABLE_PREFIX.'Theme SET Enabled=1, PrimaryTheme =1 LIMIT 1'); - - // update categories cache + // update category cache $updater =& $this->Application->recallObject('kPermCacheUpdater'); /* @var $updater kPermCacheUpdater */ $updater->OneStepRun(); break; + case 'post_config': + $this->toolkit->saveConfigValues( $this->GetVar('config') ); + break; + + case 'select_theme': + // 1. mark theme, that user is selected + $theme_id = $this->GetVar('theme'); + $theme_table = $this->Application->getUnitOption('theme', 'TableName'); + $theme_idfield = $this->Application->getUnitOption('theme', 'IDField'); + + $sql = 'UPDATE ' . $theme_table . ' + SET Enabled = 1, PrimaryTheme = 1 + WHERE ' . $theme_idfield . ' = ' . $theme_id; + $this->Conn->Query($sql); + + if ($this->Application->isModuleEnabled('In-Portal')) { + // 2. compile theme stylesheets (only In-Portal uses them) + $css_table = $this->Application->getUnitOption('css', 'TableName'); + $css_idfield = $this->Application->getUnitOption('css', 'IDField'); + + $sql = 'SELECT LOWER(Name) AS Name, ' . $css_idfield . ' + FROM ' . $css_table; + $css_hash = $this->Conn->GetCol($sql, $css_idfield); + + $css_item =& $this->Application->recallObject('css', null, Array('skip_autoload' => true)); + /* @var $css_item StyleshetsItem */ + + foreach ($css_hash as $stylesheet_id => $theme_name) { + $css_item->Load($stylesheet_id); + $css_item->Compile(); + + $sql = 'UPDATE ' . $theme_table . ' + SET StylesheetId = ' . $stylesheet_id . ' + WHERE LOWER(Name) = ' . $this->Conn->qstr($theme_name); + $this->Conn->Query($sql); + } + } + break; + case 'upgrade_modules': // get installed modules from db and compare their versions to upgrade script $modules = $this->Application->GetVar('modules'); @@ -466,7 +758,7 @@ if (!$start_from_module) { $this->RunUpgrades($module_info['Path'], $regs[1], 'before'); } - if (!$this->RunSQLText($sqls, null, null, $start_from_query)) { + 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
'; @@ -475,20 +767,20 @@ $start_from_query = 0; // so that next module start from the beggining $this->RunUpgrades($module_info['Path'], $regs[1], 'after'); - // after upgrade sqls are executed update version - $this->SetModuleVersion($module_name, $module_info['ToVersion']); + // after upgrade sqls are executed update version and upgrade language pack + $this->toolkit->SetModuleVersion($module_name, $module_info['ToVersion']); + $this->toolkit->ImportLanguage('/' . $module_info['Path'] . 'install/english', true); } } - else { - $this->errorMessage = 'Please select module(-s) to upgrade'; - } break; + case 'fix_paths': + $this->toolkit->saveConfigValues( $this->Application->GetVar('config') ); + break; + case 'finish': // delete cache - $sql = 'DELETE FROM '.TABLE_PREFIX.'Cache - WHERE VarName IN ("config_files","configs_parsed","sections_parsed")'; - $this->Conn->Query($sql); + $this->toolkit->deleteCache(); // set installation finished mark if ($this->Application->ConfigValue('InstallFinished') === false) { @@ -541,8 +833,8 @@ } $upgrade_object = new $upgrade_classes[$module_path](); - if (method_exists($upgrade_object, 'setInstallator')) { - $upgrade_object->setInstallator($this); + if (method_exists($upgrade_object, 'setToolkit')) { + $upgrade_object->setToolkit(&$this->toolkit); } foreach ($versions as $version) { @@ -554,41 +846,6 @@ } /** - * Sets module version to passed - * - * @param string $module_name - * @param string $version - */ - function SetModuleVersion($module_name, $version = false) - { - if ($version === false) { - $version = $this->GetMaxModuleVersion($module_name); - } - - $table_prefix = $this->systemConfig['Database']['TablePrefix']; - - $sql = 'UPDATE '.$table_prefix.'Modules - SET Version = "'.$version.'" - WHERE Name = "'.$module_name.'"'; - $this->Conn->Query($sql); - } - - - /** - * Sets new configuration variable value - * - * @param string $name - * @param mixed $value - */ - function SetConfigValue($name, $value) - { - $sql = 'UPDATE '.TABLE_PREFIX.'ConfigurationValues - SET VariableValue = '.$this->Conn->qstr($value).' - WHERE VariableName = '.$this->Conn->qstr($name); - $this->Conn->Query($sql); - } - - /** * Initialize kApplication * * @param bool $force initialize in any case @@ -601,8 +858,12 @@ include_once(FULL_PATH.'/core/kernel/startup.php'); $this->Application =& kApplication::Instance(); + $this->toolkit->Application =& kApplication::Instance(); + $this->Application->Init(); + $this->Conn =& $this->Application->GetADODBConnection(); + $this->toolkit->Conn =& $this->Application->GetADODBConnection(); } } @@ -620,44 +881,34 @@ if (isset($this->Application)) { $this->Application->Done(); - -// echo 'SID: ['.$this->Application->GetSID().']
'; } exit; } - function GetMaxModuleVersion($module_name) + function ConnectToDatabase() { - $upgrades_file = sprintf(UPGRADES_FILE, mb_strtolower($module_name).'/', 'sql'); - if (!file_exists($upgrades_file)) { - // no upgrade file - return '4.0.1'; - } + include_once FULL_PATH . '/core/kernel/db/db_connection.php'; - $sqls = file_get_contents($upgrades_file); - $versions_found = preg_match_all('/'.VERSION_MARK.'/s', $sqls, $regs); - if (!$versions_found) { - // upgrades file doesn't contain version definitions - return '4.0.1'; + $required_keys = Array ('DBType', 'DBUser', 'DBName'); + foreach ($required_keys as $required_key) { + if (!$this->toolkit->getSystemConfig('Database', $required_key)) { + // one of required db connection settings missing -> abort connection + return false; + } } - return end($regs[1]); - } + $this->Conn = new kDBConnection($this->toolkit->getSystemConfig('Database', 'DBType'), Array(&$this, 'DBErrorHandler')); + $this->Conn->Connect( + $this->toolkit->getSystemConfig('Database', 'DBHost'), + $this->toolkit->getSystemConfig('Database', 'DBUser'), + $this->toolkit->getSystemConfig('Database', 'DBUserPassword'), + $this->toolkit->getSystemConfig('Database', 'DBName') + ); - function ConnectToDatabase() - { - include_once FULL_PATH.'/core/kernel/db/db_connection.php'; + // setup toolkit too + $this->toolkit->Conn =& $this->Conn; - if (!isset($this->systemConfig['Database']['DBType']) || - !isset($this->systemConfig['Database']['DBUser']) || - !isset($this->systemConfig['Database']['DBName']) - ) { - return false; - } - - $this->Conn = new kDBConnection($this->systemConfig['Database']['DBType'], Array(&$this, 'DBErrorHandler')); - $this->Conn->Connect($this->systemConfig['Database']['DBHost'], $this->systemConfig['Database']['DBUser'], $this->systemConfig['Database']['DBUserPassword'], $this->systemConfig['Database']['DBName']); return $this->Conn->errorCode == 0; } @@ -668,10 +919,10 @@ */ function AlreadyInstalled() { - $table_prefix = $this->systemConfig['Database']['TablePrefix']; + $table_prefix = $this->toolkit->getSystemConfig('Database', 'TablePrefix'); $sql = 'SELECT VariableValue - FROM '.$table_prefix.'ConfigurationValues + FROM ' . $table_prefix . 'ConfigurationValues WHERE VariableName = "InstallFinished"'; return $this->TableExists('ConfigurationValues') && $this->Conn->GetOne($sql); @@ -684,7 +935,7 @@ // 2. user has all types of permissions in database - if (mb_strlen($this->systemConfig['Database']['TablePrefix']) > 7) { + if (mb_strlen($this->toolkit->getSystemConfig('Database', 'TablePrefix')) > 7) { $this->errorMessage = 'Table prefix should not be longer than 7 characters'; return false; } @@ -721,7 +972,7 @@ } else { // user has insufficient permissions in database specified - $db_error = 'Permission Error: ('.$this->Conn->getErrorCode().') '.$this->Conn->getErrorMsg(); + $this->errorMessage = 'Permission Error: ('.$this->Conn->getErrorCode().') '.$this->Conn->getErrorMsg(); return false; } } @@ -743,7 +994,7 @@ */ function TableExists($tables) { - $prefix = $this->systemConfig['Database']['TablePrefix']; + $prefix = $this->toolkit->getSystemConfig('Database', 'TablePrefix'); $all_found = true; $tables = explode(',', $tables); @@ -759,86 +1010,6 @@ } /** - * 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); - if (!$this->RunSQLText($sqls, $replace_from, $replace_to)) { - $this->Done(); - } - } - - /** - * Runs SQLs from string - * - * @param string $sqls - * @param mixed $replace_from - * @param mixed $replace_to - */ - function RunSQLText(&$sqls, $replace_from = null, $replace_to = null, $start_from=0) - { - $table_prefix = $this->systemConfig['Database']['TablePrefix']; - - // add prefix to all tables - if (strlen($table_prefix) > 0) { - $replacements = Array ('CREATE TABLE ', 'INSERT INTO ', 'UPDATE ', 'ALTER TABLE ', 'DELETE FROM ', 'REPLACE INTO '); - foreach ($replacements as $replacement) { - $sqls = str_replace($replacement, $replacement.$table_prefix, $sqls); - } - $sqls = str_replace('DROP TABLE ', 'DROP TABLE IF EXISTS '.$table_prefix, $sqls); - } - - if (isset($replace_from) && isset($replace_to)) { - // 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 . "\n"); // ensures that last sql won't have ";" in it - - for ($i=$start_from; $isystemConfig['Database']['DBCollation']) { - // it is CREATE TABLE statement -> add collation - $sql .= ' COLLATE \''.$this->systemConfig['Database']['DBCollation'].'\''; - } - - $this->Conn->Query($sql); - if ($this->Conn->getErrorCode() != 0) { - $this->errorMessage = 'Error: ('.$this->Conn->getErrorCode().') '.$this->Conn->getErrorMsg().'

Database Query:
'.htmlspecialchars($sql).'
'; - $this->LastQueryNum = $i+1; - return false; - } - } - return true; - } - - function ImportLanguage($lang_file) - { - $lang_file = FULL_PATH.$lang_file.'.lang'; - if (!file_exists($lang_file)) { - return ; - } - - $lang_xml =& $this->Application->recallObjectP('LangXML', null, Array(), false); // false - don't use temp tables - $lang_xml->Parse($lang_file, '|0|1|2|', ''); - } - - /** * Returns modules list found in modules folder * * @return Array @@ -859,34 +1030,19 @@ } // this is folder in MODULES_PATH directory if (file_exists($folder_path.'/install.php') && file_exists($folder_path.'/install/install_schema.sql')) { - $modules[] = $sub_folder; + $install_order = trim( file_get_contents($folder_path . '/install/install_order.txt') ); + $modules[$install_order] = $sub_folder; } } } } + // allows to control module install order + ksort($modules, SORT_NUMERIC); return $modules; } /** - * 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 * */ @@ -909,11 +1065,11 @@ } $to_version = end($regs[1]); - $this_version = $this->ConvertModuleVersion($module_info['Version']); - if ($this->ConvertModuleVersion($to_version) > $this_version) { + $this_version = $this->toolkit->ConvertModuleVersion($module_info['Version']); + if ($this->toolkit->ConvertModuleVersion($to_version) > $this_version) { // destination version is greather then current foreach ($regs[1] as $version) { - if ($this->ConvertModuleVersion($version) > $this_version) { + if ($this->toolkit->ConvertModuleVersion($version) > $this_version) { $from_version = $version; break; } @@ -924,7 +1080,7 @@ 'ToVersion' => $to_version, ); - $ret[$module_name] = array_merge_recursive2($module_info, $version_info); + $ret[ strtolower($module_name) ] = array_merge_recursive2($module_info, $version_info); } } @@ -1091,80 +1247,6 @@ return $ret; } - function ParseConfig($parse_section = false) - { - if (!file_exists($this->INIFile)) { - return Array(); - } - - if( file_exists($this->INIFile) && !is_readable($this->INIFile) ) { - die('Could Not Open Ini File'); - } - - $contents = file($this->INIFile); - - $retval = Array(); - $section = ''; - $ln = 1; - $resave = false; - foreach ($contents as $line) { - if ($ln == 1 && $line != '<'.'?'.'php die() ?'.">\n") { - $resave = true; - } - - $ln++; - $line = trim($line); - $line = eregi_replace(';[.]*','',$line); - if (strlen($line) > 0) { - //echo $line . " - "; - if(eregi('^[[a-z]+]$',str_replace(' ', '', $line))) { - //echo 'section'; - $section = mb_substr($line, 1, (mb_strlen($line) - 2)); - if ($parse_section) { - $retval[$section] = array(); - } - continue; - } elseif (eregi('=',$line)) { - //echo 'main element'; - list ($key, $val) = explode(' = ', $line); - if (!$parse_section) { - $retval[trim($key)] = str_replace('"', '', $val); - } - else { - $retval[$section][trim($key)] = str_replace('"', '', $val); - } - } - } - } - - if ($resave) { - $fp = fopen($this->INIFile, 'w'); - reset($contents); - fwrite($fp,'<'.'?'.'php die() ?'.">\n\n"); - foreach ($contents as $line) { - fwrite($fp,"$line"); - } - fclose($fp); - } - - return $retval; - } - - function SaveConfig() - { - $fp = fopen($this->INIFile, 'w'); - fwrite($fp,'<'.'?'.'php die() ?'.">\n\n"); - - foreach ($this->systemConfig as $section_name => $section_data) { - fwrite($fp, '['.$section_name."]\n"); - foreach ($section_data as $key => $value) { - fwrite($fp, $key.' = "'.$value.'"'."\n"); - } - fwrite($fp, "\n"); - } - fclose($fp); - } - /** * Installation error handler for sql errors * @@ -1197,11 +1279,4 @@ } } } - - /*function print_pre($s) - { - echo '
', print_r($s, true). '
'; - }*/ - - ?> \ No newline at end of file