This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
1 | <?php |
||
2 | |||
3 | /** |
||
4 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||
5 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||
6 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||
7 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||
8 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||
9 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||
10 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||
11 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||
12 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||
13 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||
14 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||
15 | * |
||
16 | * This software consists of voluntary contributions made by many individuals |
||
17 | * and is licensed under the LGPL. For more information please see |
||
18 | * <http://phing.info>. |
||
19 | */ |
||
20 | |||
21 | namespace Phing\Io; |
||
22 | |||
23 | use Exception; |
||
24 | use Phing\Util\StringHelper; |
||
25 | |||
26 | /** |
||
27 | * An abstract representation of file and directory pathnames. |
||
28 | */ |
||
29 | class File |
||
30 | { |
||
31 | /** |
||
32 | * This abstract pathname's normalized pathname string. A normalized |
||
33 | * pathname string uses the default name-separator character and does not |
||
34 | * contain any duplicate or redundant separators. |
||
35 | */ |
||
36 | private $path = ''; |
||
37 | |||
38 | /** |
||
39 | * The length of this abstract pathname's prefix, or zero if it has no prefix. |
||
40 | * |
||
41 | * @var int |
||
42 | */ |
||
43 | private $prefixLength = 0; |
||
44 | |||
45 | /** |
||
46 | * constructor. |
||
47 | * |
||
48 | * @param null|mixed $arg1 |
||
49 | * @param null|mixed $arg2 |
||
50 | * |
||
51 | * @throws IOException |
||
52 | * @throws \InvalidArgumentException |
||
53 | */ |
||
54 | public function __construct($arg1 = null, $arg2 = null) |
||
55 | { |
||
56 | // simulate signature identified constructors |
||
57 | if ($arg1 instanceof File && is_string($arg2)) { |
||
58 | $this->constructFileParentStringChild($arg1, $arg2); |
||
59 | } elseif (is_string($arg1) && (null === $arg2)) { |
||
60 | $this->constructPathname($arg1); |
||
61 | } elseif (is_string($arg1) && is_string($arg2)) { |
||
62 | $this->constructStringParentStringChild($arg1, $arg2); |
||
63 | } else { |
||
64 | if (null === $arg1) { |
||
65 | throw new \InvalidArgumentException('Argument1 to function must not be null'); |
||
66 | } |
||
67 | $this->path = (string) $arg1; |
||
68 | $this->prefixLength = (int) $arg2; |
||
69 | } |
||
70 | } |
||
71 | |||
72 | /** |
||
73 | * Return string representation of the object. |
||
74 | * |
||
75 | * @return string |
||
76 | */ |
||
77 | public function __toString() |
||
78 | { |
||
79 | return $this->getPath(); |
||
80 | } |
||
81 | |||
82 | /** |
||
83 | * Returns the length of this abstract pathname's prefix. |
||
84 | * |
||
85 | * @return int |
||
86 | */ |
||
87 | public function getPrefixLength() |
||
88 | { |
||
89 | return (int) $this->prefixLength; |
||
90 | } |
||
91 | |||
92 | // -- Path-component accessors -- |
||
93 | |||
94 | /** |
||
95 | * Returns the name of the file or directory denoted by this abstract |
||
96 | * pathname. This is just the last name in the pathname's name |
||
97 | * sequence. If the pathname's name sequence is empty, then the empty |
||
98 | * string is returned. |
||
99 | * |
||
100 | * @return string The name of the file or directory denoted by this abstract |
||
101 | * pathname, or the empty string if this pathname's name sequence |
||
102 | * is empty |
||
103 | */ |
||
104 | public function getName() |
||
105 | { |
||
106 | // that's a lastIndexOf |
||
107 | $index = ((($res = strrpos($this->path, FileUtils::getSeparator())) === false) ? -1 : $res); |
||
108 | if ($index < $this->prefixLength) { |
||
109 | return substr($this->path, $this->prefixLength); |
||
110 | } |
||
111 | |||
112 | return substr($this->path, $index + 1); |
||
113 | } |
||
114 | |||
115 | /** |
||
116 | * Returns the pathname string of this abstract pathname's parent, or |
||
117 | * null if this pathname does not name a parent directory. |
||
118 | * |
||
119 | * The parent of an abstract pathname consists of the pathname's prefix, |
||
120 | * if any, and each name in the pathname's name sequence except for the last. |
||
121 | * If the name sequence is empty then the pathname does not name a parent |
||
122 | * directory. |
||
123 | * |
||
124 | * @return string $pathname string of the parent directory named by this |
||
125 | * abstract pathname, or null if this pathname does not name a parent |
||
126 | */ |
||
127 | public function getParent() |
||
128 | { |
||
129 | // that's a lastIndexOf |
||
130 | $index = ((($res = strrpos($this->path, FileUtils::getSeparator())) === false) ? -1 : $res); |
||
131 | if ($index < $this->prefixLength) { |
||
132 | if (($this->prefixLength > 0) && (strlen($this->path) > $this->prefixLength)) { |
||
133 | return substr($this->path, 0, $this->prefixLength); |
||
134 | } |
||
135 | |||
136 | return null; |
||
137 | } |
||
138 | |||
139 | return substr($this->path, 0, $index); |
||
140 | } |
||
141 | |||
142 | /** |
||
143 | * Returns the abstract pathname of this abstract pathname's parent, |
||
144 | * or null if this pathname does not name a parent directory. |
||
145 | * |
||
146 | * The parent of an abstract pathname consists of the pathname's prefix, |
||
147 | * if any, and each name in the pathname's name sequence except for the |
||
148 | * last. If the name sequence is empty then the pathname does not name |
||
149 | * a parent directory. |
||
150 | * |
||
151 | * @return null|File The abstract pathname of the parent directory named by this |
||
152 | * abstract pathname, or null if this pathname |
||
153 | * does not name a parent |
||
154 | */ |
||
155 | public function getParentFile() |
||
156 | { |
||
157 | $p = $this->getParent(); |
||
158 | if (null === $p) { |
||
0 ignored issues
–
show
introduced
by
![]() |
|||
159 | return null; |
||
160 | } |
||
161 | |||
162 | return new File((string) $p, (int) $this->prefixLength); |
||
163 | } |
||
164 | |||
165 | /** |
||
166 | * Converts this abstract pathname into a pathname string. The resulting |
||
167 | * string uses the default name-separator character to separate the names |
||
168 | * in the name sequence. |
||
169 | * |
||
170 | * @return string The string form of this abstract pathname |
||
171 | */ |
||
172 | public function getPath() |
||
173 | { |
||
174 | return (string) $this->path; |
||
175 | } |
||
176 | |||
177 | /** |
||
178 | * Returns path without leading basedir. |
||
179 | * |
||
180 | * @param string $basedir Base directory to strip |
||
181 | * |
||
182 | * @return string Path without basedir |
||
183 | * |
||
184 | * @uses getPath() |
||
185 | */ |
||
186 | public function getPathWithoutBase($basedir) |
||
187 | { |
||
188 | if (!StringHelper::endsWith(FileUtils::getSeparator(), $basedir)) { |
||
189 | $basedir .= FileUtils::getSeparator(); |
||
190 | } |
||
191 | $path = $this->getPath(); |
||
192 | if (substr($path, 0, strlen($basedir)) != $basedir) { |
||
193 | //path does not begin with basedir, we don't modify it |
||
194 | return $path; |
||
195 | } |
||
196 | |||
197 | return substr($path, strlen($basedir)); |
||
198 | } |
||
199 | |||
200 | /** |
||
201 | * Tests whether this abstract pathname is absolute. The definition of |
||
202 | * absolute pathname is system dependent. On UNIX systems, a pathname is |
||
203 | * absolute if its prefix is "/". On Win32 systems, a pathname is absolute |
||
204 | * if its prefix is a drive specifier followed by "\\", or if its prefix |
||
205 | * is "\\". |
||
206 | * |
||
207 | * @return bool true if this abstract pathname is absolute, false otherwise |
||
208 | */ |
||
209 | public function isAbsolute() |
||
210 | { |
||
211 | return 0 !== $this->prefixLength; |
||
212 | } |
||
213 | |||
214 | /** |
||
215 | * Returns the file extension for a given file. For example test.php would be returned as php. |
||
216 | * |
||
217 | * @return string the name of the extension |
||
218 | */ |
||
219 | public function getFileExtension() |
||
220 | { |
||
221 | return pathinfo((string) $this->getAbsolutePath(), PATHINFO_EXTENSION); |
||
0 ignored issues
–
show
|
|||
222 | } |
||
223 | |||
224 | /** |
||
225 | * Returns the absolute pathname string of this abstract pathname. |
||
226 | * |
||
227 | * If this abstract pathname is already absolute, then the pathname |
||
228 | * string is simply returned as if by the getPath method. |
||
229 | * If this abstract pathname is the empty abstract pathname then |
||
230 | * the pathname string of the current user directory, which is named by the |
||
231 | * system property user.dir, is returned. Otherwise this |
||
232 | * pathname is resolved in a system-dependent way. On UNIX systems, a |
||
233 | * relative pathname is made absolute by resolving it against the current |
||
234 | * user directory. On Win32 systems, a relative pathname is made absolute |
||
235 | * by resolving it against the current directory of the drive named by the |
||
236 | * pathname, if any; if not, it is resolved against the current user |
||
237 | * directory. |
||
238 | * |
||
239 | * @return string The absolute pathname string denoting the same file or |
||
240 | * directory as this abstract pathname |
||
241 | * |
||
242 | * @see #isAbsolute() |
||
243 | */ |
||
244 | public function getAbsolutePath() |
||
245 | { |
||
246 | $fs = FileSystem::getFileSystem(); |
||
247 | |||
248 | return $fs->resolveFile($this); |
||
249 | } |
||
250 | |||
251 | /** |
||
252 | * Returns the absolute form of this abstract pathname. Equivalent to |
||
253 | * getAbsolutePath. |
||
254 | * |
||
255 | * @return File The absolute abstract pathname denoting the same file or |
||
256 | * directory as this abstract pathname |
||
257 | */ |
||
258 | public function getAbsoluteFile() |
||
259 | { |
||
260 | return new File((string) $this->getAbsolutePath()); |
||
261 | } |
||
262 | |||
263 | /** |
||
264 | * Returns the canonical pathname string of this abstract pathname. |
||
265 | * |
||
266 | * A canonical pathname is both absolute and unique. The precise |
||
267 | * definition of canonical form is system-dependent. This method first |
||
268 | * converts this pathname to absolute form if necessary, as if by invoking the |
||
269 | * getAbsolutePath() method, and then maps it to its unique form in a |
||
270 | * system-dependent way. This typically involves removing redundant names |
||
271 | * such as "." and .. from the pathname, resolving symbolic links |
||
272 | * (on UNIX platforms), and converting drive letters to a standard case |
||
273 | * (on Win32 platforms). |
||
274 | * |
||
275 | * Every pathname that denotes an existing file or directory has a |
||
276 | * unique canonical form. Every pathname that denotes a nonexistent file |
||
277 | * or directory also has a unique canonical form. The canonical form of |
||
278 | * the pathname of a nonexistent file or directory may be different from |
||
279 | * the canonical form of the same pathname after the file or directory is |
||
280 | * created. Similarly, the canonical form of the pathname of an existing |
||
281 | * file or directory may be different from the canonical form of the same |
||
282 | * pathname after the file or directory is deleted. |
||
283 | * |
||
284 | * @return string The canonical pathname string denoting the same file or |
||
285 | * directory as this abstract pathname |
||
286 | */ |
||
287 | public function getCanonicalPath() |
||
288 | { |
||
289 | $fs = FileSystem::getFileSystem(); |
||
290 | |||
291 | return $fs->canonicalize($this->path); |
||
0 ignored issues
–
show
The expression
return $fs->canonicalize($this->path) could also return false which is incompatible with the documented return type string . Did you maybe forget to handle an error condition?
If the returned type also contains false, it is an indicator that maybe an error condition leading to the specific return statement remains unhandled. ![]() |
|||
292 | } |
||
293 | |||
294 | /** |
||
295 | * Returns the canonical form of this abstract pathname. Equivalent to |
||
296 | * getCanonicalPath(. |
||
297 | * |
||
298 | * @return File The canonical pathname string denoting the same file or |
||
299 | * directory as this abstract pathname |
||
300 | */ |
||
301 | public function getCanonicalFile() |
||
302 | { |
||
303 | return new File($this->getCanonicalPath()); |
||
304 | } |
||
305 | |||
306 | // -- Attribute accessors -- |
||
307 | |||
308 | /** |
||
309 | * Tests whether the application can read the file denoted by this |
||
310 | * abstract pathname. |
||
311 | * |
||
312 | * @return bool true if and only if the file specified by this |
||
313 | * abstract pathname exists and can be read by the |
||
314 | * application; false otherwise |
||
315 | */ |
||
316 | public function canRead() |
||
317 | { |
||
318 | $fs = FileSystem::getFileSystem(); |
||
319 | |||
320 | if ($fs->checkAccess($this)) { |
||
321 | return (bool) @is_link($this->getAbsolutePath()) || @is_readable($this->getAbsolutePath()); |
||
322 | } |
||
323 | |||
324 | return false; |
||
325 | } |
||
326 | |||
327 | /** |
||
328 | * Tests whether the application can modify to the file denoted by this |
||
329 | * abstract pathname. |
||
330 | * |
||
331 | * @return bool true if and only if the file system actually |
||
332 | * contains a file denoted by this abstract pathname and |
||
333 | * the application is allowed to write to the file; |
||
334 | * false otherwise |
||
335 | */ |
||
336 | public function canWrite() |
||
337 | { |
||
338 | $fs = FileSystem::getFileSystem(); |
||
339 | |||
340 | return $fs->checkAccess($this, true); |
||
341 | } |
||
342 | |||
343 | /** |
||
344 | * Tests whether the file denoted by this abstract pathname exists. |
||
345 | * |
||
346 | * @return bool true if and only if the file denoted by this |
||
347 | * abstract pathname exists; false otherwise |
||
348 | */ |
||
349 | public function exists() |
||
350 | { |
||
351 | clearstatcache(); |
||
352 | |||
353 | if (is_link($this->path)) { |
||
354 | return true; |
||
355 | } |
||
356 | |||
357 | if ($this->isDirectory()) { |
||
358 | return true; |
||
359 | } |
||
360 | |||
361 | return @file_exists($this->path) || is_link($this->path); |
||
362 | } |
||
363 | |||
364 | /** |
||
365 | * Tests whether the file denoted by this abstract pathname is a |
||
366 | * directory. |
||
367 | * |
||
368 | * @throws IOException |
||
369 | * |
||
370 | * @return bool true if and only if the file denoted by this |
||
371 | * abstract pathname exists and is a directory; |
||
372 | * false otherwise |
||
373 | */ |
||
374 | public function isDirectory() |
||
375 | { |
||
376 | clearstatcache(); |
||
377 | $fs = FileSystem::getFileSystem(); |
||
378 | if (true !== $fs->checkAccess($this)) { |
||
379 | throw new IOException('No read access to ' . $this->path); |
||
380 | } |
||
381 | |||
382 | return @is_dir($this->path) && !@is_link($this->path); |
||
383 | } |
||
384 | |||
385 | /** |
||
386 | * Tests whether the file denoted by this abstract pathname is a normal |
||
387 | * file. A file is normal if it is not a directory and, in |
||
388 | * addition, satisfies other system-dependent criteria. Any non-directory |
||
389 | * file created by a Java application is guaranteed to be a normal file. |
||
390 | * |
||
391 | * @return bool true if and only if the file denoted by this |
||
392 | * abstract pathname exists and is a normal file; |
||
393 | * false otherwise |
||
394 | */ |
||
395 | public function isFile() |
||
396 | { |
||
397 | clearstatcache(); |
||
398 | //$fs = FileSystem::getFileSystem(); |
||
399 | return @is_file($this->path); |
||
400 | } |
||
401 | |||
402 | /** |
||
403 | * Tests whether the file denoted by this abstract pathname is a symbolic link. |
||
404 | * |
||
405 | * @throws IOException |
||
406 | * |
||
407 | * @return bool true if and only if the file denoted by this |
||
408 | * abstract pathname exists and is a symbolic link; |
||
409 | * false otherwise |
||
410 | */ |
||
411 | public function isLink() |
||
412 | { |
||
413 | clearstatcache(); |
||
414 | $fs = FileSystem::getFileSystem(); |
||
415 | if (true !== $fs->checkAccess($this)) { |
||
416 | throw new IOException('No read access to ' . $this->path); |
||
417 | } |
||
418 | |||
419 | return @is_link($this->path); |
||
420 | } |
||
421 | |||
422 | /** |
||
423 | * Tests whether the file denoted by this abstract pathname is executable. |
||
424 | * |
||
425 | * @throws IOException |
||
426 | * |
||
427 | * @return bool true if and only if the file denoted by this |
||
428 | * abstract pathname exists and is a symbolic link; |
||
429 | * false otherwise |
||
430 | */ |
||
431 | public function isExecutable() |
||
432 | { |
||
433 | clearstatcache(); |
||
434 | $fs = FileSystem::getFileSystem(); |
||
435 | if (true !== $fs->checkAccess($this)) { |
||
436 | throw new IOException('No read access to ' . $this->path); |
||
437 | } |
||
438 | |||
439 | return @is_executable($this->path); |
||
440 | } |
||
441 | |||
442 | /** |
||
443 | * Returns the target of the symbolic link denoted by this abstract pathname. |
||
444 | * |
||
445 | * @return string the target of the symbolic link denoted by this abstract pathname |
||
446 | */ |
||
447 | public function getLinkTarget() |
||
448 | { |
||
449 | return @readlink($this->path); |
||
0 ignored issues
–
show
The expression
return @readlink($this->path) could also return false which is incompatible with the documented return type string . Did you maybe forget to handle an error condition?
If the returned type also contains false, it is an indicator that maybe an error condition leading to the specific return statement remains unhandled. ![]() |
|||
450 | } |
||
451 | |||
452 | /** |
||
453 | * Returns the time that the file denoted by this abstract pathname was |
||
454 | * last modified. |
||
455 | * |
||
456 | * @throws IOException |
||
457 | * |
||
458 | * @return int An int value representing the time the file was |
||
459 | * last modified, measured in seconds since the epoch |
||
460 | * (00:00:00 GMT, January 1, 1970), or 0 if the |
||
461 | * file does not exist or if an I/O error occurs |
||
462 | */ |
||
463 | public function lastModified() |
||
464 | { |
||
465 | $fs = FileSystem::getFileSystem(); |
||
466 | if (true !== $fs->checkAccess($this)) { |
||
467 | throw new IOException('No read access to ' . $this->path); |
||
468 | } |
||
469 | |||
470 | return $fs->getLastModifiedTime($this); |
||
471 | } |
||
472 | |||
473 | /** |
||
474 | * Returns the length of the file denoted by this abstract pathname. |
||
475 | * The return value is unspecified if this pathname denotes a directory. |
||
476 | * |
||
477 | * @throws IOException |
||
478 | * |
||
479 | * @return int The length, in bytes, of the file denoted by this abstract |
||
480 | * pathname, or 0 if the file does not exist |
||
481 | */ |
||
482 | public function length() |
||
483 | { |
||
484 | $fs = FileSystem::getFileSystem(); |
||
485 | if (true !== $fs->checkAccess($this)) { |
||
486 | throw new IOException('No read access to ' . $this->path . "\n"); |
||
487 | } |
||
488 | |||
489 | return $fs->getLength($this); |
||
490 | } |
||
491 | |||
492 | /** |
||
493 | * Convenience method for returning the contents of this file as a string. |
||
494 | * This method uses file_get_contents() to read file in an optimized way. |
||
495 | * |
||
496 | * @throws Exception - if file cannot be read |
||
497 | * |
||
498 | * @return string |
||
499 | */ |
||
500 | public function contents() |
||
501 | { |
||
502 | if (!$this->canRead() || !$this->isFile()) { |
||
503 | throw new IOException('Cannot read file contents!'); |
||
504 | } |
||
505 | |||
506 | return file_get_contents($this->getAbsolutePath()); |
||
507 | } |
||
508 | |||
509 | // -- File operations -- |
||
510 | |||
511 | /** |
||
512 | * Atomically creates a new, empty file named by this abstract pathname if |
||
513 | * and only if a file with this name does not yet exist. The check for the |
||
514 | * existence of the file and the creation of the file if it does not exist |
||
515 | * are a single operation that is atomic with respect to all other |
||
516 | * filesystem activities that might affect the file. |
||
517 | * |
||
518 | * @param bool $parents |
||
519 | * |
||
520 | * @throws IOException |
||
521 | * |
||
522 | * @return bool true if the named file does not exist and was |
||
523 | * successfully created; <code>false</code> if the named file |
||
524 | * already exists |
||
525 | */ |
||
526 | public function createNewFile($parents = true) |
||
527 | { |
||
528 | /** |
||
529 | * @var File $parent |
||
530 | */ |
||
531 | $parent = $this->getParentFile(); |
||
532 | if ($parents && null !== $parent && !$parent->exists()) { |
||
533 | $parent->mkdirs(); |
||
534 | } |
||
535 | |||
536 | return FileSystem::getFileSystem()->createNewFile($this->path); |
||
537 | } |
||
538 | |||
539 | /** |
||
540 | * Deletes the file or directory denoted by this abstract pathname. If |
||
541 | * this pathname denotes a directory, then the directory must be empty in |
||
542 | * order to be deleted. |
||
543 | * |
||
544 | * @param bool $recursive |
||
545 | * |
||
546 | * @throws IOException |
||
547 | */ |
||
548 | public function delete($recursive = false) |
||
549 | { |
||
550 | $fs = FileSystem::getFileSystem(); |
||
551 | if (true !== $fs->canDelete($this)) { |
||
552 | throw new IOException('Cannot delete ' . $this->path . "\n"); |
||
553 | } |
||
554 | |||
555 | $fs->delete($this, $recursive); |
||
556 | } |
||
557 | |||
558 | /** |
||
559 | * Requests that the file or directory denoted by this abstract pathname |
||
560 | * be deleted when php terminates. Deletion will be attempted only for |
||
561 | * normal termination of php and if and if only Phing::shutdown() is |
||
562 | * called. |
||
563 | * |
||
564 | * Once deletion has been requested, it is not possible to cancel the |
||
565 | * request. This method should therefore be used with care. |
||
566 | */ |
||
567 | public function deleteOnExit() |
||
568 | { |
||
569 | $fs = FileSystem::getFileSystem(); |
||
570 | $fs->deleteOnExit($this); |
||
571 | } |
||
572 | |||
573 | /** |
||
574 | * Returns an array of strings naming the files and directories in the |
||
575 | * directory denoted by this abstract pathname. |
||
576 | * |
||
577 | * If this abstract pathname does not denote a directory, then this |
||
578 | * method returns null Otherwise an array of strings is |
||
579 | * returned, one for each file or directory in the directory. Names |
||
580 | * denoting the directory itself and the directory's parent directory are |
||
581 | * not included in the result. Each string is a file name rather than a |
||
582 | * complete path. |
||
583 | * |
||
584 | * There is no guarantee that the name strings in the resulting array |
||
585 | * will appear in any specific order; they are not, in particular, |
||
586 | * guaranteed to appear in alphabetical order. |
||
587 | * |
||
588 | * @return null|array An array of strings naming the files and directories in the |
||
589 | * directory denoted by this abstract pathname. The array will be |
||
590 | * empty if the directory is empty. Returns null if |
||
591 | * this abstract pathname does not denote a directory, or if an |
||
592 | * I/O error occurs. |
||
593 | */ |
||
594 | public function listDir(): ?array |
||
595 | { |
||
596 | try { |
||
597 | $elements = FileSystem::getFileSystem()->listContents($this); |
||
598 | } catch (IOException $e) { |
||
599 | $elements = null; |
||
600 | } |
||
601 | |||
602 | return $elements; |
||
603 | } |
||
604 | |||
605 | /** |
||
606 | * Creates the directory named by this abstract pathname, including any |
||
607 | * necessary but nonexistent parent directories. Note that if this |
||
608 | * operation fails it may have succeeded in creating some of the necessary |
||
609 | * parent directories. |
||
610 | * |
||
611 | * @param null|int $mode |
||
612 | * |
||
613 | * @throws IOException |
||
614 | * |
||
615 | * @return bool true if and only if the directory was created, |
||
616 | * along with all necessary parent directories; false |
||
617 | * otherwise |
||
618 | */ |
||
619 | public function mkdirs($mode = null) |
||
620 | { |
||
621 | if ($this->exists()) { |
||
622 | return false; |
||
623 | } |
||
624 | |||
625 | try { |
||
626 | if ($this->mkdir($mode)) { |
||
627 | return true; |
||
628 | } |
||
629 | } catch (IOException $ioe) { |
||
630 | // IOException from mkdir() means that directory propbably didn't exist. |
||
631 | } |
||
632 | $parentFile = $this->getParentFile(); |
||
633 | |||
634 | return (null !== $parentFile) && ($parentFile->mkdirs() && $this->mkdir($mode)); |
||
635 | } |
||
636 | |||
637 | /** |
||
638 | * Creates the directory named by this abstract pathname. |
||
639 | * |
||
640 | * @param null|int $mode |
||
641 | * |
||
642 | * @throws IOException |
||
643 | * |
||
644 | * @return bool true if and only if the directory was created; false otherwise |
||
645 | */ |
||
646 | public function mkdir($mode = null) |
||
647 | { |
||
648 | $fs = FileSystem::getFileSystem(); |
||
649 | |||
650 | if (true !== $fs->checkAccess(new File($this->path), true)) { |
||
651 | throw new IOException('No write access to ' . $this->getPath()); |
||
652 | } |
||
653 | |||
654 | return $fs->createDirectory($this, $mode); |
||
655 | } |
||
656 | |||
657 | /** |
||
658 | * Renames the file denoted by this abstract pathname. |
||
659 | * |
||
660 | * @param File $destFile The new abstract pathname for the named file |
||
661 | * |
||
662 | * @throws IOException |
||
663 | */ |
||
664 | public function renameTo(File $destFile) |
||
665 | { |
||
666 | $fs = FileSystem::getFileSystem(); |
||
667 | if (true !== $fs->checkAccess($this)) { |
||
668 | throw new IOException('No write access to ' . $this->getPath()); |
||
669 | } |
||
670 | |||
671 | $fs->rename($this, $destFile); |
||
672 | } |
||
673 | |||
674 | /** |
||
675 | * Simple-copies file denoted by this abstract pathname into another |
||
676 | * PhingFile. |
||
677 | * |
||
678 | * @param File $destFile The new abstract pathname for the named file |
||
679 | * |
||
680 | * @throws IOException |
||
681 | */ |
||
682 | public function copyTo(File $destFile) |
||
683 | { |
||
684 | $fs = FileSystem::getFileSystem(); |
||
685 | |||
686 | if (true !== $fs->checkAccess($this)) { |
||
687 | throw new IOException('No read access to ' . $this->getPath() . "\n"); |
||
688 | } |
||
689 | |||
690 | if (true !== $fs->checkAccess($destFile, true)) { |
||
691 | throw new IOException('File::copyTo() No write access to ' . $destFile->getPath()); |
||
692 | } |
||
693 | |||
694 | $fs->copy($this, $destFile); |
||
695 | } |
||
696 | |||
697 | /** |
||
698 | * Sets the last-modified time of the file or directory named by this |
||
699 | * abstract pathname. |
||
700 | * |
||
701 | * All platforms support file-modification times to the nearest second, |
||
702 | * but some provide more precision. The argument will be truncated to fit |
||
703 | * the supported precision. If the operation succeeds and no intervening |
||
704 | * operations on the file take place, then the next invocation of the |
||
705 | * lastModified method will return the (possibly truncated) time argument |
||
706 | * that was passed to this method. |
||
707 | * |
||
708 | * @param int $time The new last-modified time, measured in milliseconds since |
||
709 | * the epoch (00:00:00 GMT, January 1, 1970) |
||
710 | * |
||
711 | * @throws Exception |
||
712 | */ |
||
713 | public function setLastModified($time) |
||
714 | { |
||
715 | $time = (int) $time; |
||
716 | if ($time < 0) { |
||
717 | throw new Exception("IllegalArgumentException, Negative {$time}\n"); |
||
718 | } |
||
719 | |||
720 | $fs = FileSystem::getFileSystem(); |
||
721 | |||
722 | $fs->setLastModifiedTime($this, $time); |
||
723 | } |
||
724 | |||
725 | /** |
||
726 | * Sets the owner of the file. |
||
727 | * |
||
728 | * @param mixed $user user name or number |
||
729 | * |
||
730 | * @throws IOException |
||
731 | */ |
||
732 | public function setUser($user) |
||
733 | { |
||
734 | $fs = FileSystem::getFileSystem(); |
||
735 | |||
736 | $fs->chown($this->getPath(), $user); |
||
737 | } |
||
738 | |||
739 | /** |
||
740 | * Sets the group of the file. |
||
741 | * |
||
742 | * @param string $group |
||
743 | * |
||
744 | * @throws IOException |
||
745 | */ |
||
746 | public function setGroup($group) |
||
747 | { |
||
748 | $fs = FileSystem::getFileSystem(); |
||
749 | |||
750 | $fs->chgrp($this->getPath(), $group); |
||
751 | } |
||
752 | |||
753 | /** |
||
754 | * Sets the mode of the file. |
||
755 | * |
||
756 | * @param int $mode octal mode |
||
757 | * |
||
758 | * @throws IOException |
||
759 | */ |
||
760 | public function setMode($mode) |
||
761 | { |
||
762 | $fs = FileSystem::getFileSystem(); |
||
763 | |||
764 | $fs->chmod($this->getPath(), $mode); |
||
765 | } |
||
766 | |||
767 | /** |
||
768 | * Retrieve the mode of this file. |
||
769 | * |
||
770 | * @return int |
||
771 | */ |
||
772 | public function getMode() |
||
773 | { |
||
774 | return @fileperms($this->getPath()); |
||
0 ignored issues
–
show
The expression
return @fileperms($this->getPath()) could also return false which is incompatible with the documented return type integer . Did you maybe forget to handle an error condition?
If the returned type also contains false, it is an indicator that maybe an error condition leading to the specific return statement remains unhandled. ![]() |
|||
775 | } |
||
776 | |||
777 | // -- Basic infrastructure -- |
||
778 | |||
779 | /** |
||
780 | * Compares two abstract pathnames lexicographically. The ordering |
||
781 | * defined by this method depends upon the underlying system. On UNIX |
||
782 | * systems, alphabetic case is significant in comparing pathnames; on Win32 |
||
783 | * systems it is not. |
||
784 | * |
||
785 | * @param File $file th file whose pathname sould be compared to the pathname of this file |
||
786 | * |
||
787 | * @return int Zero if the argument is equal to this abstract pathname, a |
||
788 | * value less than zero if this abstract pathname is |
||
789 | * lexicographically less than the argument, or a value greater |
||
790 | * than zero if this abstract pathname is lexicographically |
||
791 | * greater than the argument |
||
792 | */ |
||
793 | public function compareTo(File $file) |
||
794 | { |
||
795 | $fs = FileSystem::getFileSystem(); |
||
796 | |||
797 | return $fs->compare($this, $file); |
||
798 | } |
||
799 | |||
800 | /** |
||
801 | * Tests this abstract pathname for equality with the given object. |
||
802 | * Returns <code>true</code> if and only if the argument is not |
||
803 | * <code>null</code> and is an abstract pathname that denotes the same file |
||
804 | * or directory as this abstract pathname. Whether or not two abstract |
||
805 | * pathnames are equal depends upon the underlying system. On UNIX |
||
806 | * systems, alphabetic case is significant in comparing pathnames; on Win32 |
||
807 | * systems it is not. |
||
808 | * |
||
809 | * @param File $obj |
||
810 | * |
||
811 | * @return bool |
||
812 | */ |
||
813 | public function equals($obj) |
||
814 | { |
||
815 | if ((null !== $obj) && ($obj instanceof File)) { |
||
816 | return 0 === $this->compareTo($obj); |
||
817 | } |
||
818 | |||
819 | return false; |
||
820 | } |
||
821 | |||
822 | // -- constructors not called by signature match, so we need some helpers -- |
||
823 | |||
824 | /** |
||
825 | * @throws IOException |
||
826 | */ |
||
827 | protected function constructPathname(string $pathname): void |
||
828 | { |
||
829 | $fs = FileSystem::getFileSystem(); |
||
830 | |||
831 | $this->path = (string) $fs->normalize($pathname); |
||
832 | $this->prefixLength = (int) $fs->prefixLength($this->path); |
||
833 | } |
||
834 | |||
835 | /** |
||
836 | * @throws IOException |
||
837 | */ |
||
838 | protected function constructStringParentStringChild(string $parent, string $child): void |
||
839 | { |
||
840 | $fs = FileSystem::getFileSystem(); |
||
841 | |||
842 | if ('' === $parent) { |
||
843 | $this->path = $fs->resolve($fs->getDefaultParent(), $fs->normalize($child)); |
||
844 | } else { |
||
845 | $this->path = $fs->resolve($fs->normalize($parent), $fs->normalize($child)); |
||
846 | } |
||
847 | |||
848 | $this->prefixLength = (int) $fs->prefixLength($this->path); |
||
849 | } |
||
850 | |||
851 | /** |
||
852 | * @throws IOException |
||
853 | */ |
||
854 | protected function constructFileParentStringChild(File $parent, string $child): void |
||
855 | { |
||
856 | $fs = FileSystem::getFileSystem(); |
||
857 | |||
858 | if ('' === $parent->path) { |
||
859 | $this->path = $fs->resolve($fs->getDefaultParent(), $fs->normalize($child)); |
||
860 | } else { |
||
861 | $this->path = $fs->resolve($parent->path, $fs->normalize($child)); |
||
862 | } |
||
863 | |||
864 | $this->prefixLength = $fs->prefixLength($this->path); |
||
865 | } |
||
866 | } |
||
867 |