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