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