Completed
Pull Request — master (#582)
by
unknown
02:55
created

Local::createDirectory()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 6
rs 10
c 0
b 0
f 0
cc 3
nc 2
nop 1
1
<?php
2
3
namespace Gaufrette\Adapter;
4
5
use Gaufrette\Util;
6
use Gaufrette\Adapter;
7
use Gaufrette\Stream;
8
9
10
/**
11
 * Adapter for the local filesystem.
12
 *
13
 * @author Antoine Hérault <[email protected]>
14
 * @author Leszek Prabucki <[email protected]>
15
 */
16
class Local implements Adapter,
17
    StreamFactory,
18
    ChecksumCalculator,
19
    SizeCalculator,
20
    MimeTypeProvider
21
{
22
    protected $directory;
23
    private $create;
24
    private $mode;
25
26
    /**
27
     * @param string $directory Directory where the filesystem is located
28
     * @param bool   $create    Whether to create the directory if it does not
29
     *                          exist (default FALSE)
30
     * @param int    $mode      Mode for mkdir
31
     *
32
     * @throws \RuntimeException if the specified directory does not exist and
33
     *                          could not be created
34
     */
35
    public function __construct($directory, $create = false, $mode = 0777)
36
    {
37
        $this->directory = Util\Path::normalize($directory);
38
39
        if (is_link($this->directory)) {
40
            $this->directory = realpath($this->directory);
41
        }
42
43
        $this->create = $create;
44
        $this->mode = $mode;
45
    }
46
47
    /**
48
     * {@inheritdoc}
49
     *
50
     * @throws \OutOfBoundsException     If the computed path is out of the directory
51
     * @throws \InvalidArgumentException if the directory already exists
52
     * @throws \RuntimeException         if the directory could not be created
53
     */
54
    public function read($key)
55
    {
56
        if ($this->isDirectory($key)) {
57
            return false;
58
        }
59
60
        return file_get_contents($this->computePath($key));
61
    }
62
63
    /**
64
     * {@inheritdoc}
65
     *
66
     * @throws \OutOfBoundsException     If the computed path is out of the directory
67
     * @throws \InvalidArgumentException if the directory already exists
68
     * @throws \RuntimeException         if the directory could not be created
69
     */
70 View Code Duplication
    public function write($key, $content)
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...
71
    {
72
        $path = $this->computePath($key);
73
        $this->ensureDirectoryExists(\Gaufrette\Util\Path::dirname($path), true);
74
75
        return file_put_contents($path, $content);
76
    }
77
78
    /**
79
     * {@inheritdoc}
80
     *
81
     * @throws \OutOfBoundsException     If the computed path is out of the directory
82
     * @throws \InvalidArgumentException if the directory already exists
83
     * @throws \RuntimeException         if the directory could not be created
84
     */
85 View Code Duplication
    public function rename($sourceKey, $targetKey)
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...
86
    {
87
        $targetPath = $this->computePath($targetKey);
88
        $this->ensureDirectoryExists(\Gaufrette\Util\Path::dirname($targetPath), true);
89
90
        return rename($this->computePath($sourceKey), $targetPath);
91
    }
92
93
    /**
94
     * {@inheritdoc}
95
     */
96
    public function exists($key)
97
    {
98
        return is_file($this->computePath($key));
99
    }
100
101
    /**
102
     * {@inheritdoc}
103
     *
104
     * @throws \OutOfBoundsException     If the computed path is out of the directory
105
     * @throws \InvalidArgumentException if the directory already exists
106
     * @throws \RuntimeException         if the directory could not be created
107
     */
108
    public function keys()
109
    {
110
        $this->ensureDirectoryExists($this->directory, $this->create);
111
112
        try {
113
            $files = new \RecursiveIteratorIterator(
114
                new \RecursiveDirectoryIterator(
115
                    $this->directory,
116
                    \FilesystemIterator::SKIP_DOTS | \FilesystemIterator::UNIX_PATHS
117
                ),
118
                \RecursiveIteratorIterator::CHILD_FIRST
119
            );
120
        } catch (\Exception $e) {
121
            $files = new \EmptyIterator();
122
        }
123
124
        $keys = [];
125
        foreach ($files as $file) {
126
            $keys[] = $this->computeKey($file);
127
        }
128
        sort($keys);
129
130
        return $keys;
131
    }
132
133
    /**
134
     * {@inheritdoc}
135
     *
136
     * @throws \OutOfBoundsException     If the computed path is out of the directory
137
     * @throws \InvalidArgumentException if the directory already exists
138
     * @throws \RuntimeException         if the directory could not be created
139
     */
140
    public function mtime($key)
141
    {
142
        return filemtime($this->computePath($key));
143
    }
144
145
    /**
146
     * {@inheritdoc}
147
     *
148
     * @throws \OutOfBoundsException     If the computed path is out of the directory
149
     * @throws \InvalidArgumentException if the directory already exists
150
     * @throws \RuntimeException         if the directory could not be created
151
     */
152
    public function delete($key)
153
    {
154
        if ($this->isDirectory($key)) {
155
            self::deleteDirectory($this->computePath($key));
156
157
            return true;
158
        }
159
160
        return unlink($this->computePath($key));
161
    }
162
163
    /**
164
     * @param string $key
165
     *
166
     * @return bool
167
     *
168
     * @throws \OutOfBoundsException     If the computed path is out of the directory
169
     * @throws \InvalidArgumentException if the directory already exists
170
     * @throws \RuntimeException         if the directory could not be created
171
     */
172
    public function isDirectory($key)
173
    {
174
        return is_dir($this->computePath($key));
175
    }
176
177
    /**
178
     * {@inheritdoc}
179
     *
180
     * @throws \OutOfBoundsException     If the computed path is out of the directory
181
     * @throws \InvalidArgumentException if the directory already exists
182
     * @throws \RuntimeException         if the directory could not be created
183
     */
184
    public function createStream($key)
185
    {
186
        return new Stream\Local($this->computePath($key), $this->mode);
187
    }
188
189
    /**
190
     * {@inheritdoc}
191
     *
192
     * @throws \OutOfBoundsException     If the computed path is out of the directory
193
     * @throws \InvalidArgumentException if the directory already exists
194
     * @throws \RuntimeException         if the directory could not be created
195
     */
196
    public function checksum($key)
197
    {
198
        return Util\Checksum::fromFile($this->computePath($key));
199
    }
200
201
    /**
202
     * {@inheritdoc}
203
     *
204
     * @throws \OutOfBoundsException     If the computed path is out of the directory
205
     * @throws \InvalidArgumentException if the directory already exists
206
     * @throws \RuntimeException         if the directory could not be created
207
     */
208
    public function size($key)
209
    {
210
        return Util\Size::fromFile($this->computePath($key));
211
    }
212
213
    /**
214
     * {@inheritdoc}
215
     *
216
     * @throws \OutOfBoundsException     If the computed path is out of the directory
217
     * @throws \InvalidArgumentException if the directory already exists
218
     * @throws \RuntimeException         if the directory could not be created
219
     */
220
    public function mimeType($key)
221
    {
222
        $fileInfo = new \finfo(FILEINFO_MIME_TYPE);
223
224
        return $fileInfo->file($this->computePath($key));
225
    }
226
227
    /**
228
     * Computes the key from the specified path.
229
     *
230
     * @param $path
231
     * @return string
232
     *
233
     * @throws \OutOfBoundsException     If the computed path is out of the directory
234
     * @throws \InvalidArgumentException if the directory already exists
235
     * @throws \RuntimeException         if the directory could not be created
236
     */
237
    public function computeKey($path)
238
    {
239
        $path = $this->normalizePath($path);
240
241
        return ltrim(substr($path, strlen($this->directory)), '/');
242
    }
243
244
    /**
245
     * Computes the path from the specified key.
246
     *
247
     * @param string $key The key which for to compute the path
248
     *
249
     * @return string A path
250
     *
251
     * @throws \InvalidArgumentException If the directory already exists
252
     * @throws \OutOfBoundsException     If the computed path is out of the directory
253
     * @throws \RuntimeException         If directory does not exists and cannot be created
254
     */
255
    protected function computePath($key)
256
    {
257
        $this->ensureDirectoryExists($this->directory, $this->create);
258
259
        return $this->normalizePath($this->directory.'/'.$key);
260
    }
261
262
    /**
263
     * Normalizes the given path.
264
     *
265
     * @param string $path
266
     *
267
     * @return string
268
     * @throws \OutOfBoundsException If the computed path is out of the
269
     *                              directory
270
     */
271
    protected function normalizePath($path)
272
    {
273
        $path = Util\Path::normalize($path);
274
275
        if (0 !== strpos($path, $this->directory)) {
276
            throw new \OutOfBoundsException(sprintf('The path "%s" is out of the filesystem.', $path));
277
        }
278
279
        return $path;
280
    }
281
282
    /**
283
     * Ensures the specified directory exists, creates it if it does not.
284
     *
285
     * @param string $directory Path of the directory to test
286
     * @param bool   $create    Whether to create the directory if it does
287
     *                          not exist
288
     *
289
     * @throws \InvalidArgumentException if the directory already exists
290
     * @throws \RuntimeException if the directory does not exists and could not
291
     *                          be created
292
     */
293
    protected function ensureDirectoryExists($directory, $create = false)
294
    {
295
        if (!is_dir($directory)) {
296
            if (!$create) {
297
                throw new \RuntimeException(sprintf('The directory "%s" does not exist.', $directory));
298
            }
299
300
            $this->createDirectory($directory);
301
        }
302
    }
303
304
    /**
305
     * Creates the specified directory and its parents.
306
     *
307
     * @param string $directory Path of the directory to create
308
     *
309
     * @throws \InvalidArgumentException if the directory already exists
310
     * @throws \RuntimeException         if the directory could not be created
311
     */
312
    protected function createDirectory($directory)
313
    {
314
        if (!@mkdir($directory, $this->mode, true) && !is_dir($directory)) {
315
            throw new \RuntimeException(sprintf('The directory \'%s\' could not be created.', $directory));
316
        }
317
    }
318
319
    public static function deleteDirectory($directory)
320
    {
321
        if ($directory === '/') {
322
            throw new \InvalidArgumentException('Deleting "/" is disallowed.');
323
        }
324
325
        if (file_exists($directory)) {
326
            $iterator = new \RecursiveIteratorIterator(
327
                new \RecursiveDirectoryIterator(
328
                    $directory,
329
                    \FilesystemIterator::SKIP_DOTS | \FilesystemIterator::UNIX_PATHS
330
                ),
331
                \RecursiveIteratorIterator::CHILD_FIRST
332
            );
333
334
            foreach ($iterator as $item) {
335
                if ($item->isDir()) {
336
                    rmdir(strval($item));
337
                } else {
338
                    unlink(strval($item));
339
                }
340
            }
341
342
            rmdir($directory);
343
        }
344
    }
345
}
346