Filesystem   B
last analyzed

↳ Parent: Project

Coupling/Cohesion

Components 1
Dependencies 12

Complexity

Total Complexity 48

Size/Duplication

Total Lines 388
Duplicated Lines 23.2 %

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 48
lcom 1
cbo 12
dl 90
loc 388
ccs 146
cts 146
cp 1
rs 8.4864
c 0
b 0
f 0

27 Methods

Rating   Name   Duplication   Size   Complexity  
A getAdapter() 0 4 1
A readAndDelete() 0 14 2
A read() 0 11 2
A readStream() 0 11 2
A copy() 9 9 1
A delete() 0 7 1
A getSize() 10 10 3
A setVisibility() 0 6 1
A getMetadata() 0 7 1
A get() 0 14 3
A assertPresent() 0 6 3
A __construct() 0 5 1
A has() 0 6 2
A write() 8 8 1
A writeStream() 14 14 2
A put() 0 11 2
A putStream() 0 16 3
A update() 9 9 1
A updateStream() 13 13 2
A rename() 9 9 1
A deleteDir() 0 10 2
A createDir() 7 7 1
A listContents() 0 7 1
A getMimetype() 0 11 2
A getTimestamp() 0 11 2
A getVisibility() 11 11 2
A assertAbsent() 0 6 3

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like Filesystem often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Filesystem, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace League\Flysystem;
4
5
use InvalidArgumentException;
6
use League\Flysystem\Plugin\PluggableTrait;
7
use League\Flysystem\Util\ContentListingFormatter;
8
9
/**
10
 * @method array getWithMetadata(string $path, array $metadata)
11
 * @method bool  forceCopy(string $path, string $newpath)
12
 * @method bool  forceRename(string $path, string $newpath)
13
 * @method array listFiles(string $path = '', boolean $recursive = false)
14
 * @method array listPaths(string $path = '', boolean $recursive = false)
15
 * @method array listWith(array $keys = [], $directory = '', $recursive = false)
16
 */
