‪TYPO3CMS  11.5
SystemEnvironmentBuilder.php
Go to the documentation of this file.
1 <?php
2 
3 /*
4  * This file is part of the TYPO3 CMS project.
5  *
6  * It is free software; you can redistribute it and/or modify it under
7  * the terms of the GNU General Public License, either version 2
8  * of the License, or any later version.
9  *
10  * For the full copyright and license information, please read the
11  * LICENSE.txt file that was distributed with this source code.
12  *
13  * The TYPO3 project - inspiring people to share!
14  */
15 
16 namespace ‪TYPO3\CMS\Core\Core;
17 
20 
41 {
43  public const ‪REQUESTTYPE_FE = 1;
45  public const ‪REQUESTTYPE_BE = 2;
47  public const ‪REQUESTTYPE_CLI = 4;
49  public const ‪REQUESTTYPE_AJAX = 8;
51  public const ‪REQUESTTYPE_INSTALL = 16;
52 
61  public static function ‪run(int $entryPointLevel = 0, int $requestType = self::REQUESTTYPE_FE)
62  {
65  ‪self::setRequestType($requestType | ($requestType === self::REQUESTTYPE_BE && (str_contains($_SERVER['REQUEST_URI'] ?? '', '/typo3/ajax/') || strpos($_REQUEST['route'] ?? '', '/ajax/') === 0) ? TYPO3_REQUESTTYPE_AJAX : 0));
66  ‪self::defineLegacyConstants($requestType === self::REQUESTTYPE_FE ? 'FE' : 'BE');
67  $scriptPath = ‪self::calculateScriptPath($entryPointLevel, $requestType);
68  $rootPath = ‪self::calculateRootPath($entryPointLevel, $requestType);
69 
72  ‪self::initializeEnvironment($requestType, $scriptPath, $rootPath);
73  }
74 
84  {
85  $applicationContext = getenv('TYPO3_CONTEXT') ?: (getenv('REDIRECT_TYPO3_CONTEXT') ?: (getenv('HTTP_TYPO3_CONTEXT') ?: 'Production'));
86  return new ‪ApplicationContext($applicationContext);
87  }
88 
92  protected static function ‪defineBaseConstants()
93  {
94  // A linefeed, a carriage return, a CR-LF combination
95  defined('LF') ?: define('LF', chr(10));
96  defined('CR') ?: define('CR', chr(13));
97  defined('CRLF') ?: define('CRLF', CR . LF);
98 
99  // A generic constant to state we are in TYPO3 scope. This is especially used in script files
100  // like ext_localconf.php that run in global scope without class encapsulation: "defined('TYPO3') or die();"
101  // This is a security measure to prevent script output if those files are located within document root and
102  // called directly without bootstrap and error handling setup.
103  defined('TYPO3') ?: define('TYPO3', true);
104 
105  // Relative path from document root to typo3/ directory, hardcoded to "typo3/"
106  if (!defined('TYPO3_mainDir')) {
107  define('TYPO3_mainDir', 'typo3/');
108  }
109  }
110 
120  protected static function ‪calculateScriptPath(int $entryPointLevel, int $requestType): string
121  {
122  $isCli = ‪self::isCliRequestType($requestType);
123  // Absolute path of the entry script that was called
124  $scriptPath = GeneralUtility::fixWindowsFilePath(self::getPathThisScript($isCli));
125  $rootPath = ‪self::getRootPathFromScriptPath($scriptPath, $entryPointLevel);
126  // Check if the root path has been set in the environment (e.g. by the composer installer)
127  if (getenv('TYPO3_PATH_ROOT')) {
128  if ($isCli && self::usesComposerClassLoading()) {
129  // $scriptPath is used for various path calculations based on the document root
130  // Therefore we assume it is always a subdirectory of the document root, which is not the case
131  // in composer mode on cli, as the binary is in the composer bin directory.
132  // Because of that, we enforce the document root path of this binary to be set
133  $scriptName = 'typo3/sysext/core/bin/typo3';
134  } else {
135  // Base the script path on the path taken from the environment
136  // to make relative path calculations work in case only one of both is symlinked
137  // or has the real path
138  $scriptName = ltrim(substr($scriptPath, strlen($rootPath)), '/');
139  }
140  $rootPath = rtrim(GeneralUtility::fixWindowsFilePath((string)getenv('TYPO3_PATH_ROOT')), '/');
141  $scriptPath = $rootPath . '/' . $scriptName;
142  }
143  return $scriptPath;
144  }
145 
160  protected static function ‪calculateRootPath(int $entryPointLevel, int $requestType): string
161  {
162  // Check if the root path has been set in the environment (e.g. by the composer installer)
163  if (getenv('TYPO3_PATH_ROOT')) {
164  return rtrim(GeneralUtility::fixWindowsFilePath((string)getenv('TYPO3_PATH_ROOT')), '/');
165  }
166  $isCli = ‪self::isCliRequestType($requestType);
167  // Absolute path of the entry script that was called
168  $scriptPath = GeneralUtility::fixWindowsFilePath(self::getPathThisScript($isCli));
169  return ‪self::getRootPathFromScriptPath($scriptPath, $entryPointLevel);
170  }
171 
175  protected static function ‪initializeGlobalVariables()
176  {
177  // Unset variable(s) in global scope (security issue #13959)
178  ‪$GLOBALS['T3_SERVICES'] = [];
179  }
180 
185  protected static function ‪initializeGlobalTimeTrackingVariables()
186  {
187  // EXEC_TIME is set so that the rest of the script has a common value for the script execution time
188  ‪$GLOBALS['EXEC_TIME'] = time();
189  // $ACCESS_TIME is a common time in minutes for access control
190  ‪$GLOBALS['ACCESS_TIME'] = ‪$GLOBALS['EXEC_TIME'] - ‪$GLOBALS['EXEC_TIME'] % 60;
191  // $SIM_EXEC_TIME is set to $EXEC_TIME but can be altered later in the script if we want to
192  // simulate another execution-time when selecting from eg. a database
193  ‪$GLOBALS['SIM_EXEC_TIME'] = ‪$GLOBALS['EXEC_TIME'];
194  // If $SIM_EXEC_TIME is changed this value must be set accordingly
195  ‪$GLOBALS['SIM_ACCESS_TIME'] = ‪$GLOBALS['ACCESS_TIME'];
196  }
197 
205  protected static function ‪initializeEnvironment(int $requestType, string $scriptPath, string $sitePath)
206  {
207  if (getenv('TYPO3_PATH_ROOT')) {
208  $rootPathFromEnvironment = rtrim(GeneralUtility::fixWindowsFilePath((string)getenv('TYPO3_PATH_ROOT')), '/');
209  if ($sitePath !== $rootPathFromEnvironment) {
210  // This means, that we re-initialized the environment during a single request
211  // This currently only happens in custom code or during functional testing
212  // Once the constants are removed, we might be able to remove this code here as well and directly pass an environment to the application
213  $scriptPath = $rootPathFromEnvironment . substr($scriptPath, strlen($sitePath));
214  $sitePath = $rootPathFromEnvironment;
215  }
216  }
217 
218  $projectRootPath = GeneralUtility::fixWindowsFilePath((string)getenv('TYPO3_PATH_APP'));
219  $isDifferentRootPath = ($projectRootPath && $projectRootPath !== $sitePath);
221  static::createApplicationContext(),
222  self::isCliRequestType($requestType),
223  static::usesComposerClassLoading(),
224  $isDifferentRootPath ? $projectRootPath : $sitePath,
225  $sitePath,
226  $isDifferentRootPath ? $projectRootPath . '/var' : $sitePath . '/typo3temp/var',
227  $isDifferentRootPath ? $projectRootPath . '/config' : $sitePath . '/typo3conf',
228  $scriptPath,
229  self::isRunningOnWindows() ? 'WINDOWS' : 'UNIX'
230  );
231  }
232 
236  protected static function ‪isRunningOnWindows(): bool
237  {
238  return stripos(PHP_OS, 'darwin') === false
239  && stripos(PHP_OS, 'cygwin') === false
240  && stripos(PHP_OS, 'win') !== false;
241  }
242 
258  protected static function ‪getPathThisScript(bool $isCli)
259  {
260  if ($isCli) {
262  }
264  }
265 
271  protected static function ‪getPathThisScriptNonCli()
272  {
274  throw new \Exception('TYPO3 does only support being used with cgi.fix_pathinfo=1 on CGI server APIs.', 1675108421);
275  }
276 
277  return $_SERVER['SCRIPT_FILENAME'];
278  }
279 
288  protected static function ‪getPathThisScriptCli()
289  {
290  // Possible relative path of the called script
291  $scriptPath = $_SERVER['argv'][0] ?? $_ENV['_'] ?? $_SERVER['_'];
292  // Find out if path is relative or not
293  $isRelativePath = false;
294  if (self::isRunningOnWindows()) {
295  if (!preg_match('/^([a-zA-Z]:)?\\\\/', $scriptPath)) {
296  $isRelativePath = true;
297  }
298  } elseif ($scriptPath[0] !== '/') {
299  $isRelativePath = true;
300  }
301  // Concatenate path to current working directory with relative path and remove "/./" constructs
302  if ($isRelativePath) {
303  $workingDirectory = $_SERVER['PWD'] ?? getcwd();
304  $scriptPath = $workingDirectory . '/' . preg_replace('/\\.\\//', '', $scriptPath);
305  }
306  return $scriptPath;
307  }
308 
324  protected static function ‪getRootPathFromScriptPath($scriptPath, $entryPointLevel)
325  {
326  $entryScriptDirectory = ‪PathUtility::dirnameDuringBootstrap($scriptPath);
327  if ($entryPointLevel > 0) {
328  [$rootPath] = ‪GeneralUtility::revExplode('/', $entryScriptDirectory, $entryPointLevel + 1);
329  } else {
330  $rootPath = $entryScriptDirectory;
331  }
332  return $rootPath;
333  }
334 
338  protected static function ‪usesComposerClassLoading(): bool
339  {
340  return defined('TYPO3_COMPOSER_MODE') && TYPO3_COMPOSER_MODE;
341  }
342 
349  protected static function ‪defineTypo3RequestTypes()
350  {
351  // Check one of the constants and return early if already defined,
352  // needed if multiple requests are handled in one process, for instance in functional testing.
353  if (defined('TYPO3_REQUESTTYPE_FE')) {
354  return;
355  }
357  define('TYPO3_REQUESTTYPE_FE', self::REQUESTTYPE_FE);
359  define('TYPO3_REQUESTTYPE_BE', self::REQUESTTYPE_BE);
361  define('TYPO3_REQUESTTYPE_CLI', self::REQUESTTYPE_CLI);
363  define('TYPO3_REQUESTTYPE_AJAX', self::REQUESTTYPE_AJAX);
365  define('TYPO3_REQUESTTYPE_INSTALL', self::REQUESTTYPE_INSTALL);
366  }
367 
374  protected static function ‪setRequestType(int $requestType)
375  {
376  // Return early if already defined,
377  // needed if multiple requests are handled in one process, for instance in functional testing.
378  if (defined('TYPO3_REQUESTTYPE')) {
379  return;
380  }
382  define('TYPO3_REQUESTTYPE', $requestType);
383  }
384 
391  protected static function ‪defineLegacyConstants(string $mode)
392  {
393  // Return early if already defined,
394  // needed if multiple requests are handled in one process, for instance in functional testing.
395  if (defined('TYPO3_MODE')) {
396  return;
397  }
399  define('TYPO3_MODE', $mode);
400  }
401 
409  protected static function ‪isCliRequestType(?int $requestType): bool
410  {
411  if ($requestType === null) {
412  $requestType = PHP_SAPI === 'cli' ? ‪self::REQUESTTYPE_CLI : ‪self::REQUESTTYPE_FE;
413  }
414 
415  return ($requestType & self::REQUESTTYPE_CLI) === ‪self::REQUESTTYPE_CLI;
416  }
417 }
‪TYPO3\CMS\Core\Core\SystemEnvironmentBuilder\calculateRootPath
‪static string calculateRootPath(int $entryPointLevel, int $requestType)
Definition: SystemEnvironmentBuilder.php:160
‪TYPO3\CMS\Core\Utility\GeneralUtility\revExplode
‪static list< string > revExplode($delimiter, $string, $count=0)
Definition: GeneralUtility.php:964
‪TYPO3\CMS\Core\Utility\PathUtility
Definition: PathUtility.php:25
‪TYPO3\CMS\Core\Core\Environment\isRunningOnCgiServer
‪static bool isRunningOnCgiServer()
Definition: Environment.php:338
‪TYPO3\CMS\Core\Core\SystemEnvironmentBuilder\isCliRequestType
‪static bool isCliRequestType(?int $requestType)
Definition: SystemEnvironmentBuilder.php:409
‪TYPO3\CMS\Core\Core\SystemEnvironmentBuilder\usesComposerClassLoading
‪static bool usesComposerClassLoading()
Definition: SystemEnvironmentBuilder.php:338
‪TYPO3\CMS\Core\Core\ApplicationContext
Definition: ApplicationContext.php:39
‪TYPO3\CMS\Core\Core\SystemEnvironmentBuilder\getRootPathFromScriptPath
‪static string getRootPathFromScriptPath($scriptPath, $entryPointLevel)
Definition: SystemEnvironmentBuilder.php:324
‪TYPO3\CMS\Core\Core\SystemEnvironmentBuilder\initializeGlobalTimeTrackingVariables
‪static initializeGlobalTimeTrackingVariables()
Definition: SystemEnvironmentBuilder.php:185
‪TYPO3\CMS\Core\Core\SystemEnvironmentBuilder
Definition: SystemEnvironmentBuilder.php:41
‪TYPO3\CMS\Core\Utility\PathUtility\dirnameDuringBootstrap
‪static string dirnameDuringBootstrap($path)
Definition: PathUtility.php:349
‪TYPO3\CMS\Core\Core\SystemEnvironmentBuilder\REQUESTTYPE_BE
‪const REQUESTTYPE_BE
Definition: SystemEnvironmentBuilder.php:45
‪TYPO3\CMS\Core\Core\SystemEnvironmentBuilder\defineTypo3RequestTypes
‪static defineTypo3RequestTypes()
Definition: SystemEnvironmentBuilder.php:349
‪TYPO3\CMS\Core\Core\SystemEnvironmentBuilder\createApplicationContext
‪static ApplicationContext createApplicationContext()
Definition: SystemEnvironmentBuilder.php:83
‪TYPO3\CMS\Core\Core\SystemEnvironmentBuilder\setRequestType
‪static setRequestType(int $requestType)
Definition: SystemEnvironmentBuilder.php:374
‪TYPO3\CMS\Core\Core\SystemEnvironmentBuilder\calculateScriptPath
‪static string calculateScriptPath(int $entryPointLevel, int $requestType)
Definition: SystemEnvironmentBuilder.php:120
‪TYPO3\CMS\Core\Core\SystemEnvironmentBuilder\getPathThisScriptNonCli
‪static string getPathThisScriptNonCli()
Definition: SystemEnvironmentBuilder.php:271
‪TYPO3\CMS\Core\Core\SystemEnvironmentBuilder\defineBaseConstants
‪static defineBaseConstants()
Definition: SystemEnvironmentBuilder.php:92
‪TYPO3\CMS\Core\Core\SystemEnvironmentBuilder\REQUESTTYPE_CLI
‪const REQUESTTYPE_CLI
Definition: SystemEnvironmentBuilder.php:47
‪TYPO3\CMS\Core\Core\Environment\usesCgiFixPathInfo
‪static usesCgiFixPathInfo()
Definition: Environment.php:343
‪TYPO3\CMS\Core\Core\SystemEnvironmentBuilder\initializeGlobalVariables
‪static initializeGlobalVariables()
Definition: SystemEnvironmentBuilder.php:175
‪TYPO3\CMS\Core\Core\SystemEnvironmentBuilder\isRunningOnWindows
‪static isRunningOnWindows()
Definition: SystemEnvironmentBuilder.php:236
‪TYPO3\CMS\Core\Core\Environment\initialize
‪static initialize(ApplicationContext $context, bool $cli, bool $composerMode, string $projectPath, string $publicPath, string $varPath, string $configPath, string $currentScript, string $os)
Definition: Environment.php:111
‪TYPO3\CMS\Core\Core\SystemEnvironmentBuilder\run
‪static run(int $entryPointLevel=0, int $requestType=self::REQUESTTYPE_FE)
Definition: SystemEnvironmentBuilder.php:61
‪TYPO3\CMS\Core\Core\SystemEnvironmentBuilder\getPathThisScriptCli
‪static string getPathThisScriptCli()
Definition: SystemEnvironmentBuilder.php:288
‪TYPO3\CMS\Core\Core\SystemEnvironmentBuilder\getPathThisScript
‪static string getPathThisScript(bool $isCli)
Definition: SystemEnvironmentBuilder.php:258
‪TYPO3\CMS\Core\Core\SystemEnvironmentBuilder\REQUESTTYPE_AJAX
‪const REQUESTTYPE_AJAX
Definition: SystemEnvironmentBuilder.php:49
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:25
‪TYPO3\CMS\Core\Core
Definition: ApplicationContext.php:16
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:50
‪TYPO3\CMS\Core\Core\SystemEnvironmentBuilder\REQUESTTYPE_FE
‪const REQUESTTYPE_FE
Definition: SystemEnvironmentBuilder.php:43
‪TYPO3\CMS\Core\Core\SystemEnvironmentBuilder\defineLegacyConstants
‪static defineLegacyConstants(string $mode)
Definition: SystemEnvironmentBuilder.php:391
‪TYPO3\CMS\Core\Core\SystemEnvironmentBuilder\REQUESTTYPE_INSTALL
‪const REQUESTTYPE_INSTALL
Definition: SystemEnvironmentBuilder.php:51
‪TYPO3\CMS\Core\Core\SystemEnvironmentBuilder\initializeEnvironment
‪static initializeEnvironment(int $requestType, string $scriptPath, string $sitePath)
Definition: SystemEnvironmentBuilder.php:205