TYPO3 CMS  TYPO3_8-7
PathUtility.php
Go to the documentation of this file.
1 <?php
2 namespace TYPO3\CMS\Core\Utility;
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 
21 {
29  public static function getRelativePathTo($targetPath)
30  {
31  return self::getRelativePath(dirname(PATH_thisScript), $targetPath);
32  }
33 
40  public static function getAbsoluteWebPath($targetPath)
41  {
42  if (self::isAbsolutePath($targetPath)) {
43  if (strpos($targetPath, PATH_site) === 0) {
44  $targetPath = self::stripPathSitePrefix($targetPath);
45  if (!(TYPO3_REQUESTTYPE & TYPO3_REQUESTTYPE_CLI)) {
46  $targetPath = GeneralUtility::getIndpEnv('TYPO3_SITE_PATH') . $targetPath;
47  }
48  }
49  } elseif (strpos($targetPath, '://') !== false) {
50  return $targetPath;
51  } else {
52  // Make an absolute path out of it
53  $targetPath = GeneralUtility::resolveBackPath(dirname(PATH_thisScript) . '/' . $targetPath);
54  $targetPath = self::stripPathSitePrefix($targetPath);
55  if (!(TYPO3_REQUESTTYPE & TYPO3_REQUESTTYPE_CLI)) {
56  $targetPath = GeneralUtility::getIndpEnv('TYPO3_SITE_PATH') . $targetPath;
57  }
58  }
59  return $targetPath;
60  }
61 
70  public static function getRelativePath($sourcePath, $targetPath)
71  {
72  $relativePath = null;
73  $sourcePath = rtrim(GeneralUtility::fixWindowsFilePath($sourcePath), '/');
74  $targetPath = rtrim(GeneralUtility::fixWindowsFilePath($targetPath), '/');
75  if ($sourcePath !== $targetPath) {
76  $commonPrefix = self::getCommonPrefix([$sourcePath, $targetPath]);
77  if ($commonPrefix !== null && GeneralUtility::isAllowedAbsPath($commonPrefix)) {
78  $commonPrefixLength = strlen($commonPrefix);
79  $resolvedSourcePath = '';
80  $resolvedTargetPath = '';
81  $sourcePathSteps = 0;
82  if (strlen($sourcePath) > $commonPrefixLength) {
83  $resolvedSourcePath = (string)substr($sourcePath, $commonPrefixLength);
84  }
85  if (strlen($targetPath) > $commonPrefixLength) {
86  $resolvedTargetPath = (string)substr($targetPath, $commonPrefixLength);
87  }
88  if ($resolvedSourcePath !== '') {
89  $sourcePathSteps = count(explode('/', $resolvedSourcePath));
90  }
91  $relativePath = self::sanitizeTrailingSeparator(str_repeat('../', $sourcePathSteps) . $resolvedTargetPath);
92  }
93  }
94  return $relativePath;
95  }
96 
107  public static function getCommonPrefix(array $paths)
108  {
109  $paths = array_map([\TYPO3\CMS\Core\Utility\GeneralUtility::class, 'fixWindowsFilePath'], $paths);
110  $commonPath = null;
111  if (count($paths) === 1) {
112  $commonPath = array_shift($paths);
113  } elseif (count($paths) > 1) {
114  $parts = explode('/', array_shift($paths));
115  $comparePath = '';
116  $break = false;
117  foreach ($parts as $part) {
118  $comparePath .= $part . '/';
119  foreach ($paths as $path) {
120  if (strpos($path . '/', $comparePath) !== 0) {
121  $break = true;
122  break;
123  }
124  }
125  if ($break) {
126  break;
127  }
128  $commonPath = $comparePath;
129  }
130  }
131  if ($commonPath !== null) {
132  $commonPath = self::sanitizeTrailingSeparator($commonPath, '/');
133  }
134  return $commonPath;
135  }
136 
145  public static function sanitizeTrailingSeparator($path, $separator = '/')
146  {
147  return rtrim($path, $separator) . $separator;
148  }
149 
162  public static function basename($path)
163  {
164  $currentLocale = setlocale(LC_CTYPE, 0);
165  setlocale(LC_CTYPE, $GLOBALS['TYPO3_CONF_VARS']['SYS']['systemLocale']);
166  $basename = basename($path);
167  setlocale(LC_CTYPE, $currentLocale);
168  return $basename;
169  }
170 
183  public static function dirname($path)
184  {
185  $currentLocale = setlocale(LC_CTYPE, 0);
186  setlocale(LC_CTYPE, $GLOBALS['TYPO3_CONF_VARS']['SYS']['systemLocale']);
187  $dirname = dirname($path);
188  setlocale(LC_CTYPE, $currentLocale);
189  return $dirname;
190  }
191 
205  public static function pathinfo($path, $options = null)
206  {
207  $currentLocale = setlocale(LC_CTYPE, 0);
208  setlocale(LC_CTYPE, $GLOBALS['TYPO3_CONF_VARS']['SYS']['systemLocale']);
209  $pathinfo = $options == null ? pathinfo($path) : pathinfo($path, $options);
210  setlocale(LC_CTYPE, $currentLocale);
211  return $pathinfo;
212  }
213 
220  public static function isAbsolutePath($path)
221  {
222  // On Windows also a path starting with a drive letter is absolute: X:/
223  if (static::isWindows() && (substr($path, 1, 2) === ':/' || substr($path, 1, 2) === ':\\')) {
224  return true;
225  }
226  // Path starting with a / is always absolute, on every system
227  return $path[0] === '/';
228  }
229 
253  public static function getAbsolutePathOfRelativeReferencedFileOrPath($baseFilenameOrPath, $includeFileName)
254  {
255  $fileName = static::basename($includeFileName);
256  $basePath = substr($baseFilenameOrPath, -1) === '/' ? $baseFilenameOrPath : static::dirname($baseFilenameOrPath);
257  $newDir = static::getCanonicalPath($basePath . '/' . static::dirname($includeFileName));
258  // Avoid double slash on empty path
259  $result = (($newDir !== '/') ? $newDir : '') . '/' . $fileName;
260  return $result;
261  }
262 
263  /*********************
264  *
265  * Cleaning methods
266  *
267  *********************/
274  public static function getCanonicalPath($path)
275  {
276  // Replace backslashes with slashes to work with Windows paths if given
277  $path = trim(str_replace('\\', '/', $path));
278 
279  // @todo do we really need this? Probably only in testing context for vfs?
280  $protocol = '';
281  if (strpos($path, '://') !== false) {
282  list($protocol, $path) = explode('://', $path);
283  $protocol .= '://';
284  }
285 
286  $absolutePathPrefix = '';
287  if (static::isAbsolutePath($path)) {
288  if (static::isWindows() && substr($path, 1, 2) === ':/') {
289  $absolutePathPrefix = substr($path, 0, 3);
290  $path = substr($path, 3);
291  } else {
292  $path = ltrim($path, '/');
293  $absolutePathPrefix = '/';
294  }
295  }
296 
297  $theDirParts = explode('/', $path);
298  $theDirPartsCount = count($theDirParts);
299  for ($partCount = 0; $partCount < $theDirPartsCount; $partCount++) {
300  // double-slashes in path: remove element
301  if ($theDirParts[$partCount] === '') {
302  array_splice($theDirParts, $partCount, 1);
303  $partCount--;
304  $theDirPartsCount--;
305  }
306  // "." in path: remove element
307  if ($theDirParts[$partCount] === '.') {
308  array_splice($theDirParts, $partCount, 1);
309  $partCount--;
310  $theDirPartsCount--;
311  }
312  // ".." in path:
313  if ($theDirParts[$partCount] === '..') {
314  if ($partCount >= 1) {
315  // Rremove this and previous element
316  array_splice($theDirParts, $partCount - 1, 2);
317  $partCount -= 2;
318  $theDirPartsCount -= 2;
319  } elseif ($absolutePathPrefix) {
320  // can't go higher than root dir
321  // simply remove this part and continue
322  array_splice($theDirParts, $partCount, 1);
323  $partCount--;
324  $theDirPartsCount--;
325  }
326  }
327  }
328 
329  return $protocol . $absolutePathPrefix . implode('/', $theDirParts);
330  }
331 
339  public static function stripPathSitePrefix($path)
340  {
341  static $pathSiteLength = null;
342 
343  // calculate length when first needed
344  if (!isset($pathSiteLength)) {
345  $pathSiteLength = strlen(PATH_site);
346  }
347  return substr($path, $pathSiteLength);
348  }
349 
350  /*********************
351  *
352  * Helper methods
353  *
354  *********************/
355 
361  protected static function isWindows()
362  {
363  return TYPO3_OS === 'WIN';
364  }
365 }
static getRelativePathTo($targetPath)
Definition: PathUtility.php:29
static getCommonPrefix(array $paths)
static getAbsoluteWebPath($targetPath)
Definition: PathUtility.php:40
static getAbsolutePathOfRelativeReferencedFileOrPath($baseFilenameOrPath, $includeFileName)
static pathinfo($path, $options=null)
static getRelativePath($sourcePath, $targetPath)
Definition: PathUtility.php:70
if(TYPO3_MODE==='BE') $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tsfebeuserauth.php']['frontendEditingController']['default']
static sanitizeTrailingSeparator($path, $separator='/')