MediaWiki  master
WebInstaller.php
Go to the documentation of this file.
1 <?php
26 
33 class WebInstaller extends Installer {
34 
38  public $output;
39 
45  public $request;
46 
52  protected $session;
53 
59  protected $phpErrors;
60 
71  public $pageSequence = [
72  'Language',
73  'ExistingWiki',
74  'Welcome',
75  'DBConnect',
76  'Upgrade',
77  'DBSettings',
78  'Name',
79  'Options',
80  'Install',
81  'Complete',
82  ];
83 
89  protected $otherPages = [
90  'Restart',
91  'ReleaseNotes',
92  'Copying',
93  'UpgradeDoc', // Can't use Upgrade due to Upgrade step
94  ];
95 
102  protected $happyPages;
103 
111  protected $skippedPages;
112 
118  public $showSessionWarning = false;
119 
125  protected $tabIndex = 1;
126 
132  protected $helpBoxId = 1;
133 
139  protected $currentPageName;
140 
144  public function __construct( WebRequest $request ) {
145  parent::__construct();
146  $this->output = new WebInstallerOutput( $this );
147  $this->request = $request;
148  }
149 
157  public function execute( array $session ) {
158  $this->session = $session;
159 
160  if ( isset( $session['settings'] ) ) {
161  $this->settings = $session['settings'] + $this->settings;
162  // T187586 MediaWikiServices works with globals
163  foreach ( $this->settings as $key => $val ) {
164  $GLOBALS[$key] = $val;
165  }
166  }
167 
168  $this->setupLanguage();
169 
170  if ( ( $this->getVar( '_InstallDone' ) || $this->getVar( '_UpgradeDone' ) )
171  && $this->request->getVal( 'localsettings' )
172  ) {
173  $this->outputLS();
174  return $this->session;
175  }
176 
177  $isCSS = $this->request->getVal( 'css' );
178  if ( $isCSS ) {
179  $this->outputCss();
180  return $this->session;
181  }
182 
183  $this->happyPages = $session['happyPages'] ?? [];
184 
185  $this->skippedPages = $session['skippedPages'] ?? [];
186 
187  $lowestUnhappy = $this->getLowestUnhappy();
188 
189  # Special case for Creative Commons partner chooser box.
190  if ( $this->request->getVal( 'SubmitCC' ) ) {
192  $page = $this->getPageByName( 'Options' );
193  '@phan-var WebInstallerOptions $page';
194  $this->output->useShortHeader();
195  $this->output->allowFrames();
196  $page->submitCC();
197 
198  return $this->finish();
199  }
200 
201  if ( $this->request->getVal( 'ShowCC' ) ) {
203  $page = $this->getPageByName( 'Options' );
204  '@phan-var WebInstallerOptions $page';
205  $this->output->useShortHeader();
206  $this->output->allowFrames();
207  $this->output->addHTML( $page->getCCDoneBox() );
208 
209  return $this->finish();
210  }
211 
212  # Get the page name.
213  $pageName = $this->request->getVal( 'page', '' );
214 
215  if ( in_array( $pageName, $this->otherPages ) ) {
216  # Out of sequence
217  $pageId = false;
218  $page = $this->getPageByName( $pageName );
219  } else {
220  # Main sequence
221  if ( !$pageName || !in_array( $pageName, $this->pageSequence ) ) {
222  $pageId = $lowestUnhappy;
223  } else {
224  $pageId = array_search( $pageName, $this->pageSequence );
225  }
226 
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;
233  }
234  }
235 
236  $pageName = $this->pageSequence[$pageId];
237  $page = $this->getPageByName( $pageName );
238  }
239 
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 ) {
245  # Main sequence page
246  # Skip the skipped pages
247  $nextPageId = $pageId;
248 
249  do {
250  $nextPageId--;
251  $nextPage = $this->pageSequence[$nextPageId];
252  } while ( isset( $this->skippedPages[$nextPage] ) );
253  } else {
254  $nextPage = $this->pageSequence[$lowestUnhappy];
255  }
256 
257  $this->output->redirect( $this->getUrl( [ 'page' => $nextPage ] ) );
258 
259  return $this->finish();
260  }
261 
262  # Execute the page.
263  $this->currentPageName = $page->getName();
264  // @phan-suppress-next-line PhanTypeMismatchArgumentNullable pageName is not null here
265  $this->startPageWrapper( $pageName );
266 
267  if ( $page->isSlow() ) {
268  $this->disableTimeLimit();
269  }
270 
271  $result = $page->execute();
272 
273  $this->endPageWrapper();
274 
275  if ( $result == 'skip' ) {
276  # Page skipped without explicit submission.
277  # Skip it when we click "back" so that we don't just go forward again.
278  // @phan-suppress-next-line PhanTypeMismatchDimAssignment pageName is not null here
279  $this->skippedPages[$pageName] = true;
280  $result = 'continue';
281  } else {
282  unset( $this->skippedPages[$pageName] );
283  }
284 
285  # If it was posted, the page can request a continue to the next page.
286  if ( $result === 'continue' && !$this->output->headerDone() ) {
287  if ( $pageId !== false ) {
288  $this->happyPages[$pageId] = true;
289  }
290 
291  $lowestUnhappy = $this->getLowestUnhappy();
292 
293  if ( $this->request->getVal( 'lastPage' ) ) {
294  $nextPage = $this->request->getVal( 'lastPage' );
295  } elseif ( $pageId !== false ) {
296  $nextPage = $this->pageSequence[$pageId + 1];
297  } else {
298  $nextPage = $this->pageSequence[$lowestUnhappy];
299  }
300 
301  if ( array_search( $nextPage, $this->pageSequence ) > $lowestUnhappy ) {
302  $nextPage = $this->pageSequence[$lowestUnhappy];
303  }
304 
305  $this->output->redirect( $this->getUrl( [ 'page' => $nextPage ] ) );
306  }
307 
308  return $this->finish();
309  }
310 
315  public function getLowestUnhappy() {
316  if ( count( $this->happyPages ) == 0 ) {
317  return 0;
318  } else {
319  return max( array_keys( $this->happyPages ) ) + 1;
320  }
321  }
322 
329  public function startSession() {
330  if ( wfIniGetBool( 'session.auto_start' ) || session_id() ) {
331  // Done already
332  return true;
333  }
334 
335  // Use secure cookies if we are on HTTPS
336  $options = [];
337  if ( $this->request->getProtocol() === 'https' ) {
338  $options['cookie_secure'] = '1';
339  }
340 
341  $this->phpErrors = [];
342  set_error_handler( [ $this, 'errorHandler' ] );
343  try {
344  session_name( 'mw_installer_session' );
345  session_start( $options );
346  } catch ( Exception $e ) {
347  restore_error_handler();
348  throw $e;
349  }
350  restore_error_handler();
351 
352  if ( $this->phpErrors ) {
353  return false;
354  }
355 
356  return true;
357  }
358 
367  public function getFingerprint() {
368  // Get the base URL of the installation
369  $url = $this->request->getFullRequestURL();
370  if ( preg_match( '!^(.*\?)!', $url, $m ) ) {
371  // Trim query string
372  $url = $m[1];
373  }
374  if ( preg_match( '!^(.*)/[^/]*/[^/]*$!', $url, $m ) ) {
375  // This... seems to try to get the base path from
376  // the /mw-config/index.php. Kinda scary though?
377  $url = $m[1];
378  }
379 
380  return md5( serialize( [
381  'local path' => dirname( __DIR__ ),
382  'url' => $url,
383  'version' => MW_VERSION
384  ] ) );
385  }
386 
393  public function showError( $msg, ...$params ) {
394  if ( !( $msg instanceof Message ) ) {
395  $msg = wfMessage(
396  $msg,
397  array_map( 'htmlspecialchars', $params )
398  );
399  }
400  $text = $msg->useDatabase( false )->parse();
401  $box = Html::errorBox( $text, '', 'config-error-box' );
402  $this->output->addHTML( $box );
403  }
404 
411  public function errorHandler( $errno, $errstr ) {
412  $this->phpErrors[] = $errstr;
413  }
414 
420  public function finish() {
421  $this->output->output();
422 
423  $this->session['happyPages'] = $this->happyPages;
424  $this->session['skippedPages'] = $this->skippedPages;
425  $this->session['settings'] = $this->settings;
426 
427  return $this->session;
428  }
429 
433  public function reset() {
434  $this->session = [];
435  $this->happyPages = [];
436  $this->settings = [];
437  }
438 
446  public function getUrl( $query = [] ) {
447  $url = $this->request->getRequestURL();
448  # Remove existing query
449  $url = preg_replace( '/\?.*$/', '', $url );
450 
451  if ( $query ) {
452  $url .= '?' . wfArrayToCgi( $query );
453  }
454 
455  return $url;
456  }
457 
464  public function getPageByName( $pageName ) {
465  $pageClass = 'WebInstaller' . $pageName;
466 
467  return new $pageClass( $this );
468  }
469 
478  public function getSession( $name, $default = null ) {
479  return $this->session[$name] ?? $default;
480  }
481 
488  public function setSession( $name, $value ) {
489  $this->session[$name] = $value;
490  }
491 
497  public function nextTabIndex() {
498  return $this->tabIndex++;
499  }
500 
504  public function setupLanguage() {
505  global $wgLang, $wgLanguageCode;
506 
507  if ( $this->getSession( 'test' ) === null && !$this->request->wasPosted() ) {
509  $wgLang = MediaWikiServices::getInstance()->getLanguageFactory()
510  ->getLanguage( $wgLanguageCode );
511  RequestContext::getMain()->setLanguage( $wgLang );
512  $this->setVar( 'wgLanguageCode', $wgLanguageCode );
513  $this->setVar( '_UserLang', $wgLanguageCode );
514  } else {
515  $wgLanguageCode = $this->getVar( 'wgLanguageCode' );
516  }
517  }
518 
525  public function getAcceptLanguage() {
526  global $wgLanguageCode, $wgRequest;
527 
528  $mwLanguages = MediaWikiServices::getInstance()
529  ->getLanguageNameUtils()
530  ->getLanguageNames( LanguageNameUtils::AUTONYMS, LanguageNameUtils::SUPPORTED );
531  $headerLanguages = array_keys( $wgRequest->getAcceptLang() );
532 
533  foreach ( $headerLanguages as $lang ) {
534  if ( isset( $mwLanguages[$lang] ) ) {
535  return $lang;
536  }
537  }
538 
539  return $wgLanguageCode;
540  }
541 
547  private function startPageWrapper( $currentPageName ) {
548  $s = "<div class=\"config-page-wrapper\">\n";
549  $s .= "<div class=\"config-page\">\n";
550  $s .= "<div class=\"config-page-list\"><ul>\n";
551  $lastHappy = -1;
552 
553  foreach ( $this->pageSequence as $id => $pageName ) {
554  $happy = !empty( $this->happyPages[$id] );
555  $s .= $this->getPageListItem(
556  $pageName,
557  $happy || $lastHappy == $id - 1,
559  );
560 
561  if ( $happy ) {
562  $lastHappy = $id;
563  }
564  }
565 
566  $s .= "</ul><br/><ul>\n";
567  $s .= $this->getPageListItem( 'Restart', true, $currentPageName );
568  // End list pane
569  $s .= "</ul></div>\n";
570 
571  // Messages:
572  // config-page-language, config-page-welcome, config-page-dbconnect, config-page-upgrade,
573  // config-page-dbsettings, config-page-name, config-page-options, config-page-install,
574  // config-page-complete, config-page-restart, config-page-releasenotes,
575  // config-page-copying, config-page-upgradedoc, config-page-existingwiki
576  $s .= Html::element( 'h2', [],
577  wfMessage( 'config-page-' . strtolower( $currentPageName ) )->text() );
578 
579  $this->output->addHTMLNoFlush( $s );
580  }
581 
591  private function getPageListItem( $pageName, $enabled, $currentPageName ) {
592  $s = "<li class=\"config-page-list-item\">";
593 
594  // Messages:
595  // config-page-language, config-page-welcome, config-page-dbconnect, config-page-upgrade,
596  // config-page-dbsettings, config-page-name, config-page-options, config-page-install,
597  // config-page-complete, config-page-restart, config-page-releasenotes,
598  // config-page-copying, config-page-upgradedoc, config-page-existingwiki
599  $name = wfMessage( 'config-page-' . strtolower( $pageName ) )->text();
600 
601  if ( $enabled ) {
602  $query = [ 'page' => $pageName ];
603 
604  if ( !in_array( $pageName, $this->pageSequence ) ) {
605  if ( in_array( $currentPageName, $this->pageSequence ) ) {
606  $query['lastPage'] = $currentPageName;
607  }
608 
609  $link = Html::element( 'a',
610  [
611  'href' => $this->getUrl( $query )
612  ],
613  $name
614  );
615  } else {
616  $link = htmlspecialchars( $name );
617  }
618 
619  if ( $pageName == $currentPageName ) {
620  $s .= "<span class=\"config-page-current\">$link</span>";
621  } else {
622  $s .= $link;
623  }
624  } else {
625  $s .= Html::element( 'span',
626  [
627  'class' => 'config-page-disabled'
628  ],
629  $name
630  );
631  }
632 
633  $s .= "</li>\n";
634 
635  return $s;
636  }
637 
641  private function endPageWrapper() {
642  $this->output->addHTMLNoFlush(
643  "<div class=\"visualClear\"></div>\n" .
644  "</div>\n" .
645  "<div class=\"visualClear\"></div>\n" .
646  "</div>" );
647  }
648 
657  public function getInfoBox( $text, $icon = false, $class = '' ) {
658  $html = ( $text instanceof HtmlArmor ) ?
659  HtmlArmor::getHtml( $text ) :
660  $this->parse( $text, true );
661  $icon = ( !$icon ) ?
662  'images/info-32.png' :
663  'images/' . $icon;
664  $alt = wfMessage( 'config-information' )->text();
665 
666  return self::infoBox( $html, $icon, $alt, $class );
667  }
668 
678  public function getHelpBox( $msg, ...$args ) {
679  $args = array_map( 'htmlspecialchars', $args );
680  $text = wfMessage( $msg, $args )->useDatabase( false )->plain();
681  $html = $this->parse( $text, true );
682  $id = 'helpBox-' . $this->helpBoxId++;
683 
684  return "<div class=\"config-help-field-container\">\n" .
685  "<input type=\"checkbox\" class=\"config-help-field-checkbox\" id=\"$id\" />" .
686  "<label class=\"config-help-field-hint\" for=\"$id\" title=\"" .
687  wfMessage( 'config-help-tooltip' )->escaped() . "\">" .
688  wfMessage( 'config-help' )->escaped() . "</label>\n" .
689  "<div class=\"config-help-field-data\">" . $html . "</div>\n" .
690  "</div>\n";
691  }
692 
698  public function showHelpBox( $msg, ...$params ) {
699  $html = $this->getHelpBox( $msg, ...$params );
700  $this->output->addHTML( $html );
701  }
702 
710  public function showMessage( $msg, ...$params ) {
711  $html = '<div class="config-message">' .
712  $this->parse( wfMessage( $msg, $params )->useDatabase( false )->plain() ) .
713  "</div>\n";
714  $this->output->addHTML( $html );
715  }
716 
720  public function showStatusMessage( Status $status ) {
721  $errors = array_merge( $status->getErrorsArray(), $status->getWarningsArray() );
722  foreach ( $errors as $error ) {
723  $this->showMessage( ...$error );
724  }
725  }
726 
738  public function label( $msg, $forId, $contents, $helpData = "" ) {
739  if ( strval( $msg ) == '' ) {
740  $labelText = "\u{00A0}";
741  } else {
742  $labelText = wfMessage( $msg )->escaped();
743  }
744 
745  $attributes = [ 'class' => 'config-label' ];
746 
747  if ( $forId ) {
748  $attributes['for'] = $forId;
749  }
750 
751  return "<div class=\"config-block\">\n" .
752  " <div class=\"config-block-label\">\n" .
753  Xml::tags( 'label',
754  $attributes,
755  $labelText
756  ) . "\n" .
757  $helpData .
758  " </div>\n" .
759  " <div class=\"config-block-elements\">\n" .
760  $contents .
761  " </div>\n" .
762  "</div>\n";
763  }
764 
780  public function getTextBox( $params ) {
781  if ( !isset( $params['controlName'] ) ) {
782  $params['controlName'] = 'config_' . $params['var'];
783  }
784 
785  if ( !isset( $params['value'] ) ) {
786  $params['value'] = $this->getVar( $params['var'] );
787  }
788 
789  if ( !isset( $params['attribs'] ) ) {
790  $params['attribs'] = [];
791  }
792  if ( !isset( $params['help'] ) ) {
793  $params['help'] = "";
794  }
795 
796  return $this->label(
797  $params['label'],
798  $params['controlName'],
799  Xml::input(
800  $params['controlName'],
801  30, // intended to be overridden by CSS
802  $params['value'],
803  $params['attribs'] + [
804  'id' => $params['controlName'],
805  'class' => 'config-input-text',
806  'tabindex' => $this->nextTabIndex()
807  ]
808  ),
809  $params['help']
810  );
811  }
812 
827  public function getTextArea( $params ) {
828  if ( !isset( $params['controlName'] ) ) {
829  $params['controlName'] = 'config_' . $params['var'];
830  }
831 
832  if ( !isset( $params['value'] ) ) {
833  $params['value'] = $this->getVar( $params['var'] );
834  }
835 
836  if ( !isset( $params['attribs'] ) ) {
837  $params['attribs'] = [];
838  }
839  if ( !isset( $params['help'] ) ) {
840  $params['help'] = "";
841  }
842 
843  return $this->label(
844  $params['label'],
845  $params['controlName'],
847  $params['controlName'],
848  $params['value'],
849  30,
850  5,
851  $params['attribs'] + [
852  'id' => $params['controlName'],
853  'class' => 'config-input-text',
854  'tabindex' => $this->nextTabIndex()
855  ]
856  ),
857  $params['help']
858  );
859  }
860 
877  public function getPasswordBox( $params ) {
878  if ( !isset( $params['value'] ) ) {
879  $params['value'] = $this->getVar( $params['var'] );
880  }
881 
882  if ( !isset( $params['attribs'] ) ) {
883  $params['attribs'] = [];
884  }
885 
886  $params['value'] = $this->getFakePassword( $params['value'] );
887  $params['attribs']['type'] = 'password';
888 
889  return $this->getTextBox( $params );
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 
928  return "<div class=\"config-input-check\">\n" .
929  $params['help'] .
931  'label',
932  $params['labelAttribs'],
933  Xml::check(
934  $params['controlName'],
935  $params['value'],
936  $params['attribs'] + [
937  'id' => $params['controlName'],
938  'tabindex' => $this->nextTabIndex(),
939  ]
940  ) .
941  $labelText . "\n"
942  ) .
943  "</div>\n";
944  }
945 
966  public function getRadioSet( $params ) {
967  $items = $this->getRadioElements( $params );
968 
969  $label = $params['label'] ?? '';
970 
971  if ( !isset( $params['controlName'] ) ) {
972  $params['controlName'] = 'config_' . $params['var'];
973  }
974 
975  if ( !isset( $params['help'] ) ) {
976  $params['help'] = "";
977  }
978 
979  $s = "<ul>\n";
980  foreach ( $items as $value => $item ) {
981  $s .= "<li>$item</li>\n";
982  }
983  $s .= "</ul>\n";
984 
985  return $this->label( $label, $params['controlName'], $s, $params['help'] );
986  }
987 
997  public function getRadioElements( $params ) {
998  if ( !isset( $params['controlName'] ) ) {
999  $params['controlName'] = 'config_' . $params['var'];
1000  }
1001 
1002  if ( !isset( $params['value'] ) ) {
1003  $params['value'] = $this->getVar( $params['var'] );
1004  }
1005 
1006  $items = [];
1007 
1008  foreach ( $params['values'] as $value ) {
1009  $itemAttribs = [];
1010 
1011  if ( isset( $params['commonAttribs'] ) ) {
1012  $itemAttribs = $params['commonAttribs'];
1013  }
1014 
1015  if ( isset( $params['itemAttribs'][$value] ) ) {
1016  $itemAttribs = $params['itemAttribs'][$value] + $itemAttribs;
1017  }
1018 
1019  $checked = $value == $params['value'];
1020  $id = $params['controlName'] . '_' . $value;
1021  $itemAttribs['id'] = $id;
1022  $itemAttribs['tabindex'] = $this->nextTabIndex();
1023 
1024  $items[$value] =
1025  Xml::radio( $params['controlName'], $value, $checked, $itemAttribs ) .
1026  "\u{00A0}" .
1027  Xml::tags( 'label', [ 'for' => $id ], $this->parse(
1028  isset( $params['itemLabels'] ) ?
1029  wfMessage( $params['itemLabels'][$value] )->plain() :
1030  wfMessage( $params['itemLabelPrefix'] . strtolower( $value ) )->plain()
1031  ) );
1032  }
1033 
1034  return $items;
1035  }
1036 
1042  public function showStatusBox( $status ) {
1043  if ( !$status->isGood() ) {
1044  $html = $status->getHTML();
1045 
1046  if ( $status->isOK() ) {
1047  $box = Html::warningBox( $html, 'config-warning-box' );
1048  } else {
1049  $box = Html::errorBox( $html, '', 'config-error-box' );
1050  }
1051 
1052  $this->output->addHTML( $box );
1053  }
1054  }
1055 
1066  public function setVarsFromRequest( $varNames, $prefix = 'config_' ) {
1067  $newValues = [];
1068 
1069  foreach ( $varNames as $name ) {
1070  $value = $this->request->getVal( $prefix . $name );
1071  // T32524, do not trim passwords
1072  if ( stripos( $name, 'password' ) === false ) {
1073  $value = trim( $value );
1074  }
1075  $newValues[$name] = $value;
1076 
1077  if ( $value === null ) {
1078  // Checkbox?
1079  $this->setVar( $name, false );
1080  } elseif ( stripos( $name, 'password' ) !== false ) {
1081  $this->setPassword( $name, $value );
1082  } else {
1083  $this->setVar( $name, $value );
1084  }
1085  }
1086 
1087  return $newValues;
1088  }
1089 
1097  public function getDocUrl( $page ) {
1098  $query = [ 'page' => $page ];
1099 
1100  if ( in_array( $this->currentPageName, $this->pageSequence ) ) {
1101  $query['lastPage'] = $this->currentPageName;
1102  }
1103 
1104  return $this->getUrl( $query );
1105  }
1106 
1115  public function makeLinkItem( $url, $linkText ) {
1116  return Html::rawElement( 'li', [],
1117  Html::element( 'a', [ 'href' => $url ], $linkText )
1118  );
1119  }
1120 
1127  public function makeDownloadLinkHtml() {
1128  $anchor = Html::rawElement( 'a',
1129  [ 'href' => $this->getUrl( [ 'localsettings' => 1 ] ) ],
1130  wfMessage( 'config-download-localsettings' )->parse()
1131  );
1132 
1133  return Html::rawElement( 'div', [ 'class' => 'config-download-link' ], $anchor );
1134  }
1135 
1146  public function getLocalSettingsLocation() {
1147  return false;
1148  }
1149 
1153  public function envCheckPath() {
1154  // PHP_SELF isn't available sometimes, such as when PHP is CGI but
1155  // cgi.fix_pathinfo is disabled. In that case, fall back to SCRIPT_NAME
1156  // to get the path to the current script... hopefully it's reliable. SIGH
1157  $path = false;
1158  if ( !empty( $_SERVER['PHP_SELF'] ) ) {
1159  $path = $_SERVER['PHP_SELF'];
1160  } elseif ( !empty( $_SERVER['SCRIPT_NAME'] ) ) {
1161  $path = $_SERVER['SCRIPT_NAME'];
1162  }
1163  if ( $path === false ) {
1164  $this->showError( 'config-no-uri' );
1165  return false;
1166  }
1167 
1168  return parent::envCheckPath();
1169  }
1170 
1171  public function envPrepPath() {
1172  parent::envPrepPath();
1173  // PHP_SELF isn't available sometimes, such as when PHP is CGI but
1174  // cgi.fix_pathinfo is disabled. In that case, fall back to SCRIPT_NAME
1175  // to get the path to the current script... hopefully it's reliable. SIGH
1176  $path = false;
1177  if ( !empty( $_SERVER['PHP_SELF'] ) ) {
1178  $path = $_SERVER['PHP_SELF'];
1179  } elseif ( !empty( $_SERVER['SCRIPT_NAME'] ) ) {
1180  $path = $_SERVER['SCRIPT_NAME'];
1181  }
1182  if ( $path !== false ) {
1183  $scriptPath = preg_replace( '{^(.*)/(mw-)?config.*$}', '$1', $path );
1184 
1185  $this->setVar( 'wgScriptPath', "$scriptPath" );
1186  // Update variables set from Setup.php that are derived from wgScriptPath
1187  $this->setVar( 'wgScript', "$scriptPath/index.php" );
1188  $this->setVar( 'wgLoadScript', "$scriptPath/load.php" );
1189  $this->setVar( 'wgStylePath', "$scriptPath/skins" );
1190  $this->setVar( 'wgLocalStylePath', "$scriptPath/skins" );
1191  $this->setVar( 'wgExtensionAssetsPath', "$scriptPath/extensions" );
1192  $this->setVar( 'wgUploadPath', "$scriptPath/images" );
1193  $this->setVar( 'wgResourceBasePath', "$scriptPath" );
1194  }
1195  }
1196 
1200  protected function envGetDefaultServer() {
1201  $assumeProxiesUseDefaultProtocolPorts =
1202  $this->getVar( 'wgAssumeProxiesUseDefaultProtocolPorts' );
1203 
1204  return WebRequest::detectServer( $assumeProxiesUseDefaultProtocolPorts );
1205  }
1206 
1210  private function outputLS() {
1211  $this->request->response()->header( 'Content-type: application/x-httpd-php' );
1212  $this->request->response()->header(
1213  'Content-Disposition: attachment; filename="LocalSettings.php"'
1214  );
1215 
1217  $rightsProfile = $this->rightsProfiles[$this->getVar( '_RightsProfile' )];
1218  foreach ( $rightsProfile as $group => $rightsArr ) {
1219  $ls->setGroupRights( $group, $rightsArr );
1220  }
1221  echo $ls->getText();
1222  }
1223 
1227  public function outputCss() {
1228  $this->request->response()->header( 'Content-type: text/css' );
1229  echo $this->output->getCSS();
1230  }
1231 
1235  public function getPhpErrors() {
1236  return $this->phpErrors;
1237  }
1238 
1249  protected static function infoBox( $rawHtml, $icon, $alt, $class = '' ) {
1250  $s = Html::openElement( 'div', [ 'class' => 'mw-installer-box-left' ] ) .
1251  Html::element( 'img',
1252  [
1253  'src' => $icon,
1254  'alt' => $alt,
1255  ]
1256  ) .
1257  Html::closeElement( 'div' );
1258 
1259  $s .= Html::openElement( 'div', [ 'class' => 'mw-installer-box-right' ] ) .
1260  $rawHtml .
1261  Html::closeElement( 'div' );
1262  $s .= Html::element( 'div', [ 'style' => 'clear: left;' ], ' ' );
1263 
1264  return Html::warningBox( $s, $class )
1265  . Html::element( 'div', [ 'style' => 'clear: left;' ], ' ' );
1266  }
1267 
1268 }
serialize()
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:366
if(!defined( 'MW_NO_SESSION') &&! $wgCommandLineMode) $wgLang
Definition: Setup.php:486
Marks HTML that shouldn't be escaped.
Definition: HtmlArmor.php:30
static getHtml( $input)
Provide a string or HtmlArmor object and get safe HTML back.
Definition: HtmlArmor.php:54
static element( $element, $attribs=[], $contents='')
Identical to rawElement(), but HTML-escapes $contents (like Xml::element()).
Definition: Html.php:236
static rawElement( $element, $attribs=[], $contents='')
Returns an HTML element in a string.
Definition: Html.php:214
static warningBox( $html, $className='')
Return a warning box.
Definition: Html.php:775
static openElement( $element, $attribs=[])
Identical to rawElement(), but has no third parameter and omits the end tag (and the self-closing '/'...
Definition: Html.php:256
static errorBox( $html, $heading='', $className='')
Return an error box.
Definition: Html.php:788
static closeElement( $element)
Returns "</$element>".
Definition: Html.php:320
static getLocalSettingsGenerator(Installer $installer)
Instantiates and returns an instance of LocalSettingsGenerator or its descendant classes.
Base installer class.
Definition: Installer.php:57
parse( $text, $lineStart=false)
Convert wikitext $text to HTML.
Definition: Installer.php:771
setVar( $name, $value)
Set a MW configuration variable, or internal installer configuration variable.
Definition: Installer.php:584
getFakePassword( $realPassword)
Get a fake password for sending back to the user in HTML.
Definition: Installer.php:715
disableTimeLimit()
Disable the time limit for execution.
Definition: Installer.php:1967
array $settings
Definition: Installer.php:76
setPassword( $name, $value)
Set a variable which stores a password, except if the new value is a fake password in which case leav...
Definition: Installer.php:726
getVar( $name, $default=null)
Get an MW configuration variable, or internal installer configuration variable.
Definition: Installer.php:598
A service that provides utilities to do with language names and codes.
MediaWikiServices is the service locator for the application scope of MediaWiki.
The Message class deals with fetching and processing of interface message into a variety of formats.
Definition: Message.php:141
static getMain()
Get the RequestContext object associated with the main request.
Generic operation result class Has warning/error list, boolean status and arbitrary value.
Definition: Status.php:44
getErrorsArray()
Get the list of errors (but not warnings)
Definition: Status.php:356
getWarningsArray()
Get the list of warnings (but not errors)
Definition: Status.php:367
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.
getPasswordBox( $params)
Get a labelled password box to configure a variable.
getInfoBox( $text, $icon=false, $class='')
Get HTML for an information message box with an icon.
WebRequest $request
WebRequest object.
__construct(WebRequest $request)
getTextArea( $params)
Get a labelled textarea to configure a variable.
getFingerprint()
Get a hash of data identifying this MW installation.
string[] $otherPages
Out of sequence pages, selectable by the user at any time.
string[] $pageSequence
The main sequence of page names.
string[] $phpErrors
Captured PHP error text.
static infoBox( $rawHtml, $icon, $alt, $class='')
Get HTML for an information message box with an icon.
bool $showSessionWarning
Flag indicating that session data may have been lost.
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.
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...
Definition: WebRequest.php:43
static detectServer( $assumeProxiesUseDefaultProtocolPorts=null)
Work out an appropriate URL prefix containing scheme and host, based on information detected from $_S...
Definition: WebRequest.php:264
static textarea( $name, $content, $cols=40, $rows=5, $attribs=[])
Shortcut for creating textareas.
Definition: Xml.php:654
static check( $name, $checked=false, $attribs=[])
Convenience function to build an HTML checkbox.
Definition: Xml.php:332
static input( $name, $size=false, $value=false, $attribs=[])
Convenience function to build an HTML text input field.
Definition: Xml.php:283
static tags( $element, $attribs, $contents)
Same as Xml::element(), but does not escape contents.
Definition: Xml.php:134
static radio( $name, $value, $checked=false, $attribs=[])
Convenience function to build an HTML radio button.
Definition: Xml.php:350
$wgLanguageCode
Config variable stub for the LanguageCode setting, for use by phpdoc and IDEs.
if( $line===false) $args
Definition: mcc.php:124
foreach( $mmfl['setupFiles'] as $fileName) if( $queue) if(empty( $mmfl['quiet'])) $s
if(!isset( $args[0])) $lang