Completed
Push — master ( 25fd12...6709ed )
by Oscar
02:13
created

Directory   A

Complexity

Total Complexity 35

Size/Duplication

Total Lines 336
Duplicated Lines 17.86 %

Coupling/Cohesion

Components 1
Dependencies 5

Importance

Changes 4
Bugs 1 Features 0
Metric Value
wmc 35
c 4
b 1
f 0
lcom 1
cbo 5
dl 60
loc 336
rs 9

21 Methods

Rating   Name   Duplication   Size   Complexity  
A make() 0 4 1
A __construct() 0 6 1
A getDocument() 0 19 4
A getDirectory() 0 12 3
A hasDocument() 16 16 3
A hasDirectory() 16 16 3
A saveDocument() 0 7 1
A createDirectory() 0 7 1
A deleteDocument() 0 7 1
A deleteDirectory() 0 7 1
A getAllDocuments() 14 14 3
A getAllDirectories() 14 14 3
A getDocumentPath() 0 4 1
A getDirectoryPath() 0 8 2
A offsetExists() 0 4 1
A offsetGet() 0 4 1
A offsetSet() 0 4 1
A offsetUnset() 0 4 1
A __get() 0 4 1
A __isset() 0 4 1
A __unset() 0 4 1

How to fix   Duplicated Code   

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:

