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