eb4c6721a8a41e302a5378060aebbf73a8b1b0da
[Packages/TYPO3.CMS.git] / typo3 / sysext / core / Classes / Core / Bootstrap.php
1 <?php
2 namespace TYPO3\CMS\Core\Core;
3
4 /***************************************************************
5 * Copyright notice
6 *
7 * (c) 2012-2013 Christian Kuhn <lolli@schwarzbu.ch>
8 * All rights reserved
9 *
10 * This script is part of the TYPO3 project. The TYPO3 project is
11 * free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * The GNU General Public License can be found at
17 * http://www.gnu.org/copyleft/gpl.html.
18 * A copy is found in the textfile GPL.txt and important notices to the license
19 * from the author is found in LICENSE.txt distributed with these scripts.
20 *
21 *
22 * This script is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
26 *
27 * This copyright notice MUST APPEAR in all copies of the script!
28 ***************************************************************/
29
30 use \TYPO3\CMS\Core\Utility;
31
32 require __DIR__ . '/SystemEnvironmentBuilder.php';
33
34 /**
35 * This class encapsulates bootstrap related methods.
36 * It is required directly as the very first thing in entry scripts and
37 * used to define all base things like constants and pathes and so on.
38 *
39 * Most methods in this class have dependencies to each other. They can
40 * not be called in arbitrary order. The methods are ordered top down, so
41 * a method at the beginning has lower dependencies than a method further
42 * down. Do not fiddle with the load order in own scripts except you know
43 * exactly what you are doing!
44 *
45 * @author Christian Kuhn <lolli@schwarzbu.ch>
46 */
47 class Bootstrap {
48
49 /**
50 * @var \TYPO3\CMS\Core\Core\Bootstrap
51 */
52 static protected $instance = NULL;
53
54 /**
55 * Unique Request ID
56 *
57 * @var string
58 */
59 protected $requestId;
60
61 /**
62 * The application context
63 *
64 * @var \TYPO3\CMS\Core\Core\ApplicationContext
65 */
66 protected $applicationContext;
67
68 /**
69 * Disable direct creation of this object.
70 * Set unique requestId and the application context
71 *
72 * @var string Application context
73 */
74 protected function __construct($applicationContext) {
75 $this->requestId = uniqid();
76 $this->applicationContext = new ApplicationContext($applicationContext);
77 }
78
79 /**
80 * Disable direct cloning of this object.
81 */
82 protected function __clone() {
83
84 }
85
86 /**
87 * Return 'this' as singleton
88 *
89 * @return \TYPO3\CMS\Core\Core\Bootstrap
90 * @internal This is not a public API method, do not use in own extensions
91 */
92 static public function getInstance() {
93 if (is_null(self::$instance)) {
94 require_once(__DIR__ . '/ApplicationContext.php');
95 $applicationContext = trim(getenv('TYPO3_CONTEXT'), '"\' ') ? : 'Production';
96 self::$instance = new \TYPO3\CMS\Core\Core\Bootstrap($applicationContext);
97 }
98 return self::$instance;
99 }
100
101 /**
102 * Gets the request's unique ID
103 *
104 * @return string Unique request ID
105 * @internal This is not a public API method, do not use in own extensions
106 */
107 public function getRequestId() {
108 return $this->requestId;
109 }
110
111 /**
112 * Returns the application context this bootstrap was started in.
113 *
114 * @return \TYPO3\CMS\Core\Core\ApplicationContext The application context encapsulated in an object
115 * @internal This is not a public API method, do not use in own extensions.
116 * Use \TYPO3\CMS\Core\Utility\GeneralUtility::getApplicationContext() instead
117 */
118 public function getApplicationContext() {
119 return $this->applicationContext;
120 }
121
122 /**
123 * Prevent any unwanted output that may corrupt AJAX/compression.
124 * This does not interfere with "die()" or "echo"+"exit()" messages!
125 *
126 * @return \TYPO3\CMS\Core\Core\Bootstrap
127 * @internal This is not a public API method, do not use in own extensions
128 */
129 public function startOutputBuffering() {
130 ob_start();
131 return $this;
132 }
133
134 /**
135 * Run the base setup that checks server environment,
136 * determines pathes, populates base files and sets common configuration.
137 *
138 * Script execution will be aborted if something fails here.
139 *
140 * @param string $relativePathPart Relative path of the entry script back to document root
141 * @return \TYPO3\CMS\Core\Core\Bootstrap
142 * @internal This is not a public API method, do not use in own extensions
143 */
144 public function baseSetup($relativePathPart = '') {
145 \TYPO3\CMS\Core\Core\SystemEnvironmentBuilder::run($relativePathPart);
146 Utility\GeneralUtility::presetApplicationContext($this->applicationContext);
147 return $this;
148 }
149
150 /**
151 * Redirect to install tool if LocalConfiguration.php is missing.
152 *
153 * @param string $pathUpToDocumentRoot Can contain eg. '../' if called from a sub directory
154 * @return \TYPO3\CMS\Core\Core\Bootstrap
155 * @internal This is not a public API method, do not use in own extensions
156 */
157 public function redirectToInstallerIfLocalConfigurationFileDoesNotExist($pathUpToDocumentRoot = '') {
158 /** @var $configurationManager \TYPO3\CMS\Core\Configuration\ConfigurationManager */
159 $configurationManager = Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Configuration\\ConfigurationManager');
160 if (!file_exists($configurationManager->getLocalConfigurationFileLocation())) {
161 require_once __DIR__ . '/../Utility/HttpUtility.php';
162 Utility\HttpUtility::redirect($pathUpToDocumentRoot . 'typo3/sysext/install/Start/Install.php');
163 }
164 return $this;
165 }
166
167 /**
168 * Includes LocalConfiguration.php and sets several
169 * global settings depending on configuration.
170 *
171 * @param boolean $allowCaching Whether to allow caching - affects cache_core (autoloader)
172 * @return \TYPO3\CMS\Core\Core\Bootstrap
173 * @internal This is not a public API method, do not use in own extensions
174 */
175 public function loadConfigurationAndInitialize($allowCaching = TRUE) {
176 $bootstrap = $this->getInstance();
177
178 $bootstrap->populateLocalConfiguration();
179
180 if (!$allowCaching) {
181 $bootstrap->setCoreCacheToNullBackend();
182 }
183
184 $bootstrap->defineDatabaseConstants()
185 ->defineUserAgentConstant()
186 ->registerExtDirectComponents()
187 ->initializeCachingFramework()
188 ->registerAutoloader()
189 ->checkUtf8DatabaseSettingsOrDie()
190 ->transferDeprecatedCurlSettings()
191 ->setCacheHashOptions()
192 ->setDefaultTimezone()
193 ->initializeL10nLocales()
194 ->convertPageNotFoundHandlingToBoolean()
195 ->registerGlobalDebugFunctions()
196 // SwiftMailerAdapter is
197 // @deprecated since 6.1, will be removed two versions later - will be removed together with \TYPO3\CMS\Core\Utility\MailUtility::mail()
198 ->registerSwiftMailer()
199 ->configureExceptionHandling()
200 ->setMemoryLimit()
201 ->defineTypo3RequestTypes();
202 return $this;
203 }
204
205 /**
206 * Load TYPO3_LOADED_EXT and ext_localconf
207 *
208 * @param boolean $allowCaching
209 * @return \TYPO3\CMS\Core\Core\Bootstrap
210 * @internal This is not a public API method, do not use in own extensions
211 */
212 public function loadTypo3LoadedExtAndExtLocalconf($allowCaching = TRUE) {
213 $this->getInstance()
214 ->populateTypo3LoadedExtGlobal($allowCaching)
215 ->loadAdditionalConfigurationFromExtensions($allowCaching);
216 return $this;
217 }
218
219 /**
220 * Load TYPO3_LOADED_EXT, recreate class loader registry and load ext_localconf
221 *
222 * @return \TYPO3\CMS\Core\Core\Bootstrap
223 * @internal This is not a public API method, do not use in own extensions
224 */
225 public function reloadTypo3LoadedExtAndClassLoaderAndExtLocalconf() {
226 $bootstrap = $this->getInstance();
227 $bootstrap->populateTypo3LoadedExtGlobal(FALSE);
228 \TYPO3\CMS\Core\Core\ClassLoader::loadClassLoaderCache();
229 $bootstrap->loadAdditionalConfigurationFromExtensions(FALSE);
230 return $this;
231 }
232
233 /**
234 * Sets up additional configuration applied in all scopes
235 *
236 * @return \TYPO3\CMS\Core\Core\Bootstrap
237 * @internal This is not a public API method, do not use in own extensions
238 */
239 public function applyAdditionalConfigurationSettings() {
240 $this->getInstance()
241 ->initializeExceptionHandling()
242 ->setFinalCachingFrameworkCacheConfiguration()
243 ->defineLoggingAndExceptionConstants()
244 ->unsetReservedGlobalVariables();
245 return $this;
246 }
247
248 /**
249 * Throws an exception if no browser could be identified
250 *
251 * @return \TYPO3\CMS\Core\Core\Bootstrap
252 * @throws \RuntimeException
253 * @internal This is not a public API method, do not use in own extensions
254 */
255 public function checkValidBrowserOrDie() {
256 // Checks for proper browser
257 if (empty($GLOBALS['CLIENT']['BROWSER'])) {
258 throw new \RuntimeException('Browser Error: Your browser version looks incompatible with this TYPO3 version!', 1294587023);
259 }
260 return $this;
261 }
262
263 /**
264 * Populate the local configuration.
265 * Merge default TYPO3_CONF_VARS with content of typo3conf/LocalConfiguration.php,
266 * execute typo3conf/AdditionalConfiguration.php, define database related constants.
267 *
268 * @return \TYPO3\CMS\Core\Core\Bootstrap
269 * @internal This is not a public API method, do not use in own extensions
270 */
271 public function populateLocalConfiguration() {
272 /** @var $configurationManager \TYPO3\CMS\Core\Configuration\ConfigurationManager */
273 $configurationManager = Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Configuration\\ConfigurationManager');
274 $configurationManager->exportConfiguration();
275 return $this;
276 }
277
278 /**
279 * Set cache_core to null backend, effectively disabling eg. the autoloader cache
280 *
281 * @return \TYPO3\CMS\Core\Core\Bootstrap
282 * @internal This is not a public API method, do not use in own extensions
283 */
284 public function setCoreCacheToNullBackend() {
285 $GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['cache_core']['backend']
286 = 'TYPO3\\CMS\\Core\\Cache\\Backend\\NullBackend';
287 return $this;
288 }
289
290 /**
291 * Define database constants
292 *
293 * @return \TYPO3\CMS\Core\Core\Bootstrap
294 */
295 protected function defineDatabaseConstants() {
296 define('TYPO3_db', $GLOBALS['TYPO3_CONF_VARS']['DB']['database']);
297 define('TYPO3_db_username', $GLOBALS['TYPO3_CONF_VARS']['DB']['username']);
298 define('TYPO3_db_password', $GLOBALS['TYPO3_CONF_VARS']['DB']['password']);
299 define('TYPO3_db_host', $GLOBALS['TYPO3_CONF_VARS']['DB']['host']);
300 define('TYPO3_extTableDef_script',
301 isset($GLOBALS['TYPO3_CONF_VARS']['DB']['extTablesDefinitionScript'])
302 ? $GLOBALS['TYPO3_CONF_VARS']['DB']['extTablesDefinitionScript']
303 : 'extTables.php');
304 return $this;
305 }
306
307 /**
308 * Define user agent constant
309 *
310 * @return \TYPO3\CMS\Core\Core\Bootstrap
311 */
312 protected function defineUserAgentConstant() {
313 define('TYPO3_user_agent', 'User-Agent: ' . $GLOBALS['TYPO3_CONF_VARS']['HTTP']['userAgent']);
314 return $this;
315 }
316
317 /**
318 * Register default ExtDirect components
319 *
320 * @return \TYPO3\CMS\Core\Core\Bootstrap
321 */
322 protected function registerExtDirectComponents() {
323 if (TYPO3_MODE === 'BE') {
324 Utility\ExtensionManagementUtility::registerExtDirectComponent('TYPO3.Components.PageTree.DataProvider', 'TYPO3\\CMS\\Backend\\Tree\\Pagetree\\ExtdirectTreeDataProvider', 'web', 'user,group');
325 Utility\ExtensionManagementUtility::registerExtDirectComponent('TYPO3.Components.PageTree.Commands', 'TYPO3\\CMS\\Backend\\Tree\\Pagetree\\ExtdirectTreeCommands', 'web', 'user,group');
326 Utility\ExtensionManagementUtility::registerExtDirectComponent('TYPO3.Components.PageTree.ContextMenuDataProvider', 'TYPO3\\CMS\\Backend\\ContextMenu\\Pagetree\\Extdirect\\ContextMenuConfiguration', 'web', 'user,group');
327 Utility\ExtensionManagementUtility::registerExtDirectComponent('TYPO3.LiveSearchActions.ExtDirect', 'TYPO3\\CMS\\Backend\\Search\\LiveSearch\\ExtDirect\\LiveSearchDataProvider', 'web_list', 'user,group');
328 Utility\ExtensionManagementUtility::registerExtDirectComponent('TYPO3.BackendUserSettings.ExtDirect', 'TYPO3\\CMS\\Backend\\User\\ExtDirect\\BackendUserSettingsDataProvider');
329 if (Utility\ExtensionManagementUtility::isLoaded('context_help')) {
330 Utility\ExtensionManagementUtility::registerExtDirectComponent('TYPO3.CSH.ExtDirect', 'TYPO3\\CMS\\ContextHelp\\ExtDirect\\ContextHelpDataProvider');
331 }
332 Utility\ExtensionManagementUtility::registerExtDirectComponent('TYPO3.ExtDirectStateProvider.ExtDirect', 'TYPO3\\CMS\\Backend\\InterfaceState\\ExtDirect\\DataProvider');
333 Utility\ExtensionManagementUtility::registerExtDirectComponent(
334 'TYPO3.Components.DragAndDrop.CommandController',
335 Utility\ExtensionManagementUtility::extPath('backend') . 'Classes/View/PageLayout/Extdirect/ExtdirectPageCommands.php:TYPO3\\CMS\\Backend\\View\\PageLayout\\ExtDirect\\ExtdirectPageCommands', 'web', 'user,group'
336 );
337 }
338 return $this;
339 }
340
341 /**
342 * Initialize caching framework
343 *
344 * @return \TYPO3\CMS\Core\Core\Bootstrap
345 */
346 protected function initializeCachingFramework() {
347 \TYPO3\CMS\Core\Cache\Cache::initializeCachingFramework();
348 return $this;
349 }
350
351 /**
352 * Register autoloader
353 *
354 * @return \TYPO3\CMS\Core\Core\Bootstrap
355 */
356 protected function registerAutoloader() {
357 \TYPO3\CMS\Core\Core\ClassLoader::registerAutoloader();
358 return $this;
359 }
360
361 /**
362 * Checking for UTF-8 in the settings since TYPO3 4.5
363 *
364 * Since TYPO3 4.5, everything other than UTF-8 is deprecated.
365 *
366 * [SYS][setDBinit] is used to set the DB connection
367 * and both settings need to be adjusted for UTF-8 in order to work properly
368 *
369 * @return \TYPO3\CMS\Core\Core\Bootstrap
370 */
371 protected function checkUtf8DatabaseSettingsOrDie() {
372 if (isset($GLOBALS['TYPO3_CONF_VARS']['SYS']['setDBinit']) &&
373 $GLOBALS['TYPO3_CONF_VARS']['SYS']['setDBinit'] !== '-1' &&
374 preg_match('/SET NAMES [\'"]?utf8[\'"]?/i', $GLOBALS['TYPO3_CONF_VARS']['SYS']['setDBinit']) === FALSE &&
375 TYPO3_enterInstallScript !== '1') {
376
377 // Only accept "SET NAMES utf8" for this setting, otherwise die with a nice error
378 die('This TYPO3 installation is using the $GLOBALS[\'TYPO3_CONF_VARS\'][\'SYS\'][\'setDBinit\'] property with the following value:' . chr(10) .
379 $GLOBALS['TYPO3_CONF_VARS']['SYS']['setDBinit'] . chr(10) . chr(10) .
380 'It looks like UTF-8 is not used for this connection.' . chr(10) . chr(10) .
381 'Everything other than UTF-8 is unsupported since TYPO3 4.7.' . chr(10) .
382 'The DB, its connection and TYPO3 should be migrated to UTF-8 therefore. Please check your setup.'
383 );
384 } else {
385 $GLOBALS['TYPO3_CONF_VARS']['SYS']['setDBinit'] = 'SET NAMES utf8;';
386 }
387 return $this;
388 }
389
390 /**
391 * Parse old curl options and set new http ones instead
392 *
393 * @TODO : This code segment must still be finished
394 * @return \TYPO3\CMS\Core\Core\Bootstrap
395 */
396 protected function transferDeprecatedCurlSettings() {
397 if (!empty($GLOBALS['TYPO3_CONF_VARS']['SYS']['curlProxyServer'])) {
398 $proxyParts = Utility\GeneralUtility::revExplode(':', $GLOBALS['TYPO3_CONF_VARS']['SYS']['curlProxyServer'], 2);
399 $GLOBALS['TYPO3_CONF_VARS']['HTTP']['proxy_host'] = $proxyParts[0];
400 $GLOBALS['TYPO3_CONF_VARS']['HTTP']['proxy_port'] = $proxyParts[1];
401 }
402 if (!empty($GLOBALS['TYPO3_CONF_VARS']['SYS']['curlProxyUserPass'])) {
403 $userPassParts = explode(':', $GLOBALS['TYPO3_CONF_VARS']['SYS']['curlProxyUserPass'], 2);
404 $GLOBALS['TYPO3_CONF_VARS']['HTTP']['proxy_user'] = $userPassParts[0];
405 $GLOBALS['TYPO3_CONF_VARS']['HTTP']['proxy_password'] = $userPassParts[1];
406 }
407 return $this;
408 }
409
410 /**
411 * Set cacheHash options
412 *
413 * @return \TYPO3\CMS\Core\Core\Bootstrap
414 */
415 protected function setCacheHashOptions() {
416 $GLOBALS['TYPO3_CONF_VARS']['FE']['cacheHash'] = array(
417 'cachedParametersWhiteList' => Utility\GeneralUtility::trimExplode(',', $GLOBALS['TYPO3_CONF_VARS']['FE']['cHashOnlyForParameters'], TRUE),
418 'excludedParameters' => Utility\GeneralUtility::trimExplode(',', $GLOBALS['TYPO3_CONF_VARS']['FE']['cHashExcludedParameters'], TRUE),
419 'requireCacheHashPresenceParameters' => Utility\GeneralUtility::trimExplode(',', $GLOBALS['TYPO3_CONF_VARS']['FE']['cHashRequiredParameters'], TRUE)
420 );
421 if (trim($GLOBALS['TYPO3_CONF_VARS']['FE']['cHashExcludedParametersIfEmpty']) === '*') {
422 $GLOBALS['TYPO3_CONF_VARS']['FE']['cacheHash']['excludeAllEmptyParameters'] = TRUE;
423 } else {
424 $GLOBALS['TYPO3_CONF_VARS']['FE']['cacheHash']['excludedParametersIfEmpty'] = Utility\GeneralUtility::trimExplode(',', $GLOBALS['TYPO3_CONF_VARS']['FE']['cHashExcludedParametersIfEmpty'], TRUE);
425 }
426 return $this;
427 }
428
429 /**
430 * Set default timezone
431 *
432 * @return \TYPO3\CMS\Core\Core\Bootstrap
433 */
434 protected function setDefaultTimezone() {
435 $timeZone = $GLOBALS['TYPO3_CONF_VARS']['SYS']['phpTimeZone'];
436 if (empty($timeZone)) {
437 // Time zone from the server environment (TZ env or OS query)
438 $defaultTimeZone = @date_default_timezone_get();
439 if ($defaultTimeZone !== '') {
440 $timeZone = $defaultTimeZone;
441 } else {
442 $timeZone = 'UTC';
443 }
444 }
445 // Set default to avoid E_WARNINGs with PHP > 5.3
446 date_default_timezone_set($timeZone);
447 return $this;
448 }
449
450 /**
451 * Initialize the locales handled by TYPO3
452 *
453 * @return \TYPO3\CMS\Core\Core\Bootstrap
454 */
455 protected function initializeL10nLocales() {
456 \TYPO3\CMS\Core\Localization\Locales::initialize();
457 return $this;
458 }
459
460 /**
461 * Convert type of "pageNotFound_handling" setting in case it was written as a
462 * string (e.g. if edited in Install Tool)
463 *
464 * @TODO : Remove, if the Install Tool handles such data types correctly
465 * @return \TYPO3\CMS\Core\Core\Bootstrap
466 */
467 protected function convertPageNotFoundHandlingToBoolean() {
468 if (!strcasecmp($GLOBALS['TYPO3_CONF_VARS']['FE']['pageNotFound_handling'], 'TRUE')) {
469 $GLOBALS['TYPO3_CONF_VARS']['FE']['pageNotFound_handling'] = TRUE;
470 }
471 return $this;
472 }
473
474 /**
475 * Register xdebug(), debug(), debugBegin() and debugEnd() as global functions
476 *
477 * Note: Yes, this is possible in php! xdebug() is then a global function, even
478 * if registerGlobalDebugFunctions() is encapsulated in class scope.
479 *
480 * @return \TYPO3\CMS\Core\Core\Bootstrap
481 */
482 protected function registerGlobalDebugFunctions() {
483 require_once('GlobalDebugFunctions.php');
484 return $this;
485 }
486
487 /**
488 * Mail sending via Swift Mailer
489 *
490 * @return \TYPO3\CMS\Core\Core\Bootstrap
491 * @deprecated since 6.1, will be removed two versions later - will be removed together with \TYPO3\CMS\Core\Utility\MailUtility::mail()
492 */
493 protected function registerSwiftMailer() {
494 $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/utility/class.t3lib_utility_mail.php']['substituteMailDelivery'][] =
495 'TYPO3\\CMS\\Core\\Mail\\SwiftMailerAdapter';
496 return $this;
497 }
498
499 /**
500 * Configure and set up exception and error handling
501 *
502 * @return \TYPO3\CMS\Core\Core\Bootstrap
503 */
504 protected function configureExceptionHandling() {
505 $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['errors']['exceptionHandler'] = $GLOBALS['TYPO3_CONF_VARS']['SYS']['productionExceptionHandler'];
506 $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['errors']['exceptionalErrors'] = $GLOBALS['TYPO3_CONF_VARS']['SYS']['exceptionalErrors'];
507 // Turn error logging on/off.
508 if (($displayErrors = intval($GLOBALS['TYPO3_CONF_VARS']['SYS']['displayErrors'])) != '-1') {
509 // Special value "2" enables this feature only if $GLOBALS['TYPO3_CONF_VARS'][SYS][devIPmask] matches
510 if ($displayErrors == 2) {
511 if (Utility\GeneralUtility::cmpIP(Utility\GeneralUtility::getIndpEnv('REMOTE_ADDR'), $GLOBALS['TYPO3_CONF_VARS']['SYS']['devIPmask'])) {
512 $displayErrors = 1;
513 } else {
514 $displayErrors = 0;
515 }
516 }
517 if ($displayErrors == 0) {
518 $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['errors']['exceptionalErrors'] = 0;
519 }
520 if ($displayErrors == 1) {
521 $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['errors']['exceptionHandler'] = $GLOBALS['TYPO3_CONF_VARS']['SYS']['debugExceptionHandler'];
522 define('TYPO3_ERRORHANDLER_MODE', 'debug');
523 }
524 @ini_set('display_errors', $displayErrors);
525 } elseif (Utility\GeneralUtility::cmpIP(Utility\GeneralUtility::getIndpEnv('REMOTE_ADDR'), $GLOBALS['TYPO3_CONF_VARS']['SYS']['devIPmask'])) {
526 // With displayErrors = -1 (default), turn on debugging if devIPmask matches:
527 $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['errors']['exceptionHandler'] = $GLOBALS['TYPO3_CONF_VARS']['SYS']['debugExceptionHandler'];
528 }
529 return $this;
530 }
531
532 /**
533 * Set PHP memory limit depending on value of
534 * $GLOBALS['TYPO3_CONF_VARS']['SYS']['setMemoryLimit']
535 *
536 * @return \TYPO3\CMS\Core\Core\Bootstrap
537 */
538 protected function setMemoryLimit() {
539 if (intval($GLOBALS['TYPO3_CONF_VARS']['SYS']['setMemoryLimit']) > 16) {
540 @ini_set('memory_limit', (intval($GLOBALS['TYPO3_CONF_VARS']['SYS']['setMemoryLimit']) . 'm'));
541 }
542 return $this;
543 }
544
545 /**
546 * Define TYPO3_REQUESTTYPE* constants
547 * so devs exactly know what type of request it is
548 *
549 * @return \TYPO3\CMS\Core\Core\Bootstrap
550 */
551 protected function defineTypo3RequestTypes() {
552 define('TYPO3_REQUESTTYPE_FE', 1);
553 define('TYPO3_REQUESTTYPE_BE', 2);
554 define('TYPO3_REQUESTTYPE_CLI', 4);
555 define('TYPO3_REQUESTTYPE_AJAX', 8);
556 define('TYPO3_REQUESTTYPE_INSTALL', 16);
557 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));
558 return $this;
559 }
560
561 /**
562 * Set up $GLOBALS['TYPO3_LOADED_EXT'] array with basic information
563 * about extensions.
564 *
565 * @param boolean $allowCaching
566 * @return \TYPO3\CMS\Core\Core\Bootstrap
567 */
568 protected function populateTypo3LoadedExtGlobal($allowCaching = TRUE) {
569 $GLOBALS['TYPO3_LOADED_EXT'] = Utility\ExtensionManagementUtility::loadTypo3LoadedExtensionInformation($allowCaching);
570 return $this;
571 }
572
573 /**
574 * Load extension configuration files (ext_localconf.php)
575 *
576 * The ext_localconf.php files in extensions are meant to make changes
577 * to the global $TYPO3_CONF_VARS configuration array.
578 *
579 * @param boolean $allowCaching
580 * @return \TYPO3\CMS\Core\Core\Bootstrap
581 */
582 protected function loadAdditionalConfigurationFromExtensions($allowCaching = TRUE) {
583 Utility\ExtensionManagementUtility::loadExtLocalconf($allowCaching);
584 return $this;
585 }
586
587 /**
588 * Initialize exception handling
589 *
590 * @return \TYPO3\CMS\Core\Core\Bootstrap
591 */
592 protected function initializeExceptionHandling() {
593 if ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['errors']['exceptionHandler'] !== '') {
594 if ($GLOBALS['TYPO3_CONF_VARS']['SYS']['errorHandler'] !== '') {
595 // Register an error handler for the given errorHandlerErrors
596 $errorHandler = Utility\GeneralUtility::makeInstance($GLOBALS['TYPO3_CONF_VARS']['SYS']['errorHandler'], $GLOBALS['TYPO3_CONF_VARS']['SYS']['errorHandlerErrors']);
597 // Set errors which will be converted in an exception
598 $errorHandler->setExceptionalErrors($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['errors']['exceptionalErrors']);
599 }
600 // Instantiate the exception handler once to make sure object is registered
601 // @TODO: Figure out if this is really needed
602 Utility\GeneralUtility::makeInstance($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['errors']['exceptionHandler']);
603 }
604 return $this;
605 }
606
607 /**
608 * Extensions may register new caches, so we set the
609 * global cache array to the manager again at this point
610 *
611 * @return \TYPO3\CMS\Core\Core\Bootstrap
612 */
613 protected function setFinalCachingFrameworkCacheConfiguration() {
614 $GLOBALS['typo3CacheManager']->setCacheConfigurations($GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']);
615 return $this;
616 }
617
618 /**
619 * Define logging and exception constants
620 *
621 * @return \TYPO3\CMS\Core\Core\Bootstrap
622 */
623 protected function defineLoggingAndExceptionConstants() {
624 define('TYPO3_DLOG', $GLOBALS['TYPO3_CONF_VARS']['SYS']['enable_DLOG']);
625 define('TYPO3_ERROR_DLOG', $GLOBALS['TYPO3_CONF_VARS']['SYS']['enable_errorDLOG']);
626 define('TYPO3_EXCEPTION_DLOG', $GLOBALS['TYPO3_CONF_VARS']['SYS']['enable_exceptionDLOG']);
627 return $this;
628 }
629
630 /**
631 * Unsetting reserved global variables:
632 * Those are set in "ext:core/ext_tables.php" file:
633 *
634 * @return \TYPO3\CMS\Core\Core\Bootstrap
635 */
636 protected function unsetReservedGlobalVariables() {
637 unset($GLOBALS['PAGES_TYPES']);
638 unset($GLOBALS['TCA']);
639 unset($GLOBALS['TBE_MODULES']);
640 unset($GLOBALS['TBE_STYLES']);
641 unset($GLOBALS['FILEICONS']);
642 // Those set in init.php:
643 unset($GLOBALS['WEBMOUNTS']);
644 unset($GLOBALS['FILEMOUNTS']);
645 unset($GLOBALS['BE_USER']);
646 // Those set otherwise:
647 unset($GLOBALS['TBE_MODULES_EXT']);
648 unset($GLOBALS['TCA_DESCR']);
649 unset($GLOBALS['LOCAL_LANG']);
650 unset($GLOBALS['TYPO3_AJAX']);
651 return $this;
652 }
653
654 /**
655 * Initialize database connection in $GLOBALS and connect if requested
656 *
657 * @return \TYPO3\CMS\Core\Core\Bootstrap
658 * @internal This is not a public API method, do not use in own extensions
659 */
660 public function initializeTypo3DbGlobal() {
661 /** @var $databaseConnection \TYPO3\CMS\Core\Database\DatabaseConnection */
662 $databaseConnection = Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Database\\DatabaseConnection');
663 $databaseConnection->setDatabaseName(TYPO3_db);
664 $databaseConnection->setDatabaseUsername(TYPO3_db_username);
665 $databaseConnection->setDatabasePassword(TYPO3_db_password);
666
667 $databaseHost = TYPO3_db_host;
668 if (isset($GLOBALS['TYPO3_CONF_VARS']['DB']['port'])) {
669 $databaseConnection->setDatabasePort($GLOBALS['TYPO3_CONF_VARS']['DB']['port']);
670 } elseif (strpos($databaseHost, ':') > 0) {
671 // @TODO: Find a way to handle this case in the install tool and drop this
672 list($databaseHost, $databasePort) = explode(':', $databaseHost);
673 $databaseConnection->setDatabasePort($databasePort);
674 }
675 if (isset($GLOBALS['TYPO3_CONF_VARS']['DB']['socket'])) {
676 $databaseConnection->setDatabaseSocket($GLOBALS['TYPO3_CONF_VARS']['DB']['socket']);
677 }
678 $databaseConnection->setDatabaseHost($databaseHost);
679
680 $databaseConnection->debugOutput = $GLOBALS['TYPO3_CONF_VARS']['SYS']['sqlDebug'];
681
682 if (
683 isset($GLOBALS['TYPO3_CONF_VARS']['SYS']['no_pconnect'])
684 && !$GLOBALS['TYPO3_CONF_VARS']['SYS']['no_pconnect']
685 ) {
686 $databaseConnection->setPersistentDatabaseConnection(TRUE);
687 }
688
689 $isDatabaseHostLocalHost = $databaseHost === 'localhost' || $databaseHost === '127.0.0.1' || $databaseHost === '::1';
690 if (
691 isset($GLOBALS['TYPO3_CONF_VARS']['SYS']['dbClientCompress'])
692 && $GLOBALS['TYPO3_CONF_VARS']['SYS']['dbClientCompress']
693 && !$isDatabaseHostLocalHost
694 ) {
695 $databaseConnection->setConnectionCompression(TRUE);
696 }
697
698 if (!empty($GLOBALS['TYPO3_CONF_VARS']['SYS']['setDBinit'])) {
699 $commandsAfterConnect = \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(
700 LF,
701 str_replace('\' . LF . \'', LF, $GLOBALS['TYPO3_CONF_VARS']['SYS']['setDBinit']),
702 TRUE
703 );
704 $databaseConnection->setInitializeCommandsAfterConnect($commandsAfterConnect);
705 }
706
707 $GLOBALS['TYPO3_DB'] = $databaseConnection;
708
709 return $this;
710 }
711
712 /**
713 * Check adminOnly configuration variable and redirects
714 * to an URL in file typo3conf/LOCK_BACKEND or exit the script
715 *
716 * @throws \RuntimeException
717 * @return \TYPO3\CMS\Core\Core\Bootstrap
718 * @internal This is not a public API method, do not use in own extensions
719 */
720 public function checkLockedBackendAndRedirectOrDie() {
721 if ($GLOBALS['TYPO3_CONF_VARS']['BE']['adminOnly'] < 0) {
722 throw new \RuntimeException('TYPO3 Backend locked: Backend and Install Tool are locked for maintenance. [BE][adminOnly] is set to "' . intval($GLOBALS['TYPO3_CONF_VARS']['BE']['adminOnly']) . '".', 1294586847);
723 }
724 if (@is_file((PATH_typo3conf . 'LOCK_BACKEND'))) {
725 if (TYPO3_PROCEED_IF_NO_USER === 2) {
726
727 } else {
728 $fileContent = Utility\GeneralUtility::getUrl(PATH_typo3conf . 'LOCK_BACKEND');
729 if ($fileContent) {
730 header('Location: ' . $fileContent);
731 } else {
732 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);
733 }
734 die;
735 }
736 }
737 return $this;
738 }
739
740 /**
741 * Compare client IP with IPmaskList and exit the script run
742 * if the client is not allowed to access the backend
743 *
744 * @return \TYPO3\CMS\Core\Core\Bootstrap
745 * @internal This is not a public API method, do not use in own extensions
746 */
747 public function checkBackendIpOrDie() {
748 if (trim($GLOBALS['TYPO3_CONF_VARS']['BE']['IPmaskList'])) {
749 if (!Utility\GeneralUtility::cmpIP(Utility\GeneralUtility::getIndpEnv('REMOTE_ADDR'), $GLOBALS['TYPO3_CONF_VARS']['BE']['IPmaskList'])) {
750 // Send Not Found header - if the webserver can make use of it
751 header('Status: 404 Not Found');
752 // Just point us away from here...
753 header('Location: http://');
754 // ... and exit good!
755 die;
756 }
757 }
758 return $this;
759 }
760
761 /**
762 * Check lockSSL configuration variable and redirect
763 * to https version of the backend if needed
764 *
765 * @return \TYPO3\CMS\Core\Core\Bootstrap
766 * @internal This is not a public API method, do not use in own extensions
767 */
768 public function checkSslBackendAndRedirectIfNeeded() {
769 if (intval($GLOBALS['TYPO3_CONF_VARS']['BE']['lockSSL'])) {
770 if (intval($GLOBALS['TYPO3_CONF_VARS']['BE']['lockSSLPort'])) {
771 $sslPortSuffix = ':' . intval($GLOBALS['TYPO3_CONF_VARS']['BE']['lockSSLPort']);
772 } else {
773 $sslPortSuffix = '';
774 }
775 if ($GLOBALS['TYPO3_CONF_VARS']['BE']['lockSSL'] == 3) {
776 $requestStr = substr(Utility\GeneralUtility::getIndpEnv('TYPO3_REQUEST_SCRIPT'), strlen(Utility\GeneralUtility::getIndpEnv('TYPO3_SITE_URL') . TYPO3_mainDir));
777 if ($requestStr === 'index.php' && !Utility\GeneralUtility::getIndpEnv('TYPO3_SSL')) {
778 list(, $url) = explode('://', Utility\GeneralUtility::getIndpEnv('TYPO3_REQUEST_URL'), 2);
779 list($server, $address) = explode('/', $url, 2);
780 header('Location: https://' . $server . $sslPortSuffix . '/' . $address);
781 die;
782 }
783 } elseif (!Utility\GeneralUtility::getIndpEnv('TYPO3_SSL')) {
784 if (intval($GLOBALS['TYPO3_CONF_VARS']['BE']['lockSSL']) === 2) {
785 list(, $url) = explode('://', Utility\GeneralUtility::getIndpEnv('TYPO3_SITE_URL') . TYPO3_mainDir, 2);
786 list($server, $address) = explode('/', $url, 2);
787 header('Location: https://' . $server . $sslPortSuffix . '/' . $address);
788 } else {
789 // Send Not Found header - if the webserver can make use of it...
790 header('Status: 404 Not Found');
791 // Just point us away from here...
792 header('Location: http://');
793 }
794 // ... and exit good!
795 die;
796 }
797 }
798 return $this;
799 }
800
801 /**
802 * Load TCA for frontend
803 *
804 * This method is *only* executed in frontend scope. The idea is to execute the
805 * whole TCA and ext_tables (which manipulate TCA) on first frontend access,
806 * and then cache the full TCA on disk to be used for the next run again.
807 *
808 * This way, ext_tables.php ist not executed every time, but $GLOBALS['TCA']
809 * is still always there.
810 *
811 * @return \TYPO3\CMS\Core\Core\Bootstrap
812 * @internal This is not a public API method, do not use in own extensions
813 */
814 public function loadCachedTca() {
815 $cacheIdentifier = 'tca_fe_' . sha1((TYPO3_version . PATH_site . 'tca_fe'));
816 /** @var $codeCache \TYPO3\CMS\Core\Cache\Frontend\PhpFrontend */
817 $codeCache = $GLOBALS['typo3CacheManager']->getCache('cache_core');
818 if ($codeCache->has($cacheIdentifier)) {
819 $codeCache->requireOnce($cacheIdentifier);
820 } else {
821 $this->loadExtensionTables(TRUE);
822 $phpCodeToCache = '$GLOBALS[\'TCA\'] = ' . var_export($GLOBALS['TCA'], TRUE) . ';';
823 $codeCache->set($cacheIdentifier, $phpCodeToCache);
824 }
825 return $this;
826 }
827
828 /**
829 * Load ext_tables and friends.
830 *
831 * This will mainly set up $TCA and several other global arrays
832 * through API's like extMgm.
833 * Executes ext_tables.php files of loaded extensions or the
834 * according cache file if exists.
835 *
836 * @param boolean $allowCaching True, if reading compiled ext_tables file from cache is allowed
837 * @return \TYPO3\CMS\Core\Core\Bootstrap
838 * @internal This is not a public API method, do not use in own extensions
839 */
840 public function loadExtensionTables($allowCaching = TRUE) {
841 Utility\ExtensionManagementUtility::loadBaseTca($allowCaching);
842 Utility\ExtensionManagementUtility::loadExtTables($allowCaching);
843 $this->executeExtTablesAdditionalFile();
844 $this->runExtTablesPostProcessingHooks();
845 return $this;
846 }
847
848 /**
849 * Execute TYPO3_extTableDef_script if defined and exists
850 *
851 * Note: For backwards compatibility some global variables are
852 * explicitly set as global to be used without $GLOBALS[] in
853 * the extension table script. It is discouraged to access variables like
854 * $TBE_MODULES directly, but we can not prohibit
855 * this without heavily breaking backwards compatibility.
856 *
857 * @TODO : We could write a scheduler / reports module or an update checker
858 * @TODO : It should be defined, which global arrays are ok to be manipulated
859 *
860 * @return void
861 */
862 protected function executeExtTablesAdditionalFile() {
863 // It is discouraged to use those global variables directly, but we
864 // can not prohibit this without breaking backwards compatibility
865 global $T3_SERVICES, $T3_VAR, $TYPO3_CONF_VARS;
866 global $TBE_MODULES, $TBE_MODULES_EXT, $TCA;
867 global $PAGES_TYPES, $TBE_STYLES, $FILEICONS;
868 global $_EXTKEY;
869 // Load additional ext tables script if the file exists
870 $extTablesFile = PATH_typo3conf . TYPO3_extTableDef_script;
871 if (file_exists($extTablesFile) && is_file($extTablesFile)) {
872 include $extTablesFile;
873 }
874
875 // Apply TCA onto tables to be categorized
876 \TYPO3\CMS\Core\Category\CategoryRegistry::getInstance()->applyTca();
877 }
878
879 /**
880 * Check for registered ext tables hooks and run them
881 *
882 * @throws \UnexpectedValueException
883 * @return void
884 */
885 protected function runExtTablesPostProcessingHooks() {
886 if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['GLOBAL']['extTablesInclusion-PostProcessing'])) {
887 foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['GLOBAL']['extTablesInclusion-PostProcessing'] as $classReference) {
888 /** @var $hookObject \TYPO3\CMS\Core\Database\TableConfigurationPostProcessingHookInterface */
889 $hookObject = Utility\GeneralUtility::getUserObj($classReference);
890 if (!$hookObject instanceof \TYPO3\CMS\Core\Database\TableConfigurationPostProcessingHookInterface) {
891 throw new \UnexpectedValueException('$hookObject must implement interface TYPO3\\CMS\\Core\\Database\\TableConfigurationPostProcessingHookInterface', 1320585902);
892 }
893 $hookObject->processData();
894 }
895 }
896 }
897
898 /**
899 * Initialize sprite manager
900 *
901 * @return \TYPO3\CMS\Core\Core\Bootstrap
902 * @internal This is not a public API method, do not use in own extensions
903 */
904 public function initializeSpriteManager() {
905 \TYPO3\CMS\Backend\Sprite\SpriteManager::initialize();
906 return $this;
907 }
908
909 /**
910 * Initialize backend user object in globals
911 *
912 * @return \TYPO3\CMS\Core\Core\Bootstrap
913 * @internal This is not a public API method, do not use in own extensions
914 */
915 public function initializeBackendUser() {
916 /** @var $backendUser \TYPO3\CMS\Core\Authentication\BackendUserAuthentication */
917 $backendUser = Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Authentication\\BackendUserAuthentication');
918 $backendUser->warningEmail = $GLOBALS['TYPO3_CONF_VARS']['BE']['warning_email_addr'];
919 $backendUser->lockIP = $GLOBALS['TYPO3_CONF_VARS']['BE']['lockIP'];
920 $backendUser->auth_timeout_field = intval($GLOBALS['TYPO3_CONF_VARS']['BE']['sessionTimeout']);
921 $backendUser->OS = TYPO3_OS;
922 if (TYPO3_REQUESTTYPE & TYPO3_REQUESTTYPE_CLI) {
923 $backendUser->dontSetCookie = TRUE;
924 }
925 // The global must be available very early, because methods below
926 // might trigger code which relies on it. See: #45625
927 $GLOBALS['BE_USER'] = $backendUser;
928 $backendUser->start();
929 $backendUser->checkCLIuser();
930 $backendUser->backendCheckLogin();
931 return $this;
932 }
933
934 /**
935 * Initialize backend user mount points
936 *
937 * @return \TYPO3\CMS\Core\Core\Bootstrap
938 * @internal This is not a public API method, do not use in own extensions
939 */
940 public function initializeBackendUserMounts() {
941 // Includes deleted mount pages as well! @TODO: Figure out why ...
942 $GLOBALS['WEBMOUNTS'] = $GLOBALS['BE_USER']->returnWebmounts();
943 $GLOBALS['BE_USER']->getFileStorages();
944 $GLOBALS['FILEMOUNTS'] = $GLOBALS['BE_USER']->groupData['filemounts'];
945 return $this;
946 }
947
948 /**
949 * Initialize language object
950 *
951 * @return \TYPO3\CMS\Core\Core\Bootstrap
952 * @internal This is not a public API method, do not use in own extensions
953 */
954 public function initializeLanguageObject() {
955 /** @var $GLOBALS['LANG'] \TYPO3\CMS\Lang\LanguageService */
956 $GLOBALS['LANG'] = Utility\GeneralUtility::makeInstance('TYPO3\CMS\Lang\LanguageService');
957 $GLOBALS['LANG']->init($GLOBALS['BE_USER']->uc['lang']);
958 return $this;
959 }
960
961 /**
962 * Throw away all output that may have happened during bootstrapping by weird extensions
963 *
964 * @return \TYPO3\CMS\Core\Core\Bootstrap
965 * @internal This is not a public API method, do not use in own extensions
966 */
967 public function endOutputBufferingAndCleanPreviousOutput() {
968 ob_clean();
969 return $this;
970 }
971
972 /**
973 * Initialize output compression if configured
974 *
975 * @return \TYPO3\CMS\Core\Core\Bootstrap
976 * @internal This is not a public API method, do not use in own extensions
977 */
978 public function initializeOutputCompression() {
979 if (extension_loaded('zlib') && $GLOBALS['TYPO3_CONF_VARS']['BE']['compressionLevel']) {
980 if (Utility\MathUtility::canBeInterpretedAsInteger($GLOBALS['TYPO3_CONF_VARS']['BE']['compressionLevel'])) {
981 @ini_set('zlib.output_compression_level', $GLOBALS['TYPO3_CONF_VARS']['BE']['compressionLevel']);
982 }
983 ob_start('ob_gzhandler');
984 }
985 return $this;
986 }
987
988 /**
989 * Initialize module menu object
990 *
991 * @return \TYPO3\CMS\Core\Core\Bootstrap
992 * @internal This is not a public API method, do not use in own extensions
993 */
994 public function initializeModuleMenuObject() {
995 /** @var $moduleMenuUtility \TYPO3\CMS\Backend\Module\ModuleController */
996 $moduleMenuUtility = Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Backend\\Module\\ModuleController');
997 $moduleMenuUtility->createModuleMenu();
998 return $this;
999 }
1000
1001 /**
1002 * Things that should be performed to shut down the framework.
1003 * This method is called in all important scripts for a clean
1004 * shut down of the system.
1005 *
1006 * @return \TYPO3\CMS\Core\Core\Bootstrap
1007 * @internal This is not a public API method, do not use in own extensions
1008 */
1009 public function shutdown() {
1010 \TYPO3\CMS\Core\Core\ClassLoader::unregisterAutoloader();
1011 return $this;
1012 }
1013
1014 /**
1015 * Provides an instance of "template" for backend-modules to
1016 * work with.
1017 *
1018 * @return \TYPO3\CMS\Core\Core\Bootstrap
1019 * @internal This is not a public API method, do not use in own extensions
1020 */
1021 public function initializeBackendTemplate() {
1022 $GLOBALS['TBE_TEMPLATE'] = Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Backend\\Template\\DocumentTemplate');
1023 return $this;
1024 }
1025 }