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