TYPO3 CMS  TYPO3_6-2
PathUtility.php
Go to the documentation of this file.
1 <?php
2 namespace TYPO3\CMS\Core\Utility;
3 
22 class PathUtility {
23 
31  static public function getRelativePathTo($targetPath) {
32  return self::getRelativePath(dirname(PATH_thisScript), $targetPath);
33  }
34 
41  public static function getAbsoluteWebPath($targetPath) {
42  if (self::isAbsolutePath($targetPath)) {
43  if (strpos($targetPath, PATH_site) === 0) {
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 
60  return $targetPath;
61  }
62 
71  static public function getRelativePath($sourcePath, $targetPath) {
72  $relativePath = NULL;
73  $sourcePath = rtrim(GeneralUtility::fixWindowsFilePath($sourcePath), '/');
74  $targetPath = rtrim(GeneralUtility::fixWindowsFilePath($targetPath), '/');
75  if ($sourcePath !== $targetPath) {
76  $commonPrefix = self::getCommonPrefix(array($sourcePath, $targetPath));
77  if ($commonPrefix !== NULL && \TYPO3\CMS\Core\Utility\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  static public function getCommonPrefix(array $paths) {
108  $paths = array_map(array('TYPO3\\CMS\\Core\\Utility\\GeneralUtility', 'fixWindowsFilePath'), $paths);
109  $commonPath = NULL;
110  if (count($paths) === 1) {
111  $commonPath = array_shift($paths);
112  } elseif (count($paths) > 1) {
113  $parts = explode('/', array_shift($paths));
114  $comparePath = '';
115  $break = FALSE;
116  foreach ($parts as $part) {
117  $comparePath .= $part . '/';
118  foreach ($paths as $path) {
119  if (strpos($path . '/', $comparePath) !== 0) {
120  $break = TRUE;
121  break;
122  }
123  }
124  if ($break) {
125  break;
126  }
127  $commonPath = $comparePath;
128  }
129  }
130  if ($commonPath !== NULL) {
131  $commonPath = self::sanitizeTrailingSeparator($commonPath, '/');
132  }
133  return $commonPath;
134  }
135 
144  static public function sanitizeTrailingSeparator($path, $separator = '/') {
145  return rtrim($path, $separator) . $separator;
146  }
147 
161  static public function basename($path) {
162  $currentLocale = setlocale(LC_CTYPE, 0);
163  setlocale(LC_CTYPE, $GLOBALS['TYPO3_CONF_VARS']['SYS']['systemLocale']);
164  $basename = basename($path);
165  setlocale(LC_CTYPE, $currentLocale);
166  return $basename;
167  }
168 
182  static public function dirname($path) {
183  $currentLocale = setlocale(LC_CTYPE, 0);
184  setlocale(LC_CTYPE, $GLOBALS['TYPO3_CONF_VARS']['SYS']['systemLocale']);
185  $dirname = dirname($path);
186  setlocale(LC_CTYPE, $currentLocale);
187  return $dirname;
188  }
189 
204  static public function pathinfo($path, $options = NULL) {
205  $currentLocale = setlocale(LC_CTYPE, 0);
206  setlocale(LC_CTYPE, $GLOBALS['TYPO3_CONF_VARS']['SYS']['systemLocale']);
207  $pathinfo = $options == NULL ? pathinfo($path) : pathinfo($path, $options);
208  setlocale(LC_CTYPE, $currentLocale);
209  return $pathinfo;
210  }
211 
218  static public function isAbsolutePath($path) {
219  // On Windows also a path starting with a drive letter is absolute: X:/
220  if (static::isWindows() && (substr($path, 1, 2) === ':/' || substr($path, 1, 2) === ':\\')) {
221  return TRUE;
222  }
223  // Path starting with a / is always absolute, on every system
224  return $path[0] === '/';
225  }
226 
250  static public function getAbsolutePathOfRelativeReferencedFileOrPath($baseFilenameOrPath, $includeFileName) {
251  $fileName = static::basename($includeFileName);
252  $basePath = substr($baseFilenameOrPath, -1) === '/' ? $baseFilenameOrPath : static::dirname($baseFilenameOrPath);
253  $newDir = static::getCanonicalPath($basePath . '/' . static::dirname($includeFileName));
254  // Avoid double slash on empty path
255  $result = (($newDir !== '/') ? $newDir : '') . '/' . $fileName;
256  return $result;
257  }
258 
259 
260  /*********************
261  *
262  * Cleaning methods
263  *
264  *********************/
271  static public function getCanonicalPath($path) {
272  // Replace backslashes with slashes to work with Windows paths if given
273  $path = trim(str_replace('\\', '/', $path));
274 
275  // TODO: do we really need this? Probably only in testing context for vfs?
276  $protocol = '';
277  if (strpos($path, '://') !== FALSE) {
278  list($protocol, $path) = explode('://', $path);
279  $protocol .= '://';
280  }
281 
282  $absolutePathPrefix = '';
283  if (static::isAbsolutePath($path)) {
284  if (static::isWindows() && substr($path, 1, 2) === ':/') {
285  $absolutePathPrefix = substr($path, 0, 3);
286  $path = substr($path, 3);
287  } else {
288  $path = ltrim($path, '/');
289  $absolutePathPrefix = '/';
290  }
291  }
292 
293  $theDirParts = explode('/', $path);
294  $theDirPartsCount = count($theDirParts);
295  for ($partCount = 0; $partCount < $theDirPartsCount; $partCount++) {
296  // double-slashes in path: remove element
297  if ($theDirParts[$partCount] === '') {
298  array_splice($theDirParts, $partCount, 1);
299  $partCount--;
300  $theDirPartsCount--;
301  }
302  // "." in path: remove element
303  if ($theDirParts[$partCount] === '.') {
304  array_splice($theDirParts, $partCount, 1);
305  $partCount--;
306  $theDirPartsCount--;
307  }
308  // ".." in path:
309  if ($theDirParts[$partCount] === '..') {
310  if ($partCount >= 1) {
311  // Rremove this and previous element
312  array_splice($theDirParts, $partCount - 1, 2);
313  $partCount -= 2;
314  $theDirPartsCount -= 2;
315  } elseif ($absolutePathPrefix) {
316  // can't go higher than root dir
317  // simply remove this part and continue
318  array_splice($theDirParts, $partCount, 1);
319  $partCount--;
320  $theDirPartsCount--;
321  }
322  }
323  }
324 
325  return $protocol . $absolutePathPrefix . implode('/', $theDirParts);
326  }
327 
335  static public function stripPathSitePrefix($path) {
336  static $pathSiteLength = NULL;
337 
338  // calculate length when first needed
339  if (!isset($pathSiteLength)) {
340  $pathSiteLength = strlen(PATH_site);
341  }
342  return substr($path, $pathSiteLength);
343  }
344 
345  /*********************
346  *
347  * Helper methods
348  *
349  *********************/
350 
356  static protected function isWindows() {
357  return TYPO3_OS === 'WIN';
358  }
359 
360 }
static getRelativePathTo($targetPath)
Definition: PathUtility.php:31
static getCommonPrefix(array $paths)
static getAbsoluteWebPath($targetPath)
Definition: PathUtility.php:41
static pathinfo($path, $options=NULL)
static getAbsolutePathOfRelativeReferencedFileOrPath($baseFilenameOrPath, $includeFileName)
if($list_of_literals) if(!empty($literals)) if(!empty($literals)) $result
Analyse literals to prepend the N char to them if their contents aren&#39;t numeric.
static getRelativePath($sourcePath, $targetPath)
Definition: PathUtility.php:71
if(!defined('TYPO3_MODE')) $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_userauth.php']['logoff_pre_processing'][]
static sanitizeTrailingSeparator($path, $separator='/')