MediaWiki  master
Installer.php
Go to the documentation of this file.
1 <?php
30 
52 abstract class Installer {
53 
60  const MINIMUM_PCRE_VERSION = '7.2';
61 
65  protected $settings;
66 
72  protected $compiledDBs;
73 
79  protected $dbInstallers = [];
80 
86  protected $minMemorySize = 50;
87 
93  protected $parserTitle;
94 
100  protected $parserOptions;
101 
111  protected static $dbTypes = [
112  'mysql',
113  'postgres',
114  'sqlite',
115  ];
116 
128  protected $envChecks = [
129  'envCheckDB',
130  'envCheckPCRE',
131  'envCheckMemory',
132  'envCheckCache',
133  'envCheckModSecurity',
134  'envCheckDiff3',
135  'envCheckGraphics',
136  'envCheckGit',
137  'envCheckServer',
138  'envCheckPath',
139  'envCheckShellLocale',
140  'envCheckUploadsDirectory',
141  'envCheckLibicu',
142  'envCheckSuhosinMaxValueLength',
143  'envCheck64Bit',
144  ];
145 
151  protected $envPreps = [
152  'envPrepServer',
153  'envPrepPath',
154  ];
155 
163  protected $defaultVarNames = [
164  'wgSitename',
165  'wgPasswordSender',
166  'wgLanguageCode',
167  'wgRightsIcon',
168  'wgRightsText',
169  'wgRightsUrl',
170  'wgEnableEmail',
171  'wgEnableUserEmail',
172  'wgEnotifUserTalk',
173  'wgEnotifWatchlist',
174  'wgEmailAuthentication',
175  'wgDBname',
176  'wgDBtype',
177  'wgDiff3',
178  'wgImageMagickConvertCommand',
179  'wgGitBin',
180  'IP',
181  'wgScriptPath',
182  'wgMetaNamespace',
183  'wgDeletedDirectory',
184  'wgEnableUploads',
185  'wgShellLocale',
186  'wgSecretKey',
187  'wgUseInstantCommons',
188  'wgUpgradeKey',
189  'wgDefaultSkin',
190  'wgPingback',
191  ];
192 
200  protected $internalDefaults = [
201  '_UserLang' => 'en',
202  '_Environment' => false,
203  '_RaiseMemory' => false,
204  '_UpgradeDone' => false,
205  '_InstallDone' => false,
206  '_Caches' => [],
207  '_InstallPassword' => '',
208  '_SameAccount' => true,
209  '_CreateDBAccount' => false,
210  '_NamespaceType' => 'site-name',
211  '_AdminName' => '', // will be set later, when the user selects language
212  '_AdminPassword' => '',
213  '_AdminPasswordConfirm' => '',
214  '_AdminEmail' => '',
215  '_Subscribe' => false,
216  '_SkipOptional' => 'continue',
217  '_RightsProfile' => 'wiki',
218  '_LicenseCode' => 'none',
219  '_CCDone' => false,
220  '_Extensions' => [],
221  '_Skins' => [],
222  '_MemCachedServers' => '',
223  '_UpgradeKeySupplied' => false,
224  '_ExistingDBSettings' => false,
225 
226  // $wgLogo is probably wrong (T50084); set something that will work.
227  // Single quotes work fine here, as LocalSettingsGenerator outputs this unescaped.
228  'wgLogo' => '$wgResourceBasePath/resources/assets/wiki.png',
229  'wgAuthenticationTokenVersion' => 1,
230  ];
231 
238  private $installSteps = [];
239 
245  protected $extraInstallSteps = [];
246 
252  protected $objectCaches = [
253  'apcu' => 'apcu_fetch',
254  'wincache' => 'wincache_ucache_get'
255  ];
256 
262  public $rightsProfiles = [
263  'wiki' => [],
264  'no-anon' => [
265  '*' => [ 'edit' => false ]
266  ],
267  'fishbowl' => [
268  '*' => [
269  'createaccount' => false,
270  'edit' => false,
271  ],
272  ],
273  'private' => [
274  '*' => [
275  'createaccount' => false,
276  'edit' => false,
277  'read' => false,
278  ],
279  ],
280  ];
281 
287  public $licenses = [
288  'cc-by' => [
289  'url' => 'https://creativecommons.org/licenses/by/4.0/',
290  'icon' => '$wgResourceBasePath/resources/assets/licenses/cc-by.png',
291  ],
292  'cc-by-sa' => [
293  'url' => 'https://creativecommons.org/licenses/by-sa/4.0/',
294  'icon' => '$wgResourceBasePath/resources/assets/licenses/cc-by-sa.png',
295  ],
296  'cc-by-nc-sa' => [
297  'url' => 'https://creativecommons.org/licenses/by-nc-sa/4.0/',
298  'icon' => '$wgResourceBasePath/resources/assets/licenses/cc-by-nc-sa.png',
299  ],
300  'cc-0' => [
301  'url' => 'https://creativecommons.org/publicdomain/zero/1.0/',
302  'icon' => '$wgResourceBasePath/resources/assets/licenses/cc-0.png',
303  ],
304  'gfdl' => [
305  'url' => 'https://www.gnu.org/copyleft/fdl.html',
306  'icon' => '$wgResourceBasePath/resources/assets/licenses/gnu-fdl.png',
307  ],
308  'none' => [
309  'url' => '',
310  'icon' => '',
311  'text' => ''
312  ],
313  'cc-choose' => [
314  // Details will be filled in by the selector.
315  'url' => '',
316  'icon' => '',
317  'text' => '',
318  ],
319  ];
320 
325  'https://lists.wikimedia.org/mailman/subscribe/mediawiki-announce';
326 
331  'ca', 'cs', 'da', 'de', 'en', 'es', 'et', 'eu', 'fi', 'fr', 'hr', 'hu',
332  'it', 'ja', 'ko', 'lt', 'nl', 'no', 'pl', 'pt', 'pt-br', 'ro', 'ru',
333  'sl', 'sr', 'sv', 'tr', 'uk'
334  ];
335 
344  abstract public function showMessage( $msg, ...$params );
345 
351  abstract public function showError( $msg, ...$params );
352 
357  abstract public function showStatusMessage( Status $status );
358 
369  public static function getInstallerConfig( Config $baseConfig ) {
370  $configOverrides = new HashConfig();
371 
372  // disable (problematic) object cache types explicitly, preserving all other (working) ones
373  // bug T113843
374  $emptyCache = [ 'class' => EmptyBagOStuff::class ];
375 
376  $objectCaches = [
377  CACHE_NONE => $emptyCache,
378  CACHE_DB => $emptyCache,
379  CACHE_ANYTHING => $emptyCache,
380  CACHE_MEMCACHED => $emptyCache,
381  ] + $baseConfig->get( 'ObjectCaches' );
382 
383  $configOverrides->set( 'ObjectCaches', $objectCaches );
384 
385  // Load the installer's i18n.
386  $messageDirs = $baseConfig->get( 'MessagesDirs' );
387  $messageDirs['MediawikiInstaller'] = __DIR__ . '/i18n';
388 
389  $configOverrides->set( 'MessagesDirs', $messageDirs );
390 
391  $installerConfig = new MultiConfig( [ $configOverrides, $baseConfig ] );
392 
393  // make sure we use the installer config as the main config
394  $configRegistry = $baseConfig->get( 'ConfigRegistry' );
395  $configRegistry['main'] = function () use ( $installerConfig ) {
396  return $installerConfig;
397  };
398 
399  $configOverrides->set( 'ConfigRegistry', $configRegistry );
400 
401  return $installerConfig;
402  }
403 
407  public function __construct() {
408  global $wgMemc, $wgUser, $wgObjectCaches;
409 
410  $defaultConfig = new GlobalVarConfig(); // all the stuff from DefaultSettings.php
411  $installerConfig = self::getInstallerConfig( $defaultConfig );
412 
413  // Reset all services and inject config overrides
414  MediaWikiServices::resetGlobalInstance( $installerConfig );
415 
416  // Don't attempt to load user language options (T126177)
417  // This will be overridden in the web installer with the user-specified language
418  RequestContext::getMain()->setLanguage( 'en' );
419 
420  // Disable all global services, since we don't have any configuration yet!
421  MediaWikiServices::disableStorageBackend();
422 
423  $mwServices = MediaWikiServices::getInstance();
424 
425  // Disable i18n cache
426  $mwServices->getLocalisationCache()->disableBackend();
427 
428  // Clear language cache so the old i18n cache doesn't sneak back in
430 
431  // Disable object cache (otherwise CACHE_ANYTHING will try CACHE_DB and
432  // SqlBagOStuff will then throw since we just disabled wfGetDB)
433  $wgObjectCaches = $mwServices->getMainConfig()->get( 'ObjectCaches' );
435 
436  // Disable interwiki lookup, to avoid database access during parses
437  $mwServices->redefineService( 'InterwikiLookup', function () {
438  return new NullInterwikiLookup();
439  } );
440 
441  // Having a user with id = 0 safeguards us from DB access via User::loadOptions().
442  $wgUser = User::newFromId( 0 );
443  RequestContext::getMain()->setUser( $wgUser );
444 
445  $this->settings = $this->internalDefaults;
446 
447  foreach ( $this->defaultVarNames as $var ) {
448  $this->settings[$var] = $GLOBALS[$var];
449  }
450 
451  $this->doEnvironmentPreps();
452 
453  $this->compiledDBs = [];
454  foreach ( self::getDBTypes() as $type ) {
455  $installer = $this->getDBInstaller( $type );
456 
457  if ( !$installer->isCompiled() ) {
458  continue;
459  }
460  $this->compiledDBs[] = $type;
461  }
462 
463  $this->parserTitle = Title::newFromText( 'Installer' );
464  $this->parserOptions = new ParserOptions( $wgUser ); // language will be wrong :(
465  $this->parserOptions->setTidy( true );
466  // Don't try to access DB before user language is initialised
467  $this->setParserLanguage( $mwServices->getLanguageFactory()->getLanguage( 'en' ) );
468  }
469 
475  public static function getDBTypes() {
476  return self::$dbTypes;
477  }
478 
492  public function doEnvironmentChecks() {
493  // PHP version has already been checked by entry scripts
494  // Show message here for information purposes
495  $this->showMessage( 'config-env-php', PHP_VERSION );
496 
497  $good = true;
498  // Must go here because an old version of PCRE can prevent other checks from completing
499  $pcreVersion = explode( ' ', PCRE_VERSION, 2 )[0];
500  if ( version_compare( $pcreVersion, self::MINIMUM_PCRE_VERSION, '<' ) ) {
501  $this->showError( 'config-pcre-old', self::MINIMUM_PCRE_VERSION, $pcreVersion );
502  $good = false;
503  } else {
504  foreach ( $this->envChecks as $check ) {
505  $status = $this->$check();
506  if ( $status === false ) {
507  $good = false;
508  }
509  }
510  }
511 
512  $this->setVar( '_Environment', $good );
513 
514  return $good ? Status::newGood() : Status::newFatal( 'config-env-bad' );
515  }
516 
517  public function doEnvironmentPreps() {
518  foreach ( $this->envPreps as $prep ) {
519  $this->$prep();
520  }
521  }
522 
529  public function setVar( $name, $value ) {
530  $this->settings[$name] = $value;
531  }
532 
543  public function getVar( $name, $default = null ) {
544  return $this->settings[$name] ?? $default;
545  }
546 
552  public function getCompiledDBs() {
553  return $this->compiledDBs;
554  }
555 
563  public static function getDBInstallerClass( $type ) {
564  return ucfirst( $type ) . 'Installer';
565  }
566 
574  public function getDBInstaller( $type = false ) {
575  if ( !$type ) {
576  $type = $this->getVar( 'wgDBtype' );
577  }
578 
579  $type = strtolower( $type );
580 
581  if ( !isset( $this->dbInstallers[$type] ) ) {
582  $class = self::getDBInstallerClass( $type );
583  $this->dbInstallers[$type] = new $class( $this );
584  }
585 
586  return $this->dbInstallers[$type];
587  }
588 
594  public static function getExistingLocalSettings() {
595  global $IP;
596 
597  // You might be wondering why this is here. Well if you don't do this
598  // then some poorly-formed extensions try to call their own classes
599  // after immediately registering them. We really need to get extension
600  // registration out of the global scope and into a real format.
601  // @see https://phabricator.wikimedia.org/T69440
602  global $wgAutoloadClasses;
603  $wgAutoloadClasses = [];
604 
605  // LocalSettings.php should not call functions, except wfLoadSkin/wfLoadExtensions
606  // Define the required globals here, to ensure, the functions can do it work correctly.
607  // phpcs:ignore MediaWiki.VariableAnalysis.UnusedGlobalVariables
609 
610  Wikimedia\suppressWarnings();
611  $_lsExists = file_exists( "$IP/LocalSettings.php" );
612  Wikimedia\restoreWarnings();
613 
614  if ( !$_lsExists ) {
615  return false;
616  }
617  unset( $_lsExists );
618 
619  require "$IP/includes/DefaultSettings.php";
620  require "$IP/LocalSettings.php";
621 
622  return get_defined_vars();
623  }
624 
634  public function getFakePassword( $realPassword ) {
635  return str_repeat( '*', strlen( $realPassword ) );
636  }
637 
645  public function setPassword( $name, $value ) {
646  if ( !preg_match( '/^\*+$/', $value ) ) {
647  $this->setVar( $name, $value );
648  }
649  }
650 
662  public static function maybeGetWebserverPrimaryGroup() {
663  if ( !function_exists( 'posix_getegid' ) || !function_exists( 'posix_getpwuid' ) ) {
664  # I don't know this, this isn't UNIX.
665  return null;
666  }
667 
668  # posix_getegid() *not* getmygid() because we want the group of the webserver,
669  # not whoever owns the current script.
670  $gid = posix_getegid();
671  return posix_getpwuid( $gid )['name'] ?? null;
672  }
673 
690  public function parse( $text, $lineStart = false ) {
691  $parser = MediaWikiServices::getInstance()->getParser();
692 
693  try {
694  $out = $parser->parse( $text, $this->parserTitle, $this->parserOptions, $lineStart );
695  $html = $out->getText( [
696  'enableSectionEditLinks' => false,
697  'unwrap' => true,
698  ] );
699  $html = Parser::stripOuterParagraph( $html );
700  } catch ( Wikimedia\Services\ServiceDisabledException $e ) {
701  $html = '<!--DB access attempted during parse--> ' . htmlspecialchars( $text );
702  }
703 
704  return $html;
705  }
706 
710  public function getParserOptions() {
711  return $this->parserOptions;
712  }
713 
714  public function disableLinkPopups() {
715  $this->parserOptions->setExternalLinkTarget( false );
716  }
717 
718  public function restoreLinkPopups() {
719  global $wgExternalLinkTarget;
720  $this->parserOptions->setExternalLinkTarget( $wgExternalLinkTarget );
721  }
722 
731  public function populateSiteStats( DatabaseInstaller $installer ) {
732  $status = $installer->getConnection();
733  if ( !$status->isOK() ) {
734  return $status;
735  }
736  // @phan-suppress-next-line PhanUndeclaredMethod
737  $status->value->insert(
738  'site_stats',
739  [
740  'ss_row_id' => 1,
741  'ss_total_edits' => 0,
742  'ss_good_articles' => 0,
743  'ss_total_pages' => 0,
744  'ss_users' => 0,
745  'ss_active_users' => 0,
746  'ss_images' => 0
747  ],
748  __METHOD__, 'IGNORE'
749  );
750 
751  return Status::newGood();
752  }
753 
758  protected function envCheckDB() {
759  global $wgLang;
761  $dbType = $this->getVar( 'wgDBtype' );
762 
763  $allNames = [];
764 
765  // Messages: config-type-mysql, config-type-postgres, config-type-sqlite
766  foreach ( self::getDBTypes() as $name ) {
767  $allNames[] = wfMessage( "config-type-$name" )->text();
768  }
769 
770  $databases = $this->getCompiledDBs();
771 
772  $databases = array_flip( $databases );
773  $ok = true;
774  foreach ( array_keys( $databases ) as $db ) {
775  $installer = $this->getDBInstaller( $db );
776  $status = $installer->checkPrerequisites();
777  if ( !$status->isGood() ) {
778  if ( !$this instanceof WebInstaller && $db === $dbType ) {
779  // Strictly check the key database type instead of just outputting message
780  // Note: No perform this check run from the web installer, since this method always called by
781  // the welcome page under web installation, so $dbType will always be 'mysql'
782  $ok = false;
783  }
784  $this->showStatusMessage( $status );
785  unset( $databases[$db] );
786  }
787  }
788  $databases = array_flip( $databases );
789  if ( !$databases ) {
790  $this->showError( 'config-no-db', $wgLang->commaList( $allNames ), count( $allNames ) );
791  return false;
792  }
793  return $ok;
794  }
795 
804  protected function envCheckPCRE() {
805  Wikimedia\suppressWarnings();
806  $regexd = preg_replace( '/[\x{0430}-\x{04FF}]/iu', '', '-АБВГД-' );
807  // Need to check for \p support too, as PCRE can be compiled
808  // with utf8 support, but not unicode property support.
809  // check that \p{Zs} (space separators) matches
810  // U+3000 (Ideographic space)
811  $regexprop = preg_replace( '/\p{Zs}/u', '', "-\u{3000}-" );
812  Wikimedia\restoreWarnings();
813  if ( $regexd != '--' || $regexprop != '--' ) {
814  $this->showError( 'config-pcre-no-utf8' );
815 
816  return false;
817  }
818 
819  return true;
820  }
821 
826  protected function envCheckMemory() {
827  $limit = ini_get( 'memory_limit' );
828 
829  if ( !$limit || $limit == -1 ) {
830  return true;
831  }
832 
833  $n = wfShorthandToInteger( $limit );
834 
835  if ( $n < $this->minMemorySize * 1024 * 1024 ) {
836  $newLimit = "{$this->minMemorySize}M";
837 
838  if ( ini_set( "memory_limit", $newLimit ) === false ) {
839  $this->showMessage( 'config-memory-bad', $limit );
840  } else {
841  $this->showMessage( 'config-memory-raised', $limit, $newLimit );
842  $this->setVar( '_RaiseMemory', true );
843  }
844  }
845 
846  return true;
847  }
848 
852  protected function envCheckCache() {
853  $caches = [];
854  foreach ( $this->objectCaches as $name => $function ) {
855  if ( function_exists( $function ) ) {
856  $caches[$name] = true;
857  }
858  }
859 
860  if ( !$caches ) {
861  $this->showMessage( 'config-no-cache-apcu' );
862  }
863 
864  $this->setVar( '_Caches', $caches );
865  }
866 
871  protected function envCheckModSecurity() {
872  if ( self::apacheModulePresent( 'mod_security' )
873  || self::apacheModulePresent( 'mod_security2' ) ) {
874  $this->showMessage( 'config-mod-security' );
875  }
876 
877  return true;
878  }
879 
884  protected function envCheckDiff3() {
885  $names = [ "gdiff3", "diff3" ];
886  if ( wfIsWindows() ) {
887  $names[] = 'diff3.exe';
888  }
889  $versionInfo = [ '--version', 'GNU diffutils' ];
890 
891  $diff3 = ExecutableFinder::findInDefaultPaths( $names, $versionInfo );
892 
893  if ( $diff3 ) {
894  $this->setVar( 'wgDiff3', $diff3 );
895  } else {
896  $this->setVar( 'wgDiff3', false );
897  $this->showMessage( 'config-diff3-bad' );
898  }
899 
900  return true;
901  }
902 
907  protected function envCheckGraphics() {
908  $names = wfIsWindows() ? 'convert.exe' : 'convert';
909  $versionInfo = [ '-version', 'ImageMagick' ];
910  $convert = ExecutableFinder::findInDefaultPaths( $names, $versionInfo );
911 
912  $this->setVar( 'wgImageMagickConvertCommand', '' );
913  if ( $convert ) {
914  $this->setVar( 'wgImageMagickConvertCommand', $convert );
915  $this->showMessage( 'config-imagemagick', $convert );
916 
917  return true;
918  } elseif ( function_exists( 'imagejpeg' ) ) {
919  $this->showMessage( 'config-gd' );
920  } else {
921  $this->showMessage( 'config-no-scaling' );
922  }
923 
924  return true;
925  }
926 
933  protected function envCheckGit() {
934  $names = wfIsWindows() ? 'git.exe' : 'git';
935  $versionInfo = [ '--version', 'git version' ];
936 
937  $git = ExecutableFinder::findInDefaultPaths( $names, $versionInfo );
938 
939  if ( $git ) {
940  $this->setVar( 'wgGitBin', $git );
941  $this->showMessage( 'config-git', $git );
942  } else {
943  $this->setVar( 'wgGitBin', false );
944  $this->showMessage( 'config-git-bad' );
945  }
946 
947  return true;
948  }
949 
955  protected function envCheckServer() {
956  $server = $this->envGetDefaultServer();
957  if ( $server !== null ) {
958  $this->showMessage( 'config-using-server', $server );
959  }
960  return true;
961  }
962 
968  protected function envCheckPath() {
969  $this->showMessage(
970  'config-using-uri',
971  $this->getVar( 'wgServer' ),
972  $this->getVar( 'wgScriptPath' )
973  );
974  return true;
975  }
976 
981  protected function envCheckShellLocale() {
982  $os = php_uname( 's' );
983  $supported = [ 'Linux', 'SunOS', 'HP-UX', 'Darwin' ]; # Tested these
984 
985  if ( !in_array( $os, $supported ) ) {
986  return true;
987  }
988 
989  if ( Shell::isDisabled() ) {
990  return true;
991  }
992 
993  # Get a list of available locales.
994  $result = Shell::command( '/usr/bin/locale', '-a' )
995  ->execute();
996 
997  if ( $result->getExitCode() != 0 ) {
998  return true;
999  }
1000 
1001  $lines = $result->getStdout();
1002  $lines = array_map( 'trim', explode( "\n", $lines ) );
1003  $candidatesByLocale = [];
1004  $candidatesByLang = [];
1005  foreach ( $lines as $line ) {
1006  if ( $line === '' ) {
1007  continue;
1008  }
1009 
1010  if ( !preg_match( '/^([a-zA-Z]+)(_[a-zA-Z]+|)\.(utf8|UTF-8)(@[a-zA-Z_]*|)$/i', $line, $m ) ) {
1011  continue;
1012  }
1013 
1014  list( , $lang, , , ) = $m;
1015 
1016  $candidatesByLocale[$m[0]] = $m;
1017  $candidatesByLang[$lang][] = $m;
1018  }
1019 
1020  # Try the current value of LANG.
1021  if ( isset( $candidatesByLocale[getenv( 'LANG' )] ) ) {
1022  $this->setVar( 'wgShellLocale', getenv( 'LANG' ) );
1023 
1024  return true;
1025  }
1026 
1027  # Try the most common ones.
1028  $commonLocales = [ 'C.UTF-8', 'en_US.UTF-8', 'en_US.utf8', 'de_DE.UTF-8', 'de_DE.utf8' ];
1029  foreach ( $commonLocales as $commonLocale ) {
1030  if ( isset( $candidatesByLocale[$commonLocale] ) ) {
1031  $this->setVar( 'wgShellLocale', $commonLocale );
1032 
1033  return true;
1034  }
1035  }
1036 
1037  # Is there an available locale in the Wiki's language?
1038  $wikiLang = $this->getVar( 'wgLanguageCode' );
1039 
1040  if ( isset( $candidatesByLang[$wikiLang] ) ) {
1041  $m = reset( $candidatesByLang[$wikiLang] );
1042  $this->setVar( 'wgShellLocale', $m[0] );
1043 
1044  return true;
1045  }
1046 
1047  # Are there any at all?
1048  if ( count( $candidatesByLocale ) ) {
1049  $m = reset( $candidatesByLocale );
1050  $this->setVar( 'wgShellLocale', $m[0] );
1051 
1052  return true;
1053  }
1054 
1055  # Give up.
1056  return true;
1057  }
1058 
1063  protected function envCheckUploadsDirectory() {
1064  global $IP;
1065 
1066  $dir = $IP . '/images/';
1067  $url = $this->getVar( 'wgServer' ) . $this->getVar( 'wgScriptPath' ) . '/images/';
1068  $safe = !$this->dirIsExecutable( $dir, $url );
1069 
1070  if ( !$safe ) {
1071  $this->showMessage( 'config-uploads-not-safe', $dir );
1072  }
1073 
1074  return true;
1075  }
1076 
1082  protected function envCheckSuhosinMaxValueLength() {
1083  $currentValue = ini_get( 'suhosin.get.max_value_length' );
1084  $minRequired = 2000;
1085  $recommended = 5000;
1086  if ( $currentValue > 0 && $currentValue < $minRequired ) {
1087  $this->showError( 'config-suhosin-max-value-length', $currentValue, $minRequired, $recommended );
1088  return false;
1089  }
1090 
1091  return true;
1092  }
1093 
1100  protected function envCheck64Bit() {
1101  if ( PHP_INT_SIZE == 4 ) {
1102  $this->showMessage( 'config-using-32bit' );
1103  }
1104 
1105  return true;
1106  }
1107 
1111  protected function envCheckLibicu() {
1119  $not_normal_c = "\u{FA6C}";
1120  $normal_c = "\u{242EE}";
1121 
1122  $useNormalizer = 'php';
1123  $needsUpdate = false;
1124 
1125  if ( function_exists( 'normalizer_normalize' ) ) {
1126  $useNormalizer = 'intl';
1127  $intl = normalizer_normalize( $not_normal_c, Normalizer::FORM_C );
1128  if ( $intl !== $normal_c ) {
1129  $needsUpdate = true;
1130  }
1131  }
1132 
1133  // Uses messages 'config-unicode-using-php' and 'config-unicode-using-intl'
1134  if ( $useNormalizer === 'php' ) {
1135  $this->showMessage( 'config-unicode-pure-php-warning' );
1136  } else {
1137  $this->showMessage( 'config-unicode-using-' . $useNormalizer );
1138  if ( $needsUpdate ) {
1139  $this->showMessage( 'config-unicode-update-warning' );
1140  }
1141  }
1142  }
1143 
1147  protected function envPrepServer() {
1148  $server = $this->envGetDefaultServer();
1149  if ( $server !== null ) {
1150  $this->setVar( 'wgServer', $server );
1151  }
1152  }
1153 
1158  abstract protected function envGetDefaultServer();
1159 
1163  protected function envPrepPath() {
1164  global $IP;
1165  $IP = dirname( dirname( __DIR__ ) );
1166  $this->setVar( 'IP', $IP );
1167  }
1168 
1177  public function dirIsExecutable( $dir, $url ) {
1178  $scriptTypes = [
1179  'php' => [
1180  "<?php echo 'exec';",
1181  "#!/var/env php\n<?php echo 'exec';",
1182  ],
1183  ];
1184 
1185  // it would be good to check other popular languages here, but it'll be slow.
1186 
1187  Wikimedia\suppressWarnings();
1188 
1189  foreach ( $scriptTypes as $ext => $contents ) {
1190  foreach ( $contents as $source ) {
1191  $file = 'exectest.' . $ext;
1192 
1193  if ( !file_put_contents( $dir . $file, $source ) ) {
1194  break;
1195  }
1196 
1197  try {
1198  $text = MediaWikiServices::getInstance()->getHttpRequestFactory()->
1199  get( $url . $file, [ 'timeout' => 3 ], __METHOD__ );
1200  } catch ( Exception $e ) {
1201  // HttpRequestFactory::get can throw with allow_url_fopen = false and no curl
1202  // extension.
1203  $text = null;
1204  }
1205  unlink( $dir . $file );
1206 
1207  if ( $text == 'exec' ) {
1208  Wikimedia\restoreWarnings();
1209 
1210  return $ext;
1211  }
1212  }
1213  }
1214 
1215  Wikimedia\restoreWarnings();
1216 
1217  return false;
1218  }
1219 
1226  public static function apacheModulePresent( $moduleName ) {
1227  if ( function_exists( 'apache_get_modules' ) && in_array( $moduleName, apache_get_modules() ) ) {
1228  return true;
1229  }
1230  // try it the hard way
1231  ob_start();
1232  phpinfo( INFO_MODULES );
1233  $info = ob_get_clean();
1234 
1235  return strpos( $info, $moduleName ) !== false;
1236  }
1237 
1243  public function setParserLanguage( $lang ) {
1244  $this->parserOptions->setTargetLanguage( $lang );
1245  $this->parserOptions->setUserLang( $lang );
1246  }
1247 
1253  protected function getDocUrl( $page ) {
1254  return "{$_SERVER['PHP_SELF']}?page=" . urlencode( $page );
1255  }
1256 
1266  public function findExtensions( $directory = 'extensions' ) {
1267  switch ( $directory ) {
1268  case 'extensions':
1269  return $this->findExtensionsByType( 'extension', 'extensions' );
1270  case 'skins':
1271  return $this->findExtensionsByType( 'skin', 'skins' );
1272  default:
1273  throw new InvalidArgumentException( "Invalid extension type" );
1274  }
1275  }
1276 
1286  protected function findExtensionsByType( $type = 'extension', $directory = 'extensions' ) {
1287  if ( $this->getVar( 'IP' ) === null ) {
1288  return Status::newGood( [] );
1289  }
1290 
1291  $extDir = $this->getVar( 'IP' ) . '/' . $directory;
1292  if ( !is_readable( $extDir ) || !is_dir( $extDir ) ) {
1293  return Status::newGood( [] );
1294  }
1295 
1296  $dh = opendir( $extDir );
1297  $exts = [];
1298  $status = new Status;
1299  while ( ( $file = readdir( $dh ) ) !== false ) {
1300  // skip non-dirs and hidden directories
1301  if ( !is_dir( "$extDir/$file" ) || $file[0] === '.' ) {
1302  continue;
1303  }
1304  $extStatus = $this->getExtensionInfo( $type, $directory, $file );
1305  if ( $extStatus->isOK() ) {
1306  $exts[$file] = $extStatus->value;
1307  } elseif ( $extStatus->hasMessage( 'config-extension-not-found' ) ) {
1308  // (T225512) The directory is not actually an extension. Downgrade to warning.
1309  $status->warning( 'config-extension-not-found', $file );
1310  } else {
1311  $status->merge( $extStatus );
1312  }
1313  }
1314  closedir( $dh );
1315  uksort( $exts, 'strnatcasecmp' );
1316 
1317  $status->value = $exts;
1318 
1319  return $status;
1320  }
1321 
1329  protected function getExtensionInfo( $type, $parentRelPath, $name ) {
1330  if ( $this->getVar( 'IP' ) === null ) {
1331  throw new Exception( 'Cannot find extensions since the IP variable is not yet set' );
1332  }
1333  if ( $type !== 'extension' && $type !== 'skin' ) {
1334  throw new InvalidArgumentException( "Invalid extension type" );
1335  }
1336  $absDir = $this->getVar( 'IP' ) . "/$parentRelPath/$name";
1337  $relDir = "../$parentRelPath/$name";
1338  if ( !is_dir( $absDir ) ) {
1339  return Status::newFatal( 'config-extension-not-found', $name );
1340  }
1341  $jsonFile = $type . '.json';
1342  $fullJsonFile = "$absDir/$jsonFile";
1343  $isJson = file_exists( $fullJsonFile );
1344  $isPhp = false;
1345  if ( !$isJson ) {
1346  // Only fallback to PHP file if JSON doesn't exist
1347  $fullPhpFile = "$absDir/$name.php";
1348  $isPhp = file_exists( $fullPhpFile );
1349  }
1350  if ( !$isJson && !$isPhp ) {
1351  return Status::newFatal( 'config-extension-not-found', $name );
1352  }
1353 
1354  // Extension exists. Now see if there are screenshots
1355  $info = [];
1356  if ( is_dir( "$absDir/screenshots" ) ) {
1357  $paths = glob( "$absDir/screenshots/*.png" );
1358  foreach ( $paths as $path ) {
1359  $info['screenshots'][] = str_replace( $absDir, $relDir, $path );
1360  }
1361  }
1362 
1363  if ( $isJson ) {
1364  $jsonStatus = $this->readExtension( $fullJsonFile );
1365  if ( !$jsonStatus->isOK() ) {
1366  return $jsonStatus;
1367  }
1368  $info += $jsonStatus->value;
1369  }
1370 
1371  return Status::newGood( $info );
1372  }
1373 
1382  private function readExtension( $fullJsonFile, $extDeps = [], $skinDeps = [] ) {
1383  $load = [
1384  $fullJsonFile => 1
1385  ];
1386  if ( $extDeps ) {
1387  $extDir = $this->getVar( 'IP' ) . '/extensions';
1388  foreach ( $extDeps as $dep ) {
1389  $fname = "$extDir/$dep/extension.json";
1390  if ( !file_exists( $fname ) ) {
1391  return Status::newFatal( 'config-extension-not-found', $dep );
1392  }
1393  $load[$fname] = 1;
1394  }
1395  }
1396  if ( $skinDeps ) {
1397  $skinDir = $this->getVar( 'IP' ) . '/skins';
1398  foreach ( $skinDeps as $dep ) {
1399  $fname = "$skinDir/$dep/skin.json";
1400  if ( !file_exists( $fname ) ) {
1401  return Status::newFatal( 'config-extension-not-found', $dep );
1402  }
1403  $load[$fname] = 1;
1404  }
1405  }
1406  $registry = new ExtensionRegistry();
1407  try {
1408  $info = $registry->readFromQueue( $load );
1409  } catch ( ExtensionDependencyError $e ) {
1410  if ( $e->incompatibleCore || $e->incompatibleSkins
1411  || $e->incompatibleExtensions
1412  ) {
1413  // If something is incompatible with a dependency, we have no real
1414  // option besides skipping it
1415  return Status::newFatal( 'config-extension-dependency',
1416  basename( dirname( $fullJsonFile ) ), $e->getMessage() );
1417  } elseif ( $e->missingExtensions || $e->missingSkins ) {
1418  // There's an extension missing in the dependency tree,
1419  // so add those to the dependency list and try again
1420  $status = $this->readExtension(
1421  $fullJsonFile,
1422  array_merge( $extDeps, $e->missingExtensions ),
1423  array_merge( $skinDeps, $e->missingSkins )
1424  );
1425  if ( !$status->isOK() && !$status->hasMessage( 'config-extension-dependency' ) ) {
1426  $status = Status::newFatal( 'config-extension-dependency',
1427  basename( dirname( $fullJsonFile ) ), $status->getMessage() );
1428  }
1429  return $status;
1430  }
1431  // Some other kind of dependency error?
1432  return Status::newFatal( 'config-extension-dependency',
1433  basename( dirname( $fullJsonFile ) ), $e->getMessage() );
1434  }
1435  $ret = [];
1436  // The order of credits will be the order of $load,
1437  // so the first extension is the one we want to load,
1438  // everything else is a dependency
1439  $i = 0;
1440  foreach ( $info['credits'] as $name => $credit ) {
1441  $i++;
1442  if ( $i == 1 ) {
1443  // Extension we want to load
1444  continue;
1445  }
1446  $type = basename( $credit['path'] ) === 'skin.json' ? 'skins' : 'extensions';
1447  $ret['requires'][$type][] = $credit['name'];
1448  }
1449  $credits = array_values( $info['credits'] )[0];
1450  if ( isset( $credits['url'] ) ) {
1451  $ret['url'] = $credits['url'];
1452  }
1453  $ret['type'] = $credits['type'];
1454 
1455  return Status::newGood( $ret );
1456  }
1457 
1466  public function getDefaultSkin( array $skinNames ) {
1467  $defaultSkin = $GLOBALS['wgDefaultSkin'];
1468  if ( !$skinNames || in_array( $defaultSkin, $skinNames ) ) {
1469  return $defaultSkin;
1470  } else {
1471  return $skinNames[0];
1472  }
1473  }
1474 
1481  protected function includeExtensions() {
1482  global $IP;
1483  $exts = $this->getVar( '_Extensions' );
1484  $IP = $this->getVar( 'IP' );
1485 
1486  // Marker for DatabaseUpdater::loadExtensions so we don't
1487  // double load extensions
1488  define( 'MW_EXTENSIONS_LOADED', true );
1489 
1498  global $wgAutoloadClasses;
1499  $wgAutoloadClasses = [];
1500  $queue = [];
1501 
1502  require "$IP/includes/DefaultSettings.php";
1503 
1504  foreach ( $exts as $e ) {
1505  if ( file_exists( "$IP/extensions/$e/extension.json" ) ) {
1506  $queue["$IP/extensions/$e/extension.json"] = 1;
1507  } else {
1508  require_once "$IP/extensions/$e/$e.php";
1509  }
1510  }
1511 
1512  $registry = new ExtensionRegistry();
1513  $data = $registry->readFromQueue( $queue );
1514  $wgAutoloadClasses += $data['globals']['wgAutoloadClasses'];
1515 
1516  // @phan-suppress-next-line PhanUndeclaredVariable $wgHooks is set by DefaultSettings
1517  $hooksWeWant = $wgHooks['LoadExtensionSchemaUpdates'] ?? [];
1518 
1519  if ( isset( $data['globals']['wgHooks']['LoadExtensionSchemaUpdates'] ) ) {
1520  $hooksWeWant = array_merge_recursive(
1521  $hooksWeWant,
1522  $data['globals']['wgHooks']['LoadExtensionSchemaUpdates']
1523  );
1524  }
1525  // Unset everyone else's hooks. Lord knows what someone might be doing
1526  // in ParserFirstCallInit (see T29171)
1527  $GLOBALS['wgHooks'] = [ 'LoadExtensionSchemaUpdates' => $hooksWeWant ];
1528 
1529  return Status::newGood();
1530  }
1531 
1545  protected function getInstallSteps( DatabaseInstaller $installer ) {
1546  $coreInstallSteps = [
1547  [ 'name' => 'database', 'callback' => [ $installer, 'setupDatabase' ] ],
1548  [ 'name' => 'tables', 'callback' => [ $installer, 'createTables' ] ],
1549  [ 'name' => 'interwiki', 'callback' => [ $installer, 'populateInterwikiTable' ] ],
1550  [ 'name' => 'stats', 'callback' => [ $this, 'populateSiteStats' ] ],
1551  [ 'name' => 'keys', 'callback' => [ $this, 'generateKeys' ] ],
1552  [ 'name' => 'updates', 'callback' => [ $installer, 'insertUpdateKeys' ] ],
1553  [ 'name' => 'sysop', 'callback' => [ $this, 'createSysop' ] ],
1554  [ 'name' => 'mainpage', 'callback' => [ $this, 'createMainpage' ] ],
1555  ];
1556 
1557  // Build the array of install steps starting from the core install list,
1558  // then adding any callbacks that wanted to attach after a given step
1559  foreach ( $coreInstallSteps as $step ) {
1560  $this->installSteps[] = $step;
1561  if ( isset( $this->extraInstallSteps[$step['name']] ) ) {
1562  $this->installSteps = array_merge(
1563  $this->installSteps,
1564  $this->extraInstallSteps[$step['name']]
1565  );
1566  }
1567  }
1568 
1569  // Prepend any steps that want to be at the beginning
1570  if ( isset( $this->extraInstallSteps['BEGINNING'] ) ) {
1571  $this->installSteps = array_merge(
1572  $this->extraInstallSteps['BEGINNING'],
1573  $this->installSteps
1574  );
1575  }
1576 
1577  // Extensions should always go first, chance to tie into hooks and such
1578  if ( count( $this->getVar( '_Extensions' ) ) ) {
1579  array_unshift( $this->installSteps,
1580  [ 'name' => 'extensions', 'callback' => [ $this, 'includeExtensions' ] ]
1581  );
1582  $this->installSteps[] = [
1583  'name' => 'extension-tables',
1584  'callback' => [ $installer, 'createExtensionTables' ]
1585  ];
1586  }
1587 
1588  return $this->installSteps;
1589  }
1590 
1599  public function performInstallation( $startCB, $endCB ) {
1600  $installResults = [];
1601  $installer = $this->getDBInstaller();
1602  $installer->preInstall();
1603  $steps = $this->getInstallSteps( $installer );
1604  foreach ( $steps as $stepObj ) {
1605  $name = $stepObj['name'];
1606  call_user_func_array( $startCB, [ $name ] );
1607 
1608  // Perform the callback step
1609  $status = call_user_func( $stepObj['callback'], $installer );
1610 
1611  // Output and save the results
1612  call_user_func( $endCB, $name, $status );
1613  $installResults[$name] = $status;
1614 
1615  // If we've hit some sort of fatal, we need to bail.
1616  // Callback already had a chance to do output above.
1617  if ( !$status->isOK() ) {
1618  break;
1619  }
1620  }
1621  if ( $status->isOK() ) {
1622  $this->showMessage(
1623  'config-install-db-success'
1624  );
1625  $this->setVar( '_InstallDone', true );
1626  }
1627 
1628  return $installResults;
1629  }
1630 
1636  public function generateKeys() {
1637  $keys = [ 'wgSecretKey' => 64 ];
1638  if ( strval( $this->getVar( 'wgUpgradeKey' ) ) === '' ) {
1639  $keys['wgUpgradeKey'] = 16;
1640  }
1641 
1642  return $this->doGenerateKeys( $keys );
1643  }
1644 
1651  protected function doGenerateKeys( $keys ) {
1652  $status = Status::newGood();
1653 
1654  foreach ( $keys as $name => $length ) {
1655  $secretKey = MWCryptRand::generateHex( $length );
1656  $this->setVar( $name, $secretKey );
1657  }
1658 
1659  return $status;
1660  }
1661 
1667  protected function createSysop() {
1668  $name = $this->getVar( '_AdminName' );
1669  $user = User::newFromName( $name );
1670 
1671  if ( !$user ) {
1672  // We should've validated this earlier anyway!
1673  return Status::newFatal( 'config-admin-error-user', $name );
1674  }
1675 
1676  if ( $user->idForName() == 0 ) {
1677  $user->addToDatabase();
1678 
1679  try {
1680  $user->setPassword( $this->getVar( '_AdminPassword' ) );
1681  } catch ( PasswordError $pwe ) {
1682  return Status::newFatal( 'config-admin-error-password', $name, $pwe->getMessage() );
1683  }
1684 
1685  $user->addGroup( 'sysop' );
1686  $user->addGroup( 'bureaucrat' );
1687  $user->addGroup( 'interface-admin' );
1688  if ( $this->getVar( '_AdminEmail' ) ) {
1689  $user->setEmail( $this->getVar( '_AdminEmail' ) );
1690  }
1691  $user->saveSettings();
1692 
1693  // Update user count
1694  $ssUpdate = SiteStatsUpdate::factory( [ 'users' => 1 ] );
1695  $ssUpdate->doUpdate();
1696  }
1697  $status = Status::newGood();
1698 
1699  if ( $this->getVar( '_Subscribe' ) && $this->getVar( '_AdminEmail' ) ) {
1700  $this->subscribeToMediaWikiAnnounce( $status );
1701  }
1702 
1703  return $status;
1704  }
1705 
1710  $params = [
1711  'email' => $this->getVar( '_AdminEmail' ),
1712  'language' => 'en',
1713  'digest' => 0
1714  ];
1715 
1716  // Mailman doesn't support as many languages as we do, so check to make
1717  // sure their selected language is available
1718  $myLang = $this->getVar( '_UserLang' );
1719  if ( in_array( $myLang, $this->mediaWikiAnnounceLanguages ) ) {
1720  $myLang = $myLang == 'pt-br' ? 'pt_BR' : $myLang; // rewrite to Mailman's pt_BR
1721  $params['language'] = $myLang;
1722  }
1723 
1725  $res = MWHttpRequest::factory( $this->mediaWikiAnnounceUrl,
1726  [ 'method' => 'POST', 'postData' => $params ], __METHOD__ )->execute();
1727  if ( !$res->isOK() ) {
1728  $s->warning( 'config-install-subscribe-fail', $res->getMessage() );
1729  }
1730  } else {
1731  $s->warning( 'config-install-subscribe-notpossible' );
1732  }
1733  }
1734 
1741  protected function createMainpage( DatabaseInstaller $installer ) {
1742  $status = Status::newGood();
1744  if ( $title->exists() ) {
1745  $status->warning( 'config-install-mainpage-exists' );
1746  return $status;
1747  }
1748  try {
1749  $page = WikiPage::factory( $title );
1750  $content = new WikitextContent(
1751  wfMessage( 'mainpagetext' )->inContentLanguage()->text() . "\n\n" .
1752  wfMessage( 'mainpagedocfooter' )->inContentLanguage()->text()
1753  );
1754 
1755  $status = $page->doEditContent( $content,
1756  '',
1757  EDIT_NEW,
1758  false,
1759  User::newSystemUser( 'MediaWiki default' )
1760  );
1761  } catch ( Exception $e ) {
1762  // using raw, because $wgShowExceptionDetails can not be set yet
1763  $status->fatal( 'config-install-mainpage-failed', $e->getMessage() );
1764  }
1765 
1766  return $status;
1767  }
1768 
1772  public static function overrideConfig() {
1773  // Use PHP's built-in session handling, since MediaWiki's
1774  // SessionHandler can't work before we have an object cache set up.
1775  if ( !defined( 'MW_NO_SESSION_HANDLER' ) ) {
1776  define( 'MW_NO_SESSION_HANDLER', 1 );
1777  }
1778 
1779  // Don't access the database
1780  $GLOBALS['wgUseDatabaseMessages'] = false;
1781  // Don't cache langconv tables
1782  $GLOBALS['wgLanguageConverterCacheType'] = CACHE_NONE;
1783  // Don't try to cache ResourceLoader dependencies in the database
1784  $GLOBALS['wgResourceLoaderUseObjectCacheForDeps'] = true;
1785  // Debug-friendly
1786  $GLOBALS['wgShowExceptionDetails'] = true;
1787  $GLOBALS['wgShowHostnames'] = true;
1788  // Don't break forms
1789  $GLOBALS['wgExternalLinkTarget'] = '_blank';
1790 
1791  // Allow multiple ob_flush() calls
1792  $GLOBALS['wgDisableOutputCompression'] = true;
1793 
1794  // Use a sensible cookie prefix (not my_wiki)
1795  $GLOBALS['wgCookiePrefix'] = 'mw_installer';
1796 
1797  // Some of the environment checks make shell requests, remove limits
1798  $GLOBALS['wgMaxShellMemory'] = 0;
1799 
1800  // Override the default CookieSessionProvider with a dummy
1801  // implementation that won't stomp on PHP's cookies.
1802  $GLOBALS['wgSessionProviders'] = [
1803  [
1804  'class' => InstallerSessionProvider::class,
1805  'args' => [ [
1806  'priority' => 1,
1807  ] ]
1808  ]
1809  ];
1810 
1811  // Don't try to use any object cache for SessionManager either.
1812  $GLOBALS['wgSessionCacheType'] = CACHE_NONE;
1813 
1814  // Set a dummy $wgServer to bypass the check in Setup.php, the
1815  // web installer will automatically detect it and not use this value.
1816  $GLOBALS['wgServer'] = 'https://🌻.invalid';
1817  }
1818 
1826  public function addInstallStep( $callback, $findStep = 'BEGINNING' ) {
1827  $this->extraInstallSteps[$findStep][] = $callback;
1828  }
1829 
1834  protected function disableTimeLimit() {
1835  Wikimedia\suppressWarnings();
1836  set_time_limit( 0 );
1837  Wikimedia\restoreWarnings();
1838  }
1839 }
ParserOptions
Set options of the Parser.
Definition: ParserOptions.php:42
MediaWiki\Shell\Shell
Executes shell commands.
Definition: Shell.php:44
Installer\__construct
__construct()
Constructor, always call this from child classes.
Definition: Installer.php:407
User\newFromId
static newFromId( $id)
Static factory method for creation from a given user ID.
Definition: User.php:559
Title\newFromText
static newFromText( $text, $defaultNamespace=NS_MAIN)
Create a new Title from text, such as what one would find in a link.
Definition: Title.php:332
StatusValue\newFatal
static newFatal( $message,... $parameters)
Factory function for fatal errors.
Definition: StatusValue.php:69
Installer\createMainpage
createMainpage(DatabaseInstaller $installer)
Insert Main Page with default content.
Definition: Installer.php:1741
Installer\parse
parse( $text, $lineStart=false)
Convert wikitext $text to HTML.
Definition: Installer.php:690
ExtensionDependencyError
Copyright (C) 2018 Kunal Mehta legoktm@member.fsf.org
Definition: ExtensionDependencyError.php:24
MultiConfig
Provides a fallback sequence for Config objects.
Definition: MultiConfig.php:28
MediaWiki\MediaWikiServices
MediaWikiServices is the service locator for the application scope of MediaWiki.
Definition: MediaWikiServices.php:137
$lang
if(!isset( $args[0])) $lang
Definition: testCompression.php:37
HashConfig
A Config instance which stores all settings as a member variable.
Definition: HashConfig.php:28
Installer\showStatusMessage
showStatusMessage(Status $status)
Show a message to the installing user by using a Status object.
Installer\dirIsExecutable
dirIsExecutable( $dir, $url)
Checks if scripts located in the given directory can be executed via the given URL.
Definition: Installer.php:1177
CACHE_NONE
const CACHE_NONE
Definition: Defines.php:91
Installer\envCheckLibicu
envCheckLibicu()
Check the libicu version.
Definition: Installer.php:1111
ExtensionRegistry
ExtensionRegistry class.
Definition: ExtensionRegistry.php:18
CACHE_MEMCACHED
const CACHE_MEMCACHED
Definition: Defines.php:93
Installer\populateSiteStats
populateSiteStats(DatabaseInstaller $installer)
Install step which adds a row to the site_stats table with appropriate initial values.
Definition: Installer.php:731
WebInstaller
Class for the core installer web interface.
Definition: WebInstaller.php:32
Installer\$extraInstallSteps
array $extraInstallSteps
Extra steps for installation, for things like DatabaseInstallers to modify.
Definition: Installer.php:245
DatabaseInstaller\getConnection
getConnection()
Connect to the database using the administrative user/password currently defined in the session.
Definition: DatabaseInstaller.php:182
Installer\$rightsProfiles
array $rightsProfiles
User rights profiles.
Definition: Installer.php:262
Installer\envCheckShellLocale
envCheckShellLocale()
Environment check for preferred locale in shell.
Definition: Installer.php:981
Installer\envCheckUploadsDirectory
envCheckUploadsDirectory()
Environment check for the permissions of the uploads directory.
Definition: Installer.php:1063
Installer\$settings
array $settings
Definition: Installer.php:65
Installer\envPrepServer
envPrepServer()
Environment prep for the server hostname.
Definition: Installer.php:1147
$file
if(PHP_SAPI !='cli-server') if(!isset( $_SERVER['SCRIPT_FILENAME'])) $file
Item class for a filearchive table row.
Definition: router.php:42
Installer\performInstallation
performInstallation( $startCB, $endCB)
Actually perform the installation.
Definition: Installer.php:1599
Installer\$mediaWikiAnnounceLanguages
$mediaWikiAnnounceLanguages
Supported language codes for Mailman.
Definition: Installer.php:330
PasswordError
Show an error when any operation involving passwords fails to run.
Definition: PasswordError.php:28
User\newFromName
static newFromName( $name, $validate='valid')
Static factory method for creation from username.
Definition: User.php:535
wfMessage
wfMessage( $key,... $params)
This is the function for getting translated interface messages.
Definition: GlobalFunctions.php:1201
MediaWiki\Interwiki\NullInterwikiLookup
An interwiki lookup that has no data, intended for use in the installer.
Definition: NullInterwikiLookup.php:29
$s
$s
Definition: mergeMessageFileList.php:185
Installer\$dbInstallers
array $dbInstallers
Cached DB installer instances, access using getDBInstaller().
Definition: Installer.php:79
Installer\setParserLanguage
setParserLanguage( $lang)
ParserOptions are constructed before we determined the language, so fix it.
Definition: Installer.php:1243
Title\newMainPage
static newMainPage(MessageLocalizer $localizer=null)
Create a new Title for the Main Page.
Definition: Title.php:657
Installer\addInstallStep
addInstallStep( $callback, $findStep='BEGINNING')
Add an installation step following the given step.
Definition: Installer.php:1826
Installer\$internalDefaults
array $internalDefaults
Variables that are stored alongside globals, and are used for any configuration of the installation p...
Definition: Installer.php:200
$res
$res
Definition: testCompression.php:57
Installer\setPassword
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:645
Installer\envGetDefaultServer
envGetDefaultServer()
Helper function to be called from envPrepServer()
$wgMemc
$wgMemc
Definition: Setup.php:685
Installer\setVar
setVar( $name, $value)
Set a MW configuration variable, or internal installer configuration variable.
Definition: Installer.php:529
Installer\$parserTitle
Title $parserTitle
Cached Title, used by parse().
Definition: Installer.php:93
Installer\$objectCaches
array $objectCaches
Known object cache types and the functions used to test for their existence.
Definition: Installer.php:252
Installer\$minMemorySize
int $minMemorySize
Minimum memory size in MB.
Definition: Installer.php:86
Status
Generic operation result class Has warning/error list, boolean status and arbitrary value.
Definition: Status.php:42
User\newSystemUser
static newSystemUser( $name, $options=[])
Static factory method for creation of a "system" user from username.
Definition: User.php:757
Installer\overrideConfig
static overrideConfig()
Override the necessary bits of the config to run an installation.
Definition: Installer.php:1772
Installer\createSysop
createSysop()
Create the first user account, grant it sysop, bureaucrat and interface-admin rights.
Definition: Installer.php:1667
Installer\getFakePassword
getFakePassword( $realPassword)
Get a fake password for sending back to the user in HTML.
Definition: Installer.php:634
Config
Interface for configuration instances.
Definition: Config.php:28
Installer\showMessage
showMessage( $msg,... $params)
UI interface for displaying a short message The parameters are like parameters to wfMessage().
Installer\envCheckSuhosinMaxValueLength
envCheckSuhosinMaxValueLength()
Checks if suhosin.get.max_value_length is set, and if so generate a warning because it is incompatibl...
Definition: Installer.php:1082
$wgHooks
$wgHooks
Global list of hooks.
Definition: DefaultSettings.php:7758
Installer\envPrepPath
envPrepPath()
Environment prep for setting $IP and $wgScriptPath.
Definition: Installer.php:1163
WikiPage\factory
static factory(Title $title)
Create a WikiPage object of the appropriate class for the given title.
Definition: WikiPage.php:143
Installer\envCheckDiff3
envCheckDiff3()
Search for GNU diff3.
Definition: Installer.php:884
Config\get
get( $name)
Get a configuration variable such as "Sitename" or "UploadMaintenance.".
Installer\generateKeys
generateKeys()
Generate $wgSecretKey.
Definition: Installer.php:1636
Installer\envCheckMemory
envCheckMemory()
Environment check for available memory.
Definition: Installer.php:826
$wgLang
$wgLang
Definition: Setup.php:776
$wgObjectCaches
$wgObjectCaches
Advanced object cache configuration.
Definition: DefaultSettings.php:2420
Installer\getCompiledDBs
getCompiledDBs()
Get a list of DBs supported by current PHP setup.
Definition: Installer.php:552
ObjectCache\getInstance
static getInstance( $id)
Get a cached instance of the specified type of cache object.
Definition: ObjectCache.php:78
$queue
$queue
Definition: mergeMessageFileList.php:157
Installer\envCheckCache
envCheckCache()
Environment check for compiled object cache types.
Definition: Installer.php:852
Installer\getExistingLocalSettings
static getExistingLocalSettings()
Determine if LocalSettings.php exists.
Definition: Installer.php:594
Installer\envCheckPath
envCheckPath()
Environment check to inform user which paths we've assumed.
Definition: Installer.php:968
Installer\doGenerateKeys
doGenerateKeys( $keys)
Generate a secret value for variables using a secure generator.
Definition: Installer.php:1651
$lines
$lines
Definition: router.php:61
Installer\$parserOptions
ParserOptions $parserOptions
Cached ParserOptions, used by parse().
Definition: Installer.php:100
$title
$title
Definition: testCompression.php:38
SiteStatsUpdate\factory
static factory(array $deltas)
Definition: SiteStatsUpdate.php:71
GlobalVarConfig
Accesses configuration settings from $GLOBALS.
Definition: GlobalVarConfig.php:28
$wgExternalLinkTarget
$wgExternalLinkTarget
Set a default target for external links, e.g.
Definition: DefaultSettings.php:4564
Installer\$dbTypes
static array $dbTypes
Known database types.
Definition: Installer.php:111
Installer\getVar
getVar( $name, $default=null)
Get an MW configuration variable, or internal installer configuration variable.
Definition: Installer.php:543
WikitextContent
Content object for wiki text pages.
Definition: WikitextContent.php:36
Installer\restoreLinkPopups
restoreLinkPopups()
Definition: Installer.php:718
Installer\getDefaultSkin
getDefaultSkin(array $skinNames)
Returns a default value to be used for $wgDefaultSkin: normally the one set in DefaultSettings,...
Definition: Installer.php:1466
Installer\findExtensions
findExtensions( $directory='extensions')
Find extensions or skins in a subdirectory of $IP.
Definition: Installer.php:1266
Installer\getInstallerConfig
static getInstallerConfig(Config $baseConfig)
Constructs a Config object that contains configuration settings that should be overwritten for the in...
Definition: Installer.php:369
$content
$content
Definition: router.php:78
Installer\$envPreps
array $envPreps
A list of environment preparation methods called by doEnvironmentPreps().
Definition: Installer.php:151
$wgExtensionDirectory
$wgExtensionDirectory
Filesystem extensions directory.
Definition: DefaultSettings.php:230
StatusValue\newGood
static newGood( $value=null)
Factory function for good results.
Definition: StatusValue.php:81
wfIsWindows
wfIsWindows()
Check if the operating system is Windows.
Definition: GlobalFunctions.php:1847
$line
$line
Definition: mcc.php:119
Installer\doEnvironmentPreps
doEnvironmentPreps()
Definition: Installer.php:517
Installer\readExtension
readExtension( $fullJsonFile, $extDeps=[], $skinDeps=[])
Definition: Installer.php:1382
CACHE_ANYTHING
const CACHE_ANYTHING
Definition: Defines.php:90
Installer\getDBInstaller
getDBInstaller( $type=false)
Get an instance of DatabaseInstaller for the specified DB type.
Definition: Installer.php:574
DatabaseInstaller
Base class for DBMS-specific installation helper classes.
Definition: DatabaseInstaller.php:37
Installer\envCheckDB
envCheckDB()
Environment check for DB types.
Definition: Installer.php:758
Installer\getInstallSteps
getInstallSteps(DatabaseInstaller $installer)
Get an array of install steps.
Definition: Installer.php:1545
MWCryptRand\generateHex
static generateHex( $chars)
Generate a run of cryptographically random data and return it in hexadecimal string format.
Definition: MWCryptRand.php:36
RequestContext\getMain
static getMain()
Get the RequestContext object associated with the main request.
Definition: RequestContext.php:451
$wgAutoloadClasses
$wgAutoloadClasses
Array mapping class names to filenames, for autoloading.
Definition: DefaultSettings.php:7661
Installer\$compiledDBs
array $compiledDBs
List of detected DBs, access using getCompiledDBs().
Definition: Installer.php:72
Installer\doEnvironmentChecks
doEnvironmentChecks()
Do initial checks of the PHP environment.
Definition: Installer.php:492
Language\$mLangObjCache
static array $mLangObjCache
Definition: Language.php:130
EDIT_NEW
const EDIT_NEW
Definition: Defines.php:141
Installer\envCheckGraphics
envCheckGraphics()
Environment check for ImageMagick and GD.
Definition: Installer.php:907
wfShorthandToInteger
wfShorthandToInteger( $string='', $default=-1)
Converts shorthand byte notation to integer form.
Definition: GlobalFunctions.php:2743
Installer\apacheModulePresent
static apacheModulePresent( $moduleName)
Checks for presence of an Apache module.
Definition: Installer.php:1226
Title
Represents a title within MediaWiki.
Definition: Title.php:42
Installer\envCheckPCRE
envCheckPCRE()
Environment check for the PCRE module.
Definition: Installer.php:804
Installer\getParserOptions
getParserOptions()
Definition: Installer.php:710
MWHttpRequest\canMakeRequests
static canMakeRequests()
Simple function to test if we can make any sort of requests at all, using cURL or fopen()
Definition: MWHttpRequest.php:175
$path
$path
Definition: NoLocalSettings.php:25
Installer\envCheck64Bit
envCheck64Bit()
Checks if we're running on 64 bit or not.
Definition: Installer.php:1100
Installer\$licenses
array $licenses
License types.
Definition: Installer.php:287
Installer\disableTimeLimit
disableTimeLimit()
Disable the time limit for execution.
Definition: Installer.php:1834
Wikimedia
This program is free software; you can redistribute it and/or modify it under the terms of the GNU Ge...
$keys
$keys
Definition: testCompression.php:72
$source
$source
Definition: mwdoc-filter.php:34
Installer\envCheckServer
envCheckServer()
Environment check to inform user which server we've assumed.
Definition: Installer.php:955
Installer
Base installer class.
Definition: Installer.php:52
$ext
if(!is_readable( $file)) $ext
Definition: router.php:48
Installer\MINIMUM_PCRE_VERSION
const MINIMUM_PCRE_VERSION
The oldest version of PCRE we can support.
Definition: Installer.php:60
Installer\findExtensionsByType
findExtensionsByType( $type='extension', $directory='extensions')
Find extensions or skins, and return an array containing the value for 'Name' for each found extensio...
Definition: Installer.php:1286
Installer\showError
showError( $msg,... $params)
Same as showMessage(), but for displaying errors.
ExecutableFinder\findInDefaultPaths
static findInDefaultPaths( $names, $versionInfo=false)
Same as locateExecutable(), but checks in getPossibleBinPaths() by default.
Definition: ExecutableFinder.php:96
Installer\getDBTypes
static getDBTypes()
Get a list of known DB types.
Definition: Installer.php:475
Installer\disableLinkPopups
disableLinkPopups()
Definition: Installer.php:714
Installer\$installSteps
array[] $installSteps
The actual list of installation steps.
Definition: Installer.php:238
Installer\$mediaWikiAnnounceUrl
$mediaWikiAnnounceUrl
URL to mediawiki-announce subscription.
Definition: Installer.php:324
$IP
$IP
Definition: WebStart.php:49
Installer\includeExtensions
includeExtensions()
Installs the auto-detected extensions.
Definition: Installer.php:1481
$wgStyleDirectory
$wgStyleDirectory
Filesystem stylesheets directory.
Definition: DefaultSettings.php:237
Installer\envCheckGit
envCheckGit()
Search for git.
Definition: Installer.php:933
Installer\getDocUrl
getDocUrl( $page)
Overridden by WebInstaller to provide lastPage parameters.
Definition: Installer.php:1253
$GLOBALS
$GLOBALS['IP']
Definition: ComposerHookHandler.php:6
Installer\subscribeToMediaWikiAnnounce
subscribeToMediaWikiAnnounce(Status $s)
Definition: Installer.php:1709
CACHE_DB
const CACHE_DB
Definition: Defines.php:92
MWHttpRequest\factory
static factory( $url, array $options=null, $caller=__METHOD__)
Generate a new request object.
Definition: MWHttpRequest.php:189
Installer\maybeGetWebserverPrimaryGroup
static maybeGetWebserverPrimaryGroup()
On POSIX systems return the primary group of the webserver we're running under.
Definition: Installer.php:662
Installer\getExtensionInfo
getExtensionInfo( $type, $parentRelPath, $name)
Definition: Installer.php:1329
Installer\$defaultVarNames
array $defaultVarNames
MediaWiki configuration globals that will eventually be passed through to LocalSettings....
Definition: Installer.php:163
Installer\getDBInstallerClass
static getDBInstallerClass( $type)
Get the DatabaseInstaller class name for this type.
Definition: Installer.php:563
Installer\$envChecks
array $envChecks
A list of environment check methods called by doEnvironmentChecks().
Definition: Installer.php:128
$type
$type
Definition: testCompression.php:52
Installer\envCheckModSecurity
envCheckModSecurity()
Scare user to death if they have mod_security or mod_security2.
Definition: Installer.php:871