MediaWiki  REL1_21
WebInstallerPage.php
Go to the documentation of this file.
00001 <?php
00030 abstract class WebInstallerPage {
00031 
00037         public $parent;
00038 
00039         abstract public function execute();
00040 
00046         public function __construct( WebInstaller $parent ) {
00047                 $this->parent = $parent;
00048         }
00049 
00056         public function isSlow() {
00057                 return false;
00058         }
00059 
00060         public function addHTML( $html ) {
00061                 $this->parent->output->addHTML( $html );
00062         }
00063 
00064         public function startForm() {
00065                 $this->addHTML(
00066                         "<div class=\"config-section\">\n" .
00067                         Html::openElement(
00068                                 'form',
00069                                 array(
00070                                         'method' => 'post',
00071                                         'action' => $this->parent->getUrl( array( 'page' => $this->getName() ) )
00072                                 )
00073                         ) . "\n"
00074                 );
00075         }
00076 
00077         public function endForm( $continue = 'continue', $back = 'back' ) {
00078                 $s = "<div class=\"config-submit\">\n";
00079                 $id = $this->getId();
00080 
00081                 if ( $id === false ) {
00082                         $s .= Html::hidden( 'lastPage', $this->parent->request->getVal( 'lastPage' ) );
00083                 }
00084 
00085                 if ( $continue ) {
00086                         // Fake submit button for enter keypress (bug 26267)
00087                         $s .= Xml::submitButton( wfMessage( "config-$continue" )->text(),
00088                                 array( 'name' => "enter-$continue", 'style' =>
00089                                         'visibility:hidden;overflow:hidden;width:1px;margin:0' ) ) . "\n";
00090                 }
00091 
00092                 if ( $back ) {
00093                         $s .= Xml::submitButton( wfMessage( "config-$back" )->text(),
00094                                 array(
00095                                         'name' => "submit-$back",
00096                                         'tabindex' => $this->parent->nextTabIndex()
00097                                 ) ) . "\n";
00098                 }
00099 
00100                 if ( $continue ) {
00101                         $s .= Xml::submitButton( wfMessage( "config-$continue" )->text(),
00102                                 array(
00103                                         'name' => "submit-$continue",
00104                                         'tabindex' => $this->parent->nextTabIndex(),
00105                                 ) ) . "\n";
00106                 }
00107 
00108                 $s .= "</div></form></div>\n";
00109                 $this->addHTML( $s );
00110         }
00111 
00112         public function getName() {
00113                 return str_replace( 'WebInstaller_', '', get_class( $this ) );
00114         }
00115 
00116         protected function getId() {
00117                 return array_search( $this->getName(), $this->parent->pageSequence );
00118         }
00119 
00120         public function getVar( $var ) {
00121                 return $this->parent->getVar( $var );
00122         }
00123 
00124         public function setVar( $name, $value ) {
00125                 $this->parent->setVar( $name, $value );
00126         }
00127 
00135         protected function getFieldsetStart( $legend ) {
00136                 return "\n<fieldset><legend>" . wfMessage( $legend )->escaped() . "</legend>\n";
00137         }
00138 
00144         protected function getFieldsetEnd() {
00145                 return "</fieldset>\n";
00146         }
00147 
00151         protected function startLiveBox() {
00152                 $this->addHTML(
00153                         '<div id="config-spinner" style="display:none;">' .
00154                         '<img src="../skins/common/images/ajax-loader.gif" /></div>' .
00155                         '<script>jQuery( "#config-spinner" ).show();</script>' .
00156                         '<div id="config-live-log">' .
00157                         '<textarea name="LiveLog" rows="10" cols="30" readonly="readonly">'
00158                 );
00159                 $this->parent->output->flush();
00160         }
00161 
00165         protected function endLiveBox() {
00166                 $this->addHTML( '</textarea></div>
00167 <script>jQuery( "#config-spinner" ).hide()</script>' );
00168                 $this->parent->output->flush();
00169         }
00170 }
00171 
00172 class WebInstaller_Language extends WebInstallerPage {
00173 
00174         public function execute() {
00175                 global $wgLang;
00176                 $r = $this->parent->request;
00177                 $userLang = $r->getVal( 'uselang' );
00178                 $contLang = $r->getVal( 'ContLang' );
00179 
00180                 $languages = Language::fetchLanguageNames();
00181                 $lifetime = intval( ini_get( 'session.gc_maxlifetime' ) );
00182                 if ( !$lifetime ) {
00183                         $lifetime = 1440; // PHP default
00184                 }
00185 
00186                 if ( $r->wasPosted() ) {
00187                         # Do session test
00188                         if ( $this->parent->getSession( 'test' ) === null ) {
00189                                 $requestTime = $r->getVal( 'LanguageRequestTime' );
00190                                 if ( !$requestTime ) {
00191                                         // The most likely explanation is that the user was knocked back
00192                                         // from another page on POST due to session expiry
00193                                         $msg = 'config-session-expired';
00194                                 } elseif ( time() - $requestTime > $lifetime ) {
00195                                         $msg = 'config-session-expired';
00196                                 } else {
00197                                         $msg = 'config-no-session';
00198                                 }
00199                                 $this->parent->showError( $msg, $wgLang->formatTimePeriod( $lifetime ) );
00200                         } else {
00201                                 if ( isset( $languages[$userLang] ) ) {
00202                                         $this->setVar( '_UserLang', $userLang );
00203                                 }
00204                                 if ( isset( $languages[$contLang] ) ) {
00205                                         $this->setVar( 'wgLanguageCode', $contLang );
00206                                 }
00207                                 return 'continue';
00208                         }
00209                 } elseif ( $this->parent->showSessionWarning ) {
00210                         # The user was knocked back from another page to the start
00211                         # This probably indicates a session expiry
00212                         $this->parent->showError( 'config-session-expired',
00213                                 $wgLang->formatTimePeriod( $lifetime ) );
00214                 }
00215 
00216                 $this->parent->setSession( 'test', true );
00217 
00218                 if ( !isset( $languages[$userLang] ) ) {
00219                         $userLang = $this->getVar( '_UserLang', 'en' );
00220                 }
00221                 if ( !isset( $languages[$contLang] ) ) {
00222                         $contLang = $this->getVar( 'wgLanguageCode', 'en' );
00223                 }
00224                 $this->startForm();
00225                 $s = Html::hidden( 'LanguageRequestTime', time() ) .
00226                         $this->getLanguageSelector( 'uselang', 'config-your-language', $userLang,
00227                                 $this->parent->getHelpBox( 'config-your-language-help' ) ) .
00228                         $this->getLanguageSelector( 'ContLang', 'config-wiki-language', $contLang,
00229                                 $this->parent->getHelpBox( 'config-wiki-language-help' ) );
00230                 $this->addHTML( $s );
00231                 $this->endForm( 'continue', false );
00232         }
00233 
00243         public function getLanguageSelector( $name, $label, $selectedCode, $helpHtml = '' ) {
00244                 global $wgDummyLanguageCodes;
00245 
00246                 $s = $helpHtml;
00247 
00248                 $s .= Html::openElement( 'select', array( 'id' => $name, 'name' => $name,
00249                                 'tabindex' => $this->parent->nextTabIndex() ) ) . "\n";
00250 
00251                 $languages = Language::fetchLanguageNames();
00252                 ksort( $languages );
00253                 foreach ( $languages as $code => $lang ) {
00254                         if ( isset( $wgDummyLanguageCodes[$code] ) ) continue;
00255                         $s .= "\n" . Xml::option( "$code - $lang", $code, $code == $selectedCode );
00256                 }
00257                 $s .= "\n</select>\n";
00258                 return $this->parent->label( $label, $name, $s );
00259         }
00260 
00261 }
00262 
00263 class WebInstaller_ExistingWiki extends WebInstallerPage {
00264         public function execute() {
00265                 // If there is no LocalSettings.php, continue to the installer welcome page
00266                 $vars = Installer::getExistingLocalSettings();
00267                 if ( !$vars ) {
00268                         return 'skip';
00269                 }
00270 
00271                 // Check if the upgrade key supplied to the user has appeared in LocalSettings.php
00272                 if ( $vars['wgUpgradeKey'] !== false
00273                         && $this->getVar( '_UpgradeKeySupplied' )
00274                         && $this->getVar( 'wgUpgradeKey' ) === $vars['wgUpgradeKey'] )
00275                 {
00276                         // It's there, so the user is authorized
00277                         $status = $this->handleExistingUpgrade( $vars );
00278                         if ( $status->isOK() ) {
00279                                 return 'skip';
00280                         } else {
00281                                 $this->startForm();
00282                                 $this->parent->showStatusBox( $status );
00283                                 $this->endForm( 'continue' );
00284                                 return 'output';
00285                         }
00286                 }
00287 
00288                 // If there is no $wgUpgradeKey, tell the user to add one to LocalSettings.php
00289                 if ( $vars['wgUpgradeKey'] === false ) {
00290                         if ( $this->getVar( 'wgUpgradeKey', false ) === false ) {
00291                                 $secretKey = $this->getVar( 'wgSecretKey' ); // preserve $wgSecretKey
00292                                 $this->parent->generateKeys();
00293                                 $this->setVar( 'wgSecretKey', $secretKey );
00294                                 $this->setVar( '_UpgradeKeySupplied', true );
00295                         }
00296                         $this->startForm();
00297                         $this->addHTML( $this->parent->getInfoBox(
00298                                 wfMessage( 'config-upgrade-key-missing', "<pre dir=\"ltr\">\$wgUpgradeKey = '" .
00299                                         $this->getVar( 'wgUpgradeKey' ) . "';</pre>" )->plain()
00300                         ) );
00301                         $this->endForm( 'continue' );
00302                         return 'output';
00303                 }
00304 
00305                 // If there is an upgrade key, but it wasn't supplied, prompt the user to enter it
00306 
00307                 $r = $this->parent->request;
00308                 if ( $r->wasPosted() ) {
00309                         $key = $r->getText( 'config_wgUpgradeKey' );
00310                         if( !$key || $key !== $vars['wgUpgradeKey'] ) {
00311                                 $this->parent->showError( 'config-localsettings-badkey' );
00312                                 $this->showKeyForm();
00313                                 return 'output';
00314                         }
00315                         // Key was OK
00316                         $status = $this->handleExistingUpgrade( $vars );
00317                         if ( $status->isOK() ) {
00318                                 return 'continue';
00319                         } else {
00320                                 $this->parent->showStatusBox( $status );
00321                                 $this->showKeyForm();
00322                                 return 'output';
00323                         }
00324                 } else {
00325                         $this->showKeyForm();
00326                         return 'output';
00327                 }
00328         }
00329 
00333         protected function showKeyForm() {
00334                 $this->startForm();
00335                 $this->addHTML(
00336                         $this->parent->getInfoBox( wfMessage( 'config-localsettings-upgrade' )->plain() ).
00337                         '<br />' .
00338                         $this->parent->getTextBox( array(
00339                                 'var' => 'wgUpgradeKey',
00340                                 'label' => 'config-localsettings-key',
00341                                 'attribs' => array( 'autocomplete' => 'off' ),
00342                         ) )
00343                 );
00344                 $this->endForm( 'continue' );
00345         }
00346 
00347         protected function importVariables( $names, $vars ) {
00348                 $status = Status::newGood();
00349                 foreach ( $names as $name ) {
00350                         if ( !isset( $vars[$name] ) ) {
00351                                 $status->fatal( 'config-localsettings-incomplete', $name );
00352                         }
00353                         $this->setVar( $name, $vars[$name] );
00354                 }
00355                 return $status;
00356         }
00357 
00363         protected function handleExistingUpgrade( $vars ) {
00364                 // Check $wgDBtype
00365                 if ( !isset( $vars['wgDBtype'] ) ||
00366                          !in_array( $vars['wgDBtype'], Installer::getDBTypes() ) ) {
00367                         return Status::newFatal( 'config-localsettings-connection-error', '' );
00368                 }
00369 
00370                 // Set the relevant variables from LocalSettings.php
00371                 $requiredVars = array( 'wgDBtype' );
00372                 $status = $this->importVariables( $requiredVars, $vars );
00373                 $installer = $this->parent->getDBInstaller();
00374                 $status->merge( $this->importVariables( $installer->getGlobalNames(), $vars ) );
00375                 if ( !$status->isOK() ) {
00376                         return $status;
00377                 }
00378 
00379                 if ( isset( $vars['wgDBadminuser'] ) ) {
00380                         $this->setVar( '_InstallUser', $vars['wgDBadminuser'] );
00381                 } else {
00382                         $this->setVar( '_InstallUser', $vars['wgDBuser'] );
00383                 }
00384                 if ( isset( $vars['wgDBadminpassword'] ) ) {
00385                         $this->setVar( '_InstallPassword', $vars['wgDBadminpassword'] );
00386                 } else {
00387                         $this->setVar( '_InstallPassword', $vars['wgDBpassword'] );
00388                 }
00389 
00390                 // Test the database connection
00391                 $status = $installer->getConnection();
00392                 if ( !$status->isOK() ) {
00393                         // Adjust the error message to explain things correctly
00394                         $status->replaceMessage( 'config-connection-error',
00395                                 'config-localsettings-connection-error' );
00396                         return $status;
00397                 }
00398 
00399                 // All good
00400                 $this->setVar( '_ExistingDBSettings', true );
00401                 return $status;
00402         }
00403 }
00404 
00405 class WebInstaller_Welcome extends WebInstallerPage {
00406 
00407         public function execute() {
00408                 if ( $this->parent->request->wasPosted() ) {
00409                         if ( $this->getVar( '_Environment' ) ) {
00410                                 return 'continue';
00411                         }
00412                 }
00413                 $this->parent->output->addWikiText( wfMessage( 'config-welcome' )->plain() );
00414                 $status = $this->parent->doEnvironmentChecks();
00415                 if ( $status->isGood() ) {
00416                         $this->parent->output->addHTML( '<span class="success-message">' .
00417                                 wfMessage( 'config-env-good' )->escaped() . '</span>' );
00418                         $this->parent->output->addWikiText( wfMessage( 'config-copyright',
00419                                 SpecialVersion::getCopyrightAndAuthorList() )->plain() );
00420                         $this->startForm();
00421                         $this->endForm();
00422                 } else {
00423                         $this->parent->showStatusMessage( $status );
00424                 }
00425                 return '';
00426         }
00427 
00428 }
00429 
00430 class WebInstaller_DBConnect extends WebInstallerPage {
00431 
00432         public function execute() {
00433                 if ( $this->getVar( '_ExistingDBSettings' ) ) {
00434                         return 'skip';
00435                 }
00436 
00437                 $r = $this->parent->request;
00438                 if ( $r->wasPosted() ) {
00439                         $status = $this->submit();
00440 
00441                         if ( $status->isGood() ) {
00442                                 $this->setVar( '_UpgradeDone', false );
00443                                 return 'continue';
00444                         } else {
00445                                 $this->parent->showStatusBox( $status );
00446                         }
00447                 }
00448 
00449                 $this->startForm();
00450 
00451                 $types = "<ul class=\"config-settings-block\">\n";
00452                 $settings = '';
00453                 $defaultType = $this->getVar( 'wgDBtype' );
00454 
00455                 $dbSupport = '';
00456                 foreach( $this->parent->getDBTypes() as $type ) {
00457                         $link = DatabaseBase::factory( $type )->getSoftwareLink();
00458                         $dbSupport .= wfMessage( "config-support-$type", $link )->plain() . "\n";
00459                 }
00460                 $this->addHTML( $this->parent->getInfoBox(
00461                         wfMessage( 'config-support-info', trim( $dbSupport ) )->text() ) );
00462 
00463                 // It's possible that the library for the default DB type is not compiled in.
00464                 // In that case, instead select the first supported DB type in the list.
00465                 $compiledDBs = $this->parent->getCompiledDBs();
00466                 if ( !in_array( $defaultType, $compiledDBs ) ) {
00467                         $defaultType = $compiledDBs[0];
00468                 }
00469 
00470                 foreach ( $compiledDBs as $type ) {
00471                         $installer = $this->parent->getDBInstaller( $type );
00472                         $types .=
00473                                 '<li>' .
00474                                 Xml::radioLabel(
00475                                         $installer->getReadableName(),
00476                                         'DBType',
00477                                         $type,
00478                                         "DBType_$type",
00479                                         $type == $defaultType,
00480                                         array( 'class' => 'dbRadio', 'rel' => "DB_wrapper_$type" )
00481                                 ) .
00482                                 "</li>\n";
00483 
00484                         $settings .=
00485                                 Html::openElement( 'div', array( 'id' => 'DB_wrapper_' . $type,
00486                                                 'class' => 'dbWrapper' ) ) .
00487                                 Html::element( 'h3', array(), wfMessage( 'config-header-' . $type )->text() ) .
00488                                 $installer->getConnectForm() .
00489                                 "</div>\n";
00490                 }
00491                 $types .= "</ul><br style=\"clear: left\"/>\n";
00492 
00493                 $this->addHTML(
00494                         $this->parent->label( 'config-db-type', false, $types ) .
00495                         $settings
00496                 );
00497 
00498                 $this->endForm();
00499         }
00500 
00501         public function submit() {
00502                 $r = $this->parent->request;
00503                 $type = $r->getVal( 'DBType' );
00504                 if ( !$type ) {
00505                         return Status::newFatal( 'config-invalid-db-type' );
00506                 }
00507                 $this->setVar( 'wgDBtype', $type );
00508                 $installer = $this->parent->getDBInstaller( $type );
00509                 if ( !$installer ) {
00510                         return Status::newFatal( 'config-invalid-db-type' );
00511                 }
00512                 return $installer->submitConnectForm();
00513         }
00514 
00515 }
00516 
00517 class WebInstaller_Upgrade extends WebInstallerPage {
00518         public function isSlow() {
00519                 return true;
00520         }
00521 
00522         public function execute() {
00523                 if ( $this->getVar( '_UpgradeDone' ) ) {
00524                         // Allow regeneration of LocalSettings.php, unless we are working
00525                         // from a pre-existing LocalSettings.php file and we want to avoid
00526                         // leaking its contents
00527                         if ( $this->parent->request->wasPosted() && !$this->getVar( '_ExistingDBSettings' ) ) {
00528                                 // Done message acknowledged
00529                                 return 'continue';
00530                         } else {
00531                                 // Back button click
00532                                 // Show the done message again
00533                                 // Make them click back again if they want to do the upgrade again
00534                                 $this->showDoneMessage();
00535                                 return 'output';
00536                         }
00537                 }
00538 
00539                 // wgDBtype is generally valid here because otherwise the previous page
00540                 // (connect) wouldn't have declared its happiness
00541                 $type = $this->getVar( 'wgDBtype' );
00542                 $installer = $this->parent->getDBInstaller( $type );
00543 
00544                 if ( !$installer->needsUpgrade() ) {
00545                         return 'skip';
00546                 }
00547 
00548                 if ( $this->parent->request->wasPosted() ) {
00549                         $installer->preUpgrade();
00550 
00551                         $this->startLiveBox();
00552                         $result = $installer->doUpgrade();
00553                         $this->endLiveBox();
00554 
00555                         if ( $result ) {
00556                                 // If they're going to possibly regenerate LocalSettings, we
00557                                 // need to create the upgrade/secret keys. Bug 26481
00558                                 if( !$this->getVar( '_ExistingDBSettings' ) ) {
00559                                         $this->parent->generateKeys();
00560                                 }
00561                                 $this->setVar( '_UpgradeDone', true );
00562                                 $this->showDoneMessage();
00563                                 return 'output';
00564                         }
00565                 }
00566 
00567                 $this->startForm();
00568                 $this->addHTML( $this->parent->getInfoBox(
00569                         wfMessage( 'config-can-upgrade', $GLOBALS['wgVersion'] )->plain() ) );
00570                 $this->endForm();
00571         }
00572 
00573         public function showDoneMessage() {
00574                 $this->startForm();
00575                 $regenerate = !$this->getVar( '_ExistingDBSettings' );
00576                 if ( $regenerate ) {
00577                         $msg = 'config-upgrade-done';
00578                 } else {
00579                         $msg = 'config-upgrade-done-no-regenerate';
00580                 }
00581                 $this->parent->disableLinkPopups();
00582                 $this->addHTML(
00583                         $this->parent->getInfoBox(
00584                                 wfMessage( $msg,
00585                                         $this->getVar( 'wgServer' ) .
00586                                                 $this->getVar( 'wgScriptPath' ) . '/index' .
00587                                                 $this->getVar( 'wgScriptExtension' )
00588                                 )->plain(), 'tick-32.png'
00589                         )
00590                 );
00591                 $this->parent->restoreLinkPopups();
00592                 $this->endForm( $regenerate ? 'regenerate' : false, false );
00593         }
00594 
00595 }
00596 
00597 class WebInstaller_DBSettings extends WebInstallerPage {
00598 
00599         public function execute() {
00600                 $installer = $this->parent->getDBInstaller( $this->getVar( 'wgDBtype' ) );
00601 
00602                 $r = $this->parent->request;
00603                 if ( $r->wasPosted() ) {
00604                         $status = $installer->submitSettingsForm();
00605                         if ( $status === false ) {
00606                                 return 'skip';
00607                         } elseif ( $status->isGood() ) {
00608                                 return 'continue';
00609                         } else {
00610                                 $this->parent->showStatusBox( $status );
00611                         }
00612                 }
00613 
00614                 $form = $installer->getSettingsForm();
00615                 if ( $form === false ) {
00616                         return 'skip';
00617                 }
00618 
00619                 $this->startForm();
00620                 $this->addHTML( $form );
00621                 $this->endForm();
00622         }
00623 
00624 }
00625 
00626 class WebInstaller_Name extends WebInstallerPage {
00627 
00628         public function execute() {
00629                 $r = $this->parent->request;
00630                 if ( $r->wasPosted() ) {
00631                         if ( $this->submit() ) {
00632                                 return 'continue';
00633                         }
00634                 }
00635 
00636                 $this->startForm();
00637 
00638                 // Encourage people to not name their site 'MediaWiki' by blanking the
00639                 // field. I think that was the intent with the original $GLOBALS['wgSitename']
00640                 // but these two always were the same so had the effect of making the
00641                 // installer forget $wgSitename when navigating back to this page.
00642                 if ( $this->getVar( 'wgSitename' ) == 'MediaWiki' ) {
00643                         $this->setVar( 'wgSitename', '' );
00644                 }
00645 
00646                 // Set wgMetaNamespace to something valid before we show the form.
00647                 // $wgMetaNamespace defaults to $wgSiteName which is 'MediaWiki'
00648                 $metaNS = $this->getVar( 'wgMetaNamespace' );
00649                 $this->setVar(
00650                         'wgMetaNamespace',
00651                         wfMessage( 'config-ns-other-default' )->inContentLanguage()->text()
00652                 );
00653 
00654                 $this->addHTML(
00655                         $this->parent->getTextBox( array(
00656                                 'var' => 'wgSitename',
00657                                 'label' => 'config-site-name',
00658                                 'help' => $this->parent->getHelpBox( 'config-site-name-help' )
00659                         ) ) .
00660                         $this->parent->getRadioSet( array(
00661                                 'var' => '_NamespaceType',
00662                                 'label' => 'config-project-namespace',
00663                                 'itemLabelPrefix' => 'config-ns-',
00664                                 'values' => array( 'site-name', 'generic', 'other' ),
00665                                 'commonAttribs' => array( 'class' => 'enableForOther',
00666                                         'rel' => 'config_wgMetaNamespace' ),
00667                                 'help' => $this->parent->getHelpBox( 'config-project-namespace-help' )
00668                         ) ) .
00669                         $this->parent->getTextBox( array(
00670                                 'var' => 'wgMetaNamespace',
00671                                 'label' => '', //TODO: Needs a label?
00672                                 'attribs' => array( 'readonly' => 'readonly', 'class' => 'enabledByOther' ),
00673 
00674                         ) ) .
00675                         $this->getFieldSetStart( 'config-admin-box' ) .
00676                         $this->parent->getTextBox( array(
00677                                 'var' => '_AdminName',
00678                                 'label' => 'config-admin-name',
00679                                 'help' => $this->parent->getHelpBox( 'config-admin-help' )
00680                         ) ) .
00681                         $this->parent->getPasswordBox( array(
00682                                 'var' => '_AdminPassword',
00683                                 'label' => 'config-admin-password',
00684                         ) ) .
00685                         $this->parent->getPasswordBox( array(
00686                                 'var' => '_AdminPassword2',
00687                                 'label' => 'config-admin-password-confirm'
00688                         ) ) .
00689                         $this->parent->getTextBox( array(
00690                                 'var' => '_AdminEmail',
00691                                 'label' => 'config-admin-email',
00692                                 'help' => $this->parent->getHelpBox( 'config-admin-email-help' )
00693                         ) ) .
00694                         $this->parent->getCheckBox( array(
00695                                 'var' => '_Subscribe',
00696                                 'label' => 'config-subscribe',
00697                                 'help' => $this->parent->getHelpBox( 'config-subscribe-help' )
00698                         ) ) .
00699                         $this->getFieldSetEnd() .
00700                         $this->parent->getInfoBox( wfMessage( 'config-almost-done' )->text() ) .
00701                         $this->parent->getRadioSet( array(
00702                                 'var' => '_SkipOptional',
00703                                 'itemLabelPrefix' => 'config-optional-',
00704                                 'values' => array( 'continue', 'skip' )
00705                         ) )
00706                 );
00707 
00708                 // Restore the default value
00709                 $this->setVar( 'wgMetaNamespace', $metaNS );
00710 
00711                 $this->endForm();
00712                 return 'output';
00713         }
00714 
00715         public function submit() {
00716                 $retVal = true;
00717                 $this->parent->setVarsFromRequest( array( 'wgSitename', '_NamespaceType',
00718                         '_AdminName', '_AdminPassword', '_AdminPassword2', '_AdminEmail',
00719                         '_Subscribe', '_SkipOptional', 'wgMetaNamespace' ) );
00720 
00721                 // Validate site name
00722                 if ( strval( $this->getVar( 'wgSitename' ) ) === '' ) {
00723                         $this->parent->showError( 'config-site-name-blank' );
00724                         $retVal = false;
00725                 }
00726 
00727                 // Fetch namespace
00728                 $nsType = $this->getVar( '_NamespaceType' );
00729                 if ( $nsType == 'site-name' ) {
00730                         $name = $this->getVar( 'wgSitename' );
00731                         // Sanitize for namespace
00732                         // This algorithm should match the JS one in WebInstallerOutput.php
00733                         $name = preg_replace( '/[\[\]\{\}|#<>%+? ]/', '_', $name );
00734                         $name = str_replace( '&', '&amp;', $name );
00735                         $name = preg_replace( '/__+/', '_', $name );
00736                         $name = ucfirst( trim( $name, '_' ) );
00737                 } elseif ( $nsType == 'generic' ) {
00738                         $name = wfMessage( 'config-ns-generic' )->text();
00739                 } else { // other
00740                         $name = $this->getVar( 'wgMetaNamespace' );
00741                 }
00742 
00743                 // Validate namespace
00744                 if ( strpos( $name, ':' ) !== false ) {
00745                         $good = false;
00746                 } else {
00747                         // Title-style validation
00748                         $title = Title::newFromText( $name );
00749                         if ( !$title ) {
00750                                 $good = $nsType == 'site-name';
00751                         } else {
00752                                 $name = $title->getDBkey();
00753                                 $good = true;
00754                         }
00755                 }
00756                 if ( !$good ) {
00757                         $this->parent->showError( 'config-ns-invalid', $name );
00758                         $retVal = false;
00759                 }
00760 
00761                 // Make sure it won't conflict with any existing namespaces
00762                 global $wgContLang;
00763                 $nsIndex = $wgContLang->getNsIndex( $name );
00764                 if( $nsIndex !== false && $nsIndex !== NS_PROJECT ) {
00765                         $this->parent->showError( 'config-ns-conflict', $name );
00766                         $retVal = false;
00767                 }
00768 
00769                 $this->setVar( 'wgMetaNamespace', $name );
00770 
00771                 // Validate username for creation
00772                 $name = $this->getVar( '_AdminName' );
00773                 if ( strval( $name ) === '' ) {
00774                         $this->parent->showError( 'config-admin-name-blank' );
00775                         $cname = $name;
00776                         $retVal = false;
00777                 } else {
00778                         $cname = User::getCanonicalName( $name, 'creatable' );
00779                         if ( $cname === false ) {
00780                                 $this->parent->showError( 'config-admin-name-invalid', $name );
00781                                 $retVal = false;
00782                         } else {
00783                                 $this->setVar( '_AdminName', $cname );
00784                         }
00785                 }
00786 
00787                 // Validate password
00788                 $msg = false;
00789                 $pwd = $this->getVar( '_AdminPassword' );
00790                 $user = User::newFromName( $cname );
00791                 $valid = $user && $user->getPasswordValidity( $pwd );
00792                 if ( strval( $pwd ) === '' ) {
00793                         # $user->getPasswordValidity just checks for $wgMinimalPasswordLength.
00794                         # This message is more specific and helpful.
00795                         $msg = 'config-admin-password-blank';
00796                 } elseif ( $pwd !== $this->getVar( '_AdminPassword2' ) ) {
00797                         $msg = 'config-admin-password-mismatch';
00798                 } elseif ( $valid !== true ) {
00799                         # As of writing this will only catch the username being e.g. 'FOO' and
00800                         # the password 'foo'
00801                         $msg = $valid;
00802                 }
00803                 if ( $msg !== false ) {
00804                         call_user_func_array( array( $this->parent, 'showError' ), (array)$msg );
00805                         $this->setVar( '_AdminPassword', '' );
00806                         $this->setVar( '_AdminPassword2', '' );
00807                         $retVal = false;
00808                 }
00809 
00810                 // Validate e-mail if provided
00811                 $email = $this->getVar( '_AdminEmail' );
00812                 if( $email && !Sanitizer::validateEmail( $email ) ) {
00813                         $this->parent->showError( 'config-admin-error-bademail' );
00814                         $retVal = false;
00815                 }
00816                 // If they asked to subscribe to mediawiki-announce but didn't give
00817                 // an e-mail, show an error. Bug 29332
00818                 if( !$email && $this->getVar( '_Subscribe' ) ) {
00819                         $this->parent->showError( 'config-subscribe-noemail' );
00820                         $retVal = false;
00821                 }
00822 
00823                 return $retVal;
00824         }
00825 
00826 }
00827 
00828 class WebInstaller_Options extends WebInstallerPage {
00829 
00830         public function execute() {
00831                 if ( $this->getVar( '_SkipOptional' ) == 'skip' ) {
00832                         return 'skip';
00833                 }
00834                 if ( $this->parent->request->wasPosted() ) {
00835                         if ( $this->submit() ) {
00836                                 return 'continue';
00837                         }
00838                 }
00839 
00840                 $emailwrapperStyle = $this->getVar( 'wgEnableEmail' ) ? '' : 'display: none';
00841                 $this->startForm();
00842                 $this->addHTML(
00843                         # User Rights
00844                         $this->parent->getRadioSet( array(
00845                                 'var' => '_RightsProfile',
00846                                 'label' => 'config-profile',
00847                                 'itemLabelPrefix' => 'config-profile-',
00848                                 'values' => array_keys( $this->parent->rightsProfiles ),
00849                         ) ) .
00850                         $this->parent->getInfoBox( wfMessage( 'config-profile-help' )->plain() ) .
00851 
00852                         # Licensing
00853                         $this->parent->getRadioSet( array(
00854                                 'var' => '_LicenseCode',
00855                                 'label' => 'config-license',
00856                                 'itemLabelPrefix' => 'config-license-',
00857                                 'values' => array_keys( $this->parent->licenses ),
00858                                 'commonAttribs' => array( 'class' => 'licenseRadio' ),
00859                         ) ) .
00860                         $this->getCCChooser() .
00861                         $this->parent->getHelpBox( 'config-license-help' ) .
00862 
00863                         # E-mail
00864                         $this->getFieldSetStart( 'config-email-settings' ) .
00865                         $this->parent->getCheckBox( array(
00866                                 'var' => 'wgEnableEmail',
00867                                 'label' => 'config-enable-email',
00868                                 'attribs' => array( 'class' => 'showHideRadio', 'rel' => 'emailwrapper' ),
00869                         ) ) .
00870                         $this->parent->getHelpBox( 'config-enable-email-help' ) .
00871                         "<div id=\"emailwrapper\" style=\"$emailwrapperStyle\">" .
00872                         $this->parent->getTextBox( array(
00873                                 'var' => 'wgPasswordSender',
00874                                 'label' => 'config-email-sender'
00875                         ) ) .
00876                         $this->parent->getHelpBox( 'config-email-sender-help' ) .
00877                         $this->parent->getCheckBox( array(
00878                                 'var' => 'wgEnableUserEmail',
00879                                 'label' => 'config-email-user',
00880                         ) ) .
00881                         $this->parent->getHelpBox( 'config-email-user-help' ) .
00882                         $this->parent->getCheckBox( array(
00883                                 'var' => 'wgEnotifUserTalk',
00884                                 'label' => 'config-email-usertalk',
00885                         ) ) .
00886                         $this->parent->getHelpBox( 'config-email-usertalk-help' ) .
00887                         $this->parent->getCheckBox( array(
00888                                 'var' => 'wgEnotifWatchlist',
00889                                 'label' => 'config-email-watchlist',
00890                         ) ) .
00891                         $this->parent->getHelpBox( 'config-email-watchlist-help' ) .
00892                         $this->parent->getCheckBox( array(
00893                                 'var' => 'wgEmailAuthentication',
00894                                 'label' => 'config-email-auth',
00895                         ) ) .
00896                         $this->parent->getHelpBox( 'config-email-auth-help' ) .
00897                         "</div>" .
00898                         $this->getFieldSetEnd()
00899                 );
00900 
00901                 $extensions = $this->parent->findExtensions();
00902 
00903                 if( $extensions ) {
00904                         $extHtml = $this->getFieldSetStart( 'config-extensions' );
00905 
00906                         foreach( $extensions as $ext ) {
00907                                 $extHtml .= $this->parent->getCheckBox( array(
00908                                         'var' => "ext-$ext",
00909                                         'rawtext' => $ext,
00910                                 ) );
00911                         }
00912 
00913                         $extHtml .= $this->parent->getHelpBox( 'config-extensions-help' ) .
00914                         $this->getFieldSetEnd();
00915                         $this->addHTML( $extHtml );
00916                 }
00917 
00918                 // Having / in paths in Windows looks funny :)
00919                 $this->setVar( 'wgDeletedDirectory',
00920                         str_replace(
00921                                 '/', DIRECTORY_SEPARATOR,
00922                                 $this->getVar( 'wgDeletedDirectory' )
00923                         )
00924                 );
00925                 // If we're using the default, let the user set it relative to $wgScriptPath
00926                 $curLogo = $this->getVar( 'wgLogo' );
00927                 $logoString = ( $curLogo == "/wiki/skins/common/images/wiki.png" ) ?
00928                         '$wgStylePath/common/images/wiki.png' : $curLogo;
00929 
00930                 $uploadwrapperStyle = $this->getVar( 'wgEnableUploads' ) ? '' : 'display: none';
00931                 $this->addHTML(
00932                         # Uploading
00933                         $this->getFieldSetStart( 'config-upload-settings' ) .
00934                         $this->parent->getCheckBox( array(
00935                                 'var' => 'wgEnableUploads',
00936                                 'label' => 'config-upload-enable',
00937                                 'attribs' => array( 'class' => 'showHideRadio', 'rel' => 'uploadwrapper' ),
00938                                 'help' => $this->parent->getHelpBox( 'config-upload-help' )
00939                         ) ) .
00940                         '<div id="uploadwrapper" style="' . $uploadwrapperStyle . '">' .
00941                         $this->parent->getTextBox( array(
00942                                 'var' => 'wgDeletedDirectory',
00943                                 'label' => 'config-upload-deleted',
00944                                 'attribs' => array( 'dir' => 'ltr' ),
00945                                 'help' => $this->parent->getHelpBox( 'config-upload-deleted-help' )
00946                         ) ) .
00947                         '</div>' .
00948                         $this->parent->getTextBox( array(
00949                                 'var' => 'wgLogo',
00950                                 'value' => $logoString,
00951                                 'label' => 'config-logo',
00952                                 'attribs' => array( 'dir' => 'ltr' ),
00953                                 'help' => $this->parent->getHelpBox( 'config-logo-help' )
00954                         ) )
00955                 );
00956                 $this->addHTML(
00957                         $this->parent->getCheckBox( array(
00958                                 'var' => 'wgUseInstantCommons',
00959                                 'label' => 'config-instantcommons',
00960                                 'help' => $this->parent->getHelpBox( 'config-instantcommons-help' )
00961                         ) ) .
00962                         $this->getFieldSetEnd()
00963                 );
00964 
00965                 $caches = array( 'none' );
00966                 if( count( $this->getVar( '_Caches' ) ) ) {
00967                         $caches[] = 'accel';
00968                 }
00969                 $caches[] = 'memcached';
00970 
00971                 // We'll hide/show this on demand when the value changes, see config.js.
00972                 $cacheval = $this->getVar( 'wgMainCacheType' );
00973                 if ( !$cacheval ) {
00974                         // We need to set a default here; but don't hardcode it
00975                         // or we lose it every time we reload the page for validation
00976                         // or going back!
00977                         $cacheval = 'none';
00978                 }
00979                 $hidden = ($cacheval == 'memcached') ? '' : 'display: none';
00980                 $this->addHTML(
00981                         # Advanced settings
00982                         $this->getFieldSetStart( 'config-advanced-settings' ) .
00983                         # Object cache settings
00984                         $this->parent->getRadioSet( array(
00985                                 'var' => 'wgMainCacheType',
00986                                 'label' => 'config-cache-options',
00987                                 'itemLabelPrefix' => 'config-cache-',
00988                                 'values' => $caches,
00989                                 'value' => $cacheval,
00990                         ) ) .
00991                         $this->parent->getHelpBox( 'config-cache-help' ) .
00992                         "<div id=\"config-memcachewrapper\" style=\"$hidden\">" .
00993                         $this->parent->getTextArea( array(
00994                                 'var' => '_MemCachedServers',
00995                                 'label' => 'config-memcached-servers',
00996                                 'help' => $this->parent->getHelpBox( 'config-memcached-help' )
00997                         ) ) .
00998                         '</div>' .
00999                         $this->getFieldSetEnd()
01000                 );
01001                 $this->endForm();
01002         }
01003 
01007         public function getCCPartnerUrl() {
01008                 $server = $this->getVar( 'wgServer' );
01009                 $exitUrl = $server . $this->parent->getUrl( array(
01010                         'page' => 'Options',
01011                         'SubmitCC' => 'indeed',
01012                         'config__LicenseCode' => 'cc',
01013                         'config_wgRightsUrl' => '[license_url]',
01014                         'config_wgRightsText' => '[license_name]',
01015                         'config_wgRightsIcon' => '[license_button]',
01016                 ) );
01017                 $styleUrl = $server . dirname( dirname( $this->parent->getUrl() ) ) .
01018                         '/skins/common/config-cc.css';
01019                 $iframeUrl = 'http://creativecommons.org/license/?' .
01020                         wfArrayToCgi( array(
01021                                 'partner' => 'MediaWiki',
01022                                 'exit_url' => $exitUrl,
01023                                 'lang' => $this->getVar( '_UserLang' ),
01024                                 'stylesheet' => $styleUrl,
01025                         ) );
01026                 return $iframeUrl;
01027         }
01028 
01029         public function getCCChooser() {
01030                 $iframeAttribs = array(
01031                         'class' => 'config-cc-iframe',
01032                         'name' => 'config-cc-iframe',
01033                         'id' => 'config-cc-iframe',
01034                         'frameborder' => 0,
01035                         'width' => '100%',
01036                         'height' => '100%',
01037                 );
01038                 if ( $this->getVar( '_CCDone' ) ) {
01039                         $iframeAttribs['src'] = $this->parent->getUrl( array( 'ShowCC' => 'yes' ) );
01040                 } else {
01041                         $iframeAttribs['src'] = $this->getCCPartnerUrl();
01042                 }
01043                 $wrapperStyle = ($this->getVar( '_LicenseCode' ) == 'cc-choose') ? '' : 'display: none';
01044 
01045                 return
01046                         "<div class=\"config-cc-wrapper\" id=\"config-cc-wrapper\" style=\"$wrapperStyle\">\n" .
01047                         Html::element( 'iframe', $iframeAttribs, '', false /* not short */ ) .
01048                         "</div>\n";
01049         }
01050 
01051         public function getCCDoneBox() {
01052                 $js = "parent.document.getElementById('config-cc-wrapper').style.height = '$1';";
01053                 // If you change this height, also change it in config.css
01054                 $expandJs = str_replace( '$1', '54em', $js );
01055                 $reduceJs = str_replace( '$1', '70px', $js );
01056                 return
01057                         '<p>'.
01058                         Html::element( 'img', array( 'src' => $this->getVar( 'wgRightsIcon' ) ) ) .
01059                         '&#160;&#160;' .
01060                         htmlspecialchars( $this->getVar( 'wgRightsText' ) ) .
01061                         "</p>\n" .
01062                         "<p style=\"text-align: center\">" .
01063                         Html::element( 'a',
01064                                 array(
01065                                         'href' => $this->getCCPartnerUrl(),
01066                                         'onclick' => $expandJs,
01067                                 ),
01068                                 wfMessage( 'config-cc-again' )->text()
01069                         ) .
01070                         "</p>\n" .
01071                         "<script type=\"text/javascript\">\n" .
01072                         # Reduce the wrapper div height
01073                         htmlspecialchars( $reduceJs ) .
01074                         "\n" .
01075                         "</script>\n";
01076         }
01077 
01078         public function submitCC() {
01079                 $newValues = $this->parent->setVarsFromRequest(
01080                         array( 'wgRightsUrl', 'wgRightsText', 'wgRightsIcon' ) );
01081                 if ( count( $newValues ) != 3 ) {
01082                         $this->parent->showError( 'config-cc-error' );
01083                         return;
01084                 }
01085                 $this->setVar( '_CCDone', true );
01086                 $this->addHTML( $this->getCCDoneBox() );
01087         }
01088 
01089         public function submit() {
01090                 $this->parent->setVarsFromRequest( array( '_RightsProfile', '_LicenseCode',
01091                         'wgEnableEmail', 'wgPasswordSender', 'wgEnableUploads', 'wgLogo',
01092                         'wgEnableUserEmail', 'wgEnotifUserTalk', 'wgEnotifWatchlist',
01093                         'wgEmailAuthentication', 'wgMainCacheType', '_MemCachedServers',
01094                         'wgUseInstantCommons' ) );
01095 
01096                 if ( !in_array( $this->getVar( '_RightsProfile' ),
01097                         array_keys( $this->parent->rightsProfiles ) ) )
01098                 {
01099                         reset( $this->parent->rightsProfiles );
01100                         $this->setVar( '_RightsProfile', key( $this->parent->rightsProfiles ) );
01101                 }
01102 
01103                 $code = $this->getVar( '_LicenseCode' );
01104                 if ( $code == 'cc-choose' ) {
01105                         if ( !$this->getVar( '_CCDone' ) ) {
01106                                 $this->parent->showError( 'config-cc-not-chosen' );
01107                                 return false;
01108                         }
01109                 } elseif ( in_array( $code, array_keys( $this->parent->licenses ) ) ) {
01110                         $entry = $this->parent->licenses[$code];
01111                         if ( isset( $entry['text'] ) ) {
01112                                 $this->setVar( 'wgRightsText', $entry['text'] );
01113                         } else {
01114                                 $this->setVar( 'wgRightsText', wfMessage( 'config-license-' . $code )->text() );
01115                         }
01116                         $this->setVar( 'wgRightsUrl', $entry['url'] );
01117                         $this->setVar( 'wgRightsIcon', $entry['icon'] );
01118                 } else {
01119                         $this->setVar( 'wgRightsText', '' );
01120                         $this->setVar( 'wgRightsUrl', '' );
01121                         $this->setVar( 'wgRightsIcon', '' );
01122                 }
01123 
01124                 $extsAvailable = $this->parent->findExtensions();
01125                 $extsToInstall = array();
01126                 foreach( $extsAvailable as $ext ) {
01127                         if( $this->parent->request->getCheck( 'config_ext-' . $ext ) ) {
01128                                 $extsToInstall[] = $ext;
01129                         }
01130                 }
01131                 $this->parent->setVar( '_Extensions', $extsToInstall );
01132 
01133                 if( $this->getVar( 'wgMainCacheType' ) == 'memcached' ) {
01134                         $memcServers = explode( "\n", $this->getVar( '_MemCachedServers' ) );
01135                         if( !$memcServers ) {
01136                                 $this->parent->showError( 'config-memcache-needservers' );
01137                                 return false;
01138                         }
01139 
01140                         foreach( $memcServers as $server ) {
01141                                 $memcParts = explode( ":", $server, 2 );
01142                                 if ( !isset( $memcParts[0] )
01143                                                 || ( !IP::isValid( $memcParts[0] )
01144                                                         && ( gethostbyname( $memcParts[0] ) == $memcParts[0] ) ) ) {
01145                                         $this->parent->showError( 'config-memcache-badip', $memcParts[0] );
01146                                         return false;
01147                                 } elseif( !isset( $memcParts[1] )  ) {
01148                                         $this->parent->showError( 'config-memcache-noport', $memcParts[0] );
01149                                         return false;
01150                                 } elseif( $memcParts[1] < 1 || $memcParts[1] > 65535 ) {
01151                                         $this->parent->showError( 'config-memcache-badport', 1, 65535 );
01152                                         return false;
01153                                 }
01154                         }
01155                 }
01156                 return true;
01157         }
01158 
01159 }
01160 
01161 class WebInstaller_Install extends WebInstallerPage {
01162         public function isSlow() {
01163                 return true;
01164         }
01165 
01166         public function execute() {
01167                 if( $this->getVar( '_UpgradeDone' ) ) {
01168                         return 'skip';
01169                 } elseif( $this->getVar( '_InstallDone' ) ) {
01170                         return 'continue';
01171                 } elseif( $this->parent->request->wasPosted() ) {
01172                         $this->startForm();
01173                         $this->addHTML( "<ul>" );
01174                         $results = $this->parent->performInstallation(
01175                                 array( $this, 'startStage' ),
01176                                 array( $this, 'endStage' )
01177                         );
01178                         $this->addHTML( "</ul>" );
01179                         // PerformInstallation bails on a fatal, so make sure the last item
01180                         // completed before giving 'next.' Likewise, only provide back on failure
01181                         $lastStep = end( $results );
01182                         $continue = $lastStep->isOK() ? 'continue' : false;
01183                         $back = $lastStep->isOK() ? false : 'back';
01184                         $this->endForm( $continue, $back );
01185                 } else {
01186                         $this->startForm();
01187                         $this->addHTML( $this->parent->getInfoBox( wfMessage( 'config-install-begin' )->plain() ) );
01188                         $this->endForm();
01189                 }
01190                 return true;
01191         }
01192 
01193         public function startStage( $step ) {
01194                 $this->addHTML( "<li>" . wfMessage( "config-install-$step" )->escaped() . wfMessage( 'ellipsis' )->escaped() );
01195                 if ( $step == 'extension-tables' ) {
01196                         $this->startLiveBox();
01197                 }
01198         }
01199 
01204         public function endStage( $step, $status ) {
01205                 if ( $step == 'extension-tables' ) {
01206                         $this->endLiveBox();
01207                 }
01208                 $msg = $status->isOk() ? 'config-install-step-done' : 'config-install-step-failed';
01209                 $html = wfMessage( 'word-separator' )->escaped() . wfMessage( $msg )->escaped();
01210                 if ( !$status->isOk() ) {
01211                         $html = "<span class=\"error\">$html</span>";
01212                 }
01213                 $this->addHTML( $html . "</li>\n" );
01214                 if( !$status->isGood() ) {
01215                         $this->parent->showStatusBox( $status );
01216                 }
01217         }
01218 
01219 }
01220 
01221 class WebInstaller_Complete extends WebInstallerPage {
01222 
01223         public function execute() {
01224                 // Pop up a dialog box, to make it difficult for the user to forget
01225                 // to download the file
01226                 $lsUrl = $this->getVar( 'wgServer' ) . $this->parent->getURL( array( 'localsettings' => 1 ) );
01227                 if ( isset( $_SERVER['HTTP_USER_AGENT'] ) &&
01228                          strpos( $_SERVER['HTTP_USER_AGENT'], 'MSIE' ) !== false ) {
01229                         // JS appears the only method that works consistently with IE7+
01230                         $this->addHtml( "\n<script type=\"" . $GLOBALS['wgJsMimeType'] .
01231                                 '">jQuery( document ).ready( function() { document.location=' .
01232                                 Xml::encodeJsVar( $lsUrl) . "; } );</script>\n" );
01233                 } else {
01234                         $this->parent->request->response()->header( "Refresh: 0;url=$lsUrl" );
01235                 }
01236 
01237                 $this->startForm();
01238                 $this->parent->disableLinkPopups();
01239                 $this->addHTML(
01240                         $this->parent->getInfoBox(
01241                                 wfMessage( 'config-install-done',
01242                                         $lsUrl,
01243                                         $this->getVar( 'wgServer' ) .
01244                                                 $this->getVar( 'wgScriptPath' ) . '/index' .
01245                                                 $this->getVar( 'wgScriptExtension' ),
01246                                         '<downloadlink/>'
01247                                 )->plain(), 'tick-32.png'
01248                         )
01249                 );
01250                 $this->parent->restoreLinkPopups();
01251                 $this->endForm( false, false );
01252         }
01253 }
01254 
01255 class WebInstaller_Restart extends WebInstallerPage {
01256 
01257         public function execute() {
01258                 $r = $this->parent->request;
01259                 if ( $r->wasPosted() ) {
01260                         $really = $r->getVal( 'submit-restart' );
01261                         if ( $really ) {
01262                                 $this->parent->reset();
01263                         }
01264                         return 'continue';
01265                 }
01266 
01267                 $this->startForm();
01268                 $s = $this->parent->getWarningBox( wfMessage( 'config-help-restart' )->plain() );
01269                 $this->addHTML( $s );
01270                 $this->endForm( 'restart' );
01271         }
01272 
01273 }
01274 
01275 abstract class WebInstaller_Document extends WebInstallerPage {
01276 
01277         abstract protected function getFileName();
01278 
01279         public  function execute() {
01280                 $text = $this->getFileContents();
01281                 $text = InstallDocFormatter::format( $text );
01282                 $this->parent->output->addWikiText( $text );
01283                 $this->startForm();
01284                 $this->endForm( false );
01285         }
01286 
01287         public function getFileContents() {
01288                 $file = __DIR__ . '/../../' . $this->getFileName();
01289                 if( ! file_exists( $file ) ) {
01290                         return wfMessage( 'config-nofile', $file )->plain();
01291                 }
01292                 return file_get_contents( $file );
01293         }
01294 
01295 }
01296 
01297 class WebInstaller_Readme extends WebInstaller_Document {
01298         protected function getFileName() { return 'README'; }
01299 }
01300 
01301 class WebInstaller_ReleaseNotes extends WebInstaller_Document {
01302         protected function getFileName() {
01303                 global $wgVersion;
01304 
01305                 if( !preg_match( '/^(\d+)\.(\d+).*/i', $wgVersion, $result ) ) {
01306                         throw new MWException( 'Variable $wgVersion has an invalid value.' );
01307                 }
01308 
01309                 return 'RELEASE-NOTES-' . $result[1] . '.' . $result[2];
01310         }
01311 }
01312 
01313 class WebInstaller_UpgradeDoc extends WebInstaller_Document {
01314         protected function getFileName() { return 'UPGRADE'; }
01315 }
01316 
01317 class WebInstaller_Copying extends WebInstaller_Document {
01318         protected function getFileName() { return 'COPYING'; }
01319 }