Completed
Push4c3e34...b83e30
passed — Build
created

MountManager::filterPrefix()   A

↳ Parent: MountManager

Complexity

Conditions 4
Paths 4

Duplication

Lines 0
Ratio 0 %

Size

Total Lines 21
Code Lines 11

Code Coverage

Tests 11
CRAP Score 4

Importance

Changes 3
Bugs 2 Features 0
Metric Value
c 3
b 2
f 0
dl 0
loc 21
ccs 11
cts 11
cp 1
rs 9.0534
cc 4
eloc 11
nc 4
nop 1
crap 4
1
<?php
2
3
namespace League\Flysystem;
4
5
use InvalidArgumentException;
6
use League\Flysystem\Plugin\PluggableTrait;
7
use League\Flysystem\Plugin\PluginNotFoundException;
8
use LogicException;
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 string|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 assertPresent($path)
43
 * @method assertAbsent($path)
44
 * @method Filesystem addPlugin(PluginInterface $plugin)
45
 */
46
class MountManager
47
{
48
    use PluggableTrait;
49
50
    /**
51
     * @var array
52
     */
53
    protected $filesystems = [];
54
55
    /**
56
     * Constructor.
57
     *
58
     * @param array $filesystems
59
     */
60 45
    public function __construct(array $filesystems = [])
61
    {
62 45
        $this->mountFilesystems($filesystems);
63 45
    }
64
65
    /**
66
     * Mount filesystems.
67
     *
68
     * @param array $filesystems [:prefix => Filesystem,]
69
     *
70
     * @return $this
71
     */
72 45
    public function mountFilesystems(array $filesystems)
73
    {
74 45
        foreach ($filesystems as $prefix => $filesystem) {
75 3
            $this->mountFilesystem($prefix, $filesystem);
76 45
        }
77
78 45
        return $this;
79
    }
80
81
    /**
82
     * Mount filesystems.
83
     *
84
     * @param string              $prefix
85
     * @param FilesystemInterface $filesystem
86
     *
87
     * @return $this
88
     */
89 33
    public function mountFilesystem($prefix, FilesystemInterface $filesystem)
90
    {
91 33
        if ( ! is_string($prefix)) {
92 3
            throw new InvalidArgumentException(__METHOD__ . ' expects argument #1 to be a string.');
93
        }
94
95 30
        $this->filesystems[$prefix] = $filesystem;
96
97 30
        return $this;
98
    }
99
100
    /**
101
     * Get the filesystem with the corresponding prefix.
102
     *
103
     * @param string $prefix
104
     *
105
     * @throws LogicException
106
     *
107
     * @return FilesystemInterface
108
     */
109 33
    public function getFilesystem($prefix)
110
    {
111 33
        if ( ! isset($this->filesystems[$prefix])) {
112 3
            throw new LogicException('No filesystem mounted with prefix ' . $prefix);
113
        }
114
115 30
        return $this->filesystems[$prefix];
116
    }
117
118
    /**
119
     * Retrieve the prefix from an arguments array.
120
     *
121
     * @param array $arguments
122
     *
123
     * @return array [:prefix, :arguments]
124
     */
125 36
    public function filterPrefix(array $arguments)
126
    {
127 36
        if (empty($arguments)) {
128 3
            throw new LogicException('At least one argument needed');
129
        }
130
131 33
        $path = array_shift($arguments);
132
133 33
        if ( ! is_string($path)) {
134 3
            throw new InvalidArgumentException('First argument should be a string');
135
        }
136
137 30
        if ( ! preg_match('#^.+\:\/\/.*#', $path)) {
138 3
            throw new InvalidArgumentException('No prefix detected in path: ' . $path);
139
        }
140
141 27
        list($prefix, $path) = explode('://', $path, 2);
142 27
        array_unshift($arguments, $path);
143
144 27
        return [$prefix, $arguments];
145
    }
146
147
    /**
148
     * @param string $directory
149
     * @param bool   $recursive
150
     *
151
     * @return array
152
     */
153 3
    public function listContents($directory = '', $recursive = false)
154
    {
155 3
        list($prefix, $arguments) = $this->filterPrefix([$directory]);
156 3
        $filesystem = $this->getFilesystem($prefix);
157 3
        $directory = array_shift($arguments);
158 3
        $result = $filesystem->listContents($directory, $recursive);
159
160 3
        foreach ($result as &$file) {
161 3
            $file['filesystem'] = $prefix;
162 3
        }
163
164 3
        return $result;
165
    }
166
167
    /**
168
     * Call forwarder.
169
     *
170
     * @param string $method
171
     * @param array  $arguments
172
     *
173
     * @return mixed
174
     */
175 15
    public function __call($method, $arguments)
176
    {
177 15
        list($prefix, $arguments) = $this->filterPrefix($arguments);
178
179 15
        return $this->invokePluginOnFilesystem($method, $arguments, $prefix);
180
    }
181
182
    /**
183
     * @param $from
184
     * @param $to
185
     * @param array $config
186
     *
187
     * @return bool
188
     */
189 6
    public function copy($from, $to, array $config = [])
190
    {
191 6
        list($prefixFrom, $arguments) = $this->filterPrefix([$from]);
192
193 6
        $fsFrom = $this->getFilesystem($prefixFrom);
194 6
        $buffer = call_user_func_array([$fsFrom, 'readStream'], $arguments);
195
196 6
        if ($buffer === false) {
197 3
            return false;
198
        }
199
200 6
        list($prefixTo, $arguments) = $this->filterPrefix([$to]);
201
202 6
        $fsTo = $this->getFilesystem($prefixTo);
203 6
        $result =  call_user_func_array([$fsTo, 'writeStream'], array_merge($arguments, [$buffer, $config]));
204
205 6
        if (is_resource($buffer)) {
206 6
            fclose($buffer);
207 6
        }
208
209 6
        return $result;
210
    }
211
212
    /**
213
     * List with plugin adapter.
214
     *
215
     * @param array  $keys
216
     * @param string $directory
217
     * @param bool   $recursive
218
     */
219 3
    public function listWith(array $keys = [], $directory = '', $recursive = false)
220
    {
221 3
        list($prefix, $arguments) = $this->filterPrefix([$directory]);
222 3
        $directory = $arguments[0];
223 3
        $arguments = [$keys, $directory, $recursive];
224
225 3
        return $this->invokePluginOnFilesystem('listWith', $arguments, $prefix);
226
    }
227
228
    /**
229
     * Move a file.
230
     *
231
     * @param $from
232
     * @param $to
233
     * @param array $config
234
     *
235
     * @return bool
236
     */
237 3
    public function move($from, $to, array $config = [])
238
    {
239 3
        $copied = $this->copy($from, $to, $config);
240
241 3
        if ($copied) {
242 3
            return $this->delete($from);
243
        }
244
245 3
        return false;
246
    }
247
248
    /**
249
     * Invoke a plugin on a filesystem mounted on a given prefix.
250
     *
251
     * @param $method
252
     * @param $arguments
253
     * @param $prefix
254
     *
255
     * @return mixed
256
     */
257 18
    public function invokePluginOnFilesystem($method, $arguments, $prefix)
258
    {
259 18
        $filesystem = $this->getFilesystem($prefix);
260
261
        try {
262 18
            return $this->invokePlugin($method, $arguments, $filesystem);
263 18
        } catch (PluginNotFoundException $e) {
264
            // Let it pass, it's ok, don't panic.
265
        }
266
267 18
        $callback = [$filesystem, $method];
268
269 18
        return call_user_func_array($callback, $arguments);
270
    }
271
}
272