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