/** * Step 0 * Let's welcome them in and ask them to login! * Preforms several checks to make sure the appropriate files are available to do the updates * Validates php and db versions meet the minimum requirements * Validates the credentials supplied have db alter privileges * Checks that needed files/directories are writable */ function action_welcomeLogin() { global $modSettings, $upgradeurl, $upcontext, $db_type, $databases, $txt, $db_character_set; $db = database(); $upcontext['sub_template'] = 'welcome_message'; // Check for some key files - one template, one language, and a new and an old source file. $check = @file_exists($modSettings['theme_dir'] . '/index.template.php') && @file_exists(SOURCEDIR . '/QueryString.php') && @file_exists(SOURCEDIR . '/database/Db-' . $db_type . '.class.php') && @file_exists(dirname(__FILE__) . '/upgrade_elk_1-0_' . $db_type . '.sql'); // Need scripts to migrate from SMF? if (isset($modSettings['smfVersion']) && $modSettings['smfVersion'] < 2.1) { $check &= @file_exists(dirname(__FILE__) . '/upgrade_2-0_' . $db_type . '.sql'); } if (isset($modSettings['smfVersion']) && $modSettings['smfVersion'] < 2.0) { $check &= @file_exists(dirname(__FILE__) . '/upgrade_1-1.sql'); } if (isset($modSettings['smfVersion']) && $modSettings['smfVersion'] < 1.1) { $check &= @file_exists(dirname(__FILE__) . '/upgrade_1-0.sql'); } // If the db is not UTF if (!isset($modSettings['elkVersion']) && ($db_type == 'mysql' || $db_type == 'mysqli') && (!isset($db_character_set) || $db_character_set !== 'utf8' || empty($modSettings['global_character_set']) || $modSettings['global_character_set'] !== 'UTF-8')) { return throw_error('The upgrader detected your database is not UTF-8. In order to be able to upgrade, please first convert your database to the UTF-8 charset.'); } // Don't tell them what files exactly because it's a spot check - // just like teachers don't tell which problems they are spot checking, that's dumb. if (!$check) { return throw_error('The upgrader was unable to find some crucial files.<br /><br />Please make sure you uploaded all of the files included in the package, including the themes, sources, and other directories.'); } // Do they meet the install requirements? if (version_compare(REQUIRED_PHP_VERSION, PHP_VERSION, '>=')) { return throw_error('Warning! You do not appear to have a version of PHP installed on your webserver that meets ElkArte\'s minimum installations requirements.<br /><br />Please ask your host to upgrade.'); } if (!db_version_check()) { return throw_error('Your ' . $databases[$db_type]['name'] . ' version does not meet the minimum requirements of ElkArte.<br /><br />Please ask your host to upgrade.'); } // Do they have ALTER privileges? if (!empty($databases[$db_type]['alter_support']) && $db->query('alter_boards', 'ALTER TABLE {db_prefix}boards ORDER BY id_board', array()) === false) { return throw_error('The ' . $databases[$db_type]['name'] . ' user you have set in Settings.php does not have proper privileges.<br /><br />Please ask your host to give this user the ALTER, CREATE, and DROP privileges.'); } // Do a quick version spot check. $temp = substr(@implode('', @file(BOARDDIR . '/index.php')), 0, 4096); preg_match('~\\*\\s@version\\s+(.+)[\\s]{2}~i', $temp, $match); if (empty($match[1]) || trim(str_replace('Release Candidate', 'RC', $match[1])) != CURRENT_VERSION) { return throw_error('The upgrader found some old or outdated files.<br /><br />Please make certain you uploaded the new versions of all the files included in the package.'); } // What absolutely needs to be writable? $writable_files = array(BOARDDIR . '/Settings.php', BOARDDIR . '/Settings_bak.php'); // Check the cache directory. $CACHEDIR_temp = !defined('CACHEDIR') ? BOARDDIR . '/cache' : CACHEDIR; if (!file_exists($CACHEDIR_temp)) { @mkdir($CACHEDIR_temp); } if (!file_exists($CACHEDIR_temp)) { return throw_error('The cache directory could not be found.<br /><br />Please make sure you have a directory called "cache" in your forum directory before continuing.'); } if (!file_exists($modSettings['theme_dir'] . '/languages/' . $upcontext['language'] . '/index.' . $upcontext['language'] . '.php') && !isset($modSettings['elkVersion']) && !isset($_GET['lang'])) { return throw_error('The upgrader was unable to find language files for the language specified in Settings.php.<br />ElkArte will not work without the primary language files installed.<br /><br />Please either install them, or <a href="' . $upgradeurl . '?step=0;lang=english">use english instead</a>.'); } elseif (!isset($_GET['skiplang'])) { $temp = substr(@implode('', @file($modSettings['theme_dir'] . '/languages/' . $upcontext['language'] . '/index.' . $upcontext['language'] . '.php')), 0, 4096); preg_match('~(?://|/\\*)\\s*Version:\\s+(.+?);\\s*index(?:[\\s]{2}|\\*/)~i', $temp, $match); if (empty($match[1]) || $match[1] != CURRENT_LANG_VERSION) { return throw_error('The upgrader found some old or outdated language files, for the forum default language, ' . $upcontext['language'] . '.<br /><br />Please make certain you uploaded the new versions of all the files included in the package, even the theme and language files for the default theme.<br /> [<a href="' . $upgradeurl . '?skiplang">SKIP</a>] [<a href="' . $upgradeurl . '?lang=english">Try English</a>]'); } } // This needs to exist! if (!file_exists($modSettings['theme_dir'] . '/languages/' . $upcontext['language'] . '/Install.' . $upcontext['language'] . '.php')) { return throw_error('The upgrader could not find the "Install" language file for the forum default language, ' . $upcontext['language'] . '.<br /><br />Please make certain you uploaded all the files included in the package, even the theme and language files for the default theme.<br /> [<a href="' . $upgradeurl . '?lang=english">Try English</a>]'); } else { require_once $modSettings['theme_dir'] . '/languages/' . $upcontext['language'] . '/Install.' . $upcontext['language'] . '.php'; } if (!makeFilesWritable($writable_files)) { return false; } // Check agreement.txt. (it may not exist, in which case BOARDDIR must be writable.) if (isset($modSettings['agreement']) && (!is_writable(BOARDDIR) || file_exists(BOARDDIR . '/agreement.txt')) && !is_writable(BOARDDIR . '/agreement.txt')) { return throw_error('The upgrader was unable to obtain write access to agreement.txt.<br /><br />If you are using a linux or unix based server, please ensure that the file is chmod\'d to 777, or if it does not exist that the directory this upgrader is in is 777.<br />If your server is running Windows, please ensure that the internet guest account has the proper permissions on it or its folder.'); } elseif (isset($modSettings['agreement'])) { $fp = fopen(BOARDDIR . '/agreement.txt', 'w'); fwrite($fp, $modSettings['agreement']); fclose($fp); } // We're going to check that their board dir setting is right in case they've been moving stuff around. if (strtr(BOARDDIR, array('/' => '', '\\' => '')) != strtr(dirname(__FILE__), array('/' => '', '\\' => ''))) { $upcontext['warning'] = ' It looks as if your board directory settings <em>might</em> be incorrect. Your board directory is currently set to "' . BOARDDIR . '" but should probably be "' . dirname(__FILE__) . '". Settings.php currently lists your paths as:<br /> <ul> <li>Board Directory: ' . BOARDDIR . '</li> <li>Source Directory: ' . BOARDDIR . '</li> <li>Cache Directory: ' . $CACHEDIR_temp . '</li> </ul> If these seem incorrect please open Settings.php in a text editor before proceeding with this upgrade. If they are incorrect due to you moving your forum to a new location please download and execute the <a href="https://github.com/emanuele45/tools/downloads">Repair Settings</a> tool from the ElkArte website before continuing.'; } // Either we're logged in or we're going to present the login. if (checkLogin()) { return true; } require_once SOURCEDIR . '/Security.php'; $upcontext += createToken('login'); return false; }
function CleanupMods() { global $db_prefix, $modSettings, $upcontext, $boarddir, $sourcedir, $settings, $smcFunc, $command_line; // Sorry. Not supported for command line users. if ($command_line) { return true; } // Skipping first? if (!empty($_POST['skip'])) { unset($_POST['skip']); return true; } // If we get here withOUT SSI we need to redirect to ensure we get it! if (!isset($_GET['ssi']) || !function_exists('mktree')) { redirectLocation('&ssi=1'); } $upcontext['sub_template'] = 'clean_mods'; $upcontext['page_title'] = 'Cleanup Modifications'; // This can be skipped. $upcontext['skip'] = true; // If we're on the second redirect continue... if (isset($_POST['cleandone2'])) { return true; } // Do we already know about some writable files? if (isset($_POST['writable_files'])) { $writable_files = unserialize(base64_decode($_POST['writable_files'])); if (!makeFilesWritable($writable_files)) { // What have we left? $upcontext['writable_files'] = $writable_files; return false; } } // Load all theme paths.... $request = $smcFunc['db_query']('', ' SELECT id_theme, variable, value FROM {db_prefix}themes WHERE id_member = {int:id_member} AND variable IN ({string:theme_dir}, {string:images_url})', array('id_member' => 0, 'theme_dir' => 'theme_dir', 'images_url' => 'images_url', 'db_error_skip' => true)); $theme_paths = array(); while ($row = $smcFunc['db_fetch_assoc']($request)) { if ($row['id_theme'] == 1) { $settings['default_' . $row['variable']] = $row['value']; } elseif ($row['variable'] == 'theme_dir') { $theme_paths[$row['id_theme']][$row['variable']] = $row['value']; } } $smcFunc['db_free_result']($request); // Are there are mods installed that may need uninstalling? $request = $smcFunc['db_query']('', ' SELECT id_install, filename, name, themes_installed, version FROM {db_prefix}log_packages WHERE install_state = {int:installed} ORDER BY time_installed DESC', array('installed' => 1, 'db_error_skip' => true)); $upcontext['packages'] = array(); while ($row = $smcFunc['db_fetch_assoc']($request)) { // Work out the status. if (!file_exists($boarddir . '/Packages/' . $row['filename'])) { $status = 'Missing'; $status_color = 'red'; $result = 'Removed'; } else { $status = 'Installed'; $status_color = 'green'; $result = 'No Action Needed'; } $upcontext['packages'][$row['id_install']] = array('id' => $row['id_install'], 'themes' => explode(',', $row['themes_installed']), 'name' => $row['name'], 'filename' => $row['filename'], 'missing_file' => file_exists($boarddir . '/Packages/' . $row['filename']) ? 0 : 1, 'files' => array(), 'file_count' => 0, 'status' => $status, 'result' => $result, 'color' => $status_color, 'version' => $row['version'], 'needs_removing' => false); } $smcFunc['db_free_result']($request); // Don't carry on if there are none. if (empty($upcontext['packages'])) { return true; } // Setup some basics. if (!empty($upcontext['user']['version'])) { $_SESSION['version_emulate'] = $upcontext['user']['version']; } // Before we get started, don't report notice errors. $oldErrorReporting = error_reporting(E_ALL ^ E_NOTICE); if (!mktree($boarddir . '/Packages/temp', 0755)) { deltree($boarddir . '/Packages/temp', false); if (!mktree($boarddir . '/Packages/temp', 0777)) { deltree($boarddir . '/Packages/temp', false); //!!! Error here - plus chmod! } } // Anything which reinstalled should not have its entry removed. $reinstall_worked = array(); // We're gonna be doing some removin' $test = isset($_POST['cleandone']) ? false : true; foreach ($upcontext['packages'] as $id => $package) { // Can't do anything about this.... if ($package['missing_file']) { continue; } // Not testing *and* this wasn't checked? if (!$test && (!isset($_POST['remove']) || !isset($_POST['remove'][$id]))) { continue; } // What are the themes this was installed into? $cur_theme_paths = array(); foreach ($theme_paths as $tid => $data) { if ($tid != 1 && in_array($tid, $package['themes'])) { $cur_theme_paths[$tid] = $data; } } // Get the modifications data if applicable. $filename = $package['filename']; $packageInfo = getPackageInfo($filename); if (!is_array($packageInfo)) { continue; } $info = parsePackageInfo($packageInfo['xml'], $test, 'uninstall'); // Also get the reinstall details... if (isset($_POST['remove'])) { $infoInstall = parsePackageInfo($packageInfo['xml'], true); } if (is_file($boarddir . '/Packages/' . $filename)) { read_tgz_file($boarddir . '/Packages/' . $filename, $boarddir . '/Packages/temp'); } else { copytree($boarddir . '/Packages/' . $filename, $boarddir . '/Packages/temp'); } // Work out how we uninstall... $files = array(); foreach ($info as $change) { // Work out two things: // 1) Whether it's installed at the moment - and if so whether its fully installed, and: // 2) Whether it could be installed on the new version. if ($change['type'] == 'modification') { $contents = @file_get_contents($boarddir . '/Packages/temp/' . $upcontext['base_path'] . $change['filename']); if ($change['boardmod']) { $results = parseBoardMod($contents, $test, $change['reverse'], $cur_theme_paths); } else { $results = parseModification($contents, $test, $change['reverse'], $cur_theme_paths); } foreach ($results as $action) { // Something we can remove? Probably means it existed! if (($action['type'] == 'replace' || $action['type'] == 'append' || !empty($action['filename']) && $action['type'] == 'failure') && !in_array($action['filename'], $files)) { $files[] = $action['filename']; } if ($action['type'] == 'failure') { $upcontext['packages'][$id]['needs_removing'] = true; $upcontext['packages'][$id]['status'] = 'Reinstall Required'; $upcontext['packages'][$id]['color'] = '#FD6435'; } } } } // Store this info for the template as appropriate. $upcontext['packages'][$id]['files'] = $files; $upcontext['packages'][$id]['file_count'] = count($files); // If we've done something save the changes! if (!$test) { package_flush_cache(); } // Are we attempting to reinstall this thing? if (isset($_POST['remove']) && !$test && isset($infoInstall)) { // Need to extract again I'm afraid. if (is_file($boarddir . '/Packages/' . $filename)) { read_tgz_file($boarddir . '/Packages/' . $filename, $boarddir . '/Packages/temp'); } else { copytree($boarddir . '/Packages/' . $filename, $boarddir . '/Packages/temp'); } $errors = false; $upcontext['packages'][$id]['result'] = 'Removed'; foreach ($infoInstall as $change) { if ($change['type'] == 'modification') { $contents = @file_get_contents($boarddir . '/Packages/temp/' . $upcontext['base_path'] . $change['filename']); if ($change['boardmod']) { $results = parseBoardMod($contents, true, $change['reverse'], $cur_theme_paths); } else { $results = parseModification($contents, true, $change['reverse'], $cur_theme_paths); } // Are there any errors? foreach ($results as $action) { if ($action['type'] == 'failure') { $errors = true; } } } } if (!$errors) { $reinstall_worked[] = $id; $upcontext['packages'][$id]['result'] = 'Reinstalled'; $upcontext['packages'][$id]['color'] = 'green'; foreach ($infoInstall as $change) { if ($change['type'] == 'modification') { $contents = @file_get_contents($boarddir . '/Packages/temp/' . $upcontext['base_path'] . $change['filename']); if ($change['boardmod']) { $results = parseBoardMod($contents, false, $change['reverse'], $cur_theme_paths); } else { $results = parseModification($contents, false, $change['reverse'], $cur_theme_paths); } } } // Save the changes. package_flush_cache(); } } } // Put errors back on a sec. error_reporting($oldErrorReporting); // Check everything is writable. if ($test && !empty($upcontext['packages'])) { $writable_files = array(); foreach ($upcontext['packages'] as $package) { if (!empty($package['files'])) { foreach ($package['files'] as $file) { $writable_files[] = $file; } } } if (!empty($writable_files)) { $writable_files = array_unique($writable_files); $upcontext['writable_files'] = $writable_files; if (!makeFilesWritable($writable_files)) { return false; } } } if (file_exists($boarddir . '/Packages/temp')) { deltree($boarddir . '/Packages/temp'); } // Removing/Reinstalling any packages? if (isset($_POST['remove'])) { $deletes = array(); foreach ($_POST['remove'] as $id => $dummy) { if (!in_array((int) $id, $reinstall_worked)) { $deletes[] = (int) $id; } } if (!empty($deletes)) { upgrade_query(' UPDATE ' . $db_prefix . 'log_packages SET install_state = 0 WHERE id_install IN (' . implode(',', $deletes) . ')'); } // Ensure we don't lose our changes! package_put_contents($boarddir . '/Packages/installed.list', time()); $upcontext['sub_template'] = 'cleanup_done'; return false; } else { $allgood = true; // Is there actually anything that needs our attention? foreach ($upcontext['packages'] as $package) { if ($package['color'] != 'green') { $allgood = false; } } if ($allgood) { return true; } } $_GET['substep'] = 0; return isset($_POST['cleandone']) ? true : false; }