3ec139ce2f2990920d89021778ebba76944d18b5
[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-2013 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 */
34 class PathUtility {
35
36 /**
37 * Gets the relative path from the current used script to a given directory.
38 * The allowed TYPO3 path is checked as well, thus it's not possible to go to upper levels.
39 *
40 * @param string $targetPath Absolute target path
41 * @return NULL|string
42 */
43 static public function getRelativePathTo($targetPath) {
44 return self::getRelativePath(dirname(PATH_thisScript), $targetPath);
45 }
46
47 /**
48 * Gets the relative path from a source directory to a target directory.
49 * The allowed TYPO3 path is checked as well, thus it's not possible to go to upper levels.
50 *
51 * @param string $sourcePath Absolute source path
52 * @param string $targetPath Absolute target path
53 * @return NULL|string
54 */
55 static public function getRelativePath($sourcePath, $targetPath) {
56 $relativePath = NULL;
57 $sourcePath = rtrim(GeneralUtility::fixWindowsFilePath($sourcePath), '/');
58 $targetPath = rtrim(GeneralUtility::fixWindowsFilePath($targetPath), '/');
59 if ($sourcePath !== $targetPath) {
60 $commonPrefix = self::getCommonPrefix(array($sourcePath, $targetPath));
61 if ($commonPrefix !== NULL && \TYPO3\CMS\Core\Utility\GeneralUtility::isAllowedAbsPath($commonPrefix)) {
62 $commonPrefixLength = strlen($commonPrefix);
63 $resolvedSourcePath = '';
64 $resolvedTargetPath = '';
65 $sourcePathSteps = 0;
66 if (strlen($sourcePath) > $commonPrefixLength) {
67 $resolvedSourcePath = (string) substr($sourcePath, $commonPrefixLength);
68 }
69 if (strlen($targetPath) > $commonPrefixLength) {
70 $resolvedTargetPath = (string) substr($targetPath, $commonPrefixLength);
71 }
72 if ($resolvedSourcePath !== '') {
73 $sourcePathSteps = count(explode('/', $resolvedSourcePath));
74 }
75 $relativePath = self::sanitizeTrailingSeparator(str_repeat('../', $sourcePathSteps) . $resolvedTargetPath);
76 }
77 }
78 return $relativePath;
79 }
80
81 /**
82 * Gets the common path prefix out of many paths.
83 * + /var/www/domain.com/typo3/sysext/cms/
84 * + /var/www/domain.com/typo3/sysext/em/
85 * + /var/www/domain.com/typo3/sysext/file/
86 * = /var/www/domain.com/typo3/sysext/
87 *
88 * @param array $paths Paths to be processed
89 * @return NULL|string
90 */
91 static public function getCommonPrefix(array $paths) {
92 $paths = array_map(array('TYPO3\\CMS\\Core\\Utility\\GeneralUtility', 'fixWindowsFilePath'), $paths);
93 $commonPath = NULL;
94 if (count($paths) === 1) {
95 $commonPath = array_shift($paths);
96 } elseif (count($paths) > 1) {
97 $parts = explode('/', array_shift($paths));
98 $comparePath = '';
99 $break = FALSE;
100 foreach ($parts as $part) {
101 $comparePath .= $part . '/';
102 foreach ($paths as $path) {
103 if (strpos($path . '/', $comparePath) !== 0) {
104 $break = TRUE;
105 break;
106 }
107 }
108 if ($break) {
109 break;
110 }
111 $commonPath = $comparePath;
112 }
113 }
114 if ($commonPath !== NULL) {
115 $commonPath = self::sanitizeTrailingSeparator($commonPath, '/');
116 }
117 return $commonPath;
118 }
119
120 /**
121 * Sanitizes a trailing separator.
122 * (e.g. 'some/path' -> 'some/path/')
123 *
124 * @param string $path The path to be sanitized
125 * @param string $separator The separator to be used
126 * @return string
127 */
128 static public function sanitizeTrailingSeparator($path, $separator = '/') {
129 return rtrim($path, $separator) . $separator;
130 }
131
132
133 /**
134 * Returns trailing name component of path
135 * Since basename() is locale dependent we need to access
136 * the filesystem with the same locale of the system, not
137 * the rendering context.
138 * @see http://www.php.net/manual/en/function.basename.php
139 *
140 *
141 * @param string $path
142 *
143 * @return string
144 *
145 */
146 static public function basename($path) {
147 $currentLocale = setlocale(LC_CTYPE, 0);
148 setlocale(LC_CTYPE, $GLOBALS['TYPO3_CONF_VARS']['SYS']['systemLocale']);
149 $basename = basename($path);
150 setlocale(LC_CTYPE, $currentLocale);
151 return $basename;
152 }
153
154 /**
155 * Returns parent directory's path
156 * Since dirname() is locale dependent we need to access
157 * the filesystem with the same locale of the system, not
158 * the rendering context.
159 * @see http://www.php.net/manual/en/function.dirname.php
160 *
161 *
162 * @param string $path
163 *
164 * @return string
165 *
166 */
167 static public function dirname($path) {
168 $currentLocale = setlocale(LC_CTYPE, 0);
169 setlocale(LC_CTYPE, $GLOBALS['TYPO3_CONF_VARS']['SYS']['systemLocale']);
170 $dirname = dirname($path);
171 setlocale(LC_CTYPE, $currentLocale);
172 return $dirname;
173 }
174
175 /**
176 * Returns parent directory's path
177 * Since dirname() is locale dependent we need to access
178 * the filesystem with the same locale of the system, not
179 * the rendering context.
180 * @see http://www.php.net/manual/en/function.dirname.php
181 *
182 *
183 * @param string $path
184 * @param integer $options
185 *
186 * @return string|array
187 *
188 */
189 static public function pathinfo($path, $options = NULL) {
190 $currentLocale = setlocale(LC_CTYPE, 0);
191 setlocale(LC_CTYPE, $GLOBALS['TYPO3_CONF_VARS']['SYS']['systemLocale']);
192 $pathinfo = $options == NULL ? pathinfo($path) : pathinfo($path, $options);
193 setlocale(LC_CTYPE, $currentLocale);
194 return $pathinfo;
195 }
196 }
197
198
199 ?>