Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
path.php
1<?php
2namespace Bitrix\Main\IO;
3
6
10class Path
11{
15
16 const INVALID_FILENAME_CHARS = "\\/:*?\"'<>|~#&;";
17
18 //the pattern should be quoted, "|" is allowed below as a delimiter
19 const INVALID_FILENAME_BYTES = "\xE2\x80\xAE"; //Right-to-Left Override Unicode Character
20
21 protected static $physicalEncoding = "";
22 protected static $logicalEncoding = "";
23
24 protected static $directoryIndex = null;
25
26 public static function normalize($path)
27 {
28 if (!is_string($path) || ($path == ""))
29 return null;
30
31 //slashes doesn't matter for Windows
32 static $pattern = null, $tailPattern;
33 if (!$pattern)
34 {
35 if(strncasecmp(PHP_OS, "WIN", 3) == 0)
36 {
37 //windows
38 $pattern = "'[\\\\/]+'";
39 $tailPattern = "\0.\\/+ ";
40 }
41 else
42 {
43 //unix
44 $pattern = "'[/]+'";
45 $tailPattern = "\0/";
46 }
47 }
48 $pathTmp = preg_replace($pattern, "/", $path);
49
50 if (strpos($pathTmp, "\0") !== false)
51 throw new InvalidPathException($path);
52
53 if (preg_match("#(^|/)(\\.|\\.\\.)(/|\$)#", $pathTmp))
54 {
55 $arPathTmp = explode('/', $pathTmp);
56 $arPathStack = array();
57 foreach ($arPathTmp as $i => $pathPart)
58 {
59 if ($pathPart === '.')
60 continue;
61
62 if ($pathPart === "..")
63 {
64 if (array_pop($arPathStack) === null)
65 throw new InvalidPathException($path);
66 }
67 else
68 {
69 array_push($arPathStack, $pathPart);
70 }
71 }
72 $pathTmp = implode("/", $arPathStack);
73 }
74
75 $pathTmp = rtrim($pathTmp, $tailPattern);
76
77 if (mb_substr($path, 0, 1) === "/" && mb_substr($pathTmp, 0, 1) !== "/")
78 $pathTmp = "/".$pathTmp;
79
80 if ($pathTmp === '')
81 $pathTmp = "/";
82
83 return $pathTmp;
84 }
85
86 public static function getExtension($path)
87 {
88 $path = self::getName($path);
89 if ($path != '')
90 {
91 $pos = Text\UtfSafeString::getLastPosition($path, '.');
92 if ($pos !== false)
93 return mb_substr($path, $pos + 1);
94 }
95 return '';
96 }
97
98 public static function getName($path)
99 {
100 //$path = self::normalize($path);
101
102 $p = Text\UtfSafeString::getLastPosition($path, self::DIRECTORY_SEPARATOR);
103 if ($p !== false)
104 return mb_substr($path, $p + 1);
105
106 return $path;
107 }
108
109 public static function getDirectory($path)
110 {
111 return mb_substr($path, 0, -mb_strlen(self::getName($path)) - 1);
112 }
113
114 public static function convertLogicalToPhysical($path)
115 {
116 if (self::$physicalEncoding == "")
117 self::$physicalEncoding = self::getPhysicalEncoding();
118
119 if (self::$logicalEncoding == "")
120 self::$logicalEncoding = self::getLogicalEncoding();
121
122 if (self::$physicalEncoding == self::$logicalEncoding)
123 return $path;
124
125 return Text\Encoding::convertEncoding($path, self::$logicalEncoding, self::$physicalEncoding);
126 }
127
128 public static function convertPhysicalToLogical($path)
129 {
130 if (self::$physicalEncoding == "")
131 self::$physicalEncoding = self::getPhysicalEncoding();
132
133 if (self::$logicalEncoding == "")
134 self::$logicalEncoding = self::getLogicalEncoding();
135
136 if (self::$physicalEncoding == self::$logicalEncoding)
137 return $path;
138
139 return Text\Encoding::convertEncoding($path, self::$physicalEncoding, self::$logicalEncoding);
140 }
141
142 public static function convertLogicalToUri($path)
143 {
144 if (self::$logicalEncoding == "")
145 self::$logicalEncoding = self::getLogicalEncoding();
146
147 if (self::$directoryIndex == null)
148 self::$directoryIndex = self::getDirectoryIndexArray();
149
150 if (isset(self::$directoryIndex[self::getName($path)]))
151 $path = self::getDirectory($path)."/";
152
153 if ('utf-8' !== self::$logicalEncoding)
154 $path = Text\Encoding::convertEncoding($path, self::$logicalEncoding, 'utf-8');
155
156 return implode('/', array_map("rawurlencode", explode('/', $path)));
157 }
158
159 public static function convertPhysicalToUri($path)
160 {
161 if (self::$physicalEncoding == "")
162 self::$physicalEncoding = self::getPhysicalEncoding();
163
164 if (self::$directoryIndex == null)
165 self::$directoryIndex = self::getDirectoryIndexArray();
166
167 if (isset(self::$directoryIndex[self::getName($path)]))
168 $path = self::getDirectory($path)."/";
169
170 if ('utf-8' !== self::$physicalEncoding)
171 $path = Text\Encoding::convertEncoding($path, self::$physicalEncoding, 'utf-8');
172
173 return implode('/', array_map("rawurlencode", explode('/', $path)));
174 }
175
176 public static function convertUriToPhysical($path)
177 {
178 if (self::$physicalEncoding == "")
179 self::$physicalEncoding = self::getPhysicalEncoding();
180
181 if (self::$directoryIndex == null)
182 self::$directoryIndex = self::getDirectoryIndexArray();
183
184 $path = implode('/', array_map("rawurldecode", explode('/', $path)));
185
186 if ('utf-8' !== self::$physicalEncoding)
187 $path = Text\Encoding::convertEncoding($path, 'utf-8', self::$physicalEncoding);
188
189 return $path;
190 }
191
192 protected static function getLogicalEncoding()
193 {
194 if (defined('BX_UTF'))
195 $logicalEncoding = "utf-8";
196 elseif (defined("SITE_CHARSET") && (SITE_CHARSET <> ''))
197 $logicalEncoding = SITE_CHARSET;
198 elseif (defined("LANG_CHARSET") && (LANG_CHARSET <> ''))
199 $logicalEncoding = LANG_CHARSET;
200 elseif (defined("BX_DEFAULT_CHARSET"))
201 $logicalEncoding = BX_DEFAULT_CHARSET;
202 else
203 $logicalEncoding = "windows-1251";
204
205 return mb_strtolower($logicalEncoding);
206 }
207
208 protected static function getPhysicalEncoding()
209 {
210 $physicalEncoding = defined("BX_FILE_SYSTEM_ENCODING") ? BX_FILE_SYSTEM_ENCODING : "";
211 if ($physicalEncoding == "")
212 {
213 if (mb_strtoupper(mb_substr(PHP_OS, 0, 3)) === "WIN")
214 $physicalEncoding = "windows-1251";
215 else
216 $physicalEncoding = "utf-8";
217 }
218 return mb_strtolower($physicalEncoding);
219 }
220
221 public static function combine()
222 {
223 $numArgs = func_num_args();
224 if ($numArgs <= 0)
225 return "";
226
227 $arParts = array();
228 for ($i = 0; $i < $numArgs; $i++)
229 {
230 $arg = func_get_arg($i);
231 if (is_array($arg))
232 {
233 if (empty($arg))
234 continue;
235
236 foreach ($arg as $v)
237 {
238 if (!is_string($v) || $v == "")
239 continue;
240 $arParts[] = $v;
241 }
242 }
243 elseif (is_string($arg))
244 {
245 if ($arg == "")
246 continue;
247
248 $arParts[] = $arg;
249 }
250 }
251
252 $result = "";
253 foreach ($arParts as $part)
254 {
255 if ($result !== "")
256 $result .= self::DIRECTORY_SEPARATOR;
257 $result .= $part;
258 }
259
260 $result = self::normalize($result);
261
262 return $result;
263 }
264
265 public static function convertRelativeToAbsolute($relativePath)
266 {
267 if (!is_string($relativePath))
268 throw new Main\ArgumentTypeException("relativePath", "string");
269 if ($relativePath == "")
270 throw new Main\ArgumentNullException("relativePath");
271
272 return self::combine($_SERVER["DOCUMENT_ROOT"], $relativePath);
273 }
274
275 public static function convertSiteRelativeToAbsolute($relativePath, $site = null)
276 {
277 if (!is_string($relativePath) || $relativePath == "")
278 $site = SITE_ID;
279
280 $basePath = Main\SiteTable::getDocumentRoot($site);
281
282 return self::combine($basePath, $relativePath);
283 }
284
285 protected static function validateCommon($path)
286 {
287 if (!is_string($path))
288 {
289 return false;
290 }
291
292 if (trim($path) == "")
293 {
294 return false;
295 }
296
297 if (strpos($path, "\0") !== false)
298 {
299 return false;
300 }
301
302 if(preg_match("#(".self::INVALID_FILENAME_BYTES.")#", $path))
303 {
304 return false;
305 }
306
307 return true;
308 }
309
310 public static function validate($path)
311 {
312 if(!static::validateCommon($path))
313 {
314 return false;
315 }
316
317 return (preg_match("#^([a-z]:)?/([^\x01-\x1F".preg_quote(self::INVALID_FILENAME_CHARS, "#")."]+/?)*$#isD", $path) > 0);
318 }
319
320 public static function validateFilename($filename)
321 {
322 if(!static::validateCommon($filename))
323 {
324 return false;
325 }
326
327 return (preg_match("#^[^\x01-\x1F".preg_quote(self::INVALID_FILENAME_CHARS, "#")."]+$#isD", $filename) > 0);
328 }
329
335 public static function replaceInvalidFilename($filename, $callback)
336 {
337 return preg_replace_callback(
338 "#([\x01-\x1F".preg_quote(self::INVALID_FILENAME_CHARS, "#")."]|".self::INVALID_FILENAME_BYTES.")#",
339 $callback,
340 $filename
341 );
342 }
343
348 public static function randomizeInvalidFilename($filename)
349 {
350 return static::replaceInvalidFilename($filename,
351 function()
352 {
353 return chr(rand(97, 122));
354 }
355 );
356 }
357
358 public static function isAbsolute($path)
359 {
360 return (mb_substr($path, 0, 1) === "/") || preg_match("#^[a-z]:/#i", $path);
361 }
362
363 protected static function getDirectoryIndexArray()
364 {
365 static $directoryIndexDefault = array("index.php" => 1, "index.html" => 1, "index.htm" => 1, "index.phtml" => 1, "default.html" => 1, "index.php3" => 1);
366
367 $directoryIndex = Main\Config\Configuration::getValue("directory_index");
368 if ($directoryIndex !== null)
369 return $directoryIndex;
370
371 return $directoryIndexDefault;
372 }
373}
static convertUriToPhysical($path)
Definition path.php:176
const PATH_SEPARATOR
Definition path.php:14
static validate($path)
Definition path.php:310
static convertPhysicalToLogical($path)
Definition path.php:128
static randomizeInvalidFilename($filename)
Definition path.php:348
static validateCommon($path)
Definition path.php:285
static normalize($path)
Definition path.php:26
static isAbsolute($path)
Definition path.php:358
static $logicalEncoding
Definition path.php:22
static $directoryIndex
Definition path.php:24
static getLogicalEncoding()
Definition path.php:192
static convertRelativeToAbsolute($relativePath)
Definition path.php:265
const DIRECTORY_SEPARATOR
Definition path.php:12
static convertPhysicalToUri($path)
Definition path.php:159
static getPhysicalEncoding()
Definition path.php:208
static convertLogicalToPhysical($path)
Definition path.php:114
static convertLogicalToUri($path)
Definition path.php:142
static convertSiteRelativeToAbsolute($relativePath, $site=null)
Definition path.php:275
static getDirectory($path)
Definition path.php:109
const INVALID_FILENAME_BYTES
Definition path.php:19
static getExtension($path)
Definition path.php:86
static validateFilename($filename)
Definition path.php:320
static combine()
Definition path.php:221
const INVALID_FILENAME_CHARS
Definition path.php:16
static getDirectoryIndexArray()
Definition path.php:363
static replaceInvalidFilename($filename, $callback)
Definition path.php:335
static $physicalEncoding
Definition path.php:21
static getName($path)
Definition path.php:98
const DIRECTORY_SEPARATOR_ALT
Definition path.php:13