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