‪TYPO3CMS  ‪main
SystemEnvironmentBuilder.php
Go to the documentation of this file.
1 <?php
2 
3 declare(strict_types=1);
4 
5 /*
6  * This file is part of the TYPO3 CMS project.
7  *
8  * It is free software; you can redistribute it and/or modify it under
9  * the terms of the GNU General Public License, either version 2
10  * of the License, or any later version.
11  *
12  * For the full copyright and license information, please read the
13  * LICENSE.txt file that was distributed with this source code.
14  *
15  * The TYPO3 project - inspiring people to share!
16  */
17 
18 namespace ‪TYPO3\CMS\Core\Core;
19 
22 
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 = 0)
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 
109  protected static function ‪calculateScriptPath(int $entryPointLevel, int $requestType): string
110  {
111  $isCli = ‪self::isCliRequestType($requestType);
112  // Absolute path of the entry script that was called
113  $scriptPath = GeneralUtility::fixWindowsFilePath((string)self::getPathThisScript($isCli));
114  $rootPath = ‪self::getRootPathFromScriptPath($scriptPath, $entryPointLevel);
115  // Check if the root path has been set in the environment (e.g. by the composer installer)
116  $rootPathFromEnvironment = ‪self::getDefinedPathRoot();
117  if ($rootPathFromEnvironment) {
118  if ($isCli && self::usesComposerClassLoading()) {
119  // $scriptPath is used for various path calculations based on the document root
120  // Therefore we assume it is always a subdirectory of the document root, which is not the case
121  // in composer mode on cli, as the binary is in the composer bin directory.
122  // Because of that, we enforce the document root path of this binary to be set
123  $scriptName = 'typo3/sysext/core/bin/typo3';
124  } else {
125  // Base the script path on the path taken from the environment
126  // to make relative path calculations work in case only one of both is symlinked
127  // or has the real path
128  $scriptName = ltrim(substr($scriptPath, strlen($rootPath)), '/');
129  }
130  $rootPath = rtrim(GeneralUtility::fixWindowsFilePath($rootPathFromEnvironment), '/');
131  $scriptPath = $rootPath . '/' . $scriptName;
132  }
133  return $scriptPath;
134  }
135 
150  protected static function ‪calculateRootPath(int $entryPointLevel, int $requestType): string
151  {
152  // Check if the root path has been set in the environment (e.g. by the composer installer)
153  $pathRoot = ‪self::getDefinedPathRoot();
154  if ($pathRoot) {
155  return rtrim(GeneralUtility::fixWindowsFilePath($pathRoot), '/');
156  }
157  $isCli = ‪self::isCliRequestType($requestType);
158  // Absolute path of the entry script that was called
159  $scriptPath = GeneralUtility::fixWindowsFilePath((string)self::getPathThisScript($isCli));
160  return ‪self::getRootPathFromScriptPath($scriptPath, $entryPointLevel);
161  }
162 
166  protected static function ‪initializeGlobalVariables()
167  {
168  // Unset variable(s) in global scope (security issue #13959)
169  ‪$GLOBALS['T3_SERVICES'] = [];
170  }
171 
176  protected static function ‪initializeGlobalTimeTrackingVariables()
177  {
178  // EXEC_TIME is set so that the rest of the script has a common value for the script execution time
179  ‪$GLOBALS['EXEC_TIME'] = time();
180  // $ACCESS_TIME is a common time in minutes for access control
181  ‪$GLOBALS['ACCESS_TIME'] = ‪$GLOBALS['EXEC_TIME'] - ‪$GLOBALS['EXEC_TIME'] % 60;
182  // $SIM_EXEC_TIME is set to $EXEC_TIME but can be altered later in the script if we want to
183  // simulate another execution-time when selecting from eg. a database
184  ‪$GLOBALS['SIM_EXEC_TIME'] = ‪$GLOBALS['EXEC_TIME'];
185  // If $SIM_EXEC_TIME is changed this value must be set accordingly
186  ‪$GLOBALS['SIM_ACCESS_TIME'] = ‪$GLOBALS['ACCESS_TIME'];
187  }
188 
189  protected static function ‪getDefinedPathRoot(): string
190  {
191  return getenv('TYPO3_PATH_ROOT') ?: getenv('REDIRECT_TYPO3_PATH_ROOT') ?: '';
192  }
193 
197  protected static function ‪initializeEnvironment(int $requestType, string $scriptPath, string $sitePath)
198  {
199  $pathRoot = ‪self::getDefinedPathRoot();
200  if ($pathRoot) {
201  $rootPathFromEnvironment = rtrim(GeneralUtility::fixWindowsFilePath($pathRoot), '/');
202  if ($sitePath !== $rootPathFromEnvironment) {
203  // This means, that we re-initialized the environment during a single request
204  // This currently only happens in custom code or during functional testing
205  // Once the constants are removed, we might be able to remove this code here as well and directly pass an environment to the application
206  $scriptPath = $rootPathFromEnvironment . substr($scriptPath, strlen($sitePath));
207  $sitePath = $rootPathFromEnvironment;
208  }
209  }
210 
211  $projectRootPath = (string)(getenv('TYPO3_PATH_APP') ?: getenv('REDIRECT_TYPO3_PATH_APP') ?: '');
212  $projectRootPath = GeneralUtility::fixWindowsFilePath($projectRootPath);
213  $isDifferentRootPath = ($projectRootPath && $projectRootPath !== $sitePath);
215  static::createApplicationContext(),
216  self::isCliRequestType($requestType),
217  static::usesComposerClassLoading(),
218  $isDifferentRootPath ? $projectRootPath : $sitePath,
219  $sitePath,
220  $isDifferentRootPath ? $projectRootPath . '/var' : $sitePath . '/typo3temp/var',
221  $isDifferentRootPath ? $projectRootPath . '/config' : $sitePath . '/typo3conf',
222  $scriptPath,
223  self::isRunningOnWindows() ? 'WINDOWS' : 'UNIX'
224  );
225  }
226 
230  protected static function ‪isRunningOnWindows(): bool
231  {
232  return stripos(PHP_OS, 'darwin') === false
233  && stripos(PHP_OS, 'cygwin') === false
234  && stripos(PHP_OS, 'win') !== false;
235  }
236 
252  protected static function ‪getPathThisScript(bool $isCli)
253  {
254  if ($isCli) {
256  }
258  }
259 
265  protected static function ‪getPathThisScriptNonCli()
266  {
268  throw new \Exception('TYPO3 does only support being used with cgi.fix_pathinfo=1 on CGI server APIs.', 1675108421);
269  }
270 
271  return ‪$_SERVER['SCRIPT_FILENAME'];
272  }
273 
282  protected static function ‪getPathThisScriptCli()
283  {
284  // Possible relative path of the called script
285  $scriptPath = ‪$_SERVER['argv'][0] ?? $_ENV['_'] ?? ‪$_SERVER['_'];
286  // Find out if path is relative or not
287  $isRelativePath = false;
288  if (self::isRunningOnWindows()) {
289  if (!preg_match('/^([a-zA-Z]:)?\\\\/', $scriptPath)) {
290  $isRelativePath = true;
291  }
292  } elseif ($scriptPath[0] !== '/') {
293  $isRelativePath = true;
294  }
295  // Concatenate path to current working directory with relative path and remove "/./" constructs
296  if ($isRelativePath) {
297  $workingDirectory = ‪$_SERVER['PWD'] ?? getcwd();
298  $scriptPath = $workingDirectory . '/' . preg_replace('/\\.\\//', '', $scriptPath);
299  }
300  return $scriptPath;
301  }
302 
317  protected static function ‪getRootPathFromScriptPath($scriptPath, $entryPointLevel)
318  {
319  $entryScriptDirectory = ‪PathUtility::dirnameDuringBootstrap($scriptPath);
320  if ($entryPointLevel > 0) {
321  [$rootPath] = ‪GeneralUtility::revExplode('/', $entryScriptDirectory, $entryPointLevel + 1);
322  } else {
323  $rootPath = $entryScriptDirectory;
324  }
325  return $rootPath;
326  }
327 
328  protected static function ‪usesComposerClassLoading(): bool
329  {
330  return defined('TYPO3_COMPOSER_MODE') && TYPO3_COMPOSER_MODE;
331  }
332 
337  protected static function ‪isCliRequestType(?int $requestType): bool
338  {
339  if ($requestType === null) {
340  return PHP_SAPI === 'cli';
341  }
342 
343  return ($requestType & self::REQUESTTYPE_CLI) === ‪self::REQUESTTYPE_CLI;
344  }
345 }
‪TYPO3\CMS\Core\Core\SystemEnvironmentBuilder\calculateRootPath
‪static string calculateRootPath(int $entryPointLevel, int $requestType)
Definition: SystemEnvironmentBuilder.php:150
‪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:317
‪TYPO3\CMS\Core\Core\SystemEnvironmentBuilder\initializeGlobalTimeTrackingVariables
‪static initializeGlobalTimeTrackingVariables()
Definition: SystemEnvironmentBuilder.php:176
‪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\Core\SystemEnvironmentBuilder\getDefinedPathRoot
‪static getDefinedPathRoot()
Definition: SystemEnvironmentBuilder.php:189
‪TYPO3\CMS\Core\Core\SystemEnvironmentBuilder\calculateScriptPath
‪static string calculateScriptPath(int $entryPointLevel, int $requestType)
Definition: SystemEnvironmentBuilder.php:109
‪TYPO3\CMS\Core\Core\SystemEnvironmentBuilder\getPathThisScriptNonCli
‪static string getPathThisScriptNonCli()
Definition: SystemEnvironmentBuilder.php:265
‪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:297
‪TYPO3\CMS\Core\Core\SystemEnvironmentBuilder\initializeGlobalVariables
‪static initializeGlobalVariables()
Definition: SystemEnvironmentBuilder.php:166
‪TYPO3\CMS\Core\Core\SystemEnvironmentBuilder\isRunningOnWindows
‪static isRunningOnWindows()
Definition: SystemEnvironmentBuilder.php:230
‪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
‪$_SERVER
‪$_SERVER['TYPO3_DEPRECATED_ENTRYPOINT']
Definition: legacy-backend.php:20
‪TYPO3\CMS\Core\Core\SystemEnvironmentBuilder\usesComposerClassLoading
‪static usesComposerClassLoading()
Definition: SystemEnvironmentBuilder.php:328
‪TYPO3\CMS\Core\Core\SystemEnvironmentBuilder\getPathThisScriptCli
‪static string getPathThisScriptCli()
Definition: SystemEnvironmentBuilder.php:282
‪TYPO3\CMS\Core\Core\SystemEnvironmentBuilder\getPathThisScript
‪static string getPathThisScript(bool $isCli)
Definition: SystemEnvironmentBuilder.php:252
‪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:292
‪$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\revExplode
‪static list< string > revExplode(string $delimiter, string $string, int $limit=0)
Definition: GeneralUtility.php:787
‪TYPO3\CMS\Core\Core\SystemEnvironmentBuilder\isCliRequestType
‪static isCliRequestType(?int $requestType)
Definition: SystemEnvironmentBuilder.php:337
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:52
‪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\run
‪static run(int $entryPointLevel=0, int $requestType=0)
Definition: SystemEnvironmentBuilder.php:60
‪TYPO3\CMS\Core\Core\SystemEnvironmentBuilder\initializeEnvironment
‪static initializeEnvironment(int $requestType, string $scriptPath, string $sitePath)
Definition: SystemEnvironmentBuilder.php:197