7c55d3c8e8d7e8179cd75a9087296f3001510129
[Packages/TYPO3.CMS.git] / typo3 / sysext / core / Classes / Core / Bootstrap.php
1 <?php
2 namespace TYPO3\CMS\Core\Core;
3
4 /*
5 * This file is part of the TYPO3 CMS project.
6 *
7 * It is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License, either version 2
9 * of the License, or any later version.
10 *
11 * For the full copyright and license information, please read the
12 * LICENSE.txt file that was distributed with this source code.
13 *
14 * The TYPO3 project - inspiring people to share!
15 */
16
17 use Composer\Autoload\ClassLoader;
18 use Doctrine\Common\Annotations\AnnotationReader;
19 use Doctrine\Common\Annotations\AnnotationRegistry;
20 use Psr\Container\ContainerInterface;
21 use TYPO3\CMS\Core\Cache\Backend\BackendInterface;
22 use TYPO3\CMS\Core\Cache\Backend\NullBackend;
23 use TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend;
24 use TYPO3\CMS\Core\Cache\CacheManager;
25 use TYPO3\CMS\Core\Cache\Exception\InvalidBackendException;
26 use TYPO3\CMS\Core\Cache\Exception\InvalidCacheException;
27 use TYPO3\CMS\Core\Cache\Frontend\FrontendInterface;
28 use TYPO3\CMS\Core\Cache\Frontend\VariableFrontend;
29 use TYPO3\CMS\Core\Configuration\ConfigurationManager;
30 use TYPO3\CMS\Core\DependencyInjection\ContainerBuilder;
31 use TYPO3\CMS\Core\Imaging\IconRegistry;
32 use TYPO3\CMS\Core\IO\PharStreamWrapperInterceptor;
33 use TYPO3\CMS\Core\Log\LogManager;
34 use TYPO3\CMS\Core\Package\FailsafePackageManager;
35 use TYPO3\CMS\Core\Package\PackageManager;
36 use TYPO3\CMS\Core\Page\PageRenderer;
37 use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
38 use TYPO3\CMS\Core\Utility\GeneralUtility;
39 use TYPO3\PharStreamWrapper\Behavior;
40 use TYPO3\PharStreamWrapper\Manager;
41 use TYPO3\PharStreamWrapper\PharStreamWrapper;
42
43 /**
44 * This class encapsulates bootstrap related methods.
45 * It is required directly as the very first thing in entry scripts and
46 * used to define all base things like constants and paths and so on.
47 *
48 * Most methods in this class have dependencies to each other. They can
49 * not be called in arbitrary order. The methods are ordered top down, so
50 * a method at the beginning has lower dependencies than a method further
51 * down. Do not fiddle with the load order in own scripts except you know
52 * exactly what you are doing!
53 */
54 class Bootstrap
55 {
56 /**
57 * Bootstrap TYPO3 and return a Container that may be used
58 * to initialize an Application class.
59 *
60 * @param ClassLoader $classLoader an instance of the class loader
61 * @param bool $failsafe true if no caching and a failsaife package manager should be used
62 * @return ContainerInterface
63 */
64 public static function init(
65 ClassLoader $classLoader,
66 bool $failsafe = false
67 ): ContainerInterface {
68 $requestId = substr(md5(uniqid('', true)), 0, 13);
69
70 static::initializeClassLoader($classLoader);
71 if (!Environment::isComposerMode() && ClassLoadingInformation::isClassLoadingInformationAvailable()) {
72 ClassLoadingInformation::registerClassLoadingInformation();
73 }
74
75 static::startOutputBuffering();
76
77 $configurationManager = static::createConfigurationManager();
78 if (!static::checkIfEssentialConfigurationExists($configurationManager)) {
79 $failsafe = true;
80 }
81 static::populateLocalConfiguration($configurationManager);
82
83 $logManager = new LogManager($requestId);
84 // LogManager is used by the core ErrorHandler (using GeneralUtility::makeInstance),
85 // therefore we have to push the LogManager to GeneralUtility, in case there
86 // happen errors before we call GeneralUtility::setContainer().
87 GeneralUtility::setSingletonInstance(LogManager::class, $logManager);
88
89 static::initializeErrorHandling();
90 static::initializeIO();
91
92 $disableCaching = $failsafe ? true : false;
93 $coreCache = static::createCache('core', $disableCaching);
94 $packageManager = static::createPackageManager(
95 $failsafe ? FailsafePackageManager::class : PackageManager::class,
96 $coreCache
97 );
98
99 // Push PackageManager instance to ExtensionManagementUtility
100 // Should be fetched through the container (later) but currently a PackageManager
101 // singleton instance is required by PackageManager->activePackageDuringRuntime
102 GeneralUtility::setSingletonInstance(PackageManager::class, $packageManager);
103 ExtensionManagementUtility::setPackageManager($packageManager);
104 static::initializeRuntimeActivatedPackagesFromConfiguration($packageManager);
105
106 static::setDefaultTimezone();
107 static::setMemoryLimit();
108
109 $assetsCache = static::createCache('assets', $disableCaching);
110
111 $bootState = new \stdClass;
112 $bootState->done = false;
113
114 $builder = new ContainerBuilder([
115 'env.is_unix' => Environment::isUnix(),
116 'env.is_windows' => Environment::isWindows(),
117 'env.is_cli' => Environment::isCli(),
118 'env.is_composer_mode' => Environment::isComposerMode(),
119
120 ClassLoader::class => $classLoader,
121 ApplicationContext::class => Environment::getContext(),
122 ConfigurationManager::class => $configurationManager,
123 LogManager::class => $logManager,
124 'cache.disabled' => $disableCaching,
125 'cache.core' => $coreCache,
126 'cache.assets' => $assetsCache,
127 PackageManager::class => $packageManager,
128
129 // @internal
130 'boot.state' => $bootState,
131 ]);
132
133 $container = $builder->createDependencyInjectionContainer($packageManager, $coreCache, $failsafe);
134
135 // Push the container to GeneralUtility as we want to make sure its
136 // makeInstance() method creates classes using the container from now on.
137 GeneralUtility::setContainer($container);
138
139 if ($failsafe) {
140 $bootState->done = true;
141 return $container;
142 }
143
144 IconRegistry::setCache($assetsCache);
145 PageRenderer::setCache($assetsCache);
146 static::loadTypo3LoadedExtAndExtLocalconf(true, $coreCache);
147 static::unsetReservedGlobalVariables();
148 $bootState->done = true;
149 static::loadBaseTca(true, $coreCache);
150 static::checkEncryptionKey();
151
152 return $container;
153 }
154
155 /**
156 * Prevent any unwanted output that may corrupt AJAX/compression.
157 * This does not interfere with "die()" or "echo"+"exit()" messages!
158 *
159 * @internal This is not a public API method, do not use in own extensions
160 */
161 public static function startOutputBuffering()
162 {
163 ob_start();
164 }
165
166 /**
167 * Run the base setup that checks server environment, determines paths,
168 * populates base files and sets common configuration.
169 *
170 * Script execution will be aborted if something fails here.
171 *
172 * @throws \RuntimeException when TYPO3_REQUESTTYPE was not set before, setRequestType() needs to be called before
173 * @internal This is not a public API method, do not use in own extensions
174 */
175 public static function baseSetup()
176 {
177 if (!defined('TYPO3_REQUESTTYPE')) {
178 throw new \RuntimeException('No Request Type was set, TYPO3 does not know in which context it is run.', 1450561838);
179 }
180 if (!Environment::isComposerMode() && ClassLoadingInformation::isClassLoadingInformationAvailable()) {
181 ClassLoadingInformation::registerClassLoadingInformation();
182 }
183 }
184
185 /**
186 * Sets the class loader to the bootstrap
187 *
188 * @param ClassLoader $classLoader an instance of the class loader
189 * @internal This is not a public API method, do not use in own extensions
190 */
191 public static function initializeClassLoader(ClassLoader $classLoader)
192 {
193 ClassLoadingInformation::setClassLoader($classLoader);
194
195 /** @see initializeAnnotationRegistry */
196 AnnotationRegistry::registerLoader([$classLoader, 'loadClass']);
197
198 // Annotations used in unit tests
199 AnnotationReader::addGlobalIgnoredName('test');
200
201 // Annotations that control the extension scanner
202 AnnotationReader::addGlobalIgnoredName('extensionScannerIgnoreFile');
203 AnnotationReader::addGlobalIgnoredName('extensionScannerIgnoreLine');
204 }
205
206 /**
207 * checks if LocalConfiguration.php or PackageStates.php is missing,
208 * used to see if a redirect to the install tool is needed
209 *
210 * @param ConfigurationManager $configurationManager
211 * @return bool TRUE when the essential configuration is available, otherwise FALSE
212 * @internal This is not a public API method, do not use in own extensions
213 */
214 protected static function checkIfEssentialConfigurationExists(ConfigurationManager $configurationManager): bool
215 {
216 return file_exists($configurationManager->getLocalConfigurationFileLocation())
217 && file_exists(Environment::getLegacyConfigPath() . '/PackageStates.php');
218 }
219
220 /**
221 * Initializes the package system and loads the package configuration and settings
222 * provided by the packages.
223 *
224 * @param string $packageManagerClassName Define an alternative package manager implementation (usually for the installer)
225 * @param FrontendInterface $coreCache
226 * @return PackageManager
227 * @internal This is not a public API method, do not use in own extensions
228 */
229 public static function createPackageManager($packageManagerClassName, FrontendInterface $coreCache): PackageManager
230 {
231 $dependencyOrderingService = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Service\DependencyOrderingService::class);
232 /** @var \TYPO3\CMS\Core\Package\PackageManager $packageManager */
233 $packageManager = new $packageManagerClassName($dependencyOrderingService);
234 $packageManager->injectCoreCache($coreCache);
235 $packageManager->initialize();
236
237 return $packageManager;
238 }
239
240 /**
241 * Activates a package during runtime. This is used in AdditionalConfiguration.php
242 * to enable extensions under conditions.
243 *
244 * @param PackageManager $packageManager
245 */
246 protected static function initializeRuntimeActivatedPackagesFromConfiguration(PackageManager $packageManager)
247 {
248 $packages = $GLOBALS['TYPO3_CONF_VARS']['EXT']['runtimeActivatedPackages'] ?? [];
249 if (!empty($packages)) {
250 foreach ($packages as $runtimeAddedPackageKey) {
251 $packageManager->activatePackageDuringRuntime($runtimeAddedPackageKey);
252 }
253 }
254 }
255
256 /**
257 * Load ext_localconf of extensions
258 *
259 * @param bool $allowCaching
260 * @param FrontendInterface $coreCache
261 * @internal This is not a public API method, do not use in own extensions
262 */
263 public static function loadTypo3LoadedExtAndExtLocalconf($allowCaching = true, FrontendInterface $coreCache = null)
264 {
265 if ($allowCaching) {
266 $coreCache = $coreCache ?? GeneralUtility::makeInstance(CacheManager::class)->getCache('core');
267 }
268 ExtensionManagementUtility::loadExtLocalconf($allowCaching, $coreCache);
269 }
270
271 /**
272 * We need an early instance of the configuration manager.
273 * Since makeInstance relies on the object configuration, we create it here with new instead.
274 *
275 * @return ConfigurationManager
276 */
277 public static function createConfigurationManager(): ConfigurationManager
278 {
279 return new ConfigurationManager();
280 }
281
282 /**
283 * We need an early instance of the configuration manager.
284 * Since makeInstance relies on the object configuration, we create it here with new instead.
285 *
286 * @param ConfigurationManager $configurationManager
287 * @internal This is not a public API method, do not use in own extensions
288 */
289 protected static function populateLocalConfiguration(ConfigurationManager $configurationManager)
290 {
291 $configurationManager->exportConfiguration();
292 }
293
294 /**
295 * Instantiates an early cache instance
296 *
297 * Creates a cache instances independently from the CacheManager.
298 * The is used to create the core cache during early bootstrap when the CacheManager
299 * is not yet available (i.e. configuration is not yet loaded).
300 *
301 * @param string $identifier
302 * @param bool $disableCaching
303 * @return FrontendInterface
304 * @internal
305 */
306 public static function createCache(string $identifier, bool $disableCaching = false): FrontendInterface
307 {
308 $configuration = $GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations'][$identifier] ?? [];
309
310 $frontend = $configuration['frontend'] ?? VariableFrontend::class;
311 $backend = $configuration['backend'] ?? Typo3DatabaseBackend::class;
312 $options = $configuration['options'] ?? [];
313
314 if ($disableCaching) {
315 $backend = NullBackend::class;
316 $options = [];
317 }
318
319 $backendInstance = new $backend('production', $options);
320 if (!$backendInstance instanceof BackendInterface) {
321 throw new InvalidBackendException('"' . $backend . '" is not a valid cache backend object.', 1545260108);
322 }
323 if (is_callable([$backendInstance, 'initializeObject'])) {
324 $backendInstance->initializeObject();
325 }
326
327 $frontendInstance = new $frontend($identifier, $backendInstance);
328 if (!$frontendInstance instanceof FrontendInterface) {
329 throw new InvalidCacheException('"' . $frontend . '" is not a valid cache frontend object.', 1545260109);
330 }
331 if (is_callable([$frontendInstance, 'initializeObject'])) {
332 $frontendInstance->initializeObject();
333 }
334
335 return $frontendInstance;
336 }
337
338 /**
339 * Set default timezone
340 */
341 protected static function setDefaultTimezone()
342 {
343 $timeZone = $GLOBALS['TYPO3_CONF_VARS']['SYS']['phpTimeZone'];
344 if (empty($timeZone)) {
345 // Time zone from the server environment (TZ env or OS query)
346 $defaultTimeZone = @date_default_timezone_get();
347 if ($defaultTimeZone !== '') {
348 $timeZone = $defaultTimeZone;
349 } else {
350 $timeZone = 'UTC';
351 }
352 }
353 // Set default to avoid E_WARNINGs with PHP > 5.3
354 date_default_timezone_set($timeZone);
355 }
356
357 /**
358 * Configure and set up exception and error handling
359 *
360 * @throws \RuntimeException
361 */
362 protected static function initializeErrorHandling()
363 {
364 $productionExceptionHandlerClassName = $GLOBALS['TYPO3_CONF_VARS']['SYS']['productionExceptionHandler'];
365 $debugExceptionHandlerClassName = $GLOBALS['TYPO3_CONF_VARS']['SYS']['debugExceptionHandler'];
366
367 $errorHandlerClassName = $GLOBALS['TYPO3_CONF_VARS']['SYS']['errorHandler'];
368 $errorHandlerErrors = $GLOBALS['TYPO3_CONF_VARS']['SYS']['errorHandlerErrors'];
369 $exceptionalErrors = $GLOBALS['TYPO3_CONF_VARS']['SYS']['exceptionalErrors'];
370
371 $displayErrorsSetting = (int)$GLOBALS['TYPO3_CONF_VARS']['SYS']['displayErrors'];
372 switch ($displayErrorsSetting) {
373 case -1:
374 $ipMatchesDevelopmentSystem = GeneralUtility::cmpIP(GeneralUtility::getIndpEnv('REMOTE_ADDR'), $GLOBALS['TYPO3_CONF_VARS']['SYS']['devIPmask']);
375 $exceptionHandlerClassName = $ipMatchesDevelopmentSystem ? $debugExceptionHandlerClassName : $productionExceptionHandlerClassName;
376 $displayErrors = $ipMatchesDevelopmentSystem ? 1 : 0;
377 $exceptionalErrors = $ipMatchesDevelopmentSystem ? $exceptionalErrors : 0;
378 break;
379 case 0:
380 $exceptionHandlerClassName = $productionExceptionHandlerClassName;
381 $displayErrors = 0;
382 break;
383 case 1:
384 $exceptionHandlerClassName = $debugExceptionHandlerClassName;
385 $displayErrors = 1;
386 break;
387 default:
388 if (!(TYPO3_REQUESTTYPE & TYPO3_REQUESTTYPE_INSTALL)) {
389 // Throw exception if an invalid option is set.
390 throw new \RuntimeException(
391 'The option $TYPO3_CONF_VARS[SYS][displayErrors] is not set to "-1", "0" or "1".',
392 1476046290
393 );
394 }
395 }
396 @ini_set('display_errors', (string)$displayErrors);
397
398 if (!empty($errorHandlerClassName)) {
399 // Register an error handler for the given errorHandlerError
400 $errorHandler = GeneralUtility::makeInstance($errorHandlerClassName, $errorHandlerErrors);
401 $errorHandler->setExceptionalErrors($exceptionalErrors);
402 if (is_callable([$errorHandler, 'setDebugMode'])) {
403 $errorHandler->setDebugMode($displayErrors === 1);
404 }
405 }
406 if (!empty($exceptionHandlerClassName)) {
407 // Registering the exception handler is done in the constructor
408 GeneralUtility::makeInstance($exceptionHandlerClassName);
409 }
410 }
411
412 /**
413 * Initializes IO and stream wrapper related behavior.
414 */
415 protected static function initializeIO()
416 {
417 if (in_array('phar', stream_get_wrappers())) {
418 // destroy and re-initialize PharStreamWrapper for TYPO3 core
419 Manager::destroy();
420 Manager::initialize(
421 (new Behavior())
422 ->withAssertion(new PharStreamWrapperInterceptor())
423 );
424
425 stream_wrapper_unregister('phar');
426 stream_wrapper_register('phar', PharStreamWrapper::class);
427 }
428 }
429
430 /**
431 * Set PHP memory limit depending on value of
432 * $GLOBALS['TYPO3_CONF_VARS']['SYS']['setMemoryLimit']
433 */
434 protected static function setMemoryLimit()
435 {
436 if ((int)$GLOBALS['TYPO3_CONF_VARS']['SYS']['setMemoryLimit'] > 16) {
437 @ini_set('memory_limit', (string)((int)$GLOBALS['TYPO3_CONF_VARS']['SYS']['setMemoryLimit'] . 'm'));
438 }
439 }
440
441 /**
442 * Unsetting reserved global variables:
443 * Those are set in "ext:core/ext_tables.php" file:
444 *
445 * @internal This is not a public API method, do not use in own extensions
446 */
447 public static function unsetReservedGlobalVariables()
448 {
449 unset($GLOBALS['PAGES_TYPES']);
450 unset($GLOBALS['TCA']);
451 unset($GLOBALS['TBE_MODULES']);
452 unset($GLOBALS['TBE_STYLES']);
453 unset($GLOBALS['BE_USER']);
454 // Those set otherwise:
455 unset($GLOBALS['TBE_MODULES_EXT']);
456 unset($GLOBALS['TCA_DESCR']);
457 unset($GLOBALS['LOCAL_LANG']);
458 }
459
460 /**
461 * Load $TCA
462 *
463 * This will mainly set up $TCA through extMgm API.
464 *
465 * @param bool $allowCaching True, if loading TCA from cache is allowed
466 * @param FrontendInterface $coreCache
467 * @internal This is not a public API method, do not use in own extensions
468 */
469 public static function loadBaseTca(bool $allowCaching = true, FrontendInterface $coreCache = null)
470 {
471 if ($allowCaching) {
472 $coreCache = $coreCache ?? GeneralUtility::makeInstance(CacheManager::class)->getCache('core');
473 }
474 ExtensionManagementUtility::loadBaseTca($allowCaching, $coreCache);
475 }
476
477 /**
478 * Check if a configuration key has been configured
479 */
480 protected static function checkEncryptionKey()
481 {
482 if (empty($GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'])) {
483 throw new \RuntimeException(
484 'TYPO3 Encryption is empty. $GLOBALS[\'TYPO3_CONF_VARS\'][\'SYS\'][\'encryptionKey\'] needs to be set for TYPO3 to work securely',
485 1502987245
486 );
487 }
488 }
489
490 /**
491 * Load ext_tables and friends.
492 *
493 * This will mainly load and execute ext_tables.php files of loaded extensions
494 * or the according cache file if exists.
495 *
496 * @param bool $allowCaching True, if reading compiled ext_tables file from cache is allowed
497 * @internal This is not a public API method, do not use in own extensions
498 */
499 public static function loadExtTables(bool $allowCaching = true)
500 {
501 ExtensionManagementUtility::loadExtTables($allowCaching);
502 static::runExtTablesPostProcessingHooks();
503 }
504
505 /**
506 * Check for registered ext tables hooks and run them
507 *
508 * @throws \UnexpectedValueException
509 */
510 protected static function runExtTablesPostProcessingHooks()
511 {
512 foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['GLOBAL']['extTablesInclusion-PostProcessing'] ?? [] as $className) {
513 /** @var \TYPO3\CMS\Core\Database\TableConfigurationPostProcessingHookInterface $hookObject */
514 $hookObject = GeneralUtility::makeInstance($className);
515 if (!$hookObject instanceof \TYPO3\CMS\Core\Database\TableConfigurationPostProcessingHookInterface) {
516 throw new \UnexpectedValueException(
517 '$hookObject "' . $className . '" must implement interface TYPO3\\CMS\\Core\\Database\\TableConfigurationPostProcessingHookInterface',
518 1320585902
519 );
520 }
521 $hookObject->processData();
522 }
523 }
524
525 /**
526 * Initialize the Routing for the TYPO3 Backend
527 * Loads all routes registered inside all packages and stores them inside the Router
528 *
529 * @internal This is not a public API method, do not use in own extensions
530 */
531 public static function initializeBackendRouter()
532 {
533 // See if the Routes.php from all active packages have been built together already
534 $cacheIdentifier = 'BackendRoutesFromPackages_' . sha1(TYPO3_version . Environment::getProjectPath() . 'BackendRoutesFromPackages');
535
536 /** @var \TYPO3\CMS\Core\Cache\Frontend\FrontendInterface $codeCache */
537 $codeCache = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Cache\CacheManager::class)->getCache('core');
538 $routesFromPackages = [];
539 if ($codeCache->has($cacheIdentifier)) {
540 // substr is necessary, because the php frontend wraps php code around the cache value
541 $routesFromPackages = unserialize(substr($codeCache->get($cacheIdentifier), 6, -2));
542 } else {
543 $routesFromPackages = [[]];
544 // Loop over all packages and check for a Configuration/Backend/Routes.php file
545 $packageManager = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Package\PackageManager::class);
546 $packages = $packageManager->getActivePackages();
547 foreach ($packages as $package) {
548 $routesFileNameForPackage = $package->getPackagePath() . 'Configuration/Backend/Routes.php';
549 if (file_exists($routesFileNameForPackage)) {
550 $definedRoutesInPackage = require $routesFileNameForPackage;
551 if (is_array($definedRoutesInPackage)) {
552 $routesFromPackages[] = $definedRoutesInPackage;
553 }
554 }
555 $routesFileNameForPackage = $package->getPackagePath() . 'Configuration/Backend/AjaxRoutes.php';
556 if (file_exists($routesFileNameForPackage)) {
557 $definedRoutesInPackage = require $routesFileNameForPackage;
558 if (is_array($definedRoutesInPackage)) {
559 foreach ($definedRoutesInPackage as $routeIdentifier => $routeOptions) {
560 // prefix the route with "ajax_" as "namespace"
561 $routeOptions['path'] = '/ajax' . $routeOptions['path'];
562 $routeOptions['ajax'] = true;
563 $routesFromPackages[] = [
564 'ajax_' . $routeIdentifier => $routeOptions,
565 ];
566 }
567 }
568 }
569 }
570 $routesFromPackages = array_merge(...$routesFromPackages);
571 // Store the data from all packages in the cache
572 $codeCache->set($cacheIdentifier, serialize($routesFromPackages));
573 }
574
575 // Build Route objects from the data
576 $router = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Routing\Router::class);
577 foreach ($routesFromPackages as $name => $options) {
578 $path = $options['path'];
579 unset($options['path']);
580 $route = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Routing\Route::class, $path, $options);
581 $router->addRoute($name, $route);
582 }
583 }
584
585 /**
586 * Initialize backend user object in globals
587 *
588 * @param string $className usually \TYPO3\CMS\Core\Authentication\BackendUserAuthentication::class but can be used for CLI
589 * @internal This is not a public API method, do not use in own extensions
590 */
591 public static function initializeBackendUser($className = \TYPO3\CMS\Core\Authentication\BackendUserAuthentication::class)
592 {
593 /** @var \TYPO3\CMS\Core\Authentication\BackendUserAuthentication $backendUser */
594 $backendUser = GeneralUtility::makeInstance($className);
595 // The global must be available very early, because methods below
596 // might trigger code which relies on it. See: #45625
597 $GLOBALS['BE_USER'] = $backendUser;
598 $backendUser->start();
599 }
600
601 /**
602 * Initializes and ensures authenticated access
603 *
604 * @internal This is not a public API method, do not use in own extensions
605 * @param bool $proceedIfNoUserIsLoggedIn if set to TRUE, no forced redirect to the login page will be done
606 */
607 public static function initializeBackendAuthentication($proceedIfNoUserIsLoggedIn = false)
608 {
609 $GLOBALS['BE_USER']->backendCheckLogin($proceedIfNoUserIsLoggedIn);
610 }
611
612 /**
613 * Initialize language object
614 *
615 * @internal This is not a public API method, do not use in own extensions
616 */
617 public static function initializeLanguageObject()
618 {
619 /** @var $GLOBALS['LANG'] \TYPO3\CMS\Core\Localization\LanguageService */
620 $GLOBALS['LANG'] = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Localization\LanguageService::class);
621 $GLOBALS['LANG']->init($GLOBALS['BE_USER']->uc['lang']);
622 }
623 }