MediaWiki
REL1_23
|
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( '&', '&', $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 '  ' . 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 }