[BUGFIX] Preview images not rendered in Web > Page view on Windows systems
[Packages/TYPO3.CMS.git] / typo3 / sysext / core / Classes / Utility / PathUtility.php
1 <?php
2 namespace TYPO3\CMS\Core\Utility;
3
4 /***************************************************************
5 * Copyright notice
6 *
7 * (c) 2012 Oliver Hader <oliver.hader@typo3.org>
8 * All rights reserved
9 *
10 * This script is part of the TYPO3 project. The TYPO3 project is
11 * free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * The GNU General Public License can be found at
17 * http://www.gnu.org/copyleft/gpl.html.
18 * A copy is found in the textfile GPL.txt and important notices to the license
19 * from the author is found in LICENSE.txt distributed with these scripts.
20 *
21 *
22 * This script is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
26 *
27 * This copyright notice MUST APPEAR in all copies of the script!
28 ***************************************************************/
29 /**
30 * Class with helper functions for file paths.
31 *
32 * @author Oliver Hader <oliver.hader@typo3.org>
33 * @package TYPO3
34 * @subpackage t3lib
35 */
36 class PathUtility {
37
38 /**
39 * Gets the relative path from the current used script to a given directory.
40 * The allowed TYPO3 path is checked as well, thus it's not possible to go to upper levels.
41 *
42 * @param string $targetPath Absolute target path
43 * @return NULL|string
44 */
45 static public function getRelativePathTo($targetPath) {
46 return self::getRelativePath(dirname(PATH_thisScript), $targetPath);
47 }
48
49 /**
50 * Gets the relative path from a source directory to a target directory.
51 * The allowed TYPO3 path is checked as well, thus it's not possible to go to upper levels.
52 *
53 * @param string $sourcePath Absolute source path
54 * @param string $targetPath Absolute target path
55 * @return NULL|string
56 */
57 static public function getRelativePath($sourcePath, $targetPath) {
58 $relativePath = NULL;
59 $sourcePath = rtrim(GeneralUtility::fixWindowsFilePath($sourcePath), '/');
60 $targetPath = rtrim(GeneralUtility::fixWindowsFilePath($targetPath), '/');
61 if ($sourcePath !== $targetPath) {
62 $commonPrefix = self::getCommonPrefix(array($sourcePath, $targetPath));
63 if ($commonPrefix !== NULL && \TYPO3\CMS\Core\Utility\GeneralUtility::isAllowedAbsPath($commonPrefix)) {
64 $commonPrefixLength = strlen($commonPrefix);
65 $resolvedSourcePath = '';
66 $resolvedTargetPath = '';
67 $sourcePathSteps = 0;
68 if (strlen($sourcePath) > $commonPrefixLength) {
69 $resolvedSourcePath = (string) substr($sourcePath, $commonPrefixLength);
70 }
71 if (strlen($targetPath) > $commonPrefixLength) {
72 $resolvedTargetPath = (string) substr($targetPath, $commonPrefixLength);
73 }
74 if ($resolvedSourcePath !== '') {
75 $sourcePathSteps = count(explode('/', $resolvedSourcePath));
76 }
77 $relativePath = self::sanitizeTrailingSeparator(str_repeat('../', $sourcePathSteps) . $resolvedTargetPath);
78 }
79 }
80 return $relativePath;
81 }
82
83 /**
84 * Gets the common path prefix out of many paths.
85 * + /var/www/domain.com/typo3/sysext/cms/
86 * + /var/www/domain.com/typo3/sysext/em/
87 * + /var/www/domain.com/typo3/sysext/file/
88 * = /var/www/domain.com/typo3/sysext/
89 *
90 * @param array $paths Paths to be processed
91 * @return NULL|string
92 */
93 static public function getCommonPrefix(array $paths) {
94 $paths = array_map(array('TYPO3\\CMS\\Core\\Utility\\GeneralUtility', 'fixWindowsFilePath'), $paths);
95 $commonPath = NULL;
96 if (count($paths) === 1) {
97 $commonPath = array_shift($paths);
98 } elseif (count($paths) > 1) {
99 $parts = explode('/', array_shift($paths));
100 $comparePath = '';
101 $break = FALSE;
102 foreach ($parts as $part) {
103 $comparePath .= $part . '/';
104 foreach ($paths as $path) {
105 if (strpos($path . '/', $comparePath) !== 0) {
106 $break = TRUE;
107 break;
108 }
109 }
110 if ($break) {
111 break;
112 }
113 $commonPath = $comparePath;
114 }
115 }
116 if ($commonPath !== NULL) {
117 $commonPath = self::sanitizeTrailingSeparator($commonPath, '/');
118 }
119 return $commonPath;
120 }
121
122 /**
123 * Sanitizes a trailing separator.
124 * (e.g. 'some/path' -> 'some/path/')
125 *
126 * @param string $path The path to be sanitized
127 * @param string $separator The separator to be used
128 * @return string
129 */
130 static public function sanitizeTrailingSeparator($path, $separator = '/') {
131 return rtrim($path, $separator) . $separator;
132 }
133
134 }
135
136
137 ?>