MediaWiki master
WebInstaller.php
Go to the documentation of this file.
1<?php
24namespace MediaWiki\Installer;
25
26use Exception;
27use HtmlArmor;
35use Xml;
36
43class WebInstaller extends Installer {
44
48 public $output;
49
55 public $request;
56
62 protected $session;
63
69 protected $phpErrors;
70
81 public $pageSequence = [
82 'Language',
83 'ExistingWiki',
84 'Welcome',
85 'DBConnect',
86 'Upgrade',
87 'DBSettings',
88 'Name',
89 'Options',
90 'Install',
91 'Complete',
92 ];
93
99 protected $otherPages = [
100 'Restart',
101 'ReleaseNotes',
102 'Copying',
103 'UpgradeDoc', // Can't use Upgrade due to Upgrade step
104 ];
105
112 protected $happyPages;
113
121 protected $skippedPages;
122
128 public $showSessionWarning = false;
129
135 protected $tabIndex = 1;
136
142 protected $helpBoxId = 1;
143
150
154 public function __construct( WebRequest $request ) {
155 parent::__construct();
156 $this->output = new WebInstallerOutput( $this );
157 $this->request = $request;
158 }
159
167 public function execute( array $session ) {
168 $this->session = $session;
169
170 if ( isset( $session['settings'] ) ) {
171 $this->settings = $session['settings'] + $this->settings;
172 // T187586 MediaWikiServices works with globals
173 foreach ( $this->settings as $key => $val ) {
174 $GLOBALS[$key] = $val;
175 }
176 }
177
178 $this->setupLanguage();
179
180 if ( ( $this->getVar( '_InstallDone' ) || $this->getVar( '_UpgradeDone' ) )
181 && $this->request->getVal( 'localsettings' )
182 ) {
183 $this->outputLS();
184 return $this->session;
185 }
186
187 $isCSS = $this->request->getVal( 'css' );
188 if ( $isCSS ) {
189 $this->outputCss();
190 return $this->session;
191 }
192
193 $this->happyPages = $session['happyPages'] ?? [];
194
195 $this->skippedPages = $session['skippedPages'] ?? [];
196
197 $lowestUnhappy = $this->getLowestUnhappy();
198
199 # Get the page name.
200 $pageName = $this->request->getVal( 'page', '' );
201
202 if ( in_array( $pageName, $this->otherPages ) ) {
203 # Out of sequence
204 $pageId = false;
205 $page = $this->getPageByName( $pageName );
206 } else {
207 # Main sequence
208 if ( !$pageName || !in_array( $pageName, $this->pageSequence ) ) {
209 $pageId = $lowestUnhappy;
210 } else {
211 $pageId = array_search( $pageName, $this->pageSequence );
212 }
213
214 # If necessary, move back to the lowest-numbered unhappy page
215 if ( $pageId > $lowestUnhappy ) {
216 $pageId = $lowestUnhappy;
217 if ( $lowestUnhappy == 0 ) {
218 # Knocked back to start, possible loss of session data.
219 $this->showSessionWarning = true;
220 }
221 }
222
223 $pageName = $this->pageSequence[$pageId];
224 $page = $this->getPageByName( $pageName );
225 }
226
227 # If a back button was submitted, go back without submitting the form data.
228 if ( $this->request->wasPosted() && $this->request->getBool( 'submit-back' ) ) {
229 if ( $this->request->getVal( 'lastPage' ) ) {
230 $nextPage = $this->request->getVal( 'lastPage' );
231 } elseif ( $pageId !== false ) {
232 # Main sequence page
233 # Skip the skipped pages
234 $nextPageId = $pageId;
235
236 do {
237 $nextPageId--;
238 $nextPage = $this->pageSequence[$nextPageId];
239 } while ( isset( $this->skippedPages[$nextPage] ) );
240 } else {
241 $nextPage = $this->pageSequence[$lowestUnhappy];
242 }
243
244 $this->output->redirect( $this->getUrl( [ 'page' => $nextPage ] ) );
245
246 return $this->finish();
247 }
248
249 # Execute the page.
250 $this->currentPageName = $page->getName();
251 $this->startPageWrapper( $pageName );
252
253 if ( $page->isSlow() ) {
254 $this->disableTimeLimit();
255 }
256
257 $result = $page->execute();
258
259 $this->endPageWrapper();
260
261 if ( $result == 'skip' ) {
262 # Page skipped without explicit submission.
263 # Skip it when we click "back" so that we don't just go forward again.
264 $this->skippedPages[$pageName] = true;
265 $result = 'continue';
266 } else {
267 unset( $this->skippedPages[$pageName] );
268 }
269
270 # If it was posted, the page can request a continue to the next page.
271 if ( $result === 'continue' && !$this->output->headerDone() ) {
272 if ( $pageId !== false ) {
273 $this->happyPages[$pageId] = true;
274 }
275
276 $lowestUnhappy = $this->getLowestUnhappy();
277
278 if ( $this->request->getVal( 'lastPage' ) ) {
279 $nextPage = $this->request->getVal( 'lastPage' );
280 } elseif ( $pageId !== false ) {
281 $nextPage = $this->pageSequence[$pageId + 1];
282 } else {
283 $nextPage = $this->pageSequence[$lowestUnhappy];
284 }
285
286 if ( array_search( $nextPage, $this->pageSequence ) > $lowestUnhappy ) {
287 $nextPage = $this->pageSequence[$lowestUnhappy];
288 }
289
290 $this->output->redirect( $this->getUrl( [ 'page' => $nextPage ] ) );
291 }
292
293 return $this->finish();
294 }
295
300 public function getLowestUnhappy() {
301 if ( count( $this->happyPages ) == 0 ) {
302 return 0;
303 } else {
304 return max( array_keys( $this->happyPages ) ) + 1;
305 }
306 }
307
314 public function startSession() {
315 if ( wfIniGetBool( 'session.auto_start' ) || session_id() ) {
316 // Done already
317 return true;
318 }
319
320 // Use secure cookies if we are on HTTPS
321 $options = [];
322 if ( $this->request->getProtocol() === 'https' ) {
323 $options['cookie_secure'] = '1';
324 }
325
326 $this->phpErrors = [];
327 set_error_handler( [ $this, 'errorHandler' ] );
328 try {
329 session_name( 'mw_installer_session' );
330 session_start( $options );
331 } catch ( Exception $e ) {
332 restore_error_handler();
333 throw $e;
334 }
335 restore_error_handler();
336
337 if ( $this->phpErrors ) {
338 return false;
339 }
340
341 return true;
342 }
343
352 public function getFingerprint() {
353 // Get the base URL of the installation
354 $url = $this->request->getFullRequestURL();
355 if ( preg_match( '!^(.*\?)!', $url, $m ) ) {
356 // Trim query string
357 $url = $m[1];
358 }
359 if ( preg_match( '!^(.*)/[^/]*/[^/]*$!', $url, $m ) ) {
360 // This... seems to try to get the base path from
361 // the /mw-config/index.php. Kinda scary though?
362 $url = $m[1];
363 }
364
365 return md5( serialize( [
366 'local path' => dirname( __DIR__ ),
367 'url' => $url,
368 'version' => MW_VERSION
369 ] ) );
370 }
371
372 public function showError( $msg, ...$params ) {
373 if ( !( $msg instanceof Message ) ) {
374 $msg = wfMessage(
375 $msg,
376 array_map( 'htmlspecialchars', $params )
377 );
378 }
379 $text = $msg->useDatabase( false )->parse();
380 $box = Html::errorBox( $text, '', 'config-error-box' );
381 $this->output->addHTML( $box );
382 }
383
390 public function errorHandler( $errno, $errstr ) {
391 $this->phpErrors[] = $errstr;
392 }
393
399 public function finish() {
400 $this->output->output();
401
402 $this->session['happyPages'] = $this->happyPages;
403 $this->session['skippedPages'] = $this->skippedPages;
404 $this->session['settings'] = $this->settings;
405
406 return $this->session;
407 }
408
412 public function reset() {
413 $this->session = [];
414 $this->happyPages = [];
415 $this->settings = [];
416 }
417
425 public function getUrl( $query = [] ) {
426 $url = $this->request->getRequestURL();
427 # Remove existing query
428 $url = preg_replace( '/\?.*$/', '', $url );
429
430 if ( $query ) {
431 $url .= '?' . wfArrayToCgi( $query );
432 }
433
434 return $url;
435 }
436
443 public function getPageByName( $pageName ) {
444 $pageClass = 'MediaWiki\\Installer\\WebInstaller' . $pageName;
445
446 return new $pageClass( $this );
447 }
448
457 public function getSession( $name, $default = null ) {
458 return $this->session[$name] ?? $default;
459 }
460
467 public function setSession( $name, $value ) {
468 $this->session[$name] = $value;
469 }
470
476 public function nextTabIndex() {
477 return $this->tabIndex++;
478 }
479
483 public function setupLanguage() {
484 global $wgLang, $wgLanguageCode;
485
486 if ( $this->getSession( 'test' ) === null && !$this->request->wasPosted() ) {
488 $wgLang = MediaWikiServices::getInstance()->getLanguageFactory()
489 ->getLanguage( $wgLanguageCode );
490 RequestContext::getMain()->setLanguage( $wgLang );
491 $this->setVar( 'wgLanguageCode', $wgLanguageCode );
492 $this->setVar( '_UserLang', $wgLanguageCode );
493 } else {
494 $wgLanguageCode = $this->getVar( 'wgLanguageCode' );
495 }
496 }
497
504 public function getAcceptLanguage() {
506
507 $mwLanguages = MediaWikiServices::getInstance()
508 ->getLanguageNameUtils()
509 ->getLanguageNames( LanguageNameUtils::AUTONYMS, LanguageNameUtils::SUPPORTED );
510 $headerLanguages = array_keys( $wgRequest->getAcceptLang() );
511
512 foreach ( $headerLanguages as $lang ) {
513 if ( isset( $mwLanguages[$lang] ) ) {
514 return $lang;
515 }
516 }
517
518 return $wgLanguageCode;
519 }
520
526 private function startPageWrapper( $currentPageName ) {
527 $s = "<div class=\"config-page-wrapper\">\n";
528 $s .= "<div class=\"config-page\">\n";
529 $s .= "<div class=\"config-page-list cdx-card\"><span class=\"cdx-card__text\">";
530 $s .= "<span class=\"cdx-card__text__description\"><ul>\n";
531 $lastHappy = -1;
532
533 foreach ( $this->pageSequence as $id => $pageName ) {
534 $happy = !empty( $this->happyPages[$id] );
535 $s .= $this->getPageListItem(
536 $pageName,
537 $happy || $lastHappy == $id - 1,
539 );
540
541 if ( $happy ) {
542 $lastHappy = $id;
543 }
544 }
545
546 $s .= "</ul><br/><ul>\n";
547 $s .= $this->getPageListItem( 'Restart', true, $currentPageName );
548 // End list pane
549 $s .= "</ul></span></span></div>\n";
550
551 // Messages:
552 // config-page-language, config-page-welcome, config-page-dbconnect, config-page-upgrade,
553 // config-page-dbsettings, config-page-name, config-page-options, config-page-install,
554 // config-page-complete, config-page-restart, config-page-releasenotes,
555 // config-page-copying, config-page-upgradedoc, config-page-existingwiki
556 $s .= Html::element( 'h2', [],
557 wfMessage( 'config-page-' . strtolower( $currentPageName ) )->text() );
558
559 $this->output->addHTMLNoFlush( $s );
560 }
561
571 private function getPageListItem( $pageName, $enabled, $currentPageName ) {
572 $s = "<li class=\"config-page-list-item\">";
573
574 // Messages:
575 // config-page-language, config-page-welcome, config-page-dbconnect, config-page-upgrade,
576 // config-page-dbsettings, config-page-name, config-page-options, config-page-install,
577 // config-page-complete, config-page-restart, config-page-releasenotes,
578 // config-page-copying, config-page-upgradedoc, config-page-existingwiki
579 $name = wfMessage( 'config-page-' . strtolower( $pageName ) )->text();
580
581 if ( $enabled ) {
582 $query = [ 'page' => $pageName ];
583
584 if ( !in_array( $pageName, $this->pageSequence ) ) {
585 if ( in_array( $currentPageName, $this->pageSequence ) ) {
586 $query['lastPage'] = $currentPageName;
587 }
588
589 $link = Html::element( 'a',
590 [
591 'href' => $this->getUrl( $query )
592 ],
593 $name
594 );
595 } else {
596 $link = htmlspecialchars( $name );
597 }
598
599 if ( $pageName == $currentPageName ) {
600 $s .= "<span class=\"config-page-current\">$link</span>";
601 } else {
602 $s .= $link;
603 }
604 } else {
605 $s .= Html::element( 'span',
606 [
607 'class' => 'config-page-disabled'
608 ],
609 $name
610 );
611 }
612
613 $s .= "</li>\n";
614
615 return $s;
616 }
617
621 private function endPageWrapper() {
622 $this->output->addHTMLNoFlush(
623 "<div class=\"visualClear\"></div>\n" .
624 "</div>\n" .
625 "<div class=\"visualClear\"></div>\n" .
626 "</div>" );
627 }
628
637 public function getInfoBox( $text, $icon = false, $class = '' ) {
638 $html = ( $text instanceof HtmlArmor ) ?
639 HtmlArmor::getHtml( $text ) :
640 $this->parse( $text, true );
641 $alt = wfMessage( 'config-information' )->text();
642
643 return self::infoBox( $html, '', $alt, $class );
644 }
645
655 public function getHelpBox( $msg, ...$args ) {
656 $args = array_map( 'htmlspecialchars', $args );
657 $text = wfMessage( $msg, $args )->useDatabase( false )->plain();
658 $html = $this->parse( $text, true );
659
660 return "<div class=\"config-help-field-container\">\n" .
661 "<a class=\"config-help-field-hint\" title=\"" .
662 wfMessage( 'config-help-tooltip' )->escaped() . "\">ℹ️ " .
663 wfMessage( 'config-help' )->escaped() . "</a>\n" .
664 "<div class=\"config-help-field-content config-help-field-content-hidden " .
665 "cdx-message cdx-message--block cdx-message--notice\" style=\"margin: 10px\">" .
666 "<div class=\"cdx-message__content\">" . $html . "</div></div>\n" .
667 "</div>\n";
668 }
669
675 public function showHelpBox( $msg, ...$params ) {
676 $html = $this->getHelpBox( $msg, ...$params );
677 $this->output->addHTML( $html );
678 }
679
680 public function showMessage( $msg, ...$params ) {
681 $html = '<div class="cdx-message cdx-message--block cdx-message--notice">' .
682 '<span class="cdx-message__icon"></span><div class="cdx-message__content">' .
683 $this->parse( wfMessage( $msg, $params )->useDatabase( false )->plain() ) .
684 "</div></div>\n";
685 $this->output->addHTML( $html );
686 }
687
688 public function showStatusMessage( Status $status ) {
689 $errors = array_merge( $status->getErrorsArray(), $status->getWarningsArray() );
690 foreach ( $errors as $error ) {
691 $this->showMessage( ...$error );
692 }
693 }
694
706 public function label( $msg, $forId, $contents, $helpData = "" ) {
707 if ( strval( $msg ) == '' ) {
708 $labelText = "\u{00A0}";
709 } else {
710 $labelText = wfMessage( $msg )->escaped();
711 }
712
713 $attributes = [ 'class' => 'config-label' ];
714
715 if ( $forId ) {
716 $attributes['for'] = $forId;
717 }
718
719 return "<div class=\"config-block\">\n" .
720 " <div class=\"config-block-label\">\n" .
721 Xml::tags( 'label',
722 $attributes,
723 $labelText
724 ) . "\n" .
725 $helpData .
726 " </div>\n" .
727 " <div class=\"config-block-elements\">\n" .
728 $contents .
729 " </div>\n" .
730 "</div>\n";
731 }
732
748 public function getTextBox( $params ) {
749 if ( !isset( $params['controlName'] ) ) {
750 $params['controlName'] = 'config_' . $params['var'];
751 }
752
753 if ( !isset( $params['value'] ) ) {
754 $params['value'] = $this->getVar( $params['var'] );
755 }
756
757 if ( !isset( $params['attribs'] ) ) {
758 $params['attribs'] = [];
759 }
760 if ( !isset( $params['help'] ) ) {
761 $params['help'] = "";
762 }
763
764 return $this->label(
765 $params['label'],
766 $params['controlName'],
767 "<div class=\"cdx-text-input\">" .
768 Xml::input(
769 $params['controlName'],
770 30, // intended to be overridden by CSS
771 $params['value'],
772 $params['attribs'] + [
773 'id' => $params['controlName'],
774 'class' => 'cdx-text-input__input',
775 'tabindex' => $this->nextTabIndex()
776 ]
777 ) . "</div>",
778 $params['help']
779 );
780 }
781
796 public function getTextArea( $params ) {
797 if ( !isset( $params['controlName'] ) ) {
798 $params['controlName'] = 'config_' . $params['var'];
799 }
800
801 if ( !isset( $params['value'] ) ) {
802 $params['value'] = $this->getVar( $params['var'] );
803 }
804
805 if ( !isset( $params['attribs'] ) ) {
806 $params['attribs'] = [];
807 }
808 if ( !isset( $params['help'] ) ) {
809 $params['help'] = "";
810 }
811
812 return $this->label(
813 $params['label'],
814 $params['controlName'],
815 Xml::textarea(
816 $params['controlName'],
817 $params['value'],
818 30,
819 5,
820 $params['attribs'] + [
821 'id' => $params['controlName'],
822 'class' => 'config-input-text',
823 'tabindex' => $this->nextTabIndex()
824 ]
825 ),
826 $params['help']
827 );
828 }
829
846 public function getPasswordBox( $params ) {
847 if ( !isset( $params['value'] ) ) {
848 $params['value'] = $this->getVar( $params['var'] );
849 }
850
851 if ( !isset( $params['attribs'] ) ) {
852 $params['attribs'] = [];
853 }
854
855 $params['value'] = $this->getFakePassword( $params['value'] );
856 $params['attribs']['type'] = 'password';
857
858 return $this->getTextBox( $params );
859 }
860
868 private static function addClassAttrib( &$attribs, $class ) {
869 if ( isset( $attribs['class'] ) ) {
870 $attribs['class'] .= ' ' . $class;
871 } else {
872 $attribs['class'] = $class;
873 }
874 }
875
892 public function getCheckBox( $params ) {
893 if ( !isset( $params['controlName'] ) ) {
894 $params['controlName'] = 'config_' . $params['var'];
895 }
896
897 if ( !isset( $params['value'] ) ) {
898 $params['value'] = $this->getVar( $params['var'] );
899 }
900
901 if ( !isset( $params['attribs'] ) ) {
902 $params['attribs'] = [];
903 }
904 if ( !isset( $params['help'] ) ) {
905 $params['help'] = "";
906 }
907 if ( !isset( $params['labelAttribs'] ) ) {
908 $params['labelAttribs'] = [];
909 }
910 $labelText = $params['rawtext'] ?? $this->parse( wfMessage( $params['label'] )->plain() );
911 self::addClassAttrib( $params['attribs'], 'cdx-checkbox__input' );
912 self::addClassAttrib( $params['labelAttribs'], 'cdx-checkbox__label' );
913
914 return "<div class=\"cdx-checkbox\" style=\"margin-top: 12px; margin-bottom: 2px;\">\n" .
915 Xml::check(
916 $params['controlName'],
917 $params['value'],
918 $params['attribs'] + [
919 'id' => $params['controlName'],
920 'tabindex' => $this->nextTabIndex()
921 ]
922 ) .
923 "<span class=\"cdx-checkbox__icon\"></span>" .
924 Html::rawElement(
925 'label',
926 $params['labelAttribs'] + [
927 'for' => $params['controlName']
928 ],
929 $labelText
930 ) .
931 "</div>\n" . $params['help'];
932 }
933
954 public function getRadioSet( $params ) {
955 $items = $this->getRadioElements( $params );
956
957 $label = $params['label'] ?? '';
958
959 if ( !isset( $params['controlName'] ) ) {
960 $params['controlName'] = 'config_' . $params['var'];
961 }
962
963 if ( !isset( $params['help'] ) ) {
964 $params['help'] = "";
965 }
966
967 $s = "";
968 foreach ( $items as $item ) {
969 $s .= "$item\n";
970 }
971
972 return $this->label( $label, $params['controlName'], $s, $params['help'] );
973 }
974
984 public function getRadioElements( $params ) {
985 if ( !isset( $params['controlName'] ) ) {
986 $params['controlName'] = 'config_' . $params['var'];
987 }
988
989 if ( !isset( $params['value'] ) ) {
990 $params['value'] = $this->getVar( $params['var'] );
991 }
992
993 $items = [];
994
995 foreach ( $params['values'] as $value ) {
996 $itemAttribs = [];
997
998 if ( isset( $params['commonAttribs'] ) ) {
999 $itemAttribs = $params['commonAttribs'];
1000 }
1001
1002 if ( isset( $params['itemAttribs'][$value] ) ) {
1003 $itemAttribs = $params['itemAttribs'][$value] + $itemAttribs;
1004 }
1005
1006 $checked = $value == $params['value'];
1007 $id = $params['controlName'] . '_' . $value;
1008 $itemAttribs['id'] = $id;
1009 $itemAttribs['tabindex'] = $this->nextTabIndex();
1010 self::addClassAttrib( $itemAttribs, 'cdx-radio__input' );
1011
1012 $items[$value] =
1013 '<span class="cdx-radio">' .
1014 Xml::radio( $params['controlName'], $value, $checked, $itemAttribs ) .
1015 "<span class=\"cdx-radio__icon\"></span>\u{00A0}" .
1016 Xml::tags( 'label', [ 'for' => $id, 'class' => 'cdx-radio__label' ], $this->parse(
1017 isset( $params['itemLabels'] ) ?
1018 wfMessage( $params['itemLabels'][$value] )->plain() :
1019 wfMessage( $params['itemLabelPrefix'] . strtolower( $value ) )->plain()
1020 ) ) . '</span>';
1021 }
1022
1023 return $items;
1024 }
1025
1031 public function showStatusBox( $status ) {
1032 if ( !$status->isGood() ) {
1033 $html = $status->getHTML();
1034
1035 if ( $status->isOK() ) {
1036 $box = Html::warningBox( $html, 'config-warning-box' );
1037 } else {
1038 $box = Html::errorBox( $html, '', 'config-error-box' );
1039 }
1040
1041 $this->output->addHTML( $box );
1042 }
1043 }
1044
1055 public function setVarsFromRequest( $varNames, $prefix = 'config_' ) {
1056 $newValues = [];
1057
1058 foreach ( $varNames as $name ) {
1059 $value = $this->request->getVal( $prefix . $name );
1060 // T32524, do not trim passwords
1061 if ( $value !== null && stripos( $name, 'password' ) === false ) {
1062 $value = trim( $value );
1063 }
1064 $newValues[$name] = $value;
1065
1066 if ( $value === null ) {
1067 // Checkbox?
1068 $this->setVar( $name, false );
1069 } elseif ( stripos( $name, 'password' ) !== false ) {
1070 $this->setPassword( $name, $value );
1071 } else {
1072 $this->setVar( $name, $value );
1073 }
1074 }
1075
1076 return $newValues;
1077 }
1078
1086 public function getDocUrl( $page ) {
1087 $query = [ 'page' => $page ];
1088
1089 if ( in_array( $this->currentPageName, $this->pageSequence ) ) {
1090 $query['lastPage'] = $this->currentPageName;
1091 }
1092
1093 return $this->getUrl( $query );
1094 }
1095
1104 public function makeLinkItem( $url, $linkText ) {
1105 return Html::rawElement( 'li', [],
1106 Html::element( 'a', [ 'href' => $url ], $linkText )
1107 );
1108 }
1109
1116 public function makeDownloadLinkHtml() {
1117 $anchor = Html::rawElement( 'a',
1118 [ 'href' => $this->getUrl( [ 'localsettings' => 1 ] ) ],
1119 wfMessage( 'config-download-localsettings' )->parse()
1120 );
1121
1122 return Html::rawElement( 'div', [ 'class' => 'config-download-link' ], $anchor );
1123 }
1124
1135 public function getLocalSettingsLocation() {
1136 return false;
1137 }
1138
1142 public function envCheckPath() {
1143 // PHP_SELF isn't available sometimes, such as when PHP is CGI but
1144 // cgi.fix_pathinfo is disabled. In that case, fall back to SCRIPT_NAME
1145 // to get the path to the current script... hopefully it's reliable. SIGH
1146 $path = false;
1147 if ( !empty( $_SERVER['PHP_SELF'] ) ) {
1148 $path = $_SERVER['PHP_SELF'];
1149 } elseif ( !empty( $_SERVER['SCRIPT_NAME'] ) ) {
1150 $path = $_SERVER['SCRIPT_NAME'];
1151 }
1152 if ( $path === false ) {
1153 $this->showError( 'config-no-uri' );
1154 return false;
1155 }
1156
1157 return parent::envCheckPath();
1158 }
1159
1160 public function envPrepPath() {
1161 parent::envPrepPath();
1162 // PHP_SELF isn't available sometimes, such as when PHP is CGI but
1163 // cgi.fix_pathinfo is disabled. In that case, fall back to SCRIPT_NAME
1164 // to get the path to the current script... hopefully it's reliable. SIGH
1165 $path = false;
1166 if ( !empty( $_SERVER['PHP_SELF'] ) ) {
1167 $path = $_SERVER['PHP_SELF'];
1168 } elseif ( !empty( $_SERVER['SCRIPT_NAME'] ) ) {
1169 $path = $_SERVER['SCRIPT_NAME'];
1170 }
1171 if ( $path !== false ) {
1172 $scriptPath = preg_replace( '{^(.*)/(mw-)?config.*$}', '$1', $path );
1173
1174 $this->setVar( 'wgScriptPath', "$scriptPath" );
1175 // Update variables set from Setup.php that are derived from wgScriptPath
1176 $this->setVar( 'wgScript', "$scriptPath/index.php" );
1177 $this->setVar( 'wgLoadScript', "$scriptPath/load.php" );
1178 $this->setVar( 'wgStylePath', "$scriptPath/skins" );
1179 $this->setVar( 'wgLocalStylePath', "$scriptPath/skins" );
1180 $this->setVar( 'wgExtensionAssetsPath', "$scriptPath/extensions" );
1181 $this->setVar( 'wgUploadPath', "$scriptPath/images" );
1182 $this->setVar( 'wgResourceBasePath', "$scriptPath" );
1183 }
1184 }
1185
1189 protected function envGetDefaultServer() {
1190 $assumeProxiesUseDefaultProtocolPorts =
1191 $this->getVar( 'wgAssumeProxiesUseDefaultProtocolPorts' );
1192
1193 return WebRequest::detectServer( $assumeProxiesUseDefaultProtocolPorts );
1194 }
1195
1199 private function outputLS() {
1200 $this->request->response()->header( 'Content-type: application/x-httpd-php' );
1201 $this->request->response()->header(
1202 'Content-Disposition: attachment; filename="LocalSettings.php"'
1203 );
1204
1206 $rightsProfile = $this->rightsProfiles[$this->getVar( '_RightsProfile' )];
1207 foreach ( $rightsProfile as $group => $rightsArr ) {
1208 $ls->setGroupRights( $group, $rightsArr );
1209 }
1210 echo $ls->getText();
1211 }
1212
1216 public function outputCss() {
1217 $this->request->response()->header( 'Content-type: text/css' );
1218 echo $this->output->getCSS();
1219 }
1220
1224 public function getPhpErrors() {
1225 return $this->phpErrors;
1226 }
1227
1238 protected static function infoBox( $rawHtml, $icon, $alt, $class = '' ) {
1239 $s = Html::openElement( 'div', [ 'class' => 'mw-installer-box-left' ] ) .
1240 Html::element( 'img',
1241 [
1242 'src' => $icon,
1243 'alt' => $alt,
1244 ]
1245 ) .
1246 Html::closeElement( 'div' ) .
1247 Html::openElement( 'div', [ 'class' => 'mw-installer-box-right' ] ) .
1248 $rawHtml .
1249 Html::closeElement( 'div' ) .
1250 Html::element( 'div', [ 'style' => 'clear: left;' ], ' ' );
1251
1252 return Html::warningBox( $s, $class )
1253 . Html::element( 'div', [ 'style' => 'clear: left;' ], ' ' );
1254 }
1255
1256}
const MW_VERSION
The running version of MediaWiki.
Definition Defines.php:36
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.
global $wgRequest
Definition Setup.php:415
if(!defined( 'MW_NO_SESSION') &&MW_ENTRY_POINT !=='cli' $wgLang
Definition Setup.php:536
array $params
The job parameters.
Marks HTML that shouldn't be escaped.
Definition HtmlArmor.php:30
Group all the pieces relevant to the context of a request into one instance.
This class is a collection of static functions that serve two purposes:
Definition Html.php:56
static getLocalSettingsGenerator(Installer $installer)
Instantiates and returns an instance of LocalSettingsGenerator or its descendant classes.
Base installer class.
Definition Installer.php:90
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...
parse( $text, $lineStart=false)
Convert wikitext $text to HTML.
getVar( $name, $default=null)
Get an MW configuration variable, or internal installer configuration variable.
Output class modelled on OutputPage.
Class for the core installer web interface.
makeDownloadLinkHtml()
Helper for "Download LocalSettings" link.
envPrepPath()
Environment prep for setting $IP and $wgScriptPath.
getHelpBox( $msg,... $args)
Get small text indented help for a preceding form field.
int $tabIndex
Numeric index of the page we're on.
string[] $otherPages
Out of sequence pages, selectable by the user at any time.
getPageByName( $pageName)
Get a WebInstallerPage by name.
getLocalSettingsLocation()
If the software package wants the LocalSettings.php file to be placed in a specific location,...
errorHandler( $errno, $errstr)
Temporary error handler for session start debugging.
outputCss()
Output stylesheet for web installer pages.
showStatusMessage(Status $status)
Show a message to the installing user by using a Status object.
string $currentPageName
Name of the page we're on.
array[] $session
Cached session array.
getUrl( $query=[])
Get a URL for submission back to the same script.
getFingerprint()
Get a hash of data identifying this MW installation.
makeLinkItem( $url, $linkText)
Helper for sidebar links.
string[] $pageSequence
The main sequence of page names.
static infoBox( $rawHtml, $icon, $alt, $class='')
Get HTML for an information message box with an icon.
getTextArea( $params)
Get a labelled textarea to configure a variable.
setupLanguage()
Initializes language-related variables.
getInfoBox( $text, $icon=false, $class='')
Get HTML for an information message box with an icon.
reset()
We're restarting the installation, reset the session, happyPages, etc.
getRadioSet( $params)
Get a set of labelled radio buttons.
showHelpBox( $msg,... $params)
Output a help box.
setSession( $name, $value)
Set a session variable.
getSession( $name, $default=null)
Get a session variable.
finish()
Clean up from execute()
label( $msg, $forId, $contents, $helpData="")
Label a control by wrapping a config-input div around it and putting a label before it.
startSession()
Start the PHP session.
__construct(WebRequest $request)
getRadioElements( $params)
Get a set of labelled radio buttons.
setVarsFromRequest( $varNames, $prefix='config_')
Convenience function to set variables based on form data.
getPasswordBox( $params)
Get a labelled password box to configure a variable.
getTextBox( $params)
Get a labelled text box to configure a variable.
bool $showSessionWarning
Flag indicating that session data may have been lost.
execute(array $session)
Main entry point.
int $helpBoxId
Numeric index of the help box.
getDocUrl( $page)
Helper for WebInstallerOutput.
bool[] $skippedPages
List of "skipped" pages.
showStatusBox( $status)
Output an error or warning box using a Status object.
WebRequest $request
WebRequest object.
getAcceptLanguage()
Retrieves MediaWiki language from Accept-Language HTTP header.
string[] $phpErrors
Captured PHP error text.
getCheckBox( $params)
Get a labelled checkbox to configure a boolean variable.
bool[] $happyPages
Array of pages which have declared that they have been submitted, have validated their input,...
showMessage( $msg,... $params)
UI interface for displaying a short message The parameters are like parameters to wfMessage().
nextTabIndex()
Get the next tabindex attribute value.
getLowestUnhappy()
Find the next page in sequence that hasn't been completed.
showError( $msg,... $params)
Same as showMessage(), but for displaying errors.
A service that provides utilities to do with language names and codes.
Service locator for MediaWiki core services.
static getInstance()
Returns the global default instance of the top level service locator.
The Message class deals with fetching and processing of interface message into a variety of formats.
Definition Message.php:158
The WebRequest class encapsulates getting at data passed in the URL or via a POSTed form,...
Generic operation result class Has warning/error list, boolean status and arbitrary value.
Definition Status.php:54
getWarningsArray()
Get the list of warnings (but not errors)
Definition Status.php:304
getErrorsArray()
Get the list of errors (but not warnings)
Definition Status.php:292
Module of static functions for generating XML.
Definition Xml.php:33
$wgLanguageCode
Config variable stub for the LanguageCode setting, for use by phpdoc and IDEs.
element(SerializerNode $parent, SerializerNode $node, $contents)