c2829cbd295b871435dbf16f6495719c98e6a85c
[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 TYPO3\CMS\Core\Utility;
18
19 /**
20 * This class encapsulates bootstrap related methods.
21 * It is required directly as the very first thing in entry scripts and
22 * used to define all base things like constants and pathes and so on.
23 *
24 * Most methods in this class have dependencies to each other. They can
25 * not be called in arbitrary order. The methods are ordered top down, so
26 * a method at the beginning has lower dependencies than a method further
27 * down. Do not fiddle with the load order in own scripts except you know
28 * exactly what you are doing!
29 *
30 * @author Christian Kuhn <lolli@schwarzbu.ch>
31 */
32 class Bootstrap {
33
34 /**
35 * @var \TYPO3\CMS\Core\Core\Bootstrap
36 */
37 static protected $instance = NULL;
38
39 /**
40 * Unique Request ID
41 *
42 * @var string
43 */
44 protected $requestId;
45
46 /**
47 * The application context
48 *
49 * @var \TYPO3\CMS\Core\Core\ApplicationContext
50 */
51 protected $applicationContext;
52
53 /**
54 * @var array List of early instances
55 */
56 protected $earlyInstances = array();
57
58 /**
59 * @var string Path to install tool
60 */
61 protected $installToolPath;
62
63 /**
64 * @var string The currently active exception handling class. It is set after LocalConfiguration is included and might be changed after ex_localconf.php are loaded.
65 */
66 protected $activeExceptionHandlerClassName;
67
68 /**
69 * @var string The currently active error handling class. It is set after LocalConfiguration is included and might be changed after ex_localconf.php are loaded.
70 */
71 protected $activeErrorHandlerClassName;
72
73 /**
74 * registered request handlers
75 * @var RequestHandlerInterface[]
76 */
77 protected $availableRequestHandlers = array();
78
79 /**
80 * @var bool
81 */
82 static protected $usesComposerClassLoading = FALSE;
83
84 /**
85 * Disable direct creation of this object.
86 * Set unique requestId and the application context
87 *
88 * @var string Application context
89 */
90 protected function __construct($applicationContext) {
91 $this->requestId = substr(md5(uniqid('', TRUE)), 0, 13);
92 $this->applicationContext = new ApplicationContext($applicationContext);
93 }
94
95 /**
96 * @return bool
97 */
98 static public function usesComposerClassLoading() {
99 return self::$usesComposerClassLoading;
100 }
101
102 /**
103 * Disable direct cloning of this object.
104 */
105 protected function __clone() {
106
107 }
108
109 /**
110 * Return 'this' as singleton
111 *
112 * @return Bootstrap
113 * @internal This is not a public API method, do not use in own extensions
114 */
115 static public function getInstance() {
116 if (is_null(static::$instance)) {
117 $composerClassLoader = self::initializeComposerClassLoader();
118 $applicationContext = getenv('TYPO3_CONTEXT') ?: (getenv('REDIRECT_TYPO3_CONTEXT') ?: 'Production');
119 self::$instance = new static($applicationContext);
120 self::$instance->setEarlyInstance(\Composer\Autoload\ClassLoader::class, $composerClassLoader);
121 }
122 return static::$instance;
123 }
124
125 /**
126 * Gets the request's unique ID
127 *
128 * @return string Unique request ID
129 * @internal This is not a public API method, do not use in own extensions
130 */
131 public function getRequestId() {
132 return $this->requestId;
133 }
134
135 /**
136 * Returns the application context this bootstrap was started in.
137 *
138 * @return \TYPO3\CMS\Core\Core\ApplicationContext The application context encapsulated in an object
139 * @internal This is not a public API method, do not use in own extensions.
140 * Use \TYPO3\CMS\Core\Utility\GeneralUtility::getApplicationContext() instead
141 */
142 public function getApplicationContext() {
143 return $this->applicationContext;
144 }
145
146 /**
147 * Prevent any unwanted output that may corrupt AJAX/compression.
148 * This does not interfere with "die()" or "echo"+"exit()" messages!
149 *
150 * @return Bootstrap
151 * @internal This is not a public API method, do not use in own extensions
152 */
153 public function startOutputBuffering() {
154 ob_start();
155 return $this;
156 }
157
158 /**
159 * Main entry point called at every request usually from Global scope. Checks if everthing is correct,
160 * and sets up the base request information for a regular request, then
161 * resolves the RequestHandler which handles the request.
162 *
163 * @param string $relativePathPart Relative path of entry script back to document root
164 * @return Bootstrap
165 */
166 public function run($relativePathPart = '') {
167 $this->baseSetup($relativePathPart);
168
169 // Failsafe minimal setup mode for the install tool
170 if (defined('TYPO3_enterInstallScript')) {
171 $this->startOutputBuffering()
172 ->loadConfigurationAndInitialize(FALSE, \TYPO3\CMS\Core\Package\FailsafePackageManager::class);
173 } elseif (!$this->checkIfEssentialConfigurationExists() && !defined('TYPO3_cliMode')) {
174 // Redirect to install tool if base configuration is not found
175 $backPathToSiteRoot = str_repeat('../', count(explode('/', $relativePathPart)) - 1);
176 $this->redirectToInstallTool($backPathToSiteRoot);
177 } else {
178 // Regular request (Frontend, AJAX, Backend, CLI)
179 $this->startOutputBuffering()
180 ->loadConfigurationAndInitialize()
181 ->loadTypo3LoadedExtAndExtLocalconf(TRUE)
182 ->initializeExceptionHandling()
183 ->setFinalCachingFrameworkCacheConfiguration()
184 ->defineLoggingAndExceptionConstants()
185 ->unsetReservedGlobalVariables()
186 ->initializeTypo3DbGlobal();
187 }
188
189 // Resolve request handler that were registered based on TYPO3_MODE
190 $this->registerRequestHandlers();
191 $requestHandler = $this->resolveRequestHandler();
192 $requestHandler->handleRequest();
193 return $this;
194 }
195
196 /**
197 * Run the base setup that checks server environment, determines pathes,
198 * populates base files and sets common configuration.
199 *
200 * Script execution will be aborted if something fails here.
201 *
202 * @param string $relativePathPart Relative path of entry script back to document root
203 * @return Bootstrap
204 * @internal This is not a public API method, do not use in own extensions
205 */
206 public function baseSetup($relativePathPart = '') {
207 SystemEnvironmentBuilder::run($relativePathPart);
208 $this->addDynamicClassAliasMapsToComposerClassLoader();
209 Utility\GeneralUtility::presetApplicationContext($this->applicationContext);
210 return $this;
211 }
212
213 /**
214 * @return \Composer\Autoload\ClassLoader|\Helhum\ClassAliasLoader\Composer\ClassAliasLoader
215 */
216 static protected function initializeComposerClassLoader() {
217 $possiblePaths = array(
218 'distribution' => __DIR__ . '/../../../../../../Packages/Libraries/autoload.php',
219 'fallback' => __DIR__ . '/../../../../contrib/vendor/autoload.php',
220 );
221 foreach ($possiblePaths as $autoLoadType => $possiblePath) {
222 if (file_exists($possiblePath)) {
223 if ($autoLoadType === 'distribution') {
224 self::$usesComposerClassLoading = TRUE;
225 }
226 return include $possiblePath;
227 }
228 }
229
230 throw new \LogicException('No class loading information found for TYPO3 CMS. Please make sure you installed TYPO3 with composer or the typo3/contrib/vendor folder is present.', 1425153762);
231 }
232
233 /**
234 * Includes an alias mapping file if present.
235 * The file is generated during extension install.
236 *
237 * @throws \TYPO3\CMS\Core\Exception
238 */
239 protected function addDynamicClassAliasMapsToComposerClassLoader() {
240 if (self::$usesComposerClassLoading) {
241 return;
242 }
243 $dynamicClassAliasMapFile = PATH_site . 'typo3conf/autoload_classaliasmap.php';
244 if (file_exists($dynamicClassAliasMapFile)) {
245 $composerClassLoader = $this->getEarlyInstance(\Composer\Autoload\ClassLoader::class);
246 $classAliasMap = require $dynamicClassAliasMapFile;
247 if (is_array($classAliasMap) && !empty($classAliasMap['aliasToClassNameMapping']) && !empty($classAliasMap['classNameToAliasMapping'])) {
248 $composerClassLoader->addAliasMap($classAliasMap);
249 }
250 }
251 }
252
253 /**
254 * checks if LocalConfiguration.php or PackageStates.php is missing,
255 * used to see if a redirect to the install tool is needed
256 *
257 * @return bool TRUE when the essential configuration is available, otherwise FALSE
258 */
259 protected function checkIfEssentialConfigurationExists() {
260 $configurationManager = new \TYPO3\CMS\Core\Configuration\ConfigurationManager;
261 $this->setEarlyInstance(\TYPO3\CMS\Core\Configuration\ConfigurationManager::class, $configurationManager);
262 return (!file_exists($configurationManager->getLocalConfigurationFileLocation()) || !file_exists(PATH_typo3conf . 'PackageStates.php')) ? FALSE : TRUE;
263 }
264
265 /**
266 * Redirect to install tool if LocalConfiguration.php is missing.
267 *
268 * @param string $pathUpToDocumentRoot Can contain '../' if called from a sub directory
269 * @internal This is not a public API method, do not use in own extensions
270 */
271 public function redirectToInstallTool($pathUpToDocumentRoot = '') {
272 define('TYPO3_enterInstallScript', '1');
273 $this->defineTypo3RequestTypes();
274 Utility\HttpUtility::redirect($pathUpToDocumentRoot . 'typo3/sysext/install/Start/Install.php');
275 }
276
277 /**
278 * Adds available request handlers, which currently hard-coded here based on the TYPO3_MODE. The extensability
279 * of adding own request handlers would be too complex for now, but can be added later.
280 *
281 * @return Bootstrap
282 * @internal This is not a public API method, do not use in own extensions
283 */
284 protected function registerRequestHandlers() {
285 // Use the install tool handler if in install tool mode
286 if (!$this->checkIfEssentialConfigurationExists() || (TYPO3_REQUESTTYPE & TYPO3_REQUESTTYPE_INSTALL)) {
287 $this->availableRequestHandlers = array(
288 \TYPO3\CMS\Install\RequestHandler::class
289 );
290 } elseif (TYPO3_MODE == 'BE') {
291 $this->availableRequestHandlers = array(
292 \TYPO3\CMS\Backend\RequestHandler::class,
293 \TYPO3\CMS\Backend\BackendModuleRequestHandler::class,
294 \TYPO3\CMS\Backend\AjaxRequestHandler::class,
295 \TYPO3\CMS\Backend\CliRequestHandler::class
296 );
297 } elseif (TYPO3_MODE == 'FE') {
298 $this->availableRequestHandlers = array(
299 \TYPO3\CMS\Frontend\RequestHandler::class,
300 \TYPO3\CMS\Frontend\EidRequestHandler::class
301 );
302 }
303 return $this;
304 }
305
306 /**
307 * Fetches the request handler that suits the best based on the priority and the interface
308 * Be sure to always have the constants that are defined in $this->defineTypo3RequestTypes() are set,
309 * so most RequestHandlers can check if they can handle the request.
310 *
311 * @return RequestHandlerInterface
312 * @throws \TYPO3\CMS\Core\Exception
313 * @internal This is not a public API method, do not use in own extensions
314 */
315 public function resolveRequestHandler() {
316 $suitableRequestHandlers = array();
317 foreach ($this->availableRequestHandlers as $requestHandlerClassName) {
318 $requestHandler = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance($requestHandlerClassName, $this);
319 if ($requestHandler->canHandleRequest()) {
320 $priority = $requestHandler->getPriority();
321 if (isset($suitableRequestHandlers[$priority])) {
322 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);
323 }
324 $suitableRequestHandlers[$priority] = $requestHandler;
325 }
326 }
327 if (count($suitableRequestHandlers) === 0) {
328 throw new \TYPO3\CMS\Core\Exception('No suitable request handler found.', 1225418233);
329 }
330 ksort($suitableRequestHandlers);
331 return array_pop($suitableRequestHandlers);
332 }
333
334 /**
335 * Registers the instance of the specified object for an early boot stage.
336 * On finalizing the Object Manager initialization, all those instances will
337 * be transferred to the Object Manager's registry.
338 *
339 * @param string $objectName Object name, as later used by the Object Manager
340 * @param object $instance The instance to register
341 * @return void
342 */
343 public function setEarlyInstance($objectName, $instance) {
344 $this->earlyInstances[$objectName] = $instance;
345 }
346
347 /**
348 * Returns an instance which was registered earlier through setEarlyInstance()
349 *
350 * @param string $objectName Object name of the registered instance
351 * @return object
352 * @throws \TYPO3\CMS\Core\Exception
353 */
354 public function getEarlyInstance($objectName) {
355 if (!isset($this->earlyInstances[$objectName])) {
356 throw new \TYPO3\CMS\Core\Exception('Unknown early instance "' . $objectName . '"', 1365167380);
357 }
358 return $this->earlyInstances[$objectName];
359 }
360
361 /**
362 * Returns all registered early instances indexed by object name
363 *
364 * @return array
365 */
366 public function getEarlyInstances() {
367 return $this->earlyInstances;
368 }
369
370 /**
371 * Includes LocalConfiguration.php and sets several
372 * global settings depending on configuration.
373 *
374 * @param bool $allowCaching Whether to allow caching - affects cache_core (autoloader)
375 * @param string $packageManagerClassName Define an alternative package manager implementation (usually for the installer)
376 * @return Bootstrap
377 * @internal This is not a public API method, do not use in own extensions
378 */
379 public function loadConfigurationAndInitialize($allowCaching = TRUE, $packageManagerClassName = \TYPO3\CMS\Core\Package\PackageManager::class) {
380 $this->initializeClassLoader()
381 ->populateLocalConfiguration();
382 if (!$allowCaching) {
383 $this->disableCoreAndClassesCache();
384 }
385 $this->initializeCachingFramework()
386 ->initializeClassLoaderCaches()
387 ->initializePackageManagement($packageManagerClassName)
388 ->initializeRuntimeActivatedPackagesFromConfiguration();
389
390 $this->defineDatabaseConstants()
391 ->defineUserAgentConstant()
392 ->registerExtDirectComponents()
393 ->transferDeprecatedCurlSettings()
394 ->setCacheHashOptions()
395 ->setDefaultTimezone()
396 ->initializeL10nLocales()
397 ->convertPageNotFoundHandlingToBoolean()
398 ->registerGlobalDebugFunctions()
399 ->configureExceptionHandling()
400 ->initializeExceptionHandling()
401 ->setMemoryLimit()
402 ->defineTypo3RequestTypes();
403 return $this;
404 }
405
406 /**
407 * Initializes the Class Loader
408 *
409 * @return Bootstrap
410 * @internal This is not a public API method, do not use in own extensions
411 */
412 public function initializeClassLoader() {
413 $classLoader = new ClassLoader($this->applicationContext);
414 $this->setEarlyInstance(\TYPO3\CMS\Core\Core\ClassLoader::class, $classLoader);
415 $classAliasMap = new ClassAliasMap();
416 $classAliasMap->injectClassLoader($classLoader);
417 $classAliasMap->injectComposerClassLoader($this->getEarlyInstance(\Composer\Autoload\ClassLoader::class));
418 $this->setEarlyInstance(\TYPO3\CMS\Core\Core\ClassAliasMap::class, $classAliasMap);
419 $classLoader->injectClassAliasMap($classAliasMap);
420 spl_autoload_register(array($classLoader, 'loadClass'), TRUE, FALSE);
421 return $this;
422 }
423
424 /**
425 * Unregister class loader
426 *
427 * @return Bootstrap
428 * @internal This is not a public API method, do not use in own extensions
429 */
430 public function unregisterClassLoader() {
431 $currentClassLoader = $this->getEarlyInstance(\TYPO3\CMS\Core\Core\ClassLoader::class);
432 spl_autoload_unregister(array($currentClassLoader, 'loadClass'));
433 return $this;
434 }
435
436 /**
437 * Initialize class loader cache.
438 *
439 * @return Bootstrap
440 * @internal This is not a public API method, do not use in own extensions
441 */
442 public function initializeClassLoaderCaches() {
443 /** @var $classLoader ClassLoader */
444 $classLoader = $this->getEarlyInstance(\TYPO3\CMS\Core\Core\ClassLoader::class);
445 $classLoader->injectCoreCache($this->getEarlyInstance(\TYPO3\CMS\Core\Cache\CacheManager::class)->getCache('cache_core'));
446 $classLoader->injectClassesCache($this->getEarlyInstance(\TYPO3\CMS\Core\Cache\CacheManager::class)->getCache('cache_classes'));
447 return $this;
448 }
449
450 /**
451 * Initializes the package system and loads the package configuration and settings
452 * provided by the packages.
453 *
454 * @param string $packageManagerClassName Define an alternative package manager implementation (usually for the installer)
455 * @return Bootstrap
456 * @internal This is not a public API method, do not use in own extensions
457 */
458 public function initializePackageManagement($packageManagerClassName) {
459 /** @var \TYPO3\CMS\Core\Package\PackageManager $packageManager */
460 $packageManager = new $packageManagerClassName();
461 $this->setEarlyInstance(\TYPO3\CMS\Core\Package\PackageManager::class, $packageManager);
462 Utility\ExtensionManagementUtility::setPackageManager($packageManager);
463 $packageManager->injectClassLoader($this->getEarlyInstance(\TYPO3\CMS\Core\Core\ClassLoader::class));
464 $packageManager->injectCoreCache($this->getEarlyInstance(\TYPO3\CMS\Core\Cache\CacheManager::class)->getCache('cache_core'));
465 $packageManager->injectDependencyResolver(Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Core\Package\DependencyResolver::class));
466 $packageManager->initialize($this);
467 Utility\GeneralUtility::setSingletonInstance(\TYPO3\CMS\Core\Package\PackageManager::class, $packageManager);
468 return $this;
469 }
470
471 /**
472 * Activates a package during runtime. This is used in AdditionalConfiguration.php
473 * to enable extensions under conditions.
474 *
475 * @return Bootstrap
476 */
477 protected function initializeRuntimeActivatedPackagesFromConfiguration() {
478 if (!empty($GLOBALS['TYPO3_CONF_VARS']['EXT']['runtimeActivatedPackages']) && is_array($GLOBALS['TYPO3_CONF_VARS']['EXT']['runtimeActivatedPackages'])) {
479 /** @var \TYPO3\CMS\Core\Package\PackageManager $packageManager */
480 $packageManager = $this->getEarlyInstance(\TYPO3\CMS\Core\Package\PackageManager::class);
481 foreach ($GLOBALS['TYPO3_CONF_VARS']['EXT']['runtimeActivatedPackages'] as $runtimeAddedPackageKey) {
482 $packageManager->activatePackageDuringRuntime($runtimeAddedPackageKey);
483 }
484 }
485 return $this;
486 }
487
488 /**
489 * Load ext_localconf of extensions
490 *
491 * @param bool $allowCaching
492 * @return Bootstrap
493 * @internal This is not a public API method, do not use in own extensions
494 */
495 public function loadTypo3LoadedExtAndExtLocalconf($allowCaching = TRUE) {
496 Utility\ExtensionManagementUtility::loadExtLocalconf($allowCaching);
497 return $this;
498 }
499
500 /**
501 * Throws an exception if no browser could be identified
502 *
503 * @return Bootstrap
504 * @throws \RuntimeException
505 * @internal This is not a public API method, do not use in own extensions
506 */
507 public function checkValidBrowserOrDie() {
508 // Checks for proper browser
509 if (empty($GLOBALS['CLIENT']['BROWSER'])) {
510 throw new \RuntimeException('Browser Error: Your browser version looks incompatible with this TYPO3 version!', 1294587023);
511 }
512 return $this;
513 }
514
515 /**
516 * We need an early instance of the configuration manager.
517 * Since makeInstance relies on the object configuration, we create it here with new instead.
518 *
519 * @return Bootstrap
520 */
521 public function populateLocalConfiguration() {
522 try {
523 $configurationManager = $this->getEarlyInstance(\TYPO3\CMS\Core\Configuration\ConfigurationManager::class);
524 } catch(\TYPO3\CMS\Core\Exception $exception) {
525 $configurationManager = new \TYPO3\CMS\Core\Configuration\ConfigurationManager();
526 $this->setEarlyInstance(\TYPO3\CMS\Core\Configuration\ConfigurationManager::class, $configurationManager);
527 }
528 $configurationManager->exportConfiguration();
529 return $this;
530 }
531
532 /**
533 * Set cache_core to null backend, effectively disabling eg. the autoloader cache
534 *
535 * @return \TYPO3\CMS\Core\Core\Bootstrap
536 * @internal This is not a public API method, do not use in own extensions
537 */
538 public function disableCoreAndClassesCache() {
539 $GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['cache_core']['backend']
540 = \TYPO3\CMS\Core\Cache\Backend\NullBackend::class;
541 unset($GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['cache_core']['options']);
542 $GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['cache_classes']['backend']
543 = \TYPO3\CMS\Core\Cache\Backend\TransientMemoryBackend::class;
544 unset($GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['cache_classes']['options']);
545 return $this;
546 }
547
548 /**
549 * Define database constants
550 *
551 * @return \TYPO3\CMS\Core\Core\Bootstrap
552 */
553 protected function defineDatabaseConstants() {
554 define('TYPO3_db', $GLOBALS['TYPO3_CONF_VARS']['DB']['database']);
555 define('TYPO3_db_username', $GLOBALS['TYPO3_CONF_VARS']['DB']['username']);
556 define('TYPO3_db_password', $GLOBALS['TYPO3_CONF_VARS']['DB']['password']);
557 define('TYPO3_db_host', $GLOBALS['TYPO3_CONF_VARS']['DB']['host']);
558 // Constant TYPO3_extTableDef_script is deprecated since TYPO3 CMS 7 and will be dropped with TYPO3 CMS 8
559 define('TYPO3_extTableDef_script',
560 isset($GLOBALS['TYPO3_CONF_VARS']['DB']['extTablesDefinitionScript'])
561 ? $GLOBALS['TYPO3_CONF_VARS']['DB']['extTablesDefinitionScript']
562 : 'extTables.php');
563 return $this;
564 }
565
566 /**
567 * Define user agent constant
568 *
569 * @return \TYPO3\CMS\Core\Core\Bootstrap
570 */
571 protected function defineUserAgentConstant() {
572 define('TYPO3_user_agent', 'User-Agent: ' . $GLOBALS['TYPO3_CONF_VARS']['HTTP']['userAgent']);
573 return $this;
574 }
575
576 /**
577 * Register default ExtDirect components
578 *
579 * @return Bootstrap
580 */
581 protected function registerExtDirectComponents() {
582 if (TYPO3_MODE === 'BE') {
583 Utility\ExtensionManagementUtility::registerExtDirectComponent(
584 'TYPO3.Components.PageTree.DataProvider',
585 \TYPO3\CMS\Backend\Tree\Pagetree\ExtdirectTreeDataProvider::class
586 );
587 Utility\ExtensionManagementUtility::registerExtDirectComponent(
588 'TYPO3.Components.PageTree.Commands',
589 \TYPO3\CMS\Backend\Tree\Pagetree\ExtdirectTreeCommands::class
590 );
591 Utility\ExtensionManagementUtility::registerExtDirectComponent(
592 'TYPO3.Components.PageTree.ContextMenuDataProvider',
593 \TYPO3\CMS\Backend\ContextMenu\Pagetree\Extdirect\ContextMenuConfiguration::class
594 );
595 Utility\ExtensionManagementUtility::registerExtDirectComponent(
596 'TYPO3.LiveSearchActions.ExtDirect',
597 \TYPO3\CMS\Backend\Search\LiveSearch\ExtDirect\LiveSearchDataProvider::class,
598 'web_list',
599 'user,group'
600 );
601 Utility\ExtensionManagementUtility::registerExtDirectComponent(
602 'TYPO3.ExtDirectStateProvider.ExtDirect',
603 \TYPO3\CMS\Backend\InterfaceState\ExtDirect\DataProvider::class
604 );
605 Utility\ExtensionManagementUtility::registerExtDirectComponent(
606 'TYPO3.Components.DragAndDrop.CommandController',
607 Utility\ExtensionManagementUtility::extPath('backend') . 'Classes/View/PageLayout/Extdirect/ExtdirectPageCommands.php:' . \TYPO3\CMS\Backend\View\PageLayout\ExtDirect\ExtdirectPageCommands::class
608 );
609 }
610 return $this;
611 }
612
613 /**
614 * Initialize caching framework
615 *
616 * @return Bootstrap
617 * @internal This is not a public API method, do not use in own extensions
618 */
619 public function initializeCachingFramework() {
620 $this->setEarlyInstance(\TYPO3\CMS\Core\Cache\CacheManager::class, \TYPO3\CMS\Core\Cache\Cache::initializeCachingFramework());
621 return $this;
622 }
623
624 /**
625 * Parse old curl options and set new http ones instead
626 *
627 * @TODO: Move this functionality to the silent updater in the Install Tool
628 * @return Bootstrap
629 */
630 protected function transferDeprecatedCurlSettings() {
631 if (!empty($GLOBALS['TYPO3_CONF_VARS']['SYS']['curlProxyServer']) && empty($GLOBALS['TYPO3_CONF_VARS']['HTTP']['proxy_host'])) {
632 $curlProxy = rtrim(preg_replace('#^https?://#', '', $GLOBALS['TYPO3_CONF_VARS']['SYS']['curlProxyServer']), '/');
633 $proxyParts = Utility\GeneralUtility::revExplode(':', $curlProxy, 2);
634 $GLOBALS['TYPO3_CONF_VARS']['HTTP']['proxy_host'] = $proxyParts[0];
635 $GLOBALS['TYPO3_CONF_VARS']['HTTP']['proxy_port'] = $proxyParts[1];
636 }
637 if (!empty($GLOBALS['TYPO3_CONF_VARS']['SYS']['curlProxyUserPass']) && empty($GLOBALS['TYPO3_CONF_VARS']['HTTP']['proxy_user'])) {
638 $userPassParts = explode(':', $GLOBALS['TYPO3_CONF_VARS']['SYS']['curlProxyUserPass'], 2);
639 $GLOBALS['TYPO3_CONF_VARS']['HTTP']['proxy_user'] = $userPassParts[0];
640 $GLOBALS['TYPO3_CONF_VARS']['HTTP']['proxy_password'] = $userPassParts[1];
641 }
642 if ($GLOBALS['TYPO3_CONF_VARS']['SYS']['curlUse']) {
643 $GLOBALS['TYPO3_CONF_VARS']['HTTP']['adapter'] = 'curl';
644 }
645 return $this;
646 }
647
648 /**
649 * Set cacheHash options
650 *
651 * @return Bootstrap
652 */
653 protected function setCacheHashOptions() {
654 $GLOBALS['TYPO3_CONF_VARS']['FE']['cacheHash'] = array(
655 'cachedParametersWhiteList' => Utility\GeneralUtility::trimExplode(',', $GLOBALS['TYPO3_CONF_VARS']['FE']['cHashOnlyForParameters'], TRUE),
656 'excludedParameters' => Utility\GeneralUtility::trimExplode(',', $GLOBALS['TYPO3_CONF_VARS']['FE']['cHashExcludedParameters'], TRUE),
657 'requireCacheHashPresenceParameters' => Utility\GeneralUtility::trimExplode(',', $GLOBALS['TYPO3_CONF_VARS']['FE']['cHashRequiredParameters'], TRUE)
658 );
659 if (trim($GLOBALS['TYPO3_CONF_VARS']['FE']['cHashExcludedParametersIfEmpty']) === '*') {
660 $GLOBALS['TYPO3_CONF_VARS']['FE']['cacheHash']['excludeAllEmptyParameters'] = TRUE;
661 } else {
662 $GLOBALS['TYPO3_CONF_VARS']['FE']['cacheHash']['excludedParametersIfEmpty'] = Utility\GeneralUtility::trimExplode(',', $GLOBALS['TYPO3_CONF_VARS']['FE']['cHashExcludedParametersIfEmpty'], TRUE);
663 }
664 return $this;
665 }
666
667 /**
668 * Set default timezone
669 *
670 * @return Bootstrap
671 */
672 protected function setDefaultTimezone() {
673 $timeZone = $GLOBALS['TYPO3_CONF_VARS']['SYS']['phpTimeZone'];
674 if (empty($timeZone)) {
675 // Time zone from the server environment (TZ env or OS query)
676 $defaultTimeZone = @date_default_timezone_get();
677 if ($defaultTimeZone !== '') {
678 $timeZone = $defaultTimeZone;
679 } else {
680 $timeZone = 'UTC';
681 }
682 }
683 // Set default to avoid E_WARNINGs with PHP > 5.3
684 date_default_timezone_set($timeZone);
685 return $this;
686 }
687
688 /**
689 * Initialize the locales handled by TYPO3
690 *
691 * @return Bootstrap
692 */
693 protected function initializeL10nLocales() {
694 \TYPO3\CMS\Core\Localization\Locales::initialize();
695 return $this;
696 }
697
698 /**
699 * Convert type of "pageNotFound_handling" setting in case it was written as a
700 * string (e.g. if edited in Install Tool)
701 *
702 * @TODO : Remove, if the Install Tool handles such data types correctly
703 * @return Bootstrap
704 */
705 protected function convertPageNotFoundHandlingToBoolean() {
706 if (!strcasecmp($GLOBALS['TYPO3_CONF_VARS']['FE']['pageNotFound_handling'], 'TRUE')) {
707 $GLOBALS['TYPO3_CONF_VARS']['FE']['pageNotFound_handling'] = TRUE;
708 }
709 return $this;
710 }
711
712 /**
713 * Register xdebug(), debug(), debugBegin() and debugEnd() as global functions
714 *
715 * Note: Yes, this is possible in php! xdebug() is then a global function, even
716 * if registerGlobalDebugFunctions() is encapsulated in class scope.
717 *
718 * @return Bootstrap
719 */
720 protected function registerGlobalDebugFunctions() {
721 require_once('GlobalDebugFunctions.php');
722 return $this;
723 }
724
725 /**
726 * Configure and set up exception and error handling
727 *
728 * @return Bootstrap
729 */
730 protected function configureExceptionHandling() {
731 $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['errors']['exceptionHandler'] = $GLOBALS['TYPO3_CONF_VARS']['SYS']['productionExceptionHandler'];
732 $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['errors']['exceptionalErrors'] = $GLOBALS['TYPO3_CONF_VARS']['SYS']['exceptionalErrors'];
733 $doesIpMatch = Utility\GeneralUtility::cmpIP(Utility\GeneralUtility::getIndpEnv('REMOTE_ADDR'), $GLOBALS['TYPO3_CONF_VARS']['SYS']['devIPmask']);
734 $displayErrors = (int)$GLOBALS['TYPO3_CONF_VARS']['SYS']['displayErrors'];
735 // Turn error logging on/off.
736 if ($displayErrors !== -1) {
737 // Special value "2" enables this feature only if $GLOBALS['TYPO3_CONF_VARS'][SYS][devIPmask] matches
738 if ($displayErrors === 2) {
739 $displayErrors = (int)$doesIpMatch;
740 }
741 if ($displayErrors === 0) {
742 $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['errors']['exceptionalErrors'] = 0;
743 }
744 if ($displayErrors === 1) {
745 $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['errors']['exceptionHandler'] = $GLOBALS['TYPO3_CONF_VARS']['SYS']['debugExceptionHandler'];
746 define('TYPO3_ERRORHANDLER_MODE', 'debug');
747 }
748 @ini_set('display_errors', $displayErrors);
749 } elseif ($doesIpMatch) {
750 // With displayErrors = -1 (default), turn on debugging if devIPmask matches:
751 $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['errors']['exceptionHandler'] = $GLOBALS['TYPO3_CONF_VARS']['SYS']['debugExceptionHandler'];
752 }
753 return $this;
754 }
755
756 /**
757 * Set PHP memory limit depending on value of
758 * $GLOBALS['TYPO3_CONF_VARS']['SYS']['setMemoryLimit']
759 *
760 * @return Bootstrap
761 */
762 protected function setMemoryLimit() {
763 if ((int)$GLOBALS['TYPO3_CONF_VARS']['SYS']['setMemoryLimit'] > 16) {
764 @ini_set('memory_limit', ((int)$GLOBALS['TYPO3_CONF_VARS']['SYS']['setMemoryLimit'] . 'm'));
765 }
766 return $this;
767 }
768
769 /**
770 * Define TYPO3_REQUESTTYPE* constants
771 * so devs exactly know what type of request it is
772 *
773 * @return Bootstrap
774 */
775 protected function defineTypo3RequestTypes() {
776 define('TYPO3_REQUESTTYPE_FE', 1);
777 define('TYPO3_REQUESTTYPE_BE', 2);
778 define('TYPO3_REQUESTTYPE_CLI', 4);
779 define('TYPO3_REQUESTTYPE_AJAX', 8);
780 define('TYPO3_REQUESTTYPE_INSTALL', 16);
781 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));
782 return $this;
783 }
784
785 /**
786 * Initialize exception handling
787 * This method is called twice. First when LocalConfiguration has been loaded
788 * and a second time after extension ext_loclconf.php have been included to allow extensions
789 * to change the exception and error handler configuration.
790 *
791 * @return Bootstrap
792 * @internal This is not a public API method, do not use in own extensions
793 */
794 public function initializeExceptionHandling() {
795 if (!empty($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['errors']['exceptionHandler'])) {
796 if (!empty($GLOBALS['TYPO3_CONF_VARS']['SYS']['errorHandler'])) {
797 if ($GLOBALS['TYPO3_CONF_VARS']['SYS']['errorHandler'] !== $this->activeErrorHandlerClassName) {
798 $this->activeErrorHandlerClassName = $GLOBALS['TYPO3_CONF_VARS']['SYS']['errorHandler'];
799 // Register an error handler for the given errorHandlerErrors
800 $errorHandler = Utility\GeneralUtility::makeInstance($this->activeErrorHandlerClassName, $GLOBALS['TYPO3_CONF_VARS']['SYS']['errorHandlerErrors']);
801 // Set errors which will be converted in an exception
802 $errorHandler->setExceptionalErrors($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['errors']['exceptionalErrors']);
803 }
804 } elseif (!empty($this->activeErrorHandlerClassName)) {
805 // Restore error handler in case extensions have unset the configuration in ext_localconf.php
806 restore_error_handler();
807 }
808 if ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['errors']['exceptionHandler'] !== $this->activeExceptionHandlerClassName) {
809 $this->activeExceptionHandlerClassName = $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['errors']['exceptionHandler'];
810 // Registering the exception handler is done in the constructor
811 Utility\GeneralUtility::makeInstance($this->activeExceptionHandlerClassName);
812 }
813 } elseif (!empty($this->activeExceptionHandlerClassName)) {
814 // Restore exception handler in case extensions have unset the configuration in ext_localconf.php
815 restore_exception_handler();
816 }
817 return $this;
818 }
819
820 /**
821 * Extensions may register new caches, so we set the
822 * global cache array to the manager again at this point
823 *
824 * @return Bootstrap
825 * @internal This is not a public API method, do not use in own extensions
826 */
827 public function setFinalCachingFrameworkCacheConfiguration() {
828 $this->getEarlyInstance(\TYPO3\CMS\Core\Cache\CacheManager::class)->setCacheConfigurations($GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']);
829 return $this;
830 }
831
832 /**
833 * Define logging and exception constants
834 *
835 * @return Bootstrap
836 * @internal This is not a public API method, do not use in own extensions
837 */
838 public function defineLoggingAndExceptionConstants() {
839 define('TYPO3_DLOG', $GLOBALS['TYPO3_CONF_VARS']['SYS']['enable_DLOG']);
840 define('TYPO3_ERROR_DLOG', $GLOBALS['TYPO3_CONF_VARS']['SYS']['enable_errorDLOG']);
841 define('TYPO3_EXCEPTION_DLOG', $GLOBALS['TYPO3_CONF_VARS']['SYS']['enable_exceptionDLOG']);
842 return $this;
843 }
844
845 /**
846 * Unsetting reserved global variables:
847 * Those are set in "ext:core/ext_tables.php" file:
848 *
849 * @return Bootstrap
850 * @internal This is not a public API method, do not use in own extensions
851 */
852 public function unsetReservedGlobalVariables() {
853 unset($GLOBALS['PAGES_TYPES']);
854 unset($GLOBALS['TCA']);
855 unset($GLOBALS['TBE_MODULES']);
856 unset($GLOBALS['TBE_STYLES']);
857 unset($GLOBALS['FILEICONS']);
858 // Those set in init.php:
859 unset($GLOBALS['BE_USER']);
860 // Those set otherwise:
861 unset($GLOBALS['TBE_MODULES_EXT']);
862 unset($GLOBALS['TCA_DESCR']);
863 unset($GLOBALS['LOCAL_LANG']);
864 unset($GLOBALS['TYPO3_AJAX']);
865 return $this;
866 }
867
868 /**
869 * Initialize database connection in $GLOBALS and connect if requested
870 *
871 * @return \TYPO3\CMS\Core\Core\Bootstrap
872 * @internal This is not a public API method, do not use in own extensions
873 */
874 public function initializeTypo3DbGlobal() {
875 /** @var $databaseConnection \TYPO3\CMS\Core\Database\DatabaseConnection */
876 $databaseConnection = Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Core\Database\DatabaseConnection::class);
877 $databaseConnection->setDatabaseName(TYPO3_db);
878 $databaseConnection->setDatabaseUsername(TYPO3_db_username);
879 $databaseConnection->setDatabasePassword(TYPO3_db_password);
880
881 $databaseHost = TYPO3_db_host;
882 if (isset($GLOBALS['TYPO3_CONF_VARS']['DB']['port'])) {
883 $databaseConnection->setDatabasePort($GLOBALS['TYPO3_CONF_VARS']['DB']['port']);
884 } elseif (strpos($databaseHost, ':') > 0) {
885 // @TODO: Find a way to handle this case in the install tool and drop this
886 list($databaseHost, $databasePort) = explode(':', $databaseHost);
887 $databaseConnection->setDatabasePort($databasePort);
888 }
889 if (isset($GLOBALS['TYPO3_CONF_VARS']['DB']['socket'])) {
890 $databaseConnection->setDatabaseSocket($GLOBALS['TYPO3_CONF_VARS']['DB']['socket']);
891 }
892 $databaseConnection->setDatabaseHost($databaseHost);
893
894 $databaseConnection->debugOutput = $GLOBALS['TYPO3_CONF_VARS']['SYS']['sqlDebug'];
895
896 if (
897 isset($GLOBALS['TYPO3_CONF_VARS']['SYS']['no_pconnect'])
898 && !$GLOBALS['TYPO3_CONF_VARS']['SYS']['no_pconnect']
899 ) {
900 $databaseConnection->setPersistentDatabaseConnection(TRUE);
901 }
902
903 $isDatabaseHostLocalHost = $databaseHost === 'localhost' || $databaseHost === '127.0.0.1' || $databaseHost === '::1';
904 if (
905 isset($GLOBALS['TYPO3_CONF_VARS']['SYS']['dbClientCompress'])
906 && $GLOBALS['TYPO3_CONF_VARS']['SYS']['dbClientCompress']
907 && !$isDatabaseHostLocalHost
908 ) {
909 $databaseConnection->setConnectionCompression(TRUE);
910 }
911
912 if (!empty($GLOBALS['TYPO3_CONF_VARS']['SYS']['setDBinit'])) {
913 $commandsAfterConnect = \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(
914 LF,
915 str_replace('\' . LF . \'', LF, $GLOBALS['TYPO3_CONF_VARS']['SYS']['setDBinit']),
916 TRUE
917 );
918 $databaseConnection->setInitializeCommandsAfterConnect($commandsAfterConnect);
919 }
920
921 $GLOBALS['TYPO3_DB'] = $databaseConnection;
922 // $GLOBALS['TYPO3_DB'] needs to be defined first in order to work for DBAL
923 $GLOBALS['TYPO3_DB']->initialize();
924
925 return $this;
926 }
927
928 /**
929 * Check adminOnly configuration variable and redirects
930 * to an URL in file typo3conf/LOCK_BACKEND or exit the script
931 *
932 * @throws \RuntimeException
933 * @return Bootstrap
934 * @internal This is not a public API method, do not use in own extensions
935 */
936 public function checkLockedBackendAndRedirectOrDie() {
937 if ($GLOBALS['TYPO3_CONF_VARS']['BE']['adminOnly'] < 0) {
938 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);
939 }
940 if (@is_file((PATH_typo3conf . 'LOCK_BACKEND'))) {
941 if (TYPO3_PROCEED_IF_NO_USER === 2) {
942
943 } else {
944 $fileContent = Utility\GeneralUtility::getUrl(PATH_typo3conf . 'LOCK_BACKEND');
945 if ($fileContent) {
946 header('Location: ' . $fileContent);
947 } else {
948 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);
949 }
950 die;
951 }
952 }
953 return $this;
954 }
955
956 /**
957 * Compare client IP with IPmaskList and exit the script run
958 * if the client is not allowed to access the backend
959 *
960 * @return Bootstrap
961 * @internal This is not a public API method, do not use in own extensions
962 * @throws \RuntimeException
963 */
964 public function checkBackendIpOrDie() {
965 if (trim($GLOBALS['TYPO3_CONF_VARS']['BE']['IPmaskList'])) {
966 if (!Utility\GeneralUtility::cmpIP(Utility\GeneralUtility::getIndpEnv('REMOTE_ADDR'), $GLOBALS['TYPO3_CONF_VARS']['BE']['IPmaskList'])) {
967 throw new \RuntimeException('TYPO3 Backend access denied: The IP address of your client does not match the list of allowed IP addresses.', 1389265900);
968 }
969 }
970 return $this;
971 }
972
973 /**
974 * Check lockSSL configuration variable and redirect
975 * to https version of the backend if needed
976 *
977 * @return Bootstrap
978 * @internal This is not a public API method, do not use in own extensions
979 * @throws \RuntimeException
980 */
981 public function checkSslBackendAndRedirectIfNeeded() {
982 if ((int)$GLOBALS['TYPO3_CONF_VARS']['BE']['lockSSL']) {
983 if ((int)$GLOBALS['TYPO3_CONF_VARS']['BE']['lockSSLPort']) {
984 $sslPortSuffix = ':' . (int)$GLOBALS['TYPO3_CONF_VARS']['BE']['lockSSLPort'];
985 } else {
986 $sslPortSuffix = '';
987 }
988 if ((int)$GLOBALS['TYPO3_CONF_VARS']['BE']['lockSSL'] === 3) {
989 $requestStr = substr(Utility\GeneralUtility::getIndpEnv('TYPO3_REQUEST_SCRIPT'), strlen(Utility\GeneralUtility::getIndpEnv('TYPO3_SITE_URL') . TYPO3_mainDir));
990 if ($requestStr === 'index.php' && !Utility\GeneralUtility::getIndpEnv('TYPO3_SSL')) {
991 list(, $url) = explode('://', Utility\GeneralUtility::getIndpEnv('TYPO3_REQUEST_URL'), 2);
992 list($server, $address) = explode('/', $url, 2);
993 header('Location: https://' . $server . $sslPortSuffix . '/' . $address);
994 die;
995 }
996 } elseif (!Utility\GeneralUtility::getIndpEnv('TYPO3_SSL')) {
997 if ((int)$GLOBALS['TYPO3_CONF_VARS']['BE']['lockSSL'] === 2) {
998 list(, $url) = explode('://', Utility\GeneralUtility::getIndpEnv('TYPO3_SITE_URL') . TYPO3_mainDir, 2);
999 list($server, $address) = explode('/', $url, 2);
1000 header('Location: https://' . $server . $sslPortSuffix . '/' . $address);
1001 die;
1002 } else {
1003 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);
1004 }
1005 }
1006 }
1007 return $this;
1008 }
1009
1010 /**
1011 * Load TCA for frontend
1012 *
1013 * This method is *only* executed in frontend scope. The idea is to execute the
1014 * whole TCA and ext_tables (which manipulate TCA) on first frontend access,
1015 * and then cache the full TCA on disk to be used for the next run again.
1016 *
1017 * This way, ext_tables.php ist not executed every time, but $GLOBALS['TCA']
1018 * is still always there.
1019 *
1020 * @return Bootstrap
1021 * @internal This is not a public API method, do not use in own extensions
1022 */
1023 public function loadCachedTca() {
1024 $cacheIdentifier = 'tca_fe_' . sha1((TYPO3_version . PATH_site . 'tca_fe'));
1025 /** @var $codeCache \TYPO3\CMS\Core\Cache\Frontend\PhpFrontend */
1026 $codeCache = $this->getEarlyInstance(\TYPO3\CMS\Core\Cache\CacheManager::class)->getCache('cache_core');
1027 if ($codeCache->has($cacheIdentifier)) {
1028 // substr is necessary, because the php frontend wraps php code around the cache value
1029 $GLOBALS['TCA'] = unserialize(substr($codeCache->get($cacheIdentifier), 6, -2));
1030 } else {
1031 $this->loadExtensionTables(TRUE);
1032 $codeCache->set($cacheIdentifier, serialize($GLOBALS['TCA']));
1033 }
1034 return $this;
1035 }
1036
1037 /**
1038 * Load ext_tables and friends.
1039 *
1040 * This will mainly set up $TCA and several other global arrays
1041 * through API's like extMgm.
1042 * Executes ext_tables.php files of loaded extensions or the
1043 * according cache file if exists.
1044 *
1045 * @param bool $allowCaching True, if reading compiled ext_tables file from cache is allowed
1046 * @return Bootstrap
1047 * @internal This is not a public API method, do not use in own extensions
1048 */
1049 public function loadExtensionTables($allowCaching = TRUE) {
1050 Utility\ExtensionManagementUtility::loadBaseTca($allowCaching);
1051 Utility\ExtensionManagementUtility::loadExtTables($allowCaching);
1052 $this->executeExtTablesAdditionalFile();
1053 $this->runExtTablesPostProcessingHooks();
1054 return $this;
1055 }
1056
1057 /**
1058 * Execute TYPO3_extTableDef_script if defined and exists
1059 *
1060 * Note: For backwards compatibility some global variables are
1061 * explicitly set as global to be used without $GLOBALS[] in
1062 * the extension table script. It is discouraged to access variables like
1063 * $TBE_MODULES directly, but we can not prohibit
1064 * this without heavily breaking backwards compatibility.
1065 *
1066 * @deprecated since TYPO3 CMS 7, will be removed in TYPO3 CMS 8
1067 * @return void
1068 */
1069 protected function executeExtTablesAdditionalFile() {
1070 // It is discouraged to use those global variables directly, but we
1071 // can not prohibit this without breaking backwards compatibility
1072 global $T3_SERVICES, $T3_VAR, $TYPO3_CONF_VARS;
1073 global $TBE_MODULES, $TBE_MODULES_EXT, $TCA;
1074 global $PAGES_TYPES, $TBE_STYLES, $FILEICONS;
1075 global $_EXTKEY;
1076 // Load additional ext tables script if the file exists
1077 $extTablesFile = PATH_typo3conf . TYPO3_extTableDef_script;
1078 if (file_exists($extTablesFile) && is_file($extTablesFile)) {
1079 Utility\GeneralUtility::deprecationLog(
1080 'Using typo3conf/' . TYPO3_extTableDef_script . ' is deprecated and will be removed with TYPO3 CMS 8. Please move your TCA overrides'
1081 . ' to Configuration/TCA/Overrides of your project specific extension, or slot the signal "tcaIsBeingBuilt" for further processing.'
1082 );
1083 include $extTablesFile;
1084 }
1085 }
1086
1087 /**
1088 * Check for registered ext tables hooks and run them
1089 *
1090 * @throws \UnexpectedValueException
1091 * @return void
1092 */
1093 protected function runExtTablesPostProcessingHooks() {
1094 if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['GLOBAL']['extTablesInclusion-PostProcessing'])) {
1095 foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['GLOBAL']['extTablesInclusion-PostProcessing'] as $classReference) {
1096 /** @var $hookObject \TYPO3\CMS\Core\Database\TableConfigurationPostProcessingHookInterface */
1097 $hookObject = Utility\GeneralUtility::getUserObj($classReference);
1098 if (!$hookObject instanceof \TYPO3\CMS\Core\Database\TableConfigurationPostProcessingHookInterface) {
1099 throw new \UnexpectedValueException('$hookObject must implement interface TYPO3\\CMS\\Core\\Database\\TableConfigurationPostProcessingHookInterface', 1320585902);
1100 }
1101 $hookObject->processData();
1102 }
1103 }
1104 }
1105
1106 /**
1107 * Initialize sprite manager
1108 *
1109 * @return Bootstrap
1110 * @internal This is not a public API method, do not use in own extensions
1111 */
1112 public function initializeSpriteManager() {
1113 \TYPO3\CMS\Backend\Sprite\SpriteManager::initialize();
1114 return $this;
1115 }
1116
1117 /**
1118 * Initialize backend user object in globals
1119 *
1120 * @return Bootstrap
1121 * @internal This is not a public API method, do not use in own extensions
1122 */
1123 public function initializeBackendUser() {
1124 /** @var $backendUser \TYPO3\CMS\Core\Authentication\BackendUserAuthentication */
1125 $backendUser = Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Core\Authentication\BackendUserAuthentication::class);
1126 $backendUser->warningEmail = $GLOBALS['TYPO3_CONF_VARS']['BE']['warning_email_addr'];
1127 $backendUser->lockIP = $GLOBALS['TYPO3_CONF_VARS']['BE']['lockIP'];
1128 $backendUser->auth_timeout_field = (int)$GLOBALS['TYPO3_CONF_VARS']['BE']['sessionTimeout'];
1129 if (TYPO3_REQUESTTYPE & TYPO3_REQUESTTYPE_CLI) {
1130 $backendUser->dontSetCookie = TRUE;
1131 }
1132 // The global must be available very early, because methods below
1133 // might trigger code which relies on it. See: #45625
1134 $GLOBALS['BE_USER'] = $backendUser;
1135 $backendUser->start();
1136 return $this;
1137 }
1138
1139 /**
1140 * Initializes and ensures authenticated access
1141 *
1142 * @internal This is not a public API method, do not use in own extensions
1143 * @return \TYPO3\CMS\Core\Core\Bootstrap
1144 */
1145 public function initializeBackendAuthentication() {
1146 $GLOBALS['BE_USER']->checkCLIuser();
1147 $GLOBALS['BE_USER']->backendCheckLogin();
1148 return $this;
1149 }
1150
1151 /**
1152 * Initialize language object
1153 *
1154 * @return Bootstrap
1155 * @internal This is not a public API method, do not use in own extensions
1156 */
1157 public function initializeLanguageObject() {
1158 /** @var $GLOBALS['LANG'] \TYPO3\CMS\Lang\LanguageService */
1159 $GLOBALS['LANG'] = Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Lang\LanguageService::class);
1160 $GLOBALS['LANG']->init($GLOBALS['BE_USER']->uc['lang']);
1161 return $this;
1162 }
1163
1164 /**
1165 * Throw away all output that may have happened during bootstrapping by weird extensions
1166 *
1167 * @return Bootstrap
1168 * @internal This is not a public API method, do not use in own extensions
1169 */
1170 public function endOutputBufferingAndCleanPreviousOutput() {
1171 ob_clean();
1172 return $this;
1173 }
1174
1175 /**
1176 * Initialize output compression if configured
1177 *
1178 * @return Bootstrap
1179 * @internal This is not a public API method, do not use in own extensions
1180 */
1181 public function initializeOutputCompression() {
1182 if (extension_loaded('zlib') && $GLOBALS['TYPO3_CONF_VARS']['BE']['compressionLevel']) {
1183 if (Utility\MathUtility::canBeInterpretedAsInteger($GLOBALS['TYPO3_CONF_VARS']['BE']['compressionLevel'])) {
1184 @ini_set('zlib.output_compression_level', $GLOBALS['TYPO3_CONF_VARS']['BE']['compressionLevel']);
1185 }
1186 ob_start('ob_gzhandler');
1187 }
1188 return $this;
1189 }
1190
1191 /**
1192 * Send HTTP headers if configured
1193 *
1194 * @return Bootstrap
1195 * @internal This is not a public API method, do not use in own extensions
1196 */
1197 public function sendHttpHeaders() {
1198 if (!empty($GLOBALS['TYPO3_CONF_VARS']['BE']['HTTP']['Response']['Headers']) && is_array($GLOBALS['TYPO3_CONF_VARS']['BE']['HTTP']['Response']['Headers'])) {
1199 foreach ($GLOBALS['TYPO3_CONF_VARS']['BE']['HTTP']['Response']['Headers'] as $header) {
1200 header($header);
1201 }
1202 }
1203 return $this;
1204 }
1205
1206 /**
1207 * Things that should be performed to shut down the framework.
1208 * This method is called in all important scripts for a clean
1209 * shut down of the system.
1210 *
1211 * @return Bootstrap
1212 * @internal This is not a public API method, do not use in own extensions
1213 */
1214 public function shutdown() {
1215 return $this;
1216 }
1217
1218 /**
1219 * Provides an instance of "template" for backend-modules to
1220 * work with.
1221 *
1222 * @return Bootstrap
1223 * @internal This is not a public API method, do not use in own extensions
1224 */
1225 public function initializeBackendTemplate() {
1226 $GLOBALS['TBE_TEMPLATE'] = Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Template\DocumentTemplate::class);
1227 return $this;
1228 }
1229
1230 }