‪TYPO3CMS  ‪main
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 
60  public static function ‪run(int $entryPointLevel = 0, int $requestType = self::REQUESTTYPE_FE)
61  {
63  $scriptPath = ‪self::calculateScriptPath($entryPointLevel, $requestType);
64  $rootPath = ‪self::calculateRootPath($entryPointLevel, $requestType);
65 
68  ‪self::initializeEnvironment($requestType, $scriptPath, $rootPath);
69  }
70 
79  {
80  $applicationContext = getenv('TYPO3_CONTEXT') ?: (getenv('REDIRECT_TYPO3_CONTEXT') ?: (getenv('HTTP_TYPO3_CONTEXT') ?: 'Production'));
81  return new ‪ApplicationContext($applicationContext);
82  }
83 
87  protected static function ‪defineBaseConstants()
88  {
89  // A linefeed, a carriage return, a CR-LF combination
90  defined('LF') ?: define('LF', chr(10));
91  defined('CR') ?: define('CR', chr(13));
92  defined('CRLF') ?: define('CRLF', CR . LF);
93 
94  // A generic constant to state we are in TYPO3 scope. This is especially used in script files
95  // like ext_localconf.php that run in global scope without class encapsulation: "defined('TYPO3') or die();"
96  // This is a security measure to prevent script output if those files are located within document root and
97  // called directly without bootstrap and error handling setup.
98  defined('TYPO3') ?: define('TYPO3', true);
99 
100  // Relative path from document root to typo3/ directory, hardcoded to "typo3/"
101  // @deprecated: will be removed in TYPO3 v13.0
102  if (!defined('TYPO3_mainDir')) {
103  define('TYPO3_mainDir', 'typo3/');
104  }
105  }
106 
115  protected static function ‪calculateScriptPath(int $entryPointLevel, int $requestType): string
116  {
117  $isCli = ‪self::isCliRequestType($requestType);
118  // Absolute path of the entry script that was called
119  $scriptPath = GeneralUtility::fixWindowsFilePath(self::getPathThisScript($isCli));
120  $rootPath = ‪self::getRootPathFromScriptPath($scriptPath, $entryPointLevel);
121  // Check if the root path has been set in the environment (e.g. by the composer installer)
122  if (getenv('TYPO3_PATH_ROOT')) {
123  if ($isCli && self::usesComposerClassLoading()) {
124  // $scriptPath is used for various path calculations based on the document root
125  // Therefore we assume it is always a subdirectory of the document root, which is not the case
126  // in composer mode on cli, as the binary is in the composer bin directory.
127  // Because of that, we enforce the document root path of this binary to be set
128  $scriptName = 'typo3/sysext/core/bin/typo3';
129  } else {
130  // Base the script path on the path taken from the environment
131  // to make relative path calculations work in case only one of both is symlinked
132  // or has the real path
133  $scriptName = ltrim(substr($scriptPath, strlen($rootPath)), '/');
134  }
135  $rootPath = rtrim(GeneralUtility::fixWindowsFilePath((string)getenv('TYPO3_PATH_ROOT')), '/');
136  $scriptPath = $rootPath . '/' . $scriptName;
137  }
138  return $scriptPath;
139  }
140 
155  protected static function ‪calculateRootPath(int $entryPointLevel, int $requestType): string
156  {
157  // Check if the root path has been set in the environment (e.g. by the composer installer)
158  if (getenv('TYPO3_PATH_ROOT')) {
159  return rtrim(GeneralUtility::fixWindowsFilePath((string)getenv('TYPO3_PATH_ROOT')), '/');
160  }
161  $isCli = ‪self::isCliRequestType($requestType);
162  // Absolute path of the entry script that was called
163  $scriptPath = GeneralUtility::fixWindowsFilePath(self::getPathThisScript($isCli));
164  return ‪self::getRootPathFromScriptPath($scriptPath, $entryPointLevel);
165  }
166 
170  protected static function ‪initializeGlobalVariables()
171  {
172  // Unset variable(s) in global scope (security issue #13959)
173  ‪$GLOBALS['T3_SERVICES'] = [];
182  ‪$GLOBALS['TBE_STYLES'] = [];
183  }
184 
189  protected static function ‪initializeGlobalTimeTrackingVariables()
190  {
191  // EXEC_TIME is set so that the rest of the script has a common value for the script execution time
192  ‪$GLOBALS['EXEC_TIME'] = time();
193  // $ACCESS_TIME is a common time in minutes for access control
194  ‪$GLOBALS['ACCESS_TIME'] = ‪$GLOBALS['EXEC_TIME'] - ‪$GLOBALS['EXEC_TIME'] % 60;
195  // $SIM_EXEC_TIME is set to $EXEC_TIME but can be altered later in the script if we want to
196  // simulate another execution-time when selecting from eg. a database
197  ‪$GLOBALS['SIM_EXEC_TIME'] = ‪$GLOBALS['EXEC_TIME'];
198  // If $SIM_EXEC_TIME is changed this value must be set accordingly
199  ‪$GLOBALS['SIM_ACCESS_TIME'] = ‪$GLOBALS['ACCESS_TIME'];
200  }
201 
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 
335  protected static function ‪usesComposerClassLoading(): bool
336  {
337  return defined('TYPO3_COMPOSER_MODE') && TYPO3_COMPOSER_MODE;
338  }
339 
344  protected static function ‪isCliRequestType(?int $requestType): bool
345  {
346  if ($requestType === null) {
347  $requestType = PHP_SAPI === 'cli' ? ‪self::REQUESTTYPE_CLI : ‪self::REQUESTTYPE_FE;
348  }
349 
350  return ($requestType & self::REQUESTTYPE_CLI) === ‪self::REQUESTTYPE_CLI;
351  }
352 }
‪TYPO3\CMS\Core\Core\SystemEnvironmentBuilder\calculateRootPath
‪static string calculateRootPath(int $entryPointLevel, int $requestType)
Definition: SystemEnvironmentBuilder.php:155
‪TYPO3\CMS\Core\Utility\PathUtility
Definition: PathUtility.php:27
‪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:189
‪TYPO3\CMS\Core\Core\SystemEnvironmentBuilder
Definition: SystemEnvironmentBuilder.php:41
‪TYPO3\CMS\Core\Core\SystemEnvironmentBuilder\REQUESTTYPE_BE
‪const REQUESTTYPE_BE
Definition: SystemEnvironmentBuilder.php:45
‪TYPO3\CMS\Core\Utility\GeneralUtility\revExplode
‪static list< string > revExplode($delimiter, $string, $limit=0)
Definition: GeneralUtility.php:882
‪TYPO3\CMS\Core\Core\SystemEnvironmentBuilder\calculateScriptPath
‪static string calculateScriptPath(int $entryPointLevel, int $requestType)
Definition: SystemEnvironmentBuilder.php:115
‪TYPO3\CMS\Core\Core\SystemEnvironmentBuilder\getPathThisScriptNonCli
‪static string getPathThisScriptNonCli()
Definition: SystemEnvironmentBuilder.php:271
‪TYPO3\CMS\Core\Core\SystemEnvironmentBuilder\defineBaseConstants
‪static defineBaseConstants()
Definition: SystemEnvironmentBuilder.php:87
‪TYPO3\CMS\Core\Core\SystemEnvironmentBuilder\createApplicationContext
‪static createApplicationContext()
Definition: SystemEnvironmentBuilder.php:78
‪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:308
‪TYPO3\CMS\Core\Core\SystemEnvironmentBuilder\initializeGlobalVariables
‪static initializeGlobalVariables()
Definition: SystemEnvironmentBuilder.php:170
‪TYPO3\CMS\Core\Core\SystemEnvironmentBuilder\isRunningOnWindows
‪static isRunningOnWindows()
Definition: SystemEnvironmentBuilder.php:236
‪TYPO3\CMS\Core\Utility\PathUtility\dirnameDuringBootstrap
‪static string dirnameDuringBootstrap(string $path)
Definition: PathUtility.php:337
‪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:100
‪TYPO3\CMS\Core\Core\SystemEnvironmentBuilder\run
‪static run(int $entryPointLevel=0, int $requestType=self::REQUESTTYPE_FE)
Definition: SystemEnvironmentBuilder.php:60
‪TYPO3\CMS\Core\Core\SystemEnvironmentBuilder\usesComposerClassLoading
‪static usesComposerClassLoading()
Definition: SystemEnvironmentBuilder.php:335
‪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
‪TYPO3\CMS\Core\Core\Environment\isRunningOnCgiServer
‪static isRunningOnCgiServer()
Definition: Environment.php:303
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:25
‪TYPO3\CMS\Core\Core
Definition: ApplicationContext.php:16
‪TYPO3\CMS\Core\Core\SystemEnvironmentBuilder\isCliRequestType
‪static isCliRequestType(?int $requestType)
Definition: SystemEnvironmentBuilder.php:344
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:51
‪TYPO3\CMS\Core\Core\SystemEnvironmentBuilder\REQUESTTYPE_FE
‪const REQUESTTYPE_FE
Definition: SystemEnvironmentBuilder.php:43
‪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