17
class Filesystem implements FilesystemInterface
18
{
19
    use PluggableTrait;
20
    use ConfigAwareTrait;
21
22
    /**
23
     * @var AdapterInterface
24
     */
25
    protected $adapter;
26
27
    /**
28
     * Constructor.
29
     *
30
     * @param AdapterInterface $adapter
31
     * @param Config|array     $config
32
     */
33 234
    public function __construct(AdapterInterface $adapter, $config = null)
34
    {
35 234
        $this->adapter = $adapter;
36 234
        $this->setConfig($config);
37 234
    }
38
39
    /**
40
     * Get the Adapter.
41
     *
42
     * @return AdapterInterface adapter
43
     */
44 198
    public function getAdapter()
45
    {
46 198
        return $this->adapter;
47
    }
48
49
    /**
50
     * @inheritdoc
51
     */
52 159
    public function has($path)
53
    {
54 159
        $path = Util::normalizePath($path);
55
56 159
        return strlen($path) === 0 ? false : (bool) $this->getAdapter()->has($path);
57
    }
58
59
    /**
60
     * @inheritdoc
61
     */
62 15 View Code Duplication
    public function write($path, $contents, array $config = [])
0 ignored issues
show
Duplication introduced by Frank de Jonge
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
63
    {
64 15
        $path = Util::normalizePath($path);
65 15
        $this->assertAbsent($path);
66 12
        $config = $this->prepareConfig($config);
67
68 12
        return (bool) $this->getAdapter()->write($path, $contents, $config);
69
    }
70
71
    /**
72
     * @inheritdoc
73
     */
74 15 View Code Duplication
    public function writeStream($path, $resource, array $config = [])
0 ignored issues
show
Duplication introduced by Frank de Jonge
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
75
    {
76 15
        if ( ! is_resource($resource)) {
77 6
            throw new InvalidArgumentException(__METHOD__ . ' expects argument #2 to be a valid resource.');
78
        }
79
80 9
        $path = Util::normalizePath($path);
81 9
        $this->assertAbsent($path);
82 9
        $config = $this->prepareConfig($config);
83
84 9
        Util::rewindStream($resource);
85
86 9
        return (bool) $this->getAdapter()->writeStream($path, $resource, $config);
87
    }
88
89
    /**
90
     * @inheritdoc
91
     */
92 9
    public function put($path, $contents, array $config = [])
93
    {
94 9
        $path = Util::normalizePath($path);
95 9
        $config = $this->prepareConfig($config);
96
97 9
        if ($this->has($path)) {
98 6
            return (bool) $this->getAdapter()->update($path, $contents, $config);
99
        }
100
101 6
        return (bool) $this->getAdapter()->write($path, $contents, $config);
102
    }
103
104
    /**
105
     * @inheritdoc
106
     */
107 12
    public function putStream($path, $resource, array $config = [])
108
    {
109 12
        if ( ! is_resource($resource)) {
110 3
            throw new InvalidArgumentException(__METHOD__ . ' expects argument #2 to be a valid resource.');
111
        }
112
113 9
        $path = Util::normalizePath($path);
114 9
        $config = $this->prepareConfig($config);
115 9
        Util::rewindStream($resource);
116
117 9
        if ($this->has($path)) {
118 6
            return (bool) $this->getAdapter()->updateStream($path, $resource, $config);
119
        }
120
121 6
        return (bool) $this->getAdapter()->writeStream($path, $resource, $config);
122
    }
123
124
    /**
125
     * @inheritdoc
126
     */
127 6
    public function readAndDelete($path)
128
    {
129 6
        $path = Util::normalizePath($path);
130 6
        $this->assertPresent($path);
131 6
        $contents = $this->read($path);
132
133 6
        if ($contents === false) {
134 3
            return false;
135
        }
136
137 3
        $this->delete($path);
138
139 3
        return $contents;
140
    }
141
142
    /**
143
     * @inheritdoc
144
     */
145 6 View Code Duplication
    public function update($path, $contents, array $config = [])
0 ignored issues
show
Duplication introduced by Frank de Jonge
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
146
    {
147 6
        $path = Util::normalizePath($path);
148 6
        $config = $this->prepareConfig($config);
149
150 6
        $this->assertPresent($path);
151
152 6
        return (bool) $this->getAdapter()->update($path, $contents, $config);
153
    }
154
155
    /**
156
     * @inheritdoc
157
     */
158 15 View Code Duplication
    public function updateStream($path, $resource, array $config = [])
0 ignored issues
show
Duplication introduced by Frank de Jonge
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
159
    {
160 15
        if ( ! is_resource($resource)) {
161 6
            throw new InvalidArgumentException(__METHOD__ . ' expects argument #2 to be a valid resource.');
162
        }
163
164 9
        $path = Util::normalizePath($path);
165 9
        $config = $this->prepareConfig($config);
166 9
        $this->assertPresent($path);
167 9
        Util::rewindStream($resource);
168
169 9
        return (bool) $this->getAdapter()->updateStream($path, $resource, $config);
170
    }
171
172
    /**
173
     * @inheritdoc
174
     */
175 36
    public function read($path)
176
    {
177 36
        $path = Util::normalizePath($path);
178 36
        $this->assertPresent($path);
179
180 30
        if ( ! ($object = $this->getAdapter()->read($path))) {
181 3
            return false;
182
        }
183
184 27
        return $object['contents'];
185
    }
186
187
    /**
188
     * @inheritdoc
189
     */
190 12
    public function readStream($path)
191
    {
192 12
        $path = Util::normalizePath($path);
193 12
        $this->assertPresent($path);
194
195 12
        if ( ! $object = $this->getAdapter()->readStream($path)) {
196 6
            return false;
197
        }
198
199 9
        return $object['stream'];
200
    }
201
202
    /**
203
     * @inheritdoc
204
     */
205 9 View Code Duplication
    public function rename($path, $newpath)
0 ignored issues
show
Duplication introduced by Frank de Jonge
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
206
    {
207 9
        $path = Util::normalizePath($path);
208 9
        $newpath = Util::normalizePath($newpath);
209 9
        $this->assertPresent($path);
210 9
        $this->assertAbsent($newpath);
211
212 9
        return (bool) $this->getAdapter()->rename($path, $newpath);
213
    }
214
215
    /**
216
     * @inheritdoc
217
     */
218 12 View Code Duplication
    public function copy($path, $newpath)
0 ignored issues
show
Duplication introduced by Frank de Jonge
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
219
    {
220 12
        $path = Util::normalizePath($path);
221 12
        $newpath = Util::normalizePath($newpath);
222 12
        $this->assertPresent($path);
223 12
        $this->assertAbsent($newpath);
224
225 12
        return $this->getAdapter()->copy($path, $newpath);
226
    }
227
228
    /**
229
     * @inheritdoc
230
     */
231 60
    public function delete($path)
232
    {
233 60
        $path = Util::normalizePath($path);
234 60
        $this->assertPresent($path);
235
236 57
        return $this->getAdapter()->delete($path);
237
    }
238
239
    /**
240
     * @inheritdoc
241
     */
242 63
    public function deleteDir($dirname)
243
    {
244 63
        $dirname = Util::normalizePath($dirname);
245
246 63
        if ($dirname === '') {
247 3
            throw new RootViolationException('Root directories can not be deleted.');
248
        }
249
250 60
        return (bool) $this->getAdapter()->deleteDir($dirname);
251
    }
252
253
    /**
254
     * @inheritdoc
255
     */
256 3 View Code Duplication
    public function createDir($dirname, array $config = [])
0 ignored issues
show
Duplication introduced by Frank de Jonge
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
257
    {
258 3
        $dirname = Util::normalizePath($dirname);
259 3
        $config = $this->prepareConfig($config);
260
261 3
        return (bool) $this->getAdapter()->createDir($dirname, $config);
262
    }
263
264
    /**
265
     * @inheritdoc
266
     */
267 12
    public function listContents($directory = '', $recursive = false)
268
    {
269 12
        $directory = Util::normalizePath($directory);
270 12
        $contents = $this->getAdapter()->listContents($directory, $recursive);
271
272 12
        return (new ContentListingFormatter($directory, $recursive))->formatListing($contents);
273
    }
274
275
    /**
276
     * @inheritdoc
277
     */
278 9
    public function getMimetype($path)
279
    {
280 9
        $path = Util::normalizePath($path);
281 9
        $this->assertPresent($path);
282
283 9
        if ( ! $object = $this->getAdapter()->getMimetype($path)) {
284 3
            return false;
285
        }
286
287 6
        return $object['mimetype'];
288
    }
289
290
    /**
291
     * @inheritdoc
292
     */
293 9
    public function getTimestamp($path)
294
    {
295 9
        $path = Util::normalizePath($path);
296 9
        $this->assertPresent($path);
297
298 9
        if ( ! $object = $this->getAdapter()->getTimestamp($path)) {
299 3
            return false;
300
        }
301
302 6
        return $object['timestamp'];
303
    }
304
305
    /**
306
     * @inheritdoc
307
     */
308 9 View Code Duplication
    public function getVisibility($path)
0 ignored issues
show
Duplication introduced by Frank de Jonge
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
309
    {
310 9
        $path = Util::normalizePath($path);
311 9
        $this->assertPresent($path);
312
313 9
        if (($object = $this->getAdapter()->getVisibility($path)) === false) {
314 3
            return false;
315
        }
316
317 6
        return $object['visibility'];
318
    }
319
320
    /**
321
     * @inheritdoc
322
     */
323 9 View Code Duplication
    public function getSize($path)
0 ignored issues
show
Duplication introduced by Frank de Jonge
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
324
    {
325 9
        $path = Util::normalizePath($path);
326
327 9
        if (($object = $this->getAdapter()->getSize($path)) === false || ! isset($object['size'])) {
328 3
            return false;
329
        }
330
331 6
        return (int) $object['size'];
332
    }
333
334
    /**
335
     * @inheritdoc
336
     */
337 6
    public function setVisibility($path, $visibility)
338
    {
339 6
        $path = Util::normalizePath($path);
340
341 6
        return (bool) $this->getAdapter()->setVisibility($path, $visibility);
342
    }
343
344
    /**
345
     * @inheritdoc
346
     */
347 51
    public function getMetadata($path)
348
    {
349 51
        $path = Util::normalizePath($path);
350 51
        $this->assertPresent($path);
351
352 51
        return $this->getAdapter()->getMetadata($path);
353
    }
354
355
    /**
356
     * @inheritdoc
357
     */
358 69
    public function get($path, Handler $handler = null)
359
    {
360 69
        $path = Util::normalizePath($path);
361
362 69
        if ( ! $handler) {
363 45
            $metadata = $this->getMetadata($path);
364 45
            $handler = $metadata['type'] === 'file' ? new File($this, $path) : new Directory($this, $path);
365 45
        }
366
367 69
        $handler->setPath($path);
368 69
        $handler->setFilesystem($this);
369
370 69
        return $handler;
371
    }
372
373
    /**
374
     * Assert a file is present.
375
     *
376
     * @param string $path path to file
377
     *
378
     * @throws FileNotFoundException
379
     *
380
     * @return void
381
     */
382 129
    public function assertPresent($path)
383
    {
384 129
        if ($this->config->get('disable_asserts', false) === false && ! $this->has($path)) {
385 12
            throw new FileNotFoundException($path);
386
        }
387 123
    }
388
389
    /**
390
     * Assert a file is absent.
391
     *
392
     * @param string $path path to file
393
     *
394
     * @throws FileExistsException
395
     *
396
     * @return void
397
     */
398 45
    public function assertAbsent($path)
399
    {
400 45
        if ($this->config->get('disable_asserts', false) === false && $this->has($path)) {
401 3
            throw new FileExistsException($path);
402
        }
403 42
    }
404
}
405