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