Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 244
n/a
0 / 0
CRAP
n/a
0 / 0
1<?php
2/**
3 * The setup for all MediaWiki processes (both web-based and CLI).
4 *
5 * The entry point (such as WebStart.php and doMaintenance.php) has these responsibilities:
6 * - The entry point MUST:
7 *   - define the 'MEDIAWIKI' constant.
8 * - The entry point SHOULD:
9 *   - define the 'MW_ENTRY_POINT' constant.
10 *   - display an error if MW_CONFIG_CALLBACK is not defined and the
11 *     file specified in MW_CONFIG_FILE (or the LocalSettings.php default location)
12 *     does not exist. The error should either be sent before and instead
13 *     of the Setup.php inclusion, or (if it needs classes and dependencies
14 *     from core) the error can be displayed via a MW_CONFIG_CALLBACK,
15 *     which must then abort the process to prevent the rest of Setup.php
16 *     from executing.
17 *
18 * This file does:
19 * - run-time environment checks,
20 * - define MW_INSTALL_PATH, $IP, and $wgBaseDirectory,
21 * - load autoloaders, constants, default settings, and global functions,
22 * - load the site configuration (e.g. LocalSettings.php),
23 * - load the enabled extensions (via ExtensionRegistry),
24 * - trivial expansion of site configuration defaults and shortcuts
25 *   (no calls to MediaWikiServices or other parts of MediaWiki),
26 * - initialization of:
27 *   - PHP run-time (setlocale, memory limit, default date timezone)
28 *   - the debug logger (MWDebug)
29 *   - the service container (MediaWikiServices)
30 *   - the exception handler (MWExceptionHandler)
31 *   - the session manager (SessionManager)
32 * - complex expansion of site configuration defaults (those that require
33 *   calling into MediaWikiServices, global functions, or other classes.).
34 *
35 * This program is free software; you can redistribute it and/or modify
36 * it under the terms of the GNU General Public License as published by
37 * the Free Software Foundation; either version 2 of the License, or
38 * (at your option) any later version.
39 *
40 * This program is distributed in the hope that it will be useful,
41 * but WITHOUT ANY WARRANTY; without even the implied warranty of
42 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
43 * GNU General Public License for more details.
44 *
45 * You should have received a copy of the GNU General Public License along
46 * with this program; if not, write to the Free Software Foundation, Inc.,
47 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
48 * http://www.gnu.org/copyleft/gpl.html
49 *
50 * @file
51 */
52
53// phpcs:disable MediaWiki.Usage.DeprecatedGlobalVariables
54use MediaWiki\Config\SiteConfiguration;
55use MediaWiki\Context\RequestContext;
56use MediaWiki\Deferred\DeferredUpdates;
57use MediaWiki\HookContainer\FauxGlobalHookArray;
58use MediaWiki\HookContainer\HookRunner;
59use MediaWiki\Logger\LoggerFactory;
60use MediaWiki\MainConfigNames;
61use MediaWiki\MainConfigSchema;
62use MediaWiki\MediaWikiServices;
63use MediaWiki\Request\HeaderCallback;
64use MediaWiki\Settings\DynamicDefaultValues;
65use MediaWiki\Settings\LocalSettingsLoader;
66use MediaWiki\Settings\SettingsBuilder;
67use MediaWiki\Settings\Source\PhpSettingsSource;
68use MediaWiki\Settings\Source\ReflectionSchemaSource;
69use MediaWiki\Settings\WikiFarmSettingsLoader;
70use MediaWiki\StubObject\StubGlobalUser;
71use MediaWiki\StubObject\StubUserLang;
72use MediaWiki\Title\Title;
73use MediaWiki\User\User;
74use Psr\Log\LoggerInterface;
75use Wikimedia\RequestTimeout\RequestTimeout;
76
77/**
78 * Environment checks
79 *
80 * These are inline checks done before we include any source files,
81 * and thus these conditions may be assumed by all source code.
82 */
83
84// This file must be included from a valid entry point (e.g. WebStart.php, Maintenance.php)
85if ( !defined( 'MEDIAWIKI' ) ) {
86    exit( 1 );
87}
88
89// PHP must not be configured to overload mbstring functions. (T5782, T122807)
90// This was deprecated by upstream in PHP 7.2 and was removed in PHP 8.0.
91if ( ini_get( 'mbstring.func_overload' ) ) {
92    die( 'MediaWiki does not support installations where mbstring.func_overload is non-zero.' );
93}
94
95// The MW_ENTRY_POINT constant must always exists, to make it safe to access.
96// For compat, we do support older and custom MW entrypoints that don't set this,
97// in which case we assign a default here.
98if ( !defined( 'MW_ENTRY_POINT' ) ) {
99    /**
100     * The entry point, which may be either the script filename without the
101     * file extension, or "cli" for maintenance scripts, or "unknown" for any
102     * entry point that does not set the constant.
103     */
104    define( 'MW_ENTRY_POINT', 'unknown' );
105}
106
107// The $IP variable is defined for use by LocalSettings.php.
108// It is made available as a global variable for backwards compatibility.
109//
110// Source code should instead use the MW_INSTALL_PATH constant, or the
111// MainConfigNames::BaseDirectory setting. The BaseDirectory setting is set further
112// down in Setup.php to the value of MW_INSTALL_PATH.
113global $IP;
114$IP = wfDetectInstallPath(); // ensure MW_INSTALL_PATH is defined
115
116/**
117 * Pre-config setup: Before loading LocalSettings.php
118 *
119 * These are changes and additions to runtime that don't vary on site configuration.
120 */
121require_once MW_INSTALL_PATH . '/includes/AutoLoader.php';
122require_once MW_INSTALL_PATH . '/includes/Defines.php';
123
124// Assert that composer dependencies were successfully loaded
125if ( !interface_exists( LoggerInterface::class ) ) {
126    $message = (
127        'MediaWiki requires the <a href="https://github.com/php-fig/log">PSR-3 logging ' .
128        "library</a> to be present. This library is not embedded directly in MediaWiki's " .
129        "git repository and must be installed separately by the end user.\n\n" .
130        'Please see the <a href="https://www.mediawiki.org/wiki/Download_from_Git' .
131        '#Fetch_external_libraries">instructions for installing libraries</a> on mediawiki.org ' .
132        'for help on installing the required components.'
133    );
134    echo $message;
135    trigger_error( $message, E_USER_ERROR );
136}
137
138// Deprecated global variable for backwards-compatibility.
139// New code should check MW_ENTRY_POINT directly.
140$wgCommandLineMode = MW_ENTRY_POINT === 'cli';
141
142/**
143 * $wgConf hold the site configuration.
144 * Not used for much in a default install.
145 * @since 1.5
146 */
147$wgConf = new SiteConfiguration;
148
149$wgAutoloadClasses ??= [];
150
151$wgSettings = SettingsBuilder::getInstance();
152
153if ( defined( 'MW_USE_CONFIG_SCHEMA_CLASS' ) ) {
154    // Load config schema from MainConfigSchema. Useful for running scripts that
155    // generate other representations of the config schema. This is slow, so it
156    // should not be used for serving web traffic.
157    $wgSettings->load( new ReflectionSchemaSource( MainConfigSchema::class ) );
158} else {
159    $wgSettings->load( new PhpSettingsSource( MW_INSTALL_PATH . '/includes/config-schema.php' ) );
160}
161
162require_once MW_INSTALL_PATH . '/includes/GlobalFunctions.php';
163
164HeaderCallback::register();
165
166// Set the encoding used by PHP for reading HTTP input, and writing output.
167// This is also the default for mbstring functions.
168mb_internal_encoding( 'UTF-8' );
169
170/**
171 * Load LocalSettings.php
172 */
173
174// Initialize some config settings with dynamic defaults, and
175// make default settings available in globals for use in LocalSettings.php.
176$wgSettings->putConfigValues( [
177    MainConfigNames::BaseDirectory => MW_INSTALL_PATH,
178    MainConfigNames::ExtensionDirectory => MW_INSTALL_PATH . '/extensions',
179    MainConfigNames::StyleDirectory => MW_INSTALL_PATH . '/skins',
180    MainConfigNames::ServiceWiringFiles => [ MW_INSTALL_PATH . '/includes/ServiceWiring.php' ],
181    'Version' => MW_VERSION,
182] );
183$wgSettings->apply();
184
185// $wgSettings->apply() puts all configuration into global variables.
186// If we are not in global scope, make all relevant globals available
187// in this file's scope as well.
188$wgScopeTest = 'MediaWiki Setup.php scope test';
189if ( !isset( $GLOBALS['wgScopeTest'] ) || $GLOBALS['wgScopeTest'] !== $wgScopeTest ) {
190    foreach ( $wgSettings->getConfigSchema()->getDefinedKeys() as $key ) {
191        $var = "wg$key";
192        // phpcs:ignore MediaWiki.NamingConventions.ValidGlobalName.allowedPrefix
193        global $$var;
194    }
195    unset( $key, $var );
196}
197unset( $wgScopeTest );
198
199try {
200    if ( defined( 'MW_CONFIG_CALLBACK' ) ) {
201        call_user_func( MW_CONFIG_CALLBACK, $wgSettings );
202    } else {
203        wfDetectLocalSettingsFile( MW_INSTALL_PATH );
204
205        if ( getenv( 'MW_USE_LOCAL_SETTINGS_LOADER' ) ) {
206            // NOTE: This will not work for configuration variables that use a prefix
207            //       other than "wg".
208            $localSettingsLoader = new LocalSettingsLoader( $wgSettings, MW_INSTALL_PATH );
209            $localSettingsLoader->loadLocalSettingsFile( MW_CONFIG_FILE );
210            unset( $localSettingsLoader );
211        } else {
212            if ( str_ends_with( MW_CONFIG_FILE, '.php' ) ) {
213                // make defaults available as globals
214                $wgSettings->apply();
215                require_once MW_CONFIG_FILE;
216            } else {
217                $wgSettings->loadFile( MW_CONFIG_FILE );
218            }
219        }
220    }
221
222    // Make settings loaded by LocalSettings.php available in globals for use here
223    $wgSettings->apply();
224} catch ( MissingExtensionException $e ) {
225    // Make a common mistake give a friendly error
226    $e->render();
227}
228
229// If in a wiki-farm, load site-specific settings
230if ( $wgSettings->getConfig()->get( MainConfigNames::WikiFarmSettingsDirectory ) ) {
231    $wikiFarmSettingsLoader = new WikiFarmSettingsLoader( $wgSettings );
232    $wikiFarmSettingsLoader->loadWikiFarmSettings();
233    unset( $wikiFarmSettingsLoader );
234}
235
236// All settings should be loaded now.
237$wgSettings->enterRegistrationStage();
238
239/**
240 * Customization point after most things are loaded (constants, functions, classes,
241 * LocalSettings.
242 * Note that this runs before extensions are registered, and before most singletons become
243 * available, and before MediaWikiServices is initialized.
244 */
245
246if ( defined( 'MW_SETUP_CALLBACK' ) ) {
247    call_user_func( MW_SETUP_CALLBACK, $wgSettings );
248    // Make any additional settings available in globals for use here
249    $wgSettings->apply();
250}
251
252// Apply dynamic defaults declared in config schema callbacks.
253$dynamicDefaults = new DynamicDefaultValues( $wgSettings->getConfigSchema() );
254$dynamicDefaults->applyDynamicDefaults( $wgSettings->getConfigBuilder() );
255
256// Make updated config available in global scope.
257$wgSettings->apply();
258
259// Apply dynamic defaults implemented in SetupDynamicConfig.php.
260// Ideally, all logic in SetupDynamicConfig would be converted to
261// callbacks in the config schema.
262require __DIR__ . '/SetupDynamicConfig.php';
263
264if ( defined( 'MW_AUTOLOAD_TEST_CLASSES' ) ) {
265    require_once __DIR__ . '/../tests/common/TestsAutoLoader.php';
266}
267
268if ( $wgBaseDirectory !== MW_INSTALL_PATH ) {
269    throw new FatalError(
270        '$wgBaseDirectory must not be modified in settings files! ' .
271        'Use the MW_INSTALL_PATH environment variable to override the installation root directory.'
272    );
273}
274
275// Start time limit
276if ( $wgRequestTimeLimit && MW_ENTRY_POINT !== 'cli' ) {
277    RequestTimeout::singleton()->setWallTimeLimit( $wgRequestTimeLimit );
278}
279
280/**
281 * Load queued extensions
282 */
283if ( defined( 'MW_AUTOLOAD_TEST_CLASSES' ) ) {
284    ExtensionRegistry::getInstance()->setLoadTestClassesAndNamespaces( true );
285}
286
287ExtensionRegistry::getInstance()->setSettingsBuilder( $wgSettings );
288ExtensionRegistry::getInstance()->loadFromQueue();
289// Don't let any other extensions load
290ExtensionRegistry::getInstance()->finish();
291
292/**
293 * Customization point after ALL loading (constants, functions, classes,
294 * LocalSettings, extensions, dynamic defaults).
295 * Note that this runs before MediaWikiServices is initialized.
296 */
297if ( defined( 'MW_FINAL_SETUP_CALLBACK' ) ) {
298    call_user_func( MW_FINAL_SETUP_CALLBACK, $wgSettings );
299    // Make any additional settings available in globals for use below
300    $wgSettings->apply();
301}
302
303// Config can no longer be changed.
304$wgSettings->enterReadOnlyStage();
305
306// Set an appropriate locale (T291234)
307// setlocale() will return the locale name actually set.
308// The putenv() is meant to propagate the choice of locale to shell commands
309// so that they will interpret UTF-8 correctly. If you have a problem with a
310// shell command and need to send a special locale, you can override the locale
311// with Command::environment().
312putenv( "LC_ALL=" . setlocale( LC_ALL, 'C.UTF-8', 'C' ) );
313
314// Set PHP runtime to the desired timezone
315date_default_timezone_set( $wgLocaltimezone );
316
317MWDebug::setup();
318
319// Enable the global service locator.
320// Trivial expansion of site configuration should go before this point.
321// Any non-trivial expansion that requires calling into MediaWikiServices or other parts of MW.
322MediaWikiServices::allowGlobalInstance();
323
324// Define a constant that indicates that the bootstrapping of the service locator
325// is complete.
326define( 'MW_SERVICE_BOOTSTRAP_COMPLETE', 1 );
327
328MWExceptionRenderer::setShowExceptionDetails( $wgShowExceptionDetails );
329if ( !defined( 'MW_PHPUNIT_TEST' ) ) {
330    // Never install the handler in PHPUnit tests, otherwise PHPUnit's own handler will be unset and things
331    // like convertWarningsToExceptions won't work.
332    MWExceptionHandler::installHandler( $wgLogExceptionBacktrace, $wgPropagateErrors );
333}
334Profiler::init( $wgProfiler );
335
336// Non-trivial validation of: $wgServer
337// The FatalError page only renders cleanly after MWExceptionHandler is installed.
338if ( $wgServer === false ) {
339    // T30798: $wgServer must be explicitly set
340    throw new FatalError(
341        '$wgServer must be set in LocalSettings.php. ' .
342        'See <a href="https://www.mediawiki.org/wiki/Manual:$wgServer">' .
343        'https://www.mediawiki.org/wiki/Manual:$wgServer</a>.'
344    );
345}
346
347// Set up a fake $wgHooks array.
348// XXX: It would be nice if we could still get the originally configured hook handlers
349//      using the MainConfigNames::Hooks setting, but it's not really needed,
350//      since we need the HookContainer to be initialized first anyway.
351
352global $wgHooks;
353$wgHooks = new FauxGlobalHookArray(
354    MediaWikiServices::getInstance()->getHookContainer(),
355    $wgHooks
356);
357
358// Non-trivial expansion of: $wgCanonicalServer, $wgServerName.
359// These require calling global functions.
360// Also here are other settings that further depend on these two.
361if ( $wgCanonicalServer === false ) {
362    $wgCanonicalServer = MediaWikiServices::getInstance()->getUrlUtils()->getCanonicalServer();
363}
364$wgVirtualRestConfig['global']['domain'] = $wgCanonicalServer;
365
366if ( $wgServerName !== false ) {
367    wfWarn( '$wgServerName should be derived from $wgCanonicalServer, '
368        . 'not customized. Overwriting $wgServerName.' );
369}
370$wgServerName = parse_url( $wgCanonicalServer, PHP_URL_HOST );
371
372// $wgEmergencyContact and $wgPasswordSender may be false or empty string (T104142)
373if ( !$wgEmergencyContact ) {
374    $wgEmergencyContact = 'wikiadmin@' . $wgServerName;
375}
376if ( !$wgPasswordSender ) {
377    $wgPasswordSender = 'apache@' . $wgServerName;
378}
379if ( !$wgNoReplyAddress ) {
380    $wgNoReplyAddress = $wgPasswordSender;
381}
382
383// Non-trivial expansion of: $wgSecureLogin
384// (due to calling wfWarn).
385if ( $wgSecureLogin && substr( $wgServer, 0, 2 ) !== '//' ) {
386    $wgSecureLogin = false;
387    wfWarn( 'Secure login was enabled on a server that only supports '
388        . 'HTTP or HTTPS. Disabling secure login.' );
389}
390
391// Now that GlobalFunctions is loaded, set defaults that depend on it.
392if ( $wgTmpDirectory === false ) {
393    $wgTmpDirectory = wfTempDir();
394}
395
396if ( $wgSharedDB && $wgSharedTables ) {
397    // Apply $wgSharedDB table aliases for the local LB (all non-foreign DB connections)
398    MediaWikiServices::getInstance()->getDBLoadBalancer()->setTableAliases(
399        array_fill_keys(
400            $wgSharedTables,
401            [
402                'dbname' => $wgSharedDB,
403                'schema' => $wgSharedSchema,
404                'prefix' => $wgSharedPrefix
405            ]
406        )
407    );
408}
409
410// Raise the memory limit if it's too low
411// NOTE: This use wfDebug, and must remain after the MWDebug::setup() call.
412wfMemoryLimit( $wgMemoryLimit );
413
414// Explicit globals, so this works with bootstrap.php
415global $wgRequest, $wgInitialSessionId;
416
417// Initialize the request object in $wgRequest
418$wgRequest = RequestContext::getMain()->getRequest(); // BackCompat
419
420// Make sure that object caching does not undermine the ChronologyProtector improvements
421if ( $wgRequest->getCookie( 'UseDC', '' ) === 'master' ) {
422    // The user is pinned to the primary DC, meaning that they made recent changes which should
423    // be reflected in their subsequent web requests. Avoid the use of interim cache keys because
424    // they use a blind TTL and could be stale if an object changes twice in a short time span.
425    MediaWikiServices::getInstance()->getMainWANObjectCache()->useInterimHoldOffCaching( false );
426}
427
428// Useful debug output
429( static function () {
430    global $wgRequest;
431
432    $logger = LoggerFactory::getInstance( 'wfDebug' );
433    if ( MW_ENTRY_POINT === 'cli' ) {
434        $self = $_SERVER['PHP_SELF'] ?? '';
435        $logger->debug( "\n\nStart command line script $self" );
436    } else {
437        $debug = "\n\nStart request {$wgRequest->getMethod()} {$wgRequest->getRequestURL()}\n";
438        $debug .= "IP: " . $wgRequest->getIP() . "\n";
439        $debug .= "HTTP HEADERS:\n";
440        foreach ( $wgRequest->getAllHeaders() as $name => $value ) {
441            $debug .= "$name$value\n";
442        }
443        $debug .= "(end headers)";
444        $logger->debug( $debug );
445    }
446} )();
447
448// Most of the config is out, some might want to run hooks here.
449( new HookRunner( MediaWikiServices::getInstance()->getHookContainer() ) )->onSetupAfterCache();
450
451// Now that variant lists may be available, parse any action paths and article paths
452// as query parameters.
453//
454// Skip title interpolation on API queries where it is useless and sometimes harmful (T18019).
455//
456// Optimization: Skip on load.php and all other entrypoints besides index.php to save time.
457//
458// TODO: Figure out if this can be safely done after everything else in Setup.php (e.g. any
459// hooks or other state that would miss this?). If so, move to wfIndexMain or MediaWiki::run.
460if ( MW_ENTRY_POINT === 'index' ) {
461    $wgRequest->interpolateTitle();
462}
463
464/**
465 * @var MediaWiki\Session\SessionId|null $wgInitialSessionId The persistent session ID (if any) loaded at startup
466 */
467$wgInitialSessionId = null;
468if ( !defined( 'MW_NO_SESSION' ) && MW_ENTRY_POINT !== 'cli' ) {
469    // If session.auto_start is there, we can't touch session name
470    if ( $wgPHPSessionHandling !== 'disable' && !wfIniGetBool( 'session.auto_start' ) ) {
471        HeaderCallback::warnIfHeadersSent();
472        session_name( $wgSessionName ?: $wgCookiePrefix . '_session' );
473    }
474
475    // Create the SessionManager singleton and set up our session handler,
476    // unless we're specifically asked not to.
477    if ( !defined( 'MW_NO_SESSION_HANDLER' ) ) {
478        MediaWiki\Session\PHPSessionHandler::install(
479            MediaWiki\Session\SessionManager::singleton()
480        );
481    }
482
483    $contLang = MediaWikiServices::getInstance()->getContentLanguage();
484
485    // Initialize the session
486    try {
487        $session = MediaWiki\Session\SessionManager::getGlobalSession();
488    } catch ( MediaWiki\Session\SessionOverflowException $ex ) {
489        // The exception is because the request had multiple possible
490        // sessions tied for top priority. Report this to the user.
491        $list = [];
492        foreach ( $ex->getSessionInfos() as $info ) {
493            $list[] = $info->getProvider()->describe( $contLang );
494        }
495        $list = $contLang->listToText( $list );
496        throw new HttpError( 400,
497            Message::newFromKey( 'sessionmanager-tie', $list )->inLanguage( $contLang )
498        );
499    }
500
501    unset( $contLang );
502
503    if ( $session->isPersistent() ) {
504        $wgInitialSessionId = $session->getSessionId();
505    }
506
507    $session->renew();
508    if ( MediaWiki\Session\PHPSessionHandler::isEnabled() &&
509        ( $session->isPersistent() || $session->shouldRememberUser() ) &&
510        session_id() !== $session->getId()
511    ) {
512        // Start the PHP-session for backwards compatibility
513        if ( session_id() !== '' ) {
514            wfDebugLog( 'session', 'PHP session {old_id} was already started, changing to {new_id}', 'all', [
515                'old_id' => session_id(),
516                'new_id' => $session->getId(),
517            ] );
518            session_write_close();
519        }
520        session_id( $session->getId() );
521        session_start();
522    }
523
524    unset( $session );
525} else {
526    // Even if we didn't set up a global Session, still install our session
527    // handler unless specifically requested not to.
528    if ( !defined( 'MW_NO_SESSION_HANDLER' ) ) {
529        MediaWiki\Session\PHPSessionHandler::install(
530            MediaWiki\Session\SessionManager::singleton()
531        );
532    }
533}
534
535// Explicit globals, so this works with bootstrap.php
536global $wgUser, $wgLang, $wgOut, $wgTitle;
537
538/**
539 * @var User $wgUser
540 * @deprecated since 1.35, use an available context source when possible, or, as a backup,
541 * RequestContext::getMain()
542 */
543$wgUser = new StubGlobalUser( RequestContext::getMain()->getUser() ); // BackCompat
544register_shutdown_function( static function () {
545    StubGlobalUser::$destructorDeprecationDisarmed = true;
546} );
547
548/**
549 * @var Language|StubUserLang $wgLang
550 */
551$wgLang = new StubUserLang;
552
553/**
554 * @var MediaWiki\Output\OutputPage $wgOut
555 */
556$wgOut = RequestContext::getMain()->getOutput(); // BackCompat
557
558/**
559 * @var Title|null $wgTitle
560 */
561$wgTitle = null;
562
563// Explicit globals, so this works with bootstrap.php
564global $wgFullyInitialised, $wgExtensionFunctions;
565
566// Extension setup functions
567// Entries should be added to this variable during the inclusion
568// of the extension file. This allows the extension to perform
569// any necessary initialisation in the fully initialised environment
570foreach ( $wgExtensionFunctions as $func ) {
571    call_user_func( $func );
572}
573unset( $func ); // no global pollution; destroy reference
574
575// If the session user has a 0 id but a valid name, that means we need to
576// autocreate it.
577if ( !defined( 'MW_NO_SESSION' ) && MW_ENTRY_POINT !== 'cli' ) {
578    $sessionUser = MediaWiki\Session\SessionManager::getGlobalSession()->getUser();
579    if ( $sessionUser->getId() === 0 &&
580        MediaWikiServices::getInstance()->getUserNameUtils()->isValid( $sessionUser->getName() )
581    ) {
582        $res = MediaWikiServices::getInstance()->getAuthManager()->autoCreateUser(
583            $sessionUser,
584            MediaWiki\Auth\AuthManager::AUTOCREATE_SOURCE_SESSION,
585            true
586        );
587        \MediaWiki\Logger\LoggerFactory::getInstance( 'authevents' )->info( 'Autocreation attempt', [
588            'event' => 'autocreate',
589            'successful' => $res->isGood(),
590            'status' => ( $res->getErrorsArray() ?: $res->getWarningsArray() )[0][0] ?? '-',
591        ] );
592        unset( $res );
593    }
594    unset( $sessionUser );
595}
596
597// Optimization: Avoid overhead from DeferredUpdates and Pingback deps when turned off.
598if ( MW_ENTRY_POINT !== 'cli' && $wgPingback ) {
599    // NOTE: Do not refactor to inject Config or otherwise make unconditional service call.
600    //
601    // On a plain install of MediaWiki, Pingback is likely the *only* feature
602    // involving DeferredUpdates or DB_PRIMARY on a regular page view.
603    // To allow for error recovery and fault isolation, let admins turn this
604    // off completely. (T269516)
605    DeferredUpdates::addCallableUpdate( static function () {
606        MediaWikiServices::getInstance()->getPingback()->run();
607    } );
608}
609
610$settingsWarnings = $wgSettings->getWarnings();
611if ( $settingsWarnings ) {
612    $logger = LoggerFactory::getInstance( 'Settings' );
613    foreach ( $settingsWarnings as $msg ) {
614        $logger->warning( $msg );
615    }
616    unset( $logger );
617}
618
619unset( $settingsWarnings );
620
621// Explicit globals, so this works with bootstrap.php
622global $wgFullyInitialised;
623$wgFullyInitialised = true;
624
625// T264370
626if ( !defined( 'MW_NO_SESSION' ) && MW_ENTRY_POINT !== 'cli' ) {
627    MediaWiki\Session\SessionManager::singleton()->logPotentialSessionLeakage();
628}