Fixed some Oracle-specific installer and Strict Standards issues
[lhc/web/wiklou.git] / config / Installer.php
index 4c05c69..9e7e188 100644 (file)
@@ -44,6 +44,8 @@ require_once( "$IP/includes/ProfilerStub.php" );
 require_once( "$IP/includes/GlobalFunctions.php" );
 require_once( "$IP/includes/Hooks.php" );
 require_once( "$IP/includes/Exception.php" );
+require_once( "$IP/includes/json/Services_JSON.php" );
+require_once( "$IP/includes/json/FormatJson.php" );
 
 # If we get an exception, the user needs to know
 # all the details
@@ -53,41 +55,60 @@ wfInstallExceptionHandler();
 ## Databases we support:
 
 $ourdb = array();
-$ourdb['mysql']['fullname']      = 'MySQL';
-$ourdb['mysql']['havedriver']    = 0;
-$ourdb['mysql']['compile']       = 'mysql';
-$ourdb['mysql']['bgcolor']       = '#ffe5a7';
-$ourdb['mysql']['rootuser']      = 'root';
-
-$ourdb['postgres']['fullname']   = 'PostgreSQL';
-$ourdb['postgres']['havedriver'] = 0;
-$ourdb['postgres']['compile']    = 'pgsql';
-$ourdb['postgres']['bgcolor']    = '#aaccff';
-$ourdb['postgres']['rootuser']   = 'postgres';
-
-$ourdb['sqlite']['fullname']      = 'SQLite';
-$ourdb['sqlite']['havedriver']    = 0;
-$ourdb['sqlite']['compile']       = 'pdo_sqlite';
-$ourdb['sqlite']['bgcolor']       = '#b1ebb1';
-$ourdb['sqlite']['rootuser']      = '';
-
-$ourdb['mssql']['fullname']      = 'MSSQL';
-$ourdb['mssql']['havedriver']    = 0;
-$ourdb['mssql']['compile']       = 'mssql not ready'; # Change to 'mssql' after includes/DatabaseMssql.php added;
-$ourdb['mssql']['bgcolor']       = '#ffc0cb';
-$ourdb['mssql']['rootuser']      = 'administrator';
-
-$ourdb['ibm_db2']['fullname']   = 'DB2';
-$ourdb['ibm_db2']['havedriver'] = 0;
-$ourdb['ibm_db2']['compile']    = 'ibm_db2';
-$ourdb['ibm_db2']['bgcolor']    = '#ffeba1';
-$ourdb['ibm_db2']['rootuser']   = 'db2admin';
-
-$ourdb['oracle']['fullname']   = 'Oracle';
-$ourdb['oracle']['havedriver'] = 0;
-$ourdb['oracle']['compile']    = 'oci8';
-$ourdb['oracle']['bgcolor']    = '#ffeba1';
-$ourdb['oracle']['rootuser']   = '';
+
+$ourdb['mysql'] = array(
+       'fullname'   => 'MySQL',
+       'havedriver' => 0,
+       'compile'    => 'mysql',
+       'bgcolor'    => '#ffe5a7',
+       'rootuser'   => 'root',
+       'serverless' => false
+);
+
+$ourdb['postgres'] = array(
+       'fullname'   => 'PostgreSQL',
+       'havedriver' => 0,
+       'compile'    => 'pgsql',
+       'bgcolor'    => '#aaccff',
+       'rootuser'   => 'postgres',
+       'serverless' => false
+);
+
+$ourdb['sqlite'] = array(
+       'fullname'   => 'SQLite',
+       'havedriver' => 0,
+       'compile'    => 'pdo_sqlite',
+       'bgcolor'    => '#b1ebb1',
+       'rootuser'   => '',
+       'serverless' =>  true
+);
+
+$ourdb['mssql'] = array(
+       'fullname'   => 'MSSQL',
+       'havedriver' => 0,
+       'compile'    => 'mssql_not_ready', # Change to 'mssql' after includes/DatabaseMssql.php added;
+       'bgcolor'    => '#ffc0cb',
+       'rootuser'   => 'administrator',
+       'serverless' => false
+);
+
+$ourdb['ibm_db2'] = array(
+       'fullname'   => 'DB2',
+       'havedriver' => 0,
+       'compile'    => 'ibm_db2',
+       'bgcolor'    => '#ffeba1',
+       'rootuser'   => 'db2admin',
+       'serverless' => false
+);
+
+$ourdb['oracle'] = array(
+       'fullname'   => 'Oracle',
+       'havedriver' => 0,
+       'compile'    => 'oci8',
+       'bgcolor'    => '#ffeba1',
+       'rootuser'   => 'sys',
+       'serverless' => false
+);
 
 ?>
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
@@ -178,6 +199,7 @@ $ourdb['oracle']['rootuser']   = '';
                        font-size: 110%;
                        color: green;
                }
