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