install.php
changeset 348 87e08a6e4fec
parent 347 299a90e28abc
child 349 fdaf9070566c
equal deleted inserted replaced
347:299a90e28abc 348:87e08a6e4fec
     1 <?php
       
     2 
       
     3 /*
       
     4  * Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between
       
     5  * Version 1.1.1
       
     6  * Copyright (C) 2006-2007 Dan Fuhry
       
     7  * install.php - handles everything related to installation and initial configuration
       
     8  *
       
     9  * This program is Free Software; you can redistribute and/or modify it under the terms of the GNU General Public License
       
    10  * as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
       
    11  *
       
    12  * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
       
    13  * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
       
    14  */
       
    15  
       
    16 @include('config.php');
       
    17 if( ( defined('ENANO_INSTALLED') || defined('MIDGET_INSTALLED') ) && ((isset($_GET['mode']) && ($_GET['mode']!='finish' && $_GET['mode']!='css') && $_GET['mode']!='showlicense') || !isset($_GET['mode'])))
       
    18 {
       
    19   $_GET['title'] = 'Enano:Installation_locked';
       
    20   require('includes/common.php');
       
    21   die_friendly('Installation locked', '<p>The Enano installer has found a Enano installation in this directory. You MUST delete config.php if you want to re-install Enano.</p><p>If you wish to upgrade an older Enano installation to this version, please use the <a href="upgrade.php">upgrade script</a>.</p>');
       
    22   exit;
       
    23 }
       
    24 
       
    25 define('IN_ENANO_INSTALL', 'true');
       
    26 
       
    27 define('ENANO_VERSION', '1.1.1');
       
    28 define('ENANO_CODE_NAME', 'Germination');
       
    29 // In beta versions, define ENANO_BETA_VERSION here
       
    30 
       
    31 // This is required to make installation work right
       
    32 define("ENANO_ALLOW_LOAD_NOLANG", 1);
       
    33 
       
    34 if(!defined('scriptPath')) {
       
    35   $sp = dirname($_SERVER['REQUEST_URI']);
       
    36   if($sp == '/' || $sp == '\\') $sp = '';
       
    37   define('scriptPath', $sp);
       
    38 }
       
    39 
       
    40 if(!defined('contentPath')) {
       
    41   $sp = dirname($_SERVER['REQUEST_URI']);
       
    42   if($sp == '/' || $sp == '\\') $sp = '';
       
    43   define('contentPath', $sp);
       
    44 }
       
    45 global $_starttime, $this_page, $sideinfo;
       
    46 $_starttime = microtime(true);
       
    47 
       
    48 global $db;
       
    49 
       
    50 // Determine directory (special case for development servers)
       
    51 if ( strpos(__FILE__, '/repo/') && file_exists('.enanodev') )
       
    52 {
       
    53   $filename = str_replace('/repo/', '/', __FILE__);
       
    54 }
       
    55 else
       
    56 {
       
    57   $filename = __FILE__;
       
    58 }
       
    59 
       
    60 define('ENANO_ROOT', dirname($filename));
       
    61 
       
    62 function is_page($p)
       
    63 {
       
    64   return true;
       
    65 }
       
    66 
       
    67 function microtime_float()
       
    68 {
       
    69   list($usec, $sec) = explode(" ", microtime());
       
    70   return ((float)$usec + (float)$sec);
       
    71 }
       
    72 
       
    73 require('includes/wikiformat.php');
       
    74 require('includes/constants.php');
       
    75 require('includes/rijndael.php');
       
    76 require('includes/functions.php');
       
    77 require('includes/dbal.php');
       
    78 require('includes/lang.php');
       
    79 require('includes/json.php');
       
    80 
       
    81 // Initialize language support
       
    82 $lang = new Language('eng');
       
    83 $lang->load_file('./language/english/install.json');
       
    84 
       
    85 strip_magic_quotes_gpc();
       
    86 
       
    87 //
       
    88 // INSTALLER LIBRARY
       
    89 //
       
    90 
       
    91 $neutral_color = 'C';
       
    92 
       
    93 function run_installer_stage($stage_id, $stage_name, $function, $failure_explanation, $allow_skip = true)
       
    94 {
       
    95   static $resumed = false;
       
    96   static $resume_stack = array();
       
    97   
       
    98   if ( empty($resume_stack) && isset($_POST['resume_stack']) && preg_match('/[a-z_]+((\|[a-z_]+)+)/', $_POST['resume_stack']) )
       
    99   {
       
   100     $resume_stack = explode('|', $_POST['resume_stack']);
       
   101   }
       
   102   
       
   103   $already_run = false;
       
   104   if ( in_array($stage_id, $resume_stack) )
       
   105   {
       
   106     $already_run = true;
       
   107   }
       
   108   
       
   109   if ( !$resumed )
       
   110   {
       
   111     if ( !isset($_GET['stage']) )
       
   112       $resumed = true;
       
   113     if ( isset($_GET['stage']) && $_GET['stage'] == $stage_id )
       
   114     {
       
   115       $resumed = true;
       
   116     }
       
   117   }
       
   118   if ( !$resumed && $allow_skip )
       
   119   {
       
   120     echo_stage_success($stage_id, $stage_name);
       
   121     return false;
       
   122   }
       
   123   if ( !function_exists($function) )
       
   124     die('libenanoinstall: CRITICAL: function "' . $function . '" for ' . $stage_id . ' doesn\'t exist');
       
   125   $result = @call_user_func($function, false, $already_run);
       
   126   if ( $result )
       
   127   {
       
   128     echo_stage_success($stage_id, $stage_name);
       
   129     $resume_stack[] = $stage_id;
       
   130     return true;
       
   131   }
       
   132   else
       
   133   {
       
   134     echo_stage_failure($stage_id, $stage_name, $failure_explanation, $resume_stack);
       
   135     return false;
       
   136   }
       
   137 }
       
   138 
       
   139 function start_install_table()
       
   140 {
       
   141   echo '<table border="0" cellspacing="0" cellpadding="0" style="margin-top: 10px;">' . "\n";
       
   142   ob_start();
       
   143 }
       
   144 
       
   145 function close_install_table()
       
   146 {
       
   147   echo '</table>' . "\n\n";
       
   148   ob_end_flush();
       
   149 }
       
   150 
       
   151 function echo_stage_success($stage_id, $stage_name)
       
   152 {
       
   153   global $neutral_color;
       
   154   $neutral_color = ( $neutral_color == 'A' ) ? 'C' : 'A';
       
   155   echo '<tr><td style="width: 500px; background-color: #' . "{$neutral_color}{$neutral_color}FF{$neutral_color}{$neutral_color}" . '; padding: 0 5px;">' . htmlspecialchars($stage_name) . '</td><td style="padding: 0 5px;"><img alt="Done" src="images/good.gif" /></td></tr>' . "\n";
       
   156   ob_flush();
       
   157 }
       
   158 
       
   159 function echo_stage_failure($stage_id, $stage_name, $failure_explanation, $resume_stack)
       
   160 {
       
   161   global $neutral_color;
       
   162   global $lang;
       
   163   
       
   164   $neutral_color = ( $neutral_color == 'A' ) ? 'C' : 'A';
       
   165   echo '<tr><td style="width: 500px; background-color: #' . "FF{$neutral_color}{$neutral_color}{$neutral_color}{$neutral_color}" . '; padding: 0 5px;">' . htmlspecialchars($stage_name) . '</td><td style="padding: 0 5px;"><img alt="Failed" src="images/bad.gif" /></td></tr>' . "\n";
       
   166   ob_flush();
       
   167   close_install_table();
       
   168   $post_data = '';
       
   169   $mysql_error = mysql_error();
       
   170   foreach ( $_POST as $key => $value )
       
   171   {
       
   172     // FIXME: These should really also be sanitized for double quotes
       
   173     $value = htmlspecialchars($value);
       
   174     $key = htmlspecialchars($key);
       
   175     $post_data .= "          <input type=\"hidden\" name=\"$key\" value=\"$value\" />\n";
       
   176   }
       
   177   echo '<form action="install.php?mode=install&amp;stage=' . $stage_id . '" method="post">
       
   178           ' . $post_data . '
       
   179           <input type="hidden" name="resume_stack" value="' . htmlspecialchars(implode('|', $resume_stack)) . '" />
       
   180           <h3>' . $lang->get('meta_msg_err_stagefailed_title') . '</h3>
       
   181            <p>' . $failure_explanation . '</p>
       
   182            ' . ( !empty($mysql_error) ? "<p>" . $lang->get('meta_msg_err_stagefailed_mysqlerror') . " $mysql_error</p>" : '' ) . '
       
   183            <p>' . $lang->get('meta_msg_err_stagefailed_body') . '</p>
       
   184            <p style="text-align: center;"><input type="submit" value="' . $lang->get('meta_btn_retry_installation') . '" /></p>
       
   185         </form>';
       
   186   global $template, $template_bak;
       
   187   if ( is_object($template_bak) )
       
   188     $template_bak->footer();
       
   189   else
       
   190     $template->footer();
       
   191   exit;
       
   192 }
       
   193 
       
   194 //
       
   195 // INSTALLER STAGES
       
   196 //
       
   197 
       
   198 function stg_mysql_connect($act_get = false)
       
   199 {
       
   200   global $db;
       
   201   $db = new mysql();
       
   202   
       
   203   static $conn = false;
       
   204   if ( $act_get )
       
   205     return $conn;
       
   206   
       
   207   $db_user =& $_POST['db_user'];
       
   208   $db_pass =& $_POST['db_pass'];
       
   209   $db_name =& $_POST['db_name'];
       
   210   
       
   211   if ( !preg_match('/^[a-z0-9_-]+$/', $db_name) )
       
   212   {
       
   213     $db_name = htmlspecialchars($db_name);
       
   214     die("<p>SECURITY: malformed database name \"$db_name\"</p>");
       
   215   }
       
   216   
       
   217   // First, try to connect using the normal credentials
       
   218   $conn = @mysql_connect($_POST['db_host'], $_POST['db_user'], $_POST['db_pass']);
       
   219   if ( !$conn )
       
   220   {
       
   221     // Connection failed. Do we have the root username and password?
       
   222     if ( !empty($_POST['db_root_user']) && !empty($_POST['db_root_pass']) )
       
   223     {
       
   224       $conn_root = @mysql_connect($_POST['db_host'], $_POST['db_root_user'], $_POST['db_root_pass']);
       
   225       if ( !$conn_root )
       
   226       {
       
   227         // Couldn't connect using either set of credentials. Bail out.
       
   228         return false;
       
   229       }
       
   230       unset($db_user, $db_pass);
       
   231       $db_user = mysql_real_escape_string($_POST['db_user']);
       
   232       $db_pass = mysql_real_escape_string($_POST['db_pass']);
       
   233       // Create the user account
       
   234       $q = @mysql_query("GRANT ALL PRIVILEGES ON test.* TO '{$db_user}'@'localhost' IDENTIFIED BY '$db_pass' WITH GRANT OPTION;", $conn_root);
       
   235       if ( !$q )
       
   236       {
       
   237         return false;
       
   238       }
       
   239       // Revoke privileges from test, we don't need them
       
   240       $q = @mysql_query("REVOKE ALL PRIVILEGES ON test.* FROM '{$db_user}'@'localhost';", $conn_root);
       
   241       if ( !$q )
       
   242       {
       
   243         return false;
       
   244       }
       
   245       if ( $_POST['db_host'] != 'localhost' && $_POST['db_host'] != '127.0.0.1' && $_POST['db_host'] != '::1' )
       
   246       {
       
   247         // If not connecting to a server running on localhost, allow from any host
       
   248         // this is safer than trying to detect the hostname of the webserver, but less secure
       
   249         $q = @mysql_query("GRANT ALL PRIVILEGES ON test.* TO '{$db_user}'@'%' IDENTIFIED BY '$db_pass' WITH GRANT OPTION;", $conn_root);
       
   250         if ( !$q )
       
   251         {
       
   252           return false;
       
   253         }
       
   254         // Revoke privileges from test, we don't need them
       
   255         $q = @mysql_query("REVOKE ALL PRIVILEGES ON test.* FROM '{$db_user}'@'%';", $conn_root);
       
   256         if ( !$q )
       
   257         {
       
   258           return false;
       
   259         }
       
   260       }
       
   261       mysql_close($conn_root);
       
   262       $conn = @mysql_connect($_POST['db_host'], $_POST['db_user'], $_POST['db_pass']);
       
   263       if ( !$conn )
       
   264       {
       
   265         // This should honestly never happen.
       
   266         return false;
       
   267       }
       
   268     }
       
   269   }
       
   270   $q = @mysql_query("USE `$db_name`;", $conn);
       
   271   if ( !$q )
       
   272   {
       
   273     // access denied to the database; try the whole root schenanegan again
       
   274     if ( !empty($_POST['db_root_user']) && !empty($_POST['db_root_pass']) )
       
   275     {
       
   276       $conn_root = @mysql_connect($_POST['db_host'], $_POST['db_root_user'], $_POST['db_root_pass']);
       
   277       if ( !$conn_root )
       
   278       {
       
   279         // Couldn't connect as root; bail out
       
   280         return false;
       
   281       }
       
   282       // create the database, if it doesn't exist
       
   283       $q = @mysql_query("CREATE DATABASE IF NOT EXISTS `$db_name`;", $conn_root);
       
   284       if ( !$q )
       
   285       {
       
   286         // this really should never fail, so don't give any tolerance to it
       
   287         return false;
       
   288       }
       
   289       unset($db_user, $db_pass);
       
   290       $db_user = mysql_real_escape_string($_POST['db_user']);
       
   291       $db_pass = mysql_real_escape_string($_POST['db_pass']);
       
   292       // we're in with root rights; grant access to the database
       
   293       $q = @mysql_query("GRANT ALL PRIVILEGES ON `$db_name`.* TO '{$db_user}'@'localhost';", $conn_root);
       
   294       if ( !$q )
       
   295       {
       
   296         return false;
       
   297       }
       
   298       if ( $_POST['db_host'] != 'localhost' && $_POST['db_host'] != '127.0.0.1' && $_POST['db_host'] != '::1' )
       
   299       {
       
   300         $q = @mysql_query("GRANT ALL PRIVILEGES ON `$db_name`.* TO '{$db_user}'@'%';", $conn_root);
       
   301         if ( !$q )
       
   302         {
       
   303           return false;
       
   304         }
       
   305       }
       
   306       mysql_close($conn_root);
       
   307       // grant tables have hopefully been flushed, kill and reconnect our regular user connection
       
   308       mysql_close($conn);
       
   309       $conn = @mysql_connect($_POST['db_host'], $_POST['db_user'], $_POST['db_pass']);
       
   310       if ( !$conn )
       
   311       {
       
   312         return false;
       
   313       }
       
   314     }
       
   315     else
       
   316     {
       
   317       return false;
       
   318     }
       
   319     // try again
       
   320     $q = @mysql_query("USE `$db_name`;", $conn);
       
   321     if ( !$q )
       
   322     {
       
   323       // really failed this time; bail out
       
   324       return false;
       
   325     }
       
   326   }
       
   327   // initialize DBAL
       
   328   $db->connect(true, $_POST['db_host'], $db_user, $db_pass, $db_name);
       
   329   // connected and database exists
       
   330   return true;
       
   331 }
       
   332 
       
   333 function stg_pgsql_connect($act_get = false)
       
   334 {
       
   335   global $db;
       
   336   $db = new postgresql();
       
   337   
       
   338   static $conn = false;
       
   339   if ( $act_get )
       
   340     return $conn;
       
   341   
       
   342   $db_user =& $_POST['db_user'];
       
   343   $db_pass =& $_POST['db_pass'];
       
   344   $db_name =& $_POST['db_name'];
       
   345   
       
   346   if ( !preg_match('/^[a-z0-9_-]+$/', $db_name) )
       
   347   {
       
   348     $db_name = htmlspecialchars($db_name);
       
   349     die("<p>SECURITY: malformed database name \"$db_name\"</p>");
       
   350   }
       
   351   
       
   352   // First, try to connect using the normal credentials
       
   353   $conn = @pg_connect("host={$_POST['db_host']} port=5432 user={$_POST['db_user']} password={$_POST['db_pass']}");
       
   354   if ( !$conn )
       
   355   {
       
   356     // Connection failed. Do we have the root username and password?
       
   357     if ( !empty($_POST['db_root_user']) && !empty($_POST['db_root_pass']) )
       
   358     {
       
   359       $conn_root = @pg_connect("host={$_POST['db_host']} port=5432 user={$_POST['db_root_user']} password={$_POST['db_root_pass']}");
       
   360       if ( !$conn_root )
       
   361       {
       
   362         // Couldn't connect using either set of credentials. Bail out.
       
   363         return false;
       
   364       }
       
   365       unset($db_user, $db_pass);
       
   366       $db_user = pg_escape_string($_POST['db_user']);
       
   367       $db_pass = pg_escape_string($_POST['db_pass']);
       
   368       // Create the user account
       
   369       $q = @pg_query("CREATE ROLE '$db_user' WITH NOSUPERUSER UNENCRYPTED PASSWORD '$db_pass';", $conn_root);
       
   370       if ( !$q )
       
   371       {
       
   372         return false;
       
   373       }
       
   374       pg_close($conn_root);
       
   375       $conn = @pg_connect("host={$_POST['db_host']} port=5432 user={$_POST['db_user']} password={$_POST['db_pass']}");
       
   376       if ( !$conn )
       
   377       {
       
   378         // This should honestly never happen.
       
   379         return false;
       
   380       }
       
   381     }
       
   382   }
       
   383   if ( !$q )
       
   384   {
       
   385     // access denied to the database; try the whole root schenanegan again
       
   386     if ( !empty($_POST['db_root_user']) && !empty($_POST['db_root_pass']) )
       
   387     {
       
   388       $conn_root = @pg_connect("host={$_POST['db_host']} port=5432 user={$_POST['db_root_user']} password={$_POST['db_root_pass']}");
       
   389       if ( !$conn_root )
       
   390       {
       
   391         // Couldn't connect as root; bail out
       
   392         return false;
       
   393       }
       
   394       unset($db_user, $db_pass);
       
   395       $db_user = pg_escape_string($_POST['db_user']);
       
   396       $db_pass = pg_escape_string($_POST['db_pass']);
       
   397       // create the database, if it doesn't exist
       
   398       $q = @mysql_query("CREATE DATABASE $db_name WITH OWNER $db_user;", $conn_root);
       
   399       if ( !$q )
       
   400       {
       
   401         // this really should never fail, so don't give any tolerance to it
       
   402         return false;
       
   403       }
       
   404       // Setting the owner to $db_user should grant all the rights we need
       
   405       pg_close($conn_root);
       
   406       // grant tables have hopefully been flushed, kill and reconnect our regular user connection
       
   407       pg_close($conn);
       
   408       $conn = @pg_connect("host={$_POST['db_host']} port=5432 user={$_POST['db_user']} password={$_POST['db_pass']}");
       
   409       if ( !$conn )
       
   410       {
       
   411         return false;
       
   412       }
       
   413     }
       
   414     else
       
   415     {
       
   416       return false;
       
   417     }
       
   418     // try again
       
   419     $q = @mysql_query("USE `$db_name`;", $conn);
       
   420     if ( !$q )
       
   421     {
       
   422       // really failed this time; bail out
       
   423       return false;
       
   424     }
       
   425   }
       
   426   // initialize DBAL
       
   427   $db->connect(true, $_POST['db_host'], $db_user, $db_pass, $db_name);
       
   428   // connected and database exists
       
   429   return true;
       
   430 }
       
   431 
       
   432 function stg_drop_tables()
       
   433 {
       
   434   global $db;
       
   435   // Our list of tables included in Enano
       
   436   $tables = Array( 'categories', 'comments', 'config', 'logs', 'page_text', 'session_keys', 'pages', 'users', 'users_extra', 'themes', 'buddies', 'banlist', 'files', 'privmsgs', 'sidebar', 'hits', 'search_index', 'groups', 'group_members', 'acl', 'tags', 'page_groups', 'page_group_members' );
       
   437   
       
   438   // Drop each table individually; if it fails, it probably means we're trying to drop a
       
   439   // table that didn't exist in the Enano version we're deleting the database for.
       
   440   foreach ( $tables as $table )
       
   441   {
       
   442     // Remember that table_prefix is sanitized.
       
   443     $table = "{$_POST['table_prefix']}$table";
       
   444     $db->sql_query("DROP TABLE $table;", $conn);
       
   445   }
       
   446   return true;
       
   447 }
       
   448 
       
   449 function stg_decrypt_admin_pass($act_get = false)
       
   450 {
       
   451   static $decrypted_pass = false;
       
   452   if ( $act_get )
       
   453     return $decrypted_pass;
       
   454   
       
   455   $aes = AESCrypt::singleton(AES_BITS, AES_BLOCKSIZE);
       
   456   
       
   457   if ( !empty($_POST['crypt_data']) )
       
   458   {
       
   459     require('config.new.php');
       
   460     if ( !isset($cryptkey) )
       
   461     {
       
   462       return false;
       
   463     }
       
   464     define('_INSTRESUME_AES_KEYBACKUP', $key);
       
   465     $key = hexdecode($cryptkey);
       
   466     
       
   467     $decrypted_pass = $aes->decrypt($_POST['crypt_data'], $key, ENC_HEX);
       
   468     
       
   469   }
       
   470   else
       
   471   {
       
   472     $decrypted_pass = $_POST['admin_pass'];
       
   473   }
       
   474   if ( empty($decrypted_pass) )
       
   475     return false;
       
   476   return true;
       
   477 }
       
   478 
       
   479 function stg_generate_aes_key($act_get = false)
       
   480 {
       
   481   static $key = false;
       
   482   if ( $act_get )
       
   483     return $key;
       
   484   
       
   485   $aes = AESCrypt::singleton(AES_BITS, AES_BLOCKSIZE);
       
   486   $key = $aes->gen_readymade_key();
       
   487   return true;
       
   488 }
       
   489 
       
   490 function stg_parse_schema($act_get = false)
       
   491 {
       
   492   static $schema;
       
   493   if ( $act_get )
       
   494     return $schema;
       
   495   
       
   496   global $db;
       
   497   
       
   498   $admin_pass = stg_decrypt_admin_pass(true);
       
   499   $key = stg_generate_aes_key(true);
       
   500   $aes = AESCrypt::singleton(AES_BITS, AES_BLOCKSIZE);
       
   501   $key = $aes->hextostring($key);
       
   502   $admin_pass = $aes->encrypt($admin_pass, $key, ENC_HEX);
       
   503   
       
   504   $cacheonoff = is_writable(ENANO_ROOT.'/cache/') ? '1' : '0';
       
   505   
       
   506   $admin_user = $_POST['admin_user'];
       
   507   $admin_user = str_replace('_', ' ', $admin_user);
       
   508   $admin_user = $db->escape($admin_user);
       
   509   
       
   510   switch ( $_POST['db_driver'] )
       
   511   {
       
   512     case 'mysql':
       
   513       $schema_file = 'schema.sql';
       
   514       break;
       
   515     case 'postgresql':
       
   516       $schema_file = 'schema-pg.sql';
       
   517       break;
       
   518   }
       
   519   
       
   520   if ( !isset($schema_file) )
       
   521     die('insanity');
       
   522   
       
   523   $schema = file_get_contents($schema_file);
       
   524   $schema = str_replace('{{SITE_NAME}}',    $db->escape($_POST['sitename']   ), $schema);
       
   525   $schema = str_replace('{{SITE_DESC}}',    $db->escape($_POST['sitedesc']   ), $schema);
       
   526   $schema = str_replace('{{COPYRIGHT}}',    $db->escape($_POST['copyright']  ), $schema);
       
   527   $schema = str_replace('{{ADMIN_USER}}',   $admin_user                                    , $schema);
       
   528   $schema = str_replace('{{ADMIN_PASS}}',   $db->escape($admin_pass          ), $schema);
       
   529   $schema = str_replace('{{ADMIN_EMAIL}}',  $db->escape($_POST['admin_email']), $schema);
       
   530   $schema = str_replace('{{ENABLE_CACHE}}', $db->escape($cacheonoff          ), $schema);
       
   531   $schema = str_replace('{{REAL_NAME}}',    '',                                              $schema);
       
   532   $schema = str_replace('{{TABLE_PREFIX}}', $_POST['table_prefix'],                          $schema);
       
   533   $schema = str_replace('{{VERSION}}',      ENANO_VERSION,                                   $schema);
       
   534   $schema = str_replace('{{ADMIN_EMBED_PHP}}', $_POST['admin_embed_php'],                    $schema);
       
   535   // Not anymore!! :-D
       
   536   // $schema = str_replace('{{BETA_VERSION}}', ENANO_BETA_VERSION,                              $schema);
       
   537   
       
   538   if(isset($_POST['wiki_mode']))
       
   539   {
       
   540     $schema = str_replace('{{WIKI_MODE}}', '1', $schema);
       
   541   }
       
   542   else
       
   543   {
       
   544     $schema = str_replace('{{WIKI_MODE}}', '0', $schema);
       
   545   }
       
   546   
       
   547   // Build an array of queries      
       
   548   $schema = explode("\n", $schema);
       
   549   
       
   550   foreach ( $schema as $i => $sql )
       
   551   {
       
   552     $query =& $schema[$i];
       
   553     $t = trim($query);
       
   554     if ( empty($t) || preg_match('/^(\#|--)/i', $t) )
       
   555     {
       
   556       unset($schema[$i]);
       
   557       unset($query);
       
   558     }
       
   559   }
       
   560   
       
   561   $schema = array_values($schema);
       
   562   $schema = implode("\n", $schema);
       
   563   $schema = explode(";\n", $schema);
       
   564   
       
   565   foreach ( $schema as $i => $sql )
       
   566   {
       
   567     $query =& $schema[$i];
       
   568     if ( substr($query, ( strlen($query) - 1 ), 1 ) != ';' )
       
   569     {
       
   570       $query .= ';';
       
   571     }
       
   572   }
       
   573   
       
   574   return true;
       
   575 }
       
   576 
       
   577 function stg_install($_unused, $already_run)
       
   578 {
       
   579   // This one's pretty easy.
       
   580   $conn = stg_mysql_connect(true);
       
   581   if ( !is_resource($conn) )
       
   582     return false;
       
   583   $schema = stg_parse_schema(true);
       
   584   if ( !is_array($schema) )
       
   585     return false;
       
   586   
       
   587   // If we're resuming installation, the encryption key was regenerated.
       
   588   // This means we'll have to update the encrypted password in the database.
       
   589   if ( $already_run )
       
   590   {
       
   591     $admin_pass = stg_decrypt_admin_pass(true);
       
   592     $key = stg_generate_aes_key(true);
       
   593     $aes = AESCrypt::singleton(AES_BITS, AES_BLOCKSIZE);
       
   594     $key = $aes->hextostring($key);
       
   595     $admin_pass = $aes->encrypt($admin_pass, $key, ENC_HEX);
       
   596     $admin_user = mysql_real_escape_string($_POST['admin_user']);
       
   597     $admin_user = str_replace('_', ' ', $admin_user);
       
   598     
       
   599     $q = @mysql_query("UPDATE {$_POST['table_prefix']}users SET password='$admin_pass' WHERE username='$admin_user';");
       
   600     if ( !$q )
       
   601     {
       
   602       echo '<p><tt>MySQL return: ' . mysql_error() . '</tt></p>';
       
   603       return false;
       
   604     }
       
   605     
       
   606     return true;
       
   607   }
       
   608   
       
   609   // OK, do the loop, baby!!!
       
   610   foreach($schema as $q)
       
   611   {
       
   612     $r = mysql_query($q, $conn);
       
   613     if ( !$r )
       
   614     {
       
   615       echo '<p><tt>MySQL return: ' . mysql_error() . '</tt></p>';
       
   616       return false;
       
   617     }
       
   618   }
       
   619   
       
   620   return true;
       
   621 }
       
   622 
       
   623 function stg_write_config()
       
   624 {
       
   625   $privkey = stg_generate_aes_key(true);
       
   626   
       
   627   switch($_POST['urlscheme'])
       
   628   {
       
   629     case "ugly":
       
   630     default:
       
   631       $cp = scriptPath.'/index.php?title=';
       
   632       break;
       
   633     case "short":
       
   634       $cp = scriptPath.'/index.php/';
       
   635       break;
       
   636     case "tiny":
       
   637       $cp = scriptPath.'/';
       
   638       break;
       
   639   }
       
   640   
       
   641   if ( $_POST['urlscheme'] == 'tiny' )
       
   642   {
       
   643     $contents = '# Begin Enano rules
       
   644 RewriteEngine on
       
   645 RewriteCond %{REQUEST_FILENAME} !-d
       
   646 RewriteCond %{REQUEST_FILENAME} !-f
       
   647 RewriteRule ^(.+) '.scriptPath.'/index.php?title=$1 [L,QSA]
       
   648 RewriteRule \.(php|html|gif|jpg|png|css|js)$ - [L]
       
   649 # End Enano rules
       
   650 ';
       
   651     if ( file_exists('./.htaccess') )
       
   652       $ht = fopen(ENANO_ROOT.'/.htaccess', 'a+');
       
   653     else
       
   654       $ht = fopen(ENANO_ROOT.'/.htaccess.new', 'w');
       
   655     if ( !$ht )
       
   656       return false;
       
   657     fwrite($ht, $contents);
       
   658     fclose($ht);
       
   659   }
       
   660 
       
   661   $config_file = '<?php
       
   662 /* Enano auto-generated configuration file - editing not recommended! */
       
   663 $dbhost   = \''.addslashes($_POST['db_host']).'\';
       
   664 $dbname   = \''.addslashes($_POST['db_name']).'\';
       
   665 $dbuser   = \''.addslashes($_POST['db_user']).'\';
       
   666 $dbpasswd = \''.addslashes($_POST['db_pass']).'\';
       
   667 if ( !defined(\'ENANO_CONSTANTS\') )
       
   668 {
       
   669 define(\'ENANO_CONSTANTS\', \'\');
       
   670 define(\'table_prefix\', \''.addslashes($_POST['table_prefix']).'\');
       
   671 define(\'scriptPath\', \''.scriptPath.'\');
       
   672 define(\'contentPath\', \''.$cp.'\');
       
   673 define(\'ENANO_INSTALLED\', \'true\');
       
   674 }
       
   675 $crypto_key = \''.$privkey.'\';
       
   676 ?>';
       
   677 
       
   678   $cf_handle = fopen(ENANO_ROOT.'/config.new.php', 'w');
       
   679   if ( !$cf_handle )
       
   680     return false;
       
   681   fwrite($cf_handle, $config_file);
       
   682   
       
   683   fclose($cf_handle);
       
   684   
       
   685   return true;
       
   686 }
       
   687 
       
   688 function _stg_rename_config_revert()
       
   689 {
       
   690   if ( file_exists('./config.php') )
       
   691   {
       
   692     @rename('./config.php', './config.new.php');
       
   693   }
       
   694   
       
   695   $handle = @fopen('./config.php.new', 'w');
       
   696   if ( !$handle )
       
   697     return false;
       
   698   $contents = '<?php $cryptkey = \'' . _INSTRESUME_AES_KEYBACKUP . '\'; ?>';
       
   699   fwrite($handle, $contents);
       
   700   fclose($handle);
       
   701   return true;
       
   702 }
       
   703 
       
   704 function stg_build_index()
       
   705 {
       
   706   global $db, $session, $paths, $template, $plugins; // Common objects;
       
   707   if ( $paths->rebuild_search_index() )
       
   708     return true;
       
   709   return false;
       
   710 }
       
   711 
       
   712 function stg_rename_config()
       
   713 {
       
   714   if ( !@rename('./config.new.php', './config.php') )
       
   715   {
       
   716     echo '<p>Can\'t rename config.php</p>';
       
   717     _stg_rename_config_revert();
       
   718     return false;
       
   719   }
       
   720   
       
   721   if ( $_POST['urlscheme'] == 'tiny' && !file_exists('./.htaccess') )
       
   722   {
       
   723     if ( !@rename('./.htaccess.new', './.htaccess') )
       
   724     {
       
   725       echo '<p>Can\'t rename .htaccess</p>';
       
   726       _stg_rename_config_revert();
       
   727       return false;
       
   728     }
       
   729   }
       
   730   return true;
       
   731 }
       
   732 
       
   733 function stg_start_api_success()
       
   734 {
       
   735   return true;
       
   736 }
       
   737 
       
   738 function stg_start_api_failure()
       
   739 {
       
   740   return false;
       
   741 }
       
   742 
       
   743 function stg_import_language()
       
   744 {
       
   745   global $db, $session, $paths, $template, $plugins; // Common objects
       
   746   
       
   747   $lang_file = ENANO_ROOT . "/language/english/enano.json";
       
   748   install_language("eng", "English", "English", $lang_file);
       
   749   
       
   750   return true;
       
   751 }
       
   752 
       
   753 function stg_init_logs()
       
   754 {
       
   755   global $db, $session, $paths, $template, $plugins; // Common objects
       
   756   
       
   757   $q = $db->sql_query('INSERT INTO ' . table_prefix . 'logs(log_type,action,time_id,date_string,author,page_text,edit_summary) VALUES(\'security\', \'install_enano\', ' . time() . ', \'' . enano_date('d M Y h:i a') . '\', \'' . mysql_real_escape_string($_POST['admin_user']) . '\', \'' . mysql_real_escape_string(ENANO_VERSION) . '\', \'' . mysql_real_escape_string($_SERVER['REMOTE_ADDR']) . '\');');
       
   758   if ( !$q )
       
   759   {
       
   760     echo '<p><tt>MySQL return: ' . mysql_error() . '</tt></p>';
       
   761     return false;
       
   762   }
       
   763   
       
   764   if ( !$session->get_permissions('clear_logs') )
       
   765   {
       
   766     echo '<p><tt>$session: denied clear_logs</tt></p>';
       
   767     return false;
       
   768   }
       
   769   
       
   770   PageUtils::flushlogs('Main_Page', 'Article');
       
   771   
       
   772   return true;
       
   773 }
       
   774 
       
   775 //die('Key size: ' . AES_BITS . '<br />Block size: ' . AES_BLOCKSIZE);
       
   776 
       
   777 if(!function_exists('wikiFormat'))
       
   778 {
       
   779   function wikiFormat($message, $filter_links = true)
       
   780   {
       
   781     $wiki = & Text_Wiki::singleton('Mediawiki');
       
   782     $wiki->setRenderConf('Xhtml', 'code', 'css_filename', 'codefilename');
       
   783     $wiki->setRenderConf('Xhtml', 'wikilink', 'view_url', contentPath);
       
   784     $result = $wiki->transform($message, 'Xhtml');
       
   785     
       
   786     // HTML fixes
       
   787     $result = preg_replace('#<tr>([\s]*?)<\/tr>#is', '', $result);
       
   788     $result = preg_replace('#<p>([\s]*?)<\/p>#is', '', $result);
       
   789     $result = preg_replace('#<br />([\s]*?)<table#is', '<table', $result);
       
   790     
       
   791     return $result;
       
   792   }
       
   793 }
       
   794 
       
   795 global $failed, $warned;
       
   796 
       
   797 $failed = false;
       
   798 $warned = false;
       
   799 
       
   800 function not($var)
       
   801 {
       
   802   if($var)
       
   803   {
       
   804     return false;
       
   805   } 
       
   806   else
       
   807   {
       
   808     return true;
       
   809   }
       
   810 }
       
   811 
       
   812 function run_test($code, $desc, $extended_desc, $warn = false)
       
   813 {
       
   814   global $failed, $warned;
       
   815   static $cv = true;
       
   816   $cv = not($cv);
       
   817   $val = eval($code);
       
   818   if($val)
       
   819   {
       
   820     if($cv) $color='CCFFCC'; else $color='AAFFAA';
       
   821     echo "<tr><td style='background-color: #$color; width: 500px; padding: 5px;'>$desc</td><td style='padding-left: 10px;'><img alt='Test passed' src='images/good.gif' /></td></tr>";
       
   822   } elseif(!$val && $warn) {
       
   823     if($cv) $color='FFFFCC'; else $color='FFFFAA';
       
   824     echo "<tr><td style='background-color: #$color; width: 500px; padding: 5px;'>$desc<br /><b>$extended_desc</b></td><td style='padding-left: 10px;'><img alt='Test passed with warning' src='images/unknown.gif' /></td></tr>";
       
   825     $warned = true;
       
   826   } else {
       
   827     if($cv) $color='FFCCCC'; else $color='FFAAAA';
       
   828     echo "<tr><td style='background-color: #$color; width: 500px; padding: 5px;'>$desc<br /><b>$extended_desc</b></td><td style='padding-left: 10px;'><img alt='Test failed' src='images/bad.gif' /></td></tr>";
       
   829     $failed = true;
       
   830   }
       
   831 }
       
   832 function is_apache() { $r = strstr($_SERVER['SERVER_SOFTWARE'], 'Apache') ? true : false; return $r; }
       
   833 
       
   834 function show_license($fb = false)
       
   835 {
       
   836   global $lang;
       
   837   ?>
       
   838   <div style="height: 500px; clip: rect(0px,auto,500px,auto); overflow: auto; padding: 10px; border: 1px dashed #456798; margin: 1em;">
       
   839   <?php
       
   840     if ( !file_exists('./GPL') || !file_exists('./language/english/install/license-deed.html') )
       
   841     {
       
   842       echo 'Cannot find the license files.';
       
   843     }
       
   844     echo file_get_contents('./language/english/install/license-deed.html');
       
   845     if ( defined('ENANO_BETA_VERSION') || $branch == 'unstable' )
       
   846     {
       
   847       ?>
       
   848       <h3><?php echo $lang->get('license_info_unstable_title'); ?></h3>
       
   849       <p><?php echo $lang->get('license_info_unstable_body'); ?></p>
       
   850       <?php
       
   851     }
       
   852     ?>
       
   853     <h3><?php echo $lang->get('license_section_gpl_heading'); ?></h3>
       
   854     <?php if ( $lang->lang_code != 'eng' ): ?>
       
   855     <p><i><?php echo $lang->get('license_gpl_blurb_inenglish'); ?></i></p>
       
   856     <?php endif; ?>
       
   857     <?php echo wikiFormat(file_get_contents(ENANO_ROOT . '/GPL')); ?>
       
   858    <?php
       
   859    global $template;
       
   860    if ( $fb )
       
   861    {
       
   862      echo '<p style="text-align: center;">Because I could never find the Create a Page button in PHP-Nuke.</p>';
       
   863      echo '<p>' . str_replace('http://enanocms.org/', 'http://www.2robots.com/2003/10/15/web-portals-suck/', $template->fading_button) . '</p>';
       
   864      echo '<p style="text-align: center;">It\'s not a portal, my friends.</p>';
       
   865    }
       
   866    ?>
       
   867  </div>
       
   868  <?php
       
   869 }
       
   870 
       
   871 require_once('includes/template.php');
       
   872 
       
   873 if(!isset($_GET['mode']))
       
   874 {
       
   875   $_GET['mode'] = 'welcome';
       
   876 }
       
   877 switch($_GET['mode'])
       
   878 {
       
   879   case 'mysql_test':
       
   880     error_reporting(0);
       
   881     $dbhost     = rawurldecode($_POST['host']);
       
   882     $dbname     = rawurldecode($_POST['name']);
       
   883     $dbuser     = rawurldecode($_POST['user']);
       
   884     $dbpass     = rawurldecode($_POST['pass']);
       
   885     $dbrootuser = rawurldecode($_POST['root_user']);
       
   886     $dbrootpass = rawurldecode($_POST['root_pass']);
       
   887     if($dbrootuser != '')
       
   888     {
       
   889       $conn = mysql_connect($dbhost, $dbrootuser, $dbrootpass);
       
   890       if(!$conn)
       
   891       {
       
   892         $e = mysql_error();
       
   893         if(strstr($e, "Lost connection"))
       
   894           die('host'.$e);
       
   895         else
       
   896           die('root'.$e);
       
   897       }
       
   898       $rsp = 'good';
       
   899       $q = mysql_query('USE `' . mysql_real_escape_string($dbname) . '`;', $conn);
       
   900       if(!$q)
       
   901       {
       
   902         $e = mysql_error();
       
   903         if(strstr($e, 'Unknown database'))
       
   904         {
       
   905           $rsp .= '_creating_db';
       
   906         }
       
   907       }
       
   908       mysql_close($conn);
       
   909       $conn = mysql_connect($dbhost, $dbuser, $dbpass);
       
   910       if(!$conn)
       
   911       {
       
   912         $e = mysql_error();
       
   913         if(strstr($e, "Lost connection"))
       
   914           die('host'.$e);
       
   915         else
       
   916           $rsp .= '_creating_user';
       
   917       }
       
   918       mysql_close($conn);
       
   919       die($rsp);
       
   920     }
       
   921     else
       
   922     {
       
   923       $conn = mysql_connect($dbhost, $dbuser, $dbpass);
       
   924       if(!$conn)
       
   925       {
       
   926         $e = mysql_error();
       
   927         if(strstr($e, "Lost connection"))
       
   928           die('host'.$e);
       
   929         else
       
   930           die('auth'.$e);
       
   931       }
       
   932       $q = mysql_query('USE `' . mysql_real_escape_string($dbname) . '`;', $conn);
       
   933       if(!$q)
       
   934       {
       
   935         $e = mysql_error();
       
   936         if(strstr($e, 'Unknown database'))
       
   937         {
       
   938           die('name'.$e);
       
   939         }
       
   940         else
       
   941         {
       
   942           die('perm'.$e);
       
   943         }
       
   944       }
       
   945     }
       
   946     $v = mysql_get_server_info();
       
   947     if(version_compare($v, '4.1.17', '<')) die('vers'.$v);
       
   948     mysql_close($conn);
       
   949     die('good');
       
   950     break;
       
   951   case 'pgsql_test':
       
   952     error_reporting(0);
       
   953     $dbhost     = rawurldecode($_POST['host']);
       
   954     $dbname     = rawurldecode($_POST['name']);
       
   955     $dbuser     = rawurldecode($_POST['user']);
       
   956     $dbpass     = rawurldecode($_POST['pass']);
       
   957     $dbrootuser = rawurldecode($_POST['root_user']);
       
   958     $dbrootpass = rawurldecode($_POST['root_pass']);
       
   959     if($dbrootuser != '')
       
   960     {
       
   961       $conn = @pg_connect("host=$dbhost port=5432 user=$dbuser password=$dbpass dbname=$dbname");
       
   962       if(!$conn)
       
   963       {
       
   964         $e = pg_last_error();
       
   965         if(strstr($e, "Lost connection"))
       
   966           die('host'.$e);
       
   967         else
       
   968           die('root'.$e);
       
   969       }
       
   970       $rsp = 'good';
       
   971       $q = mysql_query('USE `' . mysql_real_escape_string($dbname) . '`;', $conn);
       
   972       if(!$q)
       
   973       {
       
   974         $e = mysql_error();
       
   975         if(strstr($e, 'Unknown database'))
       
   976         {
       
   977           $rsp .= '_creating_db';
       
   978         }
       
   979       }
       
   980       mysql_close($conn);
       
   981       $conn = mysql_connect($dbhost, $dbuser, $dbpass);
       
   982       if(!$conn)
       
   983       {
       
   984         $e = mysql_error();
       
   985         if(strstr($e, "Lost connection"))
       
   986           die('host'.$e);
       
   987         else
       
   988           $rsp .= '_creating_user';
       
   989       }
       
   990       mysql_close($conn);
       
   991       die($rsp);
       
   992     }
       
   993     else
       
   994     {
       
   995       $conn = mysql_connect($dbhost, $dbuser, $dbpass);
       
   996       if(!$conn)
       
   997       {
       
   998         $e = mysql_error();
       
   999         if(strstr($e, "Lost connection"))
       
  1000           die('host'.$e);
       
  1001         else
       
  1002           die('auth'.$e);
       
  1003       }
       
  1004       $q = mysql_query('USE `' . mysql_real_escape_string($dbname) . '`;', $conn);
       
  1005       if(!$q)
       
  1006       {
       
  1007         $e = mysql_error();
       
  1008         if(strstr($e, 'Unknown database'))
       
  1009         {
       
  1010           die('name'.$e);
       
  1011         }
       
  1012         else
       
  1013         {
       
  1014           die('perm'.$e);
       
  1015         }
       
  1016       }
       
  1017     }
       
  1018     $v = mysql_get_server_info();
       
  1019     if(version_compare($v, '4.1.17', '<')) die('vers'.$v);
       
  1020     mysql_close($conn);
       
  1021     die('good');
       
  1022     break;  
       
  1023   case 'pophelp':
       
  1024     $topic = ( isset($_GET['topic']) ) ? $_GET['topic'] : 'invalid';
       
  1025     switch($topic)
       
  1026     {
       
  1027       case 'admin_embed_php':
       
  1028         $title = $lang->get('pophelp_admin_embed_php_title');
       
  1029         $content = $lang->get('pophelp_admin_embed_php_body');
       
  1030         break;
       
  1031       case 'url_schemes':
       
  1032         $title = $lang->get('pophelp_url_schemes_title');
       
  1033         $content = $lang->get('pophelp_url_schemes_body');
       
  1034         break;
       
  1035       default:
       
  1036         $title = 'Invalid topic';
       
  1037         $content = 'Invalid help topic.';
       
  1038         break;
       
  1039     }
       
  1040     $close_window = $lang->get('pophelp_btn_close_window');
       
  1041     echo <<<EOF
       
  1042 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
       
  1043 <html>
       
  1044   <head>
       
  1045     <title>Enano installation quick help &bull; {$title}</title>
       
  1046     <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
       
  1047     <style type="text/css">
       
  1048       body {
       
  1049         font-family: trebuchet ms, verdana, arial, helvetica, sans-serif;
       
  1050         font-size: 9pt;
       
  1051       }
       
  1052       h2          { border-bottom: 1px solid #90B0D0; margin-bottom: 0; }
       
  1053       h3          { font-size: 11pt; font-weight: bold; }
       
  1054       li          { list-style: url(../images/bullet.gif); }
       
  1055       p           { margin: 1.0em; }
       
  1056       blockquote  { background-color: #F4F4F4; border: 1px dotted #406080; margin: 1em; padding: 10px; max-height: 250px; overflow: auto; }
       
  1057       a           { color: #7090B0; }
       
  1058       a:hover     { color: #90B0D0; }
       
  1059     </style>
       
  1060   </head>
       
  1061   <body>
       
  1062     <h2>{$title}</h2>
       
  1063     {$content}
       
  1064     <p style="text-align: right;">
       
  1065       <a href="#" onclick="window.close(); return false;">{$close_window}</a>
       
  1066     </p>
       
  1067   </body>
       
  1068 </html>
       
  1069 EOF;
       
  1070     exit;
       
  1071     break;
       
  1072   case 'langjs':
       
  1073     header('Content-type: text/javascript');
       
  1074     $lang_js = enano_json_encode($lang->strings);
       
  1075     // use EEOF here because jEdit misinterprets "typ'eof'"
       
  1076     echo <<<EEOF
       
  1077 if ( typeof(enano_lang) != 'object' )
       
  1078   var enano_lang = new Object();
       
  1079 
       
  1080 enano_lang[1] = $lang_js;
       
  1081 
       
  1082 EEOF;
       
  1083     exit;
       
  1084     break;
       
  1085   default:
       
  1086     break;
       
  1087 }
       
  1088 
       
  1089 $template = new template_nodb();
       
  1090 $template->load_theme('stpatty', 'shamrock', false);
       
  1091 
       
  1092 $modestrings = Array(
       
  1093               'welcome' => $lang->get('welcome_modetitle'),
       
  1094               'license' => $lang->get('license_modetitle'),
       
  1095               'sysreqs' => $lang->get('sysreqs_modetitle'),
       
  1096               'database' => $lang->get('database_modetitle'),
       
  1097               'database_mysql'=> $lang->get('database_mysql_modetitle'),
       
  1098               'database_pgsql'=> $lang->get('database_pgsql_modetitle'),
       
  1099               'website' => $lang->get('website_modetitle'), 
       
  1100               'login'   => $lang->get('login_modetitle'),
       
  1101               'confirm' => $lang->get('confirm_modetitle'),
       
  1102               'install' => $lang->get('install_modetitle'),
       
  1103               'finish'  => $lang->get('finish_modetitle'),
       
  1104               '_hiddenstages' => '...', // all stages below this line are hidden
       
  1105               'showlicense' => $lang->get('license_modetitle')
       
  1106             );
       
  1107 
       
  1108 $sideinfo = '';
       
  1109 $vars = $template->extract_vars('elements.tpl');
       
  1110 $p = $template->makeParserText($vars['sidebar_button']);
       
  1111 $hidden = false;
       
  1112 foreach ( $modestrings as $id => $str )
       
  1113 {
       
  1114   if ( $_GET['mode'] == $id )
       
  1115   {
       
  1116     $flags = 'style="font-weight: bold; text-decoration: underline;"';
       
  1117     $this_page = $str;
       
  1118   }
       
  1119   else
       
  1120   {
       
  1121     $flags = '';
       
  1122   }
       
  1123   if ( $id == '_hiddenstages' )
       
  1124     $hidden = true;
       
  1125   if ( !$hidden )
       
  1126   {
       
  1127     $p->assign_vars(Array(
       
  1128         'HREF' => '#',
       
  1129         'FLAGS' => $flags . ' onclick="return false;"',
       
  1130         'TEXT' => $str
       
  1131       ));
       
  1132     $sideinfo .= $p->run();
       
  1133   }
       
  1134 }
       
  1135 
       
  1136 $template->init_vars();
       
  1137 
       
  1138 if(isset($_GET['mode']) && $_GET['mode'] == 'css')
       
  1139 {
       
  1140   header('Content-type: text/css');
       
  1141   echo $template->get_css();
       
  1142   exit;
       
  1143 }
       
  1144 
       
  1145 if ( defined('ENANO_IS_STABLE') )
       
  1146   $branch = 'stable';
       
  1147 else if ( defined('ENANO_IS_UNSTABLE') )
       
  1148   $branch = 'unstable';
       
  1149 else
       
  1150 {
       
  1151   $version = explode('.', ENANO_VERSION);
       
  1152   if ( !isset($version[1]) )
       
  1153     // unknown branch, really
       
  1154     $branch = 'unstable';
       
  1155   else
       
  1156   {
       
  1157     $version[1] = intval($version[1]);
       
  1158     if ( $version[1] % 2 == 1 )
       
  1159       $branch = 'unstable';
       
  1160     else
       
  1161       $branch = 'stable';
       
  1162   }
       
  1163 }
       
  1164 
       
  1165 $template->header();
       
  1166 
       
  1167 switch($_GET['mode'])
       
  1168 { 
       
  1169   default:
       
  1170   case 'welcome':
       
  1171     ?>
       
  1172     <div style="text-align: center; margin-top: 10px;">
       
  1173       <img alt="[ Enano CMS Project logo ]" src="images/enano-artwork/installer-greeting-green.png" style="display: block; margin: 0 auto; padding-left: 100px;" />
       
  1174       <h2><?php echo $lang->get('welcome_heading'); ?></h2>
       
  1175       <h3>
       
  1176         <?php
       
  1177         $branch_l = $lang->get("welcome_branch_$branch");
       
  1178         
       
  1179         $v_string = sprintf('%s %s &ndash; %s', $lang->get('welcome_version'), ENANO_VERSION, $branch_l);
       
  1180         echo $v_string;
       
  1181         ?>
       
  1182       </h3>
       
  1183       <?php
       
  1184         if ( defined('ENANO_CODE_NAME') )
       
  1185         {
       
  1186           echo '<p>';
       
  1187           echo $lang->get('welcome_aka', array(
       
  1188               'codename' => strtolower(ENANO_CODE_NAME)
       
  1189             ));
       
  1190           echo '</p>';
       
  1191         }
       
  1192       ?>
       
  1193       <form action="install.php?mode=license" method="post">
       
  1194         <input type="submit" value="<?php echo $lang->get('welcome_btn_start'); ?>" />
       
  1195       </form>
       
  1196     </div>
       
  1197     <?php
       
  1198     break;
       
  1199   case "license":
       
  1200     ?>
       
  1201     <h3><?php echo $lang->get('license_heading'); ?></h3>
       
  1202      <p><?php echo $lang->get('license_blurb_thankyou'); ?></p>
       
  1203      <p><?php echo $lang->get('license_blurb_pleaseread'); ?></p>
       
  1204      <?php show_license(); ?>
       
  1205      <div class="pagenav">
       
  1206        <form action="install.php?mode=sysreqs" method="post">
       
  1207          <table border="0">
       
  1208          <tr>
       
  1209            <td>
       
  1210              <input type="submit" value="<?php echo $lang->get('license_btn_i_agree'); ?>" />
       
  1211            </td>
       
  1212            <td>
       
  1213              <p>
       
  1214                <span style="font-weight: bold;"><?php echo $lang->get('meta_lbl_before_continue'); ?></span><br />
       
  1215                &bull; <?php echo $lang->get('license_objective_ensure_agree'); ?><br />
       
  1216                &bull; <?php echo $lang->get('license_objective_have_db_info'); ?>
       
  1217              </p>
       
  1218            </td>
       
  1219          </tr>
       
  1220          </table>
       
  1221        </form>
       
  1222      </div>
       
  1223     <?php
       
  1224     break;
       
  1225   case "sysreqs":
       
  1226     error_reporting(E_ALL);
       
  1227     ?>
       
  1228     <h3><?php echo $lang->get('sysreqs_heading'); ?></h3>
       
  1229      <p><?php echo $lang->get('sysreqs_blurb'); ?></p>
       
  1230     <table border="0" cellspacing="0" cellpadding="0">
       
  1231     <?php
       
  1232     run_test('return version_compare(\'4.3.0\', PHP_VERSION, \'<\');', $lang->get('sysreqs_req_php'), $lang->get('sysreqs_req_desc_php') );
       
  1233     run_test('return version_compare(\'5.2.0\', PHP_VERSION, \'<\');', $lang->get('sysreqs_req_php5'), $lang->get('sysreqs_req_desc_php5'), true);
       
  1234     run_test('return function_exists(\'mysql_connect\');', $lang->get('sysreqs_req_mysql'), $lang->get('sysreqs_req_desc_mysql') );
       
  1235     run_test('return function_exists(\'pg_connect\');', 'PostgreSQL extension for PHP', 'It seems that your PHP installation does not have the PostgreSQL extension enabled. Because of this, you won\'t be able to use the PostgreSQL database driver. This is OK in the majority of cases. If you want to use PostgreSQL support, you\'ll need to either compile the PHP extension for Postgres or install the extension with your distribution\'s package manager. Windows administrators will need enable php_pgsql.dll in their php.ini.', true);
       
  1236     run_test('return @ini_get(\'file_uploads\');', $lang->get('sysreqs_req_uploads'), $lang->get('sysreqs_req_desc_uploads') );
       
  1237     run_test('return is_apache();', $lang->get('sysreqs_req_apache'), $lang->get('sysreqs_req_desc_apache'), true);
       
  1238     run_test('return is_writable(ENANO_ROOT.\'/config.new.php\');', $lang->get('sysreqs_req_config'), $lang->get('sysreqs_req_desc_config') );
       
  1239     run_test('return file_exists(\'/usr/bin/convert\');', $lang->get('sysreqs_req_magick'), $lang->get('sysreqs_req_desc_magick'), true);
       
  1240     run_test('return is_writable(ENANO_ROOT.\'/cache/\');', $lang->get('sysreqs_req_cachewriteable'), $lang->get('sysreqs_req_desc_cachewriteable'), true);
       
  1241     run_test('return is_writable(ENANO_ROOT.\'/files/\');', $lang->get('sysreqs_req_fileswriteable'), $lang->get('sysreqs_req_desc_fileswriteable'), true);
       
  1242     if ( !function_exists('mysql_connect') && !function_exists('pg_connect') )
       
  1243     {
       
  1244       run_test('return false;', 'No database drivers are available.', 'You need to have at least one database driver working to install Enano. See the warnings on MySQL and PostgreSQL above for more information on installing these database drivers.', false);
       
  1245     }
       
  1246     echo '</table>';
       
  1247     if(!$failed)
       
  1248     {
       
  1249       ?>
       
  1250       
       
  1251       <div class="pagenav">
       
  1252       <?php
       
  1253       if($warned) {
       
  1254         echo '<table border="0" cellspacing="0" cellpadding="0">';
       
  1255         run_test('return false;', $lang->get('sysreqs_summary_warn_title'), $lang->get('sysreqs_summary_warn_body'), true);
       
  1256         echo '</table>';
       
  1257       } else {
       
  1258         echo '<table border="0" cellspacing="0" cellpadding="0">';
       
  1259         run_test('return true;', '<b>' . $lang->get('sysreqs_summary_success_title') . '</b><br />' . $lang->get('sysreqs_summary_success_body'), 'You should never see this text. Congratulations for being an Enano hacker!');
       
  1260         echo '</table>';
       
  1261       }
       
  1262       ?>
       
  1263       <form action="install.php?mode=database" method="post">
       
  1264         <table border="0">
       
  1265         <tr>
       
  1266           <td>
       
  1267             <input type="submit" value="<?php echo $lang->get('meta_btn_continue'); ?>" />
       
  1268           </td>
       
  1269           <td>
       
  1270             <p>
       
  1271               <span style="font-weight: bold;"><?php echo $lang->get('meta_lbl_before_continue'); ?></span><br />
       
  1272               &bull; <?php echo $lang->get('sysreqs_objective_scalebacks'); ?><br />
       
  1273               &bull; <?php echo $lang->get('license_objective_have_db_info'); ?>
       
  1274             </p>
       
  1275           </td>
       
  1276         </tr>
       
  1277         </table>
       
  1278       </form>
       
  1279       </div>
       
  1280     <?php
       
  1281     }
       
  1282     else
       
  1283     {
       
  1284       if ( $failed )
       
  1285       {
       
  1286         echo '<div class="pagenav"><table border="0" cellspacing="0" cellpadding="0">';
       
  1287         run_test('return false;', $lang->get('sysreqs_summary_fail_title'), $lang->get('sysreqs_summary_fail_body'));
       
  1288         echo '</table></div>';
       
  1289       }
       
  1290     }
       
  1291     ?>
       
  1292     <?php
       
  1293     break;
       
  1294   case "database":
       
  1295     echo '<h3>Choose a database driver</h3>';
       
  1296     echo '<p>The next step is to choose the database driver that Enano will use. In most cases this is MySQL, but there are certain
       
  1297              advantages to PostgreSQL, which is made available only experimentally.</p>';
       
  1298     if ( @file_exists('/etc/enano-is-virt-appliance') )
       
  1299     {
       
  1300       echo '<p><b>You\'re using the Enano virtual appliance.</b><br />Unless you configured the appliance manually, PostgreSQL support is not available. In 99% of cases you\'ll want to click MySQL below.</p>';
       
  1301     }
       
  1302     
       
  1303     $mysql_disable_reason = '';
       
  1304     $pgsql_disable_reason = '';
       
  1305     $mysql_disable = '';
       
  1306     $pgsql_disable = '';
       
  1307     if ( !function_exists('mysql_connect') )
       
  1308     {
       
  1309       $mysql_disable = ' disabled="disabled"';
       
  1310       $mysql_disable_reason = 'You don\'t have the MySQL PHP extension installed.';
       
  1311     }
       
  1312     if ( !function_exists('pg_connect') )
       
  1313     {
       
  1314       $pgsql_disable = ' disabled="disabled"';
       
  1315       $pgsql_disable_reason = 'You don\'t have the PostgreSQL PHP extensnion installed.';
       
  1316     }
       
  1317     if ( function_exists('pg_connect') && version_compare(PHP_VERSION, '5.0.0', '<') )
       
  1318     {
       
  1319       $pgsql_disable = ' disabled="disabled"';
       
  1320       $pgsql_disable_reason = 'You need to have at least PHP 5 to use the PostgreSQL database driver.';
       
  1321     }
       
  1322     
       
  1323     echo '<form action="install.php" method="get">';
       
  1324     ?>
       
  1325     <table border="0" cellspacing="5">
       
  1326       <tr>
       
  1327         <td>
       
  1328           <input type="image" name="mode" value="database_mysql" src="images/about-powered-mysql.png"<?php echo $mysql_disable; ?>/>
       
  1329         </td>
       
  1330         <td<?php if ( $mysql_disable ) echo ' style="opacity: 0.5; filter: alpha(opacity=50);"'; ?>>
       
  1331           <b>MySQL</b><br />
       
  1332           Click this button to use MySQL as the database backend for your site. Most web hosts support MySQL, and if you have
       
  1333           administrative access to your MySQL server, you can create a new database and user during this installation process if you
       
  1334           haven't done so already.
       
  1335           <?php
       
  1336           if ( $mysql_disable )
       
  1337           {
       
  1338             echo "<br /><br /><b>$mysql_disable_reason</b>";
       
  1339           }
       
  1340           ?>
       
  1341         </td>
       
  1342       </tr>
       
  1343       <tr>
       
  1344         <td>
       
  1345           <input type="image" name="mode" value="database_pgsql" src="images/about-powered-pgsql.png"<?php echo $pgsql_disable; ?> />
       
  1346         </td>
       
  1347         <td<?php if ( $pgsql_disable ) echo ' style="opacity: 0.5; filter: alpha(opacity=50);"'; ?>>
       
  1348           <b>PostgreSQL</b><br />
       
  1349           Click this button to use PostgreSQL as the database backend for your site. While not as widely supported, PostgreSQL has more
       
  1350           liberal licensing conditions and when properly configured is faster than MySQL. Some plugins may not work with the PostgreSQL
       
  1351           driver.
       
  1352           <?php
       
  1353           if ( $pgsql_disable )
       
  1354           {
       
  1355             echo "<br /><br /><b>$pgsql_disable_reason</b>";
       
  1356           }
       
  1357           ?>
       
  1358         </td>
       
  1359       </tr>
       
  1360     </table>
       
  1361     <?php
       
  1362     echo '</form>';
       
  1363     break;
       
  1364   case "database_mysql":
       
  1365     ?>
       
  1366     <script type="text/javascript">
       
  1367       function ajaxGet(uri, f) {
       
  1368         if (window.XMLHttpRequest) {
       
  1369           ajax = new XMLHttpRequest();
       
  1370         } else {
       
  1371           if (window.ActiveXObject) {           
       
  1372             ajax = new ActiveXObject("Microsoft.XMLHTTP");
       
  1373           } else {
       
  1374             alert('Enano client-side runtime error: No AJAX support, unable to continue');
       
  1375             return;
       
  1376           }
       
  1377         }
       
  1378         ajax.onreadystatechange = f;
       
  1379         ajax.open('GET', uri, true);
       
  1380         ajax.send(null);
       
  1381       }
       
  1382       
       
  1383       function ajaxPost(uri, parms, f) {
       
  1384         if (window.XMLHttpRequest) {
       
  1385           ajax = new XMLHttpRequest();
       
  1386         } else {
       
  1387           if (window.ActiveXObject) {           
       
  1388             ajax = new ActiveXObject("Microsoft.XMLHTTP");
       
  1389           } else {
       
  1390             alert('Enano client-side runtime error: No AJAX support, unable to continue');
       
  1391             return;
       
  1392           }
       
  1393         }
       
  1394         ajax.onreadystatechange = f;
       
  1395         ajax.open('POST', uri, true);
       
  1396         ajax.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
       
  1397         ajax.setRequestHeader("Content-length", parms.length);
       
  1398         ajax.setRequestHeader("Connection", "close");
       
  1399         ajax.send(parms);
       
  1400       }
       
  1401       function ajaxTestConnection()
       
  1402       {
       
  1403         v = verify();
       
  1404         if(!v)
       
  1405         {
       
  1406           alert($lang.get('meta_msg_err_verification'));
       
  1407           return false;
       
  1408         }
       
  1409         var frm = document.forms.dbinfo;
       
  1410         db_host      = escape(frm.db_host.value.replace('+', '%2B'));
       
  1411         db_name      = escape(frm.db_name.value.replace('+', '%2B'));
       
  1412         db_user      = escape(frm.db_user.value.replace('+', '%2B'));
       
  1413         db_pass      = escape(frm.db_pass.value.replace('+', '%2B'));
       
  1414         db_root_user = escape(frm.db_root_user.value.replace('+', '%2B'));
       
  1415         db_root_pass = escape(frm.db_root_pass.value.replace('+', '%2B'));
       
  1416         
       
  1417         parms = 'host='+db_host+'&name='+db_name+'&user='+db_user+'&pass='+db_pass+'&root_user='+db_root_user+'&root_pass='+db_root_pass;
       
  1418         ajaxPost('<?php echo scriptPath; ?>/install.php?mode=mysql_test', parms, function() {
       
  1419             if(ajax.readyState==4)
       
  1420             {
       
  1421               s = ajax.responseText.substr(0, 4);
       
  1422               t = ajax.responseText.substr(4, ajax.responseText.length);
       
  1423               if(s.substr(0, 4)=='good')
       
  1424               {
       
  1425                 document.getElementById('s_db_host').src='images/good.gif';
       
  1426                 document.getElementById('s_db_name').src='images/good.gif';
       
  1427                 document.getElementById('s_db_auth').src='images/good.gif';
       
  1428                 document.getElementById('s_db_root').src='images/good.gif';
       
  1429                 if(t.match(/_creating_db/)) document.getElementById('e_db_name').innerHTML = $lang.get('database_msg_warn_creating_db');
       
  1430                 if(t.match(/_creating_user/)) document.getElementById('e_db_auth').innerHTML = $lang.get('database_msg_warn_creating_user');
       
  1431                 document.getElementById('s_mysql_version').src='images/good.gif';
       
  1432                 document.getElementById('e_mysql_version').innerHTML = $lang.get('database_msg_info_mysql_good');
       
  1433               }
       
  1434               else
       
  1435               {
       
  1436                 switch(s)
       
  1437                 {
       
  1438                 case 'host':
       
  1439                   document.getElementById('s_db_host').src='images/bad.gif';
       
  1440                   document.getElementById('s_db_name').src='images/unknown.gif';
       
  1441                   document.getElementById('s_db_auth').src='images/unknown.gif';
       
  1442                   document.getElementById('s_db_root').src='images/unknown.gif';
       
  1443                   document.getElementById('e_db_host').innerHTML = $lang.get('database_msg_err_mysql_connect', { db_host: document.forms.dbinfo.db_host.value, mysql_error: t });
       
  1444                   document.getElementById('e_mysql_version').innerHTML = $lang.get('database_msg_warn_mysql_version');
       
  1445                   break;
       
  1446                 case 'auth':
       
  1447                   document.getElementById('s_db_host').src='images/good.gif';
       
  1448                   document.getElementById('s_db_name').src='images/unknown.gif';
       
  1449                   document.getElementById('s_db_auth').src='images/bad.gif';
       
  1450                   document.getElementById('s_db_root').src='images/unknown.gif';
       
  1451                   document.getElementById('e_db_auth').innerHTML = $lang.get('database_msg_err_mysql_auth', { mysql_error: t });
       
  1452                   document.getElementById('e_mysql_version').innerHTML = $lang.get('database_msg_warn_mysql_version');
       
  1453                   break;
       
  1454                 case 'perm':
       
  1455                   document.getElementById('s_db_host').src='images/good.gif';
       
  1456                   document.getElementById('s_db_name').src='images/bad.gif';
       
  1457                   document.getElementById('s_db_auth').src='images/good.gif';
       
  1458                   document.getElementById('s_db_root').src='images/unknown.gif';
       
  1459                   document.getElementById('e_db_name').innerHTML = $lang.get('database_msg_err_mysql_dbperm', { mysql_error: t });
       
  1460                   document.getElementById('e_mysql_version').innerHTML = $lang.get('database_msg_warn_mysql_version');
       
  1461                   break;
       
  1462                 case 'name':
       
  1463                   document.getElementById('s_db_host').src='images/good.gif';
       
  1464                   document.getElementById('s_db_name').src='images/bad.gif';
       
  1465                   document.getElementById('s_db_auth').src='images/good.gif';
       
  1466                   document.getElementById('s_db_root').src='images/unknown.gif';
       
  1467                   document.getElementById('e_db_name').innerHTML = $lang.get('database_msg_err_mysql_dbexist', { mysql_error: t });
       
  1468                   document.getElementById('e_mysql_version').innerHTML = $lang.get('database_msg_warn_mysql_version');
       
  1469                   break;
       
  1470                 case 'root':
       
  1471                   document.getElementById('s_db_host').src='images/good.gif';
       
  1472                   document.getElementById('s_db_name').src='images/unknown.gif';
       
  1473                   document.getElementById('s_db_auth').src='images/unknown.gif';
       
  1474                   document.getElementById('s_db_root').src='images/bad.gif';
       
  1475                   document.getElementById('e_db_root').innerHTML = $lang.get('database_msg_err_mysql_auth', { mysql_error: t });
       
  1476                   document.getElementById('e_mysql_version').innerHTML = $lang.get('database_msg_warn_mysql_version');
       
  1477                   break;
       
  1478                 case 'vers':
       
  1479                   document.getElementById('s_db_host').src='images/good.gif';
       
  1480                   document.getElementById('s_db_name').src='images/good.gif';
       
  1481                   document.getElementById('s_db_auth').src='images/good.gif';
       
  1482                   document.getElementById('s_db_root').src='images/good.gif';
       
  1483                   if(t.match(/_creating_db/)) document.getElementById('e_db_name').innerHTML = $lang.get('database_msg_warn_creating_db');
       
  1484                   if(t.match(/_creating_user/)) document.getElementById('e_db_auth').innerHTML = $lang.get('database_msg_warn_creating_user');
       
  1485                   
       
  1486                   document.getElementById('e_mysql_version').innerHTML = $lang.get('database_msg_err_mysql_version', { mysql_version: t });
       
  1487                   document.getElementById('s_mysql_version').src='images/bad.gif';
       
  1488                 default:
       
  1489                   alert(t);
       
  1490                   break;
       
  1491                 }
       
  1492               }
       
  1493             }
       
  1494           });
       
  1495       }
       
  1496       function verify()
       
  1497       {
       
  1498         document.getElementById('e_db_host').innerHTML = '';
       
  1499         document.getElementById('e_db_auth').innerHTML = '';
       
  1500         document.getElementById('e_db_name').innerHTML = '';
       
  1501         document.getElementById('e_db_root').innerHTML = '';
       
  1502         var frm = document.forms.dbinfo;
       
  1503         ret = true;
       
  1504         if(frm.db_host.value != '')
       
  1505         {
       
  1506           document.getElementById('s_db_host').src='images/unknown.gif';
       
  1507         }
       
  1508         else
       
  1509         {
       
  1510           document.getElementById('s_db_host').src='images/bad.gif';
       
  1511           ret = false;
       
  1512         }
       
  1513         if(frm.db_name.value.match(/^([a-z0-9_-]+)$/g))
       
  1514         {
       
  1515           document.getElementById('s_db_name').src='images/unknown.gif';
       
  1516         }
       
  1517         else
       
  1518         {
       
  1519           document.getElementById('s_db_name').src='images/bad.gif';
       
  1520           ret = false;
       
  1521         }
       
  1522         if(frm.db_user.value != '')
       
  1523         {
       
  1524           document.getElementById('s_db_auth').src='images/unknown.gif';
       
  1525         }
       
  1526         else
       
  1527         {
       
  1528           document.getElementById('s_db_auth').src='images/bad.gif';
       
  1529           ret = false;
       
  1530         }
       
  1531         if(frm.table_prefix.value.match(/^([a-z0-9_]*)$/g))
       
  1532         {
       
  1533           document.getElementById('s_table_prefix').src='images/good.gif';
       
  1534         }
       
  1535         else
       
  1536         {
       
  1537           document.getElementById('s_table_prefix').src='images/bad.gif';
       
  1538           ret = false;
       
  1539         }
       
  1540         if(frm.db_root_user.value == '')
       
  1541         {
       
  1542           document.getElementById('s_db_root').src='images/good.gif';
       
  1543         }
       
  1544         else if(frm.db_root_user.value != '' && frm.db_root_pass.value == '')
       
  1545         {
       
  1546           document.getElementById('s_db_root').src='images/bad.gif';
       
  1547           ret = false;
       
  1548         }
       
  1549         else
       
  1550         {
       
  1551           document.getElementById('s_db_root').src='images/unknown.gif';
       
  1552         }
       
  1553         if(ret) frm._cont.disabled = false;
       
  1554         else    frm._cont.disabled = true;
       
  1555         return ret;
       
  1556       }
       
  1557       window.onload = verify;
       
  1558     </script>
       
  1559     <p><?php echo $lang->get('database_blurb_needdb'); ?></p>
       
  1560     <p><?php echo $lang->get('database_blurb_howtomysql'); ?></p>
       
  1561     <?php
       
  1562     if ( file_exists('/etc/enano-is-virt-appliance') )
       
  1563     {
       
  1564       echo '<p>
       
  1565               ' . $lang->get('database_vm_login_info', array( 'host' => 'localhost', 'user' => 'enano', 'pass' => 'clurichaun', 'name' => 'enano_www1' )) . '
       
  1566             </p>';
       
  1567     }
       
  1568     ?>
       
  1569     <form name="dbinfo" action="install.php?mode=website" method="post">
       
  1570       <input type="hidden" name="db_driver" value="mysql" />
       
  1571       <table border="0">
       
  1572         <tr>
       
  1573           <td colspan="3" style="text-align: center">
       
  1574             <h3><?php echo $lang->get('database_table_title'); ?></h3>
       
  1575           </td>
       
  1576         </tr>
       
  1577         <tr>
       
  1578           <td>
       
  1579             <b><?php echo $lang->get('database_field_hostname_title'); ?></b>
       
  1580             <br /><?php echo $lang->get('database_field_hostname_body'); ?>
       
  1581             <br /><span style="color: #993300" id="e_db_host"></span>
       
  1582           </td>
       
  1583           <td>
       
  1584             <input onkeyup="verify();" name="db_host" size="30" type="text" />
       
  1585           </td>
       
  1586           <td>
       
  1587             <img id="s_db_host" alt="Good/bad icon" src="images/bad.gif" />
       
  1588           </td>
       
  1589         </tr>
       
  1590         <tr>
       
  1591           <td>
       
  1592             <b><?php echo $lang->get('database_field_dbname_title'); ?></b><br />
       
  1593             <?php echo $lang->get('database_field_dbname_body'); ?><br />
       
  1594             <span style="color: #993300" id="e_db_name"></span>
       
  1595           </td>
       
  1596           <td>
       
  1597             <input onkeyup="verify();" name="db_name" size="30" type="text" />
       
  1598           </td>
       
  1599           <td>
       
  1600             <img id="s_db_name" alt="Good/bad icon" src="images/bad.gif" />
       
  1601           </td>
       
  1602         </tr>
       
  1603         <tr>
       
  1604           <td rowspan="2">
       
  1605             <b><?php echo $lang->get('database_field_dbauth_title'); ?></b><br />
       
  1606             <?php echo $lang->get('database_field_dbauth_body'); ?><br />
       
  1607             <span style="color: #993300" id="e_db_auth"></span>
       
  1608           </td>
       
  1609           <td>
       
  1610             <input onkeyup="verify();" name="db_user" size="30" type="text" />
       
  1611           </td>
       
  1612           <td rowspan="2">
       
  1613             <img id="s_db_auth" alt="Good/bad icon" src="images/bad.gif" />
       
  1614           </td>
       
  1615         </tr>
       
  1616         <tr>
       
  1617           <td>
       
  1618             <input name="db_pass" size="30" type="password" />
       
  1619           </td>
       
  1620         </tr>
       
  1621         <tr>
       
  1622           <td colspan="3" style="text-align: center">
       
  1623             <h3><?php echo $lang->get('database_heading_optionalinfo'); ?></h3>
       
  1624           </td>
       
  1625         </tr>
       
  1626         <tr>
       
  1627           <td>
       
  1628             <b><?php echo $lang->get('database_field_tableprefix_title'); ?></b><br />
       
  1629             <?php echo $lang->get('database_field_tableprefix_body'); ?>
       
  1630           </td>
       
  1631           <td>
       
  1632             <input onkeyup="verify();" name="table_prefix" size="30" type="text" />
       
  1633           </td>
       
  1634           <td>
       
  1635             <img id="s_table_prefix" alt="Good/bad icon" src="images/good.gif" />
       
  1636           </td>
       
  1637         </tr>
       
  1638         <tr>
       
  1639           <td rowspan="2">
       
  1640             <b><?php echo $lang->get('database_field_rootauth_title'); ?></b><br />
       
  1641             <?php echo $lang->get('database_field_rootauth_body'); ?><br />
       
  1642             <span style="color: #993300" id="e_db_root"></span>
       
  1643           </td>
       
  1644           <td>
       
  1645             <input onkeyup="verify();" name="db_root_user" size="30" type="text" />
       
  1646           </td>
       
  1647           <td rowspan="2">
       
  1648             <img id="s_db_root" alt="Good/bad icon" src="images/good.gif" />
       
  1649           </td>
       
  1650         </tr>
       
  1651         <tr>
       
  1652           <td>
       
  1653             <input onkeyup="verify();" name="db_root_pass" size="30" type="password" />
       
  1654           </td>
       
  1655         </tr>
       
  1656         <tr>
       
  1657           <td>
       
  1658             <b><?php echo $lang->get('database_field_mysqlversion_title'); ?></b>
       
  1659           </td>
       
  1660           <td id="e_mysql_version">
       
  1661             <?php echo $lang->get('database_field_mysqlversion_blurb_willbechecked'); ?>
       
  1662           </td>
       
  1663           <td>
       
  1664             <img id="s_mysql_version" alt="Good/bad icon" src="images/unknown.gif" />
       
  1665           </td>
       
  1666         </tr>
       
  1667         <tr>
       
  1668           <td>
       
  1669             <b><?php echo $lang->get('database_field_droptables_title'); ?></b><br />
       
  1670             <?php echo $lang->get('database_field_droptables_body'); ?>
       
  1671           </td>
       
  1672           <td>
       
  1673             <input type="checkbox" name="drop_tables" id="dtcheck" />  <label for="dtcheck"><?php echo $lang->get('database_field_droptables_lbl'); ?></label>
       
  1674           </td>
       
  1675         </tr>
       
  1676         <tr>
       
  1677           <td colspan="3" style="text-align: center">
       
  1678             <input type="button" value="<?php echo $lang->get('database_btn_testconnection'); ?>" onclick="ajaxTestConnection();" />
       
  1679           </td>
       
  1680         </tr>
       
  1681       </table>
       
  1682       <div class="pagenav">
       
  1683         <table border="0">
       
  1684           <tr>
       
  1685             <td>
       
  1686               <input type="submit" value="<?php echo $lang->get('meta_btn_continue'); ?>" onclick="return verify();" name="_cont" />
       
  1687             </td>
       
  1688             <td>
       
  1689               <p>
       
  1690                 <span style="font-weight: bold;"><?php echo $lang->get('meta_lbl_before_continue'); ?></span><br />
       
  1691                 &bull; <?php echo $lang->get('database_objective_test'); ?><br />
       
  1692                 &bull; <?php echo $lang->get('database_objective_uncrypt'); ?>
       
  1693               </p>
       
  1694             </td>
       
  1695           </tr>
       
  1696         </table>
       
  1697       </div>
       
  1698       <?php
       
  1699       break;
       
  1700     case 'database_pgsql':
       
  1701       ?>
       
  1702     <script type="text/javascript">
       
  1703       function ajaxGet(uri, f) {
       
  1704         if (window.XMLHttpRequest) {
       
  1705           ajax = new XMLHttpRequest();
       
  1706         } else {
       
  1707           if (window.ActiveXObject) {           
       
  1708             ajax = new ActiveXObject("Microsoft.XMLHTTP");
       
  1709           } else {
       
  1710             alert('Enano client-side runtime error: No AJAX support, unable to continue');
       
  1711             return;
       
  1712           }
       
  1713         }
       
  1714         ajax.onreadystatechange = f;
       
  1715         ajax.open('GET', uri, true);
       
  1716         ajax.send(null);
       
  1717       }
       
  1718       
       
  1719       function ajaxPost(uri, parms, f) {
       
  1720         if (window.XMLHttpRequest) {
       
  1721           ajax = new XMLHttpRequest();
       
  1722         } else {
       
  1723           if (window.ActiveXObject) {           
       
  1724             ajax = new ActiveXObject("Microsoft.XMLHTTP");
       
  1725           } else {
       
  1726             alert('Enano client-side runtime error: No AJAX support, unable to continue');
       
  1727             return;
       
  1728           }
       
  1729         }
       
  1730         ajax.onreadystatechange = f;
       
  1731         ajax.open('POST', uri, true);
       
  1732         ajax.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
       
  1733         ajax.setRequestHeader("Content-length", parms.length);
       
  1734         ajax.setRequestHeader("Connection", "close");
       
  1735         ajax.send(parms);
       
  1736       }
       
  1737       function ajaxTestConnection()
       
  1738       {
       
  1739         v = verify();
       
  1740         if(!v)
       
  1741         {
       
  1742           alert($lang.get('meta_msg_err_verification'));
       
  1743           return false;
       
  1744         }
       
  1745         var frm = document.forms.dbinfo;
       
  1746         db_host      = escape(frm.db_host.value.replace('+', '%2B'));
       
  1747         db_name      = escape(frm.db_name.value.replace('+', '%2B'));
       
  1748         db_user      = escape(frm.db_user.value.replace('+', '%2B'));
       
  1749         db_pass      = escape(frm.db_pass.value.replace('+', '%2B'));
       
  1750         db_root_user = escape(frm.db_root_user.value.replace('+', '%2B'));
       
  1751         db_root_pass = escape(frm.db_root_pass.value.replace('+', '%2B'));
       
  1752         
       
  1753         parms = 'host='+db_host+'&name='+db_name+'&user='+db_user+'&pass='+db_pass+'&root_user='+db_root_user+'&root_pass='+db_root_pass;
       
  1754         ajaxPost('<?php echo scriptPath; ?>/install.php?mode=mysql_test', parms, function() {
       
  1755             if(ajax.readyState==4)
       
  1756             {
       
  1757               s = ajax.responseText.substr(0, 4);
       
  1758               t = ajax.responseText.substr(4, ajax.responseText.length);
       
  1759               if(s.substr(0, 4)=='good')
       
  1760               {
       
  1761                 document.getElementById('s_db_host').src='images/good.gif';
       
  1762                 document.getElementById('s_db_name').src='images/good.gif';
       
  1763                 document.getElementById('s_db_auth').src='images/good.gif';
       
  1764                 document.getElementById('s_db_root').src='images/good.gif';
       
  1765                 if(t.match(/_creating_db/)) document.getElementById('e_db_name').innerHTML = $lang.get('database_msg_warn_creating_db');
       
  1766                 if(t.match(/_creating_user/)) document.getElementById('e_db_auth').innerHTML = $lang.get('database_msg_warn_creating_user');
       
  1767                 document.getElementById('s_mysql_version').src='images/good.gif';
       
  1768                 document.getElementById('e_mysql_version').innerHTML = $lang.get('database_msg_info_mysql_good');
       
  1769               }
       
  1770               else
       
  1771               {
       
  1772                 switch(s)
       
  1773                 {
       
  1774                 case 'host':
       
  1775                   document.getElementById('s_db_host').src='images/bad.gif';
       
  1776                   document.getElementById('s_db_name').src='images/unknown.gif';
       
  1777                   document.getElementById('s_db_auth').src='images/unknown.gif';
       
  1778                   document.getElementById('s_db_root').src='images/unknown.gif';
       
  1779                   document.getElementById('e_db_host').innerHTML = $lang.get('database_msg_err_mysql_connect', { db_host: document.forms.dbinfo.db_host.value, mysql_error: t });
       
  1780                   document.getElementById('e_mysql_version').innerHTML = $lang.get('database_msg_warn_mysql_version');
       
  1781                   break;
       
  1782                 case 'auth':
       
  1783                   document.getElementById('s_db_host').src='images/good.gif';
       
  1784                   document.getElementById('s_db_name').src='images/unknown.gif';
       
  1785                   document.getElementById('s_db_auth').src='images/bad.gif';
       
  1786                   document.getElementById('s_db_root').src='images/unknown.gif';
       
  1787                   document.getElementById('e_db_auth').innerHTML = $lang.get('database_msg_err_mysql_auth', { mysql_error: t });
       
  1788                   document.getElementById('e_mysql_version').innerHTML = $lang.get('database_msg_warn_mysql_version');
       
  1789                   break;
       
  1790                 case 'perm':
       
  1791                   document.getElementById('s_db_host').src='images/good.gif';
       
  1792                   document.getElementById('s_db_name').src='images/bad.gif';
       
  1793                   document.getElementById('s_db_auth').src='images/good.gif';
       
  1794                   document.getElementById('s_db_root').src='images/unknown.gif';
       
  1795                   document.getElementById('e_db_name').innerHTML = $lang.get('database_msg_err_mysql_dbperm', { mysql_error: t });
       
  1796                   document.getElementById('e_mysql_version').innerHTML = $lang.get('database_msg_warn_mysql_version');
       
  1797                   break;
       
  1798                 case 'name':
       
  1799                   document.getElementById('s_db_host').src='images/good.gif';
       
  1800                   document.getElementById('s_db_name').src='images/bad.gif';
       
  1801                   document.getElementById('s_db_auth').src='images/good.gif';
       
  1802                   document.getElementById('s_db_root').src='images/unknown.gif';
       
  1803                   document.getElementById('e_db_name').innerHTML = $lang.get('database_msg_err_mysql_dbexist', { mysql_error: t });
       
  1804                   document.getElementById('e_mysql_version').innerHTML = $lang.get('database_msg_warn_mysql_version');
       
  1805                   break;
       
  1806                 case 'root':
       
  1807                   document.getElementById('s_db_host').src='images/good.gif';
       
  1808                   document.getElementById('s_db_name').src='images/unknown.gif';
       
  1809                   document.getElementById('s_db_auth').src='images/unknown.gif';
       
  1810                   document.getElementById('s_db_root').src='images/bad.gif';
       
  1811                   document.getElementById('e_db_root').innerHTML = $lang.get('database_msg_err_mysql_auth', { mysql_error: t });
       
  1812                   document.getElementById('e_mysql_version').innerHTML = $lang.get('database_msg_warn_mysql_version');
       
  1813                   break;
       
  1814                 case 'vers':
       
  1815                   document.getElementById('s_db_host').src='images/good.gif';
       
  1816                   document.getElementById('s_db_name').src='images/good.gif';
       
  1817                   document.getElementById('s_db_auth').src='images/good.gif';
       
  1818                   document.getElementById('s_db_root').src='images/good.gif';
       
  1819                   if(t.match(/_creating_db/)) document.getElementById('e_db_name').innerHTML = $lang.get('database_msg_warn_creating_db');
       
  1820                   if(t.match(/_creating_user/)) document.getElementById('e_db_auth').innerHTML = $lang.get('database_msg_warn_creating_user');
       
  1821                   
       
  1822                   document.getElementById('e_mysql_version').innerHTML = $lang.get('database_msg_err_mysql_version', { mysql_version: t });
       
  1823                   document.getElementById('s_mysql_version').src='images/bad.gif';
       
  1824                 default:
       
  1825                   alert(t);
       
  1826                   break;
       
  1827                 }
       
  1828               }
       
  1829             }
       
  1830           });
       
  1831       }
       
  1832       function verify()
       
  1833       {
       
  1834         document.getElementById('e_db_host').innerHTML = '';
       
  1835         document.getElementById('e_db_auth').innerHTML = '';
       
  1836         document.getElementById('e_db_name').innerHTML = '';
       
  1837         document.getElementById('e_db_root').innerHTML = '';
       
  1838         var frm = document.forms.dbinfo;
       
  1839         ret = true;
       
  1840         if(frm.db_host.value != '')
       
  1841         {
       
  1842           document.getElementById('s_db_host').src='images/unknown.gif';
       
  1843         }
       
  1844         else
       
  1845         {
       
  1846           document.getElementById('s_db_host').src='images/bad.gif';
       
  1847           ret = false;
       
  1848         }
       
  1849         if(frm.db_name.value.match(/^([a-z0-9_-]+)$/g))
       
  1850         {
       
  1851           document.getElementById('s_db_name').src='images/unknown.gif';
       
  1852         }
       
  1853         else
       
  1854         {
       
  1855           document.getElementById('s_db_name').src='images/bad.gif';
       
  1856           ret = false;
       
  1857         }
       
  1858         if(frm.db_user.value != '')
       
  1859         {
       
  1860           document.getElementById('s_db_auth').src='images/unknown.gif';
       
  1861         }
       
  1862         else
       
  1863         {
       
  1864           document.getElementById('s_db_auth').src='images/bad.gif';
       
  1865           ret = false;
       
  1866         }
       
  1867         if(frm.table_prefix.value.match(/^([a-z0-9_]*)$/g))
       
  1868         {
       
  1869           document.getElementById('s_table_prefix').src='images/good.gif';
       
  1870         }
       
  1871         else
       
  1872         {
       
  1873           document.getElementById('s_table_prefix').src='images/bad.gif';
       
  1874           ret = false;
       
  1875         }
       
  1876         if(frm.db_root_user.value == '')
       
  1877         {
       
  1878           document.getElementById('s_db_root').src='images/good.gif';
       
  1879         }
       
  1880         else if(frm.db_root_user.value != '' && frm.db_root_pass.value == '')
       
  1881         {
       
  1882           document.getElementById('s_db_root').src='images/bad.gif';
       
  1883           ret = false;
       
  1884         }
       
  1885         else
       
  1886         {
       
  1887           document.getElementById('s_db_root').src='images/unknown.gif';
       
  1888         }
       
  1889         if(ret) frm._cont.disabled = false;
       
  1890         else    frm._cont.disabled = true;
       
  1891         return ret;
       
  1892       }
       
  1893       window.onload = verify;
       
  1894     </script>
       
  1895     <p><?php echo $lang->get('database_blurb_needdb'); ?></p>
       
  1896     <p><?php echo $lang->get('database_blurb_howtomysql'); ?></p>
       
  1897     <?php
       
  1898     if ( file_exists('/etc/enano-is-virt-appliance') )
       
  1899     {
       
  1900       echo '<p>
       
  1901               ' . $lang->get('database_vm_login_info', array( 'host' => 'localhost', 'user' => 'enano', 'pass' => 'clurichaun', 'name' => 'enano_www1' )) . '
       
  1902             </p>';
       
  1903     }
       
  1904     ?>
       
  1905     <form name="dbinfo" action="install.php?mode=website" method="post">
       
  1906       <input type="hidden" name="db_driver" value="postgresql" />
       
  1907       <table border="0">
       
  1908         <tr><td colspan="3" style="text-align: center"><h3>Database information</h3></td></tr>
       
  1909         <tr><td><b>Database hostname</b><br />This is the hostname (or sometimes the IP address) of your Postgres server. In many cases, this is "localhost".<br /><span style="color: #993300" id="e_db_host"></span></td><td><input onkeyup="verify();" name="db_host" size="30" type="text" /></td><td><img id="s_db_host" alt="Good/bad icon" src="images/bad.gif" /></td></tr>
       
  1910         <tr><td><b>Database name</b><br />The name of the actual database. If you don't already have a database, you can create one here, if you have the username and password of a PostgreSQL superuser.<br /><span style="color: #993300" id="e_db_name"></span></td><td><input onkeyup="verify();" name="db_name" size="30" type="text" /></td><td><img id="s_db_name" alt="Good/bad icon" src="images/bad.gif" /></td></tr>
       
  1911         <tr><td rowspan="2"><b>Database login</b><br />These fields should be the username and password for a role that has permission to create and alter tables, select data, insert data, update data, and delete data. You may or may not choose to allow dropping tables.<br /><span style="color: #993300" id="e_db_auth"></span></td><td><input onkeyup="verify();" name="db_user" size="30" type="text" /></td><td rowspan="2"><img id="s_db_auth" alt="Good/bad icon" src="images/bad.gif" /></td></tr>
       
  1912         <tr><td><input name="db_pass" size="30" type="password" /></td></tr>
       
  1913         <tr><td colspan="3" style="text-align: center"><h3>Optional information</h3></td></tr>
       
  1914         <tr><td><b>Table prefix</b><br />The value that you enter here will be added to the beginning of the name of each Enano table. You may use lowercase letters (a-z), numbers (0-9), and underscores (_).</td><td><input onkeyup="verify();" name="table_prefix" size="30" type="text" /></td><td><img id="s_table_prefix" alt="Good/bad icon" src="images/good.gif" /></td></tr>
       
  1915         <tr><td rowspan="2"><b>Database administrative login</b><br />If the Postgres database or role that you entered above does not exist yet, you can create them here, assuming that you have the login information for a PostgreSQL superuser. Leave these fields blank unless you need to use them.<br /><span style="color: #993300" id="e_db_root"></span></td><td><input onkeyup="verify();" name="db_root_user" size="30" type="text" /></td><td rowspan="2"><img id="s_db_root" alt="Good/bad icon" src="images/good.gif" /></td></tr>
       
  1916         <tr><td><input onkeyup="verify();" name="db_root_pass" size="30" type="password" /></td></tr>
       
  1917         <tr><td><b>PostgreSQL version</b></td><td id="e_mysql_version">PostgreSQL version information will<br />be checked when you click "Test<br />Connection". You need to have at<br />least PostgreSQL 8.2.0 to install Enano.</td><td><img id="s_mysql_version" alt="Good/bad icon" src="images/unknown.gif" /></td></tr>
       
  1918         <tr><td><b>Delete existing tables?</b><br />If this option is checked, all the tables that will be used by Enano will be dropped (deleted) before the schema is executed. Do NOT use this option unless specifically instructed to.</td><td><input type="checkbox" name="drop_tables" id="dtcheck" />  <label for="dtcheck">Drop existing tables</label></td></tr>
       
  1919         <tr><td colspan="3" style="text-align: center"><input type="button" value="Test connection" onclick="ajaxTestConnection();" /></td></tr>
       
  1920       </table>
       
  1921       <div class="pagenav">
       
  1922        <table border="0">
       
  1923        <tr>
       
  1924        <td><input type="submit" value="Continue" onclick="return verify();" name="_cont" /></td><td><p><span style="font-weight: bold;">Before clicking continue:</span><br />&bull; Check your PostgreSQL connection using the "Test Connection" button.<br />&bull; Be aware that your database information will be transmitted unencrypted several times.</p></td>
       
  1925        </tr>
       
  1926        </table>
       
  1927      </div>
       
  1928     </form>
       
  1929     <?php
       
  1930     break;
       
  1931   case "website":
       
  1932     if ( !isset($_POST['_cont']) )
       
  1933     {
       
  1934       echo 'No POST data signature found. Please <a href="install.php?mode=license">restart the installation</a>.';
       
  1935       $template->footer();
       
  1936       exit;
       
  1937     }
       
  1938     unset($_POST['_cont']);
       
  1939     ?>
       
  1940     <script type="text/javascript">
       
  1941       function verify()
       
  1942       {
       
  1943         var frm = document.forms.siteinfo;
       
  1944         ret = true;
       
  1945         if(frm.sitename.value.match(/^(.+)$/g) && frm.sitename.value != 'Enano')
       
  1946         {
       
  1947           document.getElementById('s_name').src='images/good.gif';
       
  1948         }
       
  1949         else
       
  1950         {
       
  1951           document.getElementById('s_name').src='images/bad.gif';
       
  1952           ret = false;
       
  1953         }
       
  1954         if(frm.sitedesc.value.match(/^(.+)$/g))
       
  1955         {
       
  1956           document.getElementById('s_desc').src='images/good.gif';
       
  1957         }
       
  1958         else
       
  1959         {
       
  1960           document.getElementById('s_desc').src='images/bad.gif';
       
  1961           ret = false;
       
  1962         }
       
  1963         if(frm.copyright.value.match(/^(.+)$/g))
       
  1964         {
       
  1965           document.getElementById('s_copyright').src='images/good.gif';
       
  1966         }
       
  1967         else
       
  1968         {
       
  1969           document.getElementById('s_copyright').src='images/bad.gif';
       
  1970           ret = false;
       
  1971         }
       
  1972         if(ret) frm._cont.disabled = false;
       
  1973         else    frm._cont.disabled = true;
       
  1974         return ret;
       
  1975       }
       
  1976       window.onload = verify;
       
  1977     </script>
       
  1978     <form name="siteinfo" action="install.php?mode=login" method="post">
       
  1979       <?php
       
  1980         $k = array_keys($_POST);
       
  1981         for($i=0;$i<sizeof($_POST);$i++) {
       
  1982           echo '<input type="hidden" name="'.htmlspecialchars($k[$i]).'" value="'.htmlspecialchars($_POST[$k[$i]]).'" />'."\n";
       
  1983         }
       
  1984       ?>
       
  1985       <p><?php echo $lang->get('website_header_blurb'); ?></p>
       
  1986       <table border="0">
       
  1987         <tr>
       
  1988           <td>
       
  1989             <b><?php echo $lang->get('website_field_name_title'); ?></b><br />
       
  1990             <?php echo $lang->get('website_field_name_body'); ?>
       
  1991           </td>
       
  1992           <td>
       
  1993             <input onkeyup="verify();" name="sitename" type="text" size="30" />
       
  1994           </td>
       
  1995           <td>
       
  1996             <img id="s_name" alt="Good/bad icon" src="images/bad.gif" />
       
  1997           </td>
       
  1998         </tr>
       
  1999         <tr>
       
  2000           <td>
       
  2001             <b><?php echo $lang->get('website_field_desc_title'); ?></b><br />
       
  2002             <?php echo $lang->get('website_field_desc_body'); ?>
       
  2003           </td>
       
  2004           <td>
       
  2005             <input onkeyup="verify();" name="sitedesc" type="text" size="30" />
       
  2006           </td>
       
  2007           <td>
       
  2008             <img id="s_desc" alt="Good/bad icon" src="images/bad.gif" />
       
  2009           </td>
       
  2010         </tr>
       
  2011         <tr>
       
  2012           <td>
       
  2013             <b><?php echo $lang->get('website_field_copyright_title'); ?></b><br />
       
  2014             <?php echo $lang->get('website_field_copyright_body'); ?>
       
  2015           </td>
       
  2016           <td>
       
  2017             <input onkeyup="verify();" name="copyright" type="text" size="30" />
       
  2018           </td>
       
  2019           <td>
       
  2020             <img id="s_copyright" alt="Good/bad icon" src="images/bad.gif" />
       
  2021           </td>
       
  2022         </tr>
       
  2023         <tr>
       
  2024           <td>
       
  2025             <b><?php echo $lang->get('website_field_wikimode_title'); ?></b><br />
       
  2026             <?php echo $lang->get('website_field_wikimode_body'); ?>
       
  2027           </td>
       
  2028           <td>
       
  2029             <input name="wiki_mode" type="checkbox" id="wmcheck" />  <label for="wmcheck"><?php echo $lang->get('website_field_wikimode_checkbox'); ?></label>
       
  2030           </td>
       
  2031           <td>
       
  2032             &nbsp;
       
  2033           </td>
       
  2034         </tr>
       
  2035         <tr>
       
  2036           <td>
       
  2037             <b><?php echo $lang->get('website_field_urlscheme_title'); ?></b><br />
       
  2038             <?php echo $lang->get('website_field_urlscheme_body'); ?>
       
  2039           </td>
       
  2040           <td colspan="2">
       
  2041             <input type="radio" <?php if(!is_apache()) echo 'checked="checked" '; ?>name="urlscheme" value="ugly" id="ugly"  />  <label for="ugly"><?php echo $lang->get('website_field_urlscheme_ugly'); ?></label><br />
       
  2042             <input type="radio" <?php if(is_apache()) echo 'checked="checked" '; ?>name="urlscheme" value="short" id="short" />  <label for="short"><?php echo $lang->get('website_field_urlscheme_short'); ?></label><br />
       
  2043             <input type="radio" name="urlscheme" value="tiny" id="petite">  <label for="petite"><?php echo $lang->get('website_field_urlscheme_tiny'); ?></label><br />
       
  2044             <small><a href="install.php?mode=pophelp&amp;topic=url_schemes" onclick="window.open(this.href, 'pophelpwin', 'width=550,height=400,status=no,toolbars=no,toolbar=no,address=no,scroll=yes'); return false;"><?php echo $lang->get('website_field_urlscheme_helplink'); ?></a></small>
       
  2045           </td>
       
  2046         </tr>
       
  2047       </table>
       
  2048       <div class="pagenav">
       
  2049        <table border="0">
       
  2050          <tr>
       
  2051            <td>
       
  2052              <input type="submit" value="<?php echo $lang->get('meta_btn_continue'); ?>" onclick="return verify();" name="_cont" />
       
  2053            </td>
       
  2054            <td>
       
  2055              <p>
       
  2056                <span style="font-weight: bold;"><?php echo $lang->get('meta_lbl_before_continue'); ?></span><br />
       
  2057                &bull; <?php echo $lang->get('website_objective_verify'); ?>
       
  2058              </p>
       
  2059            </td>
       
  2060          </tr>
       
  2061        </table>
       
  2062      </div>
       
  2063     </form>
       
  2064     <?php
       
  2065     break;
       
  2066   case "login":
       
  2067     if(!isset($_POST['_cont'])) {
       
  2068       echo 'No POST data signature found. Please <a href="install.php?mode=license">restart the installation</a>.';
       
  2069       $template->footer();
       
  2070       exit;
       
  2071     }
       
  2072     unset($_POST['_cont']);
       
  2073     require('config.new.php');
       
  2074     $aes = AESCrypt::singleton(AES_BITS, AES_BLOCKSIZE);
       
  2075     if ( isset($crypto_key) )
       
  2076     {
       
  2077       $cryptkey = $crypto_key;
       
  2078     }
       
  2079     if(!isset($cryptkey) || ( isset($cryptkey) && strlen($cryptkey) != AES_BITS / 4) )
       
  2080     {
       
  2081       $cryptkey = $aes->gen_readymade_key();
       
  2082       $handle = @fopen(ENANO_ROOT.'/config.new.php', 'w');
       
  2083       if(!$handle)
       
  2084       {
       
  2085         echo '<p>ERROR: Despite my repeated attempts to verify that the configuration file can be written, I was indeed prevented from opening it for writing. Maybe you\'re still on <del>crack</del> Windows?</p>';
       
  2086         $template->footer();
       
  2087         exit;
       
  2088       }
       
  2089       fwrite($handle, '<?php $cryptkey = \''.$cryptkey.'\'; ?>');
       
  2090       fclose($handle);
       
  2091     }
       
  2092     // Sorry for the ugly hack, but this f***s up jEdit badly.
       
  2093     echo '
       
  2094     <script type="text/javascript">
       
  2095       function verify()
       
  2096       {
       
  2097         var frm = document.forms.login;
       
  2098         ret = true;
       
  2099         if ( frm.admin_user.value.match(/^([^<>&\?\'"%\/]+)$/) && !frm.admin_user.value.match(/^(?:(?:\\d{1,2}|1\\d\\d|2[0-4]\\d|25[0-5])\\.){3}(?:\\d{1,2}|1\\d\\d|2[0-4]\\d|25[0-5])$/) && frm.admin_user.value.toLowerCase() != \'anonymous\' )
       
  2100         {
       
  2101           document.getElementById(\'s_user\').src = \'images/good.gif\';
       
  2102         }
       
  2103         else
       
  2104         {
       
  2105           document.getElementById(\'s_user\').src = \'images/bad.gif\';
       
  2106           ret = false;
       
  2107         }
       
  2108         if(frm.admin_pass.value.length >= 6 && frm.admin_pass.value == frm.admin_pass_confirm.value)
       
  2109         {
       
  2110           document.getElementById(\'s_password\').src = \'images/good.gif\';
       
  2111         }
       
  2112         else
       
  2113         {
       
  2114           document.getElementById(\'s_password\').src = \'images/bad.gif\';
       
  2115           ret = false;
       
  2116         }
       
  2117         if(frm.admin_email.value.match(/^(?:[\\w\\d_-]+\\.?)+@(?:(?:[\\w\\d-]\\-?)+\\.)+\\w{2,4}$/))
       
  2118         {
       
  2119           document.getElementById(\'s_email\').src = \'images/good.gif\';
       
  2120         }
       
  2121         else
       
  2122         {
       
  2123           document.getElementById(\'s_email\').src = \'images/bad.gif\';
       
  2124           ret = false;
       
  2125         }
       
  2126         if(ret) frm._cont.disabled = false;
       
  2127         else    frm._cont.disabled = true;
       
  2128         return ret;
       
  2129       }
       
  2130       window.onload = verify;
       
  2131       
       
  2132       function cryptdata() 
       
  2133       {
       
  2134         if(!verify()) return false;
       
  2135       }
       
  2136     </script>
       
  2137     ';
       
  2138     ?>
       
  2139     <form name="login" action="install.php?mode=confirm" method="post" onsubmit="runEncryption();">
       
  2140       <?php
       
  2141         $k = array_keys($_POST);
       
  2142         for($i=0;$i<sizeof($_POST);$i++) {
       
  2143           echo '<input type="hidden" name="'.htmlspecialchars($k[$i]).'" value="'.htmlspecialchars($_POST[$k[$i]]).'" />'."\n";
       
  2144         }
       
  2145       ?>
       
  2146       <p><?php echo $lang->get('login_header_blurb'); ?></p>
       
  2147       <table border="0">
       
  2148         <tr>
       
  2149           <td><b><?php echo $lang->get('login_field_username_title'); ?></b><br /><small><?php echo $lang->get('login_field_username_body'); ?></small></td>
       
  2150           <td><input onkeyup="verify();" name="admin_user" type="text" size="30" /></td>
       
  2151           <td><img id="s_user" alt="Good/bad icon" src="images/bad.gif" /></td>
       
  2152         </tr>
       
  2153         <tr>
       
  2154           <td><?php echo $lang->get('login_field_password_title'); ?></td>
       
  2155           <td><input onkeyup="verify();" name="admin_pass" type="password" size="30" /></td>
       
  2156           <td rowspan="2"><img id="s_password" alt="Good/bad icon" src="images/bad.gif" /></td>
       
  2157         </tr>
       
  2158         <tr>
       
  2159           <td><?php echo $lang->get('login_field_password_confirm'); ?></td>
       
  2160           <td><input onkeyup="verify();" name="admin_pass_confirm" type="password" size="30" /></td>
       
  2161         </tr>
       
  2162         <tr>
       
  2163           <td><?php echo $lang->get('login_field_email_title'); ?></td>
       
  2164           <td><input onkeyup="verify();" name="admin_email" type="text" size="30" /></td>
       
  2165           <td><img id="s_email" alt="Good/bad icon" src="images/bad.gif" /></td>
       
  2166         </tr>
       
  2167         <tr>
       
  2168           <td>
       
  2169             <?php echo $lang->get('login_field_allowphp_title'); ?><br />
       
  2170             <small>
       
  2171               <span style="color: #D84308">
       
  2172                 <?php
       
  2173                   echo $lang->get('login_field_allowphp_body',
       
  2174                     array(
       
  2175                       'important_notes' => '<a href="install.php?mode=pophelp&amp;topic=admin_embed_php" onclick="window.open(this.href, \'pophelpwin\', \'width=550,height=400,status=no,toolbars=no,toolbar=no,address=no,scroll=yes\'); return false;" style="color: #D84308; text-decoration: underline;">' . $lang->get('login_field_allowphp_isi') . '</a>'
       
  2176                       )
       
  2177                     );
       
  2178                 ?>
       
  2179               </span>
       
  2180             </small>
       
  2181           </td>
       
  2182           <td>
       
  2183             <label><input type="radio" name="admin_embed_php" value="2" checked="checked" /> <?php echo $lang->get('login_field_allowphp_disabled'); ?></label>&nbsp;&nbsp;
       
  2184             <label><input type="radio" name="admin_embed_php" value="4" /> <?php echo $lang->get('login_field_allowphp_enabled'); ?></label>
       
  2185           </td>
       
  2186           <td></td>
       
  2187         </tr>
       
  2188         <tr><td colspan="3"><?php echo $lang->get('login_aes_blurb'); ?></td></tr>
       
  2189       </table>
       
  2190       <div class="pagenav">
       
  2191        <table border="0">
       
  2192          <tr>
       
  2193            <td>
       
  2194              <input type="submit" value="<?php echo $lang->get('meta_btn_continue'); ?>" onclick="return cryptdata();" name="_cont" />
       
  2195            </td>
       
  2196            <td>
       
  2197              <p>
       
  2198                <span style="font-weight: bold;"><?php echo $lang->get('meta_lbl_before_continue'); ?></span><br />
       
  2199                &bull; <?php echo $lang->get('login_objective_remember'); ?>
       
  2200              </p>
       
  2201            </td>
       
  2202          </tr>
       
  2203        </table>
       
  2204       </div>
       
  2205       <div id="cryptdebug"></div>
       
  2206       <input type="hidden" name="use_crypt" value="no" />
       
  2207       <input type="hidden" name="crypt_key" value="<?php echo $cryptkey; ?>" />
       
  2208       <input type="hidden" name="crypt_data" value="" />
       
  2209     </form>
       
  2210     <script type="text/javascript">
       
  2211     // <![CDATA[
       
  2212       var frm = document.forms.login;
       
  2213       frm.admin_user.focus();
       
  2214       function runEncryption()
       
  2215       {
       
  2216         str = '';
       
  2217         for(i=0;i<keySizeInBits/4;i++) str+='0';
       
  2218         var key = hexToByteArray(str);
       
  2219         var pt = hexToByteArray(str);
       
  2220         var ct = rijndaelEncrypt(pt, key, "ECB");
       
  2221         var ect = byteArrayToHex(ct);
       
  2222         switch(keySizeInBits)
       
  2223         {
       
  2224           case 128:
       
  2225             v = '66e94bd4ef8a2c3b884cfa59ca342b2e';
       
  2226             break;
       
  2227           case 192:
       
  2228             v = 'aae06992acbf52a3e8f4a96ec9300bd7aae06992acbf52a3e8f4a96ec9300bd7';
       
  2229             break;
       
  2230           case 256:
       
  2231             v = 'dc95c078a2408989ad48a21492842087dc95c078a2408989ad48a21492842087';
       
  2232             break;
       
  2233         }
       
  2234         var testpassed = ( ect == v && md5_vm_test() );
       
  2235         var frm = document.forms.login;
       
  2236         if(testpassed)
       
  2237         {
       
  2238           // alert('encryption self-test passed');
       
  2239           frm.use_crypt.value = 'yes';
       
  2240           var cryptkey = frm.crypt_key.value;
       
  2241           frm.crypt_key.value = '';
       
  2242           if(cryptkey != byteArrayToHex(hexToByteArray(cryptkey)))
       
  2243           {
       
  2244             alert('Byte array conversion SUCKS');
       
  2245             testpassed = false;
       
  2246           }
       
  2247           cryptkey = hexToByteArray(cryptkey);
       
  2248           if(!cryptkey || ( ( typeof cryptkey == 'string' || typeof cryptkey == 'object' ) ) && cryptkey.length != keySizeInBits / 8 )
       
  2249           {
       
  2250             frm._cont.disabled = true;
       
  2251             len = ( typeof cryptkey == 'string' || typeof cryptkey == 'object' ) ? '\nLen: '+cryptkey.length : '';
       
  2252             alert('The key is messed up\nType: '+typeof(cryptkey)+len);
       
  2253           }
       
  2254         }
       
  2255         else
       
  2256         {
       
  2257           // alert('encryption self-test FAILED');
       
  2258         }
       
  2259         if(testpassed)
       
  2260         {
       
  2261           pass = frm.admin_pass.value;
       
  2262           pass = stringToByteArray(pass);
       
  2263           cryptstring = rijndaelEncrypt(pass, cryptkey, 'ECB');
       
  2264           //decrypted = rijndaelDecrypt(cryptstring, cryptkey, 'ECB');
       
  2265           //decrypted = byteArrayToString(decrypted);
       
  2266           //return false;
       
  2267           if(!cryptstring)
       
  2268           {
       
  2269             return false;
       
  2270           }
       
  2271           cryptstring = byteArrayToHex(cryptstring);
       
  2272           // document.getElementById('cryptdebug').innerHTML = '<pre>Data: '+cryptstring+'<br />Key:  '+byteArrayToHex(cryptkey)+'</pre>';
       
  2273           frm.crypt_data.value = cryptstring;
       
  2274           frm.admin_pass.value = '';
       
  2275           frm.admin_pass_confirm.value = '';
       
  2276         }
       
  2277         return false;
       
  2278       }
       
  2279       // ]]>
       
  2280     </script>
       
  2281     <?php
       
  2282     break;
       
  2283   case "confirm":
       
  2284     if(!isset($_POST['_cont'])) {
       
  2285       echo 'No POST data signature found. Please <a href="install.php?mode=sysreqs">restart the installation</a>.';
       
  2286       $template->footer();
       
  2287       exit;
       
  2288     }
       
  2289     unset($_POST['_cont']);
       
  2290     ?>
       
  2291     <form name="confirm" action="install.php?mode=install" method="post">
       
  2292       <?php
       
  2293         $k = array_keys($_POST);
       
  2294         for($i=0;$i<sizeof($_POST);$i++) {
       
  2295           echo '<input type="hidden" name="'.htmlspecialchars($k[$i]).'" value="'.htmlspecialchars($_POST[$k[$i]]).'" />'."\n";
       
  2296         }
       
  2297       ?>
       
  2298       <h3><?php echo $lang->get('confirm_header_blurb_title'); ?></h3>
       
  2299        <p><?php echo $lang->get('confirm_header_blurb_body'); ?></p>
       
  2300       <ul>
       
  2301         <li><?php echo $lang->get('confirm_lbl_db_host'); ?> <?php echo $_POST['db_host']; ?></li>
       
  2302         <li><?php echo $lang->get('confirm_lbl_db_name'); ?> <?php echo $_POST['db_name']; ?></li>
       
  2303         <li><?php echo $lang->get('confirm_lbl_db_user'); ?> <?php echo $_POST['db_user']; ?></li>
       
  2304         <li><?php echo $lang->get('confirm_lbl_db_pass'); ?></li>
       
  2305         <li><?php echo $lang->get('confirm_lbl_sitename'); ?> <?php echo $_POST['sitename']; ?></li>
       
  2306         <li><?php echo $lang->get('confirm_lbl_sitedesc'); ?> <?php echo $_POST['sitedesc']; ?></li>
       
  2307         <li><?php echo $lang->get('confirm_lbl_adminuser'); ?> <?php echo $_POST['admin_user']; ?></li>
       
  2308         <li><?php echo $lang->get('confirm_lbl_aesbits'); ?> <?php echo $lang->get('confirm_lbl_aes_strength', array( 'aes_bits' => AES_BITS )); ?><br /><small><?php echo $lang->get('confirm_lbl_aes_change'); ?></small></li>
       
  2309       </ul>
       
  2310       <div class="pagenav">
       
  2311         <table border="0">
       
  2312           <tr>
       
  2313             <td>
       
  2314               <input type="submit" value="<?php echo $lang->get('confirm_btn_install_enano'); ?>" name="_cont" />
       
  2315             </td>
       
  2316             <td>
       
  2317               <p>
       
  2318                 <span style="font-weight: bold;"><?php echo $lang->get('meta_lbl_before_continue'); ?></span><br />
       
  2319                 <!-- Like this even needs to be localized. :-P -->
       
  2320                 &bull; <?php echo $lang->get('confirm_objective_pray'); ?>
       
  2321               </p>
       
  2322             </td>
       
  2323           </tr>
       
  2324         </table>
       
  2325       </div>
       
  2326     </form>
       
  2327     <?php
       
  2328     break;
       
  2329   case "install":
       
  2330     if(!isset($_POST['db_host']) ||
       
  2331        !isset($_POST['db_name']) ||
       
  2332        !isset($_POST['db_user']) ||
       
  2333        !isset($_POST['db_pass']) ||
       
  2334        !isset($_POST['db_driver']) ||
       
  2335        !isset($_POST['sitename']) ||
       
  2336        !isset($_POST['sitedesc']) ||
       
  2337        !isset($_POST['copyright']) ||
       
  2338        !isset($_POST['admin_user']) ||
       
  2339        !isset($_POST['admin_pass']) ||
       
  2340        !isset($_POST['admin_embed_php']) || ( isset($_POST['admin_embed_php']) && !in_array($_POST['admin_embed_php'], array('2', '4')) ) ||
       
  2341        !isset($_POST['urlscheme'])
       
  2342        )
       
  2343     {
       
  2344       echo 'The installer has detected that one or more required form values is not set. Please <a href="install.php?mode=license">restart the installation</a>.';
       
  2345       $template->footer();
       
  2346       exit;
       
  2347     }
       
  2348     if ( !in_array($_POST['db_driver'], array('mysql', 'postgresql')) )
       
  2349     {
       
  2350       echo 'Invalid database driver.';
       
  2351       $template->footer();
       
  2352       exit;
       
  2353     }
       
  2354     switch($_POST['urlscheme'])
       
  2355     {
       
  2356       case "ugly":
       
  2357       default:
       
  2358         $cp = scriptPath.'/index.php?title=';
       
  2359         break;
       
  2360       case "short":
       
  2361         $cp = scriptPath.'/index.php/';
       
  2362         break;
       
  2363       case "tiny":
       
  2364         $cp = scriptPath.'/';
       
  2365         break;
       
  2366     }
       
  2367     function err($t) { global $template; echo $t; $template->footer(); exit; }
       
  2368     
       
  2369     // $stages = array('connect', 'decrypt', 'genkey', 'parse', 'sql', 'writeconfig', 'renameconfig', 'startapi', 'initlogs');
       
  2370     
       
  2371     if ( !preg_match('/^[a-z0-9_-]*$/', $_POST['table_prefix']) )
       
  2372       err('Hacking attempt was detected in table_prefix.');
       
  2373     
       
  2374       start_install_table();
       
  2375       
       
  2376       // Are we just trying to auto-rename the config files? If so, skip everything else
       
  2377       if ( !isset($_GET['stage']) || ( isset($_GET['stage']) && $_GET['stage'] != 'renameconfig' ) )
       
  2378       {
       
  2379         // The stages connect, decrypt, genkey, and parse are preprocessing and don't do any actual data modification.
       
  2380         // Thus, they need to be run on each retry, e.g. never skipped.
       
  2381         run_installer_stage('connect', $lang->get('install_stg_connect_title'), 'stg_mysql_connect', $lang->get('install_stg_connect_body'), false);
       
  2382         if ( isset($_POST['drop_tables']) )
       
  2383         {
       
  2384           // Are we supposed to drop any existing tables? If so, do it now
       
  2385           run_installer_stage('drop', $lang->get('install_stg_drop_title'), 'stg_drop_tables', 'This step never returns failure');
       
  2386         }
       
  2387         run_installer_stage('decrypt', $lang->get('install_stg_decrypt_title'), 'stg_decrypt_admin_pass', $lang->get('install_stg_decrypt_body'), false);
       
  2388         run_installer_stage('genkey', $lang->get('install_stg_genkey_title', array( 'aes_bits' => AES_BITS )), 'stg_generate_aes_key', $lang->get('install_stg_genkey_body'), false);
       
  2389         run_installer_stage('parse', $lang->get('install_stg_parse_title'), 'stg_parse_schema', $lang->get('install_stg_parse_body'), false);
       
  2390         run_installer_stage('sql', $lang->get('install_stg_sql_title'), 'stg_install', $lang->get('install_stg_sql_body'), false);
       
  2391         run_installer_stage('writeconfig', $lang->get('install_stg_writeconfig_title'), 'stg_write_config', $lang->get('install_stg_writeconfig_body'));
       
  2392         
       
  2393         // Mainstream installation complete - Enano should be usable now
       
  2394         // The stage of starting the API is special because it has to be called out of function context.
       
  2395         // To alleviate this, we have two functions, one that returns success and one that returns failure
       
  2396         // If the Enano API load is successful, the success function is called to report the action to the user
       
  2397         // If unsuccessful, the failure report is sent
       
  2398         
       
  2399         $template_bak = $template;
       
  2400         
       
  2401         $_GET['title'] = 'Main_Page';
       
  2402         require('includes/common.php');
       
  2403         
       
  2404         if ( is_object($db) && is_object($session) )
       
  2405         {
       
  2406           run_installer_stage('startapi', $lang->get('install_stg_startapi_title'), 'stg_start_api_success', '...', false);
       
  2407         }
       
  2408         else
       
  2409         {
       
  2410           run_installer_stage('startapi', $lang->get('install_stg_startapi_title'), 'stg_start_api_failure', $lang->get('install_stg_startapi_body'), false);
       
  2411         }
       
  2412         
       
  2413         // We need to be logged in (with admin rights) before logs can be flushed
       
  2414         $admin_password = stg_decrypt_admin_pass(true);
       
  2415         $session->login_without_crypto($_POST['admin_user'], $admin_password, false);
       
  2416         
       
  2417         // Now that login cookies are set, initialize the session manager and ACLs
       
  2418         $session->start();
       
  2419         $paths->init();
       
  2420         
       
  2421         run_installer_stage('importlang', $lang->get('install_stg_importlang_title'), 'stg_import_language', $lang->get('install_stg_importlang_body'));
       
  2422         run_installer_stage('initlogs', $lang->get('install_stg_initlogs_title'), 'stg_init_logs', $lang->get('install_stg_initlogs_body'));
       
  2423         
       
  2424         run_installer_stage('buildindex', $lang->get('install_stg_buildindex_title'), 'stg_build_index', $lang->get('install_stg_buildindex_body'));
       
  2425         
       
  2426         /*
       
  2427          * HACKERS:
       
  2428          * If you're making a custom distribution of Enano, put all your custom plugin-related code here.
       
  2429          * You have access to the full Enano API as well as being logged in with complete admin rights.
       
  2430          * Don't do anything horrendously fancy here, unless you add a new stage (or more than one) and
       
  2431          * have the progress printed out properly.
       
  2432          */
       
  2433         
       
  2434       } // check for stage == renameconfig
       
  2435       else
       
  2436       {
       
  2437         // If we did skip the main installer routine, set $template_bak to make the reversal later work properly
       
  2438         $template_bak = $template;
       
  2439       }
       
  2440 
       
  2441       // Final step is to rename the config file
       
  2442       // In early revisions of 1.0.2, this step was performed prior to the initialization of the Enano API. It was decided to move
       
  2443       // this stage to the end because it will fail more often than any other stage, thus making alternate routes imperative. If this
       
  2444       // stage fails, then no big deal, we'll just have the user rename the files manually and then let them see the pretty success message.
       
  2445       run_installer_stage('renameconfig', $lang->get('install_stg_rename_title'), 'stg_rename_config', $lang->get('install_stg_rename_body'));
       
  2446       
       
  2447       close_install_table();
       
  2448       
       
  2449       unset($template);
       
  2450       $template =& $template_bak;
       
  2451     
       
  2452       echo '<h3>' . $lang->get('install_msg_complete_title') . '</h3>';
       
  2453       echo '<p>' . $lang->get('install_msg_complete_body', array('finish_link' => 'install.php?mode=finish')) . '</p>';
       
  2454       
       
  2455       // echo '<script type="text/javascript">window.location="'.scriptPath.'/install.php?mode=finish";</script>';
       
  2456       
       
  2457     break;
       
  2458   case "finish":
       
  2459     echo '<h3>' . $lang->get('finish_msg_congratulations') . '</h3>
       
  2460            ' . $lang->get('finish_body') . '
       
  2461            <p>' . $lang->get('finish_link_mainpage', array('mainpage_link' => 'index.php')) . '</p>';
       
  2462     break;
       
  2463   // this stage is never shown during the installation, but is provided for legal purposes
       
  2464   case "showlicense":
       
  2465     show_license(true);
       
  2466     break;
       
  2467 }
       
  2468 $template->footer();
       
  2469  
       
  2470 ?>