68 'https://lists.wikimedia.org/postorius/lists/mediawiki-announce.lists.wikimedia.org/';
141 'envCheckModSecurity',
147 'envCheckShellLocale',
148 'envCheckUploadsDirectory',
150 'envCheckSuhosinMaxValueLength',
182 'wgEmailAuthentication',
186 'wgImageMagickConvertCommand',
191 'wgDeletedDirectory',
195 'wgUseInstantCommons',
210 '_Environment' =>
false,
211 '_RaiseMemory' =>
false,
212 '_UpgradeDone' =>
false,
213 '_InstallDone' =>
false,
215 '_InstallPassword' =>
'',
216 '_SameAccount' =>
true,
217 '_CreateDBAccount' =>
false,
218 '_NamespaceType' =>
'site-name',
220 '_AdminPassword' =>
'',
221 '_AdminPasswordConfirm' =>
'',
223 '_Subscribe' =>
false,
224 '_SkipOptional' =>
'continue',
225 '_RightsProfile' =>
'wiki',
226 '_LicenseCode' =>
'none',
230 '_MemCachedServers' =>
'',
231 '_UpgradeKeySupplied' =>
false,
232 '_ExistingDBSettings' =>
false,
234 '_Logo' =>
'$wgResourceBasePath/resources/assets/wiki.png',
236 'wgAuthenticationTokenVersion' => 1,
260 'apcu' =>
'apcu_fetch',
261 'wincache' =>
'wincache_ucache_get'
272 '*' => [
'edit' => false ]
276 'createaccount' =>
false,
282 'createaccount' =>
false,
296 'url' =>
'https://creativecommons.org/licenses/by/4.0/',
297 'icon' =>
'$wgResourceBasePath/resources/assets/licenses/cc-by.png',
300 'url' =>
'https://creativecommons.org/licenses/by-sa/4.0/',
301 'icon' =>
'$wgResourceBasePath/resources/assets/licenses/cc-by-sa.png',
304 'url' =>
'https://creativecommons.org/licenses/by-nc-sa/4.0/',
305 'icon' =>
'$wgResourceBasePath/resources/assets/licenses/cc-by-nc-sa.png',
308 'url' =>
'https://creativecommons.org/publicdomain/zero/1.0/',
309 'icon' =>
'$wgResourceBasePath/resources/assets/licenses/cc-0.png',
312 'url' =>
'https://www.gnu.org/copyleft/fdl.html',
313 'icon' =>
'$wgResourceBasePath/resources/assets/licenses/gnu-fdl.png',
371 $emptyCache = [
'class' => EmptyBagOStuff::class ];
378 ] + $baseConfig->
get(
'ObjectCaches' );
383 $messageDirs = $baseConfig->
get(
'MessagesDirs' );
384 $messageDirs[
'MediawikiInstaller'] = __DIR__ .
'/i18n';
386 $configOverrides->set(
'MessagesDirs', $messageDirs );
388 $installerConfig =
new MultiConfig( [ $configOverrides, $baseConfig ] );
391 $configRegistry = $baseConfig->
get(
'ConfigRegistry' );
392 $configRegistry[
'main'] =
function () use ( $installerConfig ) {
393 return $installerConfig;
396 $configOverrides->set(
'ConfigRegistry', $configRegistry );
398 return $installerConfig;
411 MediaWikiServices::disableStorageBackend();
415 foreach ( $this->defaultVarNames as $var ) {
416 $this->settings[$var] =
$GLOBALS[$var];
421 $this->compiledDBs = [];
422 foreach ( self::getDBTypes() as
$type ) {
425 if ( !$installer->isCompiled() ) {
428 $this->compiledDBs[] =
$type;
431 $this->parserTitle = Title::newFromText(
'Installer' );
451 $serviceOverrides += [
453 'InterwikiLookup' =>
function () {
459 return $services->get(
'_DefaultOptionsLookup' );
466 MediaWikiServices::resetGlobalInstance( $installerConfig );
468 $mwServices = MediaWikiServices::getInstance();
470 foreach ( $serviceOverrides as $name => $callback ) {
474 $mwServices->redefineService( $name, $callback );
479 $mwServices->getLocalisationCache()->disableBackend();
482 Language::$mLangObjCache = [];
490 RequestContext::getMain()->setUser( $user );
496 RequestContext::getMain()->setLanguage(
$lang );
497 $wgLang = RequestContext::getMain()->getLanguage();
506 $this->
setParserLanguage( $mwServices->getLanguageFactory()->getLanguage(
'en' ) );
536 $this->
showMessage(
'config-env-php', PHP_VERSION );
540 $pcreVersion = explode(
' ', PCRE_VERSION, 2 )[0];
541 if ( version_compare( $pcreVersion, self::MINIMUM_PCRE_VERSION,
'<' ) ) {
542 $this->
showError(
'config-pcre-old', self::MINIMUM_PCRE_VERSION, $pcreVersion );
545 foreach ( $this->envChecks as $check ) {
546 $status = $this->$check();
547 if ( $status ===
false ) {
553 $this->
setVar(
'_Environment', $good );
555 return $good ? Status::newGood() : Status::newFatal(
'config-env-bad' );
559 foreach ( $this->envPreps as $prep ) {
570 public function setVar( $name, $value ) {
571 $this->settings[$name] = $value;
584 public function getVar( $name, $default =
null ) {
585 return $this->settings[$name] ?? $default;
605 return ucfirst(
$type ) .
'Installer';
622 if ( !isset( $this->dbInstallers[
$type] ) ) {
624 $this->dbInstallers[
$type] =
new $class( $this );
627 return $this->dbInstallers[
$type];
651 Wikimedia\suppressWarnings();
652 $_lsExists = file_exists(
"$IP/LocalSettings.php" );
653 Wikimedia\restoreWarnings();
660 require
"$IP/includes/DefaultSettings.php";
661 require
"$IP/LocalSettings.php";
663 return get_defined_vars();
676 return str_repeat(
'*', strlen( $realPassword ) );
687 if ( !preg_match(
'/^\*+$/', $value ) ) {
688 $this->
setVar( $name, $value );
704 if ( !function_exists(
'posix_getegid' ) || !function_exists(
'posix_getpwuid' ) ) {
705 # I don't know this, this isn't UNIX.
709 # posix_getegid() *not* getmygid() because we want the group of the webserver,
710 # not whoever owns the current script.
711 $gid = posix_getegid();
712 return posix_getpwuid( $gid )[
'name'] ??
null;
731 public function parse( $text, $lineStart =
false ) {
732 $parser = MediaWikiServices::getInstance()->getParser();
735 $out = $parser->parse( $text, $this->parserTitle, $this->parserOptions, $lineStart );
736 $html = $out->getText( [
737 'enableSectionEditLinks' =>
false,
740 $html = Parser::stripOuterParagraph( $html );
741 }
catch (
Wikimedia\Services\ServiceDisabledException $e ) {
742 $html =
'<!--DB access attempted during parse--> ' . htmlspecialchars( $text );
756 $this->parserOptions->setExternalLinkTarget(
false );
774 if ( !$status->isOK() ) {
778 $status->value->insert(
782 'ss_total_edits' => 0,
783 'ss_good_articles' => 0,
784 'ss_total_pages' => 0,
786 'ss_active_users' => 0,
793 return Status::newGood();
803 $dbType = $this->
getVar(
'wgDBtype' );
808 foreach ( self::getDBTypes() as $name ) {
809 $allNames[] =
wfMessage(
"config-type-$name" )->text();
814 $databases = array_flip( $databases );
816 foreach ( array_keys( $databases ) as $db ) {
818 $status = $installer->checkPrerequisites();
819 if ( !$status->isGood() ) {
820 if ( !$this instanceof
WebInstaller && $db === $dbType ) {
827 unset( $databases[$db] );
830 $databases = array_flip( $databases );
832 $this->
showError(
'config-no-db', $wgLang->commaList( $allNames ), count( $allNames ) );
847 Wikimedia\suppressWarnings();
848 $regexd = preg_replace(
'/[\x{0430}-\x{04FF}]/iu',
'',
'-АБВГД-' );
853 $regexprop = preg_replace(
'/\p{Zs}/u',
'',
"-\u{3000}-" );
854 Wikimedia\restoreWarnings();
855 if ( $regexd !=
'--' || $regexprop !=
'--' ) {
856 $this->
showError(
'config-pcre-no-utf8' );
864 if ( preg_match(
'/^b.*c$/',
'bąc' ) === 0 ) {
865 $this->
showError(
'config-pcre-invalid-newline' );
878 $limit = ini_get(
'memory_limit' );
880 if ( !$limit || $limit == -1 ) {
886 if ( $n < $this->minMemorySize * 1024 * 1024 ) {
887 $newLimit =
"{$this->minMemorySize}M";
889 if ( ini_set(
"memory_limit", $newLimit ) ===
false ) {
892 $this->
showMessage(
'config-memory-raised', $limit, $newLimit );
893 $this->
setVar(
'_RaiseMemory',
true );
905 foreach ( $this->objectCaches as $name => $function ) {
906 if ( function_exists( $function ) ) {
907 $caches[$name] =
true;
915 $this->
setVar(
'_Caches', $caches );
923 if ( self::apacheModulePresent(
'mod_security' )
924 || self::apacheModulePresent(
'mod_security2' ) ) {
936 $names = [
"gdiff3",
"diff3" ];
938 $names[] =
'diff3.exe';
940 $versionInfo = [
'--version',
'GNU diffutils' ];
942 $diff3 = ExecutableFinder::findInDefaultPaths( $names, $versionInfo );
945 $this->
setVar(
'wgDiff3', $diff3 );
947 $this->
setVar(
'wgDiff3',
false );
959 $names =
wfIsWindows() ?
'convert.exe' :
'convert';
960 $versionInfo = [
'-version',
'ImageMagick' ];
961 $convert = ExecutableFinder::findInDefaultPaths( $names, $versionInfo );
963 $this->
setVar(
'wgImageMagickConvertCommand',
'' );
965 $this->
setVar(
'wgImageMagickConvertCommand', $convert );
966 $this->
showMessage(
'config-imagemagick', $convert );
967 } elseif ( function_exists(
'imagejpeg' ) ) {
984 $versionInfo = [
'--version',
'git version' ];
986 $git = ExecutableFinder::findInDefaultPaths( $names, $versionInfo );
989 $this->
setVar(
'wgGitBin', $git );
992 $this->
setVar(
'wgGitBin',
false );
1006 if ( $server !==
null ) {
1007 $this->
showMessage(
'config-using-server', $server );
1020 $this->
getVar(
'wgServer' ),
1021 $this->
getVar(
'wgScriptPath' )
1031 $os = php_uname(
's' );
1032 $supported = [
'Linux',
'SunOS',
'HP-UX',
'Darwin' ]; # Tested these
1034 if ( !in_array( $os, $supported ) ) {
1038 if ( Shell::isDisabled() ) {
1042 # Get a list of available locales.
1043 $result = Shell::command(
'/usr/bin/locale',
'-a' )->execute();
1045 if ( $result->getExitCode() != 0 ) {
1049 $lines = $result->getStdout();
1051 $candidatesByLocale = [];
1052 $candidatesByLang = [];
1054 if (
$line ===
'' ) {
1058 if ( !preg_match(
'/^([a-zA-Z]+)(_[a-zA-Z]+|)\.(utf8|UTF-8)(@[a-zA-Z_]*|)$/i',
$line, $m ) ) {
1062 list( ,
$lang, , , ) = $m;
1064 $candidatesByLocale[$m[0]] = $m;
1065 $candidatesByLang[
$lang][] = $m;
1068 # Try the current value of LANG.
1069 if ( isset( $candidatesByLocale[getenv(
'LANG' )] ) ) {
1070 $this->
setVar(
'wgShellLocale', getenv(
'LANG' ) );
1075 # Try the most common ones.
1076 $commonLocales = [
'C.UTF-8',
'en_US.UTF-8',
'en_US.utf8',
'de_DE.UTF-8',
'de_DE.utf8' ];
1077 foreach ( $commonLocales as $commonLocale ) {
1078 if ( isset( $candidatesByLocale[$commonLocale] ) ) {
1079 $this->
setVar(
'wgShellLocale', $commonLocale );
1085 # Is there an available locale in the Wiki's language?
1086 $wikiLang = $this->
getVar(
'wgLanguageCode' );
1088 if ( isset( $candidatesByLang[$wikiLang] ) ) {
1089 $m = reset( $candidatesByLang[$wikiLang] );
1090 $this->
setVar(
'wgShellLocale', $m[0] );
1095 # Are there any at all?
1096 if ( count( $candidatesByLocale ) ) {
1097 $m = reset( $candidatesByLocale );
1098 $this->
setVar(
'wgShellLocale', $m[0] );
1114 $dir =
$IP .
'/images/';
1115 $url = $this->
getVar(
'wgServer' ) . $this->
getVar(
'wgScriptPath' ) .
'/images/';
1119 $this->
showMessage(
'config-uploads-not-safe', $dir );
1131 $currentValue = ini_get(
'suhosin.get.max_value_length' );
1132 $minRequired = 2000;
1133 $recommended = 5000;
1134 if ( $currentValue > 0 && $currentValue < $minRequired ) {
1135 $this->
showError(
'config-suhosin-max-value-length', $currentValue, $minRequired, $recommended );
1149 if ( PHP_INT_SIZE == 4 ) {
1167 $not_normal_c =
"\u{FA6C}";
1168 $normal_c =
"\u{242EE}";
1170 $useNormalizer =
'php';
1171 $needsUpdate =
false;
1173 if ( function_exists(
'normalizer_normalize' ) ) {
1174 $useNormalizer =
'intl';
1175 $intl = normalizer_normalize( $not_normal_c, Normalizer::FORM_C );
1176 if ( $intl !== $normal_c ) {
1177 $needsUpdate =
true;
1182 if ( $useNormalizer ===
'php' ) {
1183 $this->
showMessage(
'config-unicode-pure-php-warning' );
1185 $this->
showMessage(
'config-unicode-using-' . $useNormalizer );
1186 if ( $needsUpdate ) {
1187 $this->
showMessage(
'config-unicode-update-warning' );
1197 if ( $server !==
null ) {
1198 $this->
setVar(
'wgServer', $server );
1213 $IP = dirname( dirname( __DIR__ ) );
1214 $this->
setVar(
'IP', $IP );
1228 "<?php echo 'exec';",
1229 "#!/var/env php\n<?php echo 'exec';",
1236 $httpRequestFactory = MediaWikiServices::getInstance()->getHttpRequestFactory();
1238 Wikimedia\suppressWarnings();
1240 foreach ( $scriptTypes as
$ext => $contents ) {
1241 foreach ( $contents as
$source ) {
1249 $text = $httpRequestFactory->get(
1254 }
catch ( Exception $e ) {
1259 unlink( $dir .
$file );
1261 if ( $text ==
'exec' ) {
1262 Wikimedia\restoreWarnings();
1269 Wikimedia\restoreWarnings();
1281 if ( function_exists(
'apache_get_modules' ) && in_array( $moduleName, apache_get_modules() ) ) {
1286 phpinfo( INFO_MODULES );
1287 $info = ob_get_clean();
1289 return strpos( $info, $moduleName ) !==
false;
1298 $this->parserOptions->setTargetLanguage(
$lang );
1299 $this->parserOptions->setUserLang(
$lang );
1308 return "{$_SERVER['PHP_SELF']}?page=" . urlencode( $page );
1321 switch ( $directory ) {
1327 throw new InvalidArgumentException(
"Invalid extension type" );
1341 if ( $this->
getVar(
'IP' ) ===
null ) {
1342 return Status::newGood( [] );
1345 $extDir = $this->
getVar(
'IP' ) .
'/' . $directory;
1346 if ( !is_readable( $extDir ) || !is_dir( $extDir ) ) {
1347 return Status::newGood( [] );
1350 $dh = opendir( $extDir );
1353 while ( (
$file = readdir( $dh ) ) !==
false ) {
1355 if ( !is_dir(
"$extDir/$file" ) ||
$file[0] ===
'.' ) {
1359 if ( $extStatus->isOK() ) {
1360 $exts[
$file] = $extStatus->value;
1361 } elseif ( $extStatus->hasMessage(
'config-extension-not-found' ) ) {
1363 $status->warning(
'config-extension-not-found',
$file );
1365 $status->merge( $extStatus );
1369 uksort( $exts,
'strnatcasecmp' );
1371 $status->value = $exts;
1384 if ( $this->
getVar(
'IP' ) ===
null ) {
1385 throw new Exception(
'Cannot find extensions since the IP variable is not yet set' );
1387 if (
$type !==
'extension' &&
$type !==
'skin' ) {
1388 throw new InvalidArgumentException(
"Invalid extension type" );
1390 $absDir = $this->
getVar(
'IP' ) .
"/$parentRelPath/$name";
1391 $relDir =
"../$parentRelPath/$name";
1392 if ( !is_dir( $absDir ) ) {
1393 return Status::newFatal(
'config-extension-not-found', $name );
1395 $jsonFile =
$type .
'.json';
1396 $fullJsonFile =
"$absDir/$jsonFile";
1397 $isJson = file_exists( $fullJsonFile );
1401 $fullPhpFile =
"$absDir/$name.php";
1402 $isPhp = file_exists( $fullPhpFile );
1404 if ( !$isJson && !$isPhp ) {
1405 return Status::newFatal(
'config-extension-not-found', $name );
1410 if ( is_dir(
"$absDir/screenshots" ) ) {
1411 $paths = glob(
"$absDir/screenshots/*.png" );
1412 foreach ( $paths as
$path ) {
1413 $info[
'screenshots'][] = str_replace( $absDir, $relDir,
$path );
1419 if ( !$jsonStatus->isOK() ) {
1422 $info += $jsonStatus->value;
1425 return Status::newGood( $info );
1436 private function readExtension( $fullJsonFile, $extDeps = [], $skinDeps = [] ) {
1441 $extDir = $this->
getVar(
'IP' ) .
'/extensions';
1442 foreach ( $extDeps as $dep ) {
1443 $fname =
"$extDir/$dep/extension.json";
1444 if ( !file_exists( $fname ) ) {
1445 return Status::newFatal(
'config-extension-not-found', $dep );
1451 $skinDir = $this->
getVar(
'IP' ) .
'/skins';
1452 foreach ( $skinDeps as $dep ) {
1453 $fname =
"$skinDir/$dep/skin.json";
1454 if ( !file_exists( $fname ) ) {
1455 return Status::newFatal(
'config-extension-not-found', $dep );
1462 $info = $registry->readFromQueue( $load );
1464 if ( $e->incompatibleCore || $e->incompatibleSkins
1465 || $e->incompatibleExtensions
1469 return Status::newFatal(
'config-extension-dependency',
1470 basename( dirname( $fullJsonFile ) ), $e->getMessage() );
1471 } elseif ( $e->missingExtensions || $e->missingSkins ) {
1476 array_merge( $extDeps, $e->missingExtensions ),
1477 array_merge( $skinDeps, $e->missingSkins )
1479 if ( !$status->isOK() && !$status->hasMessage(
'config-extension-dependency' ) ) {
1480 $status = Status::newFatal(
'config-extension-dependency',
1481 basename( dirname( $fullJsonFile ) ), $status->getMessage() );
1486 return Status::newFatal(
'config-extension-dependency',
1487 basename( dirname( $fullJsonFile ) ), $e->getMessage() );
1494 foreach ( $info[
'credits'] as $name => $credit ) {
1500 $type = basename( $credit[
'path'] ) ===
'skin.json' ?
'skins' :
'extensions';
1501 $ret[
'requires'][
$type][] = $credit[
'name'];
1503 $credits = array_values( $info[
'credits'] )[0];
1504 if ( isset( $credits[
'url'] ) ) {
1505 $ret[
'url'] = $credits[
'url'];
1507 $ret[
'type'] = $credits[
'type'];
1509 return Status::newGood( $ret );
1521 $defaultSkin =
$GLOBALS[
'wgDefaultSkin'];
1522 if ( !$skinNames || in_array( $defaultSkin, $skinNames ) ) {
1523 return $defaultSkin;
1525 return $skinNames[0];
1538 define(
'MW_EXTENSIONS_LOADED',
true );
1542 if ( isset( $data[
'globals'][
'wgHooks'][
'LoadExtensionSchemaUpdates'] ) ) {
1543 $legacySchemaHooks = array_merge( $legacySchemaHooks,
1544 $data[
'globals'][
'wgHooks'][
'LoadExtensionSchemaUpdates'] );
1546 $extDeprecatedHooks = $data[
'attributes'][
'DeprecatedHooks'] ?? [];
1550 [
'LoadExtensionSchemaUpdates' => $legacySchemaHooks ],
1551 $data[
'attributes'][
'Hooks'] ?? [],
1554 MediaWikiServices::getInstance()->getObjectFactory()
1557 return Status::newGood();
1568 $exts = $this->
getVar(
'_Extensions' );
1569 $installPath = $this->
getVar(
'IP' );
1571 foreach ( $exts as $e ) {
1572 if ( file_exists(
"$installPath/extensions/$e/$e.php" ) ) {
1573 $files[] =
"$installPath/extensions/$e/$e.php";
1603 require
"$IP/includes/DefaultSettings.php";
1607 foreach ( $files as
$file ) {
1612 $hooksWeWant =
$wgHooks[
'LoadExtensionSchemaUpdates'] ?? [];
1616 return [
'LoadExtensionSchemaUpdates' => $hooksWeWant ];
1626 $exts = $this->
getVar(
'_Extensions' );
1627 $installPath = $this->
getVar(
'IP' );
1629 foreach ( $exts as $e ) {
1630 if ( file_exists(
"$installPath/extensions/$e/extension.json" ) ) {
1631 $queue[
"$installPath/extensions/$e/extension.json"] = 1;
1636 $data = $registry->readFromQueue(
$queue );
1650 if ( !$this->autoExtensionHookContainer ) {
1651 throw new \Exception( __METHOD__ .
1652 ': includeExtensions() has not been called' );
1671 $coreInstallSteps = [
1672 [
'name' =>
'database',
'callback' => [ $installer,
'setupDatabase' ] ],
1673 [
'name' =>
'tables',
'callback' => [ $installer,
'createTables' ] ],
1674 [
'name' =>
'tables-manual',
'callback' => [ $installer,
'createManualTables' ] ],
1675 [
'name' =>
'interwiki',
'callback' => [ $installer,
'populateInterwikiTable' ] ],
1676 [
'name' =>
'stats',
'callback' => [ $this,
'populateSiteStats' ] ],
1677 [
'name' =>
'keys',
'callback' => [ $this,
'generateKeys' ] ],
1678 [
'name' =>
'updates',
'callback' => [ $installer,
'insertUpdateKeys' ] ],
1679 [
'name' =>
'restore-services',
'callback' => [ $this,
'restoreServices' ] ],
1680 [
'name' =>
'sysop',
'callback' => [ $this,
'createSysop' ] ],
1681 [
'name' =>
'mainpage',
'callback' => [ $this,
'createMainpage' ] ],
1686 foreach ( $coreInstallSteps as $step ) {
1687 $this->installSteps[] = $step;
1688 if ( isset( $this->extraInstallSteps[$step[
'name']] ) ) {
1689 $this->installSteps = array_merge(
1690 $this->installSteps,
1691 $this->extraInstallSteps[$step[
'name']]
1697 if ( isset( $this->extraInstallSteps[
'BEGINNING'] ) ) {
1698 $this->installSteps = array_merge(
1699 $this->extraInstallSteps[
'BEGINNING'],
1705 if ( count( $this->
getVar(
'_Extensions' ) ) ) {
1706 array_unshift( $this->installSteps,
1707 [
'name' =>
'extensions',
'callback' => [ $this,
'includeExtensions' ] ]
1709 $this->installSteps[] = [
1710 'name' =>
'extension-tables',
1711 'callback' => [ $installer,
'createExtensionTables' ]
1727 $installResults = [];
1729 $installer->preInstall();
1731 foreach ( $steps as $stepObj ) {
1732 $name = $stepObj[
'name'];
1733 call_user_func_array( $startCB, [ $name ] );
1736 $status = call_user_func( $stepObj[
'callback'], $installer );
1739 call_user_func( $endCB, $name, $status );
1740 $installResults[$name] = $status;
1744 if ( !$status->isOK() ) {
1748 if ( $status->isOK() ) {
1750 'config-install-db-success'
1752 $this->
setVar(
'_InstallDone',
true );
1755 return $installResults;
1764 $keys = [
'wgSecretKey' => 64 ];
1765 if ( strval( $this->
getVar(
'wgUpgradeKey' ) ) ===
'' ) {
1766 $keys[
'wgUpgradeKey'] = 16;
1779 return $services->get(
'UserOptionsManager' );
1782 return Status::newGood();
1792 foreach (
$keys as $name => $length ) {
1794 $this->
setVar( $name, $secretKey );
1796 return Status::newGood();
1805 $name = $this->
getVar(
'_AdminName' );
1810 return Status::newFatal(
'config-admin-error-user', $name );
1813 if ( $user->idForName() == 0 ) {
1814 $user->addToDatabase();
1816 $password = $this->
getVar(
'_AdminPassword' );
1817 $status = $user->changeAuthenticationData( [
1818 'username' => $user->getName(),
1819 'password' => $password,
1820 'retype' => $password,
1822 if ( !$status->isGood() ) {
1823 return Status::newFatal(
'config-admin-error-password',
1824 $name, $status->getWikiText(
null,
null, $this->getVar(
'_UserLang' ) ) );
1827 $user->addGroup(
'sysop' );
1828 $user->addGroup(
'bureaucrat' );
1829 $user->addGroup(
'interface-admin' );
1830 if ( $this->
getVar(
'_AdminEmail' ) ) {
1831 $user->setEmail( $this->
getVar(
'_AdminEmail' ) );
1833 $user->saveSettings();
1836 $ssUpdate = SiteStatsUpdate::factory( [
'users' => 1 ] );
1837 $ssUpdate->doUpdate();
1840 if ( $this->
getVar(
'_Subscribe' ) && $this->
getVar(
'_AdminEmail' ) ) {
1843 return Status::newGood();
1850 $status = Status::newGood();
1851 $http = MediaWikiServices::getInstance()->getHttpRequestFactory();
1852 if ( !$http->canMakeRequests() ) {
1853 $status->warning(
'config-install-subscribe-fail',
1854 wfMessage(
'config-install-subscribe-notpossible' ) );
1859 $params = [
'email' => $this->
getVar(
'_AdminEmail' ) ];
1860 $req = $http->create( self::MEDIAWIKI_ANNOUNCE_URL .
'anonymous_subscribe',
1861 [
'method' =>
'POST',
'postData' => $params ], __METHOD__ );
1864 $token = str_repeat(
'a', 64 );
1865 $req->setHeader(
'Referer', self::MEDIAWIKI_ANNOUNCE_URL );
1866 $req->setHeader(
'Cookie',
"csrftoken=$token" );
1867 $req->setHeader(
'X-CSRFToken', $token );
1870 $reqStatus = $req->execute();
1871 if ( !$reqStatus->isOK() ) {
1872 $status->warning(
'config-install-subscribe-fail',
1873 Status::wrap( $reqStatus )->getMessage() );
1882 $checkReq = $http->create( self::MEDIAWIKI_ANNOUNCE_URL, [], __METHOD__ );
1883 $checkReq->setCookieJar( $req->getCookieJar() );
1884 if ( !$checkReq->execute()->isOK() ) {
1885 $status->warning(
'config-install-subscribe-possiblefail' );
1888 $html = $checkReq->getContent();
1889 if ( strpos( $html,
'Please check your inbox for further instructions' ) !==
false ) {
1891 } elseif ( strpos( $html,
'Member already subscribed' ) !==
false ) {
1892 $status->warning(
'config-install-subscribe-alreadysubscribed' );
1893 } elseif ( strpos( $html,
'Subscription request already pending' ) !==
false ) {
1894 $status->warning(
'config-install-subscribe-alreadypending' );
1896 $status->warning(
'config-install-subscribe-possiblefail' );
1908 $status = Status::newGood();
1909 $title = Title::newMainPage();
1910 if (
$title->exists() ) {
1911 $status->warning(
'config-install-mainpage-exists' );
1915 $page = WikiPage::factory(
$title );
1917 wfMessage(
'mainpagetext' )->inContentLanguage()->text() .
"\n\n" .
1918 wfMessage(
'mainpagedocfooter' )->inContentLanguage()->text()
1921 $status = $page->doEditContent(
1928 }
catch ( Exception $e ) {
1930 $status->fatal(
'config-install-mainpage-failed', $e->getMessage() );
1942 if ( !defined(
'MW_NO_SESSION_HANDLER' ) ) {
1943 define(
'MW_NO_SESSION_HANDLER', 1 );
1947 $GLOBALS[
'wgUseDatabaseMessages'] =
false;
1951 $GLOBALS[
'wgResourceLoaderUseObjectCacheForDeps'] =
true;
1953 $GLOBALS[
'wgShowExceptionDetails'] =
true;
1954 $GLOBALS[
'wgShowHostnames'] =
true;
1956 $GLOBALS[
'wgExternalLinkTarget'] =
'_blank';
1959 $GLOBALS[
'wgDisableOutputCompression'] =
true;
1962 $GLOBALS[
'wgCookiePrefix'] =
'mw_installer';
1971 'class' => InstallerSessionProvider::class,
1986 $GLOBALS[
'wgServer'] =
'https://🌻.invalid';
1997 $this->extraInstallSteps[$findStep][] = $callback;
2005 Wikimedia\suppressWarnings();
2006 set_time_limit( 0 );
2007 Wikimedia\restoreWarnings();
$wgObjectCaches
Advanced object cache configuration.
$wgStyleDirectory
Filesystem stylesheets directory.
$wgAutoloadClasses
Array mapping class names to filenames, for autoloading.
$wgHooks
Global list of hooks.
$wgExtensionDirectory
Filesystem extensions directory.
$wgExternalLinkTarget
Set a default target for external links, e.g.
wfShorthandToInteger(?string $string='', int $default=-1)
Converts shorthand byte notation to integer form.
wfIsWindows()
Check if the operating system is Windows.
wfMessage( $key,... $params)
This is the function for getting translated interface messages.
Base class for DBMS-specific installation helper classes.
getConnection()
Connect to the database using the administrative user/password currently defined in the session.
Copyright (C) 2018 Kunal Mehta legoktm@member.fsf.org
Accesses configuration settings from $GLOBALS.
A Config instance which stores all settings as a member variable.
envPrepServer()
Environment prep for the server hostname.
parse( $text, $lineStart=false)
Convert wikitext $text to HTML.
array $compiledDBs
List of detected DBs, access using getCompiledDBs().
getExtensionInfo( $type, $parentRelPath, $name)
Title $parserTitle
Cached Title, used by parse().
includeExtensions()
Installs the auto-detected extensions.
createMainpage(DatabaseInstaller $installer)
Insert Main Page with default content.
const MINIMUM_PCRE_VERSION
The oldest version of PCRE we can support.
getDefaultSkin(array $skinNames)
Returns a default value to be used for $wgDefaultSkin: normally the one set in DefaultSettings,...
envCheckLibicu()
Check the libicu version.
getDBInstaller( $type=false)
Get an instance of DatabaseInstaller for the specified DB type.
envCheckDB()
Environment check for DB types.
envCheckSuhosinMaxValueLength()
Checks if suhosin.get.max_value_length is set, and if so generate a warning because it is incompatibl...
setVar( $name, $value)
Set a MW configuration variable, or internal installer configuration variable.
array $internalDefaults
Variables that are stored alongside globals, and are used for any configuration of the installation p...
envCheckModSecurity()
Scare user to death if they have mod_security or mod_security2.
getFakePassword( $realPassword)
Get a fake password for sending back to the user in HTML.
envCheckServer()
Environment check to inform user which server we've assumed.
disableTimeLimit()
Disable the time limit for execution.
static apacheModulePresent( $moduleName)
Checks for presence of an Apache module.
array $rightsProfiles
User rights profiles.
addInstallStep( $callback, $findStep='BEGINNING')
Add an installation step following the given step.
getCompiledDBs()
Get a list of DBs supported by current PHP setup.
ParserOptions $parserOptions
Cached ParserOptions, used by parse().
dirIsExecutable( $dir, $url)
Checks if scripts located in the given directory can be executed via the given URL.
envCheckGit()
Search for git.
getDocUrl( $page)
Overridden by WebInstaller to provide lastPage parameters.
array[] $installSteps
The actual list of installation steps.
array $defaultVarNames
MediaWiki configuration globals that will eventually be passed through to LocalSettings....
const MEDIAWIKI_ANNOUNCE_URL
URL to mediawiki-announce list summary page.
resetMediaWikiServices(Config $installerConfig=null, $serviceOverrides=[])
Reset the global service container and associated global state to accommodate different stages of the...
static getExistingLocalSettings()
Determine if LocalSettings.php exists.
static getInstallerConfig(Config $baseConfig)
Constructs a Config object that contains configuration settings that should be overwritten for the in...
restoreServices()
Restore services that have been redefined in the early stage of installation.
includeExtensionFiles( $files)
Include the specified extension PHP files.
getAutoExtensionData()
Auto-detect extensions with an extension.json file.
envCheckMemory()
Environment check for available memory.
array $objectCaches
Known object cache types and the functions used to test for their existence.
array $licenses
License types.
static maybeGetWebserverPrimaryGroup()
On POSIX systems return the primary group of the webserver we're running under.
doEnvironmentChecks()
Do initial checks of the PHP environment.
performInstallation( $startCB, $endCB)
Actually perform the installation.
getAutoExtensionLegacyHooks()
Auto-detect extensions with an old style .php registration file, load the extensions,...
envCheck64Bit()
Checks if we're running on 64 bit or not.
generateKeys()
Generate $wgSecretKey.
populateSiteStats(DatabaseInstaller $installer)
Install step which adds a row to the site_stats table with appropriate initial values.
envCheckCache()
Environment check for compiled object cache types.
__construct()
Constructor, always call this from child classes.
int $minMemorySize
Minimum memory size in MB.
findExtensionsByType( $type='extension', $directory='extensions')
Find extensions or skins, and return an array containing the value for 'Name' for each found extensio...
doGenerateKeys( $keys)
Generate a secret value for variables using a secure generator.
showStatusMessage(Status $status)
Show a message to the installing user by using a Status object.
readExtension( $fullJsonFile, $extDeps=[], $skinDeps=[])
envCheckPath()
Environment check to inform user which paths we've assumed.
array $envPreps
A list of environment preparation methods called by doEnvironmentPreps().
setPassword( $name, $value)
Set a variable which stores a password, except if the new value is a fake password in which case leav...
envPrepPath()
Environment prep for setting $IP and $wgScriptPath.
static getDBTypes()
Get a list of known DB types.
createSysop()
Create the first user account, grant it sysop, bureaucrat and interface-admin rights.
envCheckPCRE()
Environment check for the PCRE module.
getVar( $name, $default=null)
Get an MW configuration variable, or internal installer configuration variable.
static getDBInstallerClass( $type)
Get the DatabaseInstaller class name for this type.
static overrideConfig()
Override the necessary bits of the config to run an installation.
array $extraInstallSteps
Extra steps for installation, for things like DatabaseInstallers to modify.
HookContainer null $autoExtensionHookContainer
static array $dbTypes
Known database types.
getAutoExtensionHookContainer()
Get the hook container previously populated by includeExtensions().
envCheckDiff3()
Search for GNU diff3.
subscribeToMediaWikiAnnounce()
envCheckShellLocale()
Environment check for preferred locale in shell.
envGetDefaultServer()
Helper function to be called from envPrepServer()
getInstallSteps(DatabaseInstaller $installer)
Get an array of install steps.
array $dbInstallers
Cached DB installer instances, access using getDBInstaller().
array $envChecks
A list of environment check methods called by doEnvironmentChecks().
envCheckGraphics()
Environment check for ImageMagick and GD.
showMessage( $msg,... $params)
UI interface for displaying a short message The parameters are like parameters to wfMessage().
showError( $msg,... $params)
Same as showMessage(), but for displaying errors.
envCheckUploadsDirectory()
Environment check for the permissions of the uploads directory.
setParserLanguage( $lang)
ParserOptions are constructed before we determined the language, so fix it.
findExtensions( $directory='extensions')
Find extensions or skins in a subdirectory of $IP.
static generateHex( $chars)
Generate a run of cryptographically random data and return it in hexadecimal string format.
Provides a fallback sequence for Config objects.
Set options of the Parser.
Generic operation result class Has warning/error list, boolean status and arbitrary value.
Represents a title within MediaWiki.
static newFromName( $name, $validate='valid')
Static factory method for creation from username.
static newFromId( $id)
Static factory method for creation from a given user ID.
static newSystemUser( $name, $options=[])
Static factory method for creation of a "system" user from username.
Class for the core installer web interface.
Content object for wiki text pages.
Interface for configuration instances.
get( $name)
Get a configuration variable such as "Sitename" or "UploadMaintenance.".
if(PHP_SAPI !='cli-server') if(!isset( $_SERVER['SCRIPT_FILENAME'])) $file
Item class for a filearchive table row.
if(!is_readable( $file)) $ext
if(!isset( $args[0])) $lang
if(!file_exists( $CREDITS)) $lines