148 parent::__construct();
163 if ( isset(
$session[
'settings'] ) ) {
166 foreach ( $this->settings as $key => $val ) {
167 $GLOBALS[$key] = $val;
173 if ( ( $this->
getVar(
'_InstallDone' ) || $this->
getVar(
'_UpgradeDone' ) )
174 && $this->request->getVal(
'localsettings' )
180 $isCSS = $this->request->getVal(
'css' );
186 $this->happyPages =
$session[
'happyPages'] ?? [];
188 $this->skippedPages =
$session[
'skippedPages'] ?? [];
192 # Special case for Creative Commons partner chooser box.
193 if ( $this->request->getVal(
'SubmitCC' ) ) {
196 '@phan-var WebInstallerOptions $page';
197 $this->output->useShortHeader();
198 $this->output->allowFrames();
204 if ( $this->request->getVal(
'ShowCC' ) ) {
207 '@phan-var WebInstallerOptions $page';
208 $this->output->useShortHeader();
209 $this->output->allowFrames();
210 $this->output->addHTML( $page->getCCDoneBox() );
216 $pageName = $this->request->getVal(
'page',
'' );
218 if ( in_array( $pageName, $this->otherPages ) ) {
224 if ( !$pageName || !in_array( $pageName, $this->pageSequence ) ) {
225 $pageId = $lowestUnhappy;
227 $pageId = array_search( $pageName, $this->pageSequence );
230 # If necessary, move back to the lowest-numbered unhappy page
231 if ( $pageId > $lowestUnhappy ) {
232 $pageId = $lowestUnhappy;
233 if ( $lowestUnhappy == 0 ) {
234 # Knocked back to start, possible loss of session data.
235 $this->showSessionWarning =
true;
239 $pageName = $this->pageSequence[$pageId];
243 # If a back button was submitted, go back without submitting the form data.
244 if ( $this->request->wasPosted() && $this->request->getBool(
'submit-back' ) ) {
245 if ( $this->request->getVal(
'lastPage' ) ) {
246 $nextPage = $this->request->getVal(
'lastPage' );
247 } elseif ( $pageId !==
false ) {
249 # Skip the skipped pages
250 $nextPageId = $pageId;
254 $nextPage = $this->pageSequence[$nextPageId];
255 }
while ( isset( $this->skippedPages[$nextPage] ) );
257 $nextPage = $this->pageSequence[$lowestUnhappy];
260 $this->output->redirect( $this->
getUrl( [
'page' => $nextPage ] ) );
266 $this->currentPageName = $page->getName();
267 $this->startPageWrapper( $pageName );
269 if ( $page->isSlow() ) {
273 $result = $page->execute();
275 $this->endPageWrapper();
277 if ( $result ==
'skip' ) {
278 # Page skipped without explicit submission.
279 # Skip it when we click "back" so that we don't just go forward again.
280 $this->skippedPages[$pageName] =
true;
281 $result =
'continue';
283 unset( $this->skippedPages[$pageName] );
286 # If it was posted, the page can request a continue to the next page.
287 if ( $result ===
'continue' && !$this->output->headerDone() ) {
288 if ( $pageId !==
false ) {
289 $this->happyPages[$pageId] =
true;
294 if ( $this->request->getVal(
'lastPage' ) ) {
295 $nextPage = $this->request->getVal(
'lastPage' );
296 } elseif ( $pageId !==
false ) {
297 $nextPage = $this->pageSequence[$pageId + 1];
299 $nextPage = $this->pageSequence[$lowestUnhappy];
302 if ( array_search( $nextPage, $this->pageSequence ) > $lowestUnhappy ) {
303 $nextPage = $this->pageSequence[$lowestUnhappy];
306 $this->output->redirect( $this->
getUrl( [
'page' => $nextPage ] ) );
317 if ( count( $this->happyPages ) == 0 ) {
320 return max( array_keys( $this->happyPages ) ) + 1;
331 if (
wfIniGetBool(
'session.auto_start' ) || session_id() ) {
338 if ( $this->request->getProtocol() ===
'https' ) {
339 $options[
'cookie_secure'] =
'1';
342 $this->phpErrors = [];
343 set_error_handler( [ $this,
'errorHandler' ] );
345 session_name(
'mw_installer_session' );
346 session_start( $options );
347 }
catch ( Exception $e ) {
348 restore_error_handler();
351 restore_error_handler();
353 if ( $this->phpErrors ) {
370 $url = $this->request->getFullRequestURL();
371 if ( preg_match(
'!^(.*\?)!', $url, $m ) ) {
375 if ( preg_match(
'!^(.*)/[^/]*/[^/]*$!', $url, $m ) ) {
381 return md5( serialize( [
382 'local path' => dirname( __DIR__ ),
395 if ( !( $msg instanceof
Message ) ) {
398 array_map(
'htmlspecialchars', $params )
401 $text = $msg->useDatabase(
false )->parse();
402 $box = Html::errorBox( $text,
'',
'config-error-box' );
403 $this->output->addHTML( $box );
413 $this->phpErrors[] = $errstr;
422 $this->output->output();
436 $this->happyPages = [];
437 $this->settings = [];
448 $url = $this->request->getRequestURL();
449 # Remove existing query
450 $url = preg_replace(
'/\?.*$/',
'', $url );
466 $pageClass =
'WebInstaller' . $pageName;
468 return new $pageClass( $this );
480 return $this->session[$name] ?? $default;
490 $this->session[$name] = $value;
499 return $this->tabIndex++;
508 if ( $this->
getSession(
'test' ) ===
null && !$this->request->wasPosted() ) {
510 $wgLang = MediaWikiServices::getInstance()->getLanguageFactory()
513 $this->
setVar(
'wgLanguageCode', $wgLanguageCode );
514 $this->
setVar(
'_UserLang', $wgLanguageCode );
529 $mwLanguages = MediaWikiServices::getInstance()
530 ->getLanguageNameUtils()
531 ->getLanguageNames( LanguageNameUtils::AUTONYMS, LanguageNameUtils::SUPPORTED );
532 $headerLanguages = array_keys(
$wgRequest->getAcceptLang() );
534 foreach ( $headerLanguages as $lang ) {
535 if ( isset( $mwLanguages[$lang] ) ) {
549 $s =
"<div class=\"config-page-wrapper\">\n";
550 $s .=
"<div class=\"config-page\">\n";
551 $s .=
"<div class=\"config-page-list\"><ul>\n";
554 foreach ( $this->pageSequence as $id => $pageName ) {
555 $happy = !empty( $this->happyPages[$id] );
556 $s .= $this->getPageListItem(
558 $happy || $lastHappy == $id - 1,
567 $s .=
"</ul><br/><ul>\n";
570 $s .=
"</ul></div>\n";
577 $s .= Html::element(
'h2', [],
580 $this->output->addHTMLNoFlush( $s );
593 $s =
"<li class=\"config-page-list-item\">";
600 $name =
wfMessage(
'config-page-' . strtolower( $pageName ) )->text();
603 $query = [
'page' => $pageName ];
605 if ( !in_array( $pageName, $this->pageSequence ) ) {
610 $link = Html::element(
'a',
612 'href' => $this->
getUrl( $query )
617 $link = htmlspecialchars( $name );
621 $s .=
"<span class=\"config-page-current\">$link</span>";
626 $s .= Html::element(
'span',
628 'class' =>
'config-page-disabled'
642 private function endPageWrapper() {
643 $this->output->addHTMLNoFlush(
644 "<div class=\"visualClear\"></div>\n" .
646 "<div class=\"visualClear\"></div>\n" .
658 public function getInfoBox( $text, $icon =
false, $class =
'' ) {
661 $this->
parse( $text,
true );
663 'images/info-32.png' :
665 $alt =
wfMessage(
'config-information' )->text();
680 $args = array_map(
'htmlspecialchars', $args );
681 $text =
wfMessage( $msg, $args )->useDatabase(
false )->plain();
682 $html = $this->
parse( $text,
true );
683 $id =
'helpBox-' . $this->helpBoxId++;
685 return "<div class=\"config-help-field-container\">\n" .
686 "<input type=\"checkbox\" class=\"config-help-field-checkbox\" id=\"$id\" />" .
687 "<label class=\"config-help-field-hint\" for=\"$id\" title=\"" .
688 wfMessage(
'config-help-tooltip' )->escaped() .
"\">" .
689 wfMessage(
'config-help' )->escaped() .
"</label>\n" .
690 "<div class=\"config-help-field-data\">" . $html .
"</div>\n" .
700 $html = $this->
getHelpBox( $msg, ...$params );
701 $this->output->addHTML( $html );
712 $html =
'<div class="config-message">' .
713 $this->
parse(
wfMessage( $msg, $params )->useDatabase(
false )->plain() ) .
715 $this->output->addHTML( $html );
723 foreach ( $errors as $error ) {
739 public function label( $msg, $forId, $contents, $helpData =
"" ) {
740 if ( strval( $msg ) ==
'' ) {
741 $labelText =
"\u{00A0}";
743 $labelText =
wfMessage( $msg )->escaped();
746 $attributes = [
'class' =>
'config-label' ];
749 $attributes[
'for'] = $forId;
752 return "<div class=\"config-block\">\n" .
753 " <div class=\"config-block-label\">\n" .
760 " <div class=\"config-block-elements\">\n" .
782 if ( !isset( $params[
'controlName'] ) ) {
783 $params[
'controlName'] =
'config_' . $params[
'var'];
786 if ( !isset( $params[
'value'] ) ) {
787 $params[
'value'] = $this->
getVar( $params[
'var'] );
790 if ( !isset( $params[
'attribs'] ) ) {
791 $params[
'attribs'] = [];
793 if ( !isset( $params[
'help'] ) ) {
794 $params[
'help'] =
"";
799 $params[
'controlName'],
801 $params[
'controlName'],
804 $params[
'attribs'] + [
805 'id' => $params[
'controlName'],
806 'class' =>
'config-input-text',
829 if ( !isset( $params[
'controlName'] ) ) {
830 $params[
'controlName'] =
'config_' . $params[
'var'];
833 if ( !isset( $params[
'value'] ) ) {
834 $params[
'value'] = $this->
getVar( $params[
'var'] );
837 if ( !isset( $params[
'attribs'] ) ) {
838 $params[
'attribs'] = [];
840 if ( !isset( $params[
'help'] ) ) {
841 $params[
'help'] =
"";
846 $params[
'controlName'],
848 $params[
'controlName'],
852 $params[
'attribs'] + [
853 'id' => $params[
'controlName'],
854 'class' =>
'config-input-text',
879 if ( !isset( $params[
'value'] ) ) {
880 $params[
'value'] = $this->
getVar( $params[
'var'] );
883 if ( !isset( $params[
'attribs'] ) ) {
884 $params[
'attribs'] = [];
888 $params[
'attribs'][
'type'] =
'password';
910 if ( !isset( $params[
'controlName'] ) ) {
911 $params[
'controlName'] =
'config_' . $params[
'var'];
914 if ( !isset( $params[
'value'] ) ) {
915 $params[
'value'] = $this->
getVar( $params[
'var'] );
918 if ( !isset( $params[
'attribs'] ) ) {
919 $params[
'attribs'] = [];
921 if ( !isset( $params[
'help'] ) ) {
922 $params[
'help'] =
"";
924 if ( !isset( $params[
'labelAttribs'] ) ) {
925 $params[
'labelAttribs'] = [];
927 $labelText = $params[
'rawtext'] ?? $this->
parse(
wfMessage( $params[
'label'] )->plain() );
929 return "<div class=\"config-input-check\">\n" .
933 $params[
'labelAttribs'],
935 $params[
'controlName'],
937 $params[
'attribs'] + [
938 'id' => $params[
'controlName'],
970 $label = $params[
'label'] ??
'';
972 if ( !isset( $params[
'controlName'] ) ) {
973 $params[
'controlName'] =
'config_' . $params[
'var'];
976 if ( !isset( $params[
'help'] ) ) {
977 $params[
'help'] =
"";
981 foreach ( $items as $item ) {
982 $s .=
"<li>$item</li>\n";
986 return $this->
label( $label, $params[
'controlName'], $s, $params[
'help'] );
999 if ( !isset( $params[
'controlName'] ) ) {
1000 $params[
'controlName'] =
'config_' . $params[
'var'];
1003 if ( !isset( $params[
'value'] ) ) {
1004 $params[
'value'] = $this->
getVar( $params[
'var'] );
1009 foreach ( $params[
'values'] as $value ) {
1012 if ( isset( $params[
'commonAttribs'] ) ) {
1013 $itemAttribs = $params[
'commonAttribs'];
1016 if ( isset( $params[
'itemAttribs'][$value] ) ) {
1017 $itemAttribs = $params[
'itemAttribs'][$value] + $itemAttribs;
1020 $checked = $value == $params[
'value'];
1021 $id = $params[
'controlName'] .
'_' . $value;
1022 $itemAttribs[
'id'] = $id;
1026 Xml::radio( $params[
'controlName'], $value, $checked, $itemAttribs ) .
1029 isset( $params[
'itemLabels'] ) ?
1030 wfMessage( $params[
'itemLabels'][$value] )->plain() :
1031 wfMessage( $params[
'itemLabelPrefix'] . strtolower( $value ) )->plain()
1044 if ( !$status->isGood() ) {
1045 $html = $status->getHTML();
1047 if ( $status->isOK() ) {
1048 $box = Html::warningBox( $html,
'config-warning-box' );
1050 $box = Html::errorBox( $html,
'',
'config-error-box' );
1053 $this->output->addHTML( $box );
1070 foreach ( $varNames as $name ) {
1071 $value = $this->request->getVal( $prefix . $name );
1073 if ( $value !==
null && stripos( $name,
'password' ) ===
false ) {
1074 $value = trim( $value );
1076 $newValues[$name] = $value;
1078 if ( $value ===
null ) {
1080 $this->
setVar( $name,
false );
1081 } elseif ( stripos( $name,
'password' ) !==
false ) {
1084 $this->
setVar( $name, $value );
1099 $query = [
'page' => $page ];
1101 if ( in_array( $this->currentPageName, $this->pageSequence ) ) {
1105 return $this->
getUrl( $query );
1117 return Html::rawElement(
'li', [],
1118 Html::element(
'a', [
'href' => $url ], $linkText )
1129 $anchor = Html::rawElement(
'a',
1130 [
'href' => $this->
getUrl( [
'localsettings' => 1 ] ) ],
1134 return Html::rawElement(
'div', [
'class' =>
'config-download-link' ], $anchor );
1159 if ( !empty( $_SERVER[
'PHP_SELF'] ) ) {
1160 $path = $_SERVER[
'PHP_SELF'];
1161 } elseif ( !empty( $_SERVER[
'SCRIPT_NAME'] ) ) {
1162 $path = $_SERVER[
'SCRIPT_NAME'];
1164 if (
$path ===
false ) {
1169 return parent::envCheckPath();
1173 parent::envPrepPath();
1178 if ( !empty( $_SERVER[
'PHP_SELF'] ) ) {
1179 $path = $_SERVER[
'PHP_SELF'];
1180 } elseif ( !empty( $_SERVER[
'SCRIPT_NAME'] ) ) {
1181 $path = $_SERVER[
'SCRIPT_NAME'];
1183 if (
$path !==
false ) {
1184 $scriptPath = preg_replace(
'{^(.*)/(mw-)?config.*$}',
'$1',
$path );
1186 $this->
setVar(
'wgScriptPath',
"$scriptPath" );
1188 $this->
setVar(
'wgScript',
"$scriptPath/index.php" );
1189 $this->
setVar(
'wgLoadScript',
"$scriptPath/load.php" );
1190 $this->
setVar(
'wgStylePath',
"$scriptPath/skins" );
1191 $this->
setVar(
'wgLocalStylePath',
"$scriptPath/skins" );
1192 $this->
setVar(
'wgExtensionAssetsPath',
"$scriptPath/extensions" );
1193 $this->
setVar(
'wgUploadPath',
"$scriptPath/images" );
1194 $this->
setVar(
'wgResourceBasePath',
"$scriptPath" );
1202 $assumeProxiesUseDefaultProtocolPorts =
1203 $this->
getVar(
'wgAssumeProxiesUseDefaultProtocolPorts' );
1205 return WebRequest::detectServer( $assumeProxiesUseDefaultProtocolPorts );
1211 private function outputLS() {
1212 $this->request->response()->header(
'Content-type: application/x-httpd-php' );
1213 $this->request->response()->header(
1214 'Content-Disposition: attachment; filename="LocalSettings.php"'
1218 $rightsProfile = $this->rightsProfiles[$this->
getVar(
'_RightsProfile' )];
1219 foreach ( $rightsProfile as $group => $rightsArr ) {
1220 $ls->setGroupRights( $group, $rightsArr );
1222 echo $ls->getText();
1229 $this->request->response()->header(
'Content-type: text/css' );
1230 echo $this->output->getCSS();
1250 protected static function infoBox( $rawHtml, $icon, $alt, $class =
'' ) {
1251 $s = Html::openElement(
'div', [
'class' =>
'mw-installer-box-left' ] ) .
1252 Html::element(
'img',
1258 Html::closeElement(
'div' ) .
1259 Html::openElement(
'div', [
'class' =>
'mw-installer-box-right' ] ) .
1261 Html::closeElement(
'div' ) .
1262 Html::element(
'div', [
'style' =>
'clear: left;' ],
' ' );
1264 return Html::warningBox( $s, $class )
1265 . Html::element(
'div', [
'style' =>
'clear: left;' ],
' ' );
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 getHtml( $input)
Provide a string or HtmlArmor object and get safe HTML back.
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.
static getMain()
Get the RequestContext object associated with the main request.
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.
static textarea( $name, $content, $cols=40, $rows=5, $attribs=[])
Shortcut for creating textareas.
static check( $name, $checked=false, $attribs=[])
Convenience function to build an HTML checkbox.
static input( $name, $size=false, $value=false, $attribs=[])
Convenience function to build an HTML text input field.
static tags( $element, $attribs, $contents)
Same as Xml::element(), but does not escape contents.
static radio( $name, $value, $checked=false, $attribs=[])
Convenience function to build an HTML radio button.
$wgLanguageCode
Config variable stub for the LanguageCode setting, for use by phpdoc and IDEs.