MediaWiki  1.27.1
Installer.php
Go to the documentation of this file.
1 <?php
42 abstract class Installer {
43 
50  const MINIMUM_PCRE_VERSION = '7.2';
51 
55  protected $settings;
56 
62  protected $compiledDBs;
63 
69  protected $dbInstallers = [];
70 
76  protected $minMemorySize = 50;
77 
83  protected $parserTitle;
84 
90  protected $parserOptions;
91 
101  protected static $dbTypes = [
102  'mysql',
103  'postgres',
104  'oracle',
105  'mssql',
106  'sqlite',
107  ];
108 
120  protected $envChecks = [
121  'envCheckDB',
122  'envCheckBrokenXML',
123  'envCheckPCRE',
124  'envCheckMemory',
125  'envCheckCache',
126  'envCheckModSecurity',
127  'envCheckDiff3',
128  'envCheckGraphics',
129  'envCheckGit',
130  'envCheckServer',
131  'envCheckPath',
132  'envCheckShellLocale',
133  'envCheckUploadsDirectory',
134  'envCheckLibicu',
135  'envCheckSuhosinMaxValueLength',
136  ];
137 
143  protected $envPreps = [
144  'envPrepServer',
145  'envPrepPath',
146  ];
147 
155  protected $defaultVarNames = [
156  'wgSitename',
157  'wgPasswordSender',
158  'wgLanguageCode',
159  'wgRightsIcon',
160  'wgRightsText',
161  'wgRightsUrl',
162  'wgEnableEmail',
163  'wgEnableUserEmail',
164  'wgEnotifUserTalk',
165  'wgEnotifWatchlist',
166  'wgEmailAuthentication',
167  'wgDBname',
168  'wgDBtype',
169  'wgDiff3',
170  'wgImageMagickConvertCommand',
171  'wgGitBin',
172  'IP',
173  'wgScriptPath',
174  'wgMetaNamespace',
175  'wgDeletedDirectory',
176  'wgEnableUploads',
177  'wgShellLocale',
178  'wgSecretKey',
179  'wgUseInstantCommons',
180  'wgUpgradeKey',
181  'wgDefaultSkin',
182  ];
183 
191  protected $internalDefaults = [
192  '_UserLang' => 'en',
193  '_Environment' => false,
194  '_RaiseMemory' => false,
195  '_UpgradeDone' => false,
196  '_InstallDone' => false,
197  '_Caches' => [],
198  '_InstallPassword' => '',
199  '_SameAccount' => true,
200  '_CreateDBAccount' => false,
201  '_NamespaceType' => 'site-name',
202  '_AdminName' => '', // will be set later, when the user selects language
203  '_AdminPassword' => '',
204  '_AdminPasswordConfirm' => '',
205  '_AdminEmail' => '',
206  '_Subscribe' => false,
207  '_SkipOptional' => 'continue',
208  '_RightsProfile' => 'wiki',
209  '_LicenseCode' => 'none',
210  '_CCDone' => false,
211  '_Extensions' => [],
212  '_Skins' => [],
213  '_MemCachedServers' => '',
214  '_UpgradeKeySupplied' => false,
215  '_ExistingDBSettings' => false,
216 
217  // $wgLogo is probably wrong (bug 48084); set something that will work.
218  // Single quotes work fine here, as LocalSettingsGenerator outputs this unescaped.
219  'wgLogo' => '$wgResourceBasePath/resources/assets/wiki.png',
220  'wgAuthenticationTokenVersion' => 1,
221  ];
222 
228  private $installSteps = [];
229 
235  protected $extraInstallSteps = [];
236 
242  protected $objectCaches = [
243  'xcache' => 'xcache_get',
244  'apc' => 'apc_fetch',
245  'wincache' => 'wincache_ucache_get'
246  ];
247 
253  public $rightsProfiles = [
254  'wiki' => [],
255  'no-anon' => [
256  '*' => [ 'edit' => false ]
257  ],
258  'fishbowl' => [
259  '*' => [
260  'createaccount' => false,
261  'edit' => false,
262  ],
263  ],
264  'private' => [
265  '*' => [
266  'createaccount' => false,
267  'edit' => false,
268  'read' => false,
269  ],
270  ],
271  ];
272 
278  public $licenses = [
279  'cc-by' => [
280  'url' => 'https://creativecommons.org/licenses/by/4.0/',
281  'icon' => '$wgResourceBasePath/resources/assets/licenses/cc-by.png',
282  ],
283  'cc-by-sa' => [
284  'url' => 'https://creativecommons.org/licenses/by-sa/4.0/',
285  'icon' => '$wgResourceBasePath/resources/assets/licenses/cc-by-sa.png',
286  ],
287  'cc-by-nc-sa' => [
288  'url' => 'https://creativecommons.org/licenses/by-nc-sa/4.0/',
289  'icon' => '$wgResourceBasePath/resources/assets/licenses/cc-by-nc-sa.png',
290  ],
291  'cc-0' => [
292  'url' => 'https://creativecommons.org/publicdomain/zero/1.0/',
293  'icon' => '$wgResourceBasePath/resources/assets/licenses/cc-0.png',
294  ],
295  'pd' => [
296  'url' => '',
297  'icon' => '$wgResourceBasePath/resources/assets/licenses/public-domain.png',
298  ],
299  'gfdl' => [
300  'url' => 'https://www.gnu.org/copyleft/fdl.html',
301  'icon' => '$wgResourceBasePath/resources/assets/licenses/gnu-fdl.png',
302  ],
303  'none' => [
304  'url' => '',
305  'icon' => '',
306  'text' => ''
307  ],
308  'cc-choose' => [
309  // Details will be filled in by the selector.
310  'url' => '',
311  'icon' => '',
312  'text' => '',
313  ],
314  ];
315 
320  'https://lists.wikimedia.org/mailman/subscribe/mediawiki-announce';
321 
326  'ca', 'cs', 'da', 'de', 'en', 'es', 'et', 'eu', 'fi', 'fr', 'hr', 'hu',
327  'it', 'ja', 'ko', 'lt', 'nl', 'no', 'pl', 'pt', 'pt-br', 'ro', 'ru',
328  'sl', 'sr', 'sv', 'tr', 'uk'
329  ];
330 
338  abstract public function showMessage( $msg /*, ... */ );
339 
344  abstract public function showError( $msg /*, ... */ );
345 
350  abstract public function showStatusMessage( Status $status );
351 
355  public function __construct() {
356  global $wgMessagesDirs, $wgUser;
357 
358  // Don't attempt to load user language options (T126177)
359  // This will be overridden in the web installer with the user-specified language
360  RequestContext::getMain()->setLanguage( 'en' );
361 
362  // Disable the i18n cache
363  Language::getLocalisationCache()->disableBackend();
364  // Disable LoadBalancer and wfGetDB etc.
366 
367  // Disable object cache (otherwise CACHE_ANYTHING will try CACHE_DB and
368  // SqlBagOStuff will then throw since we just disabled wfGetDB)
369  $GLOBALS['wgMemc'] = new EmptyBagOStuff;
371  $emptyCache = [ 'class' => 'EmptyBagOStuff' ];
372  // disable (problematic) object cache types explicitly, preserving all other (working) ones
373  // bug T113843
374  $GLOBALS['wgObjectCaches'] = [
375  CACHE_NONE => $emptyCache,
376  CACHE_DB => $emptyCache,
377  CACHE_ANYTHING => $emptyCache,
378  CACHE_MEMCACHED => $emptyCache,
379  ] + $GLOBALS['wgObjectCaches'];
380 
381  // Load the installer's i18n.
382  $wgMessagesDirs['MediawikiInstaller'] = __DIR__ . '/i18n';
383 
384  // Having a user with id = 0 safeguards us from DB access via User::loadOptions().
385  $wgUser = User::newFromId( 0 );
386  RequestContext::getMain()->setUser( $wgUser );
387 
389 
390  foreach ( $this->defaultVarNames as $var ) {
391  $this->settings[$var] = $GLOBALS[$var];
392  }
393 
394  $this->doEnvironmentPreps();
395 
396  $this->compiledDBs = [];
397  foreach ( self::getDBTypes() as $type ) {
398  $installer = $this->getDBInstaller( $type );
399 
400  if ( !$installer->isCompiled() ) {
401  continue;
402  }
403  $this->compiledDBs[] = $type;
404  }
405 
406  $this->parserTitle = Title::newFromText( 'Installer' );
407  $this->parserOptions = new ParserOptions( $wgUser ); // language will be wrong :(
408  $this->parserOptions->setEditSection( false );
409  }
410 
416  public static function getDBTypes() {
417  return self::$dbTypes;
418  }
419 
433  public function doEnvironmentChecks() {
434  // Php version has already been checked by entry scripts
435  // Show message here for information purposes
436  if ( wfIsHHVM() ) {
437  $this->showMessage( 'config-env-hhvm', HHVM_VERSION );
438  } else {
439  $this->showMessage( 'config-env-php', PHP_VERSION );
440  }
441 
442  $good = true;
443  // Must go here because an old version of PCRE can prevent other checks from completing
444  list( $pcreVersion ) = explode( ' ', PCRE_VERSION, 2 );
445  if ( version_compare( $pcreVersion, self::MINIMUM_PCRE_VERSION, '<' ) ) {
446  $this->showError( 'config-pcre-old', self::MINIMUM_PCRE_VERSION, $pcreVersion );
447  $good = false;
448  } else {
449  foreach ( $this->envChecks as $check ) {
450  $status = $this->$check();
451  if ( $status === false ) {
452  $good = false;
453  }
454  }
455  }
456 
457  $this->setVar( '_Environment', $good );
458 
459  return $good ? Status::newGood() : Status::newFatal( 'config-env-bad' );
460  }
461 
462  public function doEnvironmentPreps() {
463  foreach ( $this->envPreps as $prep ) {
464  $this->$prep();
465  }
466  }
467 
474  public function setVar( $name, $value ) {
475  $this->settings[$name] = $value;
476  }
477 
488  public function getVar( $name, $default = null ) {
489  if ( !isset( $this->settings[$name] ) ) {
490  return $default;
491  } else {
492  return $this->settings[$name];
493  }
494  }
495 
501  public function getCompiledDBs() {
502  return $this->compiledDBs;
503  }
504 
512  public function getDBInstaller( $type = false ) {
513  if ( !$type ) {
514  $type = $this->getVar( 'wgDBtype' );
515  }
516 
517  $type = strtolower( $type );
518 
519  if ( !isset( $this->dbInstallers[$type] ) ) {
520  $class = ucfirst( $type ) . 'Installer';
521  $this->dbInstallers[$type] = new $class( $this );
522  }
523 
524  return $this->dbInstallers[$type];
525  }
526 
532  public static function getExistingLocalSettings() {
533  global $IP;
534 
535  // You might be wondering why this is here. Well if you don't do this
536  // then some poorly-formed extensions try to call their own classes
537  // after immediately registering them. We really need to get extension
538  // registration out of the global scope and into a real format.
539  // @see https://phabricator.wikimedia.org/T69440
541  $wgAutoloadClasses = [];
542 
543  // @codingStandardsIgnoreStart
544  // LocalSettings.php should not call functions, except wfLoadSkin/wfLoadExtensions
545  // Define the required globals here, to ensure, the functions can do it work correctly.
547  // @codingStandardsIgnoreEnd
548 
549  MediaWiki\suppressWarnings();
550  $_lsExists = file_exists( "$IP/LocalSettings.php" );
551  MediaWiki\restoreWarnings();
552 
553  if ( !$_lsExists ) {
554  return false;
555  }
556  unset( $_lsExists );
557 
558  require "$IP/includes/DefaultSettings.php";
559  require "$IP/LocalSettings.php";
560 
561  return get_defined_vars();
562  }
563 
573  public function getFakePassword( $realPassword ) {
574  return str_repeat( '*', strlen( $realPassword ) );
575  }
576 
584  public function setPassword( $name, $value ) {
585  if ( !preg_match( '/^\*+$/', $value ) ) {
586  $this->setVar( $name, $value );
587  }
588  }
589 
601  public static function maybeGetWebserverPrimaryGroup() {
602  if ( !function_exists( 'posix_getegid' ) || !function_exists( 'posix_getpwuid' ) ) {
603  # I don't know this, this isn't UNIX.
604  return null;
605  }
606 
607  # posix_getegid() *not* getmygid() because we want the group of the webserver,
608  # not whoever owns the current script.
609  $gid = posix_getegid();
610  $group = posix_getpwuid( $gid )['name'];
611 
612  return $group;
613  }
614 
631  public function parse( $text, $lineStart = false ) {
633 
634  try {
635  $out = $wgParser->parse( $text, $this->parserTitle, $this->parserOptions, $lineStart );
636  $html = $out->getText();
637  } catch ( DBAccessError $e ) {
638  $html = '<!--DB access attempted during parse--> ' . htmlspecialchars( $text );
639 
640  if ( !empty( $this->debug ) ) {
641  $html .= "<!--\n" . $e->getTraceAsString() . "\n-->";
642  }
643  }
644 
645  return $html;
646  }
647 
651  public function getParserOptions() {
652  return $this->parserOptions;
653  }
654 
655  public function disableLinkPopups() {
656  $this->parserOptions->setExternalLinkTarget( false );
657  }
658 
659  public function restoreLinkPopups() {
660  global $wgExternalLinkTarget;
661  $this->parserOptions->setExternalLinkTarget( $wgExternalLinkTarget );
662  }
663 
672  public function populateSiteStats( DatabaseInstaller $installer ) {
673  $status = $installer->getConnection();
674  if ( !$status->isOK() ) {
675  return $status;
676  }
677  $status->value->insert(
678  'site_stats',
679  [
680  'ss_row_id' => 1,
681  'ss_total_edits' => 0,
682  'ss_good_articles' => 0,
683  'ss_total_pages' => 0,
684  'ss_users' => 0,
685  'ss_images' => 0
686  ],
687  __METHOD__, 'IGNORE'
688  );
689 
690  return Status::newGood();
691  }
692 
697  protected function envCheckDB() {
698  global $wgLang;
699 
700  $allNames = [];
701 
702  // Messages: config-type-mysql, config-type-postgres, config-type-oracle,
703  // config-type-sqlite
704  foreach ( self::getDBTypes() as $name ) {
705  $allNames[] = wfMessage( "config-type-$name" )->text();
706  }
707 
708  $databases = $this->getCompiledDBs();
709 
710  $databases = array_flip( $databases );
711  foreach ( array_keys( $databases ) as $db ) {
712  $installer = $this->getDBInstaller( $db );
713  $status = $installer->checkPrerequisites();
714  if ( !$status->isGood() ) {
715  $this->showStatusMessage( $status );
716  }
717  if ( !$status->isOK() ) {
718  unset( $databases[$db] );
719  }
720  }
721  $databases = array_flip( $databases );
722  if ( !$databases ) {
723  $this->showError( 'config-no-db', $wgLang->commaList( $allNames ), count( $allNames ) );
724 
725  // @todo FIXME: This only works for the web installer!
726  return false;
727  }
728 
729  return true;
730  }
731 
736  protected function envCheckBrokenXML() {
737  $test = new PhpXmlBugTester();
738  if ( !$test->ok ) {
739  $this->showError( 'config-brokenlibxml' );
740 
741  return false;
742  }
743 
744  return true;
745  }
746 
755  protected function envCheckPCRE() {
756  MediaWiki\suppressWarnings();
757  $regexd = preg_replace( '/[\x{0430}-\x{04FF}]/iu', '', '-АБВГД-' );
758  // Need to check for \p support too, as PCRE can be compiled
759  // with utf8 support, but not unicode property support.
760  // check that \p{Zs} (space separators) matches
761  // U+3000 (Ideographic space)
762  $regexprop = preg_replace( '/\p{Zs}/u', '', "-\xE3\x80\x80-" );
763  MediaWiki\restoreWarnings();
764  if ( $regexd != '--' || $regexprop != '--' ) {
765  $this->showError( 'config-pcre-no-utf8' );
766 
767  return false;
768  }
769 
770  return true;
771  }
772 
777  protected function envCheckMemory() {
778  $limit = ini_get( 'memory_limit' );
779 
780  if ( !$limit || $limit == -1 ) {
781  return true;
782  }
783 
785 
786  if ( $n < $this->minMemorySize * 1024 * 1024 ) {
787  $newLimit = "{$this->minMemorySize}M";
788 
789  if ( ini_set( "memory_limit", $newLimit ) === false ) {
790  $this->showMessage( 'config-memory-bad', $limit );
791  } else {
792  $this->showMessage( 'config-memory-raised', $limit, $newLimit );
793  $this->setVar( '_RaiseMemory', true );
794  }
795  }
796 
797  return true;
798  }
799 
803  protected function envCheckCache() {
804  $caches = [];
805  foreach ( $this->objectCaches as $name => $function ) {
806  if ( function_exists( $function ) ) {
807  if ( $name == 'xcache' && !wfIniGetBool( 'xcache.var_size' ) ) {
808  continue;
809  }
810  $caches[$name] = true;
811  }
812  }
813 
814  if ( !$caches ) {
815  $key = 'config-no-cache-apcu';
816  $this->showMessage( $key );
817  }
818 
819  $this->setVar( '_Caches', $caches );
820  }
821 
826  protected function envCheckModSecurity() {
827  if ( self::apacheModulePresent( 'mod_security' )
828  || self::apacheModulePresent( 'mod_security2' ) ) {
829  $this->showMessage( 'config-mod-security' );
830  }
831 
832  return true;
833  }
834 
839  protected function envCheckDiff3() {
840  $names = [ "gdiff3", "diff3", "diff3.exe" ];
841  $versionInfo = [ '$1 --version 2>&1', 'GNU diffutils' ];
842 
843  $diff3 = self::locateExecutableInDefaultPaths( $names, $versionInfo );
844 
845  if ( $diff3 ) {
846  $this->setVar( 'wgDiff3', $diff3 );
847  } else {
848  $this->setVar( 'wgDiff3', false );
849  $this->showMessage( 'config-diff3-bad' );
850  }
851 
852  return true;
853  }
854 
859  protected function envCheckGraphics() {
860  $names = [ wfIsWindows() ? 'convert.exe' : 'convert' ];
861  $versionInfo = [ '$1 -version', 'ImageMagick' ];
862  $convert = self::locateExecutableInDefaultPaths( $names, $versionInfo );
863 
864  $this->setVar( 'wgImageMagickConvertCommand', '' );
865  if ( $convert ) {
866  $this->setVar( 'wgImageMagickConvertCommand', $convert );
867  $this->showMessage( 'config-imagemagick', $convert );
868 
869  return true;
870  } elseif ( function_exists( 'imagejpeg' ) ) {
871  $this->showMessage( 'config-gd' );
872  } else {
873  $this->showMessage( 'config-no-scaling' );
874  }
875 
876  return true;
877  }
878 
885  protected function envCheckGit() {
886  $names = [ wfIsWindows() ? 'git.exe' : 'git' ];
887  $versionInfo = [ '$1 --version', 'git version' ];
888 
889  $git = self::locateExecutableInDefaultPaths( $names, $versionInfo );
890 
891  if ( $git ) {
892  $this->setVar( 'wgGitBin', $git );
893  $this->showMessage( 'config-git', $git );
894  } else {
895  $this->setVar( 'wgGitBin', false );
896  $this->showMessage( 'config-git-bad' );
897  }
898 
899  return true;
900  }
901 
907  protected function envCheckServer() {
908  $server = $this->envGetDefaultServer();
909  if ( $server !== null ) {
910  $this->showMessage( 'config-using-server', $server );
911  }
912  return true;
913  }
914 
920  protected function envCheckPath() {
921  $this->showMessage(
922  'config-using-uri',
923  $this->getVar( 'wgServer' ),
924  $this->getVar( 'wgScriptPath' )
925  );
926  return true;
927  }
928 
933  protected function envCheckShellLocale() {
934  $os = php_uname( 's' );
935  $supported = [ 'Linux', 'SunOS', 'HP-UX', 'Darwin' ]; # Tested these
936 
937  if ( !in_array( $os, $supported ) ) {
938  return true;
939  }
940 
941  # Get a list of available locales.
942  $ret = false;
943  $lines = wfShellExec( '/usr/bin/locale -a', $ret );
944 
945  if ( $ret ) {
946  return true;
947  }
948 
949  $lines = array_map( 'trim', explode( "\n", $lines ) );
950  $candidatesByLocale = [];
951  $candidatesByLang = [];
952 
953  foreach ( $lines as $line ) {
954  if ( $line === '' ) {
955  continue;
956  }
957 
958  if ( !preg_match( '/^([a-zA-Z]+)(_[a-zA-Z]+|)\.(utf8|UTF-8)(@[a-zA-Z_]*|)$/i', $line, $m ) ) {
959  continue;
960  }
961 
962  list( , $lang, , , ) = $m;
963 
964  $candidatesByLocale[$m[0]] = $m;
965  $candidatesByLang[$lang][] = $m;
966  }
967 
968  # Try the current value of LANG.
969  if ( isset( $candidatesByLocale[getenv( 'LANG' )] ) ) {
970  $this->setVar( 'wgShellLocale', getenv( 'LANG' ) );
971 
972  return true;
973  }
974 
975  # Try the most common ones.
976  $commonLocales = [ 'en_US.UTF-8', 'en_US.utf8', 'de_DE.UTF-8', 'de_DE.utf8' ];
977  foreach ( $commonLocales as $commonLocale ) {
978  if ( isset( $candidatesByLocale[$commonLocale] ) ) {
979  $this->setVar( 'wgShellLocale', $commonLocale );
980 
981  return true;
982  }
983  }
984 
985  # Is there an available locale in the Wiki's language?
986  $wikiLang = $this->getVar( 'wgLanguageCode' );
987 
988  if ( isset( $candidatesByLang[$wikiLang] ) ) {
989  $m = reset( $candidatesByLang[$wikiLang] );
990  $this->setVar( 'wgShellLocale', $m[0] );
991 
992  return true;
993  }
994 
995  # Are there any at all?
996  if ( count( $candidatesByLocale ) ) {
997  $m = reset( $candidatesByLocale );
998  $this->setVar( 'wgShellLocale', $m[0] );
999 
1000  return true;
1001  }
1002 
1003  # Give up.
1004  return true;
1005  }
1006 
1011  protected function envCheckUploadsDirectory() {
1012  global $IP;
1013 
1014  $dir = $IP . '/images/';
1015  $url = $this->getVar( 'wgServer' ) . $this->getVar( 'wgScriptPath' ) . '/images/';
1016  $safe = !$this->dirIsExecutable( $dir, $url );
1017 
1018  if ( !$safe ) {
1019  $this->showMessage( 'config-uploads-not-safe', $dir );
1020  }
1021 
1022  return true;
1023  }
1024 
1030  protected function envCheckSuhosinMaxValueLength() {
1031  $maxValueLength = ini_get( 'suhosin.get.max_value_length' );
1032  if ( $maxValueLength > 0 && $maxValueLength < 1024 ) {
1033  // Only warn if the value is below the sane 1024
1034  $this->showMessage( 'config-suhosin-max-value-length', $maxValueLength );
1035  }
1036 
1037  return true;
1038  }
1039 
1045  protected function unicodeChar( $c ) {
1046  $c = hexdec( $c );
1047  if ( $c <= 0x7F ) {
1048  return chr( $c );
1049  } elseif ( $c <= 0x7FF ) {
1050  return chr( 0xC0 | $c >> 6 ) . chr( 0x80 | $c & 0x3F );
1051  } elseif ( $c <= 0xFFFF ) {
1052  return chr( 0xE0 | $c >> 12 ) . chr( 0x80 | $c >> 6 & 0x3F ) .
1053  chr( 0x80 | $c & 0x3F );
1054  } elseif ( $c <= 0x10FFFF ) {
1055  return chr( 0xF0 | $c >> 18 ) . chr( 0x80 | $c >> 12 & 0x3F ) .
1056  chr( 0x80 | $c >> 6 & 0x3F ) .
1057  chr( 0x80 | $c & 0x3F );
1058  } else {
1059  return false;
1060  }
1061  }
1062 
1066  protected function envCheckLibicu() {
1074  $not_normal_c = $this->unicodeChar( "FA6C" );
1075  $normal_c = $this->unicodeChar( "242EE" );
1076 
1077  $useNormalizer = 'php';
1078  $needsUpdate = false;
1079 
1080  if ( function_exists( 'normalizer_normalize' ) ) {
1081  $useNormalizer = 'intl';
1082  $intl = normalizer_normalize( $not_normal_c, Normalizer::FORM_C );
1083  if ( $intl !== $normal_c ) {
1084  $needsUpdate = true;
1085  }
1086  }
1087 
1088  // Uses messages 'config-unicode-using-php' and 'config-unicode-using-intl'
1089  if ( $useNormalizer === 'php' ) {
1090  $this->showMessage( 'config-unicode-pure-php-warning' );
1091  } else {
1092  $this->showMessage( 'config-unicode-using-' . $useNormalizer );
1093  if ( $needsUpdate ) {
1094  $this->showMessage( 'config-unicode-update-warning' );
1095  }
1096  }
1097  }
1098 
1102  protected function envPrepServer() {
1103  $server = $this->envGetDefaultServer();
1104  if ( $server !== null ) {
1105  $this->setVar( 'wgServer', $server );
1106  }
1107  }
1108 
1113  abstract protected function envGetDefaultServer();
1114 
1118  protected function envPrepPath() {
1119  global $IP;
1120  $IP = dirname( dirname( __DIR__ ) );
1121  $this->setVar( 'IP', $IP );
1122  }
1123 
1131  protected static function getPossibleBinPaths() {
1132  return array_merge(
1133  [ '/usr/bin', '/usr/local/bin', '/opt/csw/bin',
1134  '/usr/gnu/bin', '/usr/sfw/bin', '/sw/bin', '/opt/local/bin' ],
1135  explode( PATH_SEPARATOR, getenv( 'PATH' ) )
1136  );
1137  }
1138 
1156  public static function locateExecutable( $path, $names, $versionInfo = false ) {
1157  if ( !is_array( $names ) ) {
1158  $names = [ $names ];
1159  }
1160 
1161  foreach ( $names as $name ) {
1162  $command = $path . DIRECTORY_SEPARATOR . $name;
1163 
1164  MediaWiki\suppressWarnings();
1165  $file_exists = file_exists( $command );
1166  MediaWiki\restoreWarnings();
1167 
1168  if ( $file_exists ) {
1169  if ( !$versionInfo ) {
1170  return $command;
1171  }
1172 
1173  $file = str_replace( '$1', wfEscapeShellArg( $command ), $versionInfo[0] );
1174  if ( strstr( wfShellExec( $file ), $versionInfo[1] ) !== false ) {
1175  return $command;
1176  }
1177  }
1178  }
1179 
1180  return false;
1181  }
1182 
1195  public static function locateExecutableInDefaultPaths( $names, $versionInfo = false ) {
1196  foreach ( self::getPossibleBinPaths() as $path ) {
1197  $exe = self::locateExecutable( $path, $names, $versionInfo );
1198  if ( $exe !== false ) {
1199  return $exe;
1200  }
1201  }
1202 
1203  return false;
1204  }
1205 
1214  public function dirIsExecutable( $dir, $url ) {
1215  $scriptTypes = [
1216  'php' => [
1217  "<?php echo 'ex' . 'ec';",
1218  "#!/var/env php5\n<?php echo 'ex' . 'ec';",
1219  ],
1220  ];
1221 
1222  // it would be good to check other popular languages here, but it'll be slow.
1223 
1224  MediaWiki\suppressWarnings();
1225 
1226  foreach ( $scriptTypes as $ext => $contents ) {
1227  foreach ( $contents as $source ) {
1228  $file = 'exectest.' . $ext;
1229 
1230  if ( !file_put_contents( $dir . $file, $source ) ) {
1231  break;
1232  }
1233 
1234  try {
1235  $text = Http::get( $url . $file, [ 'timeout' => 3 ], __METHOD__ );
1236  } catch ( Exception $e ) {
1237  // Http::get throws with allow_url_fopen = false and no curl extension.
1238  $text = null;
1239  }
1240  unlink( $dir . $file );
1241 
1242  if ( $text == 'exec' ) {
1243  MediaWiki\restoreWarnings();
1244 
1245  return $ext;
1246  }
1247  }
1248  }
1249 
1250  MediaWiki\restoreWarnings();
1251 
1252  return false;
1253  }
1254 
1261  public static function apacheModulePresent( $moduleName ) {
1262  if ( function_exists( 'apache_get_modules' ) && in_array( $moduleName, apache_get_modules() ) ) {
1263  return true;
1264  }
1265  // try it the hard way
1266  ob_start();
1267  phpinfo( INFO_MODULES );
1268  $info = ob_get_clean();
1269 
1270  return strpos( $info, $moduleName ) !== false;
1271  }
1272 
1278  public function setParserLanguage( $lang ) {
1279  $this->parserOptions->setTargetLanguage( $lang );
1280  $this->parserOptions->setUserLang( $lang );
1281  }
1282 
1288  protected function getDocUrl( $page ) {
1289  return "{$_SERVER['PHP_SELF']}?page=" . urlencode( $page );
1290  }
1291 
1301  public function findExtensions( $directory = 'extensions' ) {
1302  if ( $this->getVar( 'IP' ) === null ) {
1303  return [];
1304  }
1305 
1306  $extDir = $this->getVar( 'IP' ) . '/' . $directory;
1307  if ( !is_readable( $extDir ) || !is_dir( $extDir ) ) {
1308  return [];
1309  }
1310 
1311  // extensions -> extension.json, skins -> skin.json
1312  $jsonFile = substr( $directory, 0, strlen( $directory ) -1 ) . '.json';
1313 
1314  $dh = opendir( $extDir );
1315  $exts = [];
1316  while ( ( $file = readdir( $dh ) ) !== false ) {
1317  if ( !is_dir( "$extDir/$file" ) ) {
1318  continue;
1319  }
1320  if ( file_exists( "$extDir/$file/$jsonFile" ) || file_exists( "$extDir/$file/$file.php" ) ) {
1321  $exts[] = $file;
1322  }
1323  }
1324  closedir( $dh );
1325  natcasesort( $exts );
1326 
1327  return $exts;
1328  }
1329 
1338  public function getDefaultSkin( array $skinNames ) {
1339  $defaultSkin = $GLOBALS['wgDefaultSkin'];
1340  if ( !$skinNames || in_array( $defaultSkin, $skinNames ) ) {
1341  return $defaultSkin;
1342  } else {
1343  return $skinNames[0];
1344  }
1345  }
1346 
1352  protected function includeExtensions() {
1353  global $IP;
1354  $exts = $this->getVar( '_Extensions' );
1355  $IP = $this->getVar( 'IP' );
1356 
1366  $wgAutoloadClasses = [];
1367  $queue = [];
1368 
1369  require "$IP/includes/DefaultSettings.php";
1370 
1371  foreach ( $exts as $e ) {
1372  if ( file_exists( "$IP/extensions/$e/extension.json" ) ) {
1373  $queue["$IP/extensions/$e/extension.json"] = 1;
1374  } else {
1375  require_once "$IP/extensions/$e/$e.php";
1376  }
1377  }
1378 
1379  $registry = new ExtensionRegistry();
1380  $data = $registry->readFromQueue( $queue );
1381  $wgAutoloadClasses += $data['autoload'];
1382 
1383  $hooksWeWant = isset( $wgHooks['LoadExtensionSchemaUpdates'] ) ?
1384  $wgHooks['LoadExtensionSchemaUpdates'] : [];
1385 
1386  if ( isset( $data['globals']['wgHooks']['LoadExtensionSchemaUpdates'] ) ) {
1387  $hooksWeWant = array_merge_recursive(
1388  $hooksWeWant,
1389  $data['globals']['wgHooks']['LoadExtensionSchemaUpdates']
1390  );
1391  }
1392  // Unset everyone else's hooks. Lord knows what someone might be doing
1393  // in ParserFirstCallInit (see bug 27171)
1394  $GLOBALS['wgHooks'] = [ 'LoadExtensionSchemaUpdates' => $hooksWeWant ];
1395 
1396  return Status::newGood();
1397  }
1398 
1411  protected function getInstallSteps( DatabaseInstaller $installer ) {
1412  $coreInstallSteps = [
1413  [ 'name' => 'database', 'callback' => [ $installer, 'setupDatabase' ] ],
1414  [ 'name' => 'tables', 'callback' => [ $installer, 'createTables' ] ],
1415  [ 'name' => 'interwiki', 'callback' => [ $installer, 'populateInterwikiTable' ] ],
1416  [ 'name' => 'stats', 'callback' => [ $this, 'populateSiteStats' ] ],
1417  [ 'name' => 'keys', 'callback' => [ $this, 'generateKeys' ] ],
1418  [ 'name' => 'updates', 'callback' => [ $installer, 'insertUpdateKeys' ] ],
1419  [ 'name' => 'sysop', 'callback' => [ $this, 'createSysop' ] ],
1420  [ 'name' => 'mainpage', 'callback' => [ $this, 'createMainpage' ] ],
1421  ];
1422 
1423  // Build the array of install steps starting from the core install list,
1424  // then adding any callbacks that wanted to attach after a given step
1425  foreach ( $coreInstallSteps as $step ) {
1426  $this->installSteps[] = $step;
1427  if ( isset( $this->extraInstallSteps[$step['name']] ) ) {
1428  $this->installSteps = array_merge(
1429  $this->installSteps,
1430  $this->extraInstallSteps[$step['name']]
1431  );
1432  }
1433  }
1434 
1435  // Prepend any steps that want to be at the beginning
1436  if ( isset( $this->extraInstallSteps['BEGINNING'] ) ) {
1437  $this->installSteps = array_merge(
1438  $this->extraInstallSteps['BEGINNING'],
1439  $this->installSteps
1440  );
1441  }
1442 
1443  // Extensions should always go first, chance to tie into hooks and such
1444  if ( count( $this->getVar( '_Extensions' ) ) ) {
1445  array_unshift( $this->installSteps,
1446  [ 'name' => 'extensions', 'callback' => [ $this, 'includeExtensions' ] ]
1447  );
1448  $this->installSteps[] = [
1449  'name' => 'extension-tables',
1450  'callback' => [ $installer, 'createExtensionTables' ]
1451  ];
1452  }
1453 
1454  return $this->installSteps;
1455  }
1456 
1465  public function performInstallation( $startCB, $endCB ) {
1466  $installResults = [];
1467  $installer = $this->getDBInstaller();
1468  $installer->preInstall();
1469  $steps = $this->getInstallSteps( $installer );
1470  foreach ( $steps as $stepObj ) {
1471  $name = $stepObj['name'];
1472  call_user_func_array( $startCB, [ $name ] );
1473 
1474  // Perform the callback step
1475  $status = call_user_func( $stepObj['callback'], $installer );
1476 
1477  // Output and save the results
1478  call_user_func( $endCB, $name, $status );
1479  $installResults[$name] = $status;
1480 
1481  // If we've hit some sort of fatal, we need to bail.
1482  // Callback already had a chance to do output above.
1483  if ( !$status->isOk() ) {
1484  break;
1485  }
1486  }
1487  if ( $status->isOk() ) {
1488  $this->setVar( '_InstallDone', true );
1489  }
1490 
1491  return $installResults;
1492  }
1493 
1499  public function generateKeys() {
1500  $keys = [ 'wgSecretKey' => 64 ];
1501  if ( strval( $this->getVar( 'wgUpgradeKey' ) ) === '' ) {
1502  $keys['wgUpgradeKey'] = 16;
1503  }
1504 
1505  return $this->doGenerateKeys( $keys );
1506  }
1507 
1515  protected function doGenerateKeys( $keys ) {
1517 
1518  $strong = true;
1519  foreach ( $keys as $name => $length ) {
1520  $secretKey = MWCryptRand::generateHex( $length, true );
1521  if ( !MWCryptRand::wasStrong() ) {
1522  $strong = false;
1523  }
1524 
1525  $this->setVar( $name, $secretKey );
1526  }
1527 
1528  if ( !$strong ) {
1529  $names = array_keys( $keys );
1530  $names = preg_replace( '/^(.*)$/', '\$$1', $names );
1531  global $wgLang;
1532  $status->warning( 'config-insecure-keys', $wgLang->listToText( $names ), count( $names ) );
1533  }
1534 
1535  return $status;
1536  }
1537 
1543  protected function createSysop() {
1544  $name = $this->getVar( '_AdminName' );
1546 
1547  if ( !$user ) {
1548  // We should've validated this earlier anyway!
1549  return Status::newFatal( 'config-admin-error-user', $name );
1550  }
1551 
1552  if ( $user->idForName() == 0 ) {
1553  $user->addToDatabase();
1554 
1555  try {
1556  $user->setPassword( $this->getVar( '_AdminPassword' ) );
1557  } catch ( PasswordError $pwe ) {
1558  return Status::newFatal( 'config-admin-error-password', $name, $pwe->getMessage() );
1559  }
1560 
1561  $user->addGroup( 'sysop' );
1562  $user->addGroup( 'bureaucrat' );
1563  if ( $this->getVar( '_AdminEmail' ) ) {
1564  $user->setEmail( $this->getVar( '_AdminEmail' ) );
1565  }
1566  $user->saveSettings();
1567 
1568  // Update user count
1569  $ssUpdate = new SiteStatsUpdate( 0, 0, 0, 0, 1 );
1570  $ssUpdate->doUpdate();
1571  }
1573 
1574  if ( $this->getVar( '_Subscribe' ) && $this->getVar( '_AdminEmail' ) ) {
1576  }
1577 
1578  return $status;
1579  }
1580 
1585  $params = [
1586  'email' => $this->getVar( '_AdminEmail' ),
1587  'language' => 'en',
1588  'digest' => 0
1589  ];
1590 
1591  // Mailman doesn't support as many languages as we do, so check to make
1592  // sure their selected language is available
1593  $myLang = $this->getVar( '_UserLang' );
1594  if ( in_array( $myLang, $this->mediaWikiAnnounceLanguages ) ) {
1595  $myLang = $myLang == 'pt-br' ? 'pt_BR' : $myLang; // rewrite to Mailman's pt_BR
1596  $params['language'] = $myLang;
1597  }
1598 
1600  $res = MWHttpRequest::factory( $this->mediaWikiAnnounceUrl,
1601  [ 'method' => 'POST', 'postData' => $params ], __METHOD__ )->execute();
1602  if ( !$res->isOK() ) {
1603  $s->warning( 'config-install-subscribe-fail', $res->getMessage() );
1604  }
1605  } else {
1606  $s->warning( 'config-install-subscribe-notpossible' );
1607  }
1608  }
1609 
1616  protected function createMainpage( DatabaseInstaller $installer ) {
1618  try {
1620  $content = new WikitextContent(
1621  wfMessage( 'mainpagetext' )->inContentLanguage()->text() . "\n\n" .
1622  wfMessage( 'mainpagedocfooter' )->inContentLanguage()->text()
1623  );
1624 
1625  $status = $page->doEditContent( $content,
1626  '',
1627  EDIT_NEW,
1628  false,
1629  User::newFromName( 'MediaWiki default' )
1630  );
1631  } catch ( Exception $e ) {
1632  // using raw, because $wgShowExceptionDetails can not be set yet
1633  $status->fatal( 'config-install-mainpage-failed', $e->getMessage() );
1634  }
1635 
1636  return $status;
1637  }
1638 
1642  public static function overrideConfig() {
1643  // Use PHP's built-in session handling, since MediaWiki's
1644  // SessionHandler can't work before we have an object cache set up.
1645  define( 'MW_NO_SESSION_HANDLER', 1 );
1646 
1647  // Don't access the database
1648  $GLOBALS['wgUseDatabaseMessages'] = false;
1649  // Don't cache langconv tables
1650  $GLOBALS['wgLanguageConverterCacheType'] = CACHE_NONE;
1651  // Debug-friendly
1652  $GLOBALS['wgShowExceptionDetails'] = true;
1653  // Don't break forms
1654  $GLOBALS['wgExternalLinkTarget'] = '_blank';
1655 
1656  // Extended debugging
1657  $GLOBALS['wgShowSQLErrors'] = true;
1658  $GLOBALS['wgShowDBErrorBacktrace'] = true;
1659 
1660  // Allow multiple ob_flush() calls
1661  $GLOBALS['wgDisableOutputCompression'] = true;
1662 
1663  // Use a sensible cookie prefix (not my_wiki)
1664  $GLOBALS['wgCookiePrefix'] = 'mw_installer';
1665 
1666  // Some of the environment checks make shell requests, remove limits
1667  $GLOBALS['wgMaxShellMemory'] = 0;
1668 
1669  // Override the default CookieSessionProvider with a dummy
1670  // implementation that won't stomp on PHP's cookies.
1671  $GLOBALS['wgSessionProviders'] = [
1672  [
1673  'class' => 'InstallerSessionProvider',
1674  'args' => [ [
1675  'priority' => 1,
1676  ] ]
1677  ]
1678  ];
1679 
1680  // Don't try to use any object cache for SessionManager either.
1681  $GLOBALS['wgSessionCacheType'] = CACHE_NONE;
1682  }
1683 
1691  public function addInstallStep( $callback, $findStep = 'BEGINNING' ) {
1692  $this->extraInstallSteps[$findStep][] = $callback;
1693  }
1694 
1699  protected function disableTimeLimit() {
1700  MediaWiki\suppressWarnings();
1701  set_time_limit( 0 );
1702  MediaWiki\restoreWarnings();
1703  }
1704 }
static newFromName($name, $validate= 'valid')
Static factory method for creation from username.
Definition: User.php:568
static factory(Title $title)
Create a WikiPage object of the appropriate class for the given title.
Definition: WikiPage.php:99
envCheckServer()
Environment check to inform user which server we've assumed.
Definition: Installer.php:907
array $internalDefaults
Variables that are stored alongside globals, and are used for any configuration of the installation p...
Definition: Installer.php:191
envCheckBrokenXML()
Some versions of libxml+PHP break < and > encoding horribly.
Definition: Installer.php:736
static getLocalisationCache()
Get the LocalisationCache instance.
Definition: Language.php:402
null means default in associative array with keys and values unescaped Should be merged with default with a value of false meaning to suppress the attribute in associative array with keys and values unescaped noclasses just before the function returns a value If you return an< a > element with HTML attributes $attribs and contents $html will be returned If you return $ret will be returned and may include noclasses & $html
Definition: hooks.txt:1798
deferred txt A few of the database updates required by various functions here can be deferred until after the result page is displayed to the user For updating the view updating the linked to tables after a etc PHP does not yet have any way to tell the server to actually return and disconnect while still running these but it might have such a feature in the future We handle these by creating a deferred update object and putting those objects on a global list
Definition: deferred.txt:11
this hook is for auditing only or null if authentication failed before getting that far or null if we can t even determine that probably a stub it is not rendered in wiki pages or galleries in category pages allow injecting custom HTML after the section Any uses of the hook need to handle escaping see BaseTemplate::getToolbox and BaseTemplate::makeListItem for details on the format of individual items inside of this array or by returning and letting standard HTTP rendering take place modifiable or by returning false and taking over the output $out
Definition: hooks.txt:762
the array() calling protocol came about after MediaWiki 1.4rc1.
magic word the default is to use $key to get the and $key value or $key value text $key value html to format the value $key
Definition: hooks.txt:2321
Title $parserTitle
Cached Title, used by parse().
Definition: Installer.php:83
performInstallation($startCB, $endCB)
Actually perform the installation.
Definition: Installer.php:1465
array $dbInstallers
Cached DB installer instances, access using getDBInstaller().
Definition: Installer.php:69
if(count($args)==0) $dir
wfIsHHVM()
Check if we are running under HHVM.
restoreLinkPopups()
Definition: Installer.php:659
static newMainPage()
Create a new Title for the Main Page.
Definition: Title.php:569
dirIsExecutable($dir, $url)
Checks if scripts located in the given directory can be executed via the given URL.
Definition: Installer.php:1214
$IP
Definition: WebStart.php:58
setVar($name, $value)
Set a MW configuration variable, or internal installer configuration variable.
Definition: Installer.php:474
wfShorthandToInteger($string= '', $default=-1)
Converts shorthand byte notation to integer form.
div flags Integer display flags(NO_ACTION_LINK, NO_EXTRA_USER_LINKS) 'LogException'returning false will NOT prevent logging $e
Definition: hooks.txt:1932
$command
Definition: cdb.php:65
null means default in associative array with keys and values unescaped Should be merged with default with a value of false meaning to suppress the attribute in associative array with keys and values unescaped noclasses & $ret
Definition: hooks.txt:1798
envPrepPath()
Environment prep for setting $IP and $wgScriptPath.
Definition: Installer.php:1118
Set options of the Parser.
$wgParser
Definition: Setup.php:809
if(!isset($args[0])) $lang
processing should stop and the error should be shown to the user * false
Definition: hooks.txt:189
envCheckShellLocale()
Environment check for preferred locale in shell.
Definition: Installer.php:933
includeExtensions()
Installs the auto-detected extensions.
Definition: Installer.php:1352
envCheckGraphics()
Environment check for ImageMagick and GD.
Definition: Installer.php:859
$source
$value
static newFromId($id)
Static factory method for creation from a given user ID.
Definition: User.php:591
doEnvironmentPreps()
Definition: Installer.php:462
envCheckGit()
Search for git.
Definition: Installer.php:885
static wasStrong()
Return a boolean indicating whether or not the source used for cryptographic random bytes generation ...
array $settings
Definition: Installer.php:55
$wgHooks['ArticleShow'][]
Definition: hooks.txt:110
static locateExecutableInDefaultPaths($names, $versionInfo=false)
Same as locateExecutable(), but checks in getPossibleBinPaths() by default.
Definition: Installer.php:1195
envCheckDiff3()
Search for GNU diff3.
Definition: Installer.php:839
ParserOptions $parserOptions
Cached ParserOptions, used by parse().
Definition: Installer.php:90
wfShellExec($cmd, &$retval=null, $environ=[], $limits=[], $options=[])
Execute a shell command, with time and memory limits mirrored from the PHP configuration if supported...
envCheckModSecurity()
Scare user to death if they have mod_security or mod_security2.
Definition: Installer.php:826
static newFromText($text, $defaultNamespace=NS_MAIN)
Create a new Title from text, such as what one would find in a link.
Definition: Title.php:277
doGenerateKeys($keys)
Generate a secret value for variables using our CryptRand generator.
Definition: Installer.php:1515
when a variable name is used in a it is silently declared as a new local masking the global
Definition: design.txt:93
addInstallStep($callback, $findStep= 'BEGINNING')
Add an installation step following the given step.
Definition: Installer.php:1691
wfIsWindows()
Check if the operating system is Windows.
static newFatal($message)
Factory function for fatal errors.
Definition: Status.php:89
static canMakeRequests()
Simple function to test if we can make any sort of requests at all, using cURL or fopen() ...
warning($message)
Add a new warning.
Definition: Status.php:150
static disableBackend()
Disables all access to the load balancer, will cause all database access to throw a DBAccessError...
Definition: LBFactory.php:67
const CACHE_MEMCACHED
Definition: Defines.php:104
getConnection()
Connect to the database using the administrative user/password currently defined in the session...
this class mediates it Skin Encapsulates a look and feel for the wiki All of the functions that render HTML and make choices about how to render it are here and are called from various other places when and is meant to be subclassed with other skins that may override some of its functions The User object contains a reference to a and so rather than having a global skin object we just rely on the global User and get the skin with $wgUser and also has some character encoding functions and other locale stuff The current user interface language is instantiated as $wgLang
Definition: design.txt:56
getDocUrl($page)
Overridden by WebInstaller to provide lastPage parameters.
Definition: Installer.php:1288
array $objectCaches
Known object cache types and the functions used to test for their existence.
Definition: Installer.php:242
$wgExtensionDirectory
Filesystem extensions directory.
findExtensions($directory= 'extensions')
Finds extensions that follow the format /$directory/Name/Name.php, and returns an array containing th...
Definition: Installer.php:1301
showStatusMessage(Status $status)
Show a message to the installing user by using a Status object.
envCheckSuhosinMaxValueLength()
Checks if suhosin.get.max_value_length is set, and if so generate a warning because it decreases Reso...
Definition: Installer.php:1030
$mediaWikiAnnounceLanguages
Supported language codes for Mailman.
Definition: Installer.php:325
static getMain()
Static methods.
generateKeys()
Generate $wgSecretKey.
Definition: Installer.php:1499
$GLOBALS['IP']
static maybeGetWebserverPrimaryGroup()
On POSIX systems return the primary group of the webserver we're running under.
Definition: Installer.php:601
array $envPreps
A list of environment preparation methods called by doEnvironmentPreps().
Definition: Installer.php:143
array $envChecks
A list of environment check methods called by doEnvironmentChecks().
Definition: Installer.php:120
wfIniGetBool($setting)
Safety wrapper around ini_get() for boolean settings.
$res
Definition: database.txt:21
showMessage($msg)
UI interface for displaying a short message The parameters are like parameters to wfMessage()...
static locateExecutable($path, $names, $versionInfo=false)
Search a path for any of the given executable names.
Definition: Installer.php:1156
Class for handling updates to the site_stats table.
array array $installSteps
The actual list of installation steps.
Definition: Installer.php:228
parse($text, $lineStart=false)
Convert wikitext $text to HTML.
Definition: Installer.php:631
static getExistingLocalSettings()
Determine if LocalSettings.php exists.
Definition: Installer.php:532
Exception class for attempted DB access.
Definition: LBFactory.php:470
null means default in associative array with keys and values unescaped Should be merged with default with a value of false meaning to suppress the attribute in associative array with keys and values unescaped noclasses just before the function returns a value If you return an< a > element with HTML attributes $attribs and contents $html will be returned If you return $ret will be returned and may include noclasses after processing after in associative array form externallinks including delete and has completed for all link tables whether this was an auto creation default is conds Array Extra conditions for the No matching items in log is displayed if loglist is empty msgKey Array If you want a nice box with a set this to the key of the message First element is the message additional optional elements are parameters for the key that are processed with wfMessage() -> params() ->parseAsBlock()-offset Set to overwrite offset parameter in $wgRequest set to ''to unsetoffset-wrap String Wrap the message in html(usually something like"&lt
int $minMemorySize
Minimum memory size in MB.
Definition: Installer.php:76
$params
getInstallSteps(DatabaseInstaller $installer)
Get an array of install steps.
Definition: Installer.php:1411
array $compiledDBs
List of detected DBs, access using getCompiledDBs().
Definition: Installer.php:62
getParserOptions()
Definition: Installer.php:651
showError($msg)
Same as showMessage(), but for displaying errors.
A BagOStuff object with no objects in it.
global $wgAutoloadClasses
disableTimeLimit()
Disable the time limit for execution.
Definition: Installer.php:1699
design txt This is a brief overview of the new design More thorough and up to date information is available on the documentation wiki at etc Handles the details of getting and saving to the user table of the and dealing with sessions and cookies OutputPage Encapsulates the entire HTML page that will be sent in response to any server request It is used by calling its functions to add text
Definition: design.txt:12
static apacheModulePresent($moduleName)
Checks for presence of an Apache module.
Definition: Installer.php:1261
Content object for wiki text pages.
Test for PHP+libxml2 bug which breaks XML input subtly with certain versions.
Definition: PhpBugTests.php:30
array array $rightsProfiles
User rights profiles.
Definition: Installer.php:253
globals will be eliminated from MediaWiki replaced by an application object which would be passed to constructors Whether that would be an convenient solution remains to be but certainly PHP makes such object oriented programming models easier than they were in previous versions For the time being MediaWiki programmers will have to work in an environment with some global context At the time of globals were initialised on startup by MediaWiki of these were configuration settings
Definition: globals.txt:25
This document is intended to provide useful advice for parties seeking to redistribute MediaWiki to end users It s targeted particularly at maintainers for Linux since it s been observed that distribution packages of MediaWiki often break We ve consistently had to recommend that users seeking support use official tarballs instead of their distribution s and this often solves whatever problem the user is having It would be nice if this could such as
Definition: distributors.txt:9
createMainpage(DatabaseInstaller $installer)
Insert Main Page with default content.
Definition: Installer.php:1616
please add to it if you re going to add events to the MediaWiki code where normally authentication against an external auth plugin would be creating a local account $user
Definition: hooks.txt:242
disableLinkPopups()
Definition: Installer.php:655
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:584
unicodeChar($c)
Convert a hex string representing a Unicode code point to that code point.
Definition: Installer.php:1045
envCheckCache()
Environment check for compiled object cache types.
Definition: Installer.php:803
envCheckUploadsDirectory()
Environment check for the permissions of the uploads directory.
Definition: Installer.php:1011
ExtensionRegistry class.
injection txt This is an overview of how MediaWiki makes use of dependency injection The design described here grew from the discussion of RFC T384 The term dependency this means that anything an object needs to operate should be injected from the the object itself should only know narrow no concrete implementation of the logic it relies on The requirement to inject everything typically results in an architecture that based on two main types of and essentially stateless service objects that use other service objects to operate on the value objects As of the beginning MediaWiki is only starting to use the DI approach Much of the code still relies on global state or direct resulting in a highly cyclical dependency which acts as the top level factory for services in MediaWiki which can be used to gain access to default instances of various services MediaWikiServices however also allows new services to be defined and default services to be redefined Services are defined or redefined by providing a callback the instantiator that will return a new instance of the service When it will create an instance of MediaWikiServices and populate it with the services defined in the files listed by thereby bootstrapping the DI framework Per $wgServiceWiringFiles lists includes ServiceWiring php
Definition: injection.txt:35
const MINIMUM_PCRE_VERSION
The oldest version of PCRE we can support.
Definition: Installer.php:50
envCheckDB()
Environment check for DB types.
Definition: Installer.php:697
$lines
Definition: router.php:66
populateSiteStats(DatabaseInstaller $installer)
Install step which adds a row to the site_stats table with appropriate initial values.
Definition: Installer.php:672
Show an error when any operation involving passwords fails to run.
array $extraInstallSteps
Extra steps for installation, for things like DatabaseInstallers to modify.
Definition: Installer.php:235
getCompiledDBs()
Get a list of DBs supported by current PHP setup.
Definition: Installer.php:501
const EDIT_NEW
Definition: Defines.php:179
array array array $licenses
License types.
Definition: Installer.php:278
envGetDefaultServer()
Helper function to be called from envPrepServer()
getDBInstaller($type=false)
Get an instance of DatabaseInstaller for the specified DB type.
Definition: Installer.php:512
envCheckPCRE()
Environment check for the PCRE module.
Definition: Installer.php:755
this hook is for auditing only RecentChangesLinked and Watchlist RecentChangesLinked and Watchlist e g Watchlist removed from all revisions and log entries to which it was applied This gives extensions a chance to take it off their books as the deletion has already been partly carried out by this point or something similar the user will be unable to create the tag set and then return false from the hook function Ensure you consume the ChangeTagAfterDelete hook to carry out custom deletion actions as context called by AbstractContent::getParserOutput May be used to override the normal model specific rendering of page content $content
Definition: hooks.txt:1004
envCheckPath()
Environment check to inform user which paths we've assumed.
Definition: Installer.php:920
static generateHex($chars, $forceStrong=false)
Generate a run of (ideally) cryptographically random data and return it in hexadecimal string format...
$line
Definition: cdb.php:59
const CACHE_ANYTHING
Definition: Defines.php:101
__construct()
Constructor, always call this from child classes.
Definition: Installer.php:355
$wgStyleDirectory
Filesystem stylesheets directory.
static array $dbTypes
Known database types.
Definition: Installer.php:101
Base class for DBMS-specific installation helper classes.
static overrideConfig()
Override the necessary bits of the config to run an installation.
Definition: Installer.php:1642
Base installer class.
Definition: Installer.php:42
this hook is for auditing only RecentChangesLinked and Watchlist RecentChangesLinked and Watchlist e g Watchlist removed from all revisions and log entries to which it was applied This gives extensions a chance to take it off their books as the deletion has already been partly carried out by this point or something similar the user will be unable to create the tag set and then return false from the hook function Ensure you consume the ChangeTagAfterDelete hook to carry out custom deletion actions as context called by AbstractContent::getParserOutput May be used to override the normal model specific rendering of page content as context as context the output can only depend on parameters provided to this hook not on global state indicating whether full HTML should be generated If generation of HTML may be but other information should still be present in the ParserOutput object to manipulate or replace but no entry for that model exists in $wgContentHandlers if desired whether it is OK to use $contentModel on $title Handler functions that modify $ok should generally return false to prevent further hooks from further modifying $ok inclusive $limit
Definition: hooks.txt:1004
this hook is for auditing only RecentChangesLinked and Watchlist RecentChangesLinked and Watchlist e g Watchlist removed from all revisions and log entries to which it was applied This gives extensions a chance to take it off their books as the deletion has already been partly carried out by this point or something similar the user will be unable to create the tag set $status
Definition: hooks.txt:1004
wfEscapeShellArg()
Windows-compatible version of escapeshellarg() Windows doesn't recognise single-quotes in the shell...
static factory($url, $options=null, $caller=__METHOD__)
Generate a new request object.
static clear()
Clear all the cached instances.
static getDBTypes()
Get a list of known DB types.
Definition: Installer.php:416
setParserLanguage($lang)
ParserOptions are constructed before we determined the language, so fix it.
Definition: Installer.php:1278
getFakePassword($realPassword)
Get a fake password for sending back to the user in HTML.
Definition: Installer.php:573
static get($url, $options=[], $caller=__METHOD__)
Simple wrapper for Http::request( 'GET' )
const CACHE_NONE
Definition: Defines.php:102
getVar($name, $default=null)
Get an MW configuration variable, or internal installer configuration variable.
Definition: Installer.php:488
envCheckLibicu()
Check the libicu version.
Definition: Installer.php:1066
envCheckMemory()
Environment check for available memory.
Definition: Installer.php:777
doEnvironmentChecks()
Do initial checks of the PHP environment.
Definition: Installer.php:433
createSysop()
Create the first user account, grant it sysop and bureaucrat rights.
Definition: Installer.php:1543
static getPossibleBinPaths()
Get an array of likely places we can find executables.
Definition: Installer.php:1131
do that in ParserLimitReportFormat instead use this to modify the parameters of the image and a DIV can begin in one section and end in another Make sure your code can handle that case gracefully See the EditSectionClearerLink extension for an example zero but section is usually empty its values are the globals values before the output is cached one of or reset my talk my contributions etc etc otherwise the built in rate limiting checks are if enabled allows for interception of redirect as a string mapping parameter names to values & $type
Definition: hooks.txt:2338
envPrepServer()
Environment prep for the server hostname.
Definition: Installer.php:1102
array array array $mediaWikiAnnounceUrl
URL to mediawiki-announce subscription.
Definition: Installer.php:319
static newGood($value=null)
Factory function for good results.
Definition: Status.php:101
array $defaultVarNames
MediaWiki configuration globals that will eventually be passed through to LocalSettings.php.
Definition: Installer.php:155
const CACHE_DB
Definition: Defines.php:103
do that in ParserLimitReportFormat instead use this to modify the parameters of the image and a DIV can begin in one section and end in another Make sure your code can handle that case gracefully See the EditSectionClearerLink extension for an example zero but section is usually empty its values are the globals values before the output is cached $page
Definition: hooks.txt:2338
subscribeToMediaWikiAnnounce(Status $s)
Definition: Installer.php:1584
$wgUser
Definition: Setup.php:794
Allows to change the fields on the form that will be generated $name
Definition: hooks.txt:310
getDefaultSkin(array $skinNames)
Returns a default value to be used for $wgDefaultSkin: normally the one set in DefaultSettings, but will fall back to another if the default skin is missing and some other one is present instead.
Definition: Installer.php:1338