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/
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.
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.
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 # 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 # http://www.gnu.org/copyleft/gpl.html
22 error_reporting( E_ALL );
23 header( "Content-type: text/html; charset=utf-8" );
24 @ini_set( "display_errors", true );
26 ?><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
27 "http://www.w3.org/TR/html4/loose.dtd">
30 <meta http-equiv="Content-type" content="text/html; charset=utf-8">
31 <meta name="robots" content="noindex,nofollow">
32 <title>MediaWiki 1.5 Installation</title>
33 <style type="text/css">
38 background-color: #eee;
40 border: solid 1px #444;
48 dl.setup dd label.column {
60 /* margin-right: 200px; */
78 <a href="http://www.mediawiki.org/">
79 <img src="../skins/common/images/mediawiki.png" width="135" height="135" alt="" border="0" />
83 <p><strong><a href="http://www.mediawiki.org/">MediaWiki</a></strong> is
84 Copyright (C) 2001-2006 by Magnus Manske, Brion Vibber, Lee Daniel Crocker,
85 Tim Starling, Erik Möller, Gabriel Wicke and others.</p>
88 <li><a href="../README">Readme</a></li>
89 <li><a href="../RELEASE-NOTES">Release notes</a></li>
90 <li><a href="../docs/">doc/</a></li>
91 <li><a href="http://meta.wikipedia.org/wiki/MediaWiki_User's_Guide">User's Guide</a></li>
94 <p>This program is free software; you can redistribute it and/or modify
95 it under the terms of the GNU General Public License as published by
96 the Free Software Foundation; either version 2 of the License, or
97 (at your option) any later version.</p>
99 <p>This program is distributed in the hope that it will be useful,
100 but WITHOUT ANY WARRANTY; without even the implied warranty of
101 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
102 GNU General Public License for more details.</p>
104 <p>You should have received <a href="../COPYING">a copy of the GNU General Public License</a>
105 along with this program; if not, write to the Free Software
106 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
107 or <a href="http://www.gnu.org/copyleft/gpl.html">read it online</a></p>
112 # Relative includes seem to break if a parent directory is not readable;
113 # this is common for public_html subdirs under user home directories.
115 # As a dirty hack, we'll try to set up the include path first.
117 $IP = dirname( dirname( __FILE__ ) );
118 $sep = (DIRECTORY_SEPARATOR == "\\") ? ";" : ":";
119 ini_set( "include_path", ".$sep$IP$sep$IP/includes$sep$IP/languages" );
121 define( "MEDIAWIKI", true );
122 define( "MEDIAWIKI_INSTALL", true );
123 require_once( "includes/Defines.php" );
124 require_once( "includes/DefaultSettings.php" );
125 require_once( "includes/MagicWord.php" );
126 require_once( "includes/Namespace.php" );
129 <h1>MediaWiki <?php print $wgVersion ?> installation</h1>
134 /* Check for existing configurations and bug out! */
136 if( file_exists( "../LocalSettings.php" ) ) {
137 dieout( "<h2>Wiki is configured.</h2>
139 <p>Already configured... <a href='../index.php'>return to the wiki</a>.</p>
141 <p>(You should probably remove this directory for added security.)</p>" );
144 if( file_exists( "./LocalSettings.php" ) ) {
145 writeSuccessMessage();
150 if( !is_writable( "." ) ) {
151 dieout( "<h2>Can't write config file, aborting</h2>
153 <p>In order to configure the wiki you have to make the <tt>config</tt> subdirectory
154 writable by the web server. Once configuration is done you'll move the created
155 <tt>LocalSettings.php</tt> to the parent directory, and for added safety you can
156 then remove the <tt>config</tt> subdirectory entirely.</p>
158 <p>To make the directory writable on a Unix/Linux system:</p>
161 cd <i>/path/to/wiki</i>
167 require_once( "install-utils.inc" );
168 require_once( "maintenance/updaters.inc" );
171 function getEncoded( $data ) {
172 # removing latin1 support, no need...
175 function getSitename() { return $this->getEncoded( $this->Sitename ); }
176 function getSysopName() { return $this->getEncoded( $this->SysopName ); }
177 function getSysopPass() { return $this->getEncoded( $this->SysopPass ); }
182 <p><em>Please include all of the lines below when reporting installation problems.</em></p>
184 <h2>Checking environment...</h2>
189 $wgNoOutputBuffer = true;
190 $conf = new ConfigData;
192 install_version_checks();
194 print "<li>PHP " . phpversion() . ": ok</li>\n";
196 if( ini_get( "register_globals" ) ) {
198 <li><b class='error'>Warning:</b> <strong>PHP's
199 <tt><a href="http://php.net/register_globals">register_globals</a></tt>
200 option is enabled.</strong> MediaWiki will work correctly, but this setting
201 increases your exposure to potential security vulnerabilities in PHP-based
202 software running on your server. <strong>You should disable it if you are able.</strong></li>
208 if( ini_get( "magic_quotes_runtime" ) ) {
210 ?><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>
211 This option corrupts data input unpredictably; you cannot install or use
212 MediaWiki unless this option is disabled.
216 if( ini_get( "magic_quotes_sybase" ) ) {
218 ?><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>
219 This option corrupts data input unpredictably; you cannot install or use
220 MediaWiki unless this option is disabled.
224 if( ini_get( "mbstring.func_overload" ) ) {
226 ?><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>
227 This option causes errors and may corrupt data unpredictably;
228 you cannot install or use MediaWiki unless this option is disabled.
233 dieout( "</ul><p>Cannot install wiki.</p>" );
236 if( ini_get( "safe_mode" ) ) {
237 $conf->safeMode = true;
239 <li><b class='error'>Warning:</b> <strong>PHP's
240 <a href='http://www.php.net/features.safe-mode'>safe mode</a> is active.</strong>
241 You may have problems caused by this, particularly if using image uploads.
245 $conf->safeMode = false;
248 $sapi = php_sapi_name();
249 $conf->prettyURLs = true;
250 print "<li>PHP server API is $sapi; ";
253 case "apache2handler":
254 print "ok, using pretty URLs (<tt>index.php/Page_Title</tt>)";
260 case "apache2filter":
262 print "using ugly URLs (<tt>index.php?title=Page_Title</tt>)";
263 $conf->prettyURLs = false;
268 $conf->xml = function_exists( "utf8_encode" );
270 print "<li>Have XML / Latin1-UTF-8 conversion support.</li>\n";
272 dieout( "PHP's XML module is missing; the wiki requires functions in
273 this module and won't work in this configuration.
274 If you're running Mandrake, install the php-xml package." );
277 $memlimit = ini_get( "memory_limit" );
278 $conf->raiseMemory = false;
279 if( empty( $memlimit ) || $memlimit == -1 ) {
280 print "<li>PHP is configured with no <tt>memory_limit</tt>.</li>\n";
282 print "<li>PHP's <tt>memory_limit</tt> is " . htmlspecialchars( $memlimit ) . ". <strong>If this is too low, installation may fail!</strong> ";
283 $n = IntVal( $memlimit );
284 if( preg_match( '/^([0-9]+)[Mm]$/', trim( $memlimit ), $m ) ) {
285 $n = IntVal( $m[1] * (1024*1024) );
287 if( $n < 20*1024*1024 ) {
288 print "Attempting to raise limit to 20M... ";
289 if( false === ini_set( "memory_limit", "20M" ) ) {
292 $conf->raiseMemory = true;
299 $conf->zlib = function_exists( "gzencode" );
301 print "<li>Have zlib support; enabling output compression.</li>\n";
303 print "<li>No zlib support.</li>\n";
306 $conf->turck = function_exists( 'mmcache_get' );
307 if ( $conf->turck ) {
308 print "<li><a href=\"http://turck-mmcache.sourceforge.net/\">Turck MMCache</a> installed</li>\n";
310 $conf->eaccel = function_exists( 'eaccelerator_get' );
311 if ( $conf->eaccel ) {
312 $conf->turck = 'eaccelerator';
313 print "<li><a href=\"http://eaccelerator.sourceforge.net/\">eAccelerator</a> installed</li>\n";
315 if (!$conf->turck && !$conf->eaccel) {
316 print "<li>Neither <a href=\"http://turck-mmcache.sourceforge.net/\">Turck MMCache</a> nor <a href=\"http://eaccelerator.sourceforge.net/\">eAccelerator</a> are installed, " .
317 "can't use object caching functions</li>\n";
320 $conf->diff3 = false;
321 $diff3locations = array("/usr/bin", "/opt/csw/bin", "/usr/gnu/bin", "/usr/sfw/bin") + explode(":", getenv("PATH"));
322 $diff3names = array("gdiff3", "diff3");
324 $diff3versioninfo = array('$1 --version 2>&1', 'diff3 (GNU diffutils)');
325 foreach ($diff3locations as $loc) {
326 $exe = locate_executable($loc, $diff3names, $diff3versioninfo);
327 if ($exe !== false) {
334 print "<li>Found GNU diff3: <tt>$conf->diff3</tt>.</li>";
336 print "<li>GNU diff3 not found.</li>";
338 $conf->ImageMagick = false;
339 $imcheck = array( "/usr/bin", "/usr/local/bin", "/sw/bin", "/opt/local/bin" );
340 foreach( $imcheck as $dir ) {
341 $im = "$dir/convert";
342 if( file_exists( $im ) ) {
343 print "<li>Found ImageMagick: <tt>$im</tt>; image thumbnailing will be enabled if you enable uploads.</li>\n";
344 $conf->ImageMagick = $im;
349 $conf->HaveGD = function_exists( "imagejpeg" );
350 if( $conf->HaveGD ) {
351 print "<li>Found GD graphics library built-in";
352 if( !$conf->ImageMagick ) {
353 print ", image thumbnailing will be enabled if you enable uploads";
357 if( !$conf->ImageMagick ) {
358 print "<li>Couldn't find GD library or ImageMagick; image thumbnailing disabled.</li>\n";
362 $conf->UseImageResize = $conf->HaveGD || $conf->ImageMagick;
364 # $conf->IP = "/Users/brion/Sites/inplace";
365 $conf->IP = dirname( dirname( __FILE__ ) );
366 print "<li>Installation directory: <tt>" . htmlspecialchars( $conf->IP ) . "</tt></li>\n";
368 # $conf->ScriptPath = "/~brion/inplace";
369 $conf->ScriptPath = preg_replace( '{^(.*)/config.*$}', '$1', $_SERVER["PHP_SELF"] ); # was SCRIPT_NAME
370 print "<li>Script URI path: <tt>" . htmlspecialchars( $conf->ScriptPath ) . "</tt></li>\n";
372 $conf->posted = ($_SERVER["REQUEST_METHOD"] == "POST");
374 $conf->Sitename = ucfirst( importPost( "Sitename", "" ) );
375 $defaultEmail = empty( $_SERVER["SERVER_ADMIN"] )
377 : $_SERVER["SERVER_ADMIN"];
378 $conf->EmergencyContact = importPost( "EmergencyContact", $defaultEmail );
379 $conf->DBserver = importPost( "DBserver", "localhost" );
380 $conf->DBname = importPost( "DBname", "wikidb" );
381 $conf->DBuser = importPost( "DBuser", "wikiuser" );
382 $conf->DBpassword = importPost( "DBpassword" );
383 $conf->DBpassword2 = importPost( "DBpassword2" );
384 $conf->DBprefix = importPost( "DBprefix" );
385 $conf->DBmysql5 = (importPost( "DBmysql5" ) == "true") ? "true" : "false";
386 $conf->RootUser = importPost( "RootUser", "root" );
387 $conf->RootPW = importPost( "RootPW", "-" );
388 $conf->LanguageCode = importPost( "LanguageCode", "en" );
389 $conf->SysopName = importPost( "SysopName", "WikiSysop" );
390 $conf->SysopPass = importPost( "SysopPass" );
391 $conf->SysopPass2 = importPost( "SysopPass2" );
393 /* Check for validity */
396 if( $conf->Sitename == "" || $conf->Sitename == "MediaWiki" || $conf->Sitename == "Mediawiki" ) {
397 $errs["Sitename"] = "Must not be blank or \"MediaWiki\".";
399 if( $conf->DBuser == "" ) {
400 $errs["DBuser"] = "Must not be blank";
402 if( $conf->DBpassword == "" ) {
403 $errs["DBpassword"] = "Must not be blank";
405 if( $conf->DBpassword != $conf->DBpassword2 ) {
406 $errs["DBpassword2"] = "Passwords don't match!";
408 if( !preg_match( '/^[A-Za-z_0-9]*$/', $conf->DBprefix ) ) {
409 $errs["DBprefix"] = "Invalid table prefix";
412 if( $conf->SysopPass == "" ) {
413 $errs["SysopPass"] = "Must not be blank";
415 if( $conf->SysopPass != $conf->SysopPass2 ) {
416 $errs["SysopPass2"] = "Passwords don't match!";
419 $conf->License = importRequest( "License", "none" );
420 if( $conf->License == "gfdl" ) {
421 $conf->RightsUrl = "http://www.gnu.org/copyleft/fdl.html";
422 $conf->RightsText = "GNU Free Documentation License 1.2";
423 $conf->RightsCode = "gfdl";
424 $conf->RightsIcon = '${wgStylePath}/common/images/gnu-fdl.png';
425 } elseif( $conf->License == "none" ) {
426 $conf->RightsUrl = $conf->RightsText = $conf->RightsCode = $conf->RightsIcon = "";
428 $conf->RightsUrl = importRequest( "RightsUrl", "" );
429 $conf->RightsText = importRequest( "RightsText", "" );
430 $conf->RightsCode = importRequest( "RightsCode", "" );
431 $conf->RightsIcon = importRequest( "RightsIcon", "" );
434 $conf->Shm = importRequest( "Shm", "none" );
435 $conf->MCServers = importRequest( "MCServers" );
437 /* Test memcached servers */
439 if ( $conf->Shm == 'memcached' && $conf->MCServers ) {
440 $conf->MCServerArray = array_map( 'trim', explode( ',', $conf->MCServers ) );
441 foreach ( $conf->MCServerArray as $server ) {
442 $error = testMemcachedServer( $server );
444 $errs["MCServers"] = $error;
448 } else if ( $conf->Shm == 'memcached' ) {
449 $errs["MCServers"] = "Please specify at least one server if you wish to use memcached";
452 /* default values for installation */
453 $conf->Email =importRequest("Email", "email_enabled");
454 $conf->Emailuser=importRequest("Emailuser", "emailuser_enabled");
455 $conf->Enotif =importRequest("Enotif", "enotif_allpages");
456 $conf->Eauthent =importRequest("Eauthent", "eauthent_enabled");
458 if( $conf->posted && ( 0 == count( $errs ) ) ) {
459 do { /* So we can 'continue' to end prematurely */
460 $conf->Root = ($conf->RootPW != "");
462 /* Load up the settings and get installin' */
463 $local = writeLocalSettings( $conf );
464 $wgCommandLineMode = false;
467 $wgDBadminuser = "root";
468 $wgDBadminpassword = $conf->RootPW;
469 $wgDBprefix = $conf->DBprefix;
470 $wgCommandLineMode = true;
471 $wgUseDatabaseMessages = false; /* FIXME: For database failure */
472 require_once( "includes/Setup.php" );
475 require_once( "maintenance/InitialiseMessages.inc" );
477 $wgTitle = Title::newFromText( "Installation script" );
478 $mysqlOldClient = version_compare( mysql_get_client_info(), "4.1.0", "lt" );
479 if( $mysqlOldClient ) {
480 print "<li><b>PHP is linked with old MySQL client libraries. If you are
481 using a MySQL 4.1 server and have problems connecting to the database,
482 see <a href='http://dev.mysql.com/doc/mysql/en/old-client.html'
483 >http://dev.mysql.com/doc/mysql/en/old-client.html</a> for help.</b></li>\n";
486 # Determine how we're going to connect to the database
487 if( $conf->RootPW == '-' ) {
490 $db_user = $wgDBuser;
491 $db_pass = $wgDBpassword;
495 $db_user = $conf->RootUser;
496 $db_pass = $conf->RootPW;
499 # Now attempt the connection
500 echo( "<li>Connecting to $wgDBname on $wgDBserver as $db_user..." );
501 $wgDatabase = Database::newFromParams( $wgDBserver, $db_user, $db_pass, "", 1 );
502 if( $wgDatabase->isOpen() ) {
503 # We're in; set up a few variables
505 echo( "success.</li>\n" );
506 $wgDatabase->ignoreErrors( true );
507 $myver = mysql_get_server_info( $wgDatabase->mConn );
508 $wgDBadminuser = $db_user;
509 $wgDBadminpassword = $db_pass;
511 # There was an error; if we recognise it, give some useful feedback
513 $errno = mysql_errno();
514 $errtx = htmlspecialchars( mysql_error() );
515 echo( "failed with error $errno: $errtx.</li>\n" );
521 # The superuser details are wrong
522 $errs["RootUser"] = "Check username";
523 $errs["RootPW"] = "and password";
525 # The regular user details are wrong
526 $errs["DBuser"] = "Check username";
527 $errs["DBpassword"] = "and password";
532 $errs["DBserver"] = "Couldn't connect to database";
539 # Print out the mySQL version and enable mySQL 4 enhancements as needed
540 echo( "<li>Connected to $myver" );
541 if( version_compare( $myver, "4.0.0" ) >= 0 ) {
542 echo( "; using enhancements for mySQL 4.</li>" );
543 $conf->DBmysql4 = true;
544 $local = writeLocalSettings( $conf );
547 # Check for possible authentication problems re. password encryption in newer mySQL versions
548 $mysqlNewAuth = version_compare( $myver, "4.1.0", "ge" );
549 if( $mysqlNewAuth && $mysqlOldClient ) {
550 echo( "<li><span class=\"error\"><strong>You are using mySQL 4.1, however, PHP is linked to older client libraries. If you encounter authentication problems, 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 pertinent solutions.</strong></span></li>\n" );
553 # Check versions with regards to character sets, cough up an error if there are inconsistencies
555 if( $mysqlNewAuth ) {
556 echo( "<li>Enabling mySQL 4.1/5.0 character set mode.</li>\n" );
558 echo( "<li><span class=\"error\"><strong>mySQL 4.1/5.0 character set mode has been enabled, however, an older version of mySQL has been detected. This will likely cause the installation to fail.</li>\n" );
562 @$sel = mysql_select_db( $wgDBname, $wgDatabase->mConn );
564 print "<li>Database <tt>" . htmlspecialchars( $wgDBname ) . "</tt> exists</li>\n";
566 $err = mysql_errno();
567 if ( $err != 1049 ) {
568 print "<ul><li>Error selecting database $wgDBname: $err " . htmlspecialchars( mysql_error() ) .
572 $res = $wgDatabase->query( "CREATE DATABASE `$wgDBname`" );
574 print "<li>Couldn't create database <tt>" .
575 htmlspecialchars( $wgDBname ) .
576 "</tt>; try with root access or check your username/pass.</li>\n";
577 $errs["RootPW"] = "<- Enter";
580 print "<li>Created database <tt>" . htmlspecialchars( $wgDBname ) . "</tt></li>\n";
583 $wgDatabase->selectDB( $wgDBname );
585 if( $wgDatabase->tableExists( "cur" ) || $wgDatabase->tableExists( "revision" ) ) {
586 print "<li>There are already MediaWiki tables in this database. Checking if updates are needed...</li>\n";
588 # Create user if required
590 $conn = Database::newFromParams( $wgDBserver, $wgDBuser, $wgDBpassword, $wgDBname, 1 );
591 if ( $conn->isOpen() ) {
592 print "<li>DB user account ok</li>\n";
595 print "<li>Granting user permissions...";
596 if( $mysqlOldClient && $mysqlNewAuth ) {
597 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>";
600 dbsource( "../maintenance/users.sql", $wgDatabase );
610 print "<li>Finished update checks.</li>\n";
612 # FIXME: Check for errors
613 print "<li>Creating tables...";
615 print " using MySQL 5 table defs...";
616 dbsource( "../maintenance/mysql5/tables.sql", $wgDatabase );
618 print " using MySQL 3/4 table defs...";
619 dbsource( "../maintenance/tables.sql", $wgDatabase );
621 dbsource( "../maintenance/interwiki.sql", $wgDatabase );
622 print " done.</li>\n";
624 print "<li>Initializing data...";
625 $wgDatabase->insert( 'site_stats',
626 array( 'ss_row_id' => 1,
627 'ss_total_views' => 0,
628 'ss_total_edits' => 0,
629 'ss_good_articles' => 0 ) );
632 # Set up the DB user if we (i) can and (ii) need to
634 $db = Database::newFromParams( $wgDBserver, $wgDBuser, $wgDBpassword, $wgDBname, 1 );
635 if( $db->isOpen() ) {
638 print "<li>Granting user permissions...</li>\n";
639 dbsource( "../maintenance/users.sql", $wgDatabase );
644 if( $conf->SysopName ) {
645 $u = User::newFromName( $conf->getSysopName() );
646 if ( 0 == $u->idForName() ) {
648 $u->setPassword( $conf->getSysopPass() );
651 $u->addGroup( "sysop" );
652 $u->addGroup( "bureaucrat" );
654 print "<li>Created sysop account <tt>" .
655 htmlspecialchars( $conf->SysopName ) . "</tt>.</li>\n";
657 print "<li>Could not create user - already exists!</li>\n";
660 print "<li>Skipped sysop account creation, no name given.</li>\n";
663 $titleobj = Title::newFromText( wfMsgNoDB( "mainpage" ) );
664 $article = new Article( $titleobj );
665 $newid = $article->insertOn( $wgDatabase );
666 $revision = new Revision( array(
668 'text' => wfMsg( 'mainpagetext' ) . "\n\n" . wfMsg( 'mainpagedocfooter' ),
671 'user_text' => 'MediaWiki default',
673 $revid = $revision->insertOn( $wgDatabase );
674 $article->updateRevisionOn( $wgDatabase, $revision );
677 initialiseMessages();
678 print "</pre></li>\n";
681 /* Write out the config file now that all is well */
682 print "<p>Creating LocalSettings.php...</p>\n\n";
683 $localSettings = "<" . "?php$endl$local$endl?" . ">";
684 // Fix up a common line-ending problem (due to CVS on Windows)
685 $localSettings = str_replace( "\r\n", "\n", $localSettings );
687 if( version_compare( phpversion(), "4.3.2" ) >= 0 ) {
688 $xt = "xt"; # Refuse to overwrite an existing file
690 $xt = "wt"; # 'x' is not available prior to PHP 4.3.2. We did check above, but race conditions blah blah
692 $f = fopen( "LocalSettings.php", $xt );
695 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" .
696 "<p>Here's the file that would have been written, try to paste it into place manually:</p>\n" .
697 "<pre>\n" . htmlspecialchars( $localSettings ) . "</pre>\n" );
699 if(fwrite( $f, $localSettings ) ) {
701 writeSuccessMessage();
704 die("<p class='error'>An error occured while writing the config/LocalSettings.php file. Check user rights and disk space then try again.</p>\n");
716 if( count( $errs ) ) {
717 /* Display options form */
719 if( $conf->posted ) {
720 echo "<p class='error'>Something's not quite right yet; make sure everything below is filled out correctly.</p>\n";
724 <form action="index.php" name="config" method="post">
732 aField( $conf, "Sitename", "Site name:" );
736 Your site name should be a relatively short word. It'll appear as the namespace
737 name for 'meta' pages as well as throughout the user interface. Good site names
738 are things like "<a href="http://www.wikipedia.org/">Wikipedia</a>" and
739 "<a href="http://openfacts.berlios.de/">OpenFacts</a>"; avoid punctuation,
740 which may cause problems.
745 aField( $conf, "EmergencyContact", "Contact e-mail" );
749 This will be used as the return address for password reminders and
750 may be displayed in some error conditions so visitors can get in
751 touch with you. It is also be used as the default sender address of e-mail
752 notifications (enotifs).
756 <label class='column' for="LanguageCode">Language</label>
757 <select id="LanguageCode" name="LanguageCode">
760 $list = getLanguageList();
761 foreach( $list as $code => $name ) {
762 $sel = ($code == $conf->LanguageCode) ? 'selected="selected"' : '';
763 echo "\t\t<option value=\"$code\" $sel>$name</option>\n";
769 You may select the language for the user interface of the wiki...
770 Some localizations are less complete than others. Unicode (UTF-8 encoding)
771 is used for all localizations.
775 <label class='column'>Copyright/license metadata</label>
776 <div>Select one:</div>
779 <li><?php aField( $conf, "License", "no license metadata", "radio", "none" ); ?></li>
780 <li><?php aField( $conf, "License", "GNU Free Documentation License 1.2 (Wikipedia-compatible)", "radio", "gfdl" ); ?></li>
782 aField( $conf, "License", "a Creative Commons license...", "radio", "cc" );
783 $partner = "MediaWiki";
784 $exit = urlencode( "$wgServer{$conf->ScriptPath}/config/index.php?License=cc&RightsUrl=[license_url]&RightsText=[license_name]&RightsCode=[license_code]&RightsIcon=[license_button]" );
785 $icon = urlencode( "$wgServer$wgUploadPath/wiki.png" );
786 $ccApp = htmlspecialchars( "http://creativecommons.org/license/?partner=$partner&exit_url=$exit&partner_icon_url=$icon" );
787 print "<a href=\"$ccApp\">choose</a>";
788 ?> (link will wipe out any other data in this form!)
789 <?php if( $conf->License == "cc" ) { ?>
791 <li><?php aField( $conf, "RightsIcon", "<img src=\"" . htmlspecialchars( $conf->RightsIcon ) . "\" alt='icon' />", "hidden" ); ?></li>
792 <li><?php aField( $conf, "RightsText", htmlspecialchars( $conf->RightsText ), "hidden" ); ?></li>
793 <li><?php aField( $conf, "RightsCode", "code: " . htmlspecialchars( $conf->RightsCode ), "hidden" ); ?></li>
794 <li><?php aField( $conf, "RightsUrl", "<a href=\"" . htmlspecialchars( $conf->RightsUrl ) . "\">" . htmlspecialchars( $conf->RightsUrl ) . "</a>", "hidden" ); ?></li>
801 MediaWiki can include a basic license notice, icon, and machine-readable
802 copyright metadata if your wiki's content is to be licensed under
803 the GNU FDL or a Creative Commons license. If you're not sure, leave
809 <?php aField( $conf, "SysopName", "Sysop account name:", "" ) ?>
812 <?php aField( $conf, "SysopPass", "password:", "password" ) ?>
815 <?php aField( $conf, "SysopPass2", "again:", "password" ) ?>
818 A sysop user account can lock or delete pages, block problematic IP
819 addresses from editing, and other maintenance tasks. If creating a new
820 wiki database, a sysop account will be created with the given name
825 <label class='column'>Shared memory caching</label>
826 <div>Select one:</div>
829 <li><?php aField( $conf, "Shm", "no caching", "radio", "none" ); ?></li>
831 if ( $conf->turck ) {
833 aField( $conf, "Shm", "Turck MMCache", "radio", "turck" );
838 if ( $conf->eaccel ) {
840 aField( $conf, "Shm", "eAccelerator", "radio", "eaccel" );
844 <li><?php aField( $conf, "Shm", "Memcached", "radio", "memcached" ); ?></li>
845 <li><?php aField( $conf, "MCServers", "Memcached servers", "" ) ?></li>
849 Using a shared memory system such as Turck MMCache, eAccelerator, or Memcached will speed
850 up MediaWiki significantly. Memcached is the best solution but needs to be
851 installed. Specify the server addresses and ports in a comma-separted list. Only
852 use Turck shared memory if the wiki will be running on a single Apache server.
855 <h2>E-mail, e-mail notification and authentication setup</h2>
859 <label class='column'>E-mail (general)</label>
860 <div>Select one:</div>
863 <li><?php aField( $conf, "Email", "enabled", "radio", "email_enabled" ); ?></li>
864 <li><?php aField( $conf, "Email", "disabled", "radio", "email_disabled" ); ?></li>
868 Use this to disable all e-mail functions (send a password reminder, user-to-user e-mail and e-mail notification),
869 if sending e-mails on your server doesn't work.
872 <label class='column'>User-to-user e-mail</label>
873 <div>Select one:</div>
876 <li><?php aField( $conf, "Emailuser", "enabled", "radio", "emailuser_enabled" ); ?></li>
877 <li><?php aField( $conf, "Emailuser", "disabled", "radio", "emailuser_disabled" ); ?></li>
881 Use this to disable only the user-to-user e-mail function (EmailUser).
884 <label class='column'>E-mail notification</label>
885 <div>Select one:</div>
888 <li><?php aField( $conf, "Enotif", "disabled", "radio", "enotif_disabled" ); ?></li>
889 <li><?php aField( $conf, "Enotif", "enabled for changes of watch-listed and user_talk pages (recommended for small wikis; perhaps not suited for large wikis)", "radio", "enotif_allpages" ); ?></li>
890 <li><?php aField( $conf, "Enotif", "enabled for changes of user_talk pages only (suited for small and large wikis)", "radio", "enotif_usertalk" ); ?></li>
895 E-mail notification sends a notification e-mail to a user, when the user_talk page is changed
896 and/or when watch-listed pages are changed, depending on the above settings.
897 When testing this feature, be reminded, that obviously an e-mail address must be present in your preferences
898 and that your own changes never trigger notifications to be sent to yourself.</p>
900 <p>Users get corresponding options to select or deselect in their users' preferences.
901 The user options are not shown on the preference page, if e-mail notification is disabled.</p>
903 <p>There are additional options for fine tuning in /includes/DefaultSettings.php .</p>
907 <label class='column'>E-mail address authentication</label>
908 <div>Select one:</div>
911 <li><?php aField( $conf, "Eauthent", "disabled", "radio", "eauthent_disabled" ); ?></li>
912 <li><?php aField( $conf, "Eauthent", "enabled", "radio", "eauthent_enabled" ); ?></li>
916 <p>E-mail address authentication uses a scheme to authenticate e-mail addresses of the users. The user who initially enters or changes his/her stored e-mail address
917 gets a link with a token mailed to that address. The stored e-mail address is authenticated at the moment the user comes back to the wiki via the link.</p>
919 <p>The e-mail address stays authenticated as long as the user does not change it; the time of authentication is indicated
920 on the user preference page.</p>
922 <p>If the option is enabled, only authenticated e-mail addresses can receive EmailUser mails and/or
923 e-mail notification mails.</p>
928 <h2>Database config</h2>
932 aField( $conf, "DBserver", "MySQL server" );
935 If your database server isn't on your web server, enter the name
940 aField( $conf, "DBname", "Database name" );
943 aField( $conf, "DBuser", "DB username" );
946 aField( $conf, "DBpassword", "DB password", "password" );
949 aField( $conf, "DBpassword2", "again", "password" );
952 If you only have a single user account and database available,
953 enter those here. If you have database root access (see below)
954 you can specify new accounts/databases to be created.
958 aField( $conf, "DBprefix", "Database table prefix" );
961 <p>If you need to share one database between multiple wikis, or
962 MediaWiki and another web application, you may choose to
963 add a prefix to all the table names to avoid conflicts.</p>
965 <p>Avoid exotic characters; something like <tt>mw_</tt> is good.</p>
968 <dd><label class="column">Database charset</label>
969 <div>Select one:</div>
971 <li><?php aField( $conf, "DBmysql5", "Backwards-compatible UTF-8", "radio", "false" ); ?></li>
972 <li><?php aField( $conf, "DBmysql5", "Experimental MySQL 4.1/5.0 UTF-8", "radio", "true" ); ?></li>
976 <b>EXPERIMENTAL:</b> You can enable explicit Unicode charset support
977 for MySQL 4.1 and 5.0 servers. This is not well tested and may
978 cause things to break. <b>If upgrading an older installation, leave
979 in backwards-compatible mode.</b>
984 aField( $conf, "RootUser", "Super user:", "text" );
990 aField( $conf, "RootPW", "Password:", "password" );
994 If the database user specified above does not exist, or does not have permissions to create
995 the database or tables required, please provide details of a superuser account, such as <strong>root</strong>,
996 which does. If this is not needed, leave the password set to <strong>-</strong>.
1000 <label class='column'> </label>
1001 <input type="submit" value="Install!" />
1011 /* -------------------------------------------------------------------------------------- */
1012 function writeSuccessMessage() {
1014 if ( ini_get( 'safe_mode' ) && !ini_get( 'open_basedir' ) ) {
1016 <p>Installation successful!</p>
1017 <p>To complete the installation, please do the following:
1019 <li>Download config/LocalSettings.php with your FTP client or file manager</li>
1020 <li>Upload it to the parent directory</li>
1021 <li>Delete config/LocalSettings.php</li>
1022 <li>Start using <a href='../index.php'>your wiki</a>!
1024 <p>If you are in a shared hosting environment, do <strong>not</strong> just move LocalSettings.php
1025 remotely. LocalSettings.php is currently owned by the user your webserver is running under,
1026 which means that anyone on the same server can read your database password! Downloading
1027 it and uploading it again will hopefully change the ownership to a user ID specific to you.</p>
1030 echo "<p>Installation successful! Move the config/LocalSettings.php file into the parent directory, then follow
1031 <a href='../index.php'>this link</a> to your wiki.</p>\n";
1036 function escapePhpString( $string ) {
1037 return strtr( $string,
1048 function writeLocalSettings( $conf ) {
1049 $conf->DBmysql4 = @$conf->DBmysql4 ? 'true' : 'false';
1050 $conf->UseImageResize = $conf->UseImageResize ? 'true' : 'false';
1051 $conf->PasswordSender = $conf->EmergencyContact;
1052 $zlib = ($conf->zlib ? "" : "# ");
1053 $magic = ($conf->ImageMagick ? "" : "# ");
1054 $convert = ($conf->ImageMagick ? $conf->ImageMagick : "/usr/bin/convert" );
1055 $pretty = ($conf->prettyURLs ? "" : "# ");
1056 $ugly = ($conf->prettyURLs ? "# " : "");
1057 $rights = ($conf->RightsUrl) ? "" : "# ";
1058 $hashedUploads = $conf->safeMode ? '' : '# ';
1060 switch ( $conf->Shm ) {
1062 $cacheType = 'CACHE_MEMCACHED';
1063 $mcservers = var_export( $conf->MCServerArray, true );
1067 $cacheType = 'CACHE_ACCEL';
1068 $mcservers = 'array()';
1071 $cacheType = 'CACHE_NONE';
1072 $mcservers = 'array()';
1075 if ( $conf->Email == 'email_enabled' ) {
1076 $enableemail = 'true';
1077 $enableuseremail = ( $conf->Emailuser == 'emailuser_enabled' ) ? 'true' : 'false' ;
1078 $eauthent = ( $conf->Eauthent == 'eauthent_enabled' ) ? 'true' : 'false' ;
1079 switch ( $conf->Enotif ) {
1080 case 'enotif_usertalk':
1081 $enotifusertalk = 'true';
1082 $enotifwatchlist = 'false';
1084 case 'enotif_allpages':
1085 $enotifusertalk = 'true';
1086 $enotifwatchlist = 'true';
1089 $enotifusertalk = 'false';
1090 $enotifwatchlist = 'false';
1093 $enableuseremail = 'false';
1094 $enableemail = 'false';
1095 $eauthent = 'false';
1096 $enotifusertalk = 'false';
1097 $enotifwatchlist = 'false';
1100 $file = @fopen( "/dev/urandom", "r" );
1102 $secretKey = bin2hex( fread( $file, 32 ) );
1106 for ( $i=0; $i<8; $i++ ) {
1107 $secretKey .= dechex(mt_rand(0, 0x7fffffff));
1109 print "<li>Warning: \$wgSecretKey key is insecure, generated with mt_rand(). Consider changing it manually.</li>\n";
1112 # Add slashes to strings for double quoting
1113 $slconf = array_map( "escapePhpString", get_object_vars( $conf ) );
1114 if( $conf->License == 'gfdl' ) {
1115 # Needs literal string interpolation for the current style path
1116 $slconf['RightsIcon'] = $conf->RightsIcon;
1119 $sep = (DIRECTORY_SEPARATOR == "\\") ? ";" : ":";
1121 # This file was automatically generated by the MediaWiki installer.
1122 # If you make manual changes, please keep track in case you need to
1123 # recreate them later.
1125 \$IP = \"{$slconf['IP']}\";
1126 ini_set( \"include_path\", \".$sep\$IP$sep\$IP/includes$sep\$IP/languages\" );
1127 require_once( \"includes/DefaultSettings.php\" );
1129 # If PHP's memory limit is very low, some operations may fail.
1130 " . ($conf->raiseMemory ? '' : '# ' ) . "ini_set( 'memory_limit', '20M' );" . "
1132 if ( \$wgCommandLineMode ) {
1133 if ( isset( \$_SERVER ) && array_key_exists( 'REQUEST_METHOD', \$_SERVER ) ) {
1134 die( \"This script must be run from the command line\\n\" );
1136 } elseif ( empty( \$wgNoOutputBuffer ) ) {
1137 ## Compress output if the browser supports it
1138 {$zlib}if( !ini_get( 'zlib.output_compression' ) ) @ob_start( 'ob_gzhandler' );
1141 \$wgSitename = \"{$slconf['Sitename']}\";
1143 \$wgScriptPath = \"{$slconf['ScriptPath']}\";
1144 \$wgScript = \"\$wgScriptPath/index.php\";
1145 \$wgRedirectScript = \"\$wgScriptPath/redirect.php\";
1147 ## If using PHP as a CGI module, use the ugly URLs
1148 {$pretty}\$wgArticlePath = \"\$wgScript/\$1\";
1149 {$ugly}\$wgArticlePath = \"\$wgScript?title=\$1\";
1151 \$wgStylePath = \"\$wgScriptPath/skins\";
1152 \$wgStyleDirectory = \"\$IP/skins\";
1153 \$wgLogo = \"\$wgStylePath/common/images/wiki.png\";
1155 \$wgUploadPath = \"\$wgScriptPath/images\";
1156 \$wgUploadDirectory = \"\$IP/images\";
1158 \$wgEnableEmail = $enableemail;
1159 \$wgEnableUserEmail = $enableuseremail;
1161 \$wgEmergencyContact = \"{$slconf['EmergencyContact']}\";
1162 \$wgPasswordSender = \"{$slconf['PasswordSender']}\";
1164 ## For a detailed description of the following switches see
1165 ## http://meta.wikimedia.org/Enotif and http://meta.wikimedia.org/Eauthent
1166 ## There are many more options for fine tuning available see
1167 ## /includes/DefaultSettings.php
1168 ## UPO means: this is also a user preference option
1169 \$wgEnotifUserTalk = $enotifusertalk; # UPO
1170 \$wgEnotifWatchlist = $enotifwatchlist; # UPO
1171 \$wgEmailAuthentication = $eauthent;
1173 \$wgDBserver = \"{$slconf['DBserver']}\";
1174 \$wgDBname = \"{$slconf['DBname']}\";
1175 \$wgDBuser = \"{$slconf['DBuser']}\";
1176 \$wgDBpassword = \"{$slconf['DBpassword']}\";
1177 \$wgDBprefix = \"{$slconf['DBprefix']}\";
1179 # If you're on MySQL 3.x, this next line must be FALSE:
1180 \$wgDBmysql4 = {$conf->DBmysql4};
1182 # Experimental charset support for MySQL 4.1/5.0.
1183 \$wgDBmysql5 = {$conf->DBmysql5};
1185 ## Shared memory settings
1186 \$wgMainCacheType = $cacheType;
1187 \$wgMemCachedServers = $mcservers;
1189 ## To enable image uploads, make sure the 'images' directory
1190 ## is writable, then uncomment this:
1191 # \$wgEnableUploads = true;
1192 \$wgUseImageResize = {$conf->UseImageResize};
1193 {$magic}\$wgUseImageMagick = true;
1194 {$magic}\$wgImageMagickConvertCommand = \"{$convert}\";
1196 ## If you want to use image uploads under safe mode,
1197 ## create the directories images/archive, images/thumb and
1198 ## images/temp, and make them all writable. Then uncomment
1199 ## this, if it's not already uncommented:
1200 {$hashedUploads}\$wgHashedUploadDirectory = false;
1202 ## If you have the appropriate support software installed
1203 ## you can enable inline LaTeX equations:
1204 # \$wgUseTeX = true;
1205 \$wgMathPath = \"{\$wgUploadPath}/math\";
1206 \$wgMathDirectory = \"{\$wgUploadDirectory}/math\";
1207 \$wgTmpDirectory = \"{\$wgUploadDirectory}/tmp\";
1209 \$wgLocalInterwiki = \$wgSitename;
1211 \$wgLanguageCode = \"{$slconf['LanguageCode']}\";
1213 \$wgProxyKey = \"$secretKey\";
1215 ## Default skin: you can change the default skin. Use the internal symbolic
1216 ## names, ie 'standard', 'nostalgia', 'cologneblue', 'monobook':
1217 # \$wgDefaultSkin = 'monobook';
1219 ## For attaching licensing metadata to pages, and displaying an
1220 ## appropriate copyright notice / icon. GNU Free Documentation
1221 ## License and Creative Commons licenses are supported so far.
1222 {$rights}\$wgEnableCreativeCommonsRdf = true;
1223 \$wgRightsPage = \"\"; # Set to the title of a wiki page that describes your license/copyright
1224 \$wgRightsUrl = \"{$slconf['RightsUrl']}\";
1225 \$wgRightsText = \"{$slconf['RightsText']}\";
1226 \$wgRightsIcon = \"{$slconf['RightsIcon']}\";
1227 # \$wgRightsCode = \"{$slconf['RightsCode']}\"; # Not yet used
1229 \$wgDiff3 = \"{$slconf['diff3']}\";
1231 // Keep things in Unix line endings internally;
1232 // the system will write out as local text type.
1233 return str_replace( "\r\n", "\n", $localsettings );
1236 function dieout( $text ) {
1237 die( $text . "\n\n</body>\n</html>" );
1240 function importVar( &$var, $name, $default = "" ) {
1241 if( isset( $var[$name] ) ) {
1242 $retval = $var[$name];
1243 if ( get_magic_quotes_gpc() ) {
1244 $retval = stripslashes( $retval );
1252 function importPost( $name, $default = "" ) {
1253 return importVar( $_POST, $name, $default );
1256 function importRequest( $name, $default = "" ) {
1257 return importVar( $_REQUEST, $name, $default );
1260 function aField( &$conf, $field, $text, $type = "", $value = "" ) {
1262 $xtype = "type=\"$type\"";
1267 if(!(isset($id)) or ($id == "") ) $id = $field;
1268 $nolabel = ($type == "radio") || ($type == "hidden");
1272 echo "\t\t<label class='column' for=\"$id\">$text</label>\n";
1275 if( $type == "radio" && $value == $conf->$field ) {
1276 $checked = "checked='checked'";
1280 echo "\t\t<input $xtype name=\"$field\" id=\"$id\" $checked value=\"";
1281 if( $type == "radio" ) {
1282 echo htmlspecialchars( $value );
1284 echo htmlspecialchars( $conf->$field );
1288 echo " $text</label>\n";
1292 if(isset($errs[$field])) echo "<span class='error'>" . $errs[$field] . "</span>\n";
1295 function getLanguageList() {
1296 global $wgLanguageNames;
1297 if( !isset( $wgLanguageNames ) ) {
1298 $wgContLanguageCode = "xxx";
1299 function wfLocalUrl( $x ) { return $x; }
1300 function wfLocalUrlE( $x ) { return $x; }
1301 require_once( "languages/Names.php" );
1306 $d = opendir( "../languages" );
1307 while( false !== ($f = readdir( $d ) ) ) {
1308 if( preg_match( '/Language([A-Z][a-z_]+)\.php$/', $f, $m ) ) {
1309 $code = str_replace( '_', '-', strtolower( $m[1] ) );
1310 if( isset( $wgLanguageNames[$code] ) ) {
1311 $name = $code . ' - ' . $wgLanguageNames[$code];
1315 $codes[$code] = $name;
1323 #Check for location of an executable
1324 # @param string $loc single location to check
1325 # @param array $names filenames to check for.
1326 # @param mixed $versioninfo array of details to use when checking version, use false for no version checking
1327 function locate_executable($loc, $names, $versioninfo = false) {
1328 if (!is_array($names))
1329 $names = array($names);
1331 foreach ($names as $name) {
1332 if (file_exists("$loc/$name")) {
1334 return "$loc/$name";
1336 $file = str_replace('$1', "$loc/$name", $versioninfo[0]);
1337 if (strstr(`$file`, $versioninfo[1]) !== false)
1338 return "$loc/$name";
1344 # Test a memcached server
1345 function testMemcachedServer( $server ) {
1346 $hostport = explode(":", $server);
1349 if ( !function_exists( 'fsockopen' ) ) {
1350 $errstr = "Can't connect to memcached, fsockopen() not present";
1352 if ( !$errstr && count( $hostport ) != 2 ) {
1353 $errstr = 'Please specify host and port';
1354 var_dump( $hostport );
1357 list( $host, $port ) = $hostport;
1361 $fp = @fsockopen( $host, $port, $errno, $fsockerr, 1.0 );
1362 if ( $fp === false ) {
1363 $errstr = "Cannot connect to memcached on $host:$port : $fsockerr";
1367 $command = "version\r\n";
1368 $bytes = fwrite( $fp, $command );
1369 if ( $bytes != strlen( $command ) ) {
1370 $errstr = "Cannot write to memcached socket on $host:$port";
1374 $expected = "VERSION ";
1375 $response = fread( $fp, strlen( $expected ) );
1376 if ( $response != $expected ) {
1377 $errstr = "Didn't get correct memcached response from $host:$port";
1384 echo "<li>Connected to memcached on $host:$port successfully";