1
<?php
2
3
namespace FlyCrud;
4
5
use League\Flysystem\FilesystemInterface;
6
use League\Flysystem\Filesystem;
7
use League\Flysystem\Adapter\Local;
8
use ArrayAccess;
9
10
class Directory implements ArrayAccess
11
{
12
    protected $path;
13
    protected $format;
14
    protected $filesystem;
15
    protected $documents = [];
16
    protected $directories = [];
17
18
    /**
19
     * Creates a new directory instance.
20
     * 
21
     * @param string          $path
22
     * @param FormatInterface $format
23
     * 
24
     * @return static
25
     */
26
    public static function make($path, FormatInterface $format)
27
    {
28
        return new static(new Filesystem(new Local($path)), '', $format);
29
    }
30
31
    /**
32
     * Init the directory.
33
     * 
34
     * @param FilesystemInterface $filesystem
35
     * @param string              $path
36
     * @param FormatInterface     $format
37
     */
38
    public function __construct(FilesystemInterface $filesystem, $path, FormatInterface $format)
39
    {
40
        $this->filesystem = $filesystem;
41
        $this->format = $format;
42
        $this->path = $path;
43
    }
44
45
    /**
46
     * Read and return a document.
47
     * 
48
     * @param string $id
49
     * 
50
     * @return Document
51
     */
52
    public function getDocument($id)
53
    {
54
        if (isset($this->documents[$id])) {
55
            return $this->documents[$id];
56
        }
57
58
        if ($this->hasDocument($id)) {
59
            $path = $this->getDocumentPath($id);
60
            $source = $this->filesystem->read($path);
61
62
            if (is_string($source)) {
63
                return $this->documents[$id] = new Document($this->format->parse($source));
64
            }
65
66
            throw new Exception(sprintf('Format error in the file "%s"', $path));
67
        }
68
69
        throw new Exception(sprintf('File "%s" not found', $path));
70
    }
71
72
    /**
73
     * Read and return a directory.
74
     * 
75
     * @param string $id
76
     * 
77
     * @return static
78
     */
79
    public function getDirectory($id)
80
    {
81
        if (isset($this->directories[$id])) {
82
            return $this->directories[$id];
83
        }
84
85
        if ($this->hasDirectory($id)) {
86
            return $this->directories[$id] = new static($this->filesystem, $this->getDirectoryPath($id), $this->format);
87
        }
88
89
        throw new Exception(sprintf('Directory "%s" not found', $path));
90
    }
91
92
    /**
93
     * Check whether a document exists.
94
     * 
95
     * @param string $id
96
     * 
97
     * @return bool
98
     */
99 View Code Duplication
    public function hasDocument($id)
0 ignored issues
show
Duplication introduced by
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...
100
    {
101
        if (isset($this->documents[$id])) {
102
            return true;
103
        }
104
105
        $path = $this->getDocumentPath($id);
106
107
        if ($this->filesystem->has($path)) {
108
            $info = $this->filesystem->getMetadata($path);
109
110
            return $info['type'] === 'file';
111
        }
112
113
        return false;
114
    }
115
116
    /**
117
     * Check whether a document or directory exists.
118
     * 
119
     * @param string $id
120
     * 
121
     * @return bool
122
     */
123 View Code Duplication
    public function hasDirectory($id)
0 ignored issues
show
Duplication introduced by
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...
124
    {
125
        if (isset($this->directories[$id])) {
126
            return true;
127
        }
128
129
        $path = $this->getDirectoryPath($id);
130
131
        if ($this->filesystem->has($path)) {
132
            $info = $this->filesystem->getMetadata($path);
133
134
            return $info['type'] === 'dir';
135
        }
136
137
        return false;
138
    }
139
140
    /**
141
     * Saves a document.
142
     * 
143
     * @param string   $id
144
     * @param Document $document
145
     * 
146
     * @return self
147
     */
148
    public function saveDocument($id, Document $document)
149
    {
150
        $this->documents[$id] = $document;
151
        $this->filesystem->put($this->getDocumentPath($id), $this->format->stringify($document->getArrayCopy()));
152
153
        return $this;
154
    }
155
156
    /**
157
     * Creates a new directory.
158
     * 
159
     * @param string $id
160
     * 
161
     * @return static
162
     */
163
    public function createDirectory($id)
164
    {
165
        $path = $this->getDirectoryPath($id);
166
        $this->filesystem->createDir($path);
167
168
        return $this->directories[$id] = new static($this->filesystem, $path, $this->format);
169
    }
170
171
    /**
172
     * Deletes a document.
173
     * 
174
     * @param string $id
175
     * 
176
     * @return self
177
     */
178
    public function deleteDocument($id)
179
    {
180
        $this->filesystem->delete($this->getDocumentPath($id));
181
        unset($this->documents[$id]);
182
183
        return $this;
184
    }
185
186
    /**
187
     * Deletes a directory.
188
     * 
189
     * @param string $id
190
     * 
191
     * @return self
192
     */
193
    public function deleteDirectory($id)
194
    {
195
        $this->filesystem->deleteDir($this->getDirectoryPath($id));
196
        unset($this->directories[$id]);
197
198
        return $this;
199
    }
200
201
    /**
202
     * Returns all documents.
203
     * 
204
     * @return array
205
     */
206 View Code Duplication
    public function getAllDocuments()
0 ignored issues
show
Duplication introduced by
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...
207
    {
208
        $documents = [];
209
210
        foreach ($this->filesystem->listContents('/'.$this->path) as $info) {
211
            $id = $info['filename'];
212
213
            if ($this->hasDocument($id)) {
214
                $documents[$id] = $this->getDocument($id);
215
            }
216
        }
217
218
        return $documents;
219
    }
220
221
    /**
222
     * Returns all directories.
223
     * 
224
     * @return array
225
     */
226 View Code Duplication
    public function getAllDirectories()
0 ignored issues
show
Duplication introduced by
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...
227
    {
228
        $directories = [];
229
230
        foreach ($this->filesystem->listContents('/'.$this->path) as $info) {
231
            $id = $info['filename'];
232
233
            if ($this->hasDirectory($id)) {
234
                $directories[$id] = $this->getDirectory($id);
235
            }
236
        }
237
238
        return $directories;
239
    }
240
241
    /**
242
     * Returns a file path.
243
     * 
244
     * @param string $id
245
     * 
246
     * @return string
247
     */
248
    private function getDocumentPath($id)
249
    {
250
        return $this->getDirectoryPath($id).'.'.$this->format->getExtension();
251
    }
252
253
    /**
254
     * Returns a directory path.
255
     * 
256
     * @param string $id
257
     * 
258
     * @return string
259
     */
260
    private function getDirectoryPath($id)
261
    {
262
        if ($this->path === '') {
263
            return "/{$id}";
264
        }
265
266
        return "/{$this->path}/{$id}";
267
    }
268
269
    /**
270
     * ArrayAccess used to documents.
271
     * 
272
     * @param string $id
273
     * 
274
     * @return bool
275
     */
276
    public function offsetExists($id)
277
    {
278
        return $this->hasDocument($id);
279
    }
280
281
    /**
282
     * ArrayAccess used to documents.
283
     * 
284
     * @param string $id
285
     * 
286
     * @return Document
287
     */
288
    public function offsetGet($id)
289
    {
290
        return $this->getDocument($id);
291
    }
292
293
    /**
294
     * ArrayAccess used to documents.
295
     * 
296
     * @param string   $id
297
     * @param Document $document
298
     */
299
    public function offsetSet($id, $document)
300
    {
301
        $this->saveDocument($id, $document);
302
    }
303
304
    /**
305
     * ArrayAccess used to documents.
306
     * 
307
     * @param string $id
308
     */
309
    public function offsetUnset($id)
310
    {
311
        $this->deleteDocument($id);
312
    }
313
314
    /**
315
     * Property magic method used to directories.
316
     * 
317
     * @param string $id
318
     * 
319
     * @return Directory
320
     */
321
    public function __get($id)
322
    {
323
        return $this->getDirectory($id);
324
    }
325
326
    /**
327
     * Property magic method used to directories.
328
     * 
329
     * @param string $id
330
     */
331
    public function __isset($id)
332
    {
333
        return $this->hasDirectory($id);
334
    }
335
336
    /**
337
     * Property magic method used to directories.
338
     * 
339
     * @param string $id
340
     */
341
    public function __unset($id)
342
    {
343
        $this->deleteDirectory($id);
344
    }
345
}
346