TYPO3 CMS  TYPO3_8-7
Bootstrap.php
Go to the documentation of this file.
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 
24 
36 class Bootstrap
37 {
41  protected static $instance = null;
42 
48  protected $requestId;
49 
56 
60  protected $earlyInstances = [];
61 
65  protected $installToolPath;
66 
71  protected $availableRequestHandlers = [];
72 
78  protected $response;
79 
83  protected static $usesComposerClassLoading = false;
84 
91  protected function __construct($applicationContext)
92  {
93  $this->requestId = substr(md5(uniqid('', true)), 0, 13);
94  $this->applicationContext = new ApplicationContext($applicationContext);
95  }
96 
100  public static function usesComposerClassLoading()
101  {
102  return self::$usesComposerClassLoading;
103  }
104 
108  protected function __clone()
109  {
110  }
111 
118  public static function getInstance()
119  {
120  if (is_null(static::$instance)) {
121  $applicationContext = getenv('TYPO3_CONTEXT') ?: (getenv('REDIRECT_TYPO3_CONTEXT') ?: 'Production');
122  self::$instance = new static($applicationContext);
123  self::$instance->defineTypo3RequestTypes();
124  }
125  return static::$instance;
126  }
127 
134  public function getRequestId()
135  {
136  return $this->requestId;
137  }
138 
146  public function getApplicationContext()
147  {
149  }
150 
158  public function startOutputBuffering()
159  {
160  ob_start();
161  return $this;
162  }
163 
172  public function configure()
173  {
174  $this->startOutputBuffering()
175  ->loadConfigurationAndInitialize()
176  ->loadTypo3LoadedExtAndExtLocalconf(true)
177  ->setFinalCachingFrameworkCacheConfiguration()
178  ->defineLoggingAndExceptionConstants()
179  ->unsetReservedGlobalVariables()
180  ->initializeTypo3DbGlobal();
181  if (empty($GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'])) {
182  throw new \RuntimeException(
183  'TYPO3 Encryption is empty. $GLOBALS[\'TYPO3_CONF_VARS\'][\'SYS\'][\'encryptionKey\'] needs to be set for TYPO3 to work securely',
184  1502987245
185  );
186  }
187  return $this;
188  }
189 
201  public function baseSetup($entryPointLevel = 0)
202  {
203  if (!defined('TYPO3_REQUESTTYPE')) {
204  throw new \RuntimeException('No Request Type was set, TYPO3 does not know in which context it is run.', 1450561838);
205  }
206  SystemEnvironmentBuilder::run($entryPointLevel);
207  if (!self::$usesComposerClassLoading && ClassLoadingInformation::isClassLoadingInformationAvailable()) {
209  }
210  GeneralUtility::presetApplicationContext($this->applicationContext);
211  return $this;
212  }
213 
221  public function initializeClassLoader($classLoader)
222  {
223  $this->setEarlyInstance(\Composer\Autoload\ClassLoader::class, $classLoader);
224  if (defined('TYPO3_COMPOSER_MODE') && TYPO3_COMPOSER_MODE) {
225  self::$usesComposerClassLoading = true;
226  }
227  return $this;
228  }
229 
238  {
239  $configurationManager = new \TYPO3\CMS\Core\Configuration\ConfigurationManager;
240  $this->setEarlyInstance(\TYPO3\CMS\Core\Configuration\ConfigurationManager::class, $configurationManager);
241  return file_exists($configurationManager->getLocalConfigurationFileLocation()) && file_exists(PATH_typo3conf . 'PackageStates.php');
242  }
243 
250  public function redirectToInstallTool($entryPointLevel = 0)
251  {
252  $path = TYPO3_mainDir . 'install.php';
253  if ($entryPointLevel > 0) {
254  $path = str_repeat('../', $entryPointLevel) . $path;
255  }
256  header('Location: ' . $path);
257  die;
258  }
259 
267  public function registerRequestHandlerImplementation($requestHandler)
268  {
269  $this->availableRequestHandlers[] = $requestHandler;
270  return $this;
271  }
272 
283  protected function resolveRequestHandler($request)
284  {
285  $suitableRequestHandlers = [];
286  foreach ($this->availableRequestHandlers as $requestHandlerClassName) {
288  $requestHandler = GeneralUtility::makeInstance($requestHandlerClassName, $this);
289  if ($requestHandler->canHandleRequest($request)) {
290  $priority = $requestHandler->getPriority();
291  if (isset($suitableRequestHandlers[$priority])) {
292  throw new \TYPO3\CMS\Core\Exception('More than one request handler with the same priority can handle the request, but only one handler may be active at a time!', 1176471352);
293  }
294  $suitableRequestHandlers[$priority] = $requestHandler;
295  }
296  }
297  if (empty($suitableRequestHandlers)) {
298  throw new \TYPO3\CMS\Core\Exception('No suitable request handler found.', 1225418233);
299  }
300  ksort($suitableRequestHandlers);
301  return array_pop($suitableRequestHandlers);
302  }
303 
313  public function handleRequest($request)
314  {
315  // Resolve request handler that were registered based on the Application
316  $requestHandler = $this->resolveRequestHandler($request);
317 
318  // Execute the command which returns a Response object or NULL
319  $this->response = $requestHandler->handleRequest($request);
320  return $this;
321  }
322 
328  protected function sendResponse()
329  {
330  if ($this->response instanceof \Psr\Http\Message\ResponseInterface) {
331  if (!headers_sent()) {
332  // If the response code was not changed by legacy code (still is 200)
333  // then allow the PSR-7 response object to explicitly set it.
334  // Otherwise let legacy code take precedence.
335  // This code path can be deprecated once we expose the response object to third party code
336  if (http_response_code() === 200) {
337  header('HTTP/' . $this->response->getProtocolVersion() . ' ' . $this->response->getStatusCode() . ' ' . $this->response->getReasonPhrase());
338  }
339 
340  foreach ($this->response->getHeaders() as $name => $values) {
341  header($name . ': ' . implode(', ', $values));
342  }
343  }
344  echo $this->response->getBody()->__toString();
345  }
346  return $this;
347  }
348 
358  public function setEarlyInstance($objectName, $instance)
359  {
360  $this->earlyInstances[$objectName] = $instance;
361  }
362 
371  public function getEarlyInstance($objectName)
372  {
373  if (!isset($this->earlyInstances[$objectName])) {
374  throw new \TYPO3\CMS\Core\Exception('Unknown early instance "' . $objectName . '"', 1365167380);
375  }
376  return $this->earlyInstances[$objectName];
377  }
378 
385  public function getEarlyInstances()
386  {
387  return $this->earlyInstances;
388  }
389 
399  public function loadConfigurationAndInitialize($allowCaching = true, $packageManagerClassName = \TYPO3\CMS\Core\Package\PackageManager::class)
400  {
402  ->initializeErrorHandling()
403  ->initializeIO();
404  if (!$allowCaching) {
405  $this->disableCoreCache();
406  }
408  ->initializePackageManagement($packageManagerClassName)
409  ->initializeRuntimeActivatedPackagesFromConfiguration()
410  ->defineUserAgentConstant()
411  ->registerExtDirectComponents()
412  ->setCacheHashOptions()
413  ->setDefaultTimezone()
414  ->initializeL10nLocales()
415  ->setMemoryLimit();
416  if ($allowCaching) {
418  }
419  return $this;
420  }
421 
430  public function initializePackageManagement($packageManagerClassName)
431  {
433  $packageManager = new $packageManagerClassName();
434  $this->setEarlyInstance(\TYPO3\CMS\Core\Package\PackageManager::class, $packageManager);
436  $packageManager->injectCoreCache($this->getEarlyInstance(\TYPO3\CMS\Core\Cache\CacheManager::class)->getCache('cache_core'));
437  $dependencyResolver = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Package\DependencyResolver::class);
438  $dependencyResolver->injectDependencyOrderingService(GeneralUtility::makeInstance(\TYPO3\CMS\Core\Service\DependencyOrderingService::class));
439  $packageManager->injectDependencyResolver($dependencyResolver);
440  $packageManager->initialize();
441  GeneralUtility::setSingletonInstance(\TYPO3\CMS\Core\Package\PackageManager::class, $packageManager);
442  return $this;
443  }
444 
453  {
454  if (!self::$usesComposerClassLoading && !ClassLoadingInformation::isClassLoadingInformationAvailable()) {
456  ClassLoadingInformation::dumpClassLoadingInformation();
458  }
459  return $this;
460  }
461 
468  protected function initializeRuntimeActivatedPackagesFromConfiguration()
469  {
470  if (!empty($GLOBALS['TYPO3_CONF_VARS']['EXT']['runtimeActivatedPackages']) && is_array($GLOBALS['TYPO3_CONF_VARS']['EXT']['runtimeActivatedPackages'])) {
472  $packageManager = $this->getEarlyInstance(\TYPO3\CMS\Core\Package\PackageManager::class);
473  foreach ($GLOBALS['TYPO3_CONF_VARS']['EXT']['runtimeActivatedPackages'] as $runtimeAddedPackageKey) {
474  $packageManager->activatePackageDuringRuntime($runtimeAddedPackageKey);
475  }
476  }
477  return $this;
478  }
479 
487  public function loadTypo3LoadedExtAndExtLocalconf($allowCaching = true)
488  {
489  ExtensionManagementUtility::loadExtLocalconf($allowCaching);
490  return $this;
491  }
492 
500  public function populateLocalConfiguration()
501  {
502  try {
503  $configurationManager = $this->getEarlyInstance(\TYPO3\CMS\Core\Configuration\ConfigurationManager::class);
504  } catch (\TYPO3\CMS\Core\Exception $exception) {
505  $configurationManager = new \TYPO3\CMS\Core\Configuration\ConfigurationManager();
506  $this->setEarlyInstance(\TYPO3\CMS\Core\Configuration\ConfigurationManager::class, $configurationManager);
507  }
508  $configurationManager->exportConfiguration();
509  return $this;
510  }
511 
518  public function disableCoreCache()
519  {
520  $GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['cache_core']['backend']
521  = \TYPO3\CMS\Core\Cache\Backend\NullBackend::class;
522  unset($GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['cache_core']['options']);
523  return $this;
524  }
525 
531  protected function defineUserAgentConstant()
532  {
533  define('TYPO3_user_agent', 'User-Agent: ' . $GLOBALS['TYPO3_CONF_VARS']['HTTP']['headers']['User-Agent']);
534  return $this;
535  }
536 
542  protected function registerExtDirectComponents()
543  {
544  if (TYPO3_MODE === 'BE') {
546  'TYPO3.Components.PageTree.DataProvider',
547  \TYPO3\CMS\Backend\Tree\Pagetree\ExtdirectTreeDataProvider::class
548  );
550  'TYPO3.Components.PageTree.Commands',
551  \TYPO3\CMS\Backend\Tree\Pagetree\ExtdirectTreeCommands::class
552  );
553  }
554  return $this;
555  }
556 
564  public function initializeCachingFramework()
565  {
566  $cacheManager = new \TYPO3\CMS\Core\Cache\CacheManager();
567  $cacheManager->setCacheConfigurations($GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']);
568  GeneralUtility::setSingletonInstance(\TYPO3\CMS\Core\Cache\CacheManager::class, $cacheManager);
569  $this->setEarlyInstance(\TYPO3\CMS\Core\Cache\CacheManager::class, $cacheManager);
570  return $this;
571  }
572 
578  protected function setCacheHashOptions()
579  {
580  $GLOBALS['TYPO3_CONF_VARS']['FE']['cacheHash'] = [
581  'cachedParametersWhiteList' => GeneralUtility::trimExplode(',', $GLOBALS['TYPO3_CONF_VARS']['FE']['cHashOnlyForParameters'], true),
582  'excludedParameters' => GeneralUtility::trimExplode(',', $GLOBALS['TYPO3_CONF_VARS']['FE']['cHashExcludedParameters'], true),
583  'requireCacheHashPresenceParameters' => GeneralUtility::trimExplode(',', $GLOBALS['TYPO3_CONF_VARS']['FE']['cHashRequiredParameters'], true),
584  ];
585  if (trim($GLOBALS['TYPO3_CONF_VARS']['FE']['cHashExcludedParametersIfEmpty']) === '*') {
586  $GLOBALS['TYPO3_CONF_VARS']['FE']['cacheHash']['excludeAllEmptyParameters'] = true;
587  } else {
588  $GLOBALS['TYPO3_CONF_VARS']['FE']['cacheHash']['excludedParametersIfEmpty'] = GeneralUtility::trimExplode(',', $GLOBALS['TYPO3_CONF_VARS']['FE']['cHashExcludedParametersIfEmpty'], true);
589  }
590  return $this;
591  }
592 
598  protected function setDefaultTimezone()
599  {
600  $timeZone = $GLOBALS['TYPO3_CONF_VARS']['SYS']['phpTimeZone'];
601  if (empty($timeZone)) {
602  // Time zone from the server environment (TZ env or OS query)
603  $defaultTimeZone = @date_default_timezone_get();
604  if ($defaultTimeZone !== '') {
605  $timeZone = $defaultTimeZone;
606  } else {
607  $timeZone = 'UTC';
608  }
609  }
610  // Set default to avoid E_WARNINGs with PHP > 5.3
611  date_default_timezone_set($timeZone);
612  return $this;
613  }
614 
620  protected function initializeL10nLocales()
621  {
622  \TYPO3\CMS\Core\Localization\Locales::initialize();
623  return $this;
624  }
625 
632  protected function initializeErrorHandling()
633  {
634  $productionExceptionHandlerClassName = $GLOBALS['TYPO3_CONF_VARS']['SYS']['productionExceptionHandler'];
635  $debugExceptionHandlerClassName = $GLOBALS['TYPO3_CONF_VARS']['SYS']['debugExceptionHandler'];
636 
637  $errorHandlerClassName = $GLOBALS['TYPO3_CONF_VARS']['SYS']['errorHandler'];
638  $errorHandlerErrors = $GLOBALS['TYPO3_CONF_VARS']['SYS']['errorHandlerErrors'];
639  $exceptionalErrors = $GLOBALS['TYPO3_CONF_VARS']['SYS']['exceptionalErrors'];
640 
641  $displayErrorsSetting = (int)$GLOBALS['TYPO3_CONF_VARS']['SYS']['displayErrors'];
642  switch ($displayErrorsSetting) {
643  case -1:
644  $ipMatchesDevelopmentSystem = GeneralUtility::cmpIP(GeneralUtility::getIndpEnv('REMOTE_ADDR'), $GLOBALS['TYPO3_CONF_VARS']['SYS']['devIPmask']);
645  $exceptionHandlerClassName = $ipMatchesDevelopmentSystem ? $debugExceptionHandlerClassName : $productionExceptionHandlerClassName;
646  $displayErrors = $ipMatchesDevelopmentSystem ? 1 : 0;
647  $exceptionalErrors = $ipMatchesDevelopmentSystem ? $exceptionalErrors : 0;
648  break;
649  case 0:
650  $exceptionHandlerClassName = $productionExceptionHandlerClassName;
651  $displayErrors = 0;
652  break;
653  case 1:
654  $exceptionHandlerClassName = $debugExceptionHandlerClassName;
655  $displayErrors = 1;
656  break;
657  default:
658  if (!(TYPO3_REQUESTTYPE & TYPO3_REQUESTTYPE_INSTALL)) {
659  // Throw exception if an invalid option is set.
660  throw new \RuntimeException(
661  'The option $TYPO3_CONF_VARS[SYS][displayErrors] is not set to "-1", "0" or "1".',
662  1476046290
663  );
664  }
665  }
666  @ini_set('display_errors', $displayErrors);
667 
668  if (!empty($errorHandlerClassName)) {
669  // Register an error handler for the given errorHandlerError
670  $errorHandler = GeneralUtility::makeInstance($errorHandlerClassName, $errorHandlerErrors);
671  $errorHandler->setExceptionalErrors($exceptionalErrors);
672  if (is_callable([$errorHandler, 'setDebugMode'])) {
673  $errorHandler->setDebugMode($displayErrors === 1);
674  }
675  }
676  if (!empty($exceptionHandlerClassName)) {
677  // Registering the exception handler is done in the constructor
678  GeneralUtility::makeInstance($exceptionHandlerClassName);
679  }
680  return $this;
681  }
682 
686  protected function initializeIO()
687  {
688  if (in_array('phar', stream_get_wrappers())) {
689  // destroy and re-initialize PharStreamWrapper for TYPO3 core
690  Manager::destroy();
691  Manager::initialize(
692  (new Behavior())
693  ->withAssertion(new PharStreamWrapperInterceptor())
694  );
695 
696  stream_wrapper_unregister('phar');
697  stream_wrapper_register('phar', PharStreamWrapper::class);
698  }
699  }
700 
707  protected function setMemoryLimit()
708  {
709  if ((int)$GLOBALS['TYPO3_CONF_VARS']['SYS']['setMemoryLimit'] > 16) {
710  @ini_set('memory_limit', ((int)$GLOBALS['TYPO3_CONF_VARS']['SYS']['setMemoryLimit'] . 'm'));
711  }
712  return $this;
713  }
714 
721  protected function defineTypo3RequestTypes()
722  {
723  define('TYPO3_REQUESTTYPE_FE', 1);
724  define('TYPO3_REQUESTTYPE_BE', 2);
725  define('TYPO3_REQUESTTYPE_CLI', 4);
726  define('TYPO3_REQUESTTYPE_AJAX', 8);
727  define('TYPO3_REQUESTTYPE_INSTALL', 16);
728  }
729 
736  public function setRequestType($requestType)
737  {
738  if (defined('TYPO3_REQUESTTYPE')) {
739  throw new \RuntimeException('TYPO3_REQUESTTYPE has already been set, cannot be called multiple times', 1450561878);
740  }
741  define('TYPO3_REQUESTTYPE', $requestType);
742  return $this;
743  }
744 
753  {
754  $this->getEarlyInstance(\TYPO3\CMS\Core\Cache\CacheManager::class)->setCacheConfigurations($GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']);
755  return $this;
756  }
757 
765  {
766  define('TYPO3_DLOG', $GLOBALS['TYPO3_CONF_VARS']['SYS']['enable_DLOG']);
767  define('TYPO3_ERROR_DLOG', $GLOBALS['TYPO3_CONF_VARS']['SYS']['enable_errorDLOG']);
768  define('TYPO3_EXCEPTION_DLOG', $GLOBALS['TYPO3_CONF_VARS']['SYS']['enable_exceptionDLOG']);
769  return $this;
770  }
771 
780  {
781  unset($GLOBALS['PAGES_TYPES']);
782  unset($GLOBALS['TCA']);
783  unset($GLOBALS['TBE_MODULES']);
784  unset($GLOBALS['TBE_STYLES']);
785  unset($GLOBALS['BE_USER']);
786  // Those set otherwise:
787  unset($GLOBALS['TBE_MODULES_EXT']);
788  unset($GLOBALS['TCA_DESCR']);
789  unset($GLOBALS['LOCAL_LANG']);
790  return $this;
791  }
792 
799  public function initializeTypo3DbGlobal()
800  {
802  $databaseConnection = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Database\DatabaseConnection::class);
803  $databaseConnection->setDatabaseName(
804  $GLOBALS['TYPO3_CONF_VARS']['DB']['Connections']['Default']['dbname'] ?? ''
805  );
806  $databaseConnection->setDatabaseUsername(
807  $GLOBALS['TYPO3_CONF_VARS']['DB']['Connections']['Default']['user'] ?? ''
808  );
809  $databaseConnection->setDatabasePassword(
810  $GLOBALS['TYPO3_CONF_VARS']['DB']['Connections']['Default']['password'] ?? ''
811  );
812  $databaseConnection->setConnectionCharset(
813  $GLOBALS['TYPO3_CONF_VARS']['DB']['Connections']['Default']['charset'] ?? 'utf8'
814  );
815 
816  $databaseHost = $GLOBALS['TYPO3_CONF_VARS']['DB']['Connections']['Default']['host'] ?? '';
817  if (isset($GLOBALS['TYPO3_CONF_VARS']['DB']['Connections']['Default']['port'])) {
818  $databaseConnection->setDatabasePort($GLOBALS['TYPO3_CONF_VARS']['DB']['Connections']['Default']['port']);
819  } elseif (strpos($databaseHost, ':') > 0) {
820  // @TODO: Find a way to handle this case in the install tool and drop this
821  list($databaseHost, $databasePort) = explode(':', $databaseHost);
822  $databaseConnection->setDatabasePort($databasePort);
823  }
824  if (isset($GLOBALS['TYPO3_CONF_VARS']['DB']['Connections']['Default']['unix_socket'])) {
825  $databaseConnection->setDatabaseSocket(
826  $GLOBALS['TYPO3_CONF_VARS']['DB']['Connections']['Default']['unix_socket']
827  );
828  }
829  $databaseConnection->setDatabaseHost($databaseHost);
830 
831  $databaseConnection->debugOutput = $GLOBALS['TYPO3_CONF_VARS']['SYS']['sqlDebug'];
832 
833  if (isset($GLOBALS['TYPO3_CONF_VARS']['DB']['Connections']['Default']['persistentConnection'])
834  && $GLOBALS['TYPO3_CONF_VARS']['DB']['Connections']['Default']['persistentConnection']
835  ) {
836  $databaseConnection->setPersistentDatabaseConnection(true);
837  }
838 
839  $isDatabaseHostLocalHost = in_array($databaseHost, ['localhost', '127.0.0.1', '::1'], true);
840  if (isset($GLOBALS['TYPO3_CONF_VARS']['DB']['Connections']['Default']['driverOptions'])
841  && $GLOBALS['TYPO3_CONF_VARS']['DB']['Connections']['Default']['driverOptions'] & MYSQLI_CLIENT_COMPRESS
842  && !$isDatabaseHostLocalHost
843  ) {
844  $databaseConnection->setConnectionCompression(true);
845  }
846 
847  if (!empty($GLOBALS['TYPO3_CONF_VARS']['DB']['Connections']['Default']['initCommands'])) {
848  $commandsAfterConnect = GeneralUtility::trimExplode(
849  LF,
850  str_replace(
851  '\' . LF . \'',
852  LF,
853  $GLOBALS['TYPO3_CONF_VARS']['DB']['Connections']['Default']['initCommands']
854  ),
855  true
856  );
857  $databaseConnection->setInitializeCommandsAfterConnect($commandsAfterConnect);
858  }
859 
860  $GLOBALS['TYPO3_DB'] = $databaseConnection;
861  // $GLOBALS['TYPO3_DB'] needs to be defined first in order to work for DBAL
862  $GLOBALS['TYPO3_DB']->initialize();
863 
864  return $this;
865  }
866 
876  public function checkLockedBackendAndRedirectOrDie($forceProceeding = false)
877  {
878  if ($GLOBALS['TYPO3_CONF_VARS']['BE']['adminOnly'] < 0) {
879  throw new \RuntimeException('TYPO3 Backend locked: Backend and Install Tool are locked for maintenance. [BE][adminOnly] is set to "' . (int)$GLOBALS['TYPO3_CONF_VARS']['BE']['adminOnly'] . '".', 1294586847);
880  }
881  if (@is_file(PATH_typo3conf . 'LOCK_BACKEND') && $forceProceeding === false) {
882  $fileContent = file_get_contents(PATH_typo3conf . 'LOCK_BACKEND');
883  if ($fileContent) {
884  header('Location: ' . $fileContent);
885  } else {
886  throw new \RuntimeException('TYPO3 Backend locked: Browser backend is locked for maintenance. Remove lock by removing the file "typo3conf/LOCK_BACKEND" or use CLI-scripts.', 1294586848);
887  }
888  die;
889  }
890  return $this;
891  }
892 
901  public function checkBackendIpOrDie()
902  {
903  if (trim($GLOBALS['TYPO3_CONF_VARS']['BE']['IPmaskList'])) {
904  if (!GeneralUtility::cmpIP(GeneralUtility::getIndpEnv('REMOTE_ADDR'), $GLOBALS['TYPO3_CONF_VARS']['BE']['IPmaskList'])) {
905  throw new \RuntimeException('TYPO3 Backend access denied: The IP address of your client does not match the list of allowed IP addresses.', 1389265900);
906  }
907  }
908  return $this;
909  }
910 
920  {
921  if ((bool)$GLOBALS['TYPO3_CONF_VARS']['BE']['lockSSL'] && !GeneralUtility::getIndpEnv('TYPO3_SSL')) {
922  if ((int)$GLOBALS['TYPO3_CONF_VARS']['BE']['lockSSLPort']) {
923  $sslPortSuffix = ':' . (int)$GLOBALS['TYPO3_CONF_VARS']['BE']['lockSSLPort'];
924  } else {
925  $sslPortSuffix = '';
926  }
927  list(, $url) = explode('://', GeneralUtility::getIndpEnv('TYPO3_SITE_URL') . TYPO3_mainDir, 2);
928  list($server, $address) = explode('/', $url, 2);
929  header('Location: https://' . $server . $sslPortSuffix . '/' . $address);
930  die;
931  }
932  return $this;
933  }
934 
948  public function loadExtensionTables($allowCaching = true)
949  {
951  $this->loadBaseTca($allowCaching)->loadExtTables($allowCaching);
952  return $this;
953  }
954 
964  public function loadBaseTca(bool $allowCaching = true): Bootstrap
965  {
966  ExtensionManagementUtility::loadBaseTca($allowCaching);
967  return $this;
968  }
969 
980  public function loadExtTables(bool $allowCaching = true): Bootstrap
981  {
982  ExtensionManagementUtility::loadExtTables($allowCaching);
983  $this->runExtTablesPostProcessingHooks();
984  return $this;
985  }
986 
992  protected function runExtTablesPostProcessingHooks()
993  {
994  if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['GLOBAL']['extTablesInclusion-PostProcessing'])) {
995  foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['GLOBAL']['extTablesInclusion-PostProcessing'] as $classReference) {
997  $hookObject = GeneralUtility::getUserObj($classReference);
998  if (!$hookObject instanceof \TYPO3\CMS\Core\Database\TableConfigurationPostProcessingHookInterface) {
999  throw new \UnexpectedValueException(
1000  '$hookObject "' . $classReference . '" must implement interface TYPO3\\CMS\\Core\\Database\\TableConfigurationPostProcessingHookInterface',
1001  1320585902
1002  );
1003  }
1004  $hookObject->processData();
1005  }
1006  }
1007  }
1008 
1016  public function initializeBackendRouter()
1017  {
1018  // See if the Routes.php from all active packages have been built together already
1019  $cacheIdentifier = 'BackendRoutesFromPackages_' . sha1((TYPO3_version . PATH_site . 'BackendRoutesFromPackages'));
1020 
1022  $codeCache = $this->getEarlyInstance(\TYPO3\CMS\Core\Cache\CacheManager::class)->getCache('cache_core');
1023  $routesFromPackages = [];
1024  if ($codeCache->has($cacheIdentifier)) {
1025  // substr is necessary, because the php frontend wraps php code around the cache value
1026  $routesFromPackages = unserialize(substr($codeCache->get($cacheIdentifier), 6, -2));
1027  } else {
1028  // Loop over all packages and check for a Configuration/Backend/Routes.php file
1029  $packageManager = $this->getEarlyInstance(\TYPO3\CMS\Core\Package\PackageManager::class);
1030  $packages = $packageManager->getActivePackages();
1031  foreach ($packages as $package) {
1032  $routesFileNameForPackage = $package->getPackagePath() . 'Configuration/Backend/Routes.php';
1033  if (file_exists($routesFileNameForPackage)) {
1034  $definedRoutesInPackage = require $routesFileNameForPackage;
1035  if (is_array($definedRoutesInPackage)) {
1036  $routesFromPackages = array_merge($routesFromPackages, $definedRoutesInPackage);
1037  }
1038  }
1039  $routesFileNameForPackage = $package->getPackagePath() . 'Configuration/Backend/AjaxRoutes.php';
1040  if (file_exists($routesFileNameForPackage)) {
1041  $definedRoutesInPackage = require $routesFileNameForPackage;
1042  if (is_array($definedRoutesInPackage)) {
1043  foreach ($definedRoutesInPackage as $routeIdentifier => $routeOptions) {
1044  // prefix the route with "ajax_" as "namespace"
1045  $routeOptions['path'] = '/ajax' . $routeOptions['path'];
1046  $routesFromPackages['ajax_' . $routeIdentifier] = $routeOptions;
1047  $routesFromPackages['ajax_' . $routeIdentifier]['ajax'] = true;
1048  }
1049  }
1050  }
1051  }
1052  // Store the data from all packages in the cache
1053  $codeCache->set($cacheIdentifier, serialize($routesFromPackages));
1054  }
1055 
1056  // Build Route objects from the data
1057  $router = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Routing\Router::class);
1058  foreach ($routesFromPackages as $name => $options) {
1059  $path = $options['path'];
1060  unset($options['path']);
1061  $route = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Routing\Route::class, $path, $options);
1062  $router->addRoute($name, $route);
1063  }
1064  return $this;
1065  }
1066 
1074  public function initializeBackendUser($className = \TYPO3\CMS\Core\Authentication\BackendUserAuthentication::class)
1075  {
1077  $backendUser = GeneralUtility::makeInstance($className);
1078  // The global must be available very early, because methods below
1079  // might trigger code which relies on it. See: #45625
1080  $GLOBALS['BE_USER'] = $backendUser;
1081  $backendUser->start();
1082  return $this;
1083  }
1084 
1092  public function initializeBackendAuthentication($proceedIfNoUserIsLoggedIn = false)
1093  {
1094  $GLOBALS['BE_USER']->backendCheckLogin($proceedIfNoUserIsLoggedIn);
1095  return $this;
1096  }
1097 
1104  public function initializeLanguageObject()
1105  {
1107  $GLOBALS['LANG'] = GeneralUtility::makeInstance(\TYPO3\CMS\Lang\LanguageService::class);
1108  $GLOBALS['LANG']->init($GLOBALS['BE_USER']->uc['lang']);
1109  return $this;
1110  }
1111 
1119  {
1120  ob_clean();
1121  return $this;
1122  }
1123 
1131  {
1132  if (extension_loaded('zlib') && $GLOBALS['TYPO3_CONF_VARS']['BE']['compressionLevel']) {
1133  if (MathUtility::canBeInterpretedAsInteger($GLOBALS['TYPO3_CONF_VARS']['BE']['compressionLevel'])) {
1134  @ini_set('zlib.output_compression_level', $GLOBALS['TYPO3_CONF_VARS']['BE']['compressionLevel']);
1135  }
1136  ob_start('ob_gzhandler');
1137  }
1138  return $this;
1139  }
1140 
1147  public function sendHttpHeaders()
1148  {
1149  if (!empty($GLOBALS['TYPO3_CONF_VARS']['BE']['HTTP']['Response']['Headers']) && is_array($GLOBALS['TYPO3_CONF_VARS']['BE']['HTTP']['Response']['Headers'])) {
1150  foreach ($GLOBALS['TYPO3_CONF_VARS']['BE']['HTTP']['Response']['Headers'] as $header) {
1151  header($header);
1152  }
1153  }
1154  return $this;
1155  }
1156 
1165  public function shutdown()
1166  {
1167  $this->sendResponse();
1168  return $this;
1169  }
1170 
1178  public function initializeBackendTemplate()
1179  {
1180  $GLOBALS['TBE_TEMPLATE'] = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Template\DocumentTemplate::class);
1181  return $this;
1182  }
1183 }
__construct($applicationContext)
Definition: Bootstrap.php:91
loadTypo3LoadedExtAndExtLocalconf($allowCaching=true)
Definition: Bootstrap.php:487
loadExtensionTables($allowCaching=true)
Definition: Bootstrap.php:948
setEarlyInstance($objectName, $instance)
Definition: Bootstrap.php:358
registerRequestHandlerImplementation($requestHandler)
Definition: Bootstrap.php:267
static setSingletonInstance($className, SingletonInterface $instance)
loadExtTables(bool $allowCaching=true)
Definition: Bootstrap.php:980
static trimExplode($delim, $string, $removeEmptyValues=false, $limit=0)
baseSetup($entryPointLevel=0)
Definition: Bootstrap.php:201
static makeInstance($className,... $constructorArguments)
loadBaseTca(bool $allowCaching=true)
Definition: Bootstrap.php:964
redirectToInstallTool($entryPointLevel=0)
Definition: Bootstrap.php:250
initializeBackendAuthentication($proceedIfNoUserIsLoggedIn=false)
Definition: Bootstrap.php:1092
initializeClassLoader($classLoader)
Definition: Bootstrap.php:221
static registerExtDirectComponent($endpointName, $callbackClass, $moduleName=null, $accessLevel=null)
static setPackageManager(PackageManager $packageManager)
if(TYPO3_MODE==='BE') $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tsfebeuserauth.php']['frontendEditingController']['default']
loadConfigurationAndInitialize($allowCaching=true, $packageManagerClassName=\TYPO3\CMS\Core\Package\PackageManager::class)
Definition: Bootstrap.php:399
checkLockedBackendAndRedirectOrDie($forceProceeding=false)
Definition: Bootstrap.php:876
static presetApplicationContext(ApplicationContext $applicationContext)