154 parent::__construct();
169 if ( isset(
$session[
'settings'] ) ) {
172 foreach ( $this->settings as $key => $val ) {
173 $GLOBALS[$key] = $val;
179 if ( ( $this->
getVar(
'_InstallDone' ) || $this->
getVar(
'_UpgradeDone' ) )
180 && $this->request->getVal(
'localsettings' )
186 $isCSS = $this->request->getCheck(
'css' );
192 $this->happyPages =
$session[
'happyPages'] ?? [];
194 $this->skippedPages =
$session[
'skippedPages'] ?? [];
199 $pageName = $this->request->getVal(
'page',
'' );
201 if ( in_array( $pageName, $this->otherPages ) ) {
207 if ( !$pageName || !in_array( $pageName, $this->pageSequence ) ) {
208 $pageId = $lowestUnhappy;
210 $pageId = array_search( $pageName, $this->pageSequence );
213 # If necessary, move back to the lowest-numbered unhappy page
214 if ( $pageId > $lowestUnhappy ) {
215 $pageId = $lowestUnhappy;
216 if ( $lowestUnhappy == 0 ) {
217 # Knocked back to start, possible loss of session data.
218 $this->showSessionWarning =
true;
222 $pageName = $this->pageSequence[$pageId];
226 # If a back button was submitted, go back without submitting the form data.
227 if ( $this->request->wasPosted() && $this->request->getBool(
'submit-back' ) ) {
228 if ( $this->request->getVal(
'lastPage' ) ) {
229 $nextPage = $this->request->getVal(
'lastPage' );
230 } elseif ( $pageId !==
false ) {
232 # Skip the skipped pages
233 $nextPageId = $pageId;
237 $nextPage = $this->pageSequence[$nextPageId];
238 }
while ( isset( $this->skippedPages[$nextPage] ) );
240 $nextPage = $this->pageSequence[$lowestUnhappy];
243 $this->output->redirect( $this->
getUrl( [
'page' => $nextPage ] ) );
249 $this->currentPageName = $page->getName();
250 $this->startPageWrapper( $pageName );
252 if ( $page->isSlow() ) {
256 $result = $page->execute();
258 $this->endPageWrapper();
260 if ( $result ==
'skip' ) {
261 # Page skipped without explicit submission.
262 # Skip it when we click "back" so that we don't just go forward again.
263 $this->skippedPages[$pageName] =
true;
264 $result =
'continue';
266 unset( $this->skippedPages[$pageName] );
269 # If it was posted, the page can request a continue to the next page.
270 if ( $result ===
'continue' && !$this->output->headerDone() ) {
271 if ( $pageId !==
false ) {
272 $this->happyPages[$pageId] =
true;
277 if ( $this->request->getVal(
'lastPage' ) ) {
278 $nextPage = $this->request->getVal(
'lastPage' );
279 } elseif ( $pageId !==
false ) {
280 $nextPage = $this->pageSequence[$pageId + 1];
282 $nextPage = $this->pageSequence[$lowestUnhappy];
285 if ( array_search( $nextPage, $this->pageSequence ) > $lowestUnhappy ) {
286 $nextPage = $this->pageSequence[$lowestUnhappy];
289 $this->output->redirect( $this->
getUrl( [
'page' => $nextPage ] ) );
300 if ( count( $this->happyPages ) == 0 ) {
303 return max( array_keys( $this->happyPages ) ) + 1;
314 if (
wfIniGetBool(
'session.auto_start' ) || session_id() ) {
321 if ( $this->request->getProtocol() ===
'https' ) {
322 $options[
'cookie_secure'] =
'1';
325 $this->phpErrors = [];
328 session_name(
'mw_installer_session' );
329 session_start( $options );
330 }
catch ( Exception $e ) {
331 restore_error_handler();
334 restore_error_handler();
336 if ( $this->phpErrors ) {
353 $url = $this->request->getFullRequestURL();
354 if ( preg_match(
'!^(.*\?)!',
$url, $m ) ) {
358 if ( preg_match(
'!^(.*)/[^/]*/[^/]*$!',
$url, $m ) ) {
364 return md5( serialize( [
365 'local path' => dirname( __DIR__ ),
372 if ( !( $msg instanceof
Message ) ) {
375 array_map(
'htmlspecialchars', $params )
378 $text = $msg->useDatabase(
false )->parse();
379 $box = Html::errorBox( $text,
'',
'config-error-box' );
380 $this->output->addHTML( $box );
390 $this->phpErrors[] = $errstr;
399 $this->output->output();
413 $this->happyPages = [];
414 $this->settings = [];
425 $url = $this->request->getRequestURL();
426 # Remove existing query
427 $url = preg_replace(
'/\?.*$/',
'',
$url );
443 $pageClass =
'MediaWiki\\Installer\\WebInstaller' . $pageName;
445 return new $pageClass( $this );
457 return $this->session[$name] ?? $default;
467 $this->session[$name] = $value;
476 return $this->tabIndex++;
485 if ( $this->
getSession(
'test' ) ===
null && !$this->request->wasPosted() ) {
489 RequestContext::getMain()->setLanguage(
$wgLang );
490 $this->
setVar(
'wgLanguageCode', $wgLanguageCode );
491 $this->
setVar(
'_UserLang', $wgLanguageCode );
507 ->getLanguageNameUtils()
508 ->getLanguageNames( LanguageNameUtils::AUTONYMS, LanguageNameUtils::SUPPORTED );
509 $headerLanguages = array_keys( $this->request->getAcceptLang() );
511 foreach ( $headerLanguages as $lang ) {
512 if ( isset( $mwLanguages[$lang] ) ) {
526 $s =
"<div class=\"config-page-wrapper\">\n";
527 $s .=
"<div class=\"config-page\">\n";
528 $s .=
"<div class=\"config-page-list cdx-card\"><span class=\"cdx-card__text\">";
529 $s .=
"<span class=\"cdx-card__text__description\"><ul>\n";
532 foreach ( $this->pageSequence as $id => $pageName ) {
533 $happy = !empty( $this->happyPages[$id] );
534 $s .= $this->getPageListItem(
536 $happy || $lastHappy == $id - 1,
545 $s .=
"</ul><br/><ul>\n";
548 $s .=
"</ul></span></span></div>\n";
558 $this->output->addHTMLNoFlush( $s );
571 $s =
"<li class=\"config-page-list-item\">";
578 $name =
wfMessage(
'config-page-' . strtolower( $pageName ) )->text();
581 $query = [
'page' => $pageName ];
583 if ( !in_array( $pageName, $this->pageSequence ) ) {
590 'href' => $this->
getUrl( $query )
595 $link = htmlspecialchars( $name );
599 $s .=
"<span class=\"config-page-current\">$link</span>";
606 'class' =>
'config-page-disabled'
620 private function endPageWrapper() {
621 $this->output->addHTMLNoFlush(
622 "<div class=\"visualClear\"></div>\n" .
624 "<div class=\"visualClear\"></div>\n" .
638 $params = array_map(
'htmlspecialchars', $params );
639 $text =
wfMessage( $msg, $params )->useDatabase(
false )->plain();
640 $html = $this->
parse( $text,
true );
642 return "<div class=\"config-help-field-container\">\n" .
643 "<a class=\"config-help-field-hint\" title=\"" .
644 wfMessage(
'config-help-tooltip' )->escaped() .
"\">ℹ️ " .
645 wfMessage(
'config-help' )->escaped() .
"</a>\n" .
646 "<div class=\"config-help-field-content config-help-field-content-hidden " .
647 "cdx-message cdx-message--block cdx-message--notice\" style=\"margin: 10px\">" .
648 "<div class=\"cdx-message__content\">" . $html .
"</div></div>\n" .
660 HtmlArmor::getHtml( $text ) :
661 $this->
parse( $text,
true );
662 return '<div class="cdx-message cdx-message--block cdx-message--notice">' .
663 '<span class="cdx-message__icon"></span><div class="cdx-message__content">' .
664 '<p><strong>' .
wfMessage(
'config-information' )->escaped() .
'</strong></p>' .
670 $html =
'<div class="cdx-message cdx-message--block cdx-message--success">' .
671 '<span class="cdx-message__icon"></span><div class="cdx-message__content">' .
672 $this->
parse(
wfMessage( $msg, $params )->useDatabase(
false )->plain() ) .
674 $this->output->addHTML( $html );
678 $html =
'<div class="cdx-message cdx-message--block cdx-message--notice">' .
679 '<span class="cdx-message__icon"></span><div class="cdx-message__content">' .
680 $this->
parse(
wfMessage( $msg, $params )->useDatabase(
false )->plain() ) .
682 $this->output->addHTML( $html );
686 $html =
'<div class="cdx-message cdx-message--block cdx-message--warning">' .
687 '<span class="cdx-message__icon"></span><div class="cdx-message__content">' .
688 $this->
parse(
wfMessage( $msg, $params )->useDatabase(
false )->plain() ) .
690 $this->output->addHTML( $html );
695 foreach ( $status->
getMessages(
'error' ) as $msg ) {
698 foreach ( $status->
getMessages(
'warning' ) as $msg ) {
714 public function label( $msg, $forId, $contents, $helpData =
"" ) {
715 if ( strval( $msg ) ==
'' ) {
716 $labelText =
"\u{00A0}";
718 $labelText =
wfMessage( $msg )->escaped();
721 $attributes = [
'class' =>
'config-label' ];
724 $attributes[
'for'] = $forId;
727 return "<div class=\"config-block\">\n" .
728 " <div class=\"config-block-label\">\n" .
729 Html::rawElement(
'label',
735 " <div class=\"config-block-elements\">\n" .
757 if ( !isset( $params[
'controlName'] ) ) {
758 $params[
'controlName'] =
'config_' . $params[
'var'];
761 if ( !isset( $params[
'value'] ) ) {
762 $params[
'value'] = $this->
getVar( $params[
'var'] );
765 if ( !isset( $params[
'attribs'] ) ) {
766 $params[
'attribs'] = [];
768 if ( !isset( $params[
'help'] ) ) {
769 $params[
'help'] =
"";
774 $params[
'controlName'],
775 "<div class=\"cdx-text-input\">" .
777 $params[
'controlName'],
780 $params[
'attribs'] + [
781 'id' => $params[
'controlName'],
783 'class' =>
'cdx-text-input__input',
806 if ( !isset( $params[
'controlName'] ) ) {
807 $params[
'controlName'] =
'config_' . $params[
'var'];
810 if ( !isset( $params[
'value'] ) ) {
811 $params[
'value'] = $this->
getVar( $params[
'var'] );
814 if ( !isset( $params[
'attribs'] ) ) {
815 $params[
'attribs'] = [];
817 if ( !isset( $params[
'help'] ) ) {
818 $params[
'help'] =
"";
823 $params[
'controlName'],
825 $params[
'controlName'],
827 $params[
'attribs'] + [
828 'id' => $params[
'controlName'],
831 'class' =>
'config-input-text',
856 if ( !isset( $params[
'value'] ) ) {
857 $params[
'value'] = $this->
getVar( $params[
'var'] );
860 if ( !isset( $params[
'attribs'] ) ) {
861 $params[
'attribs'] = [];
865 $params[
'attribs'][
'type'] =
'password';
887 if ( !isset( $params[
'controlName'] ) ) {
888 $params[
'controlName'] =
'config_' . $params[
'var'];
891 if ( !isset( $params[
'value'] ) ) {
892 $params[
'value'] = $this->
getVar( $params[
'var'] );
895 if ( !isset( $params[
'attribs'] ) ) {
896 $params[
'attribs'] = [];
898 if ( !isset( $params[
'help'] ) ) {
899 $params[
'help'] =
"";
901 if ( !isset( $params[
'labelAttribs'] ) ) {
902 $params[
'labelAttribs'] = [];
904 $labelText = $params[
'rawtext'] ?? $this->
parse(
wfMessage( $params[
'label'] )->plain() );
905 $labelText =
'<span class="cdx-label__label__text"> ' . $labelText .
'</span>';
906 Html::addClass( $params[
'attribs'][
'class'],
'cdx-checkbox__input' );
907 Html::addClass( $params[
'labelAttribs'][
'class'],
'cdx-label__label' );
909 return "<div class=\"cdx-checkbox\" style=\"margin-top: 12px; margin-bottom: 2px;\">" .
910 "<div class=\"cdx-checkbox__wrapper\">\n" .
912 $params[
'controlName'],
914 $params[
'attribs'] + [
915 'id' => $params[
'controlName'],
919 "<span class=\"cdx-checkbox__icon\"></span>" .
920 "<div class=\"cdx-checkbox__label cdx-label\">" .
923 $params[
'labelAttribs'] + [
924 'for' => $params[
'controlName']
928 "</div></div></div>\n" . $params[
'help'];
954 $label = $params[
'label'] ??
'';
956 if ( !isset( $params[
'controlName'] ) ) {
957 $params[
'controlName'] =
'config_' . $params[
'var'];
960 if ( !isset( $params[
'help'] ) ) {
961 $params[
'help'] =
"";
965 foreach ( $items as $item ) {
969 return $this->
label( $label, $params[
'controlName'], $s, $params[
'help'] );
982 if ( !isset( $params[
'controlName'] ) ) {
983 $params[
'controlName'] =
'config_' . $params[
'var'];
986 if ( !isset( $params[
'value'] ) ) {
987 $params[
'value'] = $this->
getVar( $params[
'var'] );
992 foreach ( $params[
'values'] as $value ) {
995 if ( isset( $params[
'commonAttribs'] ) ) {
996 $itemAttribs = $params[
'commonAttribs'];
999 if ( isset( $params[
'itemAttribs'][$value] ) ) {
1000 $itemAttribs = $params[
'itemAttribs'][$value] + $itemAttribs;
1003 $checked = $value == $params[
'value'];
1004 $id = $params[
'controlName'] .
'_' . $value;
1005 $itemAttribs[
'id'] = $id;
1007 Html::addClass( $itemAttribs[
'class'],
'cdx-radio__input' );
1009 $radioText = $this->
parse(
1010 isset( $params[
'itemLabels'] ) ?
1011 wfMessage( $params[
'itemLabels'][$value] )->plain() :
1012 wfMessage( $params[
'itemLabelPrefix'] . strtolower( $value ) )->plain()
1015 '<span class="cdx-radio">' .
1016 '<span class="cdx-radio__wrapper">' .
1017 Html::radio( $params[
'controlName'], $checked, $itemAttribs + [
'value' => $value ] ) .
1018 '<span class="cdx-radio__icon"></span>' .
1019 '<span class="cdx-radio__label cdx-label">' .
1022 [
'for' => $id,
'class' =>
'cdx-label__label' ],
1023 '<span class="cdx-label__label__text">' . $radioText .
'</span>'
1024 ) .
'</span></span></span>';
1036 if ( !$status->isGood() ) {
1037 $html = $status->getHTML();
1039 if ( $status->isOK() ) {
1040 $box = Html::warningBox( $html,
'config-warning-box' );
1042 $box = Html::errorBox( $html,
'',
'config-error-box' );
1045 $this->output->addHTML( $box );
1062 foreach ( $varNames as $name ) {
1063 $value = $this->request->getVal( $prefix . $name );
1065 if ( $value !==
null && stripos( $name,
'password' ) ===
false ) {
1066 $value = trim( $value );
1068 $newValues[$name] = $value;
1070 if ( $value ===
null ) {
1072 $this->
setVar( $name,
false );
1073 } elseif ( stripos( $name,
'password' ) !==
false ) {
1076 $this->
setVar( $name, $value );
1091 $query = [
'page' => $page ];
1093 if ( in_array( $this->currentPageName, $this->pageSequence ) ) {
1097 return $this->
getUrl( $query );
1109 return Html::rawElement(
'li', [],
1136 if ( !empty( $_SERVER[
'PHP_SELF'] ) ) {
1137 $path = $_SERVER[
'PHP_SELF'];
1138 } elseif ( !empty( $_SERVER[
'SCRIPT_NAME'] ) ) {
1139 $path = $_SERVER[
'SCRIPT_NAME'];
1141 if (
$path ===
false ) {
1146 return parent::envCheckPath();
1154 if ( !empty( $_SERVER[
'PHP_SELF'] ) ) {
1155 $path = $_SERVER[
'PHP_SELF'];
1156 } elseif ( !empty( $_SERVER[
'SCRIPT_NAME'] ) ) {
1157 $path = $_SERVER[
'SCRIPT_NAME'];
1159 if (
$path !==
false ) {
1160 $scriptPath = preg_replace(
'{^(.*)/(mw-)?config.*$}',
'$1',
$path );
1163 'wgScriptPath' =>
"$scriptPath",
1165 'wgScript' =>
"$scriptPath/index.php",
1166 'wgLoadScript' =>
"$scriptPath/load.php",
1167 'wgStylePath' =>
"$scriptPath/skins",
1168 'wgLocalStylePath' =>
"$scriptPath/skins",
1169 'wgExtensionAssetsPath' =>
"$scriptPath/extensions",
1170 'wgUploadPath' =>
"$scriptPath/images",
1171 'wgResourceBasePath' =>
"$scriptPath",
1181 $assumeProxiesUseDefaultProtocolPorts =
1182 $this->
getVar(
'wgAssumeProxiesUseDefaultProtocolPorts' );
1184 return WebRequest::detectServer( $assumeProxiesUseDefaultProtocolPorts );
1197 private function outputLS() {
1198 $this->request->response()->header(
'Content-type: application/x-httpd-php' );
1199 $this->request->response()->header(
1200 'Content-Disposition: attachment; filename="LocalSettings.php"'
1204 $rightsProfile = $this->rightsProfiles[$this->
getVar(
'_RightsProfile' )];
1205 foreach ( $rightsProfile as $group => $rightsArr ) {
1206 $ls->setGroupRights( $group, $rightsArr );
1208 echo $ls->getText();
1215 $this->request->response()->header(
'Content-type: text/css' );
1216 echo $this->output->getCSS();
1243 $dbInstaller->preUpgrade();
1247 $taskFactory->registerWebUpgradeTasks( $taskList );
1248 $taskRunner =
new TaskRunner( $taskList, $taskFactory, TaskFactory::PROFILE_WEB_UPGRADE );
1252 $status = $taskRunner->execute();
1253 $ret = $status->isOK();
1255 $this->
setVar(
'_UpgradeDone',
true );
1256 }
catch ( Exception $e ) {
1258 echo
"\nAn error occurred:\n";
1259 echo $e->getMessage();
1268 return htmlspecialchars( $string );
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') &&MW_ENTRY_POINT !=='cli' $wgLang
Group all the pieces relevant to the context of a request into one instance.
getMessages(?string $type=null)
Returns a list of error messages, optionally only those of the given type.
$wgLanguageCode
Config variable stub for the LanguageCode setting, for use by phpdoc and IDEs.