PluginProbe
WPIDE – File Manager & Code Editor / 3.5.9
WPIDE – File Manager & Code Editor v3.5.9
3.5.9 3.5.8 3.5.7 2.0.14 2.0.15 2.0.16 2.0.2 2.0.4 2.0.5 2.0.6 2.0.7 2.0.8 2.0.9 2.1 2.2 2.3 2.3.1 2.3.2 2.4.0 2.5 2.6 3.0 3.1 3.2 3.3 All 55 releases
wpide / vendor / league / flysystem / src / Adapter / Local.php

Local.php in WPIDE – File Manager & Code Editor 3.5.9, at vendor/league/flysystem/src/Adapter/Local.php

534 lines 12.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace League\Flysystem\Adapter;
4
5 use DirectoryIterator;
6 use FilesystemIterator;
7 use finfo as Finfo;
8 use League\Flysystem\Config;
9 use League\Flysystem\Exception;
10 use League\Flysystem\NotSupportedException;
11 use League\Flysystem\UnreadableFileException;
12 use League\Flysystem\Util;
13 use LogicException;
14 use RecursiveDirectoryIterator;
15 use RecursiveIteratorIterator;
16 use SplFileInfo;
17
18 class Local extends AbstractAdapter
19 {
20 /**
21 * @var int
22 */
23 const SKIP_LINKS = 0001;
24
25 /**
26 * @var int
27 */
28 const DISALLOW_LINKS = 0002;
29
30 /**
31 * @var array
32 */
33 protected static $permissions = [
34 'file' => [
35 'public' => 0644,
36 'private' => 0600,
37 ],
38 'dir' => [
39 'public' => 0755,
40 'private' => 0700,
41 ],
42 ];
43
44 /**
45 * @var string
46 */
47 protected $pathSeparator = DIRECTORY_SEPARATOR;
48
49 /**
50 * @var array
51 */
52 protected $permissionMap;
53
54 /**
55 * @var int
56 */
57 protected $writeFlags;
58
59 /**
60 * @var int
61 */
62 private $linkHandling;
63
64 /**
65 * Constructor.
66 *
67 * @param string $root
68 * @param int $writeFlags
69 * @param int $linkHandling
70 * @param array $permissions
71 *
72 * @throws LogicException
73 */
74 public function __construct($root, $writeFlags = LOCK_EX, $linkHandling = self::DISALLOW_LINKS, array $permissions = [])
75 {
76 $root = is_link($root) ? realpath($root) : $root;
77 $this->permissionMap = array_replace_recursive(static::$permissions, $permissions);
78 $this->ensureDirectory($root);
79
80 if ( ! is_dir($root) || ! is_readable($root)) {
81 throw new LogicException('The root path ' . $root . ' is not readable.');
82 }
83
84 $this->setPathPrefix($root);
85 $this->writeFlags = $writeFlags;
86 $this->linkHandling = $linkHandling;
87 }
88
89 /**
90 * Ensure the root directory exists.
91 *
92 * @param string $root root directory path
93 *
94 * @return void
95 *
96 * @throws Exception in case the root directory can not be created
97 */
98 protected function ensureDirectory($root)
99 {
100 if ( ! is_dir($root)) {
101 $umask = umask(0);
102
103 if ( ! @mkdir($root, $this->permissionMap['dir']['public'], true)) {
104 $mkdirError = error_get_last();
105 }
106
107 umask($umask);
108 clearstatcache(false, $root);
109
110 if ( ! is_dir($root)) {
111 $errorMessage = isset($mkdirError['message']) ? $mkdirError['message'] : '';
112 throw new Exception(sprintf('Impossible to create the root directory "%s". %s', $root, $errorMessage));
113 }
114 }
115 }
116
117 /**
118 * @inheritdoc
119 */
120 public function has($path)
121 {
122 $location = $this->applyPathPrefix($path);
123
124 return file_exists($location);
125 }
126
127 /**
128 * @inheritdoc
129 */
130 public function write($path, $contents, Config $config)
131 {
132 $location = $this->applyPathPrefix($path);
133 $this->ensureDirectory(dirname($location));
134
135 if (($size = file_put_contents($location, $contents, $this->writeFlags)) === false) {
136 return false;
137 }
138
139 $type = 'file';
140 $result = compact('contents', 'type', 'size', 'path');
141
142 if ($visibility = $config->get('visibility')) {
143 $result['visibility'] = $visibility;
144 $this->setVisibility($path, $visibility);
145 }
146
147 return $result;
148 }
149
150 /**
151 * @inheritdoc
152 */
153 public function writeStream($path, $resource, Config $config)
154 {
155 $location = $this->applyPathPrefix($path);
156 $this->ensureDirectory(dirname($location));
157 $stream = fopen($location, 'w+b');
158
159 if ( ! $stream || stream_copy_to_stream($resource, $stream) === false || ! fclose($stream)) {
160 return false;
161 }
162
163 $type = 'file';
164 $result = compact('type', 'path');
165
166 if ($visibility = $config->get('visibility')) {
167 $this->setVisibility($path, $visibility);
168 $result['visibility'] = $visibility;
169 }
170
171 return $result;
172 }
173
174 /**
175 * @inheritdoc
176 */
177 public function readStream($path)
178 {
179 $location = $this->applyPathPrefix($path);
180 $stream = fopen($location, 'rb');
181
182 return ['type' => 'file', 'path' => $path, 'stream' => $stream];
183 }
184
185 /**
186 * @inheritdoc
187 */
188 public function updateStream($path, $resource, Config $config)
189 {
190 return $this->writeStream($path, $resource, $config);
191 }
192
193 /**
194 * @inheritdoc
195 */
196 public function update($path, $contents, Config $config)
197 {
198 $location = $this->applyPathPrefix($path);
199 $size = file_put_contents($location, $contents, $this->writeFlags);
200
201 if ($size === false) {
202 return false;
203 }
204
205 $type = 'file';
206
207 $result = compact('type', 'path', 'size', 'contents');
208
209 if ($visibility = $config->get('visibility')) {
210 $this->setVisibility($path, $visibility);
211 $result['visibility'] = $visibility;
212 }
213
214 return $result;
215 }
216
217 /**
218 * @inheritdoc
219 */
220 public function read($path)
221 {
222 $location = $this->applyPathPrefix($path);
223 $contents = @file_get_contents($location);
224
225 if ($contents === false) {
226 return false;
227 }
228
229 return ['type' => 'file', 'path' => $path, 'contents' => $contents];
230 }
231
232 /**
233 * @inheritdoc
234 */
235 public function rename($path, $newpath)
236 {
237 $location = $this->applyPathPrefix($path);
238 $destination = $this->applyPathPrefix($newpath);
239 $parentDirectory = $this->applyPathPrefix(Util::dirname($newpath));
240 $this->ensureDirectory($parentDirectory);
241
242 return rename($location, $destination);
243 }
244
245 /**
246 * @inheritdoc
247 */
248 public function copy($path, $newpath)
249 {
250 $location = $this->applyPathPrefix($path);
251 $destination = $this->applyPathPrefix($newpath);
252 $this->ensureDirectory(dirname($destination));
253
254 return copy($location, $destination);
255 }
256
257 /**
258 * @inheritdoc
259 */
260 public function delete($path)
261 {
262 $location = $this->applyPathPrefix($path);
263
264 return @unlink($location);
265 }
266
267 /**
268 * @inheritdoc
269 */
270 public function listContents($directory = '', $recursive = false)
271 {
272 $result = [];
273 $location = $this->applyPathPrefix($directory);
274
275 if ( ! is_dir($location)) {
276 return [];
277 }
278
279 $iterator = $recursive ? $this->getRecursiveDirectoryIterator($location) : $this->getDirectoryIterator($location);
280
281 foreach ($iterator as $file) {
282 $path = $this->getFilePath($file);
283
284 if (preg_match('#(^|/|\\\\)\.{1,2}$#', $path)) {
285 continue;
286 }
287
288 $result[] = $this->normalizeFileInfo($file);
289 }
290
291 unset($iterator);
292
293 return array_filter($result);
294 }
295
296 /**
297 * @inheritdoc
298 */
299 public function getMetadata($path)
300 {
301 $location = $this->applyPathPrefix($path);
302 clearstatcache(false, $location);
303 $info = new SplFileInfo($location);
304
305 return $this->normalizeFileInfo($info);
306 }
307
308 /**
309 * @inheritdoc
310 */
311 public function getSize($path)
312 {
313 return $this->getMetadata($path);
314 }
315
316 /**
317 * @inheritdoc
318 */
319 public function getMimetype($path)
320 {
321 $location = $this->applyPathPrefix($path);
322 $finfo = new Finfo(FILEINFO_MIME_TYPE);
323 $mimetype = $finfo->file($location);
324
325 if (in_array($mimetype, ['application/octet-stream', 'inode/x-empty', 'application/x-empty'])) {
326 $mimetype = Util\MimeType::detectByFilename($location);
327 }
328
329 return ['path' => $path, 'type' => 'file', 'mimetype' => $mimetype];
330 }
331
332 /**
333 * @inheritdoc
334 */
335 public function getTimestamp($path)
336 {
337 return $this->getMetadata($path);
338 }
339
340 /**
341 * @inheritdoc
342 */
343 public function getVisibility($path)
344 {
345 $location = $this->applyPathPrefix($path);
346 clearstatcache(false, $location);
347 $permissions = octdec(substr(sprintf('%o', fileperms($location)), -4));
348 $type = is_dir($location) ? 'dir' : 'file';
349
350 foreach ($this->permissionMap[$type] as $visibility => $visibilityPermissions) {
351 if ($visibilityPermissions == $permissions) {
352 return compact('path', 'visibility');
353 }
354 }
355
356 $visibility = substr(sprintf('%o', fileperms($location)), -4);
357
358 return compact('path', 'visibility');
359 }
360
361 /**
362 * @inheritdoc
363 */
364 public function setVisibility($path, $visibility)
365 {
366 $location = $this->applyPathPrefix($path);
367 $type = is_dir($location) ? 'dir' : 'file';
368 $success = chmod($location, $this->permissionMap[$type][$visibility]);
369
370 if ($success === false) {
371 return false;
372 }
373
374 return compact('path', 'visibility');
375 }
376
377 /**
378 * @inheritdoc
379 */
380 public function createDir($dirname, Config $config)
381 {
382 $location = $this->applyPathPrefix($dirname);
383 $umask = umask(0);
384 $visibility = $config->get('visibility', 'public');
385 $return = ['path' => $dirname, 'type' => 'dir'];
386
387 if ( ! is_dir($location)) {
388 if (false === @mkdir($location, $this->permissionMap['dir'][$visibility], true)
389 || false === is_dir($location)) {
390 $return = false;
391 }
392 }
393
394 umask($umask);
395
396 return $return;
397 }
398
399 /**
400 * @inheritdoc
401 */
402 public function deleteDir($dirname)
403 {
404 $location = $this->applyPathPrefix($dirname);
405
406 if ( ! is_dir($location)) {
407 return false;
408 }
409
410 $contents = $this->getRecursiveDirectoryIterator($location, RecursiveIteratorIterator::CHILD_FIRST);
411
412 /** @var SplFileInfo $file */
413 foreach ($contents as $file) {
414 $this->guardAgainstUnreadableFileInfo($file);
415 $this->deleteFileInfoObject($file);
416 }
417
418 unset($contents);
419
420 return rmdir($location);
421 }
422
423 /**
424 * @param SplFileInfo $file
425 */
426 protected function deleteFileInfoObject(SplFileInfo $file)
427 {
428 switch ($file->getType()) {
429 case 'dir':
430 rmdir($file->getRealPath());
431 break;
432 case 'link':
433 unlink($file->getPathname());
434 break;
435 default:
436 unlink($file->getRealPath());
437 }
438 }
439
440 /**
441 * Normalize the file info.
442 *
443 * @param SplFileInfo $file
444 *
445 * @return array|void
446 *
447 * @throws NotSupportedException
448 */
449 protected function normalizeFileInfo(SplFileInfo $file)
450 {
451 if ( ! $file->isLink()) {
452 return $this->mapFileInfo($file);
453 }
454
455 if ($this->linkHandling & self::DISALLOW_LINKS) {
456 throw NotSupportedException::forLink($file);
457 }
458 }
459
460 /**
461 * Get the normalized path from a SplFileInfo object.
462 *
463 * @param SplFileInfo $file
464 *
465 * @return string
466 */
467 protected function getFilePath(SplFileInfo $file)
468 {
469 $location = $file->getPathname();
470 $path = $this->removePathPrefix($location);
471
472 return trim(str_replace('\\', '/', $path), '/');
473 }
474
475 /**
476 * @param string $path
477 * @param int $mode
478 *
479 * @return RecursiveIteratorIterator
480 */
481 protected function getRecursiveDirectoryIterator($path, $mode = RecursiveIteratorIterator::SELF_FIRST)
482 {
483 return new RecursiveIteratorIterator(
484 new RecursiveDirectoryIterator($path, FilesystemIterator::SKIP_DOTS),
485 $mode
486 );
487 }
488
489 /**
490 * @param string $path
491 *
492 * @return DirectoryIterator
493 */
494 protected function getDirectoryIterator($path)
495 {
496 $iterator = new DirectoryIterator($path);
497
498 return $iterator;
499 }
500
501 /**
502 * @param SplFileInfo $file
503 *
504 * @return array
505 */
506 protected function mapFileInfo(SplFileInfo $file)
507 {
508 $normalized = [
509 'type' => $file->getType(),
510 'path' => $this->getFilePath($file),
511 ];
512
513 $normalized['timestamp'] = $file->getMTime();
514
515 if ($normalized['type'] === 'file') {
516 $normalized['size'] = $file->getSize();
517 }
518
519 return $normalized;
520 }
521
522 /**
523 * @param SplFileInfo $file
524 *
525 * @throws UnreadableFileException
526 */
527 protected function guardAgainstUnreadableFileInfo(SplFileInfo $file)
528 {
529 if ( ! $file->isReadable()) {
530 throw UnreadableFileException::forFileInfo($file);
531 }
532 }
533 }
534