MediaWiki 1.42.0-rc.0
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
378 public function showError( $msg, ...$params ) {
379 if ( !( $msg instanceof Message ) ) {
380 $msg = wfMessage(
381 $msg,
382 array_map( 'htmlspecialchars', $params )
383 );
384 }
385 $text = $msg->useDatabase( false )->parse();
386 $box = Html::errorBox( $text, '', 'config-error-box' );
387 $this->output->addHTML( $box );
388 }
389
396 public function errorHandler( $errno, $errstr ) {
397 $this->phpErrors[] = $errstr;
398 }
399
405 public function finish() {
406 $this->output->output();
407
408 $this->session['happyPages'] = $this->happyPages;
409 $this->session['skippedPages'] = $this->skippedPages;
410 $this->session['settings'] = $this->settings;
411
412 return $this->session;
413 }
414
418 public function reset() {
419 $this->session = [];
420 $this->happyPages = [];
421 $this->settings = [];
422 }
423
431 public function getUrl( $query = [] ) {
432 $url = $this->request->getRequestURL();
433 # Remove existing query
434 $url = preg_replace( '/\?.*$/', '', $url );
435
436 if ( $query ) {
437 $url .= '?' . wfArrayToCgi( $query );
438 }
439
440 return $url;
441 }
442
449 public function getPageByName( $pageName ) {
450 $pageClass = 'MediaWiki\\Installer\\WebInstaller' . $pageName;
451
452 return new $pageClass( $this );
453 }
454
463 public function getSession( $name, $default = null ) {
464 return $this->session[$name] ?? $default;
465 }
466
473 public function setSession( $name, $value ) {
474 $this->session[$name] = $value;
475 }
476
482 public function nextTabIndex() {
483 return $this->tabIndex++;
484 }
485
489 public function setupLanguage() {
490 global $wgLang, $wgLanguageCode;
491
492 if ( $this->getSession( 'test' ) === null && !$this->request->wasPosted() ) {
494 $wgLang = MediaWikiServices::getInstance()->getLanguageFactory()
495 ->getLanguage( $wgLanguageCode );
496 RequestContext::getMain()->setLanguage( $wgLang );
497 $this->setVar( 'wgLanguageCode', $wgLanguageCode );
498 $this->setVar( '_UserLang', $wgLanguageCode );
499 } else {
500 $wgLanguageCode = $this->getVar( 'wgLanguageCode' );
501 }
502 }
503
510 public function getAcceptLanguage() {
512
513 $mwLanguages = MediaWikiServices::getInstance()
514 ->getLanguageNameUtils()
515 ->getLanguageNames( LanguageNameUtils::AUTONYMS, LanguageNameUtils::SUPPORTED );
516 $headerLanguages = array_keys( $wgRequest->getAcceptLang() );
517
518 foreach ( $headerLanguages as $lang ) {
519 if ( isset( $mwLanguages[$lang] ) ) {
520 return $lang;
521 }
522 }
523
524 return $wgLanguageCode;
525 }
526
532 private function startPageWrapper( $currentPageName ) {
533 $s = "<div class=\"config-page-wrapper\">\n";
534 $s .= "<div class=\"config-page\">\n";
535 $s .= "<div class=\"config-page-list cdx-card\"><span class=\"cdx-card__text\">";
536 $s .= "<span class=\"cdx-card__text__description\"><ul>\n";
537 $lastHappy = -1;
538
539 foreach ( $this->pageSequence as $id => $pageName ) {
540 $happy = !empty( $this->happyPages[$id] );
541 $s .= $this->getPageListItem(
542 $pageName,
543 $happy || $lastHappy == $id - 1,
545 );
546
547 if ( $happy ) {
548 $lastHappy = $id;
549 }
550 }
551
552 $s .= "</ul><br/><ul>\n";
553 $s .= $this->getPageListItem( 'Restart', true, $currentPageName );
554 // End list pane
555 $s .= "</ul></span></span></div>\n";
556
557 // Messages:
558 // config-page-language, config-page-welcome, config-page-dbconnect, config-page-upgrade,
559 // config-page-dbsettings, config-page-name, config-page-options, config-page-install,
560 // config-page-complete, config-page-restart, config-page-releasenotes,
561 // config-page-copying, config-page-upgradedoc, config-page-existingwiki
562 $s .= Html::element( 'h2', [],
563 wfMessage( 'config-page-' . strtolower( $currentPageName ) )->text() );
564
565 $this->output->addHTMLNoFlush( $s );
566 }
567
577 private function getPageListItem( $pageName, $enabled, $currentPageName ) {
578 $s = "<li class=\"config-page-list-item\">";
579
580 // Messages:
581 // config-page-language, config-page-welcome, config-page-dbconnect, config-page-upgrade,
582 // config-page-dbsettings, config-page-name, config-page-options, config-page-install,
583 // config-page-complete, config-page-restart, config-page-releasenotes,
584 // config-page-copying, config-page-upgradedoc, config-page-existingwiki
585 $name = wfMessage( 'config-page-' . strtolower( $pageName ) )->text();
586
587 if ( $enabled ) {
588 $query = [ 'page' => $pageName ];
589
590 if ( !in_array( $pageName, $this->pageSequence ) ) {
591 if ( in_array( $currentPageName, $this->pageSequence ) ) {
592 $query['lastPage'] = $currentPageName;
593 }
594
595 $link = Html::element( 'a',
596 [
597 'href' => $this->getUrl( $query )
598 ],
599 $name
600 );
601 } else {
602 $link = htmlspecialchars( $name );
603 }
604
605 if ( $pageName == $currentPageName ) {
606 $s .= "<span class=\"config-page-current\">$link</span>";
607 } else {
608 $s .= $link;
609 }
610 } else {
611 $s .= Html::element( 'span',
612 [
613 'class' => 'config-page-disabled'
614 ],
615 $name
616 );
617 }
618
619 $s .= "</li>\n";
620
621 return $s;
622 }
623
627 private function endPageWrapper() {
628 $this->output->addHTMLNoFlush(
629 "<div class=\"visualClear\"></div>\n" .
630 "</div>\n" .
631 "<div class=\"visualClear\"></div>\n" .
632 "</div>" );
633 }
634
643 public function getInfoBox( $text, $icon = false, $class = '' ) {
644 $html = ( $text instanceof HtmlArmor ) ?
645 HtmlArmor::getHtml( $text ) :
646 $this->parse( $text, true );
647 $alt = wfMessage( 'config-information' )->text();
648
649 return self::infoBox( $html, '', $alt, $class );
650 }
651
661 public function getHelpBox( $msg, ...$args ) {
662 $args = array_map( 'htmlspecialchars', $args );
663 $text = wfMessage( $msg, $args )->useDatabase( false )->plain();
664 $html = $this->parse( $text, true );
665
666 return "<div class=\"config-help-field-container\">\n" .
667 "<a class=\"config-help-field-hint\" title=\"" .
668 wfMessage( 'config-help-tooltip' )->escaped() . "\">ℹ️ " .
669 wfMessage( 'config-help' )->escaped() . "</a>\n" .
670 "<div class=\"config-help-field-content config-help-field-content-hidden " .
671 "cdx-message cdx-message--block cdx-message--notice\" style=\"margin: 10px\">" .
672 "<div class=\"cdx-message__content\">" . $html . "</div></div>\n" .
673 "</div>\n";
674 }
675
681 public function showHelpBox( $msg, ...$params ) {
682 $html = $this->getHelpBox( $msg, ...$params );
683 $this->output->addHTML( $html );
684 }
685
693 public function showMessage( $msg, ...$params ) {
694 $html = '<div class="cdx-message cdx-message--block cdx-message--notice">' .
695 '<span class="cdx-message__icon"></span><div class="cdx-message__content">' .
696 $this->parse( wfMessage( $msg, $params )->useDatabase( false )->plain() ) .
697 "</div></div>\n";
698 $this->output->addHTML( $html );
699 }
700
704 public function showStatusMessage( Status $status ) {
705 $errors = array_merge( $status->getErrorsArray(), $status->getWarningsArray() );
706 foreach ( $errors as $error ) {
707 $this->showMessage( ...$error );
708 }
709 }
710
722 public function label( $msg, $forId, $contents, $helpData = "" ) {
723 if ( strval( $msg ) == '' ) {
724 $labelText = "\u{00A0}";
725 } else {
726 $labelText = wfMessage( $msg )->escaped();
727 }
728
729 $attributes = [ 'class' => 'config-label' ];
730
731 if ( $forId ) {
732 $attributes['for'] = $forId;
733 }
734
735 return "<div class=\"config-block\">\n" .
736 " <div class=\"config-block-label\">\n" .
737 Xml::tags( 'label',
738 $attributes,
739 $labelText
740 ) . "\n" .
741 $helpData .
742 " </div>\n" .
743 " <div class=\"config-block-elements\">\n" .
744 $contents .
745 " </div>\n" .
746 "</div>\n";
747 }
748
764 public function getTextBox( $params ) {
765 if ( !isset( $params['controlName'] ) ) {
766 $params['controlName'] = 'config_' . $params['var'];
767 }
768
769 if ( !isset( $params['value'] ) ) {
770 $params['value'] = $this->getVar( $params['var'] );
771 }
772
773 if ( !isset( $params['attribs'] ) ) {
774 $params['attribs'] = [];
775 }
776 if ( !isset( $params['help'] ) ) {
777 $params['help'] = "";
778 }
779
780 return $this->label(
781 $params['label'],
782 $params['controlName'],
783 "<div class=\"cdx-text-input\">" .
784 Xml::input(
785 $params['controlName'],
786 30, // intended to be overridden by CSS
787 $params['value'],
788 $params['attribs'] + [
789 'id' => $params['controlName'],
790 'class' => 'cdx-text-input__input',
791 'tabindex' => $this->nextTabIndex()
792 ]
793 ) . "</div>",
794 $params['help']
795 );
796 }
797
812 public function getTextArea( $params ) {
813 if ( !isset( $params['controlName'] ) ) {
814 $params['controlName'] = 'config_' . $params['var'];
815 }
816
817 if ( !isset( $params['value'] ) ) {
818 $params['value'] = $this->getVar( $params['var'] );
819 }
820
821 if ( !isset( $params['attribs'] ) ) {
822 $params['attribs'] = [];
823 }
824 if ( !isset( $params['help'] ) ) {
825 $params['help'] = "";
826 }
827
828 return $this->label(
829 $params['label'],
830 $params['controlName'],
831 Xml::textarea(
832 $params['controlName'],
833 $params['value'],
834 30,
835 5,
836 $params['attribs'] + [
837 'id' => $params['controlName'],
838 'class' => 'config-input-text',
839 'tabindex' => $this->nextTabIndex()
840 ]
841 ),
842 $params['help']
843 );
844 }
845
862 public function getPasswordBox( $params ) {
863 if ( !isset( $params['value'] ) ) {
864 $params['value'] = $this->getVar( $params['var'] );
865 }
866
867 if ( !isset( $params['attribs'] ) ) {
868 $params['attribs'] = [];
869 }
870
871 $params['value'] = $this->getFakePassword( $params['value'] );
872 $params['attribs']['type'] = 'password';
873
874 return $this->getTextBox( $params );
875 }
876
884 private static function addClassAttrib( &$attribs, $class ) {
885 if ( isset( $attribs['class'] ) ) {
886 $attribs['class'] .= ' ' . $class;
887 } else {
888 $attribs['class'] = $class;
889 }
890 }
891
908 public function getCheckBox( $params ) {
909 if ( !isset( $params['controlName'] ) ) {
910 $params['controlName'] = 'config_' . $params['var'];
911 }
912
913 if ( !isset( $params['value'] ) ) {
914 $params['value'] = $this->getVar( $params['var'] );
915 }
916
917 if ( !isset( $params['attribs'] ) ) {
918 $params['attribs'] = [];
919 }
920 if ( !isset( $params['help'] ) ) {
921 $params['help'] = "";
922 }
923 if ( !isset( $params['labelAttribs'] ) ) {
924 $params['labelAttribs'] = [];
925 }
926 $labelText = $params['rawtext'] ?? $this->parse( wfMessage( $params['label'] )->plain() );
927 self::addClassAttrib( $params['attribs'], 'cdx-checkbox__input' );
928 self::addClassAttrib( $params['labelAttribs'], 'cdx-checkbox__label' );
929
930 return "<div class=\"cdx-checkbox\" style=\"margin-top: 12px; margin-bottom: 2px;\">\n" .
931 Xml::check(
932 $params['controlName'],
933 $params['value'],
934 $params['attribs'] + [
935 'id' => $params['controlName'],
936 'tabindex' => $this->nextTabIndex()
937 ]
938 ) .
939 "<span class=\"cdx-checkbox__icon\"></span>" .
940 Html::rawElement(
941 'label',
942 $params['labelAttribs'] + [
943 'for' => $params['controlName']
944 ],
945 $labelText
946 ) .
947 "</div>\n" . $params['help'];
948 }
949
970 public function getRadioSet( $params ) {
971 $items = $this->getRadioElements( $params );
972
973 $label = $params['label'] ?? '';
974
975 if ( !isset( $params['controlName'] ) ) {
976 $params['controlName'] = 'config_' . $params['var'];
977 }
978
979 if ( !isset( $params['help'] ) ) {
980 $params['help'] = "";
981 }
982
983 $s = "";
984 foreach ( $items as $item ) {
985 $s .= "$item\n";
986 }
987
988 return $this->label( $label, $params['controlName'], $s, $params['help'] );
989 }
990
1000 public function getRadioElements( $params ) {
1001 if ( !isset( $params['controlName'] ) ) {
1002 $params['controlName'] = 'config_' . $params['var'];
1003 }
1004
1005 if ( !isset( $params['value'] ) ) {
1006 $params['value'] = $this->getVar( $params['var'] );
1007 }
1008
1009 $items = [];
1010
1011 foreach ( $params['values'] as $value ) {
1012 $itemAttribs = [];
1013
1014 if ( isset( $params['commonAttribs'] ) ) {
1015 $itemAttribs = $params['commonAttribs'];
1016 }
1017
1018 if ( isset( $params['itemAttribs'][$value] ) ) {
1019 $itemAttribs = $params['itemAttribs'][$value] + $itemAttribs;
1020 }
1021
1022 $checked = $value == $params['value'];
1023 $id = $params['controlName'] . '_' . $value;
1024 $itemAttribs['id'] = $id;
1025 $itemAttribs['tabindex'] = $this->nextTabIndex();
1026 self::addClassAttrib( $itemAttribs, 'cdx-radio__input' );
1027
1028 $items[$value] =
1029 '<span class="cdx-radio">' .
1030 Xml::radio( $params['controlName'], $value, $checked, $itemAttribs ) .
1031 "<span class=\"cdx-radio__icon\"></span>\u{00A0}" .
1032 Xml::tags( 'label', [ 'for' => $id, 'class' => 'cdx-radio__label' ], $this->parse(
1033 isset( $params['itemLabels'] ) ?
1034 wfMessage( $params['itemLabels'][$value] )->plain() :
1035 wfMessage( $params['itemLabelPrefix'] . strtolower( $value ) )->plain()
1036 ) ) . '</span>';
1037 }
1038
1039 return $items;
1040 }
1041
1047 public function showStatusBox( $status ) {
1048 if ( !$status->isGood() ) {
1049 $html = $status->getHTML();
1050
1051 if ( $status->isOK() ) {
1052 $box = Html::warningBox( $html, 'config-warning-box' );
1053 } else {
1054 $box = Html::errorBox( $html, '', 'config-error-box' );
1055 }
1056
1057 $this->output->addHTML( $box );
1058 }
1059 }
1060
1071 public function setVarsFromRequest( $varNames, $prefix = 'config_' ) {
1072 $newValues = [];
1073
1074 foreach ( $varNames as $name ) {
1075 $value = $this->request->getVal( $prefix . $name );
1076 // T32524, do not trim passwords
1077 if ( $value !== null && stripos( $name, 'password' ) === false ) {
1078 $value = trim( $value );
1079 }
1080 $newValues[$name] = $value;
1081
1082 if ( $value === null ) {
1083 // Checkbox?
1084 $this->setVar( $name, false );
1085 } elseif ( stripos( $name, 'password' ) !== false ) {
1086 $this->setPassword( $name, $value );
1087 } else {
1088 $this->setVar( $name, $value );
1089 }
1090 }
1091
1092 return $newValues;
1093 }
1094
1102 public function getDocUrl( $page ) {
1103 $query = [ 'page' => $page ];
1104
1105 if ( in_array( $this->currentPageName, $this->pageSequence ) ) {
1106 $query['lastPage'] = $this->currentPageName;
1107 }
1108
1109 return $this->getUrl( $query );
1110 }
1111
1120 public function makeLinkItem( $url, $linkText ) {
1121 return Html::rawElement( 'li', [],
1122 Html::element( 'a', [ 'href' => $url ], $linkText )
1123 );
1124 }
1125
1132 public function makeDownloadLinkHtml() {
1133 $anchor = Html::rawElement( 'a',
1134 [ 'href' => $this->getUrl( [ 'localsettings' => 1 ] ) ],
1135 wfMessage( 'config-download-localsettings' )->parse()
1136 );
1137
1138 return Html::rawElement( 'div', [ 'class' => 'config-download-link' ], $anchor );
1139 }
1140
1151 public function getLocalSettingsLocation() {
1152 return false;
1153 }
1154
1158 public function envCheckPath() {
1159 // PHP_SELF isn't available sometimes, such as when PHP is CGI but
1160 // cgi.fix_pathinfo is disabled. In that case, fall back to SCRIPT_NAME
1161 // to get the path to the current script... hopefully it's reliable. SIGH
1162 $path = false;
1163 if ( !empty( $_SERVER['PHP_SELF'] ) ) {
1164 $path = $_SERVER['PHP_SELF'];
1165 } elseif ( !empty( $_SERVER['SCRIPT_NAME'] ) ) {
1166 $path = $_SERVER['SCRIPT_NAME'];
1167 }
1168 if ( $path === false ) {
1169 $this->showError( 'config-no-uri' );
1170 return false;
1171 }
1172
1173 return parent::envCheckPath();
1174 }
1175
1176 public function envPrepPath() {
1177 parent::envPrepPath();
1178 // PHP_SELF isn't available sometimes, such as when PHP is CGI but
1179 // cgi.fix_pathinfo is disabled. In that case, fall back to SCRIPT_NAME
1180 // to get the path to the current script... hopefully it's reliable. SIGH
1181 $path = false;
1182 if ( !empty( $_SERVER['PHP_SELF'] ) ) {
1183 $path = $_SERVER['PHP_SELF'];
1184 } elseif ( !empty( $_SERVER['SCRIPT_NAME'] ) ) {
1185 $path = $_SERVER['SCRIPT_NAME'];
1186 }
1187 if ( $path !== false ) {
1188 $scriptPath = preg_replace( '{^(.*)/(mw-)?config.*$}', '$1', $path );
1189
1190 $this->setVar( 'wgScriptPath', "$scriptPath" );
1191 // Update variables set from Setup.php that are derived from wgScriptPath
1192 $this->setVar( 'wgScript', "$scriptPath/index.php" );
1193 $this->setVar( 'wgLoadScript', "$scriptPath/load.php" );
1194 $this->setVar( 'wgStylePath', "$scriptPath/skins" );
1195 $this->setVar( 'wgLocalStylePath', "$scriptPath/skins" );
1196 $this->setVar( 'wgExtensionAssetsPath', "$scriptPath/extensions" );
1197 $this->setVar( 'wgUploadPath', "$scriptPath/images" );
1198 $this->setVar( 'wgResourceBasePath', "$scriptPath" );
1199 }
1200 }
1201
1205 protected function envGetDefaultServer() {
1206 $assumeProxiesUseDefaultProtocolPorts =
1207 $this->getVar( 'wgAssumeProxiesUseDefaultProtocolPorts' );
1208
1209 return WebRequest::detectServer( $assumeProxiesUseDefaultProtocolPorts );
1210 }
1211
1215 private function outputLS() {
1216 $this->request->response()->header( 'Content-type: application/x-httpd-php' );
1217 $this->request->response()->header(
1218 'Content-Disposition: attachment; filename="LocalSettings.php"'
1219 );
1220
1222 $rightsProfile = $this->rightsProfiles[$this->getVar( '_RightsProfile' )];
1223 foreach ( $rightsProfile as $group => $rightsArr ) {
1224 $ls->setGroupRights( $group, $rightsArr );
1225 }
1226 echo $ls->getText();
1227 }
1228
1232 public function outputCss() {
1233 $this->request->response()->header( 'Content-type: text/css' );
1234 echo $this->output->getCSS();
1235 }
1236
1240 public function getPhpErrors() {
1241 return $this->phpErrors;
1242 }
1243
1254 protected static function infoBox( $rawHtml, $icon, $alt, $class = '' ) {
1255 $s = Html::openElement( 'div', [ 'class' => 'mw-installer-box-left' ] ) .
1256 Html::element( 'img',
1257 [
1258 'src' => $icon,
1259 'alt' => $alt,
1260 ]
1261 ) .
1262 Html::closeElement( 'div' ) .
1263 Html::openElement( 'div', [ 'class' => 'mw-installer-box-right' ] ) .
1264 $rawHtml .
1265 Html::closeElement( 'div' ) .
1266 Html::element( 'div', [ 'style' => 'clear: left;' ], ' ' );
1267
1268 return Html::warningBox( $s, $class )
1269 . Html::element( 'div', [ 'style' => 'clear: left;' ], ' ' );
1270 }
1271
1272}
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:88
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.
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)
Show a short informational message.
nextTabIndex()
Get the next tabindex attribute value.
getLowestUnhappy()
Find the next page in sequence that hasn't been completed.
showError( $msg,... $params)
Show an error message in a box.
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:157
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:302
getErrorsArray()
Get the list of errors (but not warnings)
Definition Status.php:291
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)