Example #1
0
/**
 * 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 &quot;cache&quot; 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 />&nbsp;&nbsp;&nbsp;[<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 &quot;Install&quot; 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 />&nbsp;&nbsp;&nbsp;[<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 &quot;' . BOARDDIR . '&quot; but should probably be &quot;' . dirname(__FILE__) . '&quot;. 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;
}
Example #2
0
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;
}