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