]> gitweb.fluxo.info Git - lorea/elgg.git/commitdiff
Refs #2129 - integrates new installer code from http://github.com/cash/Elgg - does...
authorcash <cash@36083f99-b078-4883-b0ff-0f9b5a30f544>
Fri, 1 Oct 2010 12:13:24 +0000 (12:13 +0000)
committercash <cash@36083f99-b078-4883-b0ff-0f9b5a30f544>
Fri, 1 Oct 2010 12:13:24 +0000 (12:13 +0000)
git-svn-id: http://code.elgg.org/elgg/trunk@6991 36083f99-b078-4883-b0ff-0f9b5a30f544

23 files changed:
engine/settings.example.php
engine/start.php
htaccess_dist
install.php
install/ElggInstaller.php [new file with mode: 0644]
install/install.css [new file with mode: 0644]
languages/en.php
views/failsafe/input/password.php [new file with mode: 0644]
views/failsafe/install/footer.php [new file with mode: 0644]
views/failsafe/install/forms/admin.php [new file with mode: 0644]
views/failsafe/install/forms/database.php [new file with mode: 0644]
views/failsafe/install/forms/settings.php [new file with mode: 0644]
views/failsafe/install/forms/template.php [new file with mode: 0644]
views/failsafe/install/header.php [new file with mode: 0644]
views/failsafe/install/nav.php [new file with mode: 0644]
views/failsafe/install/pages/admin.php [new file with mode: 0644]
views/failsafe/install/pages/complete.php [new file with mode: 0644]
views/failsafe/install/pages/database.php [new file with mode: 0644]
views/failsafe/install/pages/requirements.php [new file with mode: 0644]
views/failsafe/install/pages/settings.php [new file with mode: 0644]
views/failsafe/install/pages/welcome.php [new file with mode: 0644]
views/failsafe/install/sidebar.php [new file with mode: 0644]
views/failsafe/page_shells/install.php [new file with mode: 0644]

index 4f47872cb5fae57a9f99404890fcc9d5d4f8013a..aa50be6bc6f330ec2cd078c0990db8082974a3a3 100644 (file)
@@ -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.
  *
index d9ec01b87b9a8c586d47bc58a85ca2b347bea418..db9bff0e4397d4d3b888aaf6853c2cf840b713d4 100644 (file)
  * 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
+}
index a2c4dac8bc36d1401a54ed40eb965681a99f146e..48129d0f925ec602a3f39842dfc9ed2e5100e628 100644 (file)
@@ -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>
index 83d0a40c72aa55f698b87ffebe5aeee5176dac1f..6573e6b2cc447218ed59c62f6fb98a277ca37ee6 100644 (file)
@@ -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 (file)
index 0000000..6d15535
--- /dev/null
@@ -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 (file)
index 0000000..de10f10
--- /dev/null
@@ -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;
+}
index 95ec4ba3833a53da2c15d66d43e190bbd4eb28d2..d92aff61e7aeb9f4ccb817b8c08828827db01631 100644 (file)
@@ -934,6 +934,107 @@ You cannot reply to this email.",
        'actiongatekeeper:timeerror' => 'The page you were using has expired. Please refresh and try again.',
        '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
  */
diff --git a/views/failsafe/input/password.php b/views/failsafe/input/password.php
new file mode 100644 (file)
index 0000000..461f779
--- /dev/null
@@ -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 (file)
index 0000000..69cd27f
--- /dev/null
@@ -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 (file)
index 0000000..ae83cad
--- /dev/null
@@ -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 (file)
index 0000000..a3fa8dd
--- /dev/null
@@ -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 (file)
index 0000000..67cba10
--- /dev/null
@@ -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 (file)
index 0000000..a2d93f4
--- /dev/null
@@ -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 (file)
index 0000000..d821e31
--- /dev/null
@@ -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 (file)
index 0000000..d6a20ea
--- /dev/null
@@ -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 (file)
index 0000000..1fdd5dc
--- /dev/null
@@ -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 (file)
index 0000000..60838a6
--- /dev/null
@@ -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 (file)
index 0000000..7765c6e
--- /dev/null
@@ -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 (file)
index 0000000..b651684
--- /dev/null
@@ -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 (file)
index 0000000..6f20573
--- /dev/null
@@ -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 (file)
index 0000000..f069e4b
--- /dev/null
@@ -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 (file)
index 0000000..8136cd8
--- /dev/null
@@ -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 (file)
index 0000000..b023197
--- /dev/null
@@ -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>