+
                .success-box {
                        font-size: 130%;
                }
@@ -185,23 +207,25 @@ $ourdb['oracle']['rootuser']   = '';
        </style>
        <script type="text/javascript">
        <!--
+       <?php echo 'var databases = ' . FormatJson::encode( $ourdb ) . ';'; ?>
+       
+       function show(id, showOrHide) {
+               var i = document.getElementById(id);
+               if (i) i.style.display = showOrHide ? 'block' : 'none';
+       }
        function hideall() {
-               <?php foreach (array_keys($ourdb) as $db) {
-               echo "\n                var i = document.getElementById('$db'); if (i) i.style.display='none';";
+               for (db in databases) {
+                       show(db, false);
                }
-               ?>
-
        }
-       function toggleDBarea(id,defaultroot) {
+       function toggleDBarea(id, defaultroot) {
                hideall();
                var dbarea = document.getElementById(id);
                if (dbarea) dbarea.style.display = (dbarea.style.display == 'none') ? 'block' : 'none';
                var db = document.getElementById('RootUser');
-               if (defaultroot) {
-<?php foreach (array_keys($ourdb) as $db) {
-                       echo "                  if (id == '$db') { db.value = '".$ourdb[$db]['rootuser']."';}\n";
-}?>
-               }
+               db.value = databases[id].rootuser;
+               show('db-server-settings1', !databases[id].serverless);
+               show('db-server-settings2', !databases[id].serverless);
        }
        // -->
        </script>
@@ -635,8 +659,8 @@ print "<li style='font-weight:bold;color:green;font-size:110%'>Environment check
 
        ## Postgres specific:
        $conf->DBport      = importPost( "DBport",      "5432" );
-       $conf->DBmwschema  = importPost( "DBmwschema",  "mediawiki" );
        $conf->DBts2schema = importPost( "DBts2schema", "public" );
+       $conf->DBpgschema  = importPost( "DBpgschema",  "mediawiki" );
        
        ## SQLite specific
        $conf->SQLiteDataDir = importPost( "SQLiteDataDir", "" );
@@ -648,8 +672,8 @@ print "<li style='font-weight:bold;color:green;font-size:110%'>Environment check
        ## DB2 specific:
        // New variable in order to have a different default port number
        $conf->DBport_db2   = importPost( "DBport_db2",      "50000" );
-       $conf->DBmwschema   = importPost( "DBmwschema",  "mediawiki" );
        $conf->DBcataloged  = importPost( "DBcataloged",  "cataloged" );
+       $conf->DBdb2schema  = importPost( "DBdb2schema",  "mediawiki" );
 
        // Oracle specific
        $conf->DBprefix_ora     = importPost( "DBprefix_ora" );
@@ -664,17 +688,19 @@ $errs = array();
 if( preg_match( '/^$|^mediawiki$|#/i', $conf->Sitename ) ) {
        $errs["Sitename"] = "Must not be blank or \"MediaWiki\" and may not contain \"#\"";
 }
-if( $conf->DBuser == "" ) {
-       $errs["DBuser"] = "Must not be blank";
-}
-if( ($conf->DBtype == 'mysql') && (strlen($conf->DBuser) > 16) ) {
-       $errs["DBuser"] = "Username too long";
-}
-if( $conf->DBpassword == "" && $conf->DBtype != "postgres" ) {
-       $errs["DBpassword"] = "Must not be blank";
-}
-if( $conf->DBpassword != $conf->DBpassword2 ) {
-       $errs["DBpassword2"] = "Passwords don't match!";
+if( !$ourdb[$conf->DBtype]['serverless'] ) {
+       if( $conf->DBuser == "" ) {
+               $errs["DBuser"] = "Must not be blank";
+       }
+       if( ($conf->DBtype == 'mysql') && (strlen($conf->DBuser) > 16) ) {
+               $errs["DBuser"] = "Username too long";
+       }
+       if( $conf->DBpassword == "" && $conf->DBtype != "postgres" ) {
+               $errs["DBpassword"] = "Must not be blank";
+       }
+       if( $conf->DBpassword != $conf->DBpassword2 ) {
+               $errs["DBpassword2"] = "Passwords don't match!";
+       }
 }
 if( !preg_match( '/^[A-Za-z_0-9]*$/', $conf->DBprefix ) ) {
        $errs["DBprefix"] = "Invalid table prefix";
@@ -713,7 +739,7 @@ if( $conf->SysopName ) {
                # Various password checks
                if( $conf->SysopPass != '' ) {
                        if( $conf->SysopPass == $conf->SysopPass2 ) {
-                               if( $u->isValidPassword( $conf->SysopPass ) !== true ) {
+                               if( !$u->isValidPassword( $conf->SysopPass ) ) {
                                        $errs['SysopPass'] = "Bad password";
                                }
                        } else {
@@ -823,9 +849,14 @@ if( $conf->posted && ( 0 == count( $errs ) ) ) {
 
                ## Postgres specific:
                $wgDBport      = $conf->DBport;
-               $wgDBmwschema  = $conf->DBmwschema;
                $wgDBts2schema = $conf->DBts2schema;
 
+               if( $wgDBtype == 'postgres' ) {
+                       $wgDBmwschema = $conf->DBpgschema;
+               } elseif ( $wgDBtype == 'ibm_db2' ) {
+                       $wgDBmwschema = $conf->DBdb2schema;
+               }
+
                if( $conf->DBprefix2 != '' ) {
                        // For MSSQL
                        $wgDBprefix = $conf->DBprefix2;
@@ -944,8 +975,8 @@ if( $conf->posted && ( 0 == count( $errs ) ) ) {
                        if ("$wgSQLiteDataDir" == '') {
                                $wgSQLiteDataDir = dirname($_SERVER['DOCUMENT_ROOT']).'/data';
                        }
-                       echo "<li>Attempting to connect to SQLite database at \"" . 
-                               htmlspecialchars( $wgSQLiteDataDir ) .  "\"";
+                       echo '<li>Attempting to connect to SQLite database at "' . 
+                               htmlspecialchars( $wgSQLiteDataDir ) . '": ';
                        if ( !is_dir( $wgSQLiteDataDir ) ) {
                                if ( is_writable( dirname( $wgSQLiteDataDir ) ) ) {
                                        $ok = wfMkdirParents( $wgSQLiteDataDir, $wgSQLiteDataDirMode );
@@ -953,25 +984,40 @@ if( $conf->posted && ( 0 == count( $errs ) ) ) {
                                        $ok = false;
                                }
                                if ( !$ok ) {
-                                       echo "cannot create data directory</li>";
+                                       echo "cannot create data directory</li>";
                                        $errs['SQLiteDataDir'] = 'Enter a valid data directory';
                                        continue;
                                }
                        }
                        if ( !is_writable( $wgSQLiteDataDir ) ) {
-                               echo "data directory not writable</li>";
+                               echo "data directory not writable</li>";
                                $errs['SQLiteDataDir'] = 'Enter a writable data directory';
                                continue;
                        }
-                       $dataFile = "$wgSQLiteDataDir/$wgDBname.sqlite";
-                       if ( file_exists( $dataFile ) && !is_writable( $dataFile ) ) {
-                               echo ": data file not writable</li>";
-                               $errs['SQLiteDataDir'] = "$wgDBname.sqlite is not writable";
+                       $dataFile = DatabaseSqlite::generateFileName( $wgSQLiteDataDir, $wgDBname );
+                       if ( file_exists( $dataFile ) ) {
+                               if ( !is_writable( $dataFile ) ) {
+                                       echo "data file not writable</li>";
+                                       $errs['SQLiteDataDir'] = basename( $dataFile ) . " is not writable";
+                                       continue;
+                               }
+                       } else {
+                               if ( file_put_contents( $dataFile, '' ) === false ) {
+                                       echo 'could not create database file "' . htmlspecialchars( basename( $dataFile ) ) . "\"</li>\n";
+                                       $errs['SQLiteDataDir'] = "couldn't create " . basename( $dataFile );
+                                       continue;
+                               }
+                       }
+                       try {
+                               $wgDatabase = new DatabaseSqlite( false, false, false, $wgDBname, 1 );
+                       }
+                       catch( MWException $ex ) {
+                               echo 'error: ' . htmlspecialchars( $ex->getMessage() ) . "</li>\n";
                                continue;
                        }
-                       $wgDatabase = new DatabaseSqlite( false, false, false, $wgDBname, 1 );
+                       
                        if (!$wgDatabase->isOpen()) {
-                               print "error: " . htmlspecialchars( $wgDatabase->lastError() ) . "</li>\n";
+                               print "error: " . htmlspecialchars( $wgDatabase->lastError() ) . "</li>\n";
                                $errs['SQLiteDataDir'] = 'Could not connect to database';
                                continue;
                        } else {
@@ -981,7 +1027,10 @@ if( $conf->posted && ( 0 == count( $errs ) ) ) {
                        echo "ok</li>\n";
                } elseif ( $conf->DBtype == 'oracle' ) {
                        echo "<li>Attempting to connect to database \"" . htmlspecialchars( $wgDBname ) ."\"</li>";
+                       $old_error_level = error_reporting();
+                       error_reporting($old_error_level & ~E_WARNING); //disable E_WARNING for test connect (oci returns login denied as warning)
                        $wgDatabase = $dbc->newFromParams('DUMMY', $wgDBuser, $wgDBpassword, $wgDBname, 1);
+                       error_reporting($old_error_level);
                        if (!$wgDatabase->isOpen()) {
                                $ok = true;
                                echo "<li>Connect failed.</li>";
@@ -1222,7 +1271,7 @@ if( $conf->posted && ( 0 == count( $errs ) ) ) {
                        print " done.</li>\n";
                        
                
-                       if ($conf->DBtype == 'ibm_db2') {
+                       if ( $conf->DBtype == 'ibm_db2' ) {
                                // Now that table creation is done, make sure everything is committed
                                // Do this before doing inserts through API
                                if ($wgDatabase->lastError()) {
@@ -1233,6 +1282,10 @@ if( $conf->posted && ( 0 == count( $errs ) ) ) {
                                        print "<li>MediaWiki tables successfully created</li>\n";
                                        $wgDatabase->commit();
                                }
+                       } elseif ( $conf->DBtype == 'sqlite' ) {
+                               // Ensure proper searchindex format. We have to do that separately because
+                               // if SQLite is compiled without the FTS3 module, table creation syntax will be invalid.
+                               sqlite_setup_searchindex();
                        }
 
                        print "<li>Initializing statistics...</li>\n";
@@ -1538,38 +1591,42 @@ if( count( $errs ) ) {
        ?></ul>
        </div>
 
-       <div class="config-input" style="clear:left">
-       <?php aField( $conf, "DBserver", "Database host:" ); ?>
+       <div id="db-server-settings1">
+               <div class="config-input" style="clear:left">
+               <?php aField( $conf, "DBserver", "Database host:" ); ?>
+               </div>
+               <p class="config-desc">
+                       If your database server isn't on your web server, enter the name or IP address here.
+               </p>
        </div>
-       <p class="config-desc">
-               If your database server isn't on your web server, enter the name or IP address here.
-       </p>
-
-       <div class="config-input"><?php aField( $conf, "DBname", "Database name:" ); ?></div>
-       <div class="config-input"><?php aField( $conf, "DBuser", "DB username:" ); ?></div>
-       <div class="config-input"><?php aField( $conf, "DBpassword", "DB password:", "password" ); ?></div>
-       <div class="config-input"><?php aField( $conf, "DBpassword2", "DB password confirm:", "password" ); ?></div>
-       <p class="config-desc">
-               If you only have a single user account and database available,
-               enter those here. If you have database root access (see below)
-               you can specify new accounts/databases to be created. This account 
-               will not be created if it pre-exists. If this is the case, ensure that it
-               has SELECT, INSERT, UPDATE, and DELETE permissions on the MediaWiki database.
-       </p>
 
-       <div class="config-input">
-               <label class="column">Superuser account:</label>
-               <input type="checkbox" name="useroot" id="useroot" <?php if( $useRoot ) { ?>checked="checked" <?php } ?> />
-               &nbsp;<label for="useroot">Use superuser account</label>
+               <div class="config-input"><?php aField( $conf, "DBname", "Database name:" ); ?></div>
+       <div id="db-server-settings2">
+               <div class="config-input"><?php aField( $conf, "DBuser", "DB username:" ); ?></div>
+               <div class="config-input"><?php aField( $conf, "DBpassword", "DB password:", "password" ); ?></div>
+               <div class="config-input"><?php aField( $conf, "DBpassword2", "DB password confirm:", "password" ); ?></div>
+               <p class="config-desc">
+                       If you only have a single user account and database available,
+                       enter those here. If you have database root access (see below)
+                       you can specify new accounts/databases to be created. This account 
+                       will not be created if it pre-exists. If this is the case, ensure that it
+                       has SELECT, INSERT, UPDATE, and DELETE permissions on the MediaWiki database.
+               </p>
+
+               <div class="config-input">
+                       <label class="column">Superuser account:</label>
+                       <input type="checkbox" name="useroot" id="useroot" <?php if( $useRoot ) { ?>checked="checked" <?php } ?> />
+                       &nbsp;<label for="useroot">Use superuser account</label>
+               </div>
+               <div class="config-input"><?php aField( $conf, "RootUser", "Superuser name:", "text" ); ?></div>
+               <div class="config-input"><?php aField( $conf, "RootPW", "Superuser password:", "password" ); ?></div>
+
+               <p class="config-desc">
+                       If the database user specified above does not exist, or does not have access to create
+                       the database (if needed) or tables within it, please check the box and provide details
+                       of a superuser account, such as <strong>root</strong>, which does.
+               </p>
        </div>
-       <div class="config-input"><?php aField( $conf, "RootUser", "Superuser name:", "text" ); ?></div>
-       <div class="config-input"><?php aField( $conf, "RootPW", "Superuser password:", "password" ); ?></div>
-
-       <p class="config-desc">
-               If the database user specified above does not exist, or does not have access to create
-               the database (if needed) or tables within it, please check the box and provide details
-               of a superuser account, such as <strong>root</strong>, which does.
-       </p>
 
        <?php database_switcher('mysql'); ?>
        <div class="config-input"><?php aField( $conf, "DBprefix", "Database table prefix:" ); ?></div>
@@ -1612,7 +1669,7 @@ if( count( $errs ) ) {
 
        <?php database_switcher('postgres'); ?>
        <div class="config-input"><?php aField( $conf, "DBport", "Database port:" ); ?></div>
-       <div class="config-input"><?php aField( $conf, "DBmwschema", "Schema for mediawiki:" ); ?></div>
+       <div class="config-input"><?php aField( $conf, "DBpgschema", "Schema for mediawiki:" ); ?></div>
        <div class="config-input"><?php aField( $conf, "DBts2schema", "Schema for tsearch2:" ); ?></div>
        <div class="config-desc">
                <p>The username specified above (at "DB username") will have its search path set to the above schemas, 
@@ -1622,9 +1679,6 @@ if( count( $errs ) ) {
        </fieldset>
 
        <?php database_switcher('sqlite'); ?>
-       <div class="config-desc">
-               <b>NOTE:</b> SQLite only uses the <i>Database name</i> setting above, the user, password and root settings are ignored.
-       </div>
        <div class="config-input"><?php
                aField( $conf, "SQLiteDataDir", "SQLite data directory:" );
        ?></div>
@@ -1655,7 +1709,7 @@ if( count( $errs ) ) {
                aField( $conf, "DBport_db2", "Database port:" );
        ?></div>
        <div class="config-input"><?php
-               aField( $conf, "DBmwschema", "Schema for mediawiki:" );
+               aField( $conf, "DBdb2schema", "Schema for mediawiki:" );
        ?></div>
        <div>Select one:</div>
                <ul class="plain">
@@ -1841,7 +1895,7 @@ function writeLocalSettings( $conf ) {
                $dbsettings =
 "# Postgres specific settings
 \$wgDBport           = \"{$slconf['DBport']}\";
-\$wgDBmwschema       = \"{$slconf['DBmwschema']}\";
+\$wgDBmwschema       = \"{$slconf['DBpgschema']}\";
 \$wgDBts2schema      = \"{$slconf['DBts2schema']}\";";
        } elseif( $conf->DBtype == 'sqlite' ) {
                $dbsettings =
@@ -1855,7 +1909,7 @@ function writeLocalSettings( $conf ) {
                $dbsettings =
 "# DB2 specific settings
 \$wgDBport_db2       = \"{$slconf['DBport_db2']}\";
-\$wgDBmwschema       = \"{$slconf['DBmwschema']}\";
+\$wgDBmwschema       = \"{$slconf['DBdb2schema']}\";
 \$wgDBcataloged      = \"{$slconf['DBcataloged']}\";";
        } elseif( $conf->DBtype == 'oracle' ) {
                $dbsettings =
@@ -1909,6 +1963,13 @@ if ( \$wgCommandLineMode ) {
 \$wgScriptPath       = \"{$slconf['ScriptPath']}\";
 \$wgScriptExtension  = \"{$slconf['ScriptExtension']}\";
 
+## The relative URL path to the skins directory 
+\$wgStylePath        = \"\$wgScriptPath/skins\";
+
+## The relative URL path to the logo.  Make sure you change this from the default,
+## or else you'll overwrite your logo when you upgrade!
+\$wgLogo             = \"\$wgStylePath/common/images/wiki.png\";
+
 ## UPO means: this is also a user preference option
 
 \$wgEnableEmail      = $enableemail;
@@ -2092,6 +2153,7 @@ function getLanguageList() {
                $m = array();
                if( preg_match( '/Messages([A-Z][a-z_]+)\.php$/', $f, $m ) ) {
                        $code = str_replace( '_', '-', strtolower( $m[1] ) );
+                       if( $code == 'qqq' ) continue;
                        if( isset( $wgLanguageNames[$code] ) ) {
                                $name = wfBCP47( $code ) . ' - ' . $wgLanguageNames[$code];
                        } else {
@@ -2188,7 +2250,7 @@ function database_switcher($db) {
        global $ourdb;
        $color = $ourdb[$db]['bgcolor'];
        $full = $ourdb[$db]['fullname'];
-       print "<fieldset id='$db'><legend>$full specific options</legend>\n";
+       print "<fieldset id='$db' style='clear:both'><legend>$full-specific options</legend>\n";
 }
 
 function printListItem( $item ) {
@@ -2199,7 +2261,7 @@ function printListItem( $item ) {
 function getShellLocale( $wikiLang ) {
        # Give up now if we're in safe mode or open_basedir
        # It's theoretically possible but tricky to work with
-       if ( wfIniGetBool( "safe_mode" ) || ini_get( 'open_basedir' ) ) {
+       if ( wfIniGetBool( "safe_mode" ) || ini_get( 'open_basedir' ) || !function_exists('exec') ) {
                return false;
        }