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