MountManager   A
last analyzed

Coupling/Cohesion

Components 1
Dependencies 3

Complexity

Total Complexity 26

Size/Duplication

Total Lines 276
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 26
lcom 1
cbo 3
dl 0
loc 276
ccs 75
cts 75
cp 1
rs 10
c 0
b 0
f 0

12 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A mountFilesystem() 0 10 2
A getFilesystem() 0 8 2
A filterPrefix() 0 17 3
A __call() 0 6 1
A mountFilesystems() 0 8 2
A listContents() 0 12 2
A copy() 0 20 3
A listWith() 0 7 1
B move() 0 24 5
A invokePluginOnFilesystem() 0 14 2
A getPrefixAndPath() 0 8 2
1
<?php
2
3
namespace League\Flysystem;
4
5
use InvalidArgumentException;
6
use League\Flysystem\FilesystemNotFoundException;
7
use League\Flysystem\Plugin\PluggableTrait;
8
use League\Flysystem\Plugin\PluginNotFoundException;
9
10
/**
11
 * Class MountManager.
12
 *
13
 * Proxies methods to Filesystem (@see __call):
14
 *
15
 * @method AdapterInterface getAdapter($prefix)
16
 * @method Config getConfig($prefix)
17
 * @method bool has($path)
18
 * @method bool write($path, $contents, array $config = [])
19
 * @method bool writeStream($path, $resource, array $config = [])
20
 * @method bool put($path, $contents, $config = [])
21
 * @method bool putStream($path, $contents, $config = [])
22
 * @method string readAndDelete($path)
23
 * @method bool update($path, $contents, $config = [])
24
 * @method bool updateStream($path, $resource, $config = [])
25
 * @method string|false read($path)
26
 * @method resource|false readStream($path)
27
 * @method bool rename($path, $newpath)
28
 * @method bool delete($path)
29
 * @method bool deleteDir($dirname)
30
 * @method bool createDir($dirname, $config = [])
31
 * @method array listFiles($directory = '', $recursive = false)
32
 * @method array listPaths($directory = '', $recursive = false)
33
 * @method array getWithMetadata($path, array $metadata)
34
 * @method string|false getMimetype($path)
35
 * @method int|false getTimestamp($path)
36
 * @method string|false getVisibility($path)
37
 * @method int|false getSize($path);
38
 * @method bool setVisibility($path, $visibility)
39
 * @method array|false getMetadata($path)
40
 * @method Handler get($path, Handler $handler = null)
41
 * @method Filesystem flushCache()
42
 * @method void assertPresent($path)
43
 * @method void assertAbsent($path)
44
 * @method Filesystem addPlugin(PluginInterface $plugin)
45
 */
