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