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