e2e0f910c6bcb7268b967f154b729a289f72ef7a
[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->getInstance()
360 ->loadAdditionalConfigurationFromExtensions($allowCaching);
361 return $this;
362 }
363
364 /**
365 * Sets up additional configuration applied in all scopes
366 *
367 * @return Bootstrap
368 * @internal This is not a public API method, do not use in own extensions
369 */
370 public function applyAdditionalConfigurationSettings() {
371 $this->getInstance()
372 ->initializeExceptionHandling()
373 ->setFinalCachingFrameworkCacheConfiguration()
374 ->defineLoggingAndExceptionConstants()
375 ->unsetReservedGlobalVariables();
376 return $this;
377 }
378
379 /**
380 * Throws an exception if no browser could be identified
381 *
382 * @return Bootstrap
383 * @throws \RuntimeException
384 * @internal This is not a public API method, do not use in own extensions
385 */
386 public function checkValidBrowserOrDie() {
387 // Checks for proper browser
388 if (empty($GLOBALS['CLIENT']['BROWSER'])) {
389 throw new \RuntimeException('Browser Error: Your browser version looks incompatible with this TYPO3 version!', 1294587023);
390 }
391 return $this;
392 }
393
394 /**
395 * We need an early instance of the configuration manager.
396 * Since makeInstance relies on the object configuration, we create it here with new instead.
397 *
398 * @return Bootstrap
399 */
400 public function populateLocalConfiguration() {
401 try {
402 $configurationManager = $this->getEarlyInstance(\TYPO3\CMS\Core\Configuration\ConfigurationManager::class);
403 } catch(\TYPO3\CMS\Core\Exception $exception) {
404 $configurationManager = new \TYPO3\CMS\Core\Configuration\ConfigurationManager();
405 $this->setEarlyInstance(\TYPO3\CMS\Core\Configuration\ConfigurationManager::class, $configurationManager);
406 }
407 $configurationManager->exportConfiguration();
408 return $this;
409 }
410
411 /**
412 * Set cache_core to null backend, effectively disabling eg. the autoloader cache
413 *
414 * @return \TYPO3\CMS\Core\Core\Bootstrap
415 * @internal This is not a public API method, do not use in own extensions
416 */
417 public function disableCoreAndClassesCache() {
418 $GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['cache_core']['backend']
419 = \TYPO3\CMS\Core\Cache\Backend\NullBackend::class;
420 $GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['cache_classes']['backend']
421 = \TYPO3\CMS\Core\Cache\Backend\TransientMemoryBackend::class;
422 return $this;
423 }
424
425 /**
426 * Define database constants
427 *
428 * @return \TYPO3\CMS\Core\Core\Bootstrap
429 */
430 protected function defineDatabaseConstants() {
431 define('TYPO3_db', $GLOBALS['TYPO3_CONF_VARS']['DB']['database']);
432 define('TYPO3_db_username', $GLOBALS['TYPO3_CONF_VARS']['DB']['username']);
433 define('TYPO3_db_password', $GLOBALS['TYPO3_CONF_VARS']['DB']['password']);
434 define('TYPO3_db_host', $GLOBALS['TYPO3_CONF_VARS']['DB']['host']);
435 define('TYPO3_extTableDef_script',
436 isset($GLOBALS['TYPO3_CONF_VARS']['DB']['extTablesDefinitionScript'])
437 ? $GLOBALS['TYPO3_CONF_VARS']['DB']['extTablesDefinitionScript']
438 : 'extTables.php');
439 return $this;
440 }
441
442 /**
443 * Define user agent constant
444 *
445 * @return \TYPO3\CMS\Core\Core\Bootstrap
446 */
447 protected function defineUserAgentConstant() {
448 define('TYPO3_user_agent', 'User-Agent: ' . $GLOBALS['TYPO3_CONF_VARS']['HTTP']['userAgent']);
449 return $this;
450 }
451
452 /**
453 * Register default ExtDirect components
454 *
455 * @return Bootstrap
456 */
457 protected function registerExtDirectComponents() {
458 if (TYPO3_MODE === 'BE') {
459 Utility\ExtensionManagementUtility::registerExtDirectComponent('TYPO3.Components.PageTree.DataProvider', \TYPO3\CMS\Backend\Tree\Pagetree\ExtdirectTreeDataProvider::class, 'web', 'user,group');
460 Utility\ExtensionManagementUtility::registerExtDirectComponent('TYPO3.Components.PageTree.Commands', \TYPO3\CMS\Backend\Tree\Pagetree\ExtdirectTreeCommands::class, 'web', 'user,group');
461 Utility\ExtensionManagementUtility::registerExtDirectComponent('TYPO3.Components.PageTree.ContextMenuDataProvider', \TYPO3\CMS\Backend\ContextMenu\Pagetree\Extdirect\ContextMenuConfiguration::class, 'web', 'user,group');
462 Utility\ExtensionManagementUtility::registerExtDirectComponent('TYPO3.LiveSearchActions.ExtDirect', \TYPO3\CMS\Backend\Search\LiveSearch\ExtDirect\LiveSearchDataProvider::class, 'web_list', 'user,group');
463 Utility\ExtensionManagementUtility::registerExtDirectComponent('TYPO3.BackendUserSettings.ExtDirect', \TYPO3\CMS\Backend\User\ExtDirect\BackendUserSettingsDataProvider::class);
464 if (Utility\ExtensionManagementUtility::isLoaded('context_help')) {
465 Utility\ExtensionManagementUtility::registerExtDirectComponent('TYPO3.CSH.ExtDirect', \TYPO3\CMS\ContextHelp\ExtDirect\ContextHelpDataProvider::class);
466 }
467 Utility\ExtensionManagementUtility::registerExtDirectComponent('TYPO3.ExtDirectStateProvider.ExtDirect', \TYPO3\CMS\Backend\InterfaceState\ExtDirect\DataProvider::class);
468 Utility\ExtensionManagementUtility::registerExtDirectComponent(
469 'TYPO3.Components.DragAndDrop.CommandController',
470 Utility\ExtensionManagementUtility::extPath('backend') . 'Classes/View/PageLayout/Extdirect/ExtdirectPageCommands.php:' . \TYPO3\CMS\Backend\View\PageLayout\ExtDirect\ExtdirectPageCommands::class, 'web', 'user,group'
471 );
472 }
473 return $this;
474 }
475
476 /**
477 * Initialize caching framework
478 *
479 * @return Bootstrap
480 * @internal This is not a public API method, do not use in own extensions
481 */
482 public function initializeCachingFramework() {
483 $this->setEarlyInstance(\TYPO3\CMS\Core\Cache\CacheManager::class, \TYPO3\CMS\Core\Cache\Cache::initializeCachingFramework());
484 return $this;
485 }
486
487 /**
488 * Parse old curl options and set new http ones instead
489 *
490 * @TODO: Move this functionality to the silent updater in the Install Tool
491 * @return Bootstrap
492 */
493 protected function transferDeprecatedCurlSettings() {
494 if (!empty($GLOBALS['TYPO3_CONF_VARS']['SYS']['curlProxyServer']) && empty($GLOBALS['TYPO3_CONF_VARS']['HTTP']['proxy_host'])) {
495 $curlProxy = rtrim(preg_replace('#^https?://#', '', $GLOBALS['TYPO3_CONF_VARS']['SYS']['curlProxyServer']), '/');
496 $proxyParts = Utility\GeneralUtility::revExplode(':', $curlProxy, 2);
497 $GLOBALS['TYPO3_CONF_VARS']['HTTP']['proxy_host'] = $proxyParts[0];
498 $GLOBALS['TYPO3_CONF_VARS']['HTTP']['proxy_port'] = $proxyParts[1];
499 }
500 if (!empty($GLOBALS['TYPO3_CONF_VARS']['SYS']['curlProxyUserPass']) && empty($GLOBALS['TYPO3_CONF_VARS']['HTTP']['proxy_user'])) {
501 $userPassParts = explode(':', $GLOBALS['TYPO3_CONF_VARS']['SYS']['curlProxyUserPass'], 2);
502 $GLOBALS['TYPO3_CONF_VARS']['HTTP']['proxy_user'] = $userPassParts[0];
503 $GLOBALS['TYPO3_CONF_VARS']['HTTP']['proxy_password'] = $userPassParts[1];
504 }
505 if ($GLOBALS['TYPO3_CONF_VARS']['SYS']['curlUse']) {
506 $GLOBALS['TYPO3_CONF_VARS']['HTTP']['adapter'] = 'curl';
507 }
508 return $this;
509 }
510
511 /**
512 * Set cacheHash options
513 *
514 * @return Bootstrap
515 */
516 protected function setCacheHashOptions() {
517 $GLOBALS['TYPO3_CONF_VARS']['FE']['cacheHash'] = array(
518 'cachedParametersWhiteList' => Utility\GeneralUtility::trimExplode(',', $GLOBALS['TYPO3_CONF_VARS']['FE']['cHashOnlyForParameters'], TRUE),
519 'excludedParameters' => Utility\GeneralUtility::trimExplode(',', $GLOBALS['TYPO3_CONF_VARS']['FE']['cHashExcludedParameters'], TRUE),
520 'requireCacheHashPresenceParameters' => Utility\GeneralUtility::trimExplode(',', $GLOBALS['TYPO3_CONF_VARS']['FE']['cHashRequiredParameters'], TRUE)
521 );
522 if (trim($GLOBALS['TYPO3_CONF_VARS']['FE']['cHashExcludedParametersIfEmpty']) === '*') {
523 $GLOBALS['TYPO3_CONF_VARS']['FE']['cacheHash']['excludeAllEmptyParameters'] = TRUE;
524 } else {
525 $GLOBALS['TYPO3_CONF_VARS']['FE']['cacheHash']['excludedParametersIfEmpty'] = Utility\GeneralUtility::trimExplode(',', $GLOBALS['TYPO3_CONF_VARS']['FE']['cHashExcludedParametersIfEmpty'], TRUE);
526 }
527 return $this;
528 }
529
530 /**
531 * Set default timezone
532 *
533 * @return Bootstrap
534 */
535 protected function setDefaultTimezone() {
536 $timeZone = $GLOBALS['TYPO3_CONF_VARS']['SYS']['phpTimeZone'];
537 if (empty($timeZone)) {
538 // Time zone from the server environment (TZ env or OS query)
539 $defaultTimeZone = @date_default_timezone_get();
540 if ($defaultTimeZone !== '') {
541 $timeZone = $defaultTimeZone;
542 } else {
543 $timeZone = 'UTC';
544 }
545 }
546 // Set default to avoid E_WARNINGs with PHP > 5.3
547 date_default_timezone_set($timeZone);
548 return $this;
549 }
550
551 /**
552 * Initialize the locales handled by TYPO3
553 *
554 * @return Bootstrap
555 */
556 protected function initializeL10nLocales() {
557 \TYPO3\CMS\Core\Localization\Locales::initialize();
558 return $this;
559 }
560
561 /**
562 * Convert type of "pageNotFound_handling" setting in case it was written as a
563 * string (e.g. if edited in Install Tool)
564 *
565 * @TODO : Remove, if the Install Tool handles such data types correctly
566 * @return Bootstrap
567 */
568 protected function convertPageNotFoundHandlingToBoolean() {
569 if (!strcasecmp($GLOBALS['TYPO3_CONF_VARS']['FE']['pageNotFound_handling'], 'TRUE')) {
570 $GLOBALS['TYPO3_CONF_VARS']['FE']['pageNotFound_handling'] = TRUE;
571 }
572 return $this;
573 }
574
575 /**
576 * Register xdebug(), debug(), debugBegin() and debugEnd() as global functions
577 *
578 * Note: Yes, this is possible in php! xdebug() is then a global function, even
579 * if registerGlobalDebugFunctions() is encapsulated in class scope.
580 *
581 * @return Bootstrap
582 */
583 protected function registerGlobalDebugFunctions() {
584 require_once('GlobalDebugFunctions.php');
585 return $this;
586 }
587
588 /**
589 * Configure and set up exception and error handling
590 *
591 * @return Bootstrap
592 */
593 protected function configureExceptionHandling() {
594 $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['errors']['exceptionHandler'] = $GLOBALS['TYPO3_CONF_VARS']['SYS']['productionExceptionHandler'];
595 $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['errors']['exceptionalErrors'] = $GLOBALS['TYPO3_CONF_VARS']['SYS']['exceptionalErrors'];
596 $doesIpMatch = Utility\GeneralUtility::cmpIP(Utility\GeneralUtility::getIndpEnv('REMOTE_ADDR'), $GLOBALS['TYPO3_CONF_VARS']['SYS']['devIPmask']);
597 $displayErrors = (int)$GLOBALS['TYPO3_CONF_VARS']['SYS']['displayErrors'];
598 // Turn error logging on/off.
599 if ($displayErrors !== -1) {
600 // Special value "2" enables this feature only if $GLOBALS['TYPO3_CONF_VARS'][SYS][devIPmask] matches
601 if ($displayErrors === 2) {
602 $displayErrors = (int)$doesIpMatch;
603 }
604 if ($displayErrors === 0) {
605 $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['errors']['exceptionalErrors'] = 0;
606 }
607 if ($displayErrors === 1) {
608 $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['errors']['exceptionHandler'] = $GLOBALS['TYPO3_CONF_VARS']['SYS']['debugExceptionHandler'];
609 define('TYPO3_ERRORHANDLER_MODE', 'debug');
610 }
611 @ini_set('display_errors', $displayErrors);
612 } elseif ($doesIpMatch) {
613 // With displayErrors = -1 (default), turn on debugging if devIPmask matches:
614 $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['errors']['exceptionHandler'] = $GLOBALS['TYPO3_CONF_VARS']['SYS']['debugExceptionHandler'];
615 }
616 return $this;
617 }
618
619 /**
620 * Set PHP memory limit depending on value of
621 * $GLOBALS['TYPO3_CONF_VARS']['SYS']['setMemoryLimit']
622 *
623 * @return Bootstrap
624 */
625 protected function setMemoryLimit() {
626 if ((int)$GLOBALS['TYPO3_CONF_VARS']['SYS']['setMemoryLimit'] > 16) {
627 @ini_set('memory_limit', ((int)$GLOBALS['TYPO3_CONF_VARS']['SYS']['setMemoryLimit'] . 'm'));
628 }
629 return $this;
630 }
631
632 /**
633 * Define TYPO3_REQUESTTYPE* constants
634 * so devs exactly know what type of request it is
635 *
636 * @return Bootstrap
637 */
638 protected function defineTypo3RequestTypes() {
639 define('TYPO3_REQUESTTYPE_FE', 1);
640 define('TYPO3_REQUESTTYPE_BE', 2);
641 define('TYPO3_REQUESTTYPE_CLI', 4);
642 define('TYPO3_REQUESTTYPE_AJAX', 8);
643 define('TYPO3_REQUESTTYPE_INSTALL', 16);
644 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));
645 return $this;
646 }
647
648 /**
649 * Load extension configuration files (ext_localconf.php)
650 *
651 * The ext_localconf.php files in extensions are meant to make changes
652 * to the global $TYPO3_CONF_VARS configuration array.
653 *
654 * @param bool $allowCaching
655 * @return Bootstrap
656 */
657 protected function loadAdditionalConfigurationFromExtensions($allowCaching = TRUE) {
658 Utility\ExtensionManagementUtility::loadExtLocalconf($allowCaching);
659 return $this;
660 }
661
662 /**
663 * Initialize exception handling
664 * This method is called twice. First when LocalConfiguration has been loaded
665 * and a second time after extension ext_loclconf.php have been included to allow extensions
666 * to change the exception and error handler configuration.
667 *
668 * @return Bootstrap
669 */
670 protected function initializeExceptionHandling() {
671 if (!empty($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['errors']['exceptionHandler'])) {
672 if (!empty($GLOBALS['TYPO3_CONF_VARS']['SYS']['errorHandler'])) {
673 if ($GLOBALS['TYPO3_CONF_VARS']['SYS']['errorHandler'] !== $this->activeErrorHandlerClassName) {
674 $this->activeErrorHandlerClassName = $GLOBALS['TYPO3_CONF_VARS']['SYS']['errorHandler'];
675 // Register an error handler for the given errorHandlerErrors
676 $errorHandler = Utility\GeneralUtility::makeInstance($this->activeErrorHandlerClassName, $GLOBALS['TYPO3_CONF_VARS']['SYS']['errorHandlerErrors']);
677 // Set errors which will be converted in an exception
678 $errorHandler->setExceptionalErrors($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['errors']['exceptionalErrors']);
679 }
680 } elseif (!empty($this->activeErrorHandlerClassName)) {
681 // Restore error handler in case extensions have unset the configuration in ext_localconf.php
682 restore_error_handler();
683 }
684 if ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['errors']['exceptionHandler'] !== $this->activeExceptionHandlerClassName) {
685 $this->activeExceptionHandlerClassName = $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['errors']['exceptionHandler'];
686 // Registering the exception handler is done in the constructor
687 Utility\GeneralUtility::makeInstance($this->activeExceptionHandlerClassName);
688 }
689 } elseif (!empty($this->activeExceptionHandlerClassName)) {
690 // Restore exception handler in case extensions have unset the configuration in ext_localconf.php
691 restore_exception_handler();
692 }
693 return $this;
694 }
695
696 /**
697 * Extensions may register new caches, so we set the
698 * global cache array to the manager again at this point
699 *
700 * @return Bootstrap
701 */
702 protected function setFinalCachingFrameworkCacheConfiguration() {
703 $this->getEarlyInstance(\TYPO3\CMS\Core\Cache\CacheManager::class)->setCacheConfigurations($GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']);
704 return $this;
705 }
706
707 /**
708 * Define logging and exception constants
709 *
710 * @return Bootstrap
711 */
712 protected function defineLoggingAndExceptionConstants() {
713 define('TYPO3_DLOG', $GLOBALS['TYPO3_CONF_VARS']['SYS']['enable_DLOG']);
714 define('TYPO3_ERROR_DLOG', $GLOBALS['TYPO3_CONF_VARS']['SYS']['enable_errorDLOG']);
715 define('TYPO3_EXCEPTION_DLOG', $GLOBALS['TYPO3_CONF_VARS']['SYS']['enable_exceptionDLOG']);
716 return $this;
717 }
718
719 /**
720 * Unsetting reserved global variables:
721 * Those are set in "ext:core/ext_tables.php" file:
722 *
723 * @return Bootstrap
724 */
725 protected function unsetReservedGlobalVariables() {
726 unset($GLOBALS['PAGES_TYPES']);
727 unset($GLOBALS['TCA']);
728 unset($GLOBALS['TBE_MODULES']);
729 unset($GLOBALS['TBE_STYLES']);
730 unset($GLOBALS['FILEICONS']);
731 // Those set in init.php:
732 unset($GLOBALS['BE_USER']);
733 // Those set otherwise:
734 unset($GLOBALS['TBE_MODULES_EXT']);
735 unset($GLOBALS['TCA_DESCR']);
736 unset($GLOBALS['LOCAL_LANG']);
737 unset($GLOBALS['TYPO3_AJAX']);
738 return $this;
739 }
740
741 /**
742 * Initialize database connection in $GLOBALS and connect if requested
743 *
744 * @return \TYPO3\CMS\Core\Core\Bootstrap
745 * @internal This is not a public API method, do not use in own extensions
746 */
747 public function initializeTypo3DbGlobal() {
748 /** @var $databaseConnection \TYPO3\CMS\Core\Database\DatabaseConnection */
749 $databaseConnection = Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Core\Database\DatabaseConnection::class);
750 $databaseConnection->setDatabaseName(TYPO3_db);
751 $databaseConnection->setDatabaseUsername(TYPO3_db_username);
752 $databaseConnection->setDatabasePassword(TYPO3_db_password);
753
754 $databaseHost = TYPO3_db_host;
755 if (isset($GLOBALS['TYPO3_CONF_VARS']['DB']['port'])) {
756 $databaseConnection->setDatabasePort($GLOBALS['TYPO3_CONF_VARS']['DB']['port']);
757 } elseif (strpos($databaseHost, ':') > 0) {
758 // @TODO: Find a way to handle this case in the install tool and drop this
759 list($databaseHost, $databasePort) = explode(':', $databaseHost);
760 $databaseConnection->setDatabasePort($databasePort);
761 }
762 if (isset($GLOBALS['TYPO3_CONF_VARS']['DB']['socket'])) {
763 $databaseConnection->setDatabaseSocket($GLOBALS['TYPO3_CONF_VARS']['DB']['socket']);
764 }
765 $databaseConnection->setDatabaseHost($databaseHost);
766
767 $databaseConnection->debugOutput = $GLOBALS['TYPO3_CONF_VARS']['SYS']['sqlDebug'];
768
769 if (
770 isset($GLOBALS['TYPO3_CONF_VARS']['SYS']['no_pconnect'])
771 && !$GLOBALS['TYPO3_CONF_VARS']['SYS']['no_pconnect']
772 ) {
773 $databaseConnection->setPersistentDatabaseConnection(TRUE);
774 }
775
776 $isDatabaseHostLocalHost = $databaseHost === 'localhost' || $databaseHost === '127.0.0.1' || $databaseHost === '::1';
777 if (
778 isset($GLOBALS['TYPO3_CONF_VARS']['SYS']['dbClientCompress'])
779 && $GLOBALS['TYPO3_CONF_VARS']['SYS']['dbClientCompress']
780 && !$isDatabaseHostLocalHost
781 ) {
782 $databaseConnection->setConnectionCompression(TRUE);
783 }
784
785 if (!empty($GLOBALS['TYPO3_CONF_VARS']['SYS']['setDBinit'])) {
786 $commandsAfterConnect = \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(
787 LF,
788 str_replace('\' . LF . \'', LF, $GLOBALS['TYPO3_CONF_VARS']['SYS']['setDBinit']),
789 TRUE
790 );
791 $databaseConnection->setInitializeCommandsAfterConnect($commandsAfterConnect);
792 }
793
794 $GLOBALS['TYPO3_DB'] = $databaseConnection;
795 // $GLOBALS['TYPO3_DB'] needs to be defined first in order to work for DBAL
796 $GLOBALS['TYPO3_DB']->initialize();
797
798 return $this;
799 }
800
801 /**
802 * Check adminOnly configuration variable and redirects
803 * to an URL in file typo3conf/LOCK_BACKEND or exit the script
804 *
805 * @throws \RuntimeException
806 * @return Bootstrap
807 * @internal This is not a public API method, do not use in own extensions
808 */
809 public function checkLockedBackendAndRedirectOrDie() {
810 if ($GLOBALS['TYPO3_CONF_VARS']['BE']['adminOnly'] < 0) {
811 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);
812 }
813 if (@is_file((PATH_typo3conf . 'LOCK_BACKEND'))) {
814 if (TYPO3_PROCEED_IF_NO_USER === 2) {
815
816 } else {
817 $fileContent = Utility\GeneralUtility::getUrl(PATH_typo3conf . 'LOCK_BACKEND');
818 if ($fileContent) {
819 header('Location: ' . $fileContent);
820 } else {
821 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);
822 }
823 die;
824 }
825 }
826 return $this;
827 }
828
829 /**
830 * Compare client IP with IPmaskList and exit the script run
831 * if the client is not allowed to access the backend
832 *
833 * @return Bootstrap
834 * @internal This is not a public API method, do not use in own extensions
835 * @throws \RuntimeException
836 */
837 public function checkBackendIpOrDie() {
838 if (trim($GLOBALS['TYPO3_CONF_VARS']['BE']['IPmaskList'])) {
839 if (!Utility\GeneralUtility::cmpIP(Utility\GeneralUtility::getIndpEnv('REMOTE_ADDR'), $GLOBALS['TYPO3_CONF_VARS']['BE']['IPmaskList'])) {
840 throw new \RuntimeException('TYPO3 Backend access denied: The IP address of your client does not match the list of allowed IP addresses.', 1389265900);
841 }
842 }
843 return $this;
844 }
845
846 /**
847 * Check lockSSL configuration variable and redirect
848 * to https version of the backend if needed
849 *
850 * @return Bootstrap
851 * @internal This is not a public API method, do not use in own extensions
852 * @throws \RuntimeException
853 */
854 public function checkSslBackendAndRedirectIfNeeded() {
855 if ((int)$GLOBALS['TYPO3_CONF_VARS']['BE']['lockSSL']) {
856 if ((int)$GLOBALS['TYPO3_CONF_VARS']['BE']['lockSSLPort']) {
857 $sslPortSuffix = ':' . (int)$GLOBALS['TYPO3_CONF_VARS']['BE']['lockSSLPort'];
858 } else {
859 $sslPortSuffix = '';
860 }
861 if ((int)$GLOBALS['TYPO3_CONF_VARS']['BE']['lockSSL'] === 3) {
862 $requestStr = substr(Utility\GeneralUtility::getIndpEnv('TYPO3_REQUEST_SCRIPT'), strlen(Utility\GeneralUtility::getIndpEnv('TYPO3_SITE_URL') . TYPO3_mainDir));
863 if ($requestStr === 'index.php' && !Utility\GeneralUtility::getIndpEnv('TYPO3_SSL')) {
864 list(, $url) = explode('://', Utility\GeneralUtility::getIndpEnv('TYPO3_REQUEST_URL'), 2);
865 list($server, $address) = explode('/', $url, 2);
866 header('Location: https://' . $server . $sslPortSuffix . '/' . $address);
867 die;
868 }
869 } elseif (!Utility\GeneralUtility::getIndpEnv('TYPO3_SSL')) {
870 if ((int)$GLOBALS['TYPO3_CONF_VARS']['BE']['lockSSL'] === 2) {
871 list(, $url) = explode('://', Utility\GeneralUtility::getIndpEnv('TYPO3_SITE_URL') . TYPO3_mainDir, 2);
872 list($server, $address) = explode('/', $url, 2);
873 header('Location: https://' . $server . $sslPortSuffix . '/' . $address);
874 die;
875 } else {
876 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);
877 }
878 }
879 }
880 return $this;
881 }
882
883 /**
884 * Load TCA for frontend
885 *
886 * This method is *only* executed in frontend scope. The idea is to execute the
887 * whole TCA and ext_tables (which manipulate TCA) on first frontend access,
888 * and then cache the full TCA on disk to be used for the next run again.
889 *
890 * This way, ext_tables.php ist not executed every time, but $GLOBALS['TCA']
891 * is still always there.
892 *
893 * @return Bootstrap
894 * @internal This is not a public API method, do not use in own extensions
895 */
896 public function loadCachedTca() {
897 $cacheIdentifier = 'tca_fe_' . sha1((TYPO3_version . PATH_site . 'tca_fe'));
898 /** @var $codeCache \TYPO3\CMS\Core\Cache\Frontend\PhpFrontend */
899 $codeCache = $this->getEarlyInstance(\TYPO3\CMS\Core\Cache\CacheManager::class)->getCache('cache_core');
900 if ($codeCache->has($cacheIdentifier)) {
901 // substr is necessary, because the php frontend wraps php code around the cache value
902 $GLOBALS['TCA'] = unserialize(substr($codeCache->get($cacheIdentifier), 6, -2));
903 } else {
904 $this->loadExtensionTables(TRUE);
905 $codeCache->set($cacheIdentifier, serialize($GLOBALS['TCA']));
906 }
907 return $this;
908 }
909
910 /**
911 * Load ext_tables and friends.
912 *
913 * This will mainly set up $TCA and several other global arrays
914 * through API's like extMgm.
915 * Executes ext_tables.php files of loaded extensions or the
916 * according cache file if exists.
917 *
918 * @param bool $allowCaching True, if reading compiled ext_tables file from cache is allowed
919 * @return Bootstrap
920 * @internal This is not a public API method, do not use in own extensions
921 */
922 public function loadExtensionTables($allowCaching = TRUE) {
923 Utility\ExtensionManagementUtility::loadBaseTca($allowCaching);
924 Utility\ExtensionManagementUtility::loadExtTables($allowCaching);
925 $this->executeExtTablesAdditionalFile();
926 $this->runExtTablesPostProcessingHooks();
927 return $this;
928 }
929
930 /**
931 * Execute TYPO3_extTableDef_script if defined and exists
932 *
933 * Note: For backwards compatibility some global variables are
934 * explicitly set as global to be used without $GLOBALS[] in
935 * the extension table script. It is discouraged to access variables like
936 * $TBE_MODULES directly, but we can not prohibit
937 * this without heavily breaking backwards compatibility.
938 *
939 * @TODO : We could write a scheduler / reports module or an update checker
940 * @TODO : It should be defined, which global arrays are ok to be manipulated
941 *
942 * @return void
943 */
944 protected function executeExtTablesAdditionalFile() {
945 // It is discouraged to use those global variables directly, but we
946 // can not prohibit this without breaking backwards compatibility
947 global $T3_SERVICES, $T3_VAR, $TYPO3_CONF_VARS;
948 global $TBE_MODULES, $TBE_MODULES_EXT, $TCA;
949 global $PAGES_TYPES, $TBE_STYLES, $FILEICONS;
950 global $_EXTKEY;
951 // Load additional ext tables script if the file exists
952 $extTablesFile = PATH_typo3conf . TYPO3_extTableDef_script;
953 if (file_exists($extTablesFile) && is_file($extTablesFile)) {
954 include $extTablesFile;
955 }
956 }
957
958 /**
959 * Check for registered ext tables hooks and run them
960 *
961 * @throws \UnexpectedValueException
962 * @return void
963 */
964 protected function runExtTablesPostProcessingHooks() {
965 if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['GLOBAL']['extTablesInclusion-PostProcessing'])) {
966 foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['GLOBAL']['extTablesInclusion-PostProcessing'] as $classReference) {
967 /** @var $hookObject \TYPO3\CMS\Core\Database\TableConfigurationPostProcessingHookInterface */
968 $hookObject = Utility\GeneralUtility::getUserObj($classReference);
969 if (!$hookObject instanceof \TYPO3\CMS\Core\Database\TableConfigurationPostProcessingHookInterface) {
970 throw new \UnexpectedValueException('$hookObject must implement interface TYPO3\\CMS\\Core\\Database\\TableConfigurationPostProcessingHookInterface', 1320585902);
971 }
972 $hookObject->processData();
973 }
974 }
975 }
976
977 /**
978 * Initialize sprite manager
979 *
980 * @return Bootstrap
981 * @internal This is not a public API method, do not use in own extensions
982 */
983 public function initializeSpriteManager() {
984 \TYPO3\CMS\Backend\Sprite\SpriteManager::initialize();
985 return $this;
986 }
987
988 /**
989 * Initialize backend user object in globals
990 *
991 * @return Bootstrap
992 * @internal This is not a public API method, do not use in own extensions
993 */
994 public function initializeBackendUser() {
995 /** @var $backendUser \TYPO3\CMS\Core\Authentication\BackendUserAuthentication */
996 $backendUser = Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Core\Authentication\BackendUserAuthentication::class);
997 $backendUser->warningEmail = $GLOBALS['TYPO3_CONF_VARS']['BE']['warning_email_addr'];
998 $backendUser->lockIP = $GLOBALS['TYPO3_CONF_VARS']['BE']['lockIP'];
999 $backendUser->auth_timeout_field = (int)$GLOBALS['TYPO3_CONF_VARS']['BE']['sessionTimeout'];
1000 $backendUser->OS = TYPO3_OS;
1001 if (TYPO3_REQUESTTYPE & TYPO3_REQUESTTYPE_CLI) {
1002 $backendUser->dontSetCookie = TRUE;
1003 }
1004 // The global must be available very early, because methods below
1005 // might trigger code which relies on it. See: #45625
1006 $GLOBALS['BE_USER'] = $backendUser;
1007 $backendUser->start();
1008 return $this;
1009 }
1010
1011 /**
1012 * Initializes and ensures authenticated access
1013 *
1014 * @internal This is not a public API method, do not use in own extensions
1015 * @return \TYPO3\CMS\Core\Core\Bootstrap
1016 */
1017 public function initializeBackendAuthentication() {
1018 $GLOBALS['BE_USER']->checkCLIuser();
1019 $GLOBALS['BE_USER']->backendCheckLogin();
1020 return $this;
1021 }
1022
1023 /**
1024 * Initialize language object
1025 *
1026 * @return Bootstrap
1027 * @internal This is not a public API method, do not use in own extensions
1028 */
1029 public function initializeLanguageObject() {
1030 /** @var $GLOBALS['LANG'] \TYPO3\CMS\Lang\LanguageService */
1031 $GLOBALS['LANG'] = Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Lang\LanguageService::class);
1032 $GLOBALS['LANG']->init($GLOBALS['BE_USER']->uc['lang']);
1033 return $this;
1034 }
1035
1036 /**
1037 * Throw away all output that may have happened during bootstrapping by weird extensions
1038 *
1039 * @return Bootstrap
1040 * @internal This is not a public API method, do not use in own extensions
1041 */
1042 public function endOutputBufferingAndCleanPreviousOutput() {
1043 ob_clean();
1044 return $this;
1045 }
1046
1047 /**
1048 * Initialize output compression if configured
1049 *
1050 * @return Bootstrap
1051 * @internal This is not a public API method, do not use in own extensions
1052 */
1053 public function initializeOutputCompression() {
1054 if (extension_loaded('zlib') && $GLOBALS['TYPO3_CONF_VARS']['BE']['compressionLevel']) {
1055 if (Utility\MathUtility::canBeInterpretedAsInteger($GLOBALS['TYPO3_CONF_VARS']['BE']['compressionLevel'])) {
1056 @ini_set('zlib.output_compression_level', $GLOBALS['TYPO3_CONF_VARS']['BE']['compressionLevel']);
1057 }
1058 ob_start('ob_gzhandler');
1059 }
1060 return $this;
1061 }
1062
1063 /**
1064 * Send HTTP headers if configured
1065 *
1066 * @return Bootstrap
1067 * @internal This is not a public API method, do not use in own extensions
1068 */
1069 public function sendHttpHeaders() {
1070 if (!empty($GLOBALS['TYPO3_CONF_VARS']['BE']['HTTP']['Response']['Headers']) && is_array($GLOBALS['TYPO3_CONF_VARS']['BE']['HTTP']['Response']['Headers'])) {
1071 foreach ($GLOBALS['TYPO3_CONF_VARS']['BE']['HTTP']['Response']['Headers'] as $header) {
1072 header($header);
1073 }
1074 }
1075 return $this;
1076 }
1077
1078 /**
1079 * Things that should be performed to shut down the framework.
1080 * This method is called in all important scripts for a clean
1081 * shut down of the system.
1082 *
1083 * @return Bootstrap
1084 * @internal This is not a public API method, do not use in own extensions
1085 */
1086 public function shutdown() {
1087 return $this;
1088 }
1089
1090 /**
1091 * Provides an instance of "template" for backend-modules to
1092 * work with.
1093 *
1094 * @return Bootstrap
1095 * @internal This is not a public API method, do not use in own extensions
1096 */
1097 public function initializeBackendTemplate() {
1098 $GLOBALS['TBE_TEMPLATE'] = Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Template\DocumentTemplate::class);
1099 return $this;
1100 }
1101
1102 }