diff options
author | cash <cash@36083f99-b078-4883-b0ff-0f9b5a30f544> | 2010-10-01 12:13:24 +0000 |
---|---|---|
committer | cash <cash@36083f99-b078-4883-b0ff-0f9b5a30f544> | 2010-10-01 12:13:24 +0000 |
commit | 6e0c8998901bcae422a41d630c8cb95441239f7b (patch) | |
tree | a46e9124d2c9ffad20a7d6d803c4406701b29c2a | |
parent | da9858182b8ae223428dd802f3eeb7624dcd3645 (diff) | |
download | elgg-6e0c8998901bcae422a41d630c8cb95441239f7b.tar.gz elgg-6e0c8998901bcae422a41d630c8cb95441239f7b.tar.bz2 |
Refs #2129 - integrates new installer code from http://github.com/cash/Elgg - does not work yet with non-Apache web servers
git-svn-id: http://code.elgg.org/elgg/trunk@6991 36083f99-b078-4883-b0ff-0f9b5a30f544
23 files changed, 2051 insertions, 208 deletions
diff --git a/engine/settings.example.php b/engine/settings.example.php index 4f47872cb..aa50be6bc 100644 --- a/engine/settings.example.php +++ b/engine/settings.example.php @@ -29,105 +29,24 @@ if (!isset($CONFIG)) { * to explain, but if you know you need it, skip past this section. */ -/** - * The database username - * - * @global string $CONFIG->dbuser - * @name $CONFIG->dbuser - */ -$CONFIG->dbuser = '{{CONFIG_DBUSER}}'; - -/** - * The database password - * - * @global string $CONFIG->dbpass - */ -$CONFIG->dbpass = '{{CONFIG_DBPASS}}'; - -/** - * The database name - * - * @global string $CONFIG->dbname - */ -$CONFIG->dbname = '{{CONFIG_DBNAME}}'; - -/** - * The database host. - * - * For most installations, this is 'localhost' - * - * @global string $CONFIG->dbhost - */ -$CONFIG->dbhost = '{{CONFIG_DBHOST}}'; - -/** - * The database prefix - * - * This prefix will be appended to all Elgg tables. If you're sharing - * a database with other applications, use a database prefix to namespace tables - * in order to avoid table name collisions. - * - * @global string $CONFIG->dbprefix - */ -$CONFIG->dbprefix = '{{CONFIG_DBPREFIX}}'; - -/** - * Multiple database connections - * - * Here you can set up multiple connections for reads and writes. To do this, uncomment out - * the lines below. - * - * @todo Does this work? - */ - -/* - -// Yes! We want to split reads and writes -$CONFIG->db->split = true; - -// READS -// Database username -$CONFIG->db['read']->dbuser = ""; - -// Database password -$CONFIG->db['read']->dbpass = ""; - -// Database name -$CONFIG->db['read']->dbname = ""; - -// Database server -// (For most configurations, you can leave this as 'localhost') -$CONFIG->db['read']->dbhost = "localhost"; - -// WRITES // Database username -$CONFIG->db['write']->dbuser = ""; +$CONFIG->dbuser = '{{dbuser}}'; // Database password -$CONFIG->db['write']->dbpass = ""; +$CONFIG->dbpass = '{{dbpassword}}'; // Database name -$CONFIG->db['write']->dbname = ""; +$CONFIG->dbname = '{{dbname}}'; // Database server // (For most configurations, you can leave this as 'localhost') -$CONFIG->db['write']->dbhost = "localhost"; +$CONFIG->dbhost = '{{dbhost}}'; - */ - -/* - * For extra connections for both reads and writes, you can turn both - * $CONFIG->db['read'] and $CONFIG->db['write'] into an array, eg: - * - * $CONFIG->db['read'][0]->dbhost = "localhost"; - * - * Note that the array keys must be numeric and consecutive, i.e., they start - * at 0, the next one must be at 1, etc. - */ +// Database table prefix +// If you're sharing a database with other applications, you will want to use this +// to differentiate Elgg's tables. +$CONFIG->dbprefix = '{{dbprefix}}'; -/* - * Optional configuration - */ /** * Memcache setup (optional) @@ -146,6 +65,7 @@ $CONFIG->db['write']->dbhost = "localhost"; // array('server2', 11211) //); + /** * Use non-standard headers for broken MTAs. * diff --git a/engine/start.php b/engine/start.php index d9ec01b87..db9bff0e4 100644 --- a/engine/start.php +++ b/engine/start.php @@ -11,19 +11,19 @@ * If Elgg is uninstalled, the browser will be redirected to an * installation page. * - * If in an installation, attempts to save the .htaccess and - * settings.php files during {@link sanitised()} - * - * @warning The view type is set to 'failsafe' during boot. This means calling - * {@link elgg_get_viewtype()} will return 'failsafe' in any function called by - * the events listed above regardless of actual view. The original view is restored - * after booting. - * * @see install.php * @package Elgg.Core * @subpackage Core */ +/* + * No settings means a fresh install + */ +if (!file_exists(dirname(__FILE__) . '/settings.php')) { + header("Location: install.php"); + exit; +} + /** * The time with microseconds when the Elgg engine was started. * @@ -73,110 +73,77 @@ foreach ($required_files as $file) { } } -// Use fallback view until sanitised -$oldview = get_input('view', 'default'); -set_input('view', 'failsafe'); - // Register the error handler set_error_handler('__elgg_php_error_handler'); set_exception_handler('__elgg_php_exception_handler'); -// attempt to save settings.php and .htaccess if in installation. -if ($sanitised = sanitised()) { - /** - * Load the system settings - */ - if (!include_once(dirname(__FILE__) . "/settings.php")) { - throw new InstallationException("Elgg could not load the settings file."); - } - // Get config - global $CONFIG; - - // load the rest of the library files from engine/lib/ - $lib_files = array( - // these need to be loaded first. - 'database.php', 'actions.php', - - 'admin.php', 'annotations.php', 'api.php', 'cache.php', - 'calendar.php', 'configuration.php', 'cron.php', 'entities.php', - 'export.php', 'extender.php', 'filestore.php', 'group.php', - 'input.php', 'install.php', 'location.php', 'mb_wrapper.php', - 'memcache.php', 'metadata.php', 'metastrings.php', 'notification.php', - 'objects.php', 'opendd.php', 'pagehandler.php', - 'pageowner.php', 'pam.php', 'plugins.php', 'query.php', - 'relationships.php', 'river.php', 'sites.php', 'social.php', - 'statistics.php', 'system_log.php', 'tags.php', 'usersettings.php', - 'users.php', 'version.php', 'widgets.php', 'xml.php', 'xml-rpc.php' - ); - - foreach($lib_files as $file) { - $file = $lib_dir . $file; - elgg_log("Loading $file..."); - if (!include_once($file)) { - throw new InstallationException("Could not load {$file}"); - } - } -} else { - throw new InstallationException(elgg_echo('installation:error:configuration')); +/** + * Load the system settings + */ +if (!include_once(dirname(__FILE__) . "/settings.php")) { + throw new InstallationException("Elgg could not load the settings file."); } -// Autodetect some default configuration settings -set_default_config(); - -// Trigger boot events for core. Plugins can't hook -// into this because they haven't been loaded yet. -trigger_elgg_event('boot', 'system'); - -// Check if installed -$installed = is_installed(); -$db_installed = is_db_installed(); -/** - * Forward if Elgg is not installed. - */ -if ((!$installed || !$db_installed) - && !substr_count($_SERVER["PHP_SELF"], "install.php") - && !substr_count($_SERVER["PHP_SELF"], "css.php") - && !substr_count($_SERVER["PHP_SELF"], "action_handler.php")) { +// load the rest of the library files from engine/lib/ +$lib_files = array( + // these need to be loaded first. + 'database.php', 'actions.php', + + 'admin.php', 'annotations.php', 'api.php', 'cache.php', + 'calendar.php', 'configuration.php', 'cron.php', 'entities.php', + 'export.php', 'extender.php', 'filestore.php', 'group.php', + 'input.php', 'install.php', 'location.php', 'mb_wrapper.php', + 'memcache.php', 'metadata.php', 'metastrings.php', 'notification.php', + 'objects.php', 'opendd.php', 'pagehandler.php', + 'pageowner.php', 'pam.php', 'plugins.php', 'query.php', + 'relationships.php', 'river.php', 'sites.php', 'social.php', + 'statistics.php', 'system_log.php', 'tags.php', 'usersettings.php', + 'users.php', 'version.php', 'widgets.php', 'xml.php', 'xml-rpc.php' +); - header("Location: install.php"); - exit; +foreach($lib_files as $file) { + $file = $lib_dir . $file; + elgg_log("Loading $file..."); + if (!include_once($file)) { + throw new InstallationException("Could not load {$file}"); + } } -// Load plugins -if (($installed) && ($db_installed) && ($sanitised)) { - load_plugins(); - - trigger_elgg_event('plugins_boot', 'system'); +// check if the install was completed +// @todo move into function +$installed = FALSE; +try { + $installed = is_installed(); +} catch (DatabaseException $e) {} +if (!$installed) { + header("Location: install.php"); + exit; } -// Trigger system init event for plugins -if (!substr_count($_SERVER["PHP_SELF"], "install.php") - && !substr_count($_SERVER["PHP_SELF"], "setup.php")) { +// Autodetect some default configuration settings +set_default_config(); - trigger_elgg_event('init', 'system'); -} +// Trigger events +trigger_elgg_event('boot', 'system'); -// System booted, return to normal view -if (!elgg_is_valid_view_type($oldview)) { - if (empty($CONFIG->view)) { - $oldview = 'default'; - } else { - $oldview = $CONFIG->view; - } -} +// Load the plugins that are active +load_plugins(); +trigger_elgg_event('plugins_boot', 'system'); -set_input('view', $oldview); +// Trigger system init event for plugins +trigger_elgg_event('init', 'system'); // Regenerate the simple cache if expired. -// Don't do it on upgrade, because upgrade does it itself. -if (($installed) && ($db_installed) && !(defined('upgrading') && upgrading == 'upgrading')) { - $lastupdate = datalist_get("simplecache_lastupdate_$oldview"); - $lastcached = datalist_get("simplecache_lastcached_$oldview"); +// Don't do it on upgrade because upgrade does it itself. +if (!defined('upgrading')) { + $view = get_input('view', 'default'); + $lastupdate = datalist_get("simplecache_lastupdate_$view"); + $lastcached = datalist_get("simplecache_lastcached_$view"); if ($lastupdate == 0 || $lastcached < $lastupdate) { - elgg_view_regenerate_simplecache($oldview); + elgg_view_regenerate_simplecache($view); } // needs to be set for links in html head $CONFIG->lastcache = $lastcached; -}
\ No newline at end of file +} diff --git a/htaccess_dist b/htaccess_dist index a2c4dac8b..48129d0f9 100644 --- a/htaccess_dist +++ b/htaccess_dist @@ -115,4 +115,7 @@ RewriteRule mt/mt-xmlrpc.cgi engine/handlers/xml-rpc_handler.php RewriteRule ^tag/(.+)/?$ engine/handlers/pagehandler.php?handler=search&page=$1 +# rule for rewrite module test during install - can be removed after installation +RewriteRule ^modrewrite.php$ install.php + </IfModule> diff --git a/install.php b/install.php index 83d0a40c7..6573e6b2c 100644 --- a/install.php +++ b/install.php @@ -4,35 +4,18 @@ * * @package Elgg * @subpackage Core - * @author Curverider Ltd * @link http://elgg.org/ */ -/** - * Start the Elgg engine - */ -require_once(dirname(__FILE__) . "/engine/start.php"); -global $CONFIG; - -elgg_set_viewtype('failsafe'); -/** - * If we're installed, go back to the homepage - */ -if ((is_installed() && is_db_installed() && datalist_get('installed'))) { - forward("index.php"); +// check for PHP 4 before we do anything else +if (version_compare(PHP_VERSION, '5.0.0', '<')) { + echo "Your server's version of PHP (" . PHP_VERSION . ") is too old to run Elgg.\n"; + exit; } -/** - * Install the database - */ -if (!is_db_installed()) { - validate_platform(); - run_sql_script(dirname(__FILE__) . "/engine/schema/mysql.sql"); - init_site_secret(); - system_message(elgg_echo("installation:success")); -} +require_once(dirname(__FILE__) . "/install/ElggInstaller.php"); -/** - * Load the front page - */ -page_draw(elgg_echo("installation:settings"), elgg_view_layout("one_column", elgg_view("settings/install")));
\ No newline at end of file +$installer = new ElggInstaller(); + +$step = get_input('step', 'welcome'); +$installer->run($step); diff --git a/install/ElggInstaller.php b/install/ElggInstaller.php new file mode 100644 index 000000000..6d1553572 --- /dev/null +++ b/install/ElggInstaller.php @@ -0,0 +1,1274 @@ +<?php +/** + * Elgg Installer. + * Controller for installing Elgg. + * + * @package Elgg + * @subpackage Installer + * @author Curverider Ltd + * @link http://elgg.org/ + */ + +class ElggInstaller { + + protected $steps = array( + 'welcome', + 'requirements', + 'database', + 'settings', + 'admin', + 'complete', + ); + + protected $status = array( + 'database' => FALSE, + 'settings' => FALSE, + 'admin' => FALSE, + ); + + protected $isAction; + + /** + * Constructor bootstraps the Elgg engine + */ + public function __construct() { + $this->isAction = $_SERVER['REQUEST_METHOD'] === 'POST'; + + $this->bootstrapConfig(); + + $this->bootstrapEngine(); + + elgg_set_viewtype('failsafe'); + + set_error_handler('__elgg_php_error_handler'); + set_exception_handler('__elgg_php_exception_handler'); + } + + /** + * Dispatches a request to one of the step controllers + * + * @param string $step + */ + public function run($step) { + + // check if this a mod rewrite test coming in + $this->runModRewriteTest(); + + if (!in_array($step, $this->getSteps())) { + throw new InstallationException("$step is an unknown installation step."); + } + + $this->setInstallStatus(); + + $this->checkInstallCompletion($step); + + // check if this is an install being resumed + $this->resumeInstall($step); + + $this->finishBootstraping($step); + + $params = $this->getPostVariables(); + $this->$step($params); + } + + /** + * Renders the data passed by a controller + * + * @param string $step + * @param array $vars + */ + protected function render($step, $vars = array()) { + + $vars['next_step'] = $this->getNextStep($step); + + $title = elgg_echo("install:$step"); + $body = elgg_view("install/pages/$step", $vars); + page_draw( + $title, + $body, + 'page_shells/install', + array( + 'step' => $step, + 'steps' => $this->getSteps(), + ) + ); + exit; + } + + /** + * Step controllers + */ + + /** + * Welcome controller + * + * @param array $vars Not used + */ + protected function welcome($vars) { + $this->render('welcome'); + } + + /** + * Requirements controller + * + * Checks version of php, libraries, permissions, and rewrite rules + * + * @param array $vars + */ + protected function requirements($vars) { + + $report = array(); + + // check PHP parameters and libraries + $this->checkPHP($report); + + // @todo - rewrite this to handle different web servers + // attempt to create .htaccess file + $htaccessExists = $this->createHtaccess($report); + + // check rewrite module + if ($htaccessExists) { + $this->checkRewriteModule($report); + } + + // check for existence of settings file + if ($this->checkSettingsFile() != TRUE) { + // no file, so check permissions on engine directory + $this->checkEngineDir($report); + } + + // check the database later + $report['database'] = array(array( + 'severity' => 'info', + 'message' => elgg_echo('install:check:database') + )); + + // any failures? + $numFailures = $this->countNumConditions($report, 'failure'); + + // any warnings + $numWarnings = $this->countNumConditions($report, 'warning'); + + + $params = array( + 'report' => $report, + 'num_failures' => $numFailures, + 'num_warnings' => $numWarnings, + ); + + $this->render('requirements', $params); + } + + /** + * Database set up controller + * + * Creates the settings.php file and creates the database tables + * + * @param array $submissionVars Submitted form variables + */ + protected function database($submissionVars) { + + $formVars = array( + 'dbuser' => array( + 'type' => 'text', + 'value' => '', + 'required' => TRUE, + ), + 'dbpassword' => array( + 'type' => 'password', + 'value' => '', + 'required' => TRUE, + ), + 'dbname' => array( + 'type' => 'text', + 'value' => '', + 'required' => TRUE, + ), + 'dbhost' => array( + 'type' => 'text', + 'value' => 'localhost', + 'required' => TRUE, + ), + 'dbprefix' => array( + 'type' => 'text', + 'value' => 'elgg_', + 'required' => TRUE, + ), + ); + + if ($this->checkSettingsFile()) { + // user manually created settings file so we fake out action test + $this->isAction = TRUE; + } + + if ($this->isAction) { + do { + // only create settings file if it doesn't exist + if (!$this->checkSettingsFile()) { + if (!$this->validateDatabaseVars($submissionVars, $formVars)) { + // error so we break out of action and serve same page + break; + } + + if (!$this->createSettingsFile($submissionVars)) { + break; + } + } + + // check db version and connect + if (!$this->connectToDatabase()) { + break; + } + + if (!$this->installDatabase()) { + break; + } + + system_message('Database has been installed.'); + + $this->continueToNextStep('database'); + } while (FALSE); // PHP doesn't support breaking out of if statements + } + + $formVars = $this->makeFormSticky($formVars, $submissionVars); + + $params = array('variables' => $formVars,); + + if ($this->checkSettingsFile()) { + // settings file exists and we're here so failed to create database + $params['failure'] = TRUE; + } + + $this->render('database', $params); + } + + /** + * Site settings controller + * + * Sets the site name, URL, data directory, etc. + * + * @param array $submissionVars + */ + protected function settings($submissionVars) { + global $CONFIG; + + $languages = get_installed_translations(); + $formVars = array( + 'sitename' => array( + 'type' => 'text', + 'value' => 'New Elgg site', + 'required' => TRUE, + ), + 'siteemail' => array( + 'type' => 'text', + 'value' => '', + 'required' => FALSE, + ), + 'wwwroot' => array( + 'type' => 'text', + 'value' => $CONFIG->wwwroot, + 'required' => TRUE, + ), + 'path' => array( + 'type' => 'text', + 'value' => $CONFIG->path, + 'required' => TRUE, + ), + 'dataroot' => array( + 'type' => 'text', + 'value' => '', + 'required' => TRUE, + ), + 'language' => array( + 'type' => 'pulldown', + 'value' => 'en', + 'options_values' => $languages, + 'required' => TRUE, + ), + 'siteaccess' => array( + 'type' => 'access', + 'value' => ACCESS_PUBLIC, + 'required' => TRUE, + ), + ); + + if ($this->isAction) { + do { + if (!$this->validateSettingsVars($submissionVars, $formVars)) { + break; + } + + if (!$this->saveSiteSettings($submissionVars)) { + break; + } + + system_message('Site settings have been saved.'); + + $this->continueToNextStep('settings'); + + } while (FALSE); // PHP doesn't support breaking out of if statements + } + + $formVars = $this->makeFormSticky($formVars, $submissionVars); + + $this->render('settings', array('variables' => $formVars)); + } + + /** + * Admin account controller + * + * Creates an admin user account + * + * @param array $submissionVars + */ + protected function admin($submissionVars) { + $formVars = array( + 'displayname' => array( + 'type' => 'text', + 'value' => '', + 'required' => TRUE, + ), + 'email' => array( + 'type' => 'text', + 'value' => '', + 'required' => TRUE, + ), + 'username' => array( + 'type' => 'text', + 'value' => '', + 'required' => TRUE, + ), + 'password1' => array( + 'type' => 'password', + 'value' => '', + 'required' => TRUE, + ), + 'password2' => array( + 'type' => 'password', + 'value' => '', + 'required' => TRUE, + ), + ); + + if ($this->isAction) { + do { + if (!$this->validateAdminVars($submissionVars, $formVars)) { + break; + } + + if (!$this->createAdminAccount($submissionVars)) { + break; + } + + system_message('Admin account has been created.'); + + $this->continueToNextStep('admin'); + + } while (FALSE); // PHP doesn't support breaking out of if statements + } + + $formVars = $this->makeFormSticky($formVars, $submissionVars); + + $this->render('admin', array('variables' => $formVars)); + } + + /** + * Controller for last step + * + * @param array $vars + */ + protected function complete($vars) { + + $this->render('complete'); + } + + /** + * Step management + */ + + /** + * Get an array of steps + * + * @return array + */ + protected function getSteps() { + return $this->steps; + } + + /** + * Forwards the browser to the next step + * + * @param string $currentStep + */ + protected function continueToNextStep($currentStep) { + $this->isAction = FALSE; + forward($this->getNextStepUrl($currentStep)); + } + + /** + * Get the next step as a string + * + * @param string $currentStep + * @return string + */ + protected function getNextStep($currentStep) { + return $this->steps[1 + array_search($currentStep, $this->steps)]; + } + + /** + * Get the URL of the next step + * + * @param string $currentStep + * @return string + */ + protected function getNextStepUrl($currentStep) { + global $CONFIG; + $nextStep = $this->getNextStep($currentStep); + return "{$CONFIG->wwwroot}install.php?step=$nextStep"; + } + + /** + * Check the different nstall steps for completion + */ + protected function setInstallStatus() { + global $CONFIG; + + $settingsCreated = $this->checkSettingsFile(); + if ($settingsCreated == FALSE) { + return; + } + + $this->loadSettingsFile(); + + // must be able to connect to database to jump install steps + $dbSettingsPass = $this->checkDatabaseSettings( + $CONFIG->dbuser, + $CONFIG->dbpass, + $CONFIG->dbname, + $CONFIG->dbhost + ); + if ($dbSettingsPass == FALSE) { + return; + } + + if (!include_once("{$CONFIG->path}engine/lib/database.php")) { + throw new InstallationException("Could not load database.php"); + } + + // check that the config table has been created + $query = "show tables"; + $result = get_data($query); + if ($result) { + foreach ($result as $table) { + $table = (array) $table; + if (in_array("{$CONFIG->dbprefix}config", $table)) { + $this->status['database'] = TRUE; + } + } + if ($this->status['database'] == FALSE) { + return; + } + } + + // check that the config table has entries + $query = "SELECT COUNT(*) AS total FROM {$CONFIG->dbprefix}config"; + $result = get_data($query); + if ($result && $result[0]->total > 0) { + $this->status['settings'] = TRUE; + } else { + return; + } + + // check that the users entity table has an entry + $query = "SELECT COUNT(*) AS total FROM {$CONFIG->dbprefix}users_entity"; + $result = get_data($query); + if ($result && $result[0]->total > 0) { + $this->status['admin'] = TRUE; + } else { + return; + } + } + + /** + * Security check to ensure the installer cannot be run after installation + * has finished. If this is detected, the viewer is sent to the front page. + * + * @param string $step + */ + protected function checkInstallCompletion($step) { + if ($step != 'complete') { + if (!in_array(FALSE, $this->status)) { + // install complete but someone is trying to view an install page + forward(); + } + } + } + + /** + * Check if this is a case of a install being resumed and figure + * out where to continue from. Returns the best guess on the step. + * + * @param string $step + * @return string + */ + protected function resumeInstall($step) { + global $CONFIG; + + // only do a resume from the first step + if ($step !== 'welcome') { + return; + } + + if ($this->status['database'] == FALSE) { + return; + } + + if ($this->status['settings'] == FALSE) { + forward("{$CONFIG->wwwroot}install.php?step=settings"); + } + + if ($this->status['admin'] == FALSE) { + forward("{$CONFIG->wwwroot}install.php?step=admin"); + } + + // everything appears to be set up + forward("{$CONFIG->wwwroot}install.php?step=complete"); + } + + /** + * Bootstraping + */ + + /** + * Load the essential libraries of the engine + */ + protected function bootstrapEngine() { + global $CONFIG; + + $lib_dir = $CONFIG->path . 'engine/lib/'; + + // bootstrapping with required files in a required order + $required_files = array( + 'exceptions.php', 'elgglib.php', 'views.php', 'access.php', 'system_log.php', 'export.php', + 'sessions.php', 'languages.php', 'input.php', 'install.php', 'cache.php', 'output.php' + ); + + foreach ($required_files as $file) { + $path = $lib_dir . $file; + if (!include($path)) { + echo "Could not load file '$path'. " + . 'Please check your Elgg installation for all required files.'; + exit; + } + } + } + + /** + * Load remaining engine libraries and complete bootstraping (see start.php) + * + * @param string $step + */ + protected function finishBootstraping($step) { + + // install has its own session handling + session_name('Elgg'); + session_start(); + unregister_elgg_event_handler('boot', 'system', 'session_init'); + + // once the database has been created, load rest of engine + $dbIndex = array_search('database', $this->getSteps()); + $stepIndex = array_search($step, $this->getSteps()); + + if ($stepIndex > $dbIndex) { + global $CONFIG; + $lib_dir = $CONFIG->path . 'engine/lib/'; + + $this->loadSettingsFile(); + + $lib_files = array( + // these want to be loaded first apparently? + 'database.php', 'actions.php', + + 'admin.php', 'annotations.php', 'api.php', + 'calendar.php', 'configuration.php', 'cron.php', 'entities.php', + 'extender.php', 'filestore.php', 'group.php', + 'location.php', 'mb_wrapper.php', + 'memcache.php', 'metadata.php', 'metastrings.php', 'notification.php', + 'objects.php', 'opendd.php', 'pagehandler.php', + 'pageowner.php', 'pam.php', 'plugins.php', 'query.php', + 'relationships.php', 'river.php', 'sites.php', 'social.php', + 'statistics.php', 'tags.php', 'usersettings.php', + 'users.php', 'version.php', 'widgets.php', 'xml.php', 'xml-rpc.php' + ); + + foreach ($lib_files as $file) { + $path = $lib_dir . $file; + if (!include_once($path)) { + throw new InstallationException("Could not load {$file}"); + } + } + + set_default_config(); + + trigger_elgg_event('boot', 'system'); + trigger_elgg_event('init', 'system'); + } + } + + /** + * Set up configuration variables + */ + protected function bootstrapConfig() { + global $CONFIG; + if (!isset($CONFIG)) { + $CONFIG = new stdClass; + } + + $CONFIG->wwwroot = $this->getBaseUrl(); + $CONFIG->url = $CONFIG->wwwroot; + $CONFIG->path = dirname(dirname(__FILE__)) . '/'; + } + + /** + * Get the best guess at the base URL + * @todo Should this be a core function? + * @return string + */ + protected function getBaseUrl() { + $protocol = 'http'; + if (!empty($_SERVER["HTTPS"]) && $_SERVER["HTTPS"] == "on") { + $protocol = 'https'; + } + $port = ':' . $_SERVER["SERVER_PORT"]; + if ($port == ':80' || $port == ':443') { + $port = ''; + } + $uri = $_SERVER['REQUEST_URI']; + $cutoff = strpos($uri, 'install.php'); + $uri = substr($uri, 0, $cutoff); + + $url = "$protocol://{$_SERVER['SERVER_NAME']}$port{$uri}"; + return $url; + } + + function loadSettingsFile() { + global $CONFIG; + + if (!include_once("{$CONFIG->path}engine/settings.php")) { + throw new InstallationException("Elgg could not load the settings file. It does not exist or there is a permissions issue."); + } + } + + /** + * Action handling methods + */ + + /** + * Return an associative array of post variables + * (could be selective based on expected variables) + * + * @return array + */ + protected function getPostVariables() { + $vars = array(); + foreach ($_POST as $k => $v) { + $vars[$k] = $v; + } + return $vars; + } + + /** + * If form is reshown, remember previously submitted variables + * + * @param array $formVars + * @param array $submissionVars + * @return array + */ + protected function makeFormSticky($formVars, $submissionVars) { + foreach ($submissionVars as $field => $value) { + $formVars[$field]['value'] = $value; + } + return $formVars; + } + + /** + * Requirement checks support methods + */ + + /** + * Create Elgg's .htaccess file or confirm that it exists + * + * @param array $report Reference to the report array + * @return bool + */ + protected function createHtaccess(&$report) { + global $CONFIG; + + $filename = "{$CONFIG->path}.htaccess"; + if (file_exists($filename)) { + // check that this is the Elgg .htaccess + $data = file_get_contents($filename); + if ($data === FALSE) { + // don't have permission to read the file + } + if (strpos($data, 'Elgg') === FALSE) { + $report['htaccess'] = array( + array( + 'severity' => 'failure', + 'message' => elgg_echo('install:check:htaccess_exists'), + ) + ); + return FALSE; + } else { + // Elgg .htaccess is already there + return TRUE; + } + } + + if (!is_writable($CONFIG->path)) { + $report['htaccess'] = array( + array( + 'severity' => 'failure', + 'message' => elgg_echo('install:check:root'), + ) + ); + return FALSE; + } + + // create the .htaccess file + $result = copy("{$CONFIG->path}htaccess_dist", $filename); + if (!$result) { + $report['htaccess'] = array( + array( + 'severity' => 'failure', + 'message' => elgg_echo('install:check:htaccess_fail'), + ) + ); + } + + return $result; + } + + /** + * Check that the engine dir is writable + * @param array $report + * @return bool + */ + protected function checkEngineDir(&$report) { + global $CONFIG; + + $writable = is_writable("{$CONFIG->path}engine"); + if (!$writable) { + $report['engine'] = array( + array( + 'severity' => 'failure', + 'message' => elgg_echo('install:check:enginedir'), + ) + ); + return FALSE; + } + + return TRUE; + } + + /** + * Check that the settings file exists + * @return bool + */ + protected function checkSettingsFile() { + global $CONFIG; + + if (is_readable("{$CONFIG->path}engine/settings.php")) { + return TRUE; + } + + return FALSE; + } + + /** + * Check version of PHP, extensions, and variables + * @param array $report + */ + protected function checkPHP(&$report) { + $phpReport = array(); + + $elgg_php_version = '5.2.0'; + if (version_compare(PHP_VERSION, $elgg_php_version, '<')) { + $phpReport[] = array( + 'severity' => 'failure', + 'message' => sprintf(elgg_echo('install:check:php:version'), $elgg_php_version, PHP_VERSION) + ); + } + + $this->checkPhpExtensions($phpReport); + + $this->checkPhpDirectives($phpReport); + + if (count($phpReport) == 0) { + $phpReport[] = array( + 'severity' => 'pass', + 'message' => elgg_echo('install:check:php:success') + ); + } + + $report['php'] = $phpReport; + } + + /** + * Check the server's PHP extensions + * + * @param array $phpReport + */ + protected function checkPhpExtensions(&$phpReport) { + $extensions = get_loaded_extensions(); + $requiredExtensions = array( + 'mysql', + 'json', + 'xml', + 'gd', + ); + foreach ($requiredExtensions as $extension) { + if (!in_array($extension, $extensions)) { + $phpReport[] = array( + 'severity' => 'failure', + 'message' => sprintf(elgg_echo('install:check:php:extension'), $extension) + ); + } + } + + $recommendedExtensions = array( + 'mbstring', + ); + foreach ($recommendedExtensions as $extension) { + if (!in_array($extension, $extensions)) { + $phpReport[] = array( + 'severity' => 'warning', + 'message' => sprintf(elgg_echo('install:check:php:extension:recommend'), $extension) + ); + } + } + } + + /** + * Check PHP parameters + * + * @param array $phpReport + */ + protected function checkPhpDirectives(&$phpReport) { + if (ini_get('open_basedir')) { + $phpReport[] = array( + 'severity' => 'warning', + 'message' => elgg_echo("install:check:php:open_basedir") + ); + } + + if (ini_get('safe_mode')) { + $phpReport[] = array( + 'severity' => 'warning', + 'message' => elgg_echo("install:check:php:safe_mode") + ); + } + } + + /** + * Confirm that Apache's rewrite module and AllowOverride are set up + * @param array $report + * @return bool + */ + protected function checkRewriteModule(&$report) { + global $CONFIG; + + $url = "{$CONFIG->wwwroot}modrewrite.php"; + + if (function_exists('curl_init')) { + // try curl if installed + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, $url); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + $response = curl_exec($ch); + curl_close($ch); + $result = $response === 'success'; + } else if (ini_get('allow_url_fopen')) { + // use file_get_contents as fallback + $data = file_get_contents($url); + $result = $data === 'success'; + } else { + $report['htaccess'] = array( + array( + 'severity' => 'warning', + 'message' => elgg_echo('install:check:rewrite:unknown'), + ) + ); + return FALSE; + } + + if ($result) { + $report['htaccess'] = array( + array( + 'severity' => 'pass', + 'message' => elgg_echo('install:check:rewrite:success'), + ) + ); + } else { + $report['htaccess'] = array( + array( + 'severity' => 'failure', + 'message' => elgg_echo('install:check:rewrite:fail'), + ) + ); + } + + return $result; + } + + /** + * Check if the request is coming from the mod rewrite test on the + * requirements page. + */ + protected function runModRewriteTest() { + if (strpos($_SERVER['REQUEST_URI'], 'modrewrite.php') !== FALSE) { + echo 'success'; + exit; + } + } + + /** + * Count the number of failures in the requirements report + * + * @param array $report + * @param string $condition 'failure' or 'warning' + * @return int + */ + protected function countNumConditions($report, $condition) { + $count = 0; + foreach ($report as $category => $checks) { + foreach ($checks as $check) { + if ($check['severity'] === $condition) { + $count++; + } + } + } + + return $count; + } + + + /** + * Database support methods + */ + + /** + * Validate the variables for the database step + * + * @param array $submissionVars + * @param array $formVars + * @return bool + */ + protected function validateDatabaseVars($submissionVars, $formVars) { + + foreach ($formVars as $field => $info) { + if ($info['required'] == TRUE && !$submissionVars[$field]) { + $name = elgg_echo("installation:database:label:$field"); + register_error("$name is required"); + return FALSE; + } + } + + return $this->checkDatabaseSettings( + $submissionVars['dbuser'], + $submissionVars['dbpassword'], + $submissionVars['dbname'], + $submissionVars['dbhost'] + ); + } + + /** + * Confirm the settings for the database + * + * @param string $user + * @param string $password + * @param string $dbname + * @param string $host + * @return bool + */ + function checkDatabaseSettings($user, $password, $dbname, $host) { + $mysql_dblink = mysql_connect($host, $user, $password, true); + if ($mysql_dblink == FALSE) { + register_error('Unable to connect to the database with these settings.'); + return $FALSE; + } + + $result = mysql_select_db($dbname, $mysql_dblink); + + // check MySQL version - must be 5.0 or > + $version = mysql_get_server_info(); + $points = explode('.', $version); + if ($points[0] < 5) { + register_error("MySQL must be 5.0 or above. Your server is using $version."); + return FALSE; + } + + mysql_close($mysql_dblink); + + if (!$result) { + register_error("Unable to use database $dbname"); + } + + return $result; + } + + /** + * Writes the settings file to the engine directory + * + * @param array $params + * @return bool + */ + protected function createSettingsFile($params) { + global $CONFIG; + + $templateFile = "{$CONFIG->path}engine/settings.example.php"; + $template = file_get_contents($templateFile); + if (!$template) { + register_error('Unable to read engine/settings.example.php'); + return FALSE; + } + + foreach ($params as $k => $v) { + $template = str_replace("{{".$k."}}", $v, $template); + } + + $settingsFilename = "{$CONFIG->path}engine/settings.php"; + $result = file_put_contents($settingsFilename, $template); + if (!$result) { + register_error('Unable to write engine/settings.php'); + return FALSE; + } + + return TRUE; + } + + /** + * Bootstrap database connection before entire engine is available + * + * @return bool + */ + protected function connectToDatabase() { + global $CONFIG; + + if (!include_once("{$CONFIG->path}engine/settings.php")) { + register_error("Elgg could not load the settings file."); + return FALSE; + } + + if (!include_once("{$CONFIG->path}engine/lib/database.php")) { + register_error("Elgg could not load the database library."); + return FALSE; + } + + try { + setup_db_connections(); + } catch (Exception $e) { + register_error($e->getMessage()); + return FALSE; + } + + return TRUE; + } + + /** + * Create the database tables + * + * @return bool + */ + protected function installDatabase() { + global $CONFIG; + + try { + run_sql_script("{$CONFIG->path}engine/schema/mysql.sql"); + } catch (Exception $e) { + register_error($e->getMessage()); + return FALSE; + } + + return TRUE; + } + + /** + * Site settings support methods + */ + + /** + * Validate the site settings form variables + * + * @param array $submissionVars + * @param array $formVars + * @return bool + */ + protected function validateSettingsVars($submissionVars, $formVars) { + + foreach ($formVars as $field => $info) { + if ($info['required'] == TRUE && !$submissionVars[$field]) { + $name = elgg_echo("installation:settings:label:$field"); + register_error("$name is required"); + return FALSE; + } + } + + // check that data root is writable + if (!is_writable($submissionVars['dataroot'])) { + register_error("Your data directory {$submissionVars['dataroot']} is not writable by the web server."); + return FALSE; + } + + // check that data root is not subdirectory of Elgg root + if (stripos($submissionVars['dataroot'], $submissionVars['path']) !== FALSE) { + register_error("Your data directory {$submissionVars['dataroot']} must be outside of your install path for security."); + return FALSE; + } + + // @todo move is_email_address to a better library than users.php + // check that email address is email address + //if ($submissionVars['siteemail'] && !is_email_address($submissionVars['siteemail'])) { + // register_error("{$submissionVars['']} is not a valid email address."); + // return FALSE; + //} + + // @todo check that url is a url + + + return TRUE; + } + + /** + * Initialize the site including site entity, plugins, and configuration + * + * @param array $submissionVars + * @return bool + */ + protected function saveSiteSettings($submissionVars) { + global $CONFIG; + + // ensure that file path, data path, and www root end in / + $submissionVars['path'] = sanitise_filepath($submissionVars['path']); + $submissionVars['dataroot'] = sanitise_filepath($submissionVars['dataroot']); + $submissionVars['wwwroot'] = sanitise_filepath($submissionVars['wwwroot']); + + $site = new ElggSite(); + $site->name = $submissionVars['sitename']; + $site->url = $submissionVars['wwwroot']; + $site->access_id = ACCESS_PUBLIC; + $site->email = $submissionVars['siteemail']; + $guid = $site->save(); + + if (!$guid) { + register_error("Unable to create the site."); + return FALSE; + } + + // bootstrap site info + $CONFIG->site_guid = $guid; + $CONFIG->site = $site; + + datalist_set('installed', time()); + datalist_set('path', $submissionVars['path']); + datalist_set('dataroot', $submissionVars['dataroot']); + datalist_set('default_site', $site->getGUID()); + datalist_set('version', get_version()); + + set_config('view', 'default', $site->getGUID()); + set_config('language', $submissionVars['language'], $site->getGUID()); + set_config('default_access', $submissionVars['siteaccess'], $site->getGUID()); + set_config('allow_registration', TRUE, $site->getGUID()); + set_config('walled_garden', FALSE, $site->getGUID()); + + $this->enablePlugins(); + + // reset the views path in case of installing over an old data dir. + $dataroot = datalist_get('dataroot'); + $cache = new ElggFileCache($dataroot); + $cache->delete('view_paths'); + + return TRUE; + } + + /** + * Enable a set of default plugins + */ + protected function enablePlugins() { + // activate plugins with manifest.xml: elgg_install_state = enabled + $plugins = get_plugin_list(); + foreach ($plugins as $plugin) { + if ($manifest = load_plugin_manifest($plugin)) { + if (isset($manifest['elgg_install_state']) && $manifest['elgg_install_state'] == 'enabled') { + enable_plugin($plugin); + } + } + } + } + + /** + * Admin account support methods + */ + + /** + * Validate account form variables + * + * @param array $submissionVars + * @param array $formVars + * @return bool + */ + protected function validateAdminVars($submissionVars, $formVars) { + + foreach ($formVars as $field => $info) { + if ($info['required'] == TRUE && !$submissionVars[$field]) { + $name = elgg_echo("installation:admin:label:$field"); + register_error("$name is required"); + return FALSE; + } + } + + if ($submissionVars['password1'] !== $submissionVars['password2']) { + register_error("Your passwords must match."); + return FALSE; + } + + if (trim($submissionVars['password1']) == "") { + register_error("Password cannot be empty."); + return FALSE; + } + + return TRUE; + } + + /** + * Create a user account for the admin + * + * @param array $submissionVars + * @return bool + */ + protected function createAdminAccount($submissionVars) { + global $CONFIG; + + $guid = register_user( + $submissionVars['username'], + $submissionVars['password1'], + $submissionVars['displayname'], + $submissionVars['email'] + ); + + if (!$guid) { + register_error("Unable to create an admin account."); + return FALSE; + } + + // @todo - register plugin hook instead for can edit + // need a logged in user to set admin flag so we go directly to database + $result = update_data("UPDATE {$CONFIG->dbprefix}users_entity set admin='yes' where guid=$guid"); + if (!$result) { + register_error("Unable to give new user account admin privileges."); + return FALSE; + } + + return TRUE; + } +} diff --git a/install/install.css b/install/install.css new file mode 100644 index 000000000..de10f10a5 --- /dev/null +++ b/install/install.css @@ -0,0 +1,266 @@ +html, body, div, span, applet, object, iframe, +h1, h2, h3, h4, h5, h6, p, blockquote, pre, +a, abbr, acronym, address, big, cite, code, +del, dfn, em, font, img, ins, kbd, q, s, samp, +small, strike, strong, sub, sup, tt, +dl, dt, dd, ol, ul, li, +fieldset, form, label, legend, +table, caption, tbody, tfoot, thead, tr, th, td { + margin: 0; + padding: 0; + border: 0; + outline: 0; + font-weight: inherit; + font-style: inherit; + font-size: 100%; + font-family: inherit; + vertical-align: baseline; +} + +body { + color: #333333; + background: #4690d6; + font-size: 80%; + font-family: "Lucida Grande",Arial,Tahoma,Verdana,sans-serif; + text-align: left; +} + +h1, h2, h3, h4, h5, h6 { + font-weight: bold; +} +h1 { font-size: 1.8em; } +h2 { font-size: 1.5em; } +h3 { font-size: 1.2em; } +h4 { font-size: 1.0em; } +h5 { font-size: 0.9em; } +h6 { font-size: 0.8em; } + +a { + color: #4690d6; + text-decoration: none; +} + +a:hover { + color: #0054a7; + text-decoration: underline; +} + +p { + margin: 0px 0px 15px 0; +} + +img { + border: none; +} + +h2 { + border-bottom: 1px solid #555555; + margin-bottom: 20px; +} + +ul { + list-style: none; +} + +.clearfloat { + clear:both; + height:0; + font-size: 1px; + line-height: 0px; +} + +#elgg_wrapper { + background: white; + width: 800px; + margin: auto; + padding: 10px 40px; + margin-top: 20px; + border-right: 1px solid #666666; + border-bottom: 1px solid #666666; +} +#elgg_header { + margin: 20px 10px; +} +#elgg_sidebar { + float: left; + width: 250px; +} +#elgg_content { + float: left; + width: 550px; + min-height: 320px; + padding-bottom: 60px; + position: relative; +} +#elgg_footer { + width: 800px; + height: 20px; + clear: both; + padding: 10px 20px 0 20px; + margin: auto; + margin-bottom: 40px; +} + +.install_nav { + width: 100%; + text-align: right; + position: absolute; + bottom: 0px; +} + +#elgg_footer a { + color: white; +} + +#elgg_footer li { + float: left; + list-style: none; + margin-right: 20px; +} + +#elgg_sidebar ol { + padding-left: 30px; +} + +#elgg_sidebar li { + font-size: 1.2em; + margin-bottom: 5px; +} + +.past { + text-decoration: line-through; +} +.present { + font-weight: bold; +} + +.future { + color: #cccccc; +} + +h3 { + margin: 15px 0 5px; +} + +label { + font-weight: bold; + color:#333333; + font-size: 140%; +} +input[type="text"], +input[type="password"] { + font: 120% Arial, Helvetica, sans-serif; + padding: 5px; + border: 1px solid #cccccc; + color:#666666; + width:566px; +} +.database_settings input[type="text"], +.database_settings input[type="password"] { + width:220px; +} +textarea { + width: 100%; + height: 100%; + font: 120% Arial, Helvetica, sans-serif; + border: solid 1px #cccccc; + padding: 5px; + color:#666666; +} +textarea:focus, input[type="password"]:focus, input[type="text"]:focus { + border: solid 1px #4690d6; + background: #e4ecf5; + color:#333333; +} +input[type="submit"] { + font-family: Arial, Helvetica, sans-serif; + font-size: 16px; + font-weight: bold; + color: #ffffff; + background: #4690d6; + border: 4px solid #4690d6; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + width: auto; + height: 35px; + padding: 2px 6px 2px 6px; + margin: 10px 0 10px 0; + cursor: pointer; + float: right; +} + +input[type="submit"]:hover { + background: #0054a7; + border: 4px solid #0054a7; +} + +select { + display: block; + padding: 5px; +} + +.install_nav a { + font-family: Arial, Helvetica, sans-serif; + font-size: 16px; + font-weight: bold; + color: #ffffff; + background: #4690d6; + border: 4px solid #4690d6; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + padding: 2px 9px 2px 9px; + margin: 10px; + cursor: pointer; + float: right; +} + +.install_nav a:hover { + text-decoration: none; + background: #0054a7; + border: 4px solid #0054a7; +} +.install_nav .disabled, .install_nav .disabled:hover { + background: #555555; + border-color: #555555; + cursor: default; +} + +#elgg_system_message { + padding: 3px 10px 3px 10px; + margin-bottom: 20px; +} + +.success { + border: 1px solid #00cc00; + background: #ccffcc; +} + +.error { + border: 1px solid #D3322A; + background: #F7DAD8; +} + +#elgg_content li { + margin-top: 5px; + padding: 5px; +} + +.pass { + border: 1px solid #00cc00; + background: #ccffcc; +} + +.warning { + border: 1px solid #ded0a9; + background: #FEF5AA; +} + +.failure { + border: 1px solid #D3322A; + background: #F7DAD8; +} + +.info { + border: 1px solid #aaaaaa; + background: #ffffff; +} diff --git a/languages/en.php b/languages/en.php index 95ec4ba38..d92aff61e 100644 --- a/languages/en.php +++ b/languages/en.php @@ -935,6 +935,107 @@ You cannot reply to this email.", 'actiongatekeeper:pluginprevents' => 'A extension has prevented this form from being submitted.', /** + * Installation + * @todo - move to separate language file for install + */ + 'install:welcome' => 'Welcome', + 'install:requirements' => 'Requirements check', + 'install:database' => 'Database installation', + 'install:settings' => 'Configure site', + 'install:admin' => 'Create admin account', + 'install:complete' => 'Finished', + + 'install:welcome:instructions' => "Installing Elgg has 6 simple steps and reading this welcome is the first one! + +If you haven't already, read through the installation instructions included with Elgg (or click the instructions link at the bottom of the page). + +If you are ready to proceed, click the Next button.", + 'install:requirements:instructions:success' => "Your server passed the requirement checks.", + 'install:requirements:instructions:failure' => "Your server failed the requirements check. After you have fixed the below issues, refresh this page.", + 'install:requirements:instructions:warning' => "Your server passed the requirements check, but there is at least one warning. We recommend that you check the install troubleshooting page for more details.", + + 'install:require:php' => 'PHP', + 'install:require:htaccess' => 'Web server', + 'install:require:engine' => 'Settings file', + 'install:require:database' => 'Database', + + 'install:check:root' => 'Your web server does not have permission to create an .htaccess file in the root directory of Elgg. You have two choices: + + 1. Change the permissions on the root directory + + 2. Copy the file htaccess_dist to .htaccess', + + 'install:check:php:version' => 'Elgg requires PHP %s or above. This server is using version %s.', + 'install:check:php:extension' => 'Elgg requires the PHP extension %s.', + 'install:check:php:extension:recommend' => 'It is recommended that the PHP extension %s is installed.', + 'install:check:php:open_basedir' => 'The open_basedir PHP directive may prevent Elgg from saving files to its data directory.', + 'install:check:php:safe_mode' => 'Running PHP in safe mode is not recommened and may cause problems with Elgg.', + + 'install:check:htaccess_exists' => 'There is an .htaccess file in the root directory of Elgg. Please remove it.', + 'install:check:htaccess_fail' => 'Unable to create an .htaccess file in the root directory of Elgg. You will need to copy htaccess_dist to .htaccess', + 'install:check:rewrite:success' => 'The test of the rewrite rules was successful.', + + 'install:check:enginedir' => 'Your web server does not have permission to create the settings.php file in the engine directory. You have two choices: + + 1. Change the permissions on the engine directory + + 2. Copy the file settings.example.php to settings.php and follow the instructions in it for setting your database parameters.', + + 'install:check:php:success' => "Your server's PHP satisfies all of Elgg's requirements.", + 'install:check:database' => 'The database requirements are checked when Elgg loads its database.', + + 'install:database:instructions' => "If you haven't already created a database for Elgg, do that now. Then fill in the values below to initialize the Elgg database.", + + 'installation:database:label:dbuser' => 'Database Username', + 'installation:database:label:dbpassword' => 'Database Password', + 'installation:database:label:dbname' => 'Database Name', + 'installation:database:label:dbhost' => 'Database Host', + 'installation:database:label:dbprefix' => 'Database Table Prefix', + + 'installation:database:help:dbuser' => 'User that has full priviledges to the MySQL database that you created for Elgg', + 'installation:database:help:dbpassword' => 'Password for the above database user account', + 'installation:database:help:dbname' => 'Name of the Elgg database', + 'installation:database:help:dbhost' => 'Hostname of the MySQL server (usually localhost)', + 'installation:database:help:dbprefix' => "The prefix given to all of Elgg's tables (usually elgg_)", + + 'install:dbuser' => '', + + 'install:settings:instructions' => "We need some information about the site as we configure Elgg. If you haven't created a data directory for Elgg, please do so before completing this step.", + + 'installation:settings:label:sitename' => 'Site Name', + 'installation:settings:label:siteemail' => 'Site Email Address', + 'installation:settings:label:wwwroot' => 'Site URL', + 'installation:settings:label:path' => 'Elgg Install Directory', + 'installation:settings:label:dataroot' => 'Data Directory', + 'installation:settings:label:language' => 'Site Language', + 'installation:settings:label:siteaccess' => 'Default Site Access', + + 'installation:settings:help:sitename' => 'The name of your new Elgg site', + 'installation:settings:help:siteemail' => 'Email address used by Elgg for communication with users', + 'installation:settings:help:wwwroot' => 'The address of the site (Elgg usually guesses this correctly)', + 'installation:settings:help:path' => 'The directory where you put the Elgg code (Elgg usually guesses this correctly)', + 'installation:settings:help:dataroot' => 'The directory that you created for Elgg to save files (the permissions on this directory are checked when you click Next)', + 'installation:settings:help:language' => 'The default language for the site', + 'installation:settings:help:siteaccess' => 'The default access level for new user created content', + + 'install:admin:instructions' => "It is now time to create an administrator's account.", + + 'installation:admin:label:displayname' => 'Display Name', + 'installation:admin:label:email' => 'Email Address', + 'installation:admin:label:username' => 'Username', + 'installation:admin:label:password1' => 'Password', + 'installation:admin:label:password2' => 'Password Again', + + 'installation:admin:help:displayname' => 'The name that is displayed on the site for this account', + 'installation:admin:help:email' => '', + 'installation:admin:help:username' => 'Account username used for logging in', + 'installation:admin:help:password1' => 'Account password must be at least x characters long', + 'installation:admin:help:password2' => 'Retype password to confirm', + + 'install:complete:instructions' => 'Your Elgg site is now ready to be used. Click the button below to be taken to your site.', + + +/** * Word blacklists */ 'word:blacklist' => 'and, the, then, but, she, his, her, him, one, not, also, about, now, hence, however, still, likewise, otherwise, therefore, conversely, rather, consequently, furthermore, nevertheless, instead, meanwhile, accordingly, this, seems, what, whom, whose, whoever, whomever', diff --git a/views/failsafe/input/password.php b/views/failsafe/input/password.php new file mode 100644 index 000000000..461f77955 --- /dev/null +++ b/views/failsafe/input/password.php @@ -0,0 +1,23 @@ +<?php +/** + * Elgg password input + * Displays a password input field + * + * @package Elgg + * @subpackage Core + * @author Curverider Ltd + * @link http://elgg.org/ + * + * @uses $vars['value'] The current value, if any + * @uses $vars['js'] Any Javascript to enter into the input tag + * @uses $vars['internalname'] The name of the input field + * + */ + +$class = $vars['class']; +if (!$class) { + $class = "input_password"; +} +?> + +<input type="password" <?php if ($vars['disabled']) echo ' disabled="yes" '; ?> <?php echo $vars['js']; ?> name="<?php echo $vars['internalname']; ?>" <?php if (isset($vars['internalid'])) echo "id=\"{$vars['internalid']}\""; ?> value="<?php echo htmlentities($vars['value'], ENT_QUOTES, 'UTF-8'); ?>" class="<?php echo $class; ?>" /> diff --git a/views/failsafe/install/footer.php b/views/failsafe/install/footer.php new file mode 100644 index 000000000..69cd27f66 --- /dev/null +++ b/views/failsafe/install/footer.php @@ -0,0 +1,10 @@ +<?php +/** + * Install footer - offers help links + */ +?> +<ul> + <li><a href="http://docs.elgg.org/wiki/Installation">Install instructions</a></li> + <li><a href="http://docs.elgg.org/wiki/Install_Troubleshooting">Install troubleshooting</a></li> + <li><a href="http://community.elgg.org/pg/groups/world/">Elgg community forums</a></li> +</ul>
\ No newline at end of file diff --git a/views/failsafe/install/forms/admin.php b/views/failsafe/install/forms/admin.php new file mode 100644 index 000000000..ae83cadea --- /dev/null +++ b/views/failsafe/install/forms/admin.php @@ -0,0 +1,21 @@ +<?php +/** + * Admin account form + * + * @uses $vars['variables'] Array of form variables. See ElggInstaller. + */ + +$vars['type'] = 'admin'; +$form_body = elgg_view('install/forms/template', $vars); + + +// @todo bug in current_page_url() with :8080 sites +//$url = current_page_url(); +$url = '/install.php?step=admin'; + +$params = array( + 'body' => $form_body, + 'action' => $url, + 'disable_security' => TRUE, +); +echo elgg_view('input/form', $params); diff --git a/views/failsafe/install/forms/database.php b/views/failsafe/install/forms/database.php new file mode 100644 index 000000000..a3fa8dd65 --- /dev/null +++ b/views/failsafe/install/forms/database.php @@ -0,0 +1,20 @@ +<?php +/** + * Database form + * + * @uses $vars['variables'] Array of form variables. See ElggInstaller. + */ + +$vars['type'] = 'database'; +$form_body = elgg_view('install/forms/template', $vars); + +// @todo bug in current_page_url() with :8080 sites +//$url = current_page_url(); +$url = '/install.php?step=database'; + +$params = array( + 'body' => $form_body, + 'action' => $url, + 'disable_security' => TRUE, +); +echo elgg_view('input/form', $params); diff --git a/views/failsafe/install/forms/settings.php b/views/failsafe/install/forms/settings.php new file mode 100644 index 000000000..67cba10f6 --- /dev/null +++ b/views/failsafe/install/forms/settings.php @@ -0,0 +1,20 @@ +<?php +/** + * Site settings form + * + * @uses $vars['variables'] Array of form variables. See ElggInstaller. + */ + +$vars['type'] = 'settings'; +$form_body = elgg_view('install/forms/template', $vars); + +// @todo bug in current_page_url() with :8080 sites +//$url = current_page_url(); +$url = '/install.php?step=settings'; + +$params = array( + 'body' => $form_body, + 'action' => $url, + 'disable_security' => TRUE, +); +echo elgg_view('input/form', $params); diff --git a/views/failsafe/install/forms/template.php b/views/failsafe/install/forms/template.php new file mode 100644 index 000000000..a2d93f42e --- /dev/null +++ b/views/failsafe/install/forms/template.php @@ -0,0 +1,27 @@ +<?php +/** + * Generic form template for install forms + * + * @uses $vars['variables'] + * @uses $vars['type'] Type of form: admin, database, settings + */ + +$variables = $vars['variables']; +$type = $vars['type']; + +$form_body = ''; +foreach ($variables as $field => $params) { + $label = elgg_echo("installation:$type:label:$field"); + $help = elgg_echo("installation:$type:help:$field"); + $params['internalname'] = $field; + + $form_body .= '<p>'; + $form_body .= "<label>$label</label>"; + $form_body .= elgg_view("input/{$params['type']}", $params); + $form_body .= "<span class=\"install_help\">$help</span>"; + $form_body .= '</p>'; +} + +$form_body .= elgg_view('input/submit', array('value' => elgg_echo('next'))); + +echo $form_body; diff --git a/views/failsafe/install/header.php b/views/failsafe/install/header.php new file mode 100644 index 000000000..d821e31e5 --- /dev/null +++ b/views/failsafe/install/header.php @@ -0,0 +1,6 @@ +<?php +/** + * Install header + */ +?> +<h1>Elgg</h1> diff --git a/views/failsafe/install/nav.php b/views/failsafe/install/nav.php new file mode 100644 index 000000000..d6a20ea2b --- /dev/null +++ b/views/failsafe/install/nav.php @@ -0,0 +1,35 @@ +<?php +/** + * Navigation for installation pages + * + * @uses $vars['url'] base url of site + * @uses $vars['next_step'] next step as string + * @uses $vars['refresh'] should refresh button be shown? + * @uses $vars['advance'] should the next button be active? + */ + + +// has a refresh button been requested +$refresh = ''; +if (isset($vars['refresh']) && $vars['refresh']) { + $refresh_text = elgg_echo('Refresh'); + $refresh = "<a href=\"\">$refresh_text</a>"; +} + +// create next button and selectively disable +$next_text = elgg_echo('next'); +$next_link = "{$vars['url']}install.php?step={$vars['next_step']}"; +$next = "<a href=\"$next_link\" disable=\"disable\">$next_text</a>"; +if (isset($vars['advance']) && !$vars['advance']) { + // disable the next button + $next = "<a class=\"disabled\">$next_text</a>"; +} + + +echo <<<___END +<div class="install_nav"> + $next + $refresh +</div> + +___END; diff --git a/views/failsafe/install/pages/admin.php b/views/failsafe/install/pages/admin.php new file mode 100644 index 000000000..1fdd5dced --- /dev/null +++ b/views/failsafe/install/pages/admin.php @@ -0,0 +1,8 @@ +<?php +/** + * Install create admin account page + */ + +echo autop(elgg_echo('install:admin:instructions')); + +echo elgg_view('install/forms/admin', $vars); diff --git a/views/failsafe/install/pages/complete.php b/views/failsafe/install/pages/complete.php new file mode 100644 index 000000000..60838a630 --- /dev/null +++ b/views/failsafe/install/pages/complete.php @@ -0,0 +1,14 @@ +<?php +/** + * Install completion page + */ + +echo autop(elgg_echo('install:complete:instructions')); + +?> + +<div class="install_nav"> +<?php + echo "<a href=\"{$vars['url']}index.php\">Go to site</a>"; +?> +</div> diff --git a/views/failsafe/install/pages/database.php b/views/failsafe/install/pages/database.php new file mode 100644 index 000000000..7765c6e48 --- /dev/null +++ b/views/failsafe/install/pages/database.php @@ -0,0 +1,16 @@ +<?php +/** + * Install database page + * + * @uses $vars['failure'] Settings file exists but something went wrong + */ + +if (isset($vars['failure']) && $vars['failure']) { + echo autop(elgg_echo('install:database:error')); + $vars['refresh'] = TRUE; + $vars['advance'] = FALSE; + echo elgg_view('install/nav', $vars); +} else { + echo autop(elgg_echo('install:database:instructions')); + echo elgg_view('install/forms/database', $vars); +}
\ No newline at end of file diff --git a/views/failsafe/install/pages/requirements.php b/views/failsafe/install/pages/requirements.php new file mode 100644 index 000000000..b6516840f --- /dev/null +++ b/views/failsafe/install/pages/requirements.php @@ -0,0 +1,39 @@ +<?php +/** + * Install requirements checking page + * + * @uses $vars['num_failures] Number of requirements failures + * @uses $vars['num_warnings] Number of recommendation warnings + */ + +if ($vars['num_failures'] != 0) { + $instruct_text = elgg_echo('install:requirements:instructions:failure'); +} elseif ($vars['num_warnings'] != 0) { + $instruct_text = elgg_echo('install:requirements:instructions:warning'); +} else { + $instruct_text = elgg_echo('install:requirements:instructions:success'); +} + +echo autop($instruct_text); + +$report = $vars['report']; +foreach ($report as $category => $checks) { + $title = elgg_echo("install:require:$category"); + echo "<h3>$title</h3>"; + echo "<ul>"; + foreach ($checks as $check) { + echo "<li class=\"{$check['severity']}\">"; + echo autop($check['message']); + echo "</li>"; + } + echo "</ul>"; +} + +$vars['refresh'] = TRUE; + +// cannot advance to next step with a failure +if ($vars['num_failures'] != 0) { + $vars['advance'] = FALSE; +} + +echo elgg_view('install/nav', $vars); diff --git a/views/failsafe/install/pages/settings.php b/views/failsafe/install/pages/settings.php new file mode 100644 index 000000000..6f20573ef --- /dev/null +++ b/views/failsafe/install/pages/settings.php @@ -0,0 +1,5 @@ +<?php + +echo autop(elgg_echo('install:settings:instructions')); + +echo elgg_view('install/forms/settings', $vars); diff --git a/views/failsafe/install/pages/welcome.php b/views/failsafe/install/pages/welcome.php new file mode 100644 index 000000000..f069e4ba7 --- /dev/null +++ b/views/failsafe/install/pages/welcome.php @@ -0,0 +1,8 @@ +<?php +/** + * Install welcome page + */ + +echo autop(elgg_echo('install:welcome:instructions')); + +echo elgg_view('install/nav', $vars); diff --git a/views/failsafe/install/sidebar.php b/views/failsafe/install/sidebar.php new file mode 100644 index 000000000..8136cd898 --- /dev/null +++ b/views/failsafe/install/sidebar.php @@ -0,0 +1,26 @@ +<?php +/** + * Install sidebar + * + * @uses $vars['step'] Current step + * @uses $vars['steps'] Array of steps + */ + +$current_step = $vars['step']; +$steps = $vars['steps']; + +$current_step_index = array_search($current_step, $steps); + +echo '<ol>'; +foreach ($steps as $index => $step) { + if ($index < $current_step_index) { + $class = 'past'; + } elseif ($index == $current_step_index) { + $class = 'present'; + } else { + $class = 'future'; + } + $text = elgg_echo("install:$step"); + echo "<li class=\"$class\">$text</li>"; +} +echo '</ol>'; diff --git a/views/failsafe/page_shells/install.php b/views/failsafe/page_shells/install.php new file mode 100644 index 000000000..b023197fa --- /dev/null +++ b/views/failsafe/page_shells/install.php @@ -0,0 +1,51 @@ +<?php +/** + * Elgg install pageshell + * + * @package Elgg + * @subpackage Core + * @author Curverider Ltd + * @link http://elgg.org/ + * + * @uses $vars['title'] The page title + * @uses $vars['body'] The main content of the page + * @uses $vars['sysmessages'] Array of system status messages + */ + +// we won't trust server configuration but specify utf-8 +header('Content-type: text/html; charset=utf-8'); + +// turn off browser caching +header('Pragma: public', TRUE); +header("Cache-Control: no-cache, must-revalidate", TRUE); +header('Expires: Fri, 05 Feb 1982 00:00:00 -0500', TRUE); + +?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> + <head> + <title>Elgg Install : <?php echo $vars['title']; ?></title> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> + <link rel="SHORTCUT ICON" href="<?php echo $vars['url']; ?>_graphics/favicon.ico" /> + <link rel="stylesheet" href="<?php echo $vars['url']; ?>install/install.css" type="text/css" /> + </head> + <body> + <div id="elgg_wrapper"> + <div id="elgg_header"> + <?php echo elgg_view('install/header', $vars); ?> + </div> + <div id="elgg_sidebar"> + <?php echo elgg_view('install/sidebar', $vars); ?> + </div> + <div id="elgg_content"> + <h2><?php echo $vars['title']; ?></h2> + <?php echo elgg_view('messages/list', array('object' => $vars['sysmessages'])); ?> + <?php echo $vars['body']; ?> + </div> + <div class="clearfloat"></div> + </div> + <div id="elgg_footer"> + <?php echo elgg_view('install/footer'); ?> + </div> + </body> +</html> |