145 parent::__construct();
160 if ( isset(
$session[
'settings'] ) ) {
163 foreach ( $this->settings as $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();
266 if ( $page->isSlow() ) {
270 $result = $page->execute();
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 )->plain();
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() ) {
508 RequestContext::getMain()->setLanguage(
$wgLang );
509 $this->
setVar(
'wgLanguageCode', $wgLanguageCode );
510 $this->
setVar(
'_UserLang', $wgLanguageCode );
514 $wgContLang = MediaWikiServices::getInstance()->getContentLanguage();
525 $mwLanguages = Language::fetchLanguageNames(
null,
'mwfile' );
526 $headerLanguages = array_keys(
$wgRequest->getAcceptLang() );
528 foreach ( $headerLanguages as
$lang ) {
529 if ( isset( $mwLanguages[
$lang] ) ) {
543 $s =
"<div class=\"config-page-wrapper\">\n";
544 $s .=
"<div class=\"config-page\">\n";
545 $s .=
"<div class=\"config-page-list\"><ul>\n";
548 foreach ( $this->pageSequence as $id => $pageName ) {
549 $happy = !empty( $this->happyPages[$id] );
552 $happy || $lastHappy == $id - 1,
561 $s .=
"</ul><br/><ul>\n";
564 $s .=
"</ul></div>\n";
571 $s .= Html::element(
'h2', [],
574 $this->output->addHTMLNoFlush(
$s );
587 $s =
"<li class=\"config-page-list-item\">";
594 $name =
wfMessage(
'config-page-' . strtolower( $pageName ) )->text();
597 $query = [
'page' => $pageName ];
599 if ( !in_array( $pageName, $this->pageSequence ) ) {
604 $link = Html::element(
'a',
606 'href' => $this->
getUrl( $query )
611 $link = htmlspecialchars( $name );
615 $s .=
"<span class=\"config-page-current\">$link</span>";
620 $s .= Html::element(
'span',
622 'class' =>
'config-page-disabled'
637 $this->output->addHTMLNoFlush(
638 "<div class=\"visualClear\"></div>\n" .
640 "<div class=\"visualClear\"></div>\n" .
654 return $this->
getInfoBox( $text,
'critical-32.png',
'config-error-box' );
667 return $this->
getInfoBox( $text,
'warning-32.png',
'config-warning-box' );
678 public function getInfoBox( $text, $icon =
false, $class =
false ) {
680 HtmlArmor::getHtml( $text ) :
681 $this->
parse( $text,
true );
682 $icon = ( $icon == false ) ?
683 'images/info-32.png' :
685 $alt =
wfMessage(
'config-information' )->text();
687 return Html::infoBox( $html, $icon, $alt, $class );
698 $args = array_map(
'htmlspecialchars',
$args );
700 $html = $this->
parse( $text,
true );
701 $id =
'helpBox-' . $this->helpBoxId++;
703 return "<div class=\"config-help-field-container\">\n" .
704 "<input type=\"checkbox\" class=\"config-help-field-checkbox\" id=\"$id\" />" .
705 "<label class=\"config-help-field-hint\" for=\"$id\" title=\"" .
706 wfMessage(
'config-help-tooltip' )->escaped() .
"\">" .
707 wfMessage(
'config-help' )->escaped() .
"</label>\n" .
708 "<div class=\"config-help-field-data\">" . $html .
"</div>\n" .
718 $html = $this->
getHelpBox( $msg, ...$params );
719 $this->output->addHTML( $html );
730 $html =
'<div class="config-message">' .
731 $this->
parse(
wfMessage( $msg, $params )->useDatabase(
false )->plain() ) .
733 $this->output->addHTML( $html );
741 foreach ( $errors as $error ) {
756 public function label( $msg, $forId, $contents, $helpData =
"" ) {
757 if ( strval( $msg ) ==
'' ) {
758 $labelText =
"\u{00A0}";
760 $labelText =
wfMessage( $msg )->escaped();
763 $attributes = [
'class' =>
'config-label' ];
766 $attributes[
'for'] = $forId;
769 return "<div class=\"config-block\">\n" .
770 " <div class=\"config-block-label\">\n" .
777 " <div class=\"config-block-elements\">\n" .
798 if ( !isset( $params[
'controlName'] ) ) {
799 $params[
'controlName'] =
'config_' . $params[
'var'];
802 if ( !isset( $params[
'value'] ) ) {
803 $params[
'value'] = $this->
getVar( $params[
'var'] );
806 if ( !isset( $params[
'attribs'] ) ) {
807 $params[
'attribs'] = [];
809 if ( !isset( $params[
'help'] ) ) {
810 $params[
'help'] =
"";
815 $params[
'controlName'],
817 $params[
'controlName'],
820 $params[
'attribs'] + [
821 'id' => $params[
'controlName'],
822 'class' =>
'config-input-text',
845 if ( !isset( $params[
'controlName'] ) ) {
846 $params[
'controlName'] =
'config_' . $params[
'var'];
849 if ( !isset( $params[
'value'] ) ) {
850 $params[
'value'] = $this->
getVar( $params[
'var'] );
853 if ( !isset( $params[
'attribs'] ) ) {
854 $params[
'attribs'] = [];
856 if ( !isset( $params[
'help'] ) ) {
857 $params[
'help'] =
"";
862 $params[
'controlName'],
864 $params[
'controlName'],
868 $params[
'attribs'] + [
869 'id' => $params[
'controlName'],
870 'class' =>
'config-input-text',
894 if ( !isset( $params[
'value'] ) ) {
895 $params[
'value'] = $this->
getVar( $params[
'var'] );
898 if ( !isset( $params[
'attribs'] ) ) {
899 $params[
'attribs'] = [];
903 $params[
'attribs'][
'type'] =
'password';
924 if ( !isset( $params[
'controlName'] ) ) {
925 $params[
'controlName'] =
'config_' . $params[
'var'];
928 if ( !isset( $params[
'value'] ) ) {
929 $params[
'value'] = $this->
getVar( $params[
'var'] );
932 if ( !isset( $params[
'attribs'] ) ) {
933 $params[
'attribs'] = [];
935 if ( !isset( $params[
'help'] ) ) {
936 $params[
'help'] =
"";
938 if ( !isset( $params[
'labelAttribs'] ) ) {
939 $params[
'labelAttribs'] = [];
941 $labelText = $params[
'rawtext'] ?? $this->
parse(
wfMessage( $params[
'label'] )->plain() );
943 return "<div class=\"config-input-check\">\n" .
947 $params[
'labelAttribs'],
949 $params[
'controlName'],
951 $params[
'attribs'] + [
952 'id' => $params[
'controlName'],
983 $label = $params[
'label'] ??
'';
985 if ( !isset( $params[
'controlName'] ) ) {
986 $params[
'controlName'] =
'config_' . $params[
'var'];
989 if ( !isset( $params[
'help'] ) ) {
990 $params[
'help'] =
"";
994 foreach ( $items as $value => $item ) {
995 $s .=
"<li>$item</li>\n";
999 return $this->
label( $label, $params[
'controlName'],
$s, $params[
'help'] );
1011 if ( !isset( $params[
'controlName'] ) ) {
1012 $params[
'controlName'] =
'config_' . $params[
'var'];
1015 if ( !isset( $params[
'value'] ) ) {
1016 $params[
'value'] = $this->
getVar( $params[
'var'] );
1021 foreach ( $params[
'values'] as $value ) {
1024 if ( isset( $params[
'commonAttribs'] ) ) {
1025 $itemAttribs = $params[
'commonAttribs'];
1028 if ( isset( $params[
'itemAttribs'][$value] ) ) {
1029 $itemAttribs = $params[
'itemAttribs'][$value] + $itemAttribs;
1032 $checked = $value == $params[
'value'];
1033 $id = $params[
'controlName'] .
'_' . $value;
1034 $itemAttribs[
'id'] = $id;
1038 Xml::radio( $params[
'controlName'], $value, $checked, $itemAttribs ) .
1040 Xml::tags(
'label', [
'for' => $id ], $this->
parse(
1041 isset( $params[
'itemLabels'] ) ?
1042 wfMessage( $params[
'itemLabels'][$value] )->plain() :
1043 wfMessage( $params[
'itemLabelPrefix'] . strtolower( $value ) )->plain()
1056 if ( !$status->isGood() ) {
1057 $text = $status->getWikiText();
1059 if ( $status->isOK() ) {
1060 $box = Html::warningBox( $text,
'config-warning-box' );
1062 $box = Html::errorBox( $text,
'',
'config-error-box' );
1065 $this->output->addHTML( $box );
1082 foreach ( $varNames as $name ) {
1083 $value = $this->request->getVal( $prefix . $name );
1085 if ( stripos( $name,
'password' ) ===
false ) {
1086 $value = trim( $value );
1088 $newValues[$name] = $value;
1090 if ( $value ===
null ) {
1092 $this->
setVar( $name,
false );
1093 } elseif ( stripos( $name,
'password' ) !==
false ) {
1096 $this->
setVar( $name, $value );
1111 $query = [
'page' => $page ];
1113 if ( in_array( $this->currentPageName, $this->pageSequence ) ) {
1117 return $this->
getUrl( $query );
1129 return Html::rawElement(
'li', [],
1130 Html::element(
'a', [
'href' => $url ], $linkText )
1141 $anchor = Html::rawElement(
'a',
1142 [
'href' => $this->
getUrl( [
'localsettings' => 1 ] ) ],
1146 return Html::rawElement(
'div', [
'class' =>
'config-download-link' ], $anchor );
1171 if ( !empty( $_SERVER[
'PHP_SELF'] ) ) {
1172 $path = $_SERVER[
'PHP_SELF'];
1173 } elseif ( !empty( $_SERVER[
'SCRIPT_NAME'] ) ) {
1174 $path = $_SERVER[
'SCRIPT_NAME'];
1176 if (
$path ===
false ) {
1181 return parent::envCheckPath();
1185 parent::envPrepPath();
1190 if ( !empty( $_SERVER[
'PHP_SELF'] ) ) {
1191 $path = $_SERVER[
'PHP_SELF'];
1192 } elseif ( !empty( $_SERVER[
'SCRIPT_NAME'] ) ) {
1193 $path = $_SERVER[
'SCRIPT_NAME'];
1195 if (
$path !==
false ) {
1196 $scriptPath = preg_replace(
'{^(.*)/(mw-)?config.*$}',
'$1',
$path );
1198 $this->
setVar(
'wgScriptPath',
"$scriptPath" );
1200 $this->
setVar(
'wgScript',
"$scriptPath/index.php" );
1201 $this->
setVar(
'wgLoadScript',
"$scriptPath/load.php" );
1202 $this->
setVar(
'wgStylePath',
"$scriptPath/skins" );
1203 $this->
setVar(
'wgLocalStylePath',
"$scriptPath/skins" );
1204 $this->
setVar(
'wgExtensionAssetsPath',
"$scriptPath/extensions" );
1205 $this->
setVar(
'wgUploadPath',
"$scriptPath/images" );
1206 $this->
setVar(
'wgResourceBasePath',
"$scriptPath" );
1214 return WebRequest::detectServer();
1223 $this->request->response()->header(
'Content-type: application/x-httpd-php' );
1224 $this->request->response()->header(
1225 'Content-Disposition: attachment; filename="LocalSettings.php"'
1229 $rightsProfile = $this->rightsProfiles[$this->
getVar(
'_RightsProfile' )];
1230 foreach ( $rightsProfile as $group => $rightsArr ) {
1231 $ls->setGroupRights( $group, $rightsArr );
1233 echo $ls->getText();
1240 $this->request->response()->header(
'Content-type: text/css' );
1241 echo $this->output->getCSS();
$wgLanguageCode
Site language code.
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.
wfDeprecated( $function, $version=false, $component=false, $callerOffset=2)
Throws a warning that $function is deprecated.
if(! $wgDBerrorLogTZ) $wgRequest
Marks HTML that shouldn't be escaped.
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 provides methods which fulfil two basic services:
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.
startPageWrapper( $currentPageName)
Called by execute() before page output starts, to show a page list.
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.
endPageWrapper()
Output some stuff after a page is finished.
outputLS()
Actually output LocalSettings.php for download.
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.
getWarningBox( $text)
Get HTML for a warning box with an icon.
getPasswordBox( $params)
Get a labelled password box to configure a variable.
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.
bool $showSessionWarning
Flag indicating that session data may have been lost.
getErrorBox( $text)
Get HTML for an error box with an icon.
getPageListItem( $pageName, $enabled, $currentPageName)
Get a list item for the page list.
showStatusMessage(Status $status)
getCheckBox( $params)
Get a labelled checkbox to configure a boolean variable.
getInfoBox( $text, $icon=false, $class=false)
Get HTML for an information message box with an icon.
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...
if(!isset( $args[0])) $lang