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