46
class MountManager
47
{
48
    use PluggableTrait;
49
50
    /**
51
     * @var FilesystemInterface[]
52
     */
53
    protected $filesystems = [];
54
55
    /**
56
     * Constructor.
57
     *
58
     * @param FilesystemInterface[] $filesystems [:prefix => Filesystem,]
59
     *
60
     * @throws InvalidArgumentException
61
     */
62 51
    public function __construct(array $filesystems = [])
63
    {
64 51
        $this->mountFilesystems($filesystems);
65 51
    }
66
67
    /**
68
     * Mount filesystems.
69
     *
70
     * @param FilesystemInterface[] $filesystems [:prefix => Filesystem,]
71
     *
72
     * @throws InvalidArgumentException
73
     *
74
     * @return $this
75
     */
76 51
    public function mountFilesystems(array $filesystems)
77
    {
78 51
        foreach ($filesystems as $prefix => $filesystem) {
79 3
            $this->mountFilesystem($prefix, $filesystem);
80 17
        }
81
82 51
        return $this;
83
    }
84
85
    /**
86
     * Mount filesystems.
87
     *
88
     * @param string              $prefix
89
     * @param FilesystemInterface $filesystem
90
     *
91
     * @throws InvalidArgumentException
92
     *
93
     * @return $this
94
     */
95 36
    public function mountFilesystem($prefix, FilesystemInterface $filesystem)
96
    {
97 36
        if ( ! is_string($prefix)) {
98 3
            throw new InvalidArgumentException(__METHOD__ . ' expects argument #1 to be a string.');
99
        }
100
101 33
        $this->filesystems[$prefix] = $filesystem;
102
103 33
        return $this;
104
    }
105
106
    /**
107
     * Get the filesystem with the corresponding prefix.
108
     *
109
     * @param string $prefix
110
     *
111
     * @throws FilesystemNotFoundException
112
     *
113
     * @return FilesystemInterface
114
     */
115 33
    public function getFilesystem($prefix)
116
    {
117 33
        if ( ! isset($this->filesystems[$prefix])) {
118 3
            throw new FilesystemNotFoundException('No filesystem mounted with prefix ' . $prefix);
119
        }
120
121 30
        return $this->filesystems[$prefix];
122
    }
123
124
    /**
125
     * Retrieve the prefix from an arguments array.
126
     *
127
     * @param array $arguments
128
     *
129
     * @throws InvalidArgumentException
130
     *
131
     * @return array [:prefix, :arguments]
132
     */
133 24
    public function filterPrefix(array $arguments)
134
    {
135 24
        if (empty($arguments)) {
136 3
            throw new InvalidArgumentException('At least one argument needed');
137
        }
138
139 21
        $path = array_shift($arguments);
140
141 21
        if ( ! is_string($path)) {
142 3
            throw new InvalidArgumentException('First argument should be a string');
143
        }
144
145 18
        list($prefix, $path) = $this->getPrefixAndPath($path);
146 15
        array_unshift($arguments, $path);
147
148 15
        return [$prefix, $arguments];
149
    }
150
151
    /**
152
     * @param string $directory
153
     * @param bool   $recursive
154
     *
155
     * @throws InvalidArgumentException
156
     * @throws FilesystemNotFoundException
157
     *
158
     * @return array
159
     */
160 3
    public function listContents($directory = '', $recursive = false)
161
    {
162 3
        list($prefix, $directory) = $this->getPrefixAndPath($directory);
163 3
        $filesystem = $this->getFilesystem($prefix);
164 3
        $result = $filesystem->listContents($directory, $recursive);
165
166 3
        foreach ($result as &$file) {
167 3
            $file['filesystem'] = $prefix;
168 1
        }
169
170 3
        return $result;
171
    }
172
173
    /**
174
     * Call forwarder.
175
     *
176
     * @param string $method
177
     * @param array  $arguments
178
     *
179
     * @throws InvalidArgumentException
180
     * @throws FilesystemNotFoundException
181
     *
182
     * @return mixed
183
     */
184 15
    public function __call($method, $arguments)
185
    {
186 15
        list($prefix, $arguments) = $this->filterPrefix($arguments);
187
188 15
        return $this->invokePluginOnFilesystem($method, $arguments, $prefix);
189
    }
190
191
    /**
192
     * @param string $from
193
     * @param string $to
194
     * @param array  $config
195
     *
196
     * @throws InvalidArgumentException
197
     * @throws FilesystemNotFoundException
198
     * @throws FileExistsException
199
     *
200
     * @return bool
201
     */
202 3
    public function copy($from, $to, array $config = [])
203
    {
204 3
        list($prefixFrom, $from) = $this->getPrefixAndPath($from);
205
206 3
        $buffer = $this->getFilesystem($prefixFrom)->readStream($from);
207
208 3
        if ($buffer === false) {
209 3
            return false;
210
        }
211
212 3
        list($prefixTo, $to) = $this->getPrefixAndPath($to);
213
214 3
        $result = $this->getFilesystem($prefixTo)->writeStream($to, $buffer, $config);
215
216 3
        if (is_resource($buffer)) {
217 3
            fclose($buffer);
218 1
        }
219
220 3
        return $result;
221
    }
222
223
    /**
224
     * List with plugin adapter.
225
     *
226
     * @param array  $keys
227
     * @param string $directory
228
     * @param bool   $recursive
229
     *
230
     * @throws InvalidArgumentException
231
     * @throws FilesystemNotFoundException
232
     *
233
     * @return array
234
     */
235 3
    public function listWith(array $keys = [], $directory = '', $recursive = false)
236
    {
237 3
        list($prefix, $directory) = $this->getPrefixAndPath($directory);
238 3
        $arguments = [$keys, $directory, $recursive];
239
240 3
        return $this->invokePluginOnFilesystem('listWith', $arguments, $prefix);
241
    }
242
243
    /**
244
     * Move a file.
245
     *
246
     * @param string $from
247
     * @param string $to
248
     * @param array  $config
249
     *
250
     * @throws InvalidArgumentException
251
     * @throws FilesystemNotFoundException
252
     *
253
     * @return bool
254
     */
255 6
    public function move($from, $to, array $config = [])
256
    {
257 6
        list($prefixFrom, $pathFrom) = $this->getPrefixAndPath($from);
258 6
        list($prefixTo, $pathTo) = $this->getPrefixAndPath($to);
259
260 6
        if ($prefixFrom === $prefixTo) {
261 3
            $filesystem = $this->getFilesystem($prefixFrom);
262 3
            $renamed = $filesystem->rename($pathFrom, $pathTo);
263
264 3
            if ($renamed && isset($config['visibility'])) {
265 3
                return $filesystem->setVisibility($pathTo, $config['visibility']);
266
            }
267
268 3
            return $renamed;
269
        }
270
271 3
        $copied = $this->copy($from, $to, $config);
272
273 3
        if ($copied) {
274 3
            return $this->delete($from);
275
        }
276
277 3
        return false;
278
    }
279
280
    /**
281
     * Invoke a plugin on a filesystem mounted on a given prefix.
282
     *
283
     * @param string $method
284
     * @param array  $arguments
285
     * @param string $prefix
286
     *
287
     * @throws FilesystemNotFoundException
288
     *
289
     * @return mixed
290
     */
291 18
    public function invokePluginOnFilesystem($method, $arguments, $prefix)
292
    {
293 18
        $filesystem = $this->getFilesystem($prefix);
294
295
        try {
296 18
            return $this->invokePlugin($method, $arguments, $filesystem);
297 18
        } catch (PluginNotFoundException $e) {
298
            // Let it pass, it's ok, don't panic.
299
        }
300
301 18
        $callback = [$filesystem, $method];
302
303 18
        return call_user_func_array($callback, $arguments);
304
    }
305
306
    /**
307
     * @param string $path
308
     *
309
     * @throws InvalidArgumentException
310
     *
311
     * @return string[] [:prefix, :path]
312
     */
313 33
    protected function getPrefixAndPath($path)
314
    {
315 33
        if (strpos($path, '://') < 1) {
316 3
            throw new InvalidArgumentException('No prefix detected in path: ' . $path);
317
        }
318
319 30
        return explode('://', $path, 2);
320
    }
321
}
322