145 parent::__construct();
160 if ( isset(
$session[
'settings'] ) ) {
163 foreach ( $this->settings as $key => $val ) {
164 $GLOBALS[$key] = $val;
170 if ( ( $this->
getVar(
'_InstallDone' ) || $this->
getVar(
'_UpgradeDone' ) )
171 && $this->request->getVal(
'localsettings' )
177 $isCSS = $this->request->getVal(
'css' );
183 $this->happyPages =
$session[
'happyPages'] ?? [];
185 $this->skippedPages =
$session[
'skippedPages'] ?? [];
189 # Special case for Creative Commons partner chooser box.
190 if ( $this->request->getVal(
'SubmitCC' ) ) {
193 '@phan-var WebInstallerOptions $page';
194 $this->output->useShortHeader();
195 $this->output->allowFrames();
201 if ( $this->request->getVal(
'ShowCC' ) ) {
204 '@phan-var WebInstallerOptions $page';
205 $this->output->useShortHeader();
206 $this->output->allowFrames();
207 $this->output->addHTML( $page->getCCDoneBox() );
213 $pageName = $this->request->getVal(
'page',
'' );
215 if ( in_array( $pageName, $this->otherPages ) ) {
221 if ( !$pageName || !in_array( $pageName, $this->pageSequence ) ) {
222 $pageId = $lowestUnhappy;
224 $pageId = array_search( $pageName, $this->pageSequence );
227 # If necessary, move back to the lowest-numbered unhappy page
228 if ( $pageId > $lowestUnhappy ) {
229 $pageId = $lowestUnhappy;
230 if ( $lowestUnhappy == 0 ) {
231 # Knocked back to start, possible loss of session data.
232 $this->showSessionWarning =
true;
236 $pageName = $this->pageSequence[$pageId];
240 # If a back button was submitted, go back without submitting the form data.
241 if ( $this->request->wasPosted() && $this->request->getBool(
'submit-back' ) ) {
242 if ( $this->request->getVal(
'lastPage' ) ) {
243 $nextPage = $this->request->getVal(
'lastPage' );
244 } elseif ( $pageId !==
false ) {
246 # Skip the skipped pages
247 $nextPageId = $pageId;
251 $nextPage = $this->pageSequence[$nextPageId];
252 }
while ( isset( $this->skippedPages[$nextPage] ) );
254 $nextPage = $this->pageSequence[$lowestUnhappy];
257 $this->output->redirect( $this->
getUrl( [
'page' => $nextPage ] ) );
263 $this->currentPageName = $page->getName();
264 $this->startPageWrapper( $pageName );
266 if ( $page->isSlow() ) {
270 $result = $page->execute();
272 $this->endPageWrapper();
274 if ( $result ==
'skip' ) {
275 # Page skipped without explicit submission.
276 # Skip it when we click "back" so that we don't just go forward again.
277 $this->skippedPages[$pageName] =
true;
278 $result =
'continue';
280 unset( $this->skippedPages[$pageName] );
283 # If it was posted, the page can request a continue to the next page.
284 if ( $result ===
'continue' && !$this->output->headerDone() ) {
285 if ( $pageId !==
false ) {
286 $this->happyPages[$pageId] =
true;
291 if ( $this->request->getVal(
'lastPage' ) ) {
292 $nextPage = $this->request->getVal(
'lastPage' );
293 } elseif ( $pageId !==
false ) {
294 $nextPage = $this->pageSequence[$pageId + 1];
296 $nextPage = $this->pageSequence[$lowestUnhappy];
299 if ( array_search( $nextPage, $this->pageSequence ) > $lowestUnhappy ) {
300 $nextPage = $this->pageSequence[$lowestUnhappy];
303 $this->output->redirect( $this->
getUrl( [
'page' => $nextPage ] ) );
314 if ( count( $this->happyPages ) == 0 ) {
317 return max( array_keys( $this->happyPages ) ) + 1;
328 if (
wfIniGetBool(
'session.auto_start' ) || session_id() ) {
335 if ( $this->request->getProtocol() ===
'https' ) {
336 $options[
'cookie_secure'] =
'1';
339 $this->phpErrors = [];
340 set_error_handler( [ $this,
'errorHandler' ] );
342 session_name(
'mw_installer_session' );
343 session_start( $options );
344 }
catch ( Exception $e ) {
345 restore_error_handler();
348 restore_error_handler();
350 if ( $this->phpErrors ) {
367 $url = $this->request->getFullRequestURL();
368 if ( preg_match(
'!^(.*\?)!', $url, $m ) ) {
372 if ( preg_match(
'!^(.*)/[^/]*/[^/]*$!', $url, $m ) ) {
379 'local path' => dirname( __DIR__ ),
392 if ( !( $msg instanceof
Message ) ) {
395 array_map(
'htmlspecialchars', $params )
398 $text = $msg->useDatabase(
false )->parse();
399 $box = Html::errorBox( $text,
'',
'config-error-box' );
400 $this->output->addHTML( $box );
410 $this->phpErrors[] = $errstr;
419 $this->output->output();
433 $this->happyPages = [];
434 $this->settings = [];
445 $url = $this->request->getRequestURL();
446 # Remove existing query
447 $url = preg_replace(
'/\?.*$/',
'', $url );
463 $pageClass =
'WebInstaller' . $pageName;
465 return new $pageClass( $this );
477 return $this->session[$name] ?? $default;
487 $this->session[$name] = $value;
496 return $this->tabIndex++;
505 if ( $this->
getSession(
'test' ) ===
null && !$this->request->wasPosted() ) {
507 $wgLang = MediaWikiServices::getInstance()->getLanguageFactory()
509 RequestContext::getMain()->setLanguage(
$wgLang );
510 $this->
setVar(
'wgLanguageCode', $wgLanguageCode );
511 $this->
setVar(
'_UserLang', $wgLanguageCode );
526 $mwLanguages = MediaWikiServices::getInstance()
527 ->getLanguageNameUtils()
528 ->getLanguageNames( LanguageNameUtils::AUTONYMS, LanguageNameUtils::SUPPORTED );
529 $headerLanguages = array_keys(
$wgRequest->getAcceptLang() );
531 foreach ( $headerLanguages as
$lang ) {
532 if ( isset( $mwLanguages[
$lang] ) ) {
546 $s =
"<div class=\"config-page-wrapper\">\n";
547 $s .=
"<div class=\"config-page\">\n";
548 $s .=
"<div class=\"config-page-list\"><ul>\n";
551 foreach ( $this->pageSequence as $id => $pageName ) {
552 $happy = !empty( $this->happyPages[$id] );
553 $s .= $this->getPageListItem(
555 $happy || $lastHappy == $id - 1,
564 $s .=
"</ul><br/><ul>\n";
567 $s .=
"</ul></div>\n";
577 $this->output->addHTMLNoFlush(
$s );
590 $s =
"<li class=\"config-page-list-item\">";
597 $name =
wfMessage(
'config-page-' . strtolower( $pageName ) )->text();
600 $query = [
'page' => $pageName ];
602 if ( !in_array( $pageName, $this->pageSequence ) ) {
609 'href' => $this->
getUrl( $query )
614 $link = htmlspecialchars( $name );
618 $s .=
"<span class=\"config-page-current\">$link</span>";
625 'class' =>
'config-page-disabled'
639 private function endPageWrapper() {
640 $this->output->addHTMLNoFlush(
641 "<div class=\"visualClear\"></div>\n" .
643 "<div class=\"visualClear\"></div>\n" .
655 public function getInfoBox( $text, $icon =
false, $class =
'' ) {
657 HtmlArmor::getHtml( $text ) :
658 $this->
parse( $text,
true );
660 'images/info-32.png' :
662 $alt =
wfMessage(
'config-information' )->text();
655 public function getInfoBox( $text, $icon =
false, $class =
'' ) {
…}
677 $args = array_map(
'htmlspecialchars',
$args );
679 $html = $this->
parse( $text,
true );
680 $id =
'helpBox-' . $this->helpBoxId++;
682 return "<div class=\"config-help-field-container\">\n" .
683 "<input type=\"checkbox\" class=\"config-help-field-checkbox\" id=\"$id\" />" .
684 "<label class=\"config-help-field-hint\" for=\"$id\" title=\"" .
685 wfMessage(
'config-help-tooltip' )->escaped() .
"\">" .
686 wfMessage(
'config-help' )->escaped() .
"</label>\n" .
687 "<div class=\"config-help-field-data\">" . $html .
"</div>\n" .
697 $html = $this->
getHelpBox( $msg, ...$params );
698 $this->output->addHTML( $html );
709 $html =
'<div class="config-message">' .
710 $this->
parse(
wfMessage( $msg, $params )->useDatabase(
false )->plain() ) .
712 $this->output->addHTML( $html );
720 foreach ( $errors as $error ) {
736 public function label( $msg, $forId, $contents, $helpData =
"" ) {
737 if ( strval( $msg ) ==
'' ) {
738 $labelText =
"\u{00A0}";
740 $labelText =
wfMessage( $msg )->escaped();
743 $attributes = [
'class' =>
'config-label' ];
746 $attributes[
'for'] = $forId;
749 return "<div class=\"config-block\">\n" .
750 " <div class=\"config-block-label\">\n" .
757 " <div class=\"config-block-elements\">\n" .
736 public function label( $msg, $forId, $contents, $helpData =
"" ) {
…}
779 if ( !isset( $params[
'controlName'] ) ) {
780 $params[
'controlName'] =
'config_' . $params[
'var'];
783 if ( !isset( $params[
'value'] ) ) {
784 $params[
'value'] = $this->
getVar( $params[
'var'] );
787 if ( !isset( $params[
'attribs'] ) ) {
788 $params[
'attribs'] = [];
790 if ( !isset( $params[
'help'] ) ) {
791 $params[
'help'] =
"";
796 $params[
'controlName'],
798 $params[
'controlName'],
801 $params[
'attribs'] + [
802 'id' => $params[
'controlName'],
803 'class' =>
'config-input-text',
826 if ( !isset( $params[
'controlName'] ) ) {
827 $params[
'controlName'] =
'config_' . $params[
'var'];
830 if ( !isset( $params[
'value'] ) ) {
831 $params[
'value'] = $this->
getVar( $params[
'var'] );
834 if ( !isset( $params[
'attribs'] ) ) {
835 $params[
'attribs'] = [];
837 if ( !isset( $params[
'help'] ) ) {
838 $params[
'help'] =
"";
843 $params[
'controlName'],
845 $params[
'controlName'],
849 $params[
'attribs'] + [
850 'id' => $params[
'controlName'],
851 'class' =>
'config-input-text',
876 if ( !isset( $params[
'value'] ) ) {
877 $params[
'value'] = $this->
getVar( $params[
'var'] );
880 if ( !isset( $params[
'attribs'] ) ) {
881 $params[
'attribs'] = [];
885 $params[
'attribs'][
'type'] =
'password';
907 if ( !isset( $params[
'controlName'] ) ) {
908 $params[
'controlName'] =
'config_' . $params[
'var'];
911 if ( !isset( $params[
'value'] ) ) {
912 $params[
'value'] = $this->
getVar( $params[
'var'] );
915 if ( !isset( $params[
'attribs'] ) ) {
916 $params[
'attribs'] = [];
918 if ( !isset( $params[
'help'] ) ) {
919 $params[
'help'] =
"";
921 if ( !isset( $params[
'labelAttribs'] ) ) {
922 $params[
'labelAttribs'] = [];
924 $labelText = $params[
'rawtext'] ?? $this->
parse(
wfMessage( $params[
'label'] )->plain() );
926 return "<div class=\"config-input-check\">\n" .
930 $params[
'labelAttribs'],
932 $params[
'controlName'],
934 $params[
'attribs'] + [
935 'id' => $params[
'controlName'],
967 $label = $params[
'label'] ??
'';
969 if ( !isset( $params[
'controlName'] ) ) {
970 $params[
'controlName'] =
'config_' . $params[
'var'];
973 if ( !isset( $params[
'help'] ) ) {
974 $params[
'help'] =
"";
978 foreach ( $items as $value => $item ) {
979 $s .=
"<li>$item</li>\n";
983 return $this->
label( $label, $params[
'controlName'],
$s, $params[
'help'] );
996 if ( !isset( $params[
'controlName'] ) ) {
997 $params[
'controlName'] =
'config_' . $params[
'var'];
1000 if ( !isset( $params[
'value'] ) ) {
1001 $params[
'value'] = $this->
getVar( $params[
'var'] );
1006 foreach ( $params[
'values'] as $value ) {
1009 if ( isset( $params[
'commonAttribs'] ) ) {
1010 $itemAttribs = $params[
'commonAttribs'];
1013 if ( isset( $params[
'itemAttribs'][$value] ) ) {
1014 $itemAttribs = $params[
'itemAttribs'][$value] + $itemAttribs;
1017 $checked = $value == $params[
'value'];
1018 $id = $params[
'controlName'] .
'_' . $value;
1019 $itemAttribs[
'id'] = $id;
1023 Xml::radio( $params[
'controlName'], $value, $checked, $itemAttribs ) .
1025 Xml::tags(
'label', [
'for' => $id ], $this->
parse(
1026 isset( $params[
'itemLabels'] ) ?
1027 wfMessage( $params[
'itemLabels'][$value] )->plain() :
1028 wfMessage( $params[
'itemLabelPrefix'] . strtolower( $value ) )->plain()
1041 if ( !$status->isGood() ) {
1042 $html = $status->getHTML();
1044 if ( $status->isOK() ) {
1045 $box = Html::warningBox( $html,
'config-warning-box' );
1047 $box = Html::errorBox( $html,
'',
'config-error-box' );
1050 $this->output->addHTML( $box );
1067 foreach ( $varNames as $name ) {
1068 $value = $this->request->getVal( $prefix . $name );
1070 if ( $value !==
null && stripos( $name,
'password' ) ===
false ) {
1071 $value = trim( $value );
1073 $newValues[$name] = $value;
1075 if ( $value ===
null ) {
1077 $this->
setVar( $name,
false );
1078 } elseif ( stripos( $name,
'password' ) !==
false ) {
1081 $this->
setVar( $name, $value );
1096 $query = [
'page' => $page ];
1098 if ( in_array( $this->currentPageName, $this->pageSequence ) ) {
1102 return $this->
getUrl( $query );
1114 return Html::rawElement(
'li', [],
1115 Html::element(
'a', [
'href' => $url ], $linkText )
1126 $anchor = Html::rawElement(
'a',
1127 [
'href' => $this->
getUrl( [
'localsettings' => 1 ] ) ],
1131 return Html::rawElement(
'div', [
'class' =>
'config-download-link' ], $anchor );
1156 if ( !empty( $_SERVER[
'PHP_SELF'] ) ) {
1157 $path = $_SERVER[
'PHP_SELF'];
1158 } elseif ( !empty( $_SERVER[
'SCRIPT_NAME'] ) ) {
1159 $path = $_SERVER[
'SCRIPT_NAME'];
1161 if (
$path ===
false ) {
1166 return parent::envCheckPath();
1170 parent::envPrepPath();
1175 if ( !empty( $_SERVER[
'PHP_SELF'] ) ) {
1176 $path = $_SERVER[
'PHP_SELF'];
1177 } elseif ( !empty( $_SERVER[
'SCRIPT_NAME'] ) ) {
1178 $path = $_SERVER[
'SCRIPT_NAME'];
1180 if (
$path !==
false ) {
1181 $scriptPath = preg_replace(
'{^(.*)/(mw-)?config.*$}',
'$1',
$path );
1183 $this->
setVar(
'wgScriptPath',
"$scriptPath" );
1185 $this->
setVar(
'wgScript',
"$scriptPath/index.php" );
1186 $this->
setVar(
'wgLoadScript',
"$scriptPath/load.php" );
1187 $this->
setVar(
'wgStylePath',
"$scriptPath/skins" );
1188 $this->
setVar(
'wgLocalStylePath',
"$scriptPath/skins" );
1189 $this->
setVar(
'wgExtensionAssetsPath',
"$scriptPath/extensions" );
1190 $this->
setVar(
'wgUploadPath',
"$scriptPath/images" );
1191 $this->
setVar(
'wgResourceBasePath',
"$scriptPath" );
1199 $assumeProxiesUseDefaultProtocolPorts =
1200 $this->
getVar(
'wgAssumeProxiesUseDefaultProtocolPorts' );
1202 return WebRequest::detectServer( $assumeProxiesUseDefaultProtocolPorts );
1208 private function outputLS() {
1209 $this->request->response()->header(
'Content-type: application/x-httpd-php' );
1210 $this->request->response()->header(
1211 'Content-Disposition: attachment; filename="LocalSettings.php"'
1215 $rightsProfile = $this->rightsProfiles[$this->
getVar(
'_RightsProfile' )];
1216 foreach ( $rightsProfile as $group => $rightsArr ) {
1217 $ls->setGroupRights( $group, $rightsArr );
1219 echo $ls->getText();
1226 $this->request->response()->header(
'Content-type: text/css' );
1227 echo $this->output->getCSS();
1247 protected static function infoBox( $rawHtml, $icon, $alt, $class =
'' ) {
1248 $s = Html::openElement(
'div', [
'class' =>
'mw-installer-box-left' ] ) .
1249 Html::element(
'img',
1255 Html::closeElement(
'div' );
1257 $s .= Html::openElement(
'div', [
'class' =>
'mw-installer-box-right' ] ) .
1259 Html::closeElement(
'div' );
1260 $s .= Html::element(
'div', [
'style' =>
'clear: left;' ],
' ' );
1262 return Html::warningBox(
$s, $class )
1263 . Html::element(
'div', [
'style' =>
'clear: left;' ],
' ' );
1247 protected static function infoBox( $rawHtml, $icon, $alt, $class =
'' ) {
…}
const MW_VERSION
The running version of MediaWiki.
wfIniGetBool( $setting)
Safety wrapper around ini_get() for boolean settings.
wfArrayToCgi( $array1, $array2=null, $prefix='')
This function takes one or two arrays as input, and returns a CGI-style string, e....
wfMessage( $key,... $params)
This is the function for getting translated interface messages.
if(!defined( 'MW_NO_SESSION') &&! $wgCommandLineMode $wgLang
Marks HTML that shouldn't be escaped.
static element( $element, $attribs=[], $contents='')
Identical to rawElement(), but HTML-escapes $contents (like Xml::element()).
static getLocalSettingsGenerator(Installer $installer)
Instantiates and returns an instance of LocalSettingsGenerator or its descendant classes.
parse( $text, $lineStart=false)
Convert wikitext $text to HTML.
setVar( $name, $value)
Set a MW configuration variable, or internal installer configuration variable.
getFakePassword( $realPassword)
Get a fake password for sending back to the user in HTML.
disableTimeLimit()
Disable the time limit for execution.
setPassword( $name, $value)
Set a variable which stores a password, except if the new value is a fake password in which case leav...
getVar( $name, $default=null)
Get an MW configuration variable, or internal installer configuration variable.
The Message class deals with fetching and processing of interface message into a variety of formats.
Generic operation result class Has warning/error list, boolean status and arbitrary value.
getErrorsArray()
Get the list of errors (but not warnings)
getWarningsArray()
Get the list of warnings (but not errors)
Output class modelled on OutputPage.
Class for the core installer web interface.
makeDownloadLinkHtml()
Helper for "Download LocalSettings" link.
setupLanguage()
Initializes language-related variables.
WebInstallerOutput $output
finish()
Clean up from execute()
getTextBox( $params)
Get a labelled text box to configure a variable.
getAcceptLanguage()
Retrieves MediaWiki language from Accept-Language HTTP header.
nextTabIndex()
Get the next tabindex attribute value.
showStatusBox( $status)
Output an error or warning box using a Status object.
setVarsFromRequest( $varNames, $prefix='config_')
Convenience function to set variables based on form data.
getPageByName( $pageName)
Get a WebInstallerPage by name.
errorHandler( $errno, $errstr)
Temporary error handler for session start debugging.
bool[] $happyPages
Array of pages which have declared that they have been submitted, have validated their input,...
getSession( $name, $default=null)
Get a session variable.
outputCss()
Output stylesheet for web installer pages.
getLowestUnhappy()
Find the next page in sequence that hasn't been completed.
showHelpBox( $msg,... $params)
Output a help box.
label( $msg, $forId, $contents, $helpData="")
Label a control by wrapping a config-input div around it and putting a label before it.
execute(array $session)
Main entry point.
getLocalSettingsLocation()
If the software package wants the LocalSettings.php file to be placed in a specific location,...
getDocUrl( $page)
Helper for WebInstallerOutput.
bool[] $skippedPages
List of "skipped" pages.
getRadioElements( $params)
Get a set of labelled radio buttons.
showMessage( $msg,... $params)
Show a short informational message.
showError( $msg,... $params)
Show an error message in a box.
setSession( $name, $value)
Set a session variable.
reset()
We're restarting the installation, reset the session, happyPages, etc.
string $currentPageName
Name of the page we're on.
getHelpBox( $msg,... $args)
Get small text indented help for a preceding form field.
getRadioSet( $params)
Get a set of labelled radio buttons.
getPasswordBox( $params)
Get a labelled password box to configure a variable.
getInfoBox( $text, $icon=false, $class='')
Get HTML for an information message box with an icon.
WebRequest $request
WebRequest object.
__construct(WebRequest $request)
getTextArea( $params)
Get a labelled textarea to configure a variable.
getFingerprint()
Get a hash of data identifying this MW installation.
string[] $otherPages
Out of sequence pages, selectable by the user at any time.
string[] $pageSequence
The main sequence of page names.
string[] $phpErrors
Captured PHP error text.
static infoBox( $rawHtml, $icon, $alt, $class='')
Get HTML for an information message box with an icon.
bool $showSessionWarning
Flag indicating that session data may have been lost.
showStatusMessage(Status $status)
getCheckBox( $params)
Get a labelled checkbox to configure a boolean variable.
makeLinkItem( $url, $linkText)
Helper for sidebar links.
startSession()
Start the PHP session.
int $tabIndex
Numeric index of the page we're on.
array[] $session
Cached session array.
getUrl( $query=[])
Get a URL for submission back to the same script.
envPrepPath()
Environment prep for setting $IP and $wgScriptPath.
int $helpBoxId
Numeric index of the help box.
The WebRequest class encapsulates getting at data passed in the URL or via a POSTed form stripping il...
$wgLanguageCode
Config variable stub for the LanguageCode setting, for use by phpdoc and IDEs.
foreach( $mmfl['setupFiles'] as $fileName) if($queue) if(empty( $mmfl['quiet'])) $s
if(!isset( $args[0])) $lang