Completed
Push — master ( b47afe...96a91e )
by Frank
13s queued 10s
created

MountManager::rename()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 6
ccs 3
cts 3
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 2
crap 1
1
<?php
2
3
namespace League\Flysystem;
4
5
use InvalidArgumentException;
6
use League\Flysystem\Plugin\PluggableTrait;
7
use League\Flysystem\Plugin\PluginNotFoundException;
8
9
/**
10
 * Class MountManager.
11
 *
12
 * Proxies methods to Filesystem (@see __call):
13
 *
14
 * @method AdapterInterface getAdapter($prefix)
15
 * @method Config getConfig($prefix)
16
 * @method array listFiles($directory = '', $recursive = false)
17
 * @method array listPaths($directory = '', $recursive = false)
18
 * @method array getWithMetadata($path, array $metadata)
19
 * @method Filesystem flushCache()
20
 * @method void assertPresent($path)
21
 * @method void assertAbsent($path)
22
 * @method Filesystem addPlugin(PluginInterface $plugin)
23
 */
24
class MountManager implements FilesystemInterface
25
{
26
    use PluggableTrait;
27
28
    /**
29
     * @var FilesystemInterface[]
30
     */
31
    protected $filesystems = [];
32
33
    /**
34
     * Constructor.
35
     *
36
     * @param FilesystemInterface[] $filesystems [:prefix => Filesystem,]
37
     *
38
     * @throws InvalidArgumentException
39
     */
40 111
    public function __construct(array $filesystems = [])
41
    {
42 111
        $this->mountFilesystems($filesystems);
43 111
    }
44
45
    /**
46
     * Mount filesystems.
47
     *
48
     * @param FilesystemInterface[] $filesystems [:prefix => Filesystem,]
49
     *
50
     * @throws InvalidArgumentException
51
     *
52
     * @return $this
53
     */
54 111
    public function mountFilesystems(array $filesystems)
55
    {
56 111
        foreach ($filesystems as $prefix => $filesystem) {
57 3
            $this->mountFilesystem($prefix, $filesystem);
58 37
        }
59
60 111
        return $this;
61
    }
62
63
    /**
64
     * Mount filesystems.
65
     *
66
     * @param string              $prefix
67
     * @param FilesystemInterface $filesystem
68
     *
69
     * @throws InvalidArgumentException
70
     *
71
     * @return $this
72
     */
73 96
    public function mountFilesystem($prefix, FilesystemInterface $filesystem)
74
    {
75 96
        if ( ! is_string($prefix)) {
76 3
            throw new InvalidArgumentException(__METHOD__ . ' expects argument #1 to be a string.');
77
        }
78
79 93
        $this->filesystems[$prefix] = $filesystem;
80
81 93
        return $this;
82
    }
83
84
    /**
85
     * Get the filesystem with the corresponding prefix.
86
     *
87
     * @param string $prefix
88
     *
89
     * @throws FilesystemNotFoundException
90
     *
91
     * @return FilesystemInterface
92
     */
93 93
    public function getFilesystem($prefix)
94
    {
95 93
        if ( ! isset($this->filesystems[$prefix])) {
96 3
            throw new FilesystemNotFoundException('No filesystem mounted with prefix ' . $prefix);
97
        }
98
99 90
        return $this->filesystems[$prefix];
100
    }
101
102
    /**
103
     * Retrieve the prefix from an arguments array.
104
     *
105
     * @param array $arguments
106
     *
107
     * @throws InvalidArgumentException
108
     *
109
     * @return array [:prefix, :arguments]
110
     */
111 9
    public function filterPrefix(array $arguments)
112
    {
113 9
        if (empty($arguments)) {
114 3
            throw new InvalidArgumentException('At least one argument needed');
115
        }
116
117 6
        $path = array_shift($arguments);
118
119 6
        if ( ! is_string($path)) {
120 3
            throw new InvalidArgumentException('First argument should be a string');
121
        }
122
123 3
        list($prefix, $path) = $this->getPrefixAndPath($path);
124
        array_unshift($arguments, $path);
125
126
        return [$prefix, $arguments];
127
    }
128
129
    /**
130
     * @param string $directory
131
     * @param bool   $recursive
132
     *
133
     * @throws InvalidArgumentException
134
     * @throws FilesystemNotFoundException
135
     *
136
     * @return array
137
     */
138 3
    public function listContents($directory = '', $recursive = false)
139
    {
140 3
        list($prefix, $directory) = $this->getPrefixAndPath($directory);
141 3
        $filesystem = $this->getFilesystem($prefix);
142 3
        $result = $filesystem->listContents($directory, $recursive);
143
144 3
        foreach ($result as &$file) {
145 3
            $file['filesystem'] = $prefix;
146 1
        }
147
148 3
        return $result;
149
    }
150
151
    /**
152
     * Call forwarder.
153
     *
154
     * @param string $method
155
     * @param array  $arguments
156
     *
157
     * @throws InvalidArgumentException
158
     * @throws FilesystemNotFoundException
159
     *
160
     * @return mixed
161
     */
162
    public function __call($method, $arguments)
163
    {
164
        list($prefix, $arguments) = $this->filterPrefix($arguments);
165
166
        return $this->invokePluginOnFilesystem($method, $arguments, $prefix);
167
    }
168
169
    /**
170
     * @param string $from
171
     * @param string $to
172
     * @param array  $config
173
     *
174
     * @throws InvalidArgumentException
175
     * @throws FilesystemNotFoundException
176
     * @throws FileExistsException
177
     *
178
     * @return bool
179
     */
180 3
    public function copy($from, $to, array $config = [])
181
    {
182 3
        list($prefixFrom, $from) = $this->getPrefixAndPath($from);
183
184 3
        $buffer = $this->getFilesystem($prefixFrom)->readStream($from);
185
186 3
        if ($buffer === false) {
187 3
            return false;
188
        }
189
190 3
        list($prefixTo, $to) = $this->getPrefixAndPath($to);
191
192 3
        $result = $this->getFilesystem($prefixTo)->writeStream($to, $buffer, $config);
193
194 3
        if (is_resource($buffer)) {
195 3
            fclose($buffer);
196 1
        }
197
198 3
        return $result;
199
    }
200
201
    /**
202
     * List with plugin adapter.
203
     *
204
     * @param array  $keys
205
     * @param string $directory
206
     * @param bool   $recursive
207
     *
208
     * @throws InvalidArgumentException
209
     * @throws FilesystemNotFoundException
210
     *
211
     * @return array
212
     */
213 3
    public function listWith(array $keys = [], $directory = '', $recursive = false)
214
    {
215 3
        list($prefix, $directory) = $this->getPrefixAndPath($directory);
216 3
        $arguments = [$keys, $directory, $recursive];
217
218 3
        return $this->invokePluginOnFilesystem('listWith', $arguments, $prefix);
219
    }
220
221
    /**
222
     * Move a file.
223
     *
224
     * @param string $from
225
     * @param string $to
226
     * @param array  $config
227
     *
228
     * @throws InvalidArgumentException
229
     * @throws FilesystemNotFoundException
230
     *
231
     * @return bool
232
     */
233 6
    public function move($from, $to, array $config = [])
234
    {
235 6
        list($prefixFrom, $pathFrom) = $this->getPrefixAndPath($from);
236 6
        list($prefixTo, $pathTo) = $this->getPrefixAndPath($to);
237
238 6
        if ($prefixFrom === $prefixTo) {
239 3
            $filesystem = $this->getFilesystem($prefixFrom);
240 3
            $renamed = $filesystem->rename($pathFrom, $pathTo);
241
242 3
            if ($renamed && isset($config['visibility'])) {
243 3
                return $filesystem->setVisibility($pathTo, $config['visibility']);
244
            }
245
246 3
            return $renamed;
247
        }
248
249 3
        $copied = $this->copy($from, $to, $config);
250
251 3
        if ($copied) {
252 3
            return $this->delete($from);
253
        }
254
255 3
        return false;
256
    }
257
258
    /**
259
     * Invoke a plugin on a filesystem mounted on a given prefix.
260
     *
261
     * @param string $method
262
     * @param array  $arguments
263
     * @param string $prefix
264
     *
265
     * @throws FilesystemNotFoundException
266
     *
267
     * @return mixed
268
     */
269 3
    public function invokePluginOnFilesystem($method, $arguments, $prefix)
270
    {
271 3
        $filesystem = $this->getFilesystem($prefix);
272
273
        try {
274 3
            return $this->invokePlugin($method, $arguments, $filesystem);
275 3
        } catch (PluginNotFoundException $e) {
276
            // Let it pass, it's ok, don't panic.
277
        }
278
279 3
        $callback = [$filesystem, $method];
280
281 3
        return call_user_func_array($callback, $arguments);
282
    }
283
284
    /**
285
     * @param string $path
286
     *
287
     * @throws InvalidArgumentException
288
     *
289
     * @return string[] [:prefix, :path]
290
     */
291 93
    protected function getPrefixAndPath($path)
292
    {
293 93
        if (strpos($path, '://') < 1) {
294 3
            throw new InvalidArgumentException('No prefix detected in path: ' . $path);
295
        }
296
297 90
        return explode('://', $path, 2);
298
    }
299
300
    /**
301
     * Check whether a file exists.
302
     *
303
     * @param string $path
304
     *
305
     * @return bool
306
     */
307 3
    public function has($path)
308
    {
309 3
        list($prefix, $path) = $this->getPrefixAndPath($path);
310
311 3
        return $this->getFilesystem($prefix)->has($path);
312
    }
313
314
    /**
315
     * Read a file.
316
     *
317
     * @param string $path The path to the file.
318
     *
319
     * @throws FileNotFoundException
320
     *
321
     * @return string|false The file contents or false on failure.
322
     */
323 15
    public function read($path)
324
    {
325 15
        list($prefix, $path) = $this->getPrefixAndPath($path);
326
327 15
        return $this->getFilesystem($prefix)->read($path);
328
    }
329
330
    /**
331
     * Retrieves a read-stream for a path.
332
     *
333
     * @param string $path The path to the file.
334
     *
335
     * @throws FileNotFoundException
336
     *
337
     * @return resource|false The path resource or false on failure.
338
     */
339 3
    public function readStream($path)
340
    {
341 3
        list($prefix, $path) = $this->getPrefixAndPath($path);
342
343 3
        return $this->getFilesystem($prefix)->readStream($path);
344
    }
345
346
    /**
347
     * Get a file's metadata.
348
     *
349
     * @param string $path The path to the file.
350
     *
351
     * @throws FileNotFoundException
352
     *
353
     * @return array|false The file metadata or false on failure.
354
     */
355 3
    public function getMetadata($path)
356
    {
357 3
        list($prefix, $path) = $this->getPrefixAndPath($path);
358
359 3
        return $this->getFilesystem($prefix)->getMetadata($path);
360
    }
361
362
    /**
363
     * Get a file's size.
364
     *
365
     * @param string $path The path to the file.
366
     *
367
     * @throws FileNotFoundException
368
     *
369
     * @return int|false The file size or false on failure.
370
     */
371 3
    public function getSize($path)
372
    {
373 3
        list($prefix, $path) = $this->getPrefixAndPath($path);
374
375 3
        return $this->getFilesystem($prefix)->getSize($path);
376
    }
377
378
    /**
379
     * Get a file's mime-type.
380
     *
381
     * @param string $path The path to the file.
382
     *
383
     * @throws FileNotFoundException
384
     *
385
     * @return string|false The file mime-type or false on failure.
386
     */
387 3
    public function getMimetype($path)
388
    {
389 3
        list($prefix, $path) = $this->getPrefixAndPath($path);
390
391 3
        return $this->getFilesystem($prefix)->getMimetype($path);
392
    }
393
394
    /**
395
     * Get a file's timestamp.
396
     *
397
     * @param string $path The path to the file.
398
     *
399
     * @throws FileNotFoundException
400
     *
401
     * @return string|false The timestamp or false on failure.
402
     */
403 3
    public function getTimestamp($path)
404
    {
405 3
        list($prefix, $path) = $this->getPrefixAndPath($path);
406
407 3
        return $this->getFilesystem($prefix)->getTimestamp($path);
408
    }
409
410
    /**
411
     * Get a file's visibility.
412
     *
413
     * @param string $path The path to the file.
414
     *
415
     * @throws FileNotFoundException
416
     *
417
     * @return string|false The visibility (public|private) or false on failure.
418
     */
419 3
    public function getVisibility($path)
420
    {
421 3
        list($prefix, $path) = $this->getPrefixAndPath($path);
422
423 3
        return $this->getFilesystem($prefix)->getVisibility($path);
424
    }
425
426
    /**
427
     * Write a new file.
428
     *
429
     * @param string $path     The path of the new file.
430
     * @param string $contents The file contents.
431
     * @param array  $config   An optional configuration array.
432
     *
433
     * @throws FileExistsException
434
     *
435
     * @return bool True on success, false on failure.
436
     */
437 3
    public function write($path, $contents, array $config = [])
438
    {
439 3
        list($prefix, $path) = $this->getPrefixAndPath($path);
440
441 3
        return $this->getFilesystem($prefix)->write($path, $contents, $config);
442
    }
443
444
    /**
445
     * Write a new file using a stream.
446
     *
447
     * @param string   $path     The path of the new file.
448
     * @param resource $resource The file handle.
449
     * @param array    $config   An optional configuration array.
450
     *
451
     * @throws InvalidArgumentException If $resource is not a file handle.
452
     * @throws FileExistsException
453
     *
454
     * @return bool True on success, false on failure.
455
     */
456 3
    public function writeStream($path, $resource, array $config = [])
457
    {
458 3
        list($prefix, $path) = $this->getPrefixAndPath($path);
459
460 3
        return $this->getFilesystem($prefix)->writeStream($path, $resource, $config);
461
    }
462
463
    /**
464
     * Update an existing file.
465
     *
466
     * @param string $path     The path of the existing file.
467
     * @param string $contents The file contents.
468
     * @param array  $config   An optional configuration array.
469
     *
470
     * @throws FileNotFoundException
471
     *
472
     * @return bool True on success, false on failure.
473
     */
474 3
    public function update($path, $contents, array $config = [])
475
    {
476 3
        list($prefix, $path) = $this->getPrefixAndPath($path);
477
478 3
        return $this->getFilesystem($prefix)->update($path, $contents, $config);
479
    }
480
481
    /**
482
     * Update an existing file using a stream.
483
     *
484
     * @param string   $path     The path of the existing file.
485
     * @param resource $resource The file handle.
486
     * @param array    $config   An optional configuration array.
487
     *
488
     * @throws InvalidArgumentException If $resource is not a file handle.
489
     * @throws FileNotFoundException
490
     *
491
     * @return bool True on success, false on failure.
492
     */
493 3
    public function updateStream($path, $resource, array $config = [])
494
    {
495 3
        list($prefix, $path) = $this->getPrefixAndPath($path);
496
497 3
        return $this->getFilesystem($prefix)->updateStream($path, $resource, $config);
498
    }
499
500
    /**
501
     * Rename a file.
502
     *
503
     * @param string $path    Path to the existing file.
504
     * @param string $newpath The new path of the file.
505
     *
506
     * @throws FileExistsException   Thrown if $newpath exists.
507
     * @throws FileNotFoundException Thrown if $path does not exist.
508
     *
509
     * @return bool True on success, false on failure.
510
     */
511 3
    public function rename($path, $newpath)
512
    {
513 3
        list($prefix, $path) = $this->getPrefixAndPath($path);
514
515 3
        return $this->getFilesystem($prefix)->rename($path, $newpath);
516
    }
517
518
    /**
519
     * Delete a file.
520
     *
521
     * @param string $path
522
     *
523
     * @throws FileNotFoundException
524
     *
525
     * @return bool True on success, false on failure.
526
     */
527 3
    public function delete($path)
528
    {
529 3
        list($prefix, $path) = $this->getPrefixAndPath($path);
530
531 3
        return $this->getFilesystem($prefix)->delete($path);
532
    }
533
534
    /**
535
     * Delete a directory.
536
     *
537
     * @param string $dirname
538
     *
539
     * @throws RootViolationException Thrown if $dirname is empty.
540
     *
541
     * @return bool True on success, false on failure.
542
     */
543 3
    public function deleteDir($dirname)
544
    {
545 3
        list($prefix, $dirname) = $this->getPrefixAndPath($dirname);
546
547 3
        return $this->getFilesystem($prefix)->deleteDir($dirname);
548
    }
549
550
    /**
551
     * Create a directory.
552
     *
553
     * @param string $dirname The name of the new directory.
554
     * @param array  $config  An optional configuration array.
555
     *
556
     * @return bool True on success, false on failure.
557
     */
558 3
    public function createDir($dirname, array $config = [])
559
    {
560 3
        list($prefix, $dirname) = $this->getPrefixAndPath($dirname);
561
562 3
        return $this->getFilesystem($prefix)->createDir($dirname);
563
    }
564
565
    /**
566
     * Set the visibility for a file.
567
     *
568
     * @param string $path       The path to the file.
569
     * @param string $visibility One of 'public' or 'private'.
570
     *
571
     * @throws FileNotFoundException
572
     *
573
     * @return bool True on success, false on failure.
574
     */
575 3
    public function setVisibility($path, $visibility)
576
    {
577 3
        list($prefix, $path) = $this->getPrefixAndPath($path);
578
579 3
        return $this->getFilesystem($prefix)->setVisibility($path, $visibility);
580
    }
581
582
    /**
583
     * Create a file or update if exists.
584
     *
585
     * @param string $path     The path to the file.
586
     * @param string $contents The file contents.
587
     * @param array  $config   An optional configuration array.
588
     *
589
     * @return bool True on success, false on failure.
590
     */
591 3
    public function put($path, $contents, array $config = [])
592
    {
593 3
        list($prefix, $path) = $this->getPrefixAndPath($path);
594
595 3
        return $this->getFilesystem($prefix)->put($path, $contents, $config);
596
    }
597
598
    /**
599
     * Create a file or update if exists.
600
     *
601
     * @param string   $path     The path to the file.
602
     * @param resource $resource The file handle.
603
     * @param array    $config   An optional configuration array.
604
     *
605
     * @throws InvalidArgumentException Thrown if $resource is not a resource.
606
     *
607
     * @return bool True on success, false on failure.
608
     */
609 3
    public function putStream($path, $resource, array $config = [])
610
    {
611 3
        list($prefix, $path) = $this->getPrefixAndPath($path);
612
613 3
        return $this->getFilesystem($prefix)->putStream($path, $resource, $config);
614
    }
615
616
    /**
617
     * Read and delete a file.
618
     *
619
     * @param string $path The path to the file.
620
     *
621
     * @throws FileNotFoundException
622
     *
623
     * @return string|false The file contents, or false on failure.
624
     */
625 3
    public function readAndDelete($path)
626
    {
627 3
        list($prefix, $path) = $this->getPrefixAndPath($path);
628
629 3
        return $this->getFilesystem($prefix)->readAndDelete($path);
630
    }
631
632
    /**
633
     * Get a file/directory handler.
634
     *
635
     * @deprecated
636
     *
637
     * @param string  $path    The path to the file.
638
     * @param Handler $handler An optional existing handler to populate.
639
     *
640
     * @return Handler Either a file or directory handler.
641
     */
642 3
    public function get($path, Handler $handler = null)
643
    {
644 3
        list($prefix, $path) = $this->getPrefixAndPath($path);
645
646 3
        return $this->getFilesystem($prefix)->get($path);
1 ignored issue
show
Deprecated Code introduced by Frank de Jonge
The method League\Flysystem\FilesystemInterface::get() has been deprecated.

This method has been deprecated.

Loading history...
647
    }
648
}
649