TYPO3 CMS  TYPO3_8-7
SystemEnvironmentBuilder.php
Go to the documentation of this file.
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 
19 
40 {
48  protected static $supportedCgiServerApis = [
49  'fpm-fcgi',
50  'cgi',
51  'isapi',
52  'cgi-fcgi',
53  'srv', // HHVM with fastcgi
54  ];
55 
61  protected static $disabledFunctions = null;
62 
70  public static function run($entryPointLevel = 0)
71  {
72  self::defineBaseConstants();
73  self::definePaths($entryPointLevel);
74  self::checkMainPathsExist();
75  self::initializeGlobalVariables();
76  self::initializeGlobalTimeTrackingVariables();
77  self::initializeBasicErrorReporting();
78  }
79 
83  protected static function defineBaseConstants()
84  {
85  // This version, branch and copyright
86  define('TYPO3_version', '8.7.31-dev');
87  define('TYPO3_branch', '8.7');
88  define('TYPO3_copyright_year', '1998-2019');
89 
90  // TYPO3 external links
91  define('TYPO3_URL_GENERAL', 'https://typo3.org/');
92  define('TYPO3_URL_LICENSE', 'https://typo3.org/typo3-cms/overview/licenses/');
93  define('TYPO3_URL_EXCEPTION', 'https://typo3.org/go/exception/CMS/');
94  define('TYPO3_URL_MAILINGLISTS', 'http://lists.typo3.org/cgi-bin/mailman/listinfo');
95  define('TYPO3_URL_DOCUMENTATION', 'https://typo3.org/documentation/');
96  define('TYPO3_URL_DOCUMENTATION_TSREF', 'https://docs.typo3.org/typo3cms/TyposcriptReference/');
97  define('TYPO3_URL_DOCUMENTATION_TSCONFIG', 'https://docs.typo3.org/typo3cms/TSconfigReference/');
98  define('TYPO3_URL_CONSULTANCY', 'https://typo3.org/support/professional-services/');
99  define('TYPO3_URL_CONTRIBUTE', 'https://typo3.org/contribute/');
100  define('TYPO3_URL_SECURITY', 'https://typo3.org/teams/security/');
101  define('TYPO3_URL_DOWNLOAD', 'https://typo3.org/download/');
102  define('TYPO3_URL_SYSTEMREQUIREMENTS', 'https://typo3.org/typo3-cms/overview/requirements/');
103  define('TYPO3_URL_DONATE', 'https://typo3.org/community/contribute/donate/');
104  define('TYPO3_URL_WIKI_OPCODECACHE', 'https://wiki.typo3.org/Opcode_Cache');
105 
106  // A null, a tabulator, a linefeed, a carriage return, a substitution, a CR-LF combination
107  defined('NUL') ?: define('NUL', chr(0));
108  defined('TAB') ?: define('TAB', chr(9));
109  defined('LF') ?: define('LF', chr(10));
110  defined('CR') ?: define('CR', chr(13));
111  defined('SUB') ?: define('SUB', chr(26));
112  defined('CRLF') ?: define('CRLF', CR . LF);
113 
114  // Security related constant: Default value of fileDenyPattern
115  define('FILE_DENY_PATTERN_DEFAULT', '\\.(php[3-8]?|phpsh|phtml|pht|phar|shtml|cgi)(\\..*)?$|\\.pl$|^\\.htaccess$');
116  // Security related constant: List of file extensions that should be registered as php script file extensions
117  define('PHP_EXTENSIONS_DEFAULT', 'php,php3,php4,php5,php6,php7,php8,phpsh,inc,phtml,pht,phar');
118 
119  // Operating system identifier
120  // Either "WIN" or empty string
121  defined('TYPO3_OS') ?: define('TYPO3_OS', self::getTypo3Os());
122 
123  // Service error constants
124  // General error - something went wrong
125  define('T3_ERR_SV_GENERAL', -1);
126  // During execution it showed that the service is not available and should be ignored. The service itself should call $this->setNonAvailable()
127  define('T3_ERR_SV_NOT_AVAIL', -2);
128  // Passed subtype is not possible with this service
129  define('T3_ERR_SV_WRONG_SUBTYPE', -3);
130  // Passed subtype is not possible with this service
131  define('T3_ERR_SV_NO_INPUT', -4);
132  // File not found which the service should process
133  define('T3_ERR_SV_FILE_NOT_FOUND', -20);
134  // File not readable
135  define('T3_ERR_SV_FILE_READ', -21);
136  // File not writable
137  define('T3_ERR_SV_FILE_WRITE', -22);
138  // Passed subtype is not possible with this service
139  define('T3_ERR_SV_PROG_NOT_FOUND', -40);
140  // Passed subtype is not possible with this service
141  define('T3_ERR_SV_PROG_FAILED', -41);
142  }
143 
149  protected static function definePaths($entryPointLevel = 0)
150  {
151  // Absolute path of the entry script that was called
152  $scriptPath = GeneralUtility::fixWindowsFilePath(self::getPathThisScript());
153  $rootPath = self::getRootPathFromScriptPath($scriptPath, $entryPointLevel);
154  // Check if the root path has been set in the environment (e.g. by the composer installer)
155  if (getenv('TYPO3_PATH_ROOT')) {
156  if ((TYPO3_REQUESTTYPE & TYPO3_REQUESTTYPE_CLI)
158  && StringUtility::endsWith($scriptPath, 'typo3')
159  ) {
160  // PATH_thisScript is used for various path calculations based on the document root
161  // Therefore we assume it is always a subdirectory of the document root, which is not the case
162  // in composer mode on cli, as the binary is in the composer bin directory.
163  // Because of that, we enforce the document root path of this binary to be set
164  $scriptName = '/typo3/sysext/core/bin/typo3';
165  } else {
166  // Base the script path on the path taken from the environment
167  // to make relative path calculations work in case only one of both is symlinked
168  // or has the real path
169  $scriptName = substr($scriptPath, strlen($rootPath));
170  }
171  $rootPath = GeneralUtility::fixWindowsFilePath(getenv('TYPO3_PATH_ROOT'));
172  $scriptPath = $rootPath . $scriptName;
173  }
174 
175  if (!defined('PATH_thisScript')) {
176  define('PATH_thisScript', $scriptPath);
177  }
178  // Absolute path of the document root of the instance with trailing slash
179  if (!defined('PATH_site')) {
180  define('PATH_site', $rootPath . '/');
181  }
182  // Relative path from document root to typo3/ directory
183  // Hardcoded to "typo3/"
184  define('TYPO3_mainDir', 'typo3/');
185  // Absolute path of the typo3 directory of the instance with trailing slash
186  // Example "/var/www/instance-name/htdocs/typo3/"
187  define('PATH_typo3', PATH_site . TYPO3_mainDir);
188  // Absolute path to the typo3conf directory with trailing slash
189  // Example "/var/www/instance-name/htdocs/typo3conf/"
190  define('PATH_typo3conf', PATH_site . 'typo3conf/');
191  }
192 
196  protected static function checkMainPathsExist()
197  {
198  if (!is_file(PATH_thisScript)) {
199  static::exitWithMessage('Unable to determine path to entry script.');
200  }
201  }
202 
206  protected static function initializeGlobalVariables()
207  {
208  // Unset variable(s) in global scope (security issue #13959)
209  unset($GLOBALS['error']);
210  $GLOBALS['TYPO3_MISC'] = [];
211  $GLOBALS['T3_VAR'] = [];
212  $GLOBALS['T3_SERVICES'] = [];
213  }
214 
219  protected static function initializeGlobalTimeTrackingVariables()
220  {
221  // Set PARSETIME_START to the system time in milliseconds.
222  $GLOBALS['PARSETIME_START'] = GeneralUtility::milliseconds();
223  // Microtime of (nearly) script start
224  $GLOBALS['TYPO3_MISC']['microtime_start'] = microtime(true);
225  // EXEC_TIME is set so that the rest of the script has a common value for the script execution time
226  $GLOBALS['EXEC_TIME'] = time();
227  // $ACCESS_TIME is a common time in minutes for access control
228  $GLOBALS['ACCESS_TIME'] = $GLOBALS['EXEC_TIME'] - $GLOBALS['EXEC_TIME'] % 60;
229  // $SIM_EXEC_TIME is set to $EXEC_TIME but can be altered later in the script if we want to
230  // simulate another execution-time when selecting from eg. a database
231  $GLOBALS['SIM_EXEC_TIME'] = $GLOBALS['EXEC_TIME'];
232  // If $SIM_EXEC_TIME is changed this value must be set accordingly
233  $GLOBALS['SIM_ACCESS_TIME'] = $GLOBALS['ACCESS_TIME'];
234  }
235 
244  protected static function initializeBasicErrorReporting()
245  {
246  // Core should be notice free at least until this point ...
247  error_reporting(E_ALL & ~(E_STRICT | E_NOTICE | E_DEPRECATED));
248  }
249 
255  protected static function getTypo3Os()
256  {
257  $typoOs = '';
258  if (!stristr(PHP_OS, 'darwin') && !stristr(PHP_OS, 'cygwin') && stristr(PHP_OS, 'win')) {
259  $typoOs = 'WIN';
260  }
261  return $typoOs;
262  }
263 
278  protected static function getPathThisScript()
279  {
280  if (TYPO3_REQUESTTYPE & TYPO3_REQUESTTYPE_CLI) {
281  return self::getPathThisScriptCli();
282  }
283  return self::getPathThisScriptNonCli();
284  }
285 
293  protected static function getPathThisScriptNonCli()
294  {
295  $cgiPath = '';
296  if (isset($_SERVER['ORIG_PATH_TRANSLATED'])) {
297  $cgiPath = $_SERVER['ORIG_PATH_TRANSLATED'];
298  } elseif (isset($_SERVER['PATH_TRANSLATED'])) {
299  $cgiPath = $_SERVER['PATH_TRANSLATED'];
300  }
301  if ($cgiPath && in_array(PHP_SAPI, self::$supportedCgiServerApis, true)) {
302  $scriptPath = $cgiPath;
303  } else {
304  if (isset($_SERVER['ORIG_SCRIPT_FILENAME'])) {
305  $scriptPath = $_SERVER['ORIG_SCRIPT_FILENAME'];
306  } else {
307  $scriptPath = $_SERVER['SCRIPT_FILENAME'];
308  }
309  }
310  return $scriptPath;
311  }
312 
321  protected static function getPathThisScriptCli()
322  {
323  // Possible relative path of the called script
324  if (isset($_SERVER['argv'][0])) {
325  $scriptPath = $_SERVER['argv'][0];
326  } elseif (isset($_ENV['_'])) {
327  $scriptPath = $_ENV['_'];
328  } else {
329  $scriptPath = $_SERVER['_'];
330  }
331  // Find out if path is relative or not
332  $isRelativePath = false;
333  if (TYPO3_OS === 'WIN') {
334  if (!preg_match('/^([a-zA-Z]:)?\\\\/', $scriptPath)) {
335  $isRelativePath = true;
336  }
337  } else {
338  if ($scriptPath[0] !== '/') {
339  $isRelativePath = true;
340  }
341  }
342  // Concatenate path to current working directory with relative path and remove "/./" constructs
343  if ($isRelativePath) {
344  if (isset($_SERVER['PWD'])) {
345  $workingDirectory = $_SERVER['PWD'];
346  } else {
347  $workingDirectory = getcwd();
348  }
349  $scriptPath = $workingDirectory . '/' . preg_replace('/\\.\\//', '', $scriptPath);
350  }
351  return $scriptPath;
352  }
353 
369  protected static function getRootPathFromScriptPath($scriptPath, $entryPointLevel)
370  {
371  $entryScriptDirectory = dirname($scriptPath);
372  if ($entryPointLevel > 0) {
373  list($rootPath) = GeneralUtility::revExplode('/', $entryScriptDirectory, $entryPointLevel + 1);
374  } else {
375  $rootPath = $entryScriptDirectory;
376  }
377  return $rootPath;
378  }
379 
385  protected static function exitWithMessage($message)
386  {
387  $headers = [
389  'Content-Type: text/plain'
390  ];
391  if (!headers_sent()) {
392  foreach ($headers as $header) {
393  header($header);
394  }
395  }
396  echo $message . LF;
397  exit(1);
398  }
399 
406  public static function isFunctionDisabled($function)
407  {
408  if (static::$disabledFunctions === null) {
409  static::$disabledFunctions = GeneralUtility::trimExplode(',', ini_get('disable_functions'));
410  }
411  if (!empty(static::$disabledFunctions)) {
412  return in_array($function, static::$disabledFunctions, true);
413  }
414 
415  return false;
416  }
417 }
static trimExplode($delim, $string, $removeEmptyValues=false, $limit=0)
static getRootPathFromScriptPath($scriptPath, $entryPointLevel)
static revExplode($delimiter, $string, $count=0)
if(TYPO3_MODE==='BE') $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tsfebeuserauth.php']['frontendEditingController']['default']
static endsWith($haystack, $needle)