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