]> scripts.mit.edu Git - autoinstalls/mediawiki.git/blob - config/Installer.php
MediaWiki 1.16.3-scripts
[autoinstalls/mediawiki.git] / config / Installer.php
1 <?php
2
3 # MediaWiki web-based config/installation
4 # Copyright (C) 2004 Brion Vibber <brion@pobox.com>, 2006 Rob Church <robchur@gmail.com>
5 # http://www.mediawiki.org/
6 #
7 # This program is free software; you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 2 of the License, or
10 # (at your option) any later version.
11 #
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
16 #
17 # You should have received a copy of the GNU General Public License along
18 # with this program; if not, write to the Free Software Foundation, Inc.,
19 # 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
20 # http://www.gnu.org/copyleft/gpl.html
21
22 if( !defined( 'MEDIAWIKI_INSTALL' ) ) {
23         die( 'Not an entry point.' );
24 }
25
26 error_reporting( E_ALL | E_STRICT );
27 header( "Content-type: text/html; charset=utf-8" );
28 header( 'X-Frame-Options: DENY' );
29 @ini_set( "display_errors", true );
30
31 # In case of errors, let output be clean.
32 $wgRequestTime = microtime( true );
33
34 // Run version checks before including other files
35 // so people don't see a scary parse error.
36 require_once( "$IP/maintenance/install-utils.inc" );
37 install_version_checks();
38
39 require_once( "$IP/includes/Defines.php" );
40 require_once( "$IP/includes/DefaultSettings.php" );
41 require_once( "$IP/includes/AutoLoader.php" );
42 require_once( "$IP/includes/MagicWord.php" );
43 require_once( "$IP/includes/Namespace.php" );
44 require_once( "$IP/includes/ProfilerStub.php" );
45 require_once( "$IP/includes/GlobalFunctions.php" );
46 require_once( "$IP/includes/Hooks.php" );
47 require_once( "$IP/includes/Exception.php" );
48 require_once( "$IP/includes/json/Services_JSON.php" );
49 require_once( "$IP/includes/json/FormatJson.php" );
50
51 $wgMaxShellMemory = 0;
52
53 # If we get an exception, the user needs to know
54 # all the details
55 $wgShowExceptionDetails = true;
56 $wgShowSQLErrors = true;
57 wfInstallExceptionHandler();
58 ## Databases we support:
59
60 $ourdb = array();
61
62 $ourdb['mysql'] = array(
63         'fullname'   => 'MySQL',
64         'havedriver' => 0,
65         'compile'    => 'mysql',
66         'bgcolor'    => '#ffe5a7',
67         'rootuser'   => 'root',
68         'serverless' => false
69 );
70
71 $ourdb['postgres'] = array(
72         'fullname'   => 'PostgreSQL',
73         'havedriver' => 0,
74         'compile'    => 'pgsql',
75         'bgcolor'    => '#aaccff',
76         'rootuser'   => 'postgres',
77         'serverless' => false
78 );
79
80 $ourdb['sqlite'] = array(
81         'fullname'   => 'SQLite',
82         'havedriver' => 0,
83         'compile'    => 'pdo_sqlite',
84         'bgcolor'    => '#b1ebb1',
85         'rootuser'   => '',
86         'serverless' =>  true
87 );
88
89 $ourdb['mssql'] = array(
90         'fullname'   => 'MSSQL',
91         'havedriver' => 0,
92         'compile'    => 'mssql_not_ready', # Change to 'mssql' after includes/DatabaseMssql.php added;
93         'bgcolor'    => '#ffc0cb',
94         'rootuser'   => 'administrator',
95         'serverless' => false
96 );
97
98 $ourdb['ibm_db2'] = array(
99         'fullname'   => 'DB2',
100         'havedriver' => 0,
101         'compile'    => 'ibm_db2',
102         'bgcolor'    => '#ffeba1',
103         'rootuser'   => 'db2admin',
104         'serverless' => false
105 );
106
107 $ourdb['oracle'] = array(
108         'fullname'   => 'Oracle',
109         'havedriver' => 0,
110         'compile'    => 'oci8',
111         'bgcolor'    => '#ffeba1',
112         'rootuser'   => 'sys',
113         'serverless' => false
114 );
115
116 ?>
117 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
118 <html xmlns="http://www.w3.org/1999/xhtml" lang="en" dir="ltr">
119 <head>
120         <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
121         <meta name="robots" content="noindex,nofollow"/>
122         <title>MediaWiki <?php echo htmlspecialchars( $wgVersion ); ?> Installation</title>
123         <style type="text/css">
124
125                 @import "../skins/monobook/main.css";
126
127                 .env-check {
128                         font-size: 90%;
129                         margin: 1em 0 1em 2.5em;
130                 }
131
132                 .config-section {
133                         margin-top: 2em;
134                 }
135
136                 .config-section label.column {
137                         clear: left;
138                         font-weight: bold;
139                         width: 13em;
140                         float: left;
141                         text-align: right;
142                         padding-right: 1em;
143                         padding-top: .2em;
144                 }
145
146                 .config-input {
147                         clear: left;
148                         zoom: 100%; /* IE hack */
149                 }
150
151                 .config-section .config-desc {
152                         clear: left;
153                         margin: 0 0 2em 18em;
154                         padding-top: 1em;
155                         font-size: 85%;
156                 }
157
158                 .iput-text, .iput-password {
159                         width: 14em;
160                         margin-right: 1em;
161                 }
162
163                 .error {
164                         color: red;
165                         background-color: #fff;
166                         font-weight: bold;
167                         left: 1em;
168                         font-size: 100%;
169                 }
170
171                 .error-top {
172                         color: red;
173                         background-color: #FFF0F0;
174                         border: 2px solid red;
175                         font-size: 130%;
176                         font-weight: bold;
177                         padding: 1em 1.5em;
178                         margin: 2em 0 1em;
179                 }
180
181                 ul.plain {
182                         list-style-type: none;
183                         list-style-image: none;
184                         float: left;
185                         margin: 0;
186                         padding: 0;
187                 }
188
189                 .btn-install {
190                         font-weight: bold;
191                         font-size: 110%;
192                         padding: .2em .3em;
193                 }
194
195                 .license {
196                         font-size: 85%;
197                         padding-top: 3em;
198                 }
199
200                 span.success-message {
201                         font-weight: bold;
202                         font-size: 110%;
203                         color: green;
204                 }
205
206                 .success-box {
207                         font-size: 130%;
208                 }
209
210         </style>
211         <script type="text/javascript">
212         <!--
213         <?php echo 'var databases = ' . FormatJson::encode( $ourdb ) . ';'; ?>
214
215         function show(id, showOrHide) {
216                 var i = document.getElementById(id);
217                 if (i) i.style.display = showOrHide ? 'block' : 'none';
218         }
219         function hideall() {
220                 for (db in databases) {
221                         show(db, false);
222                 }
223         }
224         function toggleDBarea(id, defaultroot) {
225                 hideall();
226                 var dbarea = document.getElementById(id);
227                 if (dbarea) dbarea.style.display = (dbarea.style.display == 'none') ? 'block' : 'none';
228                 var db = document.getElementById('RootUser');
229                 db.value = databases[id].rootuser;
230                 show('db-server-settings1', !databases[id].serverless);
231                 show('db-server-settings2', !databases[id].serverless);
232         }
233         // -->
234         </script>
235 </head>
236
237 <body>
238 <div id="globalWrapper">
239 <div id="column-content">
240 <div id="content">
241 <div id="bodyContent">
242
243 <h1>MediaWiki <?php print htmlspecialchars( $wgVersion ) ?> Installation</h1>
244
245 <?php
246 $mainListOpened = false; # Is the main list (environement checking) opend ? Used by dieout
247
248 /* Check for existing configurations and bug out! */
249
250 if( file_exists( "../LocalSettings.php" ) ) {
251         $script = defined('MW_INSTALL_PHP5_EXT') ? 'index.php5' : 'index.php';
252         dieout( "<p><strong>Setup has completed, <a href='../$script'>your wiki</a> is configured.</strong></p>
253         <p>Please delete the /config directory for extra security.</p>" );
254 }
255
256 if( file_exists( "./LocalSettings.php" ) ) {
257         writeSuccessMessage();
258         dieout( '' );
259 }
260
261 if( !is_writable( "." ) ) {
262         dieout( "<h2>Can't write config file, aborting</h2>
263
264         <p>In order to configure the wiki you have to make the <tt>config</tt> subdirectory
265         writable by the web server. Once configuration is done you'll move the created
266         <tt>LocalSettings.php</tt> to the parent directory, and for added safety you can
267         then remove the <tt>config</tt> subdirectory entirely.</p>
268
269         <p>To make the directory writable on a Unix/Linux system:</p>
270
271         <pre>
272         cd <i>" . htmlspecialchars( dirname( dirname( __FILE__ ) ) ) . "</i>
273         chmod a+w config
274         </pre>
275
276         <p>Afterwards retry to start the <a href=\"\">setup</a>.</p>" );
277 }
278
279
280 require_once( "$IP/maintenance/updaters.inc" );
281
282 class ConfigData {
283         function getEncoded( $data ) {
284                 # removing latin1 support, no need...
285                 return $data;
286         }
287         function getSitename() { return $this->getEncoded( $this->Sitename ); }
288         function getSysopName() { return $this->getEncoded( $this->SysopName ); }
289         function getSysopPass() { return $this->getEncoded( $this->SysopPass ); }
290
291         function setSchema( $schema, $engine ) {
292                 $this->DBschema = $schema;
293                 if ( !preg_match( '/^\w*$/', $engine ) ){
294                         $engine = 'InnoDB';
295                 }
296                 switch ( $this->DBschema ) {
297                         case 'mysql5':
298                                 $this->DBTableOptions = "ENGINE=$engine, DEFAULT CHARSET=utf8";
299                                 $this->DBmysql5 = 'true';
300                                 break;
301                         case 'mysql5-binary':
302                                 $this->DBTableOptions = "ENGINE=$engine, DEFAULT CHARSET=binary";
303                                 $this->DBmysql5 = 'true';
304                                 break;
305                         default:
306                                 $this->DBTableOptions = "TYPE=$engine";
307                                 $this->DBmysql5 = 'false';
308                 }
309                 $this->DBengine = $engine;
310
311                 # Set the global for use during install
312                 global $wgDBTableOptions;
313                 $wgDBTableOptions = $this->DBTableOptions;
314         }
315 }
316
317 ?>
318
319 <ul>
320         <li>
321                 <b>Don't forget security updates!</b> Keep an eye on the
322                 <a href="http://lists.wikimedia.org/mailman/listinfo/mediawiki-announce">low-traffic
323                 release announcements mailing list</a>.
324         </li>
325 </ul>
326
327
328 <h2>Checking environment...</h2>
329 <p><em>Please include all of the lines below when reporting installation problems.</em></p>
330 <ul class="env-check">
331 <?php
332 $mainListOpened = true;
333
334 $endl = "
335 ";
336 define( 'MW_NO_OUTPUT_BUFFER', 1 );
337 $conf = new ConfigData;
338
339 install_version_checks();
340 $self = 'Installer'; # Maintenance script name, to please Setup.php
341
342 print "<li>PHP " . htmlspecialchars( phpversion() ) . " installed</li>\n";
343
344 error_reporting( 0 );
345 $phpdatabases = array();
346 foreach (array_keys($ourdb) as $db) {
347         $compname = $ourdb[$db]['compile'];
348         if( extension_loaded( $compname ) || ( mw_have_dl() && dl( "{$compname}." . PHP_SHLIB_SUFFIX ) ) ) {
349                 array_push($phpdatabases, $db);
350                 $ourdb[$db]['havedriver'] = 1;
351         }
352 }
353 error_reporting( E_ALL | E_STRICT );
354
355 if (!$phpdatabases) {
356         print "Could not find a suitable database driver!<ul>";
357         foreach (array_keys($ourdb) AS $db) {
358                 $comp = $ourdb[$db]['compile'];
359                 $full = $ourdb[$db]['fullname'];
360                 print "<li>For <b>$full</b>, compile PHP using <b>--with-$comp</b>, "
361                         ."or install the $comp.so module</li>\n";
362         }
363         echo '</ul>';
364         dieout( '' );
365 }
366
367 print "<li>Found database drivers for:";
368 $DefaultDBtype = '';
369 foreach (array_keys($ourdb) AS $db) {
370         if ($ourdb[$db]['havedriver']) {
371                 if ( $DefaultDBtype == '' ) {
372                         $DefaultDBtype = $db;
373                 }
374                 print "  ".$ourdb[$db]['fullname'];
375         }
376 }
377 print "</li>\n";
378
379 if( wfIniGetBool( "register_globals" ) ) {
380         ?>
381         <li>
382                 <div style="font-size:110%">
383                 <strong class="error">Warning:</strong>
384                 <strong>PHP's <tt><a href="http://php.net/register_globals">register_globals</a></tt> option is enabled. Disable it if you can.</strong>
385                 </div>
386                 MediaWiki will work, but your server is more exposed to PHP-based security vulnerabilities.
387         </li>
388         <?php
389 }
390
391 $fatal = false;
392
393 if( wfIniGetBool( "magic_quotes_runtime" ) ) {
394         $fatal = true;
395         ?><li class='error'><strong>Fatal: <a href='http://www.php.net/manual/en/ref.info.php#ini.magic-quotes-runtime'>magic_quotes_runtime</a> is active!</strong>
396         This option corrupts data input unpredictably; you cannot install or use
397         MediaWiki unless this option is disabled.</li>
398         <?php
399 }
400
401 if( wfIniGetBool( "magic_quotes_sybase" ) ) {
402         $fatal = true;
403         ?><li class='error'><strong>Fatal: <a href='http://www.php.net/manual/en/ref.sybase.php#ini.magic-quotes-sybase'>magic_quotes_sybase</a> is active!</strong>
404         This option corrupts data input unpredictably; you cannot install or use
405         MediaWiki unless this option is disabled.</li>
406         <?php
407 }
408
409 if( wfIniGetBool( "mbstring.func_overload" ) ) {
410         $fatal = true;
411         ?><li class='error'><strong>Fatal: <a href='http://www.php.net/manual/en/ref.mbstring.php#mbstring.overload'>mbstring.func_overload</a> is active!</strong>
412         This option causes errors and may corrupt data unpredictably;
413         you cannot install or use MediaWiki unless this option is disabled.</li>
414         <?php
415 }
416
417 if( wfIniGetBool( "zend.ze1_compatibility_mode" ) ) {
418         $fatal = true;
419         ?><li class="error"><strong>Fatal: <a href="http://www.php.net/manual/en/ini.core.php">zend.ze1_compatibility_mode</a> is active!</strong>
420         This option causes horrible bugs with MediaWiki; you cannot install or use
421         MediaWiki unless this option is disabled.</li>
422         <?php
423 }
424
425 if( $fatal ) {
426         dieout( "Cannot install MediaWiki." );
427 }
428
429 if( wfIniGetBool( "safe_mode" ) ) {
430         $conf->safeMode = true;
431         ?>
432         <li><b class='error'>Warning:</b> <strong>PHP's
433         <a href='http://www.php.net/features.safe-mode'>safe mode</a> is active.</strong>
434         You may have problems caused by this, particularly if using image uploads.
435         </li>
436         <?php
437 } else {
438         $conf->safeMode = false;
439 }
440
441 $sapi = htmlspecialchars( php_sapi_name() );
442 print "<li>PHP server API is $sapi; ";
443 $script = defined('MW_INSTALL_PHP5_EXT') ? 'index.php5' : 'index.php';
444 if( $wgUsePathInfo ) {
445  print "ok, using pretty URLs (<tt>$script/Page_Title</tt>)";
446 } else {
447         print "using ugly URLs (<tt>$script?title=Page_Title</tt>)";
448 }
449 print "</li>\n";
450
451 $conf->xml = function_exists( "utf8_encode" );
452 if( $conf->xml ) {
453         print "<li>Have XML / Latin1-UTF-8 conversion support.</li>\n";
454 } else {
455         dieout( "PHP's XML module is missing; the wiki requires functions in
456                 this module and won't work in this configuration.
457                 If you're running Mandrake, install the php-xml package." );
458 }
459
460 # Check for session support
461 if( !function_exists( 'session_name' ) )
462         dieout( "PHP's session module is missing. MediaWiki requires session support in order to function." );
463
464 # session.save_path doesn't *have* to be set, but if it is, and it's
465 # not valid/writable/etc. then it can cause problems
466 $sessionSavePath = mw_get_session_save_path();
467 $ssp = htmlspecialchars( $sessionSavePath );
468 # Warn the user if it's not set, but let them proceed
469 if( !$sessionSavePath ) {
470         print "<li><strong>Warning:</strong> A value for <tt>session.save_path</tt>
471         has not been set in PHP.ini. If the default value causes problems with
472         saving session data, set it to a valid path which is read/write/execute
473         for the user your web server is running under.</li>";
474 } elseif ( is_dir( $sessionSavePath ) && is_writable( $sessionSavePath ) ) {
475         # All good? Let the user know
476         print "<li>Session save path (<tt>{$ssp}</tt>) appears to be valid.</li>";
477 } else {
478         # Something not right? Warn the user, but let them proceed
479         print "<li><strong>Warning:</strong> Your <tt>session.save_path</tt> value (<tt>{$ssp}</tt>)
480                 appears to be invalid or is not writable. PHP needs to be able to save data to
481                 this location for correct session operation.</li>";
482 }
483
484 # Check for PCRE support
485 if( !function_exists( 'preg_match' ) )
486         dieout( "The PCRE support module appears to be missing. MediaWiki requires the
487         Perl-compatible regular expression functions." );
488
489 # The installer can take a while, and we really don't want it to time out
490 wfSuppressWarnings();
491 set_time_limit( 0 );
492 wfRestoreWarnings();
493
494 $memlimit = ini_get( "memory_limit" );
495 if( $memlimit == -1 ) {
496         print "<li>PHP is configured with no <tt>memory_limit</tt>.</li>\n";
497 } else {
498         print "<li>PHP's <tt>memory_limit</tt> is " . htmlspecialchars( $memlimit ). " bytes. ";
499         $newlimit = wfMemoryLimit();
500         $memlimit = wfShorthandToInteger( $memlimit );
501         if( $newlimit < $memlimit ) {
502                 print "<b>Failed raising limit, installation may fail.</b>";
503         } elseif ( $newlimit > $memlimit )  {
504                 print "Raised <tt>memory_limit</tt> to " . htmlspecialchars( $newlimit ) . " bytes. ";
505         }
506         print "</li>\n";
507 }
508
509 $conf->xcache = function_exists( 'xcache_get' );
510 if( $conf->xcache )
511         print "<li><a href=\"http://trac.lighttpd.net/xcache/\">XCache</a> installed</li>\n";
512
513 $conf->apc = function_exists('apc_fetch');
514 if ($conf->apc ) {
515         print "<li><a href=\"http://www.php.net/apc\">APC</a> installed</li>\n";
516 }
517
518 $conf->eaccel = function_exists( 'eaccelerator_get' );
519 if ( $conf->eaccel ) {
520         print "<li><a href=\"http://eaccelerator.sourceforge.net/\">eAccelerator</a> installed</li>\n";
521 }
522
523 $conf->dba = function_exists( 'dba_open' );
524
525 if( !( $conf->eaccel || $conf->apc || $conf->xcache ) ) {
526         echo( '<li>Couldn\'t find <a href="http://eaccelerator.sourceforge.net">eAccelerator</a>,
527                 <a href="http://www.php.net/apc">APC</a> or <a href="http://trac.lighttpd.net/xcache/">XCache</a>;
528                 cannot use these for object caching.</li>' );
529 }
530
531 $conf->diff3 = false;
532 $diff3locations = array_merge(
533         array(
534                 "/usr/bin",
535                 "/usr/local/bin",
536                 "/opt/csw/bin",
537                 "/usr/gnu/bin",
538                 "/usr/sfw/bin" ),
539         explode( PATH_SEPARATOR, getenv( "PATH" ) ) );
540 $diff3names = array( "gdiff3", "diff3", "diff3.exe" );
541
542 $diff3versioninfo = array( '$1 --version 2>&1', 'diff3 (GNU diffutils)' );
543 foreach ($diff3locations as $loc) {
544         $exe = locate_executable($loc, $diff3names, $diff3versioninfo);
545         if ($exe !== false) {
546                 $conf->diff3 = $exe;
547                 break;
548         }
549 }
550
551 if ($conf->diff3)
552         print "<li>Found GNU diff3: <tt>$conf->diff3</tt>.</li>";
553 else
554         print "<li>GNU diff3 not found.</li>";
555
556 $conf->ImageMagick = false;
557 $imcheck = array( "/usr/bin", "/opt/csw/bin", "/usr/local/bin", "/sw/bin", "/opt/local/bin" );
558 foreach( $imcheck as $dir ) {
559         $im = "$dir/convert";
560         if( @file_exists( $im ) ) {
561                 print "<li>Found ImageMagick: <tt>$im</tt>; image thumbnailing will be enabled if you enable uploads.</li>\n";
562                 $conf->ImageMagick = $im;
563                 break;
564         }
565 }
566
567 $conf->HaveGD = function_exists( "imagejpeg" );
568 if( $conf->HaveGD ) {
569         print "<li>Found GD graphics library built-in";
570         if( !$conf->ImageMagick ) {
571                 print ", image thumbnailing will be enabled if you enable uploads";
572         }
573         print ".</li>\n";
574 } else {
575         if( !$conf->ImageMagick ) {
576                 print "<li>Couldn't find GD library or ImageMagick; image thumbnailing disabled.</li>\n";
577         }
578 }
579
580 $conf->IP = dirname( dirname( __FILE__ ) );
581 print "<li>Installation directory: <tt>" . htmlspecialchars( $conf->IP ) . "</tt></li>\n";
582
583
584 // PHP_SELF isn't available sometimes, such as when PHP is CGI but
585 // cgi.fix_pathinfo is disabled. In that case, fall back to SCRIPT_NAME
586 // to get the path to the current script... hopefully it's reliable. SIGH
587 $path = ($_SERVER["PHP_SELF"] === '')
588         ? $_SERVER["SCRIPT_NAME"]
589         : $_SERVER["PHP_SELF"];
590
591 $conf->ScriptPath = preg_replace( '{^(.*)/config.*$}', '$1', $path );
592 print "<li>Script URI path: <tt>" . htmlspecialchars( $conf->ScriptPath ) . "</tt></li>\n";
593
594
595
596 // We may be installing from *.php5 extension file, if so, print message
597 $conf->ScriptExtension = '.php';
598 if (defined('MW_INSTALL_PHP5_EXT')) {
599     $conf->ScriptExtension = '.php5';
600     print "<li>Installing MediaWiki with <tt>php5</tt> file extensions</li>\n";
601 } else {
602     print "<li>Installing MediaWiki with <tt>php</tt> file extensions</li>\n";
603 }
604
605
606 print "<li style='font-weight:bold;color:green;font-size:110%'>Environment checked. You can install MediaWiki.</li>\n";
607         $conf->posted = ($_SERVER["REQUEST_METHOD"] == "POST");
608
609         $conf->Sitename = ucfirst( importPost( "Sitename", "" ) );
610         $defaultEmail = empty( $_SERVER["SERVER_ADMIN"] )
611                 ? 'root@localhost'
612                 : $_SERVER["SERVER_ADMIN"];
613         $conf->EmergencyContact = importPost( "EmergencyContact", $defaultEmail );
614         $conf->DBtype = importPost( "DBtype", $DefaultDBtype );
615         if ( !isset( $ourdb[$conf->DBtype] ) ) {
616                 $conf->DBtype = $DefaultDBtype;
617         }
618
619         $conf->DBserver = importPost( "DBserver", "localhost" );
620         $conf->DBname = importPost( "DBname", "wikidb" );
621         $conf->DBuser = importPost( "DBuser", "wikiuser" );
622         $conf->DBpassword = importPost( "DBpassword" );
623         $conf->DBpassword2 = importPost( "DBpassword2" );
624         $conf->SysopName = importPost( "SysopName", "WikiSysop" );
625         $conf->SysopPass = importPost( "SysopPass" );
626         $conf->SysopPass2 = importPost( "SysopPass2" );
627         $conf->RootUser = importPost( "RootUser" );
628         $conf->RootPW = importPost( "RootPW", "" );
629         $useRoot = importCheck( 'useroot', false );
630         $conf->LanguageCode = importPost( "LanguageCode", "en" );
631         ## MySQL specific:
632         $conf->DBprefix     = importPost( "DBprefix" );
633         $conf->setSchema(
634                 importPost( "DBschema", "mysql5-binary" ),
635                 importPost( "DBengine", "InnoDB" ) );
636
637         ## Postgres specific:
638         $conf->DBport      = importPost( "DBport",      "5432" );
639         $conf->DBts2schema = importPost( "DBts2schema", "public" );
640         $conf->DBpgschema  = importPost( "DBpgschema",  "mediawiki" );
641
642         ## SQLite specific
643         $conf->SQLiteDataDir = importPost( "SQLiteDataDir", "$IP/../data" );
644
645         ## MSSQL specific
646         // We need a second field so it doesn't overwrite the MySQL one
647         $conf->DBprefix2 = importPost( "DBprefix2" );
648
649         ## DB2 specific:
650         // New variable in order to have a different default port number
651         $conf->DBport_db2   = importPost( "DBport_db2",      "50000" );
652         $conf->DBcataloged  = importPost( "DBcataloged",  "cataloged" );
653         $conf->DBdb2schema  = importPost( "DBdb2schema",  "mediawiki" );
654
655         // Oracle specific
656         $conf->DBprefix_ora     = importPost( "DBprefix_ora" );
657         $conf->DBdefTS_ora     = importPost( "DBdefTS_ora", "USERS" );
658         $conf->DBtempTS_ora     = importPost( "DBtempTS_ora", "TEMP" );
659
660         $conf->ShellLocale = getShellLocale( $conf->LanguageCode );
661
662 /* Check for validity */
663 $errs = array();
664
665 if( preg_match( '/^$|^mediawiki$|#/i', $conf->Sitename ) ) {
666         $errs["Sitename"] = "Must not be blank or \"MediaWiki\" and may not contain \"#\"";
667 }
668 if( !$ourdb[$conf->DBtype]['serverless'] ) {
669         if( $conf->DBuser == "" ) {
670                 $errs["DBuser"] = "Must not be blank";
671         }
672         if( ($conf->DBtype == 'mysql') && (strlen($conf->DBuser) > 16) ) {
673                 $errs["DBuser"] = "Username too long";
674         }
675         if( $conf->DBpassword == "" && $conf->DBtype != "postgres" ) {
676                 $errs["DBpassword"] = "Must not be blank";
677         }
678         if( $conf->DBpassword != $conf->DBpassword2 ) {
679                 $errs["DBpassword2"] = "Passwords don't match!";
680         }
681 }
682 if( !preg_match( '/^[A-Za-z_0-9]*$/', $conf->DBprefix ) ) {
683         $errs["DBprefix"] = "Invalid table prefix";
684 } else {
685         untaint( $conf->DBprefix, TC_MYSQL );
686 }
687 if( !preg_match( '/^[A-Za-z_0-9]*$/', $conf->DBprefix_ora ) ) {
688         $errs["DBprefix_ora"] = "Invalid table prefix";
689 }
690
691 error_reporting( E_ALL | E_STRICT );
692
693 /**
694  * Initialise $wgLang and $wgContLang to something so we can
695  * call case-folding methods. Per Brion, this is English for
696  * now, although we could be clever and initialise to the
697  * user-selected language.
698  */
699 $wgContLang = Language::factory( 'en' );
700 $wgLang = $wgContLang;
701
702 /**
703  * We're messing about with users, so we need a stub
704  * authentication plugin...
705  */
706 $wgAuth = new AuthPlugin();
707
708 /**
709  * Validate the initial administrator account; username,
710  * password checks, etc.
711  */
712 if( $conf->SysopName ) {
713         # Check that the user can be created
714         $u = User::newFromName( $conf->SysopName );
715         if( $u instanceof User ) {
716                 # Various password checks
717                 if( $conf->SysopPass != '' ) {
718                         if( $conf->SysopPass == $conf->SysopPass2 ) {
719                                 if( !$u->isValidPassword( $conf->SysopPass ) ) {
720                                         $errs['SysopPass'] = "Bad password";
721                                 }
722                         } else {
723                                 $errs['SysopPass2'] = "Passwords don't match";
724                         }
725                 } else {
726                         $errs['SysopPass'] = "Cannot be blank";
727                 }
728                 unset( $u );
729         } else {
730                 $errs['SysopName'] = "Bad username";
731         }
732 }
733
734 $conf->License = importRequest( "License", "none" );
735 if( $conf->License == "gfdl1_2" ) {
736         $conf->RightsUrl = "http://www.gnu.org/licenses/old-licenses/fdl-1.2.txt";
737         $conf->RightsText = "GNU Free Documentation License 1.2";
738         $conf->RightsCode = "gfdl1_2";
739         $conf->RightsIcon = '${wgScriptPath}/skins/common/images/gnu-fdl.png';
740 } elseif( $conf->License == "gfdl1_3" ) {
741         $conf->RightsUrl = "http://www.gnu.org/copyleft/fdl.html";
742         $conf->RightsText = "GNU Free Documentation License 1.3";
743         $conf->RightsCode = "gfdl1_3";
744         $conf->RightsIcon = '${wgScriptPath}/skins/common/images/gnu-fdl.png';
745 } elseif( $conf->License == "none" ) {
746         $conf->RightsUrl = $conf->RightsText = $conf->RightsCode = $conf->RightsIcon = "";
747 } elseif( $conf->License == "pd" ) {
748         $conf->RightsUrl = "http://creativecommons.org/licenses/publicdomain/";
749         $conf->RightsText = "Public Domain";
750         $conf->RightsCode = "pd";
751         $conf->RightsIcon = '${wgScriptPath}/skins/common/images/public-domain.png';
752 } else {
753         $conf->RightsUrl = importRequest( "RightsUrl", "" );
754         $conf->RightsText = importRequest( "RightsText", "" );
755         $conf->RightsCode = importRequest( "RightsCode", "" );
756         $conf->RightsIcon = importRequest( "RightsIcon", "" );
757 }
758
759 $conf->Shm = importRequest( "Shm", "none" );
760 $conf->MCServers = importRequest( "MCServers" );
761
762 /* Test memcached servers */
763
764 if ( $conf->Shm == 'memcached' && $conf->MCServers ) {
765         $conf->MCServerArray = wfArrayMap( 'trim', explode( ',', $conf->MCServers ) );
766         foreach ( $conf->MCServerArray as $server ) {
767                 $error = testMemcachedServer( $server );
768                 if ( $error ) {
769                         $errs["MCServers"] = $error;
770                         break;
771                 }
772         }
773 } else if ( $conf->Shm == 'memcached' ) {
774         $errs["MCServers"] = "Please specify at least one server if you wish to use memcached";
775 }
776
777 /* default values for installation */
778 $conf->Email     = importRequest("Email", "email_enabled");
779 $conf->Emailuser = importRequest("Emailuser", "emailuser_enabled");
780 $conf->Enotif    = importRequest("Enotif", "enotif_allpages");
781 $conf->Eauthent  = importRequest("Eauthent", "eauthent_enabled");
782
783 if( $conf->posted && ( 0 == count( $errs ) ) ) {
784         do { /* So we can 'continue' to end prematurely */
785                 $conf->Root = ($conf->RootPW != "");
786
787                 /* Load up the settings and get installin' */
788                 $local = writeLocalSettings( $conf );
789                 echo "<li style=\"list-style: none\">\n";
790                 echo "<p><b>Generating configuration file...</b></p>\n";
791                 echo "</li>\n";
792
793                 $wgCommandLineMode = false;
794                 chdir( ".." );
795                 $ok = eval( $local );
796                 if( $ok === false ) {
797                         dieout( "<p>Errors in generated configuration; " .
798                                 "most likely due to a bug in the installer... " .
799                                 "Config file was: </p>" .
800                                 "<pre>" .
801                                 htmlspecialchars( $local ) .
802                                 "</pre>" );
803                 }
804                 $conf->DBtypename = '';
805                 foreach (array_keys($ourdb) as $db) {
806                         if ($conf->DBtype === $db)
807                                 $conf->DBtypename = $ourdb[$db]['fullname'];
808                 }
809                 if ( ! strlen($conf->DBtype)) {
810                         $errs["DBpicktype"] = "Please choose a database type";
811                         continue;
812                 }
813
814                 if (! $conf->DBtypename) {
815                         $errs["DBtype"] = "Unknown database type '$conf->DBtype'";
816                         continue;
817                 }
818                 print "<li>Database type: " . htmlspecialchars( $conf->DBtypename ) . "</li>\n";
819                 $dbclass = 'Database'.ucfirst($conf->DBtype);
820                 $wgDBtype = $conf->DBtype;
821                 $wgDBadminuser = "root";
822                 $wgDBadminpassword = $conf->RootPW;
823
824                 ## Mysql specific:
825                 $wgDBprefix = $conf->DBprefix;
826
827                 ## Postgres specific:
828                 $wgDBport      = $conf->DBport;
829                 $wgDBts2schema = $conf->DBts2schema;
830
831                 if( $wgDBtype == 'postgres' ) {
832                         $wgDBmwschema = $conf->DBpgschema;
833                 } elseif ( $wgDBtype == 'ibm_db2' ) {
834                         $wgDBmwschema = $conf->DBdb2schema;
835                 }
836
837                 if( $conf->DBprefix2 != '' ) {
838                         // For MSSQL
839                         $wgDBprefix = $conf->DBprefix2;
840                 } elseif( $conf->DBprefix_ora != '' ) {
841                         // For Oracle
842                         $wgDBprefix = $conf->DBprefix_ora;
843                 }
844
845                 ## DB2 specific:
846                 $wgDBcataloged = $conf->DBcataloged;
847
848                 $wgCommandLineMode = true;
849                 if (! defined ( 'STDERR' ) )
850                         define( 'STDERR', fopen("php://stderr", "wb"));
851                 $wgUseDatabaseMessages = false; /* FIXME: For database failure */
852                 require_once( "$IP/includes/Setup.php" );
853                 Language::getLocalisationCache()->disableBackend();
854
855                 chdir( "config" );
856
857                 $wgTitle = Title::newFromText( "Installation script" );
858                 error_reporting( E_ALL | E_STRICT );
859                 print "<li>Loading class: " . htmlspecialchars( $dbclass ) . "</li>\n";
860                 if ( $conf->DBtype != 'sqlite' ) {
861                         $dbc = new $dbclass;
862                 }
863
864                 if( $conf->DBtype == 'mysql' ) {
865                         $mysqlOldClient = version_compare( mysql_get_client_info(), "4.1.0", "lt" );
866                         if( $mysqlOldClient ) {
867                                 print "<li><b>PHP is linked with old MySQL client libraries. If you are
868                                         using a MySQL 4.1 server and have problems connecting to the database,
869                                         see <a href='http://dev.mysql.com/doc/mysql/en/old-client.html'
870                                         >http://dev.mysql.com/doc/mysql/en/old-client.html</a> for help.</b></li>\n";
871                         }
872                         $ok = true; # Let's be optimistic
873
874                         # Decide if we're going to use the superuser or the regular database user
875                         $conf->Root = $useRoot;
876                         if( $conf->Root ) {
877                                 $db_user = $conf->RootUser;
878                                 $db_pass = $conf->RootPW;
879                         } else {
880                                 $db_user = $wgDBuser;
881                                 $db_pass = $wgDBpassword;
882                         }
883
884                         # Attempt to connect
885                         echo( "<li>Attempting to connect to database server as " . htmlspecialchars( $db_user ) . "..." );
886                         $wgDatabase = Database::newFromParams( $wgDBserver, $db_user, $db_pass, '', 1 );
887
888                         # Check the connection and respond to errors
889                         if( $wgDatabase->isOpen() ) {
890                                 # Seems OK
891                                 $ok = true;
892                                 $wgDBadminuser = $db_user;
893                                 $wgDBadminpassword = $db_pass;
894                                 echo( "success.</li>\n" );
895                                 $wgDatabase->ignoreErrors( true );
896                                 $myver = $wgDatabase->getServerVersion();
897                         } else {
898                                 # There were errors, report them and back out
899                                 $ok = false;
900                                 $errno = mysql_errno();
901                                 $errtx = htmlspecialchars( mysql_error() );
902                                 switch( $errno ) {
903                                         case 1045:
904                                         case 2000:
905                                                 echo( "failed due to authentication errors. Check passwords.</li>" );
906                                                 if( $conf->Root ) {
907                                                         # The superuser details are wrong
908                                                         $errs["RootUser"] = "Check username";
909                                                         $errs["RootPW"] = "and password";
910                                                 } else {
911                                                         # The regular user details are wrong
912                                                         $errs["DBuser"] = "Check username";
913                                                         $errs["DBpassword"] = "and password";
914                                                 }
915                                                 break;
916                                         case 2002:
917                                         case 2003:
918                                         default:
919                                                 # General connection problem
920                                                 echo( htmlspecialchars( "failed with error [$errno] $errtx." ) . "</li>\n" );
921                                                 $errs["DBserver"] = "Connection failed";
922                                                 break;
923                                 } # switch
924                         } #conn. att.
925
926                         if( !$ok ) { continue; }
927                 }
928                 else if( $conf->DBtype == 'ibm_db2' ) {
929                         if( $useRoot ) {
930                                 $db_user = $conf->RootUser;
931                                 $db_pass = $conf->RootPW;
932                         } else {
933                                 $db_user = $wgDBuser;
934                                 $db_pass = $wgDBpassword;
935                         }
936
937                         echo( "<li>Attempting to connect to database \"" . htmlspecialchars( $wgDBname ) .
938                                 "\" as \"" . htmlspecialchars( $db_user ) . "\"..." );
939                         $wgDatabase = $dbc->newFromParams($wgDBserver, $db_user, $db_pass, $wgDBname, 1);
940                         // enable extra debug messages
941                         $dbc->setMode(DatabaseIbm_db2::INSTALL_MODE);
942                         $wgDatabase->setMode(DatabaseIbm_db2::INSTALL_MODE);
943
944                         if (!$wgDatabase->isOpen()) {
945                                 print " error: " . htmlspecialchars( $wgDatabase->lastError() ) . "</li>\n";
946                         } else {
947                                 $myver = $wgDatabase->getServerVersion();
948                         }
949                         if (is_callable(array($wgDatabase, 'initial_setup'))) $wgDatabase->initial_setup('', $wgDBname);
950
951                 } elseif ( $conf->DBtype == 'sqlite' ) {
952                         $wgSQLiteDataDir = $conf->SQLiteDataDir;
953                         echo '<li>Attempting to connect to SQLite database at "' .
954                                 htmlspecialchars( $wgSQLiteDataDir ) . '": ';
955                         if ( !is_dir( $wgSQLiteDataDir ) ) {
956                                 if ( is_writable( dirname( $wgSQLiteDataDir ) ) ) {
957                                         $ok = wfMkdirParents( $wgSQLiteDataDir, $wgSQLiteDataDirMode );
958                                 } else {
959                                         $ok = false;
960                                 }
961                                 if ( !$ok ) {
962                                         echo "cannot create data directory</li>";
963                                         $errs['SQLiteDataDir'] = 'Enter a valid data directory';
964                                         continue;
965                                 }
966                         }
967                         if ( !is_writable( $wgSQLiteDataDir ) ) {
968                                 echo "data directory not writable</li>";
969                                 $errs['SQLiteDataDir'] = 'Enter a writable data directory';
970                                 continue;
971                         }
972                         $dataFile = DatabaseSqlite::generateFileName( $wgSQLiteDataDir, $wgDBname );
973                         if ( file_exists( $dataFile ) ) {
974                                 if ( !is_writable( $dataFile ) ) {
975                                         echo "data file not writable</li>";
976                                         $errs['SQLiteDataDir'] = basename( $dataFile ) . " is not writable";
977                                         continue;
978                                 }
979                         } else {
980                                 if ( file_put_contents( $dataFile, '' ) === false ) {
981                                         echo 'could not create database file "' . htmlspecialchars( basename( $dataFile ) ) . "\"</li>\n";
982                                         $errs['SQLiteDataDir'] = "couldn't create " . basename( $dataFile );
983                                         continue;
984                                 }
985                         }
986                         try {
987                                 $wgDatabase = new DatabaseSqlite( false, false, false, $wgDBname, 1 );
988                         }
989                         catch( MWException $ex ) {
990                                 echo 'error: ' . htmlspecialchars( $ex->getMessage() ) . "</li>\n";
991                                 continue;
992                         }
993
994                         if (!$wgDatabase->isOpen()) {
995                                 print "error: " . htmlspecialchars( $wgDatabase->lastError() ) . "</li>\n";
996                                 $errs['SQLiteDataDir'] = 'Could not connect to database';
997                                 continue;
998                         } else {
999                                 $myver = $wgDatabase->getServerVersion();
1000                         }
1001                         if ( is_callable( array( $wgDatabase, 'initial_setup' ) ) ) {
1002                                 $wgDatabase->initial_setup('', $wgDBname);
1003                         }
1004                         echo "ok</li>\n";
1005                 } elseif ( $conf->DBtype == 'oracle' ) {
1006                         echo "<li>Attempting to connect to database \"" . htmlspecialchars( $wgDBname ) ."\"</li>";
1007                         $old_error_level = error_reporting();
1008                         wfSuppressWarnings();
1009                         $wgDatabase = $dbc->newFromParams('DUMMY', $wgDBuser, $wgDBpassword, $wgDBname, 1);
1010                         wfRestoreWarnings();
1011                         if (!$wgDatabase->isOpen()) {
1012                                 $ok = true;
1013                                 echo "<li>Connect failed.</li>";
1014                                 if ($useRoot) {
1015                                         if (ini_get('oci8.privileged_connect') === false) {
1016                                                 echo "<li>Privileged connect disabled, please set oci8.privileged_connect or run maintenance/ora/user.sql script manually prior to continuing.</li>";
1017                                                 $ok = false;
1018                                         } else {
1019                                                 $wgDBadminuser = $conf->RootUser;
1020                                                 $wgDBadminpassword = $conf->RootPW;
1021                                                 echo "<li>Attempting to create DB user.</li>";
1022                                                 $wgDatabase = $dbc->newFromParams('DUMMY', $wgDBadminuser, $wgDBadminpassword, $wgDBname, 1, 64);
1023                                                 if ($wgDatabase->isOpen()) {
1024                                                         $wgDBOracleDefTS = $conf->DBdefTS_ora;
1025                                                         $wgDBOracleTempTS = $conf->DBtempTS_ora;
1026                                                         $res = $wgDatabase->sourceFile( "../maintenance/ora/user.sql"  );
1027                                                         if ($res !== true) dieout($res);
1028                                                 } else {
1029                                                         echo "<li>Invalid database superuser, please supply a valid superuser account.</li>";
1030                                                         echo "<li>ERR: ".print_r(oci_error(), true)."</li>";
1031                                                         $ok = false;
1032                                                 }
1033                                         }
1034                                 } else {
1035                                         echo "<li>Database superuser missing, please supply a valid superuser account.</li>";
1036                                         $ok = false;
1037                                 }
1038                                 if (!$ok) {
1039                                         $errs["RootUser"] = "Check username";
1040                                         $errs["RootPW"] = "and password";
1041                                 } else {
1042                                         echo "<li>Attempting to connect to database with new user \"" . htmlspecialchars( $wgDBname ) ."\"</li>";
1043                                         $wgDatabase = $dbc->newFromParams('DUMMY', $wgDBuser, $wgDBpassword, $wgDBname, 1);
1044                                 }
1045                         }
1046                         if ($ok) {
1047                                 $myver = $wgDatabase->getServerVersion();
1048                         }
1049                 } else { # not mysql
1050                         error_reporting( E_ALL | E_STRICT );
1051                         $wgSuperUser = '';
1052                         ## Possible connect as a superuser
1053                         // Changed !mysql to postgres check since it seems to only apply to postgres
1054                         if( $useRoot && $conf->DBtype == 'postgres' ) {
1055                                 $wgDBsuperuser = $conf->RootUser;
1056                                 echo( "<li>Attempting to connect to database \"postgres\" as superuser \"" .
1057                                         htmlspecialchars( $wgDBsuperuser ) . "\"..." );
1058                                 $wgDatabase = $dbc->newFromParams($wgDBserver, $wgDBsuperuser, $conf->RootPW, "postgres", 1);
1059                                 if (!$wgDatabase->isOpen()) {
1060                                         print " error: " . htmlspecialchars( $wgDatabase->lastError() ) . "</li>\n";
1061                                         $errs["DBserver"] = "Could not connect to database as superuser";
1062                                         $errs["RootUser"] = "Check username";
1063                                         $errs["RootPW"] = "and password";
1064                                         continue;
1065                                 }
1066                                 $wgDatabase->initial_setup($conf->RootPW, 'postgres');
1067                         }
1068                         echo( "<li>Attempting to connect to database \"" . htmlspecialchars( $wgDBname ) .
1069                                 "\" as \"" . htmlspecialchars( $wgDBuser ) . "\"..." );
1070                         $wgDatabase = $dbc->newFromParams($wgDBserver, $wgDBuser, $wgDBpassword, $wgDBname, 1);
1071                         if (!$wgDatabase->isOpen()) {
1072                                 print " error: " . htmlspecialchars( $wgDatabase->lastError() ) . "</li>\n";
1073                                 $errs["DBserver"] = "Could not connect to database as user";
1074                                 $errs["DBuser"] = "Check username";
1075                                 $errs["DBpassword"] = "and password";
1076                                 continue;
1077                         } else {
1078                                 $myver = $wgDatabase->getServerVersion();
1079                         }
1080                         if (is_callable(array($wgDatabase, 'initial_setup'))) $wgDatabase->initial_setup('', $wgDBname);
1081                 }
1082
1083                 if ( !$wgDatabase->isOpen() ) {
1084                         $errs["DBserver"] = "Couldn't connect to database";
1085                         continue;
1086                 }
1087
1088                 print "<li>Connected to " . htmlspecialchars( "{$conf->DBtype} $myver" );
1089                 if ($conf->DBtype == 'mysql') {
1090                         if( version_compare( $myver, "4.0.14" ) < 0 ) {
1091                                 print "</li>\n";
1092                                 dieout( "-- mysql 4.0.14 or later required. Aborting." );
1093                         }
1094                         $mysqlNewAuth = version_compare( $myver, "4.1.0", "ge" );
1095                         if( $mysqlNewAuth && $mysqlOldClient ) {
1096                                 print "; <b class='error'>You are using MySQL 4.1 server, but PHP is linked
1097                                         to old client libraries; if you have trouble with authentication, see
1098                                         <a href='http://dev.mysql.com/doc/mysql/en/old-client.html'
1099                                         >http://dev.mysql.com/doc/mysql/en/old-client.html</a> for help.</b>";
1100                         }
1101                         if( $wgDBmysql5 ) {
1102                                 if( $mysqlNewAuth ) {
1103                                         print "; enabling MySQL 4.1/5.0 charset mode";
1104                                 } else {
1105                                         print "; <b class='error'>MySQL 4.1/5.0 charset mode enabled,
1106                                                 but older version detected; will likely fail.</b>";
1107                                 }
1108                         }
1109                         print "</li>\n";
1110
1111                         @$sel = $wgDatabase->selectDB( $wgDBname );
1112                         if( $sel ) {
1113                                 print "<li>Database <tt>" . htmlspecialchars( $wgDBname ) . "</tt> exists</li>\n";
1114                         } else {
1115                                 $err = mysql_errno();
1116                                 $databaseSafe = htmlspecialchars( $wgDBname );
1117                                 if( $err == 1102 /* Invalid database name */ ) {
1118                                         print "<ul><li><strong>{$databaseSafe}</strong> is not a valid database name.</li></ul>";
1119                                         continue;
1120                                 } elseif( $err != 1049 /* Database doesn't exist */ ) {
1121                                         print "<ul><li>Error selecting database <strong>{$databaseSafe}</strong>: {$err} ";
1122                                         print htmlspecialchars( mysql_error() ) . "</li></ul>";
1123                                         continue;
1124                                 }
1125                                 print "<li>Attempting to create database...</li>";
1126                                 $res = $wgDatabase->query( "CREATE DATABASE `$wgDBname`" );
1127                                 if( !$res ) {
1128                                         print "<li>Couldn't create database <tt>" .
1129                                                 htmlspecialchars( $wgDBname ) .
1130                                                 "</tt>; try with root access or check your username/pass.</li>\n";
1131                                         $errs["RootPW"] = "<- Enter";
1132                                         continue;
1133                                 }
1134                                 print "<li>Created database <tt>" . htmlspecialchars( $wgDBname ) . "</tt></li>\n";
1135                         }
1136                         $wgDatabase->selectDB( $wgDBname );
1137                 }
1138                 else if ($conf->DBtype == 'postgres') {
1139                         if( version_compare( $myver, "8.0" ) < 0 ) {
1140                                 dieout( "<b>Postgres 8.0 or later is required</b>. Aborting." );
1141                         }
1142                 }
1143
1144                 if( $wgDatabase->tableExists( "cur" ) || $wgDatabase->tableExists( "revision" ) ) {
1145                         print "<li>There are already MediaWiki tables in this database. Checking if updates are needed...</li>\n";
1146
1147                         if ( $conf->DBtype == 'mysql') {
1148                                 # Determine existing default character set
1149                                 if ( $wgDatabase->tableExists( "revision" ) ) {
1150                                         $revision = $wgDatabase->escapeLike( $conf->DBprefix . 'revision' );
1151                                         $res = $wgDatabase->query( "SHOW TABLE STATUS LIKE '$revision'" );
1152                                         $row = $wgDatabase->fetchObject( $res );
1153                                         if ( !$row ) {
1154                                                 echo "<li>SHOW TABLE STATUS query failed!</li>\n";
1155                                                 $existingSchema = false;
1156                                                 $existingEngine = false;
1157                                         } else {
1158                                                 if ( preg_match( '/^latin1/', $row->Collation ) ) {
1159                                                         $existingSchema = 'mysql4';
1160                                                 } elseif ( preg_match( '/^utf8/', $row->Collation ) ) {
1161                                                         $existingSchema = 'mysql5';
1162                                                 } elseif ( preg_match( '/^binary/', $row->Collation ) ) {
1163                                                         $existingSchema = 'mysql5-binary';
1164                                                 } else {
1165                                                         $existingSchema = false;
1166                                                         echo "<li><strong>Warning:</strong> Unrecognised existing collation</li>\n";
1167                                                 }
1168                                                 if ( isset( $row->Engine ) ) {
1169                                                         $existingEngine = $row->Engine;
1170                                                 } else {
1171                                                         $existingEngine = $row->Type;
1172                                                 }
1173                                         }
1174                                         if ( $existingSchema && $existingSchema != $conf->DBschema ) {
1175                                                 $encExisting = htmlspecialchars( $existingSchema );
1176                                                 $encRequested = htmlspecialchars( $conf->DBschema );
1177                                                 print "<li><strong>Warning:</strong> you requested the $encRequested schema, " .
1178                                                         "but the existing database has the $encExisting schema. This upgrade script ".
1179                                                         "can't convert it, so it will remain $encExisting.</li>\n";
1180                                                 $conf->setSchema( $existingSchema, $conf->DBengine );
1181                                         }
1182                                         if ( $existingEngine && $existingEngine != $conf->DBengine ) {
1183                                                 $encExisting = htmlspecialchars( $existingEngine );
1184                                                 $encRequested = htmlspecialchars( $conf->DBengine );
1185                                                 print "<li><strong>Warning:</strong> you requested the $encRequested storage " .
1186                                                         "engine, but the existing database uses the $encExisting engine. This upgrade " .
1187                                                         "script can't convert it, so it will remain $encExisting.</li>\n";
1188                                                 $conf->setSchema( $conf->DBschema, $existingEngine );
1189                                         }
1190                                 }
1191
1192                                 # Create user if required
1193                                 if ( $conf->Root ) {
1194                                         $conn = $dbc->newFromParams( $wgDBserver, $wgDBuser, $wgDBpassword, $wgDBname, 1 );
1195                                         if ( $conn->isOpen() ) {
1196                                                 print "<li>DB user account ok</li>\n";
1197                                                 $conn->close();
1198                                         } else {
1199                                                 print "<li>Granting user permissions...";
1200                                                 if( $mysqlOldClient && $mysqlNewAuth ) {
1201                                                         print " <b class='error'>If the next step fails, see <a href='http://dev.mysql.com/doc/mysql/en/old-client.html'>http://dev.mysql.com/doc/mysql/en/old-client.html</a> for help.</b>";
1202                                                 }
1203                                                 print "</li>\n";
1204                                                 $res = $wgDatabase->sourceFile( "../maintenance/users.sql" );
1205                                                 if ($res !== true) dieout($res);
1206                                         }
1207                                 }
1208                         }
1209                         print "</ul><pre>\n";
1210                         chdir( ".." );
1211                         flush();
1212                         do_all_updates();
1213                         chdir( "config" );
1214                         print "</pre>\n";
1215                         print "<ul><li>Finished update checks.</li>\n";
1216                 // if tables don't yet exist
1217                 } else {
1218                         # Determine available storage engines if possible
1219                         if ( $conf->DBtype == 'mysql' && version_compare( $myver, "4.1.2", "ge" ) ) {
1220                                 $res = $wgDatabase->query( 'SHOW ENGINES' );
1221                                 $found = false;
1222                                 while ( $row = $wgDatabase->fetchObject( $res ) ) {
1223                                         if ( $row->Engine == $conf->DBengine && ( $row->Support == 'YES' || $row->Support == 'DEFAULT' ) ) {
1224                                                 $found = true;
1225                                                 break;
1226                                         }
1227                                 }
1228                                 $wgDatabase->freeResult( $res );
1229                                 if ( !$found && $conf->DBengine != 'MyISAM' ) {
1230                                         echo "<li><strong>Warning:</strong> " . htmlspecialchars( $conf->DBengine ) .
1231                                                 " storage engine not available, " .
1232                                                 "using MyISAM instead</li>\n";
1233                                         $conf->setSchema( $conf->DBschema, 'MyISAM' );
1234                                 }
1235                         }
1236
1237                         # FIXME: Check for errors
1238                         print "<li>Creating tables...";
1239                         if ($conf->DBtype == 'mysql') {
1240                                 $res = $wgDatabase->sourceFile( "../maintenance/tables.sql" );
1241                                 if ($res === true) {
1242                                         print " done.</li>\n<li>Populating interwiki table... \n";
1243                                         $res = $wgDatabase->sourceFile( "../maintenance/interwiki.sql" );
1244                                 }
1245                                 if ($res === true) {
1246                                         print " done.</li>\n";
1247                                 } else {
1248                                         print " <b>FAILED</b></li>\n";
1249                                         dieout( htmlspecialchars( $res ) );
1250                                 }
1251                         } elseif (is_callable(array($wgDatabase, 'setup_database'))) {
1252                                 $wgDatabase->setup_database();
1253                         }
1254                         else {
1255                                 $errs["DBtype"] = "Do not know how to handle database type '$conf->DBtype'";
1256                                 continue;
1257                         }
1258
1259
1260                         if ( $conf->DBtype == 'ibm_db2' ) {
1261                                 // Now that table creation is done, make sure everything is committed
1262                                 // Do this before doing inserts through API
1263                                 if ($wgDatabase->lastError()) {
1264                                         print "<li>Errors encountered during table creation -- rolled back</li>\n";
1265                                         $wgDatabase->rollback();
1266                                 }
1267                                 else {
1268                                         print "<li>MediaWiki tables successfully created</li>\n";
1269                                         $wgDatabase->commit();
1270                                 }
1271                         } elseif ( $conf->DBtype == 'sqlite' ) {
1272                                 // Ensure proper searchindex format. We have to do that separately because
1273                                 // if SQLite is compiled without the FTS3 module, table creation syntax will be invalid.
1274                                 sqlite_setup_searchindex();
1275                         }
1276
1277                         print "<li>Initializing statistics...</li>\n";
1278                         $wgDatabase->insert( 'site_stats',
1279                                 array ( 'ss_row_id'        => 1,
1280                                                 'ss_total_views'   => 0,
1281                                                 'ss_total_edits'   => 1, # Main page first edit
1282                                                 'ss_good_articles' => 0, # Main page is not a good article - no internal link
1283                                                 'ss_total_pages'   => 1, # Main page
1284                                                 'ss_users'         => $conf->SysopName ? 1 : 0, # Sysop account, if created
1285                                                 'ss_admins'        => $conf->SysopName ? 1 : 0, # Sysop account, if created
1286                                                 'ss_images'        => 0 ) );
1287
1288                         # Set up the "regular user" account *if we can, and if we need to*
1289                         if( $conf->Root and $conf->DBtype == 'mysql') {
1290                                 # See if we need to
1291                                 $wgDatabase2 = $dbc->newFromParams( $wgDBserver, $wgDBuser, $wgDBpassword, $wgDBname, 1 );
1292                                 if( $wgDatabase2->isOpen() ) {
1293                                         # Nope, just close the test connection and continue
1294                                         $wgDatabase2->close();
1295                                         echo( "<li>User " . htmlspecialchars( $wgDBuser ) . " exists. Skipping grants.</li>\n" );
1296                                 } else {
1297                                         # Yes, so run the grants
1298                                         echo( "<li>" . htmlspecialchars( "Granting user permissions to $wgDBuser on $wgDBname..." ) );
1299                                         $res = $wgDatabase->sourceFile( "../maintenance/users.sql" );
1300                                         if ( $res === true ) {
1301                                                 echo( " success.</li>\n" );
1302                                         } else {
1303                                                 echo( " <b>FAILED</b>.</li>\n" );
1304                                                 dieout( $res );
1305                                         }
1306                                 }
1307                         }
1308
1309                         if( $conf->SysopName ) {
1310                                 $u = User::newFromName( $conf->getSysopName() );
1311                                 if ( !$u ) {
1312                                         print "<li><strong class=\"error\">Warning:</strong> Skipped sysop account creation - invalid username!</li>\n";
1313                                 }
1314                                 else if ( 0 == $u->idForName() ) {
1315                                         $u->addToDatabase();
1316                                         $u->setPassword( $conf->getSysopPass() );
1317                                         $u->saveSettings();
1318
1319                                         $u->addGroup( "sysop" );
1320                                         $u->addGroup( "bureaucrat" );
1321
1322                                         print "<li>Created sysop account <tt>" .
1323                                                 htmlspecialchars( $conf->SysopName ) . "</tt>.</li>\n";
1324                                 } else {
1325                                         print "<li>Could not create user - already exists!</li>\n";
1326                                 }
1327                         } else {
1328                                 print "<li>Skipped sysop account creation, no name given.</li>\n";
1329                         }
1330
1331                         $titleobj = Title::newFromText( wfMsgNoDB( "mainpage" ) );
1332                         $article = new Article( $titleobj );
1333                         $newid = $article->insertOn( $wgDatabase );
1334                         $revision = new Revision( array(
1335                                 'page'      => $newid,
1336                                 'text'      => wfMsg( 'mainpagetext' ) . "\n\n" . wfMsgNoTrans( 'mainpagedocfooter' ),
1337                                 'comment'   => '',
1338                                 'user'      => 0,
1339                                 'user_text' => 'MediaWiki default',
1340                                 ) );
1341                         $revid = $revision->insertOn( $wgDatabase );
1342                         $article->updateRevisionOn( $wgDatabase, $revision );
1343                 }
1344
1345                 /* Write out the config file now that all is well */
1346                 print "<li style=\"list-style: none\">\n";
1347                 print "<p>Creating LocalSettings.php...</p>\n\n";
1348                 $localSettings = "<" . "?php$endl$local";
1349                 // Fix up a common line-ending problem (due to CVS on Windows)
1350                 $localSettings = str_replace( "\r\n", "\n", $localSettings );
1351                 $f = fopen( "LocalSettings.php", 'xt' );
1352
1353                 if( $f == false ) {
1354                         print( "</li>\n" );
1355                         dieout( "<p>Couldn't write out LocalSettings.php. Check that the directory permissions are correct and that there isn't already a file of that name here...</p>\n" .
1356                         "<p>Here's the file that would have been written, try to paste it into place manually:</p>\n" .
1357                         "<pre>\n" . htmlspecialchars( $localSettings ) . "</pre>\n" );
1358                 }
1359                 if(fwrite( $f, $localSettings ) ) {
1360                         fclose( $f );
1361                         print "<hr/>\n";
1362                         writeSuccessMessage();
1363                         print "</li>\n";
1364                 } else {
1365                         fclose( $f );
1366                         dieout( "<p class='error'>An error occured while writing the config/LocalSettings.php file. Check user rights and disk space then try again.</p></li>\n" );
1367                 }
1368
1369         } while( false );
1370 }
1371
1372 print "</ul>\n";
1373 $mainListOpened = false;
1374
1375 if( count( $errs ) ) {
1376         /* Display options form */
1377
1378         if( $conf->posted ) {
1379                 echo "<p class='error-top'>Something's not quite right yet; make sure everything below is filled out correctly.</p>\n";
1380         }
1381 ?>
1382
1383 <form action="<?php echo defined('MW_INSTALL_PHP5_EXT') ? 'index.php5' : 'index.php'; ?>" name="config" method="post">
1384
1385 <h2>Site config</h2>
1386
1387 <div class="config-section">
1388         <div class="config-input">
1389                 <?php aField( $conf, "Sitename", "Wiki name:" ); ?>
1390         </div>
1391         <p class="config-desc">
1392                 Preferably a short word without punctuation, i.e. "Wikipedia".<br />
1393                 Will appear as the namespace name for "meta" pages, and throughout the interface.
1394         </p>
1395         <div class="config-input"><?php aField( $conf, "EmergencyContact", "Contact e-mail:" ); ?></div>
1396         <p class="config-desc">
1397                 Displayed to users in some error messages, used as the return address for password reminders, and used as the default sender address of e-mail notifications.
1398         </p>
1399
1400         <div class="config-input">
1401                 <label class='column' for="LanguageCode">Language:</label>
1402                 <select id="LanguageCode" name="LanguageCode"><?php
1403                         $list = getLanguageList();
1404                         foreach( $list as $code => $name ) {
1405                                 $sel = ($code == $conf->LanguageCode) ? 'selected="selected"' : '';
1406                                 $encCode = htmlspecialchars( $code );
1407                                 $encName = htmlspecialchars( $name );
1408                                 echo "\n\t\t<option value=\"$encCode\" $sel>$encName</option>";
1409                         }
1410                         echo "\n";
1411                 ?>
1412                 </select>
1413         </div>
1414         <p class="config-desc">
1415                 Select the language for your wiki's interface. Some localizations aren't fully complete. Unicode (UTF-8) is used for all localizations.
1416         </p>
1417
1418         <div class="config-input">
1419                 <label class='column'>Copyright/license:</label>
1420
1421                 <ul class="plain">
1422                 <li><?php aField( $conf, "License", "No license metadata", "radio", "none" ); ?></li>
1423                 <li><?php aField( $conf, "License", "Public Domain", "radio", "pd" ); ?></li>
1424                 <li><?php aField( $conf, "License", "GNU Free Documentation License 1.2", "radio", "gfdl1_2" ); ?></li>
1425                 <li><?php aField( $conf, "License", "GNU Free Documentation License 1.3", "radio", "gfdl1_3" ); ?></li>
1426                 <li><?php
1427                         aField( $conf, "License", "A Creative Commons license - ", "radio", "cc" );
1428                         $partner = "MediaWiki";
1429    $script = defined('MW_INSTALL_PHP5_EXT') ? 'index.php5' : 'index.php';
1430                         $exit = urlencode( "$wgServer{$conf->ScriptPath}/config/$script?License=cc&RightsUrl=[license_url]&RightsText=[license_name]&RightsCode=[license_code]&RightsIcon=[license_button]" );
1431                         $icon = urlencode( "$wgServer$wgUploadPath/wiki.png" );
1432                         $ccApp = htmlspecialchars( "http://creativecommons.org/license/?partner=$partner&exit_url=$exit&partner_icon_url=$icon" );
1433                         print "<a href=\"$ccApp\" target='_blank'>choose</a>";
1434                         if( $conf->License == "cc" ) { ?>
1435                         <ul>
1436                         <li><?php aField( $conf, "RightsIcon", "<img src=\"" . htmlspecialchars( $conf->RightsIcon ) . "\" alt='(Creative Commons icon)' />", "hidden" ); ?></li>
1437                         <li><?php aField( $conf, "RightsText", htmlspecialchars( $conf->RightsText ), "hidden" ); ?></li>
1438                         <li><?php aField( $conf, "RightsCode", "code: " . htmlspecialchars( $conf->RightsCode ), "hidden" ); ?></li>
1439                         <li><?php aField( $conf, "RightsUrl", "<a href=\"" . htmlspecialchars( $conf->RightsUrl ) . "\">" . htmlspecialchars( $conf->RightsUrl ) . "</a>", "hidden" ); ?></li>
1440                         </ul>
1441                         <?php } ?>
1442                         </li>
1443                 </ul>
1444         </div>
1445         <p class="config-desc">
1446                 A notice, icon, and machine-readable copyright metadata will be displayed for the license you pick.
1447         </p>
1448
1449
1450         <div class="config-input">
1451                 <?php aField( $conf, "SysopName", "Admin username:" ) ?>
1452         </div>
1453         <div class="config-input">
1454                 <?php aField( $conf, "SysopPass", "Password:", "password" ) ?>
1455         </div>
1456         <div class="config-input">
1457                 <?php aField( $conf, "SysopPass2", "Password confirm:", "password" ) ?>
1458         </div>
1459         <p class="config-desc">
1460                 An admin can lock/delete pages, block users from editing, and do other maintenance tasks.<br />
1461                 A new account will be added only when creating a new wiki database.
1462                 <br /><br />
1463                 The password cannot be the same as the username.
1464         </p>
1465
1466         <div class="config-input">
1467                 <label class='column'>Object caching:</label>
1468
1469                 <ul class="plain">
1470                 <li><?php aField( $conf, "Shm", "No caching", "radio", "none" ); ?></li>
1471                 <?php
1472                         if( $conf->xcache ) {
1473                                 echo "<li>";
1474                                 aField( $conf, 'Shm', 'XCache', 'radio', 'xcache' );
1475                                 echo "</li>\n";
1476                         }
1477                         if ( $conf->apc ) {
1478                                 echo "<li>";
1479                                 aField( $conf, "Shm", "APC", "radio", "apc" );
1480                                 echo "</li>\n";
1481                         }
1482                         if ( $conf->eaccel ) {
1483                                 echo "<li>";
1484                                 aField( $conf, "Shm", "eAccelerator", "radio", "eaccel" );
1485                                 echo "</li>\n";
1486                         }
1487                         if ( $conf->dba ) {
1488                                 echo "<li>";
1489                                 aField( $conf, "Shm", "DBA (not recommended)", "radio", "dba" );
1490                                 echo "</li>";
1491                         }
1492                 ?>
1493                 <li><?php aField( $conf, "Shm", "Memcached", "radio", "memcached" ); ?></li>
1494                 </ul>
1495                 <div style="clear:left"><?php aField( $conf, "MCServers", "Memcached servers:", "text" ) ?></div>
1496         </div>
1497         <p class="config-desc">
1498                 An object caching system such as memcached will provide a significant performance boost,
1499                 but needs to be installed. Provide the server addresses and ports in a comma-separated list.
1500                 <br /><br />
1501                 MediaWiki can also detect and support eAccelerator, APC, and XCache, but
1502                 these should not be used if the wiki will be running on multiple application servers.
1503                 <br /><br />
1504                 DBA (Berkeley-style DB) is generally slower than using no cache at all, and is only
1505                 recommended for testing.
1506         </p>
1507 </div>
1508
1509 <h2>E-mail, e-mail notification and authentication setup</h2>
1510
1511 <div class="config-section">
1512         <div class="config-input">
1513                 <label class='column'>E-mail features (global):</label>
1514                 <ul class="plain">
1515                 <li><?php aField( $conf, "Email", "Enabled", "radio", "email_enabled" ); ?></li>
1516                 <li><?php aField( $conf, "Email", "Disabled", "radio", "email_disabled" ); ?></li>
1517                 </ul>
1518         </div>
1519         <p class="config-desc">
1520                 Use this to disable all e-mail functions (password reminders, user-to-user e-mail, and e-mail notifications)
1521                 if sending mail doesn't work on your server.
1522         </p>
1523
1524         <div class="config-input">
1525                 <label class='column'>User-to-user e-mail:</label>
1526                 <ul class="plain">
1527                 <li><?php aField( $conf, "Emailuser", "Enabled", "radio", "emailuser_enabled" ); ?></li>
1528                 <li><?php aField( $conf, "Emailuser", "Disabled", "radio", "emailuser_disabled" ); ?></li>
1529                 </ul>
1530         </div>
1531         <p class="config-desc">
1532                 The user-to-user e-mail feature (Special:Emailuser) lets the wiki act as a relay to allow users to exchange e-mail without publicly advertising their e-mail address.
1533         </p>
1534         <div class="config-input">
1535                 <label class='column'>E-mail notification about changes:</label>
1536                 <ul class="plain">
1537                 <li><?php aField( $conf, "Enotif", "Disabled", "radio", "enotif_disabled" ); ?></li>
1538                 <li><?php aField( $conf, "Enotif", "Enabled for changes to user discussion pages only", "radio", "enotif_usertalk" ); ?></li>
1539                 <li><?php aField( $conf, "Enotif", "Enabled for changes to user discussion pages, and to pages on watchlists (not recommended for large wikis)", "radio", "enotif_allpages" ); ?></li>
1540                 </ul>
1541         </div>
1542         <div class="config-desc">
1543                 <p>
1544                 For this feature to work, an e-mail address must be present for the user account, and the notification
1545                 options in the user's preferences must be enabled. Also note the
1546                 authentication option below. When testing the feature, keep in mind that your own changes will never trigger notifications to be sent to yourself.</p>
1547
1548                 <p>There are additional options for fine tuning in /includes/DefaultSettings.php; copy these to your LocalSettings.php and edit them there to change them.</p>
1549         </div>
1550
1551         <div class="config-input">
1552                 <label class='column'>E-mail address authentication:</label>
1553                 <ul class="plain">
1554                 <li><?php aField( $conf, "Eauthent", "Disabled", "radio", "eauthent_disabled" ); ?></li>
1555                 <li><?php aField( $conf, "Eauthent", "Enabled", "radio", "eauthent_enabled" ); ?></li>
1556                 </ul>
1557         </div>
1558         <div class="config-desc">
1559                 <p>If this option is enabled, users have to confirm their e-mail address using a magic link sent to them whenever they set or change it, and only authenticated e-mail addresses can receive mails from other users and/or
1560                 change notification mails. Setting this option is <b>recommended</b> for public wikis because of potential abuse of the e-mail features above.</p>
1561         </div>
1562
1563 </div>
1564
1565 <h2>Database config</h2>
1566
1567 <div class="config-section">
1568 <div class="config-input">
1569         <label class='column'>Database type:</label>
1570 <?php
1571         if (isset($errs['DBpicktype'])) {
1572                 print "\t<span class='error'>" . htmlspecialchars( $errs['DBpicktype'] ) . "</span>\n";
1573         }
1574 ?>
1575         <ul class='plain'><?php
1576                 database_picker($conf);
1577         ?></ul>
1578         </div>
1579
1580         <div id="db-server-settings1">
1581                 <div class="config-input" style="clear:left">
1582                 <?php aField( $conf, "DBserver", "Database host:" ); ?>
1583                 </div>
1584                 <p class="config-desc">
1585                         If your database server isn't on your web server, enter the name or IP address here.
1586                 </p>
1587         </div>
1588
1589                 <div class="config-input"><?php aField( $conf, "DBname", "Database name:" ); ?></div>
1590         <div id="db-server-settings2">
1591                 <div class="config-input"><?php aField( $conf, "DBuser", "DB username:" ); ?></div>
1592                 <div class="config-input"><?php aField( $conf, "DBpassword", "DB password:", "password" ); ?></div>
1593                 <div class="config-input"><?php aField( $conf, "DBpassword2", "DB password confirm:", "password" ); ?></div>
1594                 <p class="config-desc">
1595                         If you only have a single user account and database available,
1596                         enter those here. If you have database root access (see below)
1597                         you can specify new accounts/databases to be created. This account
1598                         will not be created if it pre-exists. If this is the case, ensure that it
1599                         has SELECT, INSERT, UPDATE, and DELETE permissions on the MediaWiki database.
1600                 </p>
1601
1602                 <div class="config-input">
1603                         <label class="column">Superuser account:</label>
1604                         <input type="checkbox" name="useroot" id="useroot" <?php if( $useRoot ) { ?>checked="checked" <?php } ?> />
1605                         &nbsp;<label for="useroot">Use superuser account</label>
1606                 </div>
1607                 <div class="config-input"><?php aField( $conf, "RootUser", "Superuser name:", "text" ); ?></div>
1608                 <div class="config-input"><?php aField( $conf, "RootPW", "Superuser password:", "password" ); ?></div>
1609
1610                 <p class="config-desc">
1611                         If the database user specified above does not exist, or does not have access to create
1612                         the database (if needed) or tables within it, please check the box and provide details
1613                         of a superuser account, such as <strong>root</strong>, which does.
1614                 </p>
1615         </div>
1616
1617         <?php database_switcher('mysql'); ?>
1618         <div class="config-input"><?php aField( $conf, "DBprefix", "Database table prefix:" ); ?></div>
1619         <div class="config-desc">
1620                 <p>If you need to share one database between multiple wikis, or
1621                 between MediaWiki and another web application, you may choose to
1622                 add a prefix to all the table names to avoid conflicts.</p>
1623
1624                 <p>Avoid exotic characters; something like <tt>mw_</tt> is good.</p>
1625         </div>
1626
1627         <div class="config-input"><label class="column">Storage Engine</label>
1628                 <div>Select one:</div>
1629                 <ul class="plain">
1630                 <li><?php aField( $conf, "DBengine", "InnoDB", "radio", "InnoDB" ); ?></li>
1631                 <li><?php aField( $conf, "DBengine", "MyISAM", "radio", "MyISAM" ); ?></li>
1632                 </ul>
1633         </div>
1634         <p class="config-desc">
1635                 InnoDB is best for public web installations, since it has good concurrency
1636                 support. MyISAM may be faster in single-user installations. MyISAM databases
1637                 tend to get corrupted more often than InnoDB databases.
1638         </p>
1639         <div class="config-input"><label class="column">Database character set</label>
1640                 <div>Select one:</div>
1641                 <ul class="plain">
1642                 <li><?php aField( $conf, "DBschema", "MySQL 4.1/5.0 binary", "radio", "mysql5-binary" ); ?></li>
1643                 <li><?php aField( $conf, "DBschema", "MySQL 4.1/5.0 UTF-8", "radio", "mysql5" ); ?></li>
1644                 <li><?php aField( $conf, "DBschema", "MySQL 4.0 backwards-compatible UTF-8", "radio", "mysql4" ); ?></li>
1645                 </ul>
1646         </div>
1647         <p class="config-desc">
1648                 This option is ignored on upgrade, the same character set will be kept.
1649                 <br /><br />
1650                 <b>WARNING:</b> If you use <b>backwards-compatible UTF-8</b> on MySQL 4.1+, and subsequently back up the database with <tt>mysqldump</tt>, it may destroy all non-ASCII characters, irreversibly corrupting your backups!.
1651                 <br /><br />
1652                 In <b>binary mode</b>, MediaWiki stores UTF-8 text to the database in binary fields. This is more efficient than MySQL's UTF-8 mode, and allows you to use the full range of Unicode characters. In <b>UTF-8 mode</b>, MySQL will know what character set your data is in, and can present and convert it appropriately, but it won't let you store characters above the <a target="_blank" href="http://en.wikipedia.org/wiki/Mapping_of_Unicode_character_planes">Basic Multilingual Plane</a>.
1653         </p>
1654         </fieldset>
1655
1656         <?php database_switcher('postgres'); ?>
1657         <div class="config-input"><?php aField( $conf, "DBport", "Database port:" ); ?></div>
1658         <div class="config-input"><?php aField( $conf, "DBpgschema", "Schema for mediawiki:" ); ?></div>
1659         <div class="config-input"><?php aField( $conf, "DBts2schema", "Schema for tsearch2:" ); ?></div>
1660         <div class="config-desc">
1661                 <p>The username specified above (at "DB username") will have its search path set to the above schemas,
1662                 so it is recommended that you create a new user. The above schemas are generally correct:
1663         only change them if you are sure you need to.</p>
1664         </div>
1665         </fieldset>
1666
1667         <?php database_switcher('sqlite'); ?>
1668         <div class="config-input"><?php
1669                 aField( $conf, "SQLiteDataDir", "SQLite data directory:" );
1670         ?></div>
1671         <div class="config-desc">
1672                 <p>SQLite stores table data into files in the
1673                 filesystem.</p>
1674
1675                 <p>This directory must exist and be writable by the web server.</p>
1676         </div>
1677         </fieldset>
1678
1679         <?php database_switcher('mssql'); ?>
1680         <div class="config-input"><?php
1681                 aField( $conf, "DBprefix2", "Database table prefix:" );
1682         ?></div>
1683         <div class="config-desc">
1684                 <p>If you need to share one database between multiple wikis, or
1685                 between MediaWiki and another web application, you may choose to
1686                 add a prefix to all the table names to avoid conflicts.</p>
1687
1688                 <p>Avoid exotic characters; something like <tt>mw_</tt> is good.</p>
1689         </div>
1690         </fieldset>
1691
1692         <?php database_switcher('ibm_db2'); ?>
1693         <div class="config-input"><?php
1694                 aField( $conf, "DBport_db2", "Database port:" );
1695         ?></div>
1696         <div class="config-input"><?php
1697                 aField( $conf, "DBdb2schema", "Schema for mediawiki:" );
1698         ?></div>
1699         <div>Select one:</div>
1700                 <ul class="plain">
1701                 <li><?php aField( $conf, "DBcataloged", "Cataloged (DB2 installed locally)", "radio", "cataloged" ); ?></li>
1702                 <li><?php aField( $conf, "DBcataloged", "Uncataloged (remote DB2 through ODBC)", "radio", "uncataloged" ); ?></li>
1703                 </ul>
1704         <div class="config-desc">
1705                 <p>If you need to share one database between multiple wikis, or
1706                 between MediaWiki and another web application, you may specify
1707                 a different schema to avoid conflicts.</p>
1708         </div>
1709         </fieldset>
1710
1711         <?php database_switcher('oracle'); ?>
1712         <div class="config-input"><?php aField( $conf, "DBprefix_ora", "Database table prefix:" ); ?></div>
1713         <div class="config-desc">
1714                 <p>If you need to share one database between multiple wikis, or
1715                 between MediaWiki and another web application, you may choose to
1716                 add a prefix to all the table names to avoid conflicts.</p>
1717
1718                 <p>Avoid exotic characters; something like <tt>mw_</tt> is good.</p>
1719         </div>
1720         <div class="config-input"><?php aField( $conf, "DBdefTS_ora", "Default tablespace:" ); ?></div>
1721         <div class="config-input"><?php aField( $conf, "DBtempTS_ora", "Temporary tablespace:" ); ?></div>
1722         </fieldset>
1723
1724         <div class="config-input" style="padding:2em 0 3em">
1725                 <label class='column'>&nbsp;</label>
1726                 <input type="submit" value="Install MediaWiki!" class="btn-install" />
1727         </div>
1728 </div>
1729 </form>
1730 <script type="text/javascript">
1731 window.onload = toggleDBarea( <?php echo Xml::encodeJsVar( $conf->DBtype ); ?>,
1732 <?php
1733         ## If they passed in a root user name, don't populate it on page load
1734         echo strlen(importPost('RootUser', '')) ? 0 : 1;
1735 ?>);
1736 </script>
1737 <?php
1738 }
1739
1740 /* -------------------------------------------------------------------------------------- */
1741 function writeSuccessMessage() {
1742  $script = defined('MW_INSTALL_PHP5_EXT') ? 'index.php5' : 'index.php';
1743         if ( wfIniGetBool( 'safe_mode' ) && !ini_get( 'open_basedir' ) ) {
1744                 echo <<<HTML
1745 <div class="success-box">
1746 <p>Installation successful!</p>
1747 <p>To complete the installation, please do the following:
1748 <ol>
1749         <li>Download config/LocalSettings.php with your FTP client or file manager</li>
1750         <li>Upload it to the parent directory</li>
1751         <li>Delete config/LocalSettings.php</li>
1752         <li>Start using <a href='../$script'>your wiki</a>!
1753 </ol>
1754 <p>If you are in a shared hosting environment, do <strong>not</strong> just move LocalSettings.php
1755 remotely. LocalSettings.php is currently owned by the user your webserver is running under,
1756 which means that anyone on the same server can read your database password! Downloading
1757 it and uploading it again will hopefully change the ownership to a user ID specific to you.</p>
1758 </div>
1759 HTML;
1760         } else {
1761                 echo <<<HTML
1762 <div class="success-box">
1763 <p>
1764 <span class="success-message">Installation successful!</span>
1765 Move the <tt>config/LocalSettings.php</tt> file to the parent directory, then follow
1766 <a href="../$script"> this link</a> to your wiki.</p>
1767 <p>You should change file permissions for <tt>LocalSettings.php</tt> as required to
1768 prevent other users on the server reading passwords and altering configuration data.</p>
1769 </div>
1770 HTML;
1771         }
1772 }
1773
1774
1775 function escapePhpString( $string ) {
1776         if ( is_array( $string ) || is_object( $string ) ) {
1777                 return false;
1778         }
1779         return strtr( $string,
1780                 array(
1781                         "\n" => "\\n",
1782                         "\r" => "\\r",
1783                         "\t" => "\\t",
1784                         "\\" => "\\\\",
1785                         "\$" => "\\\$",
1786                         "\"" => "\\\""
1787                 ));
1788 }
1789
1790 function writeLocalSettings( $conf ) {
1791         $conf->PasswordSender = $conf->EmergencyContact;
1792         $magic = ($conf->ImageMagick ? "" : "# ");
1793         $convert = ($conf->ImageMagick ? $conf->ImageMagick : "/usr/bin/convert" );
1794         $rights = ($conf->RightsUrl) ? "" : "# ";
1795         $hashedUploads = $conf->safeMode ? '' : '# ';
1796         $dir = realpath( $conf->SQLiteDataDir );
1797         if ( !$dir ) {
1798                 $dir = $conf->SQLiteDataDir; // dumb realpath sometimes fails
1799         }
1800         $sqliteDataDir = escapePhpString( $dir );
1801
1802         if ( $conf->ShellLocale ) {
1803                 $locale = '';
1804         } else {
1805                 $locale = '# ';
1806                 $conf->ShellLocale = 'en_US.UTF-8';
1807         }
1808
1809         switch ( $conf->Shm ) {
1810                 case 'memcached':
1811                         $cacheType = 'CACHE_MEMCACHED';
1812                         $mcservers = var_export( $conf->MCServerArray, true );
1813                         break;
1814                 case 'xcache':
1815                 case 'apc':
1816                 case 'eaccel':
1817                         $cacheType = 'CACHE_ACCEL';
1818                         $mcservers = 'array()';
1819                         break;
1820                 case 'dba':
1821                         $cacheType = 'CACHE_DBA';
1822                         $mcservers = 'array()';
1823                         break;
1824                 default:
1825                         $cacheType = 'CACHE_NONE';
1826                         $mcservers = 'array()';
1827         }
1828
1829         if ( $conf->Email == 'email_enabled' ) {
1830                 $enableemail = 'true';
1831                 $enableuseremail = ( $conf->Emailuser == 'emailuser_enabled' ) ? 'true' : 'false' ;
1832                 $eauthent = ( $conf->Eauthent == 'eauthent_enabled' ) ? 'true' : 'false' ;
1833                 switch ( $conf->Enotif ) {
1834                         case 'enotif_usertalk':
1835                                 $enotifusertalk = 'true';
1836                                 $enotifwatchlist = 'false';
1837                                 break;
1838                         case 'enotif_allpages':
1839                                 $enotifusertalk = 'true';
1840                                 $enotifwatchlist = 'true';
1841                                 break;
1842                         default:
1843                                 $enotifusertalk = 'false';
1844                                 $enotifwatchlist = 'false';
1845                 }
1846         } else {
1847                 $enableuseremail = 'false';
1848                 $enableemail = 'false';
1849                 $eauthent = 'false';
1850                 $enotifusertalk = 'false';
1851                 $enotifwatchlist = 'false';
1852         }
1853
1854         $file = @fopen( "/dev/urandom", "r" );
1855         if ( $file ) {
1856                 $secretKey = bin2hex( fread( $file, 32 ) );
1857                 fclose( $file );
1858         } else {
1859                 $secretKey = "";
1860                 for ( $i=0; $i<8; $i++ ) {
1861                         $secretKey .= dechex(mt_rand(0, 0x7fffffff));
1862                 }
1863                 print "<li>Warning: \$wgSecretKey key is insecure, generated with mt_rand(). Consider changing it manually.</li>\n";
1864         }
1865
1866         # Add slashes to strings for double quoting
1867         $slconf = wfArrayMap( "escapePhpString", get_object_vars( $conf ) );
1868         if( $conf->License == 'gfdl1_2' || $conf->License == 'pd' || $conf->License == 'gfdl1_3' ) {
1869                 # Needs literal string interpolation for the current style path
1870                 $slconf['RightsIcon'] = $conf->RightsIcon;
1871         }
1872
1873         if( $conf->DBtype == 'mysql' ) {
1874                 $dbsettings =
1875 "# MySQL specific settings
1876 \$wgDBprefix         = \"{$slconf['DBprefix']}\";
1877
1878 # MySQL table options to use during installation or update
1879 \$wgDBTableOptions   = \"{$slconf['DBTableOptions']}\";
1880
1881 # Experimental charset support for MySQL 4.1/5.0.
1882 \$wgDBmysql5 = {$conf->DBmysql5};";
1883         } elseif( $conf->DBtype == 'postgres' ) {
1884                 $dbsettings =
1885 "# Postgres specific settings
1886 \$wgDBport           = \"{$slconf['DBport']}\";
1887 \$wgDBmwschema       = \"{$slconf['DBpgschema']}\";
1888 \$wgDBts2schema      = \"{$slconf['DBts2schema']}\";";
1889         } elseif( $conf->DBtype == 'sqlite' ) {
1890                 $dbsettings =
1891 "# SQLite-specific settings
1892 \$wgSQLiteDataDir    = \"{$sqliteDataDir}\";";
1893         } elseif( $conf->DBtype == 'mssql' ) {
1894                 $dbsettings =
1895 "# MSSQL specific settings
1896 \$wgDBprefix         = \"{$slconf['DBprefix2']}\";";
1897         } elseif( $conf->DBtype == 'ibm_db2' ) {
1898                 $dbsettings =
1899 "# DB2 specific settings
1900 \$wgDBport_db2       = \"{$slconf['DBport_db2']}\";
1901 \$wgDBmwschema       = \"{$slconf['DBdb2schema']}\";
1902 \$wgDBcataloged      = \"{$slconf['DBcataloged']}\";";
1903         } elseif( $conf->DBtype == 'oracle' ) {
1904                 $dbsettings =
1905 "# Oracle specific settings
1906 \$wgDBprefix         = \"{$slconf['DBprefix_ora']}\";";
1907         } else {
1908                 // ummm... :D
1909                 $dbsettings = '';
1910         }
1911
1912
1913         $localsettings = "
1914 # This file was automatically generated by the MediaWiki installer.
1915 # If you make manual changes, please keep track in case you need to
1916 # recreate them later.
1917 #
1918 # See includes/DefaultSettings.php for all configurable settings
1919 # and their default values, but don't forget to make changes in _this_
1920 # file, not there.
1921 #
1922 # Further documentation for configuration settings may be found at:
1923 # http://www.mediawiki.org/wiki/Manual:Configuration_settings
1924
1925 # If you customize your file layout, set \$IP to the directory that contains
1926 # the other MediaWiki files. It will be used as a base to locate files.
1927 if( defined( 'MW_INSTALL_PATH' ) ) {
1928         \$IP = MW_INSTALL_PATH;
1929 } else {
1930         \$IP = dirname( __FILE__ );
1931 }
1932
1933 \$path = array( \$IP, \"\$IP/includes\", \"\$IP/languages\" );
1934 set_include_path( implode( PATH_SEPARATOR, \$path ) . PATH_SEPARATOR . get_include_path() );
1935
1936 require_once( \"\$IP/includes/DefaultSettings.php\" );
1937
1938 if ( \$wgCommandLineMode ) {
1939         if ( isset( \$_SERVER ) && array_key_exists( 'REQUEST_METHOD', \$_SERVER ) ) {
1940                 die( \"This script must be run from the command line\\n\" );
1941         }
1942 }
1943 ## Uncomment this to disable output compression
1944 # \$wgDisableOutputCompression = true;
1945
1946 \$wgSitename         = \"{$slconf['Sitename']}\";
1947
1948 ## The URL base path to the directory containing the wiki;
1949 ## defaults for all runtime URL paths are based off of this.
1950 ## For more information on customizing the URLs please see:
1951 ## http://www.mediawiki.org/wiki/Manual:Short_URL
1952 \$wgScriptPath       = \"{$slconf['ScriptPath']}\";
1953 \$wgScriptExtension  = \"{$slconf['ScriptExtension']}\";
1954
1955 ## The relative URL path to the skins directory
1956 \$wgStylePath        = \"\$wgScriptPath/skins\";
1957
1958 ## The relative URL path to the logo.  Make sure you change this from the default,
1959 ## or else you'll overwrite your logo when you upgrade!
1960 \$wgLogo             = \"\$wgStylePath/common/images/wiki.png\";
1961
1962 ## UPO means: this is also a user preference option
1963
1964 \$wgEnableEmail      = $enableemail;
1965 \$wgEnableUserEmail  = $enableuseremail; # UPO
1966
1967 \$wgEmergencyContact = \"{$slconf['EmergencyContact']}\";
1968 \$wgPasswordSender = \"{$slconf['PasswordSender']}\";
1969
1970 \$wgEnotifUserTalk = $enotifusertalk; # UPO
1971 \$wgEnotifWatchlist = $enotifwatchlist; # UPO
1972 \$wgEmailAuthentication = $eauthent;
1973
1974 ## Database settings
1975 \$wgDBtype           = \"{$slconf['DBtype']}\";
1976 \$wgDBserver         = \"{$slconf['DBserver']}\";
1977 \$wgDBname           = \"{$slconf['DBname']}\";
1978 \$wgDBuser           = \"{$slconf['DBuser']}\";
1979 \$wgDBpassword       = \"{$slconf['DBpassword']}\";
1980
1981 {$dbsettings}
1982
1983 ## Shared memory settings
1984 \$wgMainCacheType = $cacheType;
1985 \$wgMemCachedServers = $mcservers;
1986
1987 ## To enable image uploads, make sure the 'images' directory
1988 ## is writable, then set this to true:
1989 \$wgEnableUploads       = false;
1990 {$magic}\$wgUseImageMagick = true;
1991 {$magic}\$wgImageMagickConvertCommand = \"{$convert}\";
1992
1993 ## If you use ImageMagick (or any other shell command) on a
1994 ## Linux server, this will need to be set to the name of an
1995 ## available UTF-8 locale
1996 {$locale}\$wgShellLocale = \"{$slconf['ShellLocale']}\";
1997
1998 ## If you want to use image uploads under safe mode,
1999 ## create the directories images/archive, images/thumb and
2000 ## images/temp, and make them all writable. Then uncomment
2001 ## this, if it's not already uncommented:
2002 {$hashedUploads}\$wgHashedUploadDirectory = false;
2003
2004 ## If you have the appropriate support software installed
2005 ## you can enable inline LaTeX equations:
2006 \$wgUseTeX           = false;
2007
2008 ## Set \$wgCacheDirectory to a writable directory on the web server
2009 ## to make your wiki go slightly faster. The directory should not
2010 ## be publically accessible from the web.
2011 #\$wgCacheDirectory = \"\$IP/cache\";
2012
2013 \$wgLocalInterwiki   = strtolower( \$wgSitename );
2014
2015 \$wgLanguageCode = \"{$slconf['LanguageCode']}\";
2016
2017 \$wgSecretKey = \"$secretKey\";
2018
2019 ## Default skin: you can change the default skin. Use the internal symbolic
2020 ## names, ie 'vector', 'monobook':
2021 \$wgDefaultSkin = 'monobook';
2022
2023 ## For attaching licensing metadata to pages, and displaying an
2024 ## appropriate copyright notice / icon. GNU Free Documentation
2025 ## License and Creative Commons licenses are supported so far.
2026 {$rights}\$wgEnableCreativeCommonsRdf = true;
2027 \$wgRightsPage = \"\"; # Set to the title of a wiki page that describes your license/copyright
2028 \$wgRightsUrl = \"{$slconf['RightsUrl']}\";
2029 \$wgRightsText = \"{$slconf['RightsText']}\";
2030 \$wgRightsIcon = \"{$slconf['RightsIcon']}\";
2031 # \$wgRightsCode = \"{$slconf['RightsCode']}\"; # Not yet used
2032
2033 \$wgDiff3 = \"{$slconf['diff3']}\";
2034
2035 # When you make changes to this configuration file, this will make
2036 # sure that cached pages are cleared.
2037 \$wgCacheEpoch = max( \$wgCacheEpoch, gmdate( 'YmdHis', @filemtime( __FILE__ ) ) );
2038 "; ## End of setting the $localsettings string
2039
2040         // Keep things in Unix line endings internally;
2041         // the system will write out as local text type.
2042         return str_replace( "\r\n", "\n", $localsettings );
2043 }
2044
2045 function dieout( $text ) {
2046         global $mainListOpened;
2047         if( $mainListOpened ) echo( "</ul>" );
2048         if( $text != '' && substr( $text, 0, 2 ) != '<p'  && substr( $text, 0, 2 ) != '<h' ){
2049                 echo "<p>$text</p>\n";
2050         } else {
2051                 echo $text;
2052         }
2053         die( "\n\n</div>\n</div>\n</div>\n</div>\n</body>\n</html>" );
2054 }
2055
2056 function importVar( &$var, $name, $default = "" ) {
2057         if( isset( $var[$name] ) ) {
2058                 $retval = $var[$name];
2059                 if ( get_magic_quotes_gpc() ) {
2060                         $retval = stripslashes( $retval );
2061                 }
2062         } else {
2063                 $retval = $default;
2064         }
2065         taint( $retval );
2066         return $retval;
2067 }
2068
2069 function importPost( $name, $default = "" ) {
2070         return importVar( $_POST, $name, $default );
2071 }
2072
2073 function importCheck( $name ) {
2074         return isset( $_POST[$name] );
2075 }
2076
2077 function importRequest( $name, $default = "" ) {
2078         return importVar( $_REQUEST, $name, $default );
2079 }
2080
2081 function aField( &$conf, $field, $text, $type = "text", $value = "", $onclick = '' ) {
2082         static $radioCount = 0;
2083         if( $type != "" ) {
2084                 $xtype = "type=\"$type\"";
2085         } else {
2086                 $xtype = "";
2087         }
2088
2089         $id = $field;
2090         $nolabel = ($type == "radio") || ($type == "hidden");
2091
2092         if ($type == 'radio')
2093                 $id .= $radioCount++;
2094
2095         if( !$nolabel ) {
2096                 echo "<label class='column' for=\"$id\">$text</label>";
2097         }
2098
2099         if( $type == "radio" && $value == $conf->$field ) {
2100                 $checked = "checked='checked'";
2101         } else {
2102                 $checked = "";
2103         }
2104         echo "<input $xtype name=\"$field\" id=\"$id\" class=\"iput-$type\" $checked ";
2105         if ($onclick) {
2106                 echo " onclick='toggleDBarea(\"$value\",1)' " ;
2107         }
2108         echo "value=\"";
2109         if( $type == "radio" ) {
2110                 echo htmlspecialchars( $value );
2111         } else {
2112                 echo htmlspecialchars( $conf->$field );
2113         }
2114
2115
2116         echo "\" />";
2117         if( $nolabel ) {
2118                 echo "<label for=\"$id\">$text</label>";
2119         }
2120
2121         global $errs;
2122         if(isset($errs[$field])) {
2123                 echo "<span class='error'>" . htmlspecialchars( $errs[$field] ) . "</span>\n";
2124         }
2125 }
2126
2127 function getLanguageList() {
2128         global $wgDummyLanguageCodes;
2129
2130         $codes = array();
2131         foreach ( Language::getLanguageNames() as $code => $name ) {
2132                 if( in_array( $code, $wgDummyLanguageCodes ) ) continue;
2133                 $codes[$code] = $code . ' - ' . $name;
2134         }
2135         ksort( $codes );
2136         return $codes;
2137 }
2138
2139 #Check for location of an executable
2140 # @param string $loc single location to check
2141 # @param array $names filenames to check for.
2142 # @param mixed $versioninfo array of details to use when checking version, use false for no version checking
2143 function locate_executable($loc, $names, $versioninfo = false) {
2144         if (!is_array($names))
2145                 $names = array($names);
2146
2147         foreach ($names as $name) {
2148                 $command = "$loc".DIRECTORY_SEPARATOR."$name";
2149                 if (@file_exists($command)) {
2150                         if (!$versioninfo)
2151                                 return $command;
2152
2153                         $file = str_replace('$1', $command, $versioninfo[0]);
2154                         if ( strstr( wfShellExec( $file ), $versioninfo[1]) !== false )
2155                                 return $command;
2156                 }
2157         }
2158         return false;
2159 }
2160
2161 # Test a memcached server
2162 function testMemcachedServer( $server ) {
2163         $hostport = explode(":", $server);
2164         $errstr = false;
2165         $fp = false;
2166         if ( !function_exists( 'fsockopen' ) ) {
2167                 $errstr = "Can't connect to memcached, fsockopen() not present";
2168         }
2169         if ( !$errstr && count( $hostport ) != 2 ) {
2170                 $errstr = 'Please specify host and port';
2171         }
2172         if ( !$errstr ) {
2173                 list( $host, $port ) = $hostport;
2174                 $errno = 0;
2175                 $fsockerr = '';
2176
2177                 $fp = @fsockopen( $host, $port, $errno, $fsockerr, 1.0 );
2178                 if ( $fp === false ) {
2179                         $errstr = "Cannot connect to memcached on $host:$port : $fsockerr";
2180                 }
2181         }
2182         if ( !$errstr ) {
2183                 $command = "version\r\n";
2184                 $bytes = fwrite( $fp, $command );
2185                 if ( $bytes != strlen( $command ) ) {
2186                         $errstr = "Cannot write to memcached socket on $host:$port";
2187                 }
2188         }
2189         if ( !$errstr ) {
2190                 $expected = "VERSION ";
2191                 $response = fread( $fp, strlen( $expected ) );
2192                 if ( $response != $expected ) {
2193                         $errstr = "Didn't get correct memcached response from $host:$port";
2194                 }
2195         }
2196         if ( $fp ) {
2197                 fclose( $fp );
2198         }
2199         if ( !$errstr ) {
2200                 echo "<li>Connected to memcached on " . htmlspecialchars( "$host:$port" ) ." successfully</li>";
2201         }
2202         return $errstr;
2203 }
2204
2205 function database_picker($conf) {
2206         global $ourdb;
2207         print "\n";
2208         foreach(array_keys($ourdb) as $db) {
2209                 if ($ourdb[$db]['havedriver']) {
2210                         print "\t<li>";
2211                         aField( $conf, "DBtype", $ourdb[$db]['fullname'], 'radio', $db, 'onclick');
2212                         print "</li>\n";
2213                 }
2214         }
2215         print "\n\t";
2216 }
2217
2218 function database_switcher($db) {
2219         global $ourdb;
2220         $color = $ourdb[$db]['bgcolor'];
2221         $full = $ourdb[$db]['fullname'];
2222         print "<fieldset id='$db' style='clear:both'><legend>$full-specific options</legend>\n";
2223 }
2224
2225 function printListItem( $item ) {
2226         print "<li>$item</li>";
2227 }
2228
2229 # Determine a suitable value for $wgShellLocale
2230 function getShellLocale( $wikiLang ) {
2231         # Give up now if we're in safe mode or open_basedir
2232         # It's theoretically possible but tricky to work with
2233         if ( wfIniGetBool( "safe_mode" ) || ini_get( 'open_basedir' ) || !function_exists('exec') ) {
2234                 return false;
2235         }
2236
2237         $os = php_uname( 's' );
2238         $supported = array( 'Linux', 'SunOS', 'HP-UX' ); # Tested these
2239         if ( !in_array( $os, $supported ) ) {
2240                 return false;
2241         }
2242
2243         # Get a list of available locales
2244         $lines = $ret = false;
2245         $lines = wfShellExec( '/usr/bin/locale -a', $ret, true );
2246         if ( $ret ) {
2247                 return false;
2248         }
2249
2250         $lines = wfArrayMap( 'trim', explode( "\n", $lines ) );
2251         $candidatesByLocale = array();
2252         $candidatesByLang = array();
2253         foreach ( $lines as $line ) {
2254                 if ( $line === '' ) {
2255                         continue;
2256                 }
2257                 if ( !preg_match( '/^([a-zA-Z]+)(_[a-zA-Z]+|)\.(utf8|UTF-8)(@[a-zA-Z_]*|)$/i', $line, $m ) ) {
2258                         continue;
2259                 }
2260                 list( $all, $lang, $territory, $charset, $modifier ) = $m;
2261                 $candidatesByLocale[$m[0]] = $m;
2262                 $candidatesByLang[$lang][] = $m;
2263         }
2264
2265         # Try the current value of LANG
2266         if ( isset( $candidatesByLocale[ getenv( 'LANG' ) ] ) ) {
2267                 return getenv( 'LANG' );
2268         }
2269
2270         # Try the most common ones
2271         $commonLocales = array( 'en_US.UTF-8', 'en_US.utf8', 'de_DE.UTF-8', 'de_DE.utf8' );
2272         foreach ( $commonLocales as $commonLocale ) {
2273                 if ( isset( $candidatesByLocale[$commonLocale] ) ) {
2274                         return $commonLocale;
2275                 }
2276         }
2277
2278         # Is there an available locale in the Wiki's language?
2279         if ( isset( $candidatesByLang[$wikiLang] ) ) {
2280                 $m = reset( $candidatesByLang[$wikiLang] );
2281                 return $m[0];
2282         }
2283
2284         # Are there any at all?
2285         if ( count( $candidatesByLocale ) ) {
2286                 $m = reset( $candidatesByLocale );
2287                 return $m[0];
2288         }
2289
2290         # Give up
2291         return false;
2292 }
2293
2294 function wfArrayMap( $function, $input ) {
2295         $ret = array_map( $function, $input );
2296         foreach ( $ret as $key => $value ) {
2297                 $taint = istainted( $input[$key] );
2298                 if ( $taint ) {
2299                         taint( $ret[$key], $taint );
2300                 }
2301         }
2302         return $ret;
2303 }
2304
2305 ?>
2306
2307         <div class="license">
2308         <hr/>
2309         <p>This program is free software; you can redistribute it and/or modify
2310          it under the terms of the GNU General Public License as published by
2311          the Free Software Foundation; either version 2 of the License, or
2312          (at your option) any later version.</p>
2313
2314          <p>This program is distributed in the hope that it will be useful,
2315          but WITHOUT ANY WARRANTY; without even the implied warranty of
2316          MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
2317          GNU General Public License for more details.</p>
2318
2319          <p>You should have received <a href="../COPYING">a copy of the GNU General Public License</a>
2320          along with this program; if not, write to the Free Software
2321          Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
2322          or <a href="http://www.gnu.org/copyleft/gpl.html">read it online</a></p>
2323         </div>
2324
2325 </div></div></div>
2326
2327
2328 <div id="column-one">
2329         <div class="portlet" id="p-logo">
2330           <a style="background-image: url(../skins/common/images/mediawiki.png);"
2331             href="../"
2332             title="Main Page"></a>
2333         </div>
2334         <script type="text/javascript"> if (window.isMSIE55) fixalpha(); </script>
2335         <div class='portlet'><div class='pBody'>
2336                 <ul>
2337                         <li><a href="../README">Readme</a></li>
2338                         <li><a href="../RELEASE-NOTES">Release notes</a></li>
2339                         <li><a href="../docs/">Documentation</a></li>
2340                         <li><a href="http://www.mediawiki.org/wiki/Help:Contents">User's Guide</a></li>
2341                         <li><a href="http://www.mediawiki.org/wiki/Manual:Contents">Administrator's Guide</a></li>
2342                         <li><a href="http://www.mediawiki.org/wiki/Manual:FAQ">FAQ</a></li>
2343                 </ul>
2344                 <p style="font-size:90%;margin-top:1em">MediaWiki is Copyright © 2001-2009 by Magnus Manske, Brion Vibber,
2345                  Lee Daniel Crocker, Tim Starling, Erik Möller, Gabriel Wicke, Ævar Arnfjörð Bjarmason, Niklas Laxström,
2346                  Domas Mituzas, Rob Church, Yuri Astrakhan, Aryeh Gregor, Aaron Schulz and others.</p>
2347         </div></div>
2348 </div>
2349
2350 </div>
2351
2352 </body>
2353 </html>