install/includes/cli-core.php
changeset 812 68060328e9c6
child 813 3fe11491f512
equal deleted inserted replaced
811:5c807fe77020 812:68060328e9c6
       
     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.6 (Caoineag beta 1)
       
     6  * Copyright (C) 2006-2008 Dan Fuhry
       
     7  * Installation package
       
     8  * cli-core.php - CLI installation wizard/core
       
     9  *
       
    10  * This program is Free Software; you can redistribute and/or modify it under the terms of the GNU General Public License
       
    11  * as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
       
    12  *
       
    13  * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
       
    14  * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
       
    15  * 
       
    16  * Thanks to Stephan for helping out with l10n in the installer (his work is in includes/stages/*.php).
       
    17  */
       
    18 
       
    19 require(dirname(__FILE__) . '/common.php');
       
    20 if ( !defined('ENANO_CLI') )
       
    21 {
       
    22   $ui = new Enano_Installer_UI('Enano installation', false);
       
    23   $ui->set_visible_stage($ui->add_stage('Error', true));
       
    24 
       
    25   $ui->step = 'Access denied';  
       
    26   $ui->show_header();
       
    27   echo '<h2>CLI only</h2>
       
    28         <p>This script must be run from the command line.</p>';
       
    29   $ui->show_footer();
       
    30   exit;
       
    31 }
       
    32 
       
    33 // parse command line args
       
    34 foreach ( array('silent', 'driver', 'dbhost', 'dbuser', 'dbpasswd', 'dbname', 'db_prefix', 'user', 'pass', 'email', 'sitename', 'sitedesc', 'copyright', 'urlscheme', 'lang_id', 'scriptpath') as $var )
       
    35 {
       
    36   if ( !isset($$var) )
       
    37   {
       
    38     $$var = false;
       
    39   }
       
    40 }
       
    41 
       
    42 for ( $i = 1; $i < count($argv); $i++ )
       
    43 {
       
    44   switch($argv[$i])
       
    45   {
       
    46     case '-q':
       
    47       $silent = true;
       
    48       break;
       
    49     case '--db-driver':
       
    50     case '-b':
       
    51       $driver = @$argv[++$i];
       
    52       break;
       
    53     case '--db-host':
       
    54     case '-h':
       
    55       $dbhost = @$argv[++$i];
       
    56       break;
       
    57     case '--db-user':
       
    58     case '-u':
       
    59       $dbuser = @$argv[++$i];
       
    60       break;
       
    61     case '--db-pass':
       
    62     case '-p':
       
    63       $dbpasswd = @$argv[++$i];
       
    64       break;
       
    65     case '--db-name':
       
    66     case '-d':
       
    67       $dbname = @$argv[++$i];
       
    68       break;
       
    69     case '--table-prefix':
       
    70     case '-t':
       
    71       $db_prefix = @$argv[++$i];
       
    72       break;
       
    73     case '--admin-user':
       
    74     case '-a':
       
    75       $user = @$argv[++$i];
       
    76       break;
       
    77     case '--admin-pass':
       
    78     case '-w':
       
    79       $pass = @$argv[++$i];
       
    80       break;
       
    81     case '--admin-email':
       
    82     case '-e':
       
    83       $email = @$argv[++$i];
       
    84       break;
       
    85     case '--site-name':
       
    86     case '-n':
       
    87       $sitename = @$argv[++$i];
       
    88       break;
       
    89     case '--site-desc':
       
    90     case '-s':
       
    91       $sitedesc = @$argv[++$i];
       
    92       break;
       
    93     case '--copyright':
       
    94     case '-c':
       
    95       $copyright = @$argv[++$i];
       
    96       break;
       
    97     case '--url-scheme':
       
    98     case '-r':
       
    99       $urlscheme_temp = @$argv[++$i];
       
   100       if ( in_array($urlscheme_temp, array('standard', 'short', 'rewrite')) )
       
   101         $urlscheme = $urlscheme_temp;
       
   102       break;
       
   103     case '--language':
       
   104     case '-l':
       
   105       $lang_id = @$argv[++$i];
       
   106       break;
       
   107     case '-i':
       
   108     case '--scriptpath':
       
   109       $scriptpath = @$argv[++$i];
       
   110       break;
       
   111     default:
       
   112       $vers = installer_enano_version();
       
   113       echo <<<EOF
       
   114 Enano CMS v$vers - CLI Installer
       
   115 Usage: {$argv[0]} [-q] [-b driver] [-h host] [-u username] [-p password]
       
   116                   [-d database] [-a adminuser] [-w adminpass] [-e email]
       
   117 All arguments are optional; missing information will be prompted for.
       
   118   -q                Quiet mode (minimal output)
       
   119   -b, --db-driver   Database driver (mysql or postgresql)
       
   120   -h, --db-host     Hostname of database server
       
   121   -u, --db-user     Username to use on database server
       
   122   -p, --db-pass     Password to use on database server
       
   123   -d, --db-name     Name of database
       
   124   -a, --admin-user  Administrator username
       
   125   -w, --admin-pass  Administrator password
       
   126   -e, --admin-email Administrator e-mail address
       
   127   -n, --site-name   Name of site
       
   128   -s, --site-desc   *SHORT* Description of site
       
   129   -c, --copyright   Copyright notice shown on pages
       
   130   -r, --url-scheme  URL scheme (standard, short, or rewrite)
       
   131   -l, --language    Language to be used on site and in installer
       
   132   -i, --scriptpath  Where Enano is relative to your website root (no trailing
       
   133                     slash)
       
   134 
       
   135 
       
   136 EOF;
       
   137       exit(1);
       
   138       break;
       
   139   }
       
   140 }
       
   141 
       
   142 if ( $silent )
       
   143 {
       
   144   define('ENANO_LIBINSTALL_SILENT', '');
       
   145 }
       
   146 
       
   147 ##
       
   148 ## PHP VERSION CHECK
       
   149 ##
       
   150 
       
   151 if ( version_compare(PHP_VERSION, '5.0.0', '<' ) )
       
   152 {
       
   153   if ( !$silent )
       
   154   {
       
   155     echo "\x1B[1mWelcome to the \x1B[34mEnano\x1B[0m CMS\x1B[1m installation wizard.\x1B[0m\n";
       
   156     echo "Installing Enano version \x1B[1m" . installer_enano_version() . "\x1B[0m on PHP " . PHP_VERSION . "\n";
       
   157   }
       
   158   installer_fail('Your version of PHP (' . PHP_VERSION . ') doesn\'t meet Enano requirements (5.0.0)');
       
   159 }
       
   160 
       
   161 ##
       
   162 ## LANGUAGE STARTUP
       
   163 ##
       
   164 
       
   165 // Include language lib and additional PHP5-only JSON functions
       
   166 require_once( ENANO_ROOT . '/includes/json2.php' );
       
   167 require_once( ENANO_ROOT . '/includes/lang.php' );
       
   168 
       
   169 // Determine language ID to use
       
   170 $langids = array_keys($languages);
       
   171 if ( $silent )
       
   172 {
       
   173   if ( !in_array($lang_id, $langids ) )
       
   174     $lang_id = $langids[0];
       
   175 }
       
   176 else if ( !in_array($lang_id, $langids) )
       
   177 {
       
   178   echo "\x1B[1mPlease select a language.\x1B[0m\n";
       
   179   echo "\x1B[32mAvailable languages:\x1B[0m\n";
       
   180   foreach ( $languages as $id => $metadata )
       
   181   {
       
   182     $id_spaced = $id;
       
   183     while ( strlen($id_spaced) < 10 )
       
   184       $id_spaced = "$id_spaced ";
       
   185     echo "  \x1B[1;34m$id_spaced\x1B[0m {$metadata['name']} ({$metadata['name_eng']})\n";
       
   186   }
       
   187   while ( !in_array($lang_id, $langids) )
       
   188   {
       
   189     $lang_id = cli_prompt('Language: ', $langids[0]);
       
   190   }
       
   191 }
       
   192 
       
   193 // We have a language ID - init language
       
   194 $language_dir = $languages[$lang_id]['dir'];
       
   195 
       
   196 // Initialize language support
       
   197 $lang = new Language($lang_id);
       
   198 $lang->load_file(ENANO_ROOT . '/language/' . $language_dir . '/install.json');
       
   199 
       
   200 ##
       
   201 ## WELCOME MESSAGE
       
   202 ##
       
   203 
       
   204 if ( !$silent )
       
   205 {
       
   206   echo parse_shellcolor_string($lang->get('cli_welcome_line1'));
       
   207   echo parse_shellcolor_string($lang->get('cli_welcome_line2', array('enano_version' => installer_enano_version(), 'php_version' => PHP_VERSION)));
       
   208 }
       
   209 
       
   210 $defaults = array(
       
   211   'driver'  => 'mysql',
       
   212   'dbhost'    => 'localhost',
       
   213   'dbuser'    => false,
       
   214   'dbpasswd'  => false,
       
   215   'dbname'    => false,
       
   216   'db_prefix'    => '',
       
   217   'user'      => 'admin',
       
   218   'pass'      => false,
       
   219   'email'     => false,
       
   220   'sitename'  => $lang->get('cli_default_site_name'),
       
   221   'sitedesc'  => $lang->get('cli_default_site_desc'),
       
   222   'copyright' => $lang->get('cli_default_copyright', array('year' => date('Y'))),
       
   223   'urlscheme' => 'standard',
       
   224   'scriptpath'=> '/enano'
       
   225 );
       
   226 
       
   227 $terms = array(
       
   228   'driver'  => $lang->get('cli_prompt_driver'),
       
   229   'dbhost'    => $lang->get('cli_prompt_dbhost'),
       
   230   'dbuser'    => $lang->get('cli_prompt_dbuser'),
       
   231   'dbpasswd'  => $lang->get('cli_prompt_dbpasswd'),
       
   232   'dbname'    => $lang->get('cli_prompt_dbname'),
       
   233   'db_prefix'    => $lang->get('cli_prompt_db_prefix'),
       
   234   'user'      => $lang->get('cli_prompt_user'),
       
   235   'pass'      => $lang->get('cli_prompt_pass'),
       
   236   'email'     => $lang->get('cli_prompt_email'),
       
   237   'sitename'  => $lang->get('cli_prompt_sitename'),
       
   238   'sitedesc'  => $lang->get('cli_prompt_sitedesc'),
       
   239   'copyright' => $lang->get('cli_prompt_copyright'),
       
   240   'urlscheme' => $lang->get('cli_prompt_urlscheme'),
       
   241   'scriptpath'=> $lang->get('cli_prompt_scriptpath')
       
   242 );
       
   243 
       
   244 foreach ( array('driver', 'dbhost', 'dbuser', 'dbpasswd', 'dbname', 'db_prefix', 'scriptpath', 'user', 'pass', 'email', 'sitename', 'sitedesc', 'copyright', 'urlscheme') as $var )
       
   245 {
       
   246   if ( empty($$var) )
       
   247   {
       
   248     switch($var)
       
   249     {
       
   250       default:
       
   251         $$var = cli_prompt($terms[$var], $defaults[$var]);
       
   252         break;
       
   253       case 'pass':
       
   254       case 'dbpasswd':
       
   255         if ( @file_exists('/bin/stty') && @is_executable('/bin/stty') )
       
   256         {
       
   257           exec('/bin/stty -echo');
       
   258           while ( true )
       
   259           {
       
   260             $$var = cli_prompt($terms[$var], $defaults[$var]);
       
   261             echo "\n";
       
   262             $confirm = cli_prompt($lang->get('cli_prompt_confirm'), $defaults[$var]);
       
   263             echo "\n";
       
   264             if ( $$var === $confirm )
       
   265               break;
       
   266             else
       
   267               echo parse_shellcolor_string($lang->get('cli_err_pass_no_match'));
       
   268           }
       
   269           exec('/bin/stty echo');
       
   270         }
       
   271         else
       
   272         {
       
   273           $$var = cli_prompt("{$terms[$var]} " . $lang->get('cli_msg_echo_warning'), $defaults[$var]);
       
   274         }
       
   275         break;
       
   276       case 'urlscheme':
       
   277         $temp = '';
       
   278         while ( !in_array($temp, array('standard', 'short', 'rewrite')) )
       
   279         {
       
   280           $temp = cli_prompt($terms[$var], $defaults[$var]);
       
   281         }
       
   282         $$var = $temp;
       
   283         break;
       
   284       case 'db_prefix':
       
   285         while ( !preg_match('/^[a-z0-9_]*$/', $$var) )
       
   286         {
       
   287           $$var = cli_prompt($terms[$var], $defaults[$var]);
       
   288         }
       
   289         break;
       
   290     }
       
   291   }
       
   292 }
       
   293 
       
   294 ##
       
   295 ## DB TEST
       
   296 ##
       
   297 
       
   298 require( ENANO_ROOT . '/includes/dbal.php' );
       
   299 require( ENANO_ROOT . '/includes/sql_parse.php' );
       
   300 $dbal = new $driver();
       
   301 
       
   302 if ( !$silent )
       
   303   echo parse_shellcolor_string($lang->get('cli_msg_testing_db'));
       
   304 
       
   305 $result = $dbal->connect(true, $dbhost, $dbuser, $dbpasswd, $dbname);
       
   306 if ( !$result )
       
   307 {
       
   308   if ( !$silent )
       
   309     echo parse_shellcolor_string($lang->get('cli_test_fail')) . "\n";
       
   310   installer_fail($lang->get('cli_err_db_connect_fail'));
       
   311 }
       
   312 
       
   313 if ( !$silent )
       
   314   echo parse_shellcolor_string($lang->get('cli_test_pass')) . "\n";
       
   315 
       
   316 ##
       
   317 ## SERVER REQUIREMENTS
       
   318 ##
       
   319 
       
   320 if ( !$silent )
       
   321 {
       
   322   echo parse_shellcolor_string($lang->get('cli_stage_sysreqs'));
       
   323 }
       
   324 
       
   325 $test_failed = false;
       
   326 
       
   327 run_test('return version_compare(\'5.2.0\', PHP_VERSION, \'<=\');', $lang->get('sysreqs_req_php5'), $lang->get('sysreqs_req_desc_php5'), true);
       
   328 run_test('return function_exists(\'mysql_connect\');', $lang->get('sysreqs_req_mysql'), $lang->get('sysreqs_req_desc_mysql'), true);
       
   329 run_test('return function_exists(\'pg_connect\');', $lang->get('sysreqs_req_postgres'), $lang->get('sysreqs_req_desc_postgres'), true);
       
   330 run_test('return @ini_get(\'file_uploads\');', $lang->get('sysreqs_req_uploads'), $lang->get('sysreqs_req_desc_uploads') );
       
   331 run_test('return config_write_test();', $lang->get('sysreqs_req_config'), $lang->get('sysreqs_req_desc_config') );
       
   332 run_test('return file_exists(\'/usr/bin/convert\');', $lang->get('sysreqs_req_magick'), $lang->get('sysreqs_req_desc_magick'), true);
       
   333 run_test('return is_writable(ENANO_ROOT.\'/cache/\');', $lang->get('sysreqs_req_cachewriteable'), $lang->get('sysreqs_req_desc_cachewriteable'), true);
       
   334 run_test('return is_writable(ENANO_ROOT.\'/files/\');', $lang->get('sysreqs_req_fileswriteable'), $lang->get('sysreqs_req_desc_fileswriteable'), true);
       
   335 if ( !function_exists('mysql_connect') && !function_exists('pg_connect') )
       
   336 {
       
   337   installer_fail($lang->get('cli_err_no_drivers'));
       
   338 }
       
   339 if ( $test_failed )
       
   340 {
       
   341   installer_fail($lang->get('cli_err_sysreqs_fail'));
       
   342 }
       
   343 
       
   344 ##
       
   345 ## STAGE 1 INSTALLATION
       
   346 ##
       
   347 
       
   348 if ( !$silent )
       
   349 {
       
   350   echo parse_shellcolor_string($lang->get('cli_msg_tests_passed'));
       
   351   echo parse_shellcolor_string($lang->get('cli_msg_installing_db_stage1'));
       
   352 }
       
   353 
       
   354 // Create the config table
       
   355 try
       
   356 {
       
   357   $sql_parser = new SQL_Parser( ENANO_ROOT . "/install/schemas/{$driver}_stage1.sql" );
       
   358 }
       
   359 catch ( Exception $e )
       
   360 {
       
   361   if ( !$silent )
       
   362     echo "\n";
       
   363   installer_fail($lang->get('cli_err_schema_load'));
       
   364 }
       
   365 // Check to see if the config table already exists
       
   366 $q = $dbal->sql_query('SELECT config_name, config_value FROM ' . $db_prefix . 'config LIMIT 1;');
       
   367 if ( !$q )
       
   368 {
       
   369   $sql_parser->assign_vars(array(
       
   370       'TABLE_PREFIX' => $db_prefix
       
   371     ));
       
   372   $sql = $sql_parser->parse();
       
   373   foreach ( $sql as $q )
       
   374   {
       
   375     if ( !$dbal->sql_query($q) )
       
   376     {
       
   377       if ( !$silent )
       
   378         echo "\n";
       
   379       echo "[$driver] " . $dbal->sql_error() . "\n";
       
   380       installer_fail($lang->get('cli_err_db_query'));
       
   381     }
       
   382   }
       
   383 }
       
   384 else
       
   385 {
       
   386   $dbal->free_result();
       
   387   if ( !$dbal->sql_query('DELETE FROM ' . $db_prefix . 'config WHERE config_name = \'install_aes_key\';') )
       
   388   {
       
   389     if ( !$silent )
       
   390       echo "\n";
       
   391     echo "[$driver] " . $dbal->sql_error() . "\n";
       
   392     installer_fail($lang->get('cli_err_db_query'));
       
   393   }
       
   394 }
       
   395 
       
   396 if ( !$silent )
       
   397   echo parse_shellcolor_string($lang->get('cli_msg_ok')) . "\n";
       
   398 
       
   399 define('table_prefix', $db_prefix);
       
   400 
       
   401 ##
       
   402 ## STAGE 2 INSTALLATION
       
   403 ##
       
   404 
       
   405 $db =& $dbal;
       
   406 $dbdriver =& $driver;
       
   407 
       
   408 // Yes, I am predicting the future here. Because I have that kind of power.
       
   409 $_SERVER['REMOTE_ADDR'] = ( intval(date('Y')) >= 2011 ) ? '::1' : '127.0.0.1';
       
   410 
       
   411 if ( !$silent )
       
   412   echo parse_shellcolor_string($lang->get('cli_msg_parsing_schema'));
       
   413 
       
   414 require_once( ENANO_ROOT . '/includes/rijndael.php' );
       
   415 require_once( ENANO_ROOT . '/includes/hmac.php' );
       
   416 
       
   417 $aes = AESCrypt::singleton(AES_BITS, AES_BLOCKSIZE);
       
   418 $hmac_secret = hexencode(AESCrypt::randkey(20), '', '');
       
   419 
       
   420 $admin_pass_clean =& $pass;
       
   421 $admin_pass = hmac_sha1($admin_pass_clean, $hmac_secret);
       
   422 
       
   423 unset($admin_pass_clean); // Security
       
   424 
       
   425 try
       
   426 {
       
   427   $sql_parser = new SQL_Parser( ENANO_ROOT . "/install/schemas/{$dbdriver}_stage2.sql" );
       
   428 }
       
   429 catch ( Exception $e )
       
   430 {
       
   431   if ( !$silent )
       
   432     echo "\n";
       
   433   installer_fail($lang->get('cli_err_schema_load'));
       
   434 }
       
   435 
       
   436 $wkt = ENANO_ROOT . "/language/{$languages[$lang_id]['dir']}/install/mainpage-default.wkt";
       
   437 if ( !file_exists( $wkt ) )
       
   438 {
       
   439   if ( !$silent )
       
   440     echo "\n";
       
   441   installer_fail($lang->get('cli_err_mainpage_load'));
       
   442 }
       
   443 $wkt = @file_get_contents($wkt);
       
   444 if ( empty($wkt) )
       
   445   return false;
       
   446 
       
   447 $wkt = $db->escape($wkt);
       
   448 
       
   449 $vars = array(
       
   450     'TABLE_PREFIX'         => table_prefix,
       
   451     'SITE_NAME'            => $sitename,
       
   452     'SITE_DESC'            => $sitedesc,
       
   453     'COPYRIGHT'            => $copyright,
       
   454     'WIKI_MODE'            => '0',
       
   455     'ENABLE_CACHE'         => ( is_writable( ENANO_ROOT . '/cache/' ) ? '1' : '0' ),
       
   456     'VERSION'              => installer_enano_version(),
       
   457     'ADMIN_USER'           => $db->escape($user),
       
   458     'ADMIN_PASS'           => $admin_pass,
       
   459     'ADMIN_PASS_SALT'      => $hmac_secret,
       
   460     'ADMIN_EMAIL'          => $db->escape($email),
       
   461     'REAL_NAME'            => '', // This has always been stubbed.
       
   462     'ADMIN_EMBED_PHP'      => strval(AUTH_DISALLOW),
       
   463     'UNIX_TIME'            => strval(time()),
       
   464     'MAIN_PAGE_CONTENT'    => $wkt,
       
   465     'IP_ADDRESS'           => $_SERVER['REMOTE_ADDR']
       
   466   );
       
   467 
       
   468 $sql_parser->assign_vars($vars);
       
   469 $schema = $sql_parser->parse();
       
   470 
       
   471 if ( !$silent )
       
   472   echo parse_shellcolor_string($lang->get('cli_msg_ok')) . "\n";
       
   473 
       
   474 ##
       
   475 ## PAYLOAD DELIVERY
       
   476 ##
       
   477 
       
   478 if ( !$silent )
       
   479   echo parse_shellcolor_string($lang->get('cli_msg_installing_db_stage2'));
       
   480 
       
   481 foreach ( $schema as $sql )
       
   482 {
       
   483   if ( !$db->check_query($sql) )
       
   484   {
       
   485     if ( !$silent )
       
   486       echo "\n";
       
   487     installer_fail($lang->get('cli_err_query_sanity_failed'));
       
   488   }
       
   489 }
       
   490 
       
   491 foreach ( $schema as $sql )
       
   492 {
       
   493   if ( !$db->sql_query($sql) )
       
   494   {
       
   495     if ( !$silent )
       
   496       echo "\n";
       
   497     echo "[$dbdriver] " . $db->sql_error() . "\n";
       
   498     installer_fail($lang->get('cli_err_db_query'));
       
   499   }
       
   500 }
       
   501 
       
   502 if ( !$silent )
       
   503   echo parse_shellcolor_string($lang->get('cli_msg_ok')) . "\n";
       
   504 
       
   505 ##
       
   506 ## CONFIG FILE GENERATION
       
   507 ##
       
   508 
       
   509 require_once( ENANO_ROOT . '/install/includes/payload.php' );
       
   510 require_once( ENANO_ROOT . '/install/includes/libenanoinstallcli.php' );
       
   511 define('scriptPath', $scriptpath);
       
   512 $urlscheme = strtr($urlscheme, array(
       
   513   'short' => 'shortened'
       
   514 ));
       
   515 $_POST['url_scheme'] =& $urlscheme;
       
   516 
       
   517 run_installer_stage('writeconfig', 'writing_config', 'stg_write_config', 'install_stg_writeconfig_body');
       
   518 
       
   519 ##
       
   520 ## FINAL STAGES
       
   521 ##
       
   522 
       
   523 if ( !$silent )
       
   524   echo parse_shellcolor_string($lang->get('cli_msg_starting_api'));
       
   525 
       
   526 // Start up the Enano API
       
   527 $db->close();
       
   528 @define('ENANO_ALLOW_LOAD_NOLANG', 1);
       
   529 // If this fails, it fails hard.
       
   530 require(ENANO_ROOT . '/includes/common.php');
       
   531 
       
   532 if ( !$silent )
       
   533   echo parse_shellcolor_string($lang->get('cli_msg_ok')) . "\n";
       
   534 
       
   535 run_installer_stage('importlang', 'importing_language', 'stg_language_setup', $lang->get('install_stg_importlang_body'));
       
   536 run_installer_stage('initlogs', 'initting_logs', 'stg_init_logs', $lang->get('install_stg_initlogs_body'));
       
   537 run_installer_stage('cleanup', 'cleaning_up', 'stg_aes_cleanup', $lang->get('install_stg_cleanup_body'), false);
       
   538 run_installer_stage('buildindex', 'initting_index', 'stg_build_index', $lang->get('install_stg_buildindex_body'));
       
   539 run_installer_stage('renameconfig', 'renaming_config', 'stg_rename_config', $lang->get('install_stg_rename_body', array('mainpage_link' => scriptPath . '/index.php')));
       
   540 
       
   541 if ( !$silent )
       
   542 {
       
   543   echo parse_shellcolor_string($lang->get('cli_msg_install_success'));
       
   544 }
       
   545 
       
   546 return true;
       
   547 
       
   548 ##
       
   549 ## FUNCTIONS
       
   550 ##
       
   551 
       
   552 function cli_prompt($prompt, $default = false)
       
   553 {
       
   554   if ( is_string($default) )
       
   555   {
       
   556     echo "$prompt [$default]: ";
       
   557     $stdin = fopen('php://stdin', 'r');
       
   558     $input = trim(fgets($stdin, 1024));
       
   559     fclose($stdin);
       
   560     if ( empty($input) )
       
   561       return $default;
       
   562     return $input;
       
   563   }
       
   564   else
       
   565   {
       
   566     while ( true )
       
   567     {
       
   568       echo "$prompt: ";
       
   569       $stdin = fopen('php://stdin', 'r');
       
   570       $input = trim(fgets($stdin, 1024));
       
   571       fclose($stdin);
       
   572       if ( !empty($input) )
       
   573         return $input;
       
   574     }
       
   575   }
       
   576 }
       
   577 
       
   578 function run_test($evalme, $test, $description, $warnonly = false)
       
   579 {
       
   580   global $silent, $test_failed, $lang;
       
   581   if ( !$silent )
       
   582     echo "$test: ";
       
   583   $result = eval($evalme);
       
   584   if ( $result )
       
   585   {
       
   586     if ( !$silent )
       
   587       echo parse_shellcolor_string($lang->get('cli_test_pass'));
       
   588   }
       
   589   else
       
   590   {
       
   591     if ( !$silent )
       
   592       echo $warnonly ? parse_shellcolor_string($lang->get('cli_test_warn')) : parse_shellcolor_string($lang->get('cli_test_fail'));
       
   593     if ( !$silent )
       
   594       echo "\n" . preg_replace('/^/m', '  ', wordwrap(strip_tags($description)));
       
   595     if ( !$warnonly )
       
   596       $test_failed = true;
       
   597   }
       
   598   if ( !$silent )
       
   599     echo "\n";
       
   600 }
       
   601 
       
   602 function installer_fail($message)
       
   603 {
       
   604   global $silent;
       
   605   if ( $silent )
       
   606     file_put_contents('php://stderr', "$message\n");
       
   607   else
       
   608     echo "\x1B[1;31m" . "Error:\x1B[0;1m $message\x1B[0m\n";
       
   609   exit(1);
       
   610 }
       
   611 
       
   612 function config_write_test()
       
   613 {
       
   614   if ( !is_writable(ENANO_ROOT.'/config.new.php') )
       
   615     return false;
       
   616   // We need to actually _open_ the file to make sure it can be written, because sometimes this fails even when is_writable() returns
       
   617   // true on Windows/IIS servers. Don't ask me why.
       
   618   $h = @fopen( ENANO_ROOT . '/config.new.php', 'a+' );
       
   619   if ( !$h )
       
   620     return false;
       
   621   fclose($h);
       
   622   return true;
       
   623 }
       
   624 
       
   625 function parse_shellcolor_string($str)
       
   626 {
       
   627   $expr = '/<c ((?:[0-9]+)(?:;[0-9]+)*)>([\w\W]*?)<\/c>/';
       
   628   while ( preg_match($expr, $str) )
       
   629     $str = preg_replace($expr, "\x1B[\\1m\\2\x1B[0m", $str);
       
   630   
       
   631   return $str;
       
   632 }
       
   633