TYPO3 CMS  TYPO3_7-6
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 (StringUtility::beginsWith($targetPath, PATH_site)) {
44  $targetPath = self::stripPathSitePrefix($targetPath);
45  if (!defined('TYPO3_cliMode')) {
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 (!defined('TYPO3_cliMode')) {
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 
163  public static function basename($path)
164  {
165  $currentLocale = setlocale(LC_CTYPE, 0);
166  setlocale(LC_CTYPE, $GLOBALS['TYPO3_CONF_VARS']['SYS']['systemLocale']);
167  $basename = basename($path);
168  setlocale(LC_CTYPE, $currentLocale);
169  return $basename;
170  }
171 
185  public static function dirname($path)
186  {
187  $currentLocale = setlocale(LC_CTYPE, 0);
188  setlocale(LC_CTYPE, $GLOBALS['TYPO3_CONF_VARS']['SYS']['systemLocale']);
189  $dirname = dirname($path);
190  setlocale(LC_CTYPE, $currentLocale);
191  return $dirname;
192  }
193 
208  public static function pathinfo($path, $options = null)
209  {
210  $currentLocale = setlocale(LC_CTYPE, 0);
211  setlocale(LC_CTYPE, $GLOBALS['TYPO3_CONF_VARS']['SYS']['systemLocale']);
212  $pathinfo = $options == null ? pathinfo($path) : pathinfo($path, $options);
213  setlocale(LC_CTYPE, $currentLocale);
214  return $pathinfo;
215  }
216 
223  public static function isAbsolutePath($path)
224  {
225  // On Windows also a path starting with a drive letter is absolute: X:/
226  if (static::isWindows() && (substr($path, 1, 2) === ':/' || substr($path, 1, 2) === ':\\')) {
227  return true;
228  }
229  // Path starting with a / is always absolute, on every system
230  return $path[0] === '/';
231  }
232 
256  public static function getAbsolutePathOfRelativeReferencedFileOrPath($baseFilenameOrPath, $includeFileName)
257  {
258  $fileName = static::basename($includeFileName);
259  $basePath = substr($baseFilenameOrPath, -1) === '/' ? $baseFilenameOrPath : static::dirname($baseFilenameOrPath);
260  $newDir = static::getCanonicalPath($basePath . '/' . static::dirname($includeFileName));
261  // Avoid double slash on empty path
262  $result = (($newDir !== '/') ? $newDir : '') . '/' . $fileName;
263  return $result;
264  }
265 
266  /*********************
267  *
268  * Cleaning methods
269  *
270  *********************/
277  public static function getCanonicalPath($path)
278  {
279  // Replace backslashes with slashes to work with Windows paths if given
280  $path = trim(str_replace('\\', '/', $path));
281 
282  // @todo do we really need this? Probably only in testing context for vfs?
283  $protocol = '';
284  if (strpos($path, '://') !== false) {
285  list($protocol, $path) = explode('://', $path);
286  $protocol .= '://';
287  }
288 
289  $absolutePathPrefix = '';
290  if (static::isAbsolutePath($path)) {
291  if (static::isWindows() && substr($path, 1, 2) === ':/') {
292  $absolutePathPrefix = substr($path, 0, 3);
293  $path = substr($path, 3);
294  } else {
295  $path = ltrim($path, '/');
296  $absolutePathPrefix = '/';
297  }
298  }
299 
300  $theDirParts = explode('/', $path);
301  $theDirPartsCount = count($theDirParts);
302  for ($partCount = 0; $partCount < $theDirPartsCount; $partCount++) {
303  // double-slashes in path: remove element
304  if ($theDirParts[$partCount] === '') {
305  array_splice($theDirParts, $partCount, 1);
306  $partCount--;
307  $theDirPartsCount--;
308  }
309  // "." in path: remove element
310  if ($theDirParts[$partCount] === '.') {
311  array_splice($theDirParts, $partCount, 1);
312  $partCount--;
313  $theDirPartsCount--;
314  }
315  // ".." in path:
316  if ($theDirParts[$partCount] === '..') {
317  if ($partCount >= 1) {
318  // Rremove this and previous element
319  array_splice($theDirParts, $partCount - 1, 2);
320  $partCount -= 2;
321  $theDirPartsCount -= 2;
322  } elseif ($absolutePathPrefix) {
323  // can't go higher than root dir
324  // simply remove this part and continue
325  array_splice($theDirParts, $partCount, 1);
326  $partCount--;
327  $theDirPartsCount--;
328  }
329  }
330  }
331 
332  return $protocol . $absolutePathPrefix . implode('/', $theDirParts);
333  }
334 
342  public static function stripPathSitePrefix($path)
343  {
344  static $pathSiteLength = null;
345 
346  // calculate length when first needed
347  if (!isset($pathSiteLength)) {
348  $pathSiteLength = strlen(PATH_site);
349  }
350  return substr($path, $pathSiteLength);
351  }
352 
353  /*********************
354  *
355  * Helper methods
356  *
357  *********************/
358 
364  protected static function isWindows()
365  {
366  return TYPO3_OS === 'WIN';
367  }
368 }
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
static beginsWith($haystack, $needle)
if(TYPO3_MODE==='BE') $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tsfebeuserauth.php']['frontendEditingController']['default']
static sanitizeTrailingSeparator($path, $separator='/')