TYPO3  7.6
core/Classes/Core/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 
20 
32 class Bootstrap
33 {
37  protected static $instance = null;
38 
44  protected $requestId;
45 
52 
56  protected $earlyInstances = array();
57 
61  protected $installToolPath;
62 
67  protected $availableRequestHandlers = array();
68 
74  protected $response;
75 
79  protected static $usesComposerClassLoading = false;
80 
87  protected function __construct($applicationContext)
88  {
89  $this->requestId = substr(md5(uniqid('', true)), 0, 13);
90  $this->applicationContext = new ApplicationContext($applicationContext);
91  }
92 
96  public static function usesComposerClassLoading()
97  {
98  return self::$usesComposerClassLoading;
99  }
100 
104  protected function __clone()
105  {
106  }
107 
114  public static function getInstance()
115  {
116  if (is_null(static::$instance)) {
117  $applicationContext = getenv('TYPO3_CONTEXT') ?: (getenv('REDIRECT_TYPO3_CONTEXT') ?: 'Production');
118  self::$instance = new static($applicationContext);
119  }
120  return static::$instance;
121  }
122 
129  public function getRequestId()
130  {
131  return $this->requestId;
132  }
133 
141  public function getApplicationContext()
142  {
144  }
145 
153  public function startOutputBuffering()
154  {
155  ob_start();
156  return $this;
157  }
158 
167  public function configure()
168  {
169  $this->startOutputBuffering()
170  ->loadConfigurationAndInitialize()
171  ->loadTypo3LoadedExtAndExtLocalconf(true)
172  ->setFinalCachingFrameworkCacheConfiguration()
173  ->defineLoggingAndExceptionConstants()
174  ->unsetReservedGlobalVariables()
175  ->initializeTypo3DbGlobal();
176 
177  return $this;
178  }
179 
190  public function baseSetup($relativePathPart = '')
191  {
192  SystemEnvironmentBuilder::run($relativePathPart);
193  if (!self::$usesComposerClassLoading && ClassLoadingInformation::isClassLoadingInformationAvailable()) {
195  }
196  GeneralUtility::presetApplicationContext($this->applicationContext);
197  return $this;
198  }
199 
207  public function initializeClassLoader($classLoader)
208  {
209  $this->setEarlyInstance(\Composer\Autoload\ClassLoader::class, $classLoader);
210  if (defined('TYPO3_COMPOSER_MODE') && TYPO3_COMPOSER_MODE) {
211  self::$usesComposerClassLoading = true;
212  }
213  return $this;
214  }
215 
224  {
225  $configurationManager = new \TYPO3\CMS\Core\Configuration\ConfigurationManager;
226  $this->setEarlyInstance(\TYPO3\CMS\Core\Configuration\ConfigurationManager::class, $configurationManager);
227  return file_exists($configurationManager->getLocalConfigurationFileLocation()) && file_exists(PATH_typo3conf . 'PackageStates.php');
228  }
229 
235  public function redirectToInstallTool($relativePathPart = '')
236  {
237  $backPathToSiteRoot = str_repeat('../', count(explode('/', $relativePathPart)) - 1);
238  header('Location: ' . $backPathToSiteRoot . 'typo3/sysext/install/Start/Install.php');
239  die;
240  }
241 
249  public function registerRequestHandlerImplementation($requestHandler)
250  {
251  $this->availableRequestHandlers[] = $requestHandler;
252  return $this;
253  }
254 
265  protected function resolveRequestHandler($request)
266  {
267  $suitableRequestHandlers = array();
268  foreach ($this->availableRequestHandlers as $requestHandlerClassName) {
270  $requestHandler = GeneralUtility::makeInstance($requestHandlerClassName, $this);
271  if ($requestHandler->canHandleRequest($request)) {
272  $priority = $requestHandler->getPriority();
273  if (isset($suitableRequestHandlers[$priority])) {
274  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);
275  }
276  $suitableRequestHandlers[$priority] = $requestHandler;
277  }
278  }
279  if (empty($suitableRequestHandlers)) {
280  throw new \TYPO3\CMS\Core\Exception('No suitable request handler found.', 1225418233);
281  }
282  ksort($suitableRequestHandlers);
283  return array_pop($suitableRequestHandlers);
284  }
285 
295  public function handleRequest($request)
296  {
297 
298  // Resolve request handler that were registered based on the Application
299  $requestHandler = $this->resolveRequestHandler($request);
300 
301  // Execute the command which returns a Response object or NULL
302  $this->response = $requestHandler->handleRequest($request);
303  return $this;
304  }
305 
311  protected function sendResponse()
312  {
313  if ($this->response instanceof \Psr\Http\Message\ResponseInterface) {
314  if (!headers_sent()) {
315  foreach ($this->response->getHeaders() as $name => $values) {
316  header($name . ': ' . implode(', ', $values));
317  }
318  // If the response code was not changed by legacy code (still is 200)
319  // then allow the PSR-7 response object to explicitly set it.
320  // Otherwise let legacy code take precedence.
321  // This code path can be deprecated once we expose the response object to third party code
322  if (http_response_code() === 200) {
323  header('HTTP/' . $this->response->getProtocolVersion() . ' ' . $this->response->getStatusCode() . ' ' . $this->response->getReasonPhrase());
324  }
325  }
326  echo $this->response->getBody()->__toString();
327  }
328  return $this;
329  }
330 
341  public function setEarlyInstance($objectName, $instance)
342  {
343  $this->earlyInstances[$objectName] = $instance;
344  }
345 
354  public function getEarlyInstance($objectName)
355  {
356  if (!isset($this->earlyInstances[$objectName])) {
357  throw new \TYPO3\CMS\Core\Exception('Unknown early instance "' . $objectName . '"', 1365167380);
358  }
359  return $this->earlyInstances[$objectName];
360  }
361 
368  public function getEarlyInstances()
369  {
370  return $this->earlyInstances;
371  }
372 
382  public function loadConfigurationAndInitialize($allowCaching = true, $packageManagerClassName = \TYPO3\CMS\Core\Package\PackageManager::class)
383  {
385  ->initializeErrorHandling();
386  if (!$allowCaching) {
387  $this->disableCoreCache();
388  }
390  ->initializePackageManagement($packageManagerClassName)
391  ->initializeRuntimeActivatedPackagesFromConfiguration()
392  ->defineDatabaseConstants()
393  ->defineUserAgentConstant()
394  ->registerExtDirectComponents()
395  ->setCacheHashOptions()
396  ->setDefaultTimezone()
397  ->initializeL10nLocales()
398  ->convertPageNotFoundHandlingToBoolean()
399  ->setMemoryLimit()
400  ->defineTypo3RequestTypes();
401  if ($allowCaching) {
403  }
404  return $this;
405  }
406 
415  public function initializePackageManagement($packageManagerClassName)
416  {
418  $packageManager = new $packageManagerClassName();
419  $this->setEarlyInstance(\TYPO3\CMS\Core\Package\PackageManager::class, $packageManager);
421  $packageManager->injectCoreCache($this->getEarlyInstance(\TYPO3\CMS\Core\Cache\CacheManager::class)->getCache('cache_core'));
422  $dependencyResolver = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Package\DependencyResolver::class);
423  $dependencyResolver->injectDependencyOrderingService(GeneralUtility::makeInstance(\TYPO3\CMS\Core\Service\DependencyOrderingService::class));
424  $packageManager->injectDependencyResolver($dependencyResolver);
425  $packageManager->initialize($this);
426  GeneralUtility::setSingletonInstance(\TYPO3\CMS\Core\Package\PackageManager::class, $packageManager);
427  return $this;
428  }
429 
437  {
438  if (!self::$usesComposerClassLoading && !ClassLoadingInformation::isClassLoadingInformationAvailable()) {
439  ClassLoadingInformation::dumpClassLoadingInformation();
441  }
442  return $this;
443  }
444 
451  protected function initializeRuntimeActivatedPackagesFromConfiguration()
452  {
453  if (!empty($GLOBALS['TYPO3_CONF_VARS']['EXT']['runtimeActivatedPackages']) && is_array($GLOBALS['TYPO3_CONF_VARS']['EXT']['runtimeActivatedPackages'])) {
455  $packageManager = $this->getEarlyInstance(\TYPO3\CMS\Core\Package\PackageManager::class);
456  foreach ($GLOBALS['TYPO3_CONF_VARS']['EXT']['runtimeActivatedPackages'] as $runtimeAddedPackageKey) {
457  $packageManager->activatePackageDuringRuntime($runtimeAddedPackageKey);
458  }
459  }
460  return $this;
461  }
462 
470  public function loadTypo3LoadedExtAndExtLocalconf($allowCaching = true)
471  {
472  ExtensionManagementUtility::loadExtLocalconf($allowCaching);
473  return $this;
474  }
475 
483  public function populateLocalConfiguration()
484  {
485  try {
486  $configurationManager = $this->getEarlyInstance(\TYPO3\CMS\Core\Configuration\ConfigurationManager::class);
487  } catch (\TYPO3\CMS\Core\Exception $exception) {
488  $configurationManager = new \TYPO3\CMS\Core\Configuration\ConfigurationManager();
489  $this->setEarlyInstance(\TYPO3\CMS\Core\Configuration\ConfigurationManager::class, $configurationManager);
490  }
491  $configurationManager->exportConfiguration();
492  return $this;
493  }
494 
501  public function disableCoreCache()
502  {
503  $GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['cache_core']['backend']
504  = \TYPO3\CMS\Core\Cache\Backend\NullBackend::class;
505  unset($GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['cache_core']['options']);
506  return $this;
507  }
508 
514  protected function defineDatabaseConstants()
515  {
516  define('TYPO3_db', $GLOBALS['TYPO3_CONF_VARS']['DB']['database']);
517  define('TYPO3_db_username', $GLOBALS['TYPO3_CONF_VARS']['DB']['username']);
518  define('TYPO3_db_password', $GLOBALS['TYPO3_CONF_VARS']['DB']['password']);
519  define('TYPO3_db_host', $GLOBALS['TYPO3_CONF_VARS']['DB']['host']);
520  // Constant TYPO3_extTableDef_script is deprecated since TYPO3 CMS 7 and will be dropped with TYPO3 CMS 8
521  define('TYPO3_extTableDef_script',
522  isset($GLOBALS['TYPO3_CONF_VARS']['DB']['extTablesDefinitionScript'])
523  ? $GLOBALS['TYPO3_CONF_VARS']['DB']['extTablesDefinitionScript']
524  : 'extTables.php');
525  return $this;
526  }
527 
533  protected function defineUserAgentConstant()
534  {
535  define('TYPO3_user_agent', 'User-Agent: ' . $GLOBALS['TYPO3_CONF_VARS']['HTTP']['userAgent']);
536  return $this;
537  }
538 
544  protected function registerExtDirectComponents()
545  {
546  if (TYPO3_MODE === 'BE') {
548  'TYPO3.Components.PageTree.DataProvider',
549  \TYPO3\CMS\Backend\Tree\Pagetree\ExtdirectTreeDataProvider::class
550  );
552  'TYPO3.Components.PageTree.Commands',
553  \TYPO3\CMS\Backend\Tree\Pagetree\ExtdirectTreeCommands::class
554  );
556  'TYPO3.Components.PageTree.ContextMenuDataProvider',
557  \TYPO3\CMS\Backend\ContextMenu\Pagetree\Extdirect\ContextMenuConfiguration::class
558  );
560  'TYPO3.ExtDirectStateProvider.ExtDirect',
561  \TYPO3\CMS\Backend\InterfaceState\ExtDirect\DataProvider::class
562  );
564  'TYPO3.Components.DragAndDrop.CommandController',
565  ExtensionManagementUtility::extPath('backend') . 'Classes/View/PageLayout/Extdirect/ExtdirectPageCommands.php:' . \TYPO3\CMS\Backend\View\PageLayout\ExtDirect\ExtdirectPageCommands::class
566  );
567  }
568  return $this;
569  }
570 
578  public function initializeCachingFramework()
579  {
580  $cacheManager = new \TYPO3\CMS\Core\Cache\CacheManager();
581  $cacheManager->setCacheConfigurations($GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']);
582  GeneralUtility::setSingletonInstance(\TYPO3\CMS\Core\Cache\CacheManager::class, $cacheManager);
583 
584  $cacheFactory = new \TYPO3\CMS\Core\Cache\CacheFactory('production', $cacheManager);
585  GeneralUtility::setSingletonInstance(\TYPO3\CMS\Core\Cache\CacheFactory::class, $cacheFactory);
586 
587  $this->setEarlyInstance(\TYPO3\CMS\Core\Cache\CacheManager::class, $cacheManager);
588  return $this;
589  }
590 
596  protected function setCacheHashOptions()
597  {
598  $GLOBALS['TYPO3_CONF_VARS']['FE']['cacheHash'] = array(
599  'cachedParametersWhiteList' => GeneralUtility::trimExplode(',', $GLOBALS['TYPO3_CONF_VARS']['FE']['cHashOnlyForParameters'], true),
600  'excludedParameters' => GeneralUtility::trimExplode(',', $GLOBALS['TYPO3_CONF_VARS']['FE']['cHashExcludedParameters'], true),
601  'requireCacheHashPresenceParameters' => GeneralUtility::trimExplode(',', $GLOBALS['TYPO3_CONF_VARS']['FE']['cHashRequiredParameters'], true)
602  );
603  if (trim($GLOBALS['TYPO3_CONF_VARS']['FE']['cHashExcludedParametersIfEmpty']) === '*') {
604  $GLOBALS['TYPO3_CONF_VARS']['FE']['cacheHash']['excludeAllEmptyParameters'] = true;
605  } else {
606  $GLOBALS['TYPO3_CONF_VARS']['FE']['cacheHash']['excludedParametersIfEmpty'] = GeneralUtility::trimExplode(',', $GLOBALS['TYPO3_CONF_VARS']['FE']['cHashExcludedParametersIfEmpty'], true);
607  }
608  return $this;
609  }
610 
616  protected function setDefaultTimezone()
617  {
618  $timeZone = $GLOBALS['TYPO3_CONF_VARS']['SYS']['phpTimeZone'];
619  if (empty($timeZone)) {
620  // Time zone from the server environment (TZ env or OS query)
621  $defaultTimeZone = @date_default_timezone_get();
622  if ($defaultTimeZone !== '') {
623  $timeZone = $defaultTimeZone;
624  } else {
625  $timeZone = 'UTC';
626  }
627  }
628  // Set default to avoid E_WARNINGs with PHP > 5.3
629  date_default_timezone_set($timeZone);
630  return $this;
631  }
632 
638  protected function initializeL10nLocales()
639  {
640  \TYPO3\CMS\Core\Localization\Locales::initialize();
641  return $this;
642  }
643 
652  {
653  if (!strcasecmp($GLOBALS['TYPO3_CONF_VARS']['FE']['pageNotFound_handling'], 'TRUE')) {
654  $GLOBALS['TYPO3_CONF_VARS']['FE']['pageNotFound_handling'] = true;
655  }
656  return $this;
657  }
658 
665  protected function initializeErrorHandling()
666  {
667  $productionExceptionHandlerClassName = $GLOBALS['TYPO3_CONF_VARS']['SYS']['productionExceptionHandler'];
668  $debugExceptionHandlerClassName = $GLOBALS['TYPO3_CONF_VARS']['SYS']['debugExceptionHandler'];
669 
670  $errorHandlerClassName = $GLOBALS['TYPO3_CONF_VARS']['SYS']['errorHandler'];
671  $errorHandlerErrors = $GLOBALS['TYPO3_CONF_VARS']['SYS']['errorHandlerErrors'];
672  $exceptionalErrors = $GLOBALS['TYPO3_CONF_VARS']['SYS']['exceptionalErrors'];
673 
674  $displayErrorsSetting = (int)$GLOBALS['TYPO3_CONF_VARS']['SYS']['displayErrors'];
675  switch ($displayErrorsSetting) {
676  case 2:
677  GeneralUtility::deprecationLog('The option "$TYPO3_CONF_VARS[SYS][displayErrors]" is set to "2" which is deprecated as of TYPO3 CMS 7, and will be removed with TYPO3 CMS 8. Please change the value to "-1"');
678  // intentionally fall through
679  case -1:
680  $ipMatchesDevelopmentSystem = GeneralUtility::cmpIP(GeneralUtility::getIndpEnv('REMOTE_ADDR'), $GLOBALS['TYPO3_CONF_VARS']['SYS']['devIPmask']);
681  $exceptionHandlerClassName = $ipMatchesDevelopmentSystem ? $debugExceptionHandlerClassName : $productionExceptionHandlerClassName;
682  $displayErrors = $ipMatchesDevelopmentSystem ? 1 : 0;
683  $exceptionalErrors = $ipMatchesDevelopmentSystem ? $exceptionalErrors : 0;
684  break;
685  case 0:
686  $exceptionHandlerClassName = $productionExceptionHandlerClassName;
687  $displayErrors = 0;
688  break;
689  case 1:
690  $exceptionHandlerClassName = $debugExceptionHandlerClassName;
691  $displayErrors = 1;
692  break;
693  default:
694  // Throw exception if an invalid option is set.
695  throw new \RuntimeException('The option $TYPO3_CONF_VARS[SYS][displayErrors] is not set to "-1", "0" or "1".');
696  }
697  @ini_set('display_errors', $displayErrors);
698 
699  if (!empty($errorHandlerClassName)) {
700  // Register an error handler for the given errorHandlerError
701  $errorHandler = GeneralUtility::makeInstance($errorHandlerClassName, $errorHandlerErrors);
702  $errorHandler->setExceptionalErrors($exceptionalErrors);
703  if (is_callable(array($errorHandler, 'setDebugMode'))) {
704  $errorHandler->setDebugMode($displayErrors === 1);
705  }
706  }
707  if (!empty($exceptionHandlerClassName)) {
708  // Registering the exception handler is done in the constructor
709  GeneralUtility::makeInstance($exceptionHandlerClassName);
710  }
711  return $this;
712  }
713 
720  protected function setMemoryLimit()
721  {
722  if ((int)$GLOBALS['TYPO3_CONF_VARS']['SYS']['setMemoryLimit'] > 16) {
723  @ini_set('memory_limit', ((int)$GLOBALS['TYPO3_CONF_VARS']['SYS']['setMemoryLimit'] . 'm'));
724  }
725  return $this;
726  }
727 
734  protected function defineTypo3RequestTypes()
735  {
736  define('TYPO3_REQUESTTYPE_FE', 1);
737  define('TYPO3_REQUESTTYPE_BE', 2);
738  define('TYPO3_REQUESTTYPE_CLI', 4);
739  define('TYPO3_REQUESTTYPE_AJAX', 8);
740  define('TYPO3_REQUESTTYPE_INSTALL', 16);
741  define('TYPO3_REQUESTTYPE', (TYPO3_MODE == 'FE' ? TYPO3_REQUESTTYPE_FE : 0) | (TYPO3_MODE == 'BE' ? TYPO3_REQUESTTYPE_BE : 0) | (defined('TYPO3_cliMode') && TYPO3_cliMode ? TYPO3_REQUESTTYPE_CLI : 0) | (defined('TYPO3_enterInstallScript') && TYPO3_enterInstallScript ? TYPO3_REQUESTTYPE_INSTALL : 0) | ($GLOBALS['TYPO3_AJAX'] ? TYPO3_REQUESTTYPE_AJAX : 0));
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  unset($GLOBALS['TYPO3_AJAX']);
791  return $this;
792  }
793 
800  public function initializeTypo3DbGlobal()
801  {
803  $databaseConnection = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Database\DatabaseConnection::class);
804  $databaseConnection->setDatabaseName(TYPO3_db);
805  $databaseConnection->setDatabaseUsername(TYPO3_db_username);
806  $databaseConnection->setDatabasePassword(TYPO3_db_password);
807 
808  $databaseHost = TYPO3_db_host;
809  if (isset($GLOBALS['TYPO3_CONF_VARS']['DB']['port'])) {
810  $databaseConnection->setDatabasePort($GLOBALS['TYPO3_CONF_VARS']['DB']['port']);
811  } elseif (strpos($databaseHost, ':') > 0) {
812  // @TODO: Find a way to handle this case in the install tool and drop this
813  list($databaseHost, $databasePort) = explode(':', $databaseHost);
814  $databaseConnection->setDatabasePort($databasePort);
815  }
816  if (isset($GLOBALS['TYPO3_CONF_VARS']['DB']['socket'])) {
817  $databaseConnection->setDatabaseSocket($GLOBALS['TYPO3_CONF_VARS']['DB']['socket']);
818  }
819  $databaseConnection->setDatabaseHost($databaseHost);
820 
821  $databaseConnection->debugOutput = $GLOBALS['TYPO3_CONF_VARS']['SYS']['sqlDebug'];
822 
823  if (
824  isset($GLOBALS['TYPO3_CONF_VARS']['SYS']['no_pconnect'])
825  && !$GLOBALS['TYPO3_CONF_VARS']['SYS']['no_pconnect']
826  ) {
827  $databaseConnection->setPersistentDatabaseConnection(true);
828  }
829 
830  $isDatabaseHostLocalHost = $databaseHost === 'localhost' || $databaseHost === '127.0.0.1' || $databaseHost === '::1';
831  if (
832  isset($GLOBALS['TYPO3_CONF_VARS']['SYS']['dbClientCompress'])
833  && $GLOBALS['TYPO3_CONF_VARS']['SYS']['dbClientCompress']
834  && !$isDatabaseHostLocalHost
835  ) {
836  $databaseConnection->setConnectionCompression(true);
837  }
838 
839  if (!empty($GLOBALS['TYPO3_CONF_VARS']['SYS']['setDBinit'])) {
840  $commandsAfterConnect = GeneralUtility::trimExplode(
841  LF,
842  str_replace('\' . LF . \'', LF, $GLOBALS['TYPO3_CONF_VARS']['SYS']['setDBinit']),
843  true
844  );
845  $databaseConnection->setInitializeCommandsAfterConnect($commandsAfterConnect);
846  }
847 
848  $GLOBALS['TYPO3_DB'] = $databaseConnection;
849  // $GLOBALS['TYPO3_DB'] needs to be defined first in order to work for DBAL
850  $GLOBALS['TYPO3_DB']->initialize();
851 
852  return $this;
853  }
854 
864  public function checkLockedBackendAndRedirectOrDie($forceProceeding = false)
865  {
866  if ($GLOBALS['TYPO3_CONF_VARS']['BE']['adminOnly'] < 0) {
867  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);
868  }
869  if (@is_file(PATH_typo3conf . 'LOCK_BACKEND') && $forceProceeding === false) {
870  $fileContent = GeneralUtility::getUrl(PATH_typo3conf . 'LOCK_BACKEND');
871  if ($fileContent) {
872  header('Location: ' . $fileContent);
873  } else {
874  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);
875  }
876  die;
877  }
878  return $this;
879  }
880 
889  public function checkBackendIpOrDie()
890  {
891  if (trim($GLOBALS['TYPO3_CONF_VARS']['BE']['IPmaskList'])) {
892  if (!GeneralUtility::cmpIP(GeneralUtility::getIndpEnv('REMOTE_ADDR'), $GLOBALS['TYPO3_CONF_VARS']['BE']['IPmaskList'])) {
893  throw new \RuntimeException('TYPO3 Backend access denied: The IP address of your client does not match the list of allowed IP addresses.', 1389265900);
894  }
895  }
896  return $this;
897  }
898 
908  {
909  if ((int)$GLOBALS['TYPO3_CONF_VARS']['BE']['lockSSL']) {
910  if (!GeneralUtility::getIndpEnv('TYPO3_SSL')) {
911  if ((int)$GLOBALS['TYPO3_CONF_VARS']['BE']['lockSSL'] === 2) {
912  if ((int)$GLOBALS['TYPO3_CONF_VARS']['BE']['lockSSLPort']) {
913  $sslPortSuffix = ':' . (int)$GLOBALS['TYPO3_CONF_VARS']['BE']['lockSSLPort'];
914  } else {
915  $sslPortSuffix = '';
916  }
917  list(, $url) = explode('://', GeneralUtility::getIndpEnv('TYPO3_SITE_URL') . TYPO3_mainDir, 2);
918  list($server, $address) = explode('/', $url, 2);
919  header('Location: https://' . $server . $sslPortSuffix . '/' . $address);
920  die;
921  } else {
922  throw new \RuntimeException('TYPO3 Backend not accessed via SSL: TYPO3 Backend is configured to only be accessible through SSL. Change the URL in your browser and try again.', 1389265726);
923  }
924  }
925  }
926  return $this;
927  }
928 
942  public function loadCachedTca()
943  {
944  $cacheIdentifier = 'tca_fe_' . sha1((TYPO3_version . PATH_site . 'tca_fe'));
946  $codeCache = $this->getEarlyInstance(\TYPO3\CMS\Core\Cache\CacheManager::class)->getCache('cache_core');
947  if ($codeCache->has($cacheIdentifier)) {
948  // substr is necessary, because the php frontend wraps php code around the cache value
949  $GLOBALS['TCA'] = unserialize(substr($codeCache->get($cacheIdentifier), 6, -2));
950  } else {
951  $this->loadExtensionTables(true);
952  $codeCache->set($cacheIdentifier, serialize($GLOBALS['TCA']));
953  }
954  return $this;
955  }
956 
969  public function loadExtensionTables($allowCaching = true)
970  {
971  ExtensionManagementUtility::loadBaseTca($allowCaching);
972  ExtensionManagementUtility::loadExtTables($allowCaching);
974  $this->runExtTablesPostProcessingHooks();
975  return $this;
976  }
977 
990  protected function executeExtTablesAdditionalFile()
991  {
992  // It is discouraged to use those global variables directly, but we
993  // can not prohibit this without breaking backwards compatibility
994  global $T3_SERVICES, $T3_VAR, $TYPO3_CONF_VARS;
995  global $TBE_MODULES, $TBE_MODULES_EXT, $TCA;
996  global $PAGES_TYPES, $TBE_STYLES;
997  global $_EXTKEY;
998  // Load additional ext tables script if the file exists
999  $extTablesFile = PATH_typo3conf . TYPO3_extTableDef_script;
1000  if (file_exists($extTablesFile) && is_file($extTablesFile)) {
1002  'Using typo3conf/' . TYPO3_extTableDef_script . ' is deprecated and will be removed with TYPO3 CMS 8. Please move your TCA overrides'
1003  . ' to Configuration/TCA/Overrides of your project specific extension, or slot the signal "tcaIsBeingBuilt" for further processing.'
1004  );
1005  include $extTablesFile;
1006  }
1007  }
1008 
1015  protected function runExtTablesPostProcessingHooks()
1016  {
1017  if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['GLOBAL']['extTablesInclusion-PostProcessing'])) {
1018  foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['GLOBAL']['extTablesInclusion-PostProcessing'] as $classReference) {
1020  $hookObject = GeneralUtility::getUserObj($classReference);
1021  if (!$hookObject instanceof \TYPO3\CMS\Core\Database\TableConfigurationPostProcessingHookInterface) {
1022  throw new \UnexpectedValueException(
1023  '$hookObject "' . $classReference . '" must implement interface TYPO3\\CMS\\Core\\Database\\TableConfigurationPostProcessingHookInterface',
1024  1320585902
1025  );
1026  }
1027  $hookObject->processData();
1028  }
1029  }
1030  }
1031 
1039  public function initializeSpriteManager()
1040  {
1041  // This method is deprecated since TYPO3 CMS 7, will be removed with TYPO3 CMS 8
1042  // This method does not log a deprecation message, because it is used only in the request handlers
1043  // and would break icons from IconUtility::getSpriteIcon() if we remove it yet.
1044  \TYPO3\CMS\Backend\Sprite\SpriteManager::initialize();
1045  return $this;
1046  }
1047 
1055  public function initializeBackendRouter()
1056  {
1057  $packageManager = $this->getEarlyInstance(\TYPO3\CMS\Core\Package\PackageManager::class);
1058 
1059  // See if the Routes.php from all active packages have been built together already
1060  $cacheIdentifier = 'BackendRoutesFromPackages_' . sha1((TYPO3_version . PATH_site . 'BackendRoutesFromPackages'));
1061 
1063  $codeCache = $this->getEarlyInstance(\TYPO3\CMS\Core\Cache\CacheManager::class)->getCache('cache_core');
1064  $routesFromPackages = array();
1065  if ($codeCache->has($cacheIdentifier)) {
1066  // substr is necessary, because the php frontend wraps php code around the cache value
1067  $routesFromPackages = unserialize(substr($codeCache->get($cacheIdentifier), 6, -2));
1068  } else {
1069  // Loop over all packages and check for a Configuration/Backend/Routes.php file
1070  $packages = $packageManager->getActivePackages();
1071  foreach ($packages as $package) {
1072  $routesFileNameForPackage = $package->getPackagePath() . 'Configuration/Backend/Routes.php';
1073  if (file_exists($routesFileNameForPackage)) {
1074  $definedRoutesInPackage = require $routesFileNameForPackage;
1075  if (is_array($definedRoutesInPackage)) {
1076  $routesFromPackages += $definedRoutesInPackage;
1077  }
1078  }
1079  $routesFileNameForPackage = $package->getPackagePath() . 'Configuration/Backend/AjaxRoutes.php';
1080  if (file_exists($routesFileNameForPackage)) {
1081  $definedRoutesInPackage = require $routesFileNameForPackage;
1082  if (is_array($definedRoutesInPackage)) {
1083  foreach ($definedRoutesInPackage as $routeIdentifier => $routeOptions) {
1084  // prefix the route with "ajax_" as "namespace"
1085  $routeOptions['path'] = '/ajax' . $routeOptions['path'];
1086  $routesFromPackages['ajax_' . $routeIdentifier] = $routeOptions;
1087  $routesFromPackages['ajax_' . $routeIdentifier]['ajax'] = true;
1088  }
1089  }
1090  }
1091  }
1092  // Store the data from all packages in the cache
1093  $codeCache->set($cacheIdentifier, serialize($routesFromPackages));
1094  }
1095 
1096  // Build Route objects from the data
1097  $router = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Routing\Router::class);
1098  foreach ($routesFromPackages as $name => $options) {
1099  $path = $options['path'];
1100  unset($options['path']);
1101  $route = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Routing\Route::class, $path, $options);
1102  $router->addRoute($name, $route);
1103  }
1104  return $this;
1105  }
1106 
1113  public function initializeBackendUser()
1114  {
1116  $backendUser = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Authentication\BackendUserAuthentication::class);
1117  $backendUser->warningEmail = $GLOBALS['TYPO3_CONF_VARS']['BE']['warning_email_addr'];
1118  $backendUser->lockIP = $GLOBALS['TYPO3_CONF_VARS']['BE']['lockIP'];
1119  $backendUser->auth_timeout_field = (int)$GLOBALS['TYPO3_CONF_VARS']['BE']['sessionTimeout'];
1120  if (TYPO3_REQUESTTYPE & TYPO3_REQUESTTYPE_CLI) {
1121  $backendUser->dontSetCookie = true;
1122  }
1123  // The global must be available very early, because methods below
1124  // might trigger code which relies on it. See: #45625
1125  $GLOBALS['BE_USER'] = $backendUser;
1126  $backendUser->start();
1127  return $this;
1128  }
1129 
1137  public function initializeBackendAuthentication($proceedIfNoUserIsLoggedIn = false)
1138  {
1139  $GLOBALS['BE_USER']->backendCheckLogin($proceedIfNoUserIsLoggedIn);
1140  return $this;
1141  }
1142 
1149  public function initializeLanguageObject()
1150  {
1152  $GLOBALS['LANG'] = GeneralUtility::makeInstance(\TYPO3\CMS\Lang\LanguageService::class);
1153  $GLOBALS['LANG']->init($GLOBALS['BE_USER']->uc['lang']);
1154  return $this;
1155  }
1156 
1164  {
1165  ob_clean();
1166  return $this;
1167  }
1168 
1176  {
1177  if (extension_loaded('zlib') && $GLOBALS['TYPO3_CONF_VARS']['BE']['compressionLevel']) {
1178  if (MathUtility::canBeInterpretedAsInteger($GLOBALS['TYPO3_CONF_VARS']['BE']['compressionLevel'])) {
1179  @ini_set('zlib.output_compression_level', $GLOBALS['TYPO3_CONF_VARS']['BE']['compressionLevel']);
1180  }
1181  ob_start('ob_gzhandler');
1182  }
1183  return $this;
1184  }
1185 
1192  public function sendHttpHeaders()
1193  {
1194  if (!empty($GLOBALS['TYPO3_CONF_VARS']['BE']['HTTP']['Response']['Headers']) && is_array($GLOBALS['TYPO3_CONF_VARS']['BE']['HTTP']['Response']['Headers'])) {
1195  foreach ($GLOBALS['TYPO3_CONF_VARS']['BE']['HTTP']['Response']['Headers'] as $header) {
1196  header($header);
1197  }
1198  }
1199  return $this;
1200  }
1201 
1210  public function shutdown()
1211  {
1212  $this->sendResponse();
1213  return $this;
1214  }
1215 
1223  public function initializeBackendTemplate()
1224  {
1225  $GLOBALS['TBE_TEMPLATE'] = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Template\DocumentTemplate::class);
1226  return $this;
1227  }
1228 }