Filesystem::extension()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 1
c 1
b 0
f 0
dl 0
loc 3
ccs 2
cts 2
cp 1
rs 10
cc 1
nc 1
nop 1
crap 1
1
<?php
2
3
namespace Yiranzai\Tools;
4
5
use Exception;
6
use FilesystemIterator;
7
use Symfony\Component\Filesystem\Exception\IOException;
8
use Symfony\Component\Filesystem\Filesystem as FilesystemAlias;
9
10
class Filesystem extends FilesystemAlias
11
{
12
13
    /**
14
     * Get the MD5 hash of the file at the given path.
15
     *
16
     * @param string $path
17
     * @return string
18
     */
19 3
    public function hash($path): string
20
    {
21 3
        return md5_file($path);
22
    }
23
24
    /**
25
     * Prepend to a file.
26
     *
27
     * @param string $path
28
     * @param string $data
29
     * @return int
30
     */
31 3
    public function prepend($path, $data): int
32
    {
33 3
        if ($this->exists($path)) {
34 3
            return $this->put($path, $data . $this->get($path));
35
        }
36
37 3
        return $this->put($path, $data);
38
    }
39
40
    /**
41
     * Determine if a file or directory exists.
42
     *
43
     * @param string $path
44
     * @return bool
45
     */
46 9
    public function exists($path): bool
47
    {
48 9
        return file_exists($path);
49
    }
50
51
    /**
52
     * Store contents in the file
53
     *
54
     * @param string $path
55
     * @param string $contents
56
     * @param bool   $lock
57
     * @return bool|int
58
     */
59 3
    public function put($path, $contents, $lock = false)
60
    {
61 3
        $this->ensureCacheDirectoryExists($path);
62 3
        return file_put_contents($path, $contents, $lock ? LOCK_EX : 0);
63
    }
64
65
    /**
66
     * Create the file cache directory if necessary.
67
     *
68
     * @param string $path
69
     * @return void
70
     */
71 3
    protected function ensureCacheDirectoryExists($path): void
72
    {
73 3
        if (!$this->exists(dirname($path))) {
74 3
            $this->makeDirectory(dirname($path), 0777, true, true);
75
        }
76 3
    }
77
78
    /**
79
     * Create a directory.
80
     *
81
     * @param string $path
82
     * @param int    $mode
83
     * @param bool   $recursive
84
     * @param bool   $force
85
     * @return bool
86
     */
87 9
    public function makeDirectory($path, $mode = 0755, $recursive = false, $force = false): bool
88
    {
89 9
        if ($force) {
90 6
            return @mkdir($path, $mode, $recursive);
91
        }
92
93 6
        return mkdir($path, $mode, $recursive);
94
    }
95
96
    /**
97
     * Get the contents of a file.
98
     *
99
     * @param string $path
100
     * @param bool   $lock
101
     * @return string
102
     */
103 6
    public function get($path, $lock = false): string
104
    {
105 6
        if ($this->isFile($path)) {
106 3
            return $lock ? $this->sharedGet($path) : file_get_contents($path);
107
        }
108
109 3
        throw new IOException("File does not exist at path {$path}");
110
    }
111
112
    /**
113
     * Determine if the given path is a file.
114
     *
115
     * @param string $file
116
     * @return bool
117
     */
118 6
    public function isFile($file): bool
119
    {
120 6
        return is_file($file);
121
    }
122
123
    /**
124
     * Get contents of a file with shared access.
125
     *
126
     * @param string $path
127
     * @return string
128
     */
129 3
    public function sharedGet($path): string
130
    {
131 3
        $contents = '';
132
133 3
        $handle = fopen($path, 'rb');
134
135 3
        if ($handle !== false) {
136
            try {
137 3
                if (flock($handle, LOCK_SH)) {
138 3
                    clearstatcache(true, $path);
139
140 3
                    $contents = fread($handle, $this->size($path) ?: 1);
141
142 3
                    flock($handle, LOCK_UN);
143
                }
144 3
            } finally {
145 3
                fclose($handle);
146
            }
147
        }
148
149 3
        return $contents;
150
    }
151
152
    /**
153
     * Get the file size of a given file.
154
     *
155
     * @param string $path
156
     * @return int
157
     */
158 3
    public function size($path): int
159
    {
160 3
        return filesize($path);
161
    }
162
163
    /**
164
     * Append to a file.
165
     *
166
     * @param string $path
167
     * @param string $data
168
     * @return int
169
     */
170 3
    public function append($path, $data): int
171
    {
172 3
        return file_put_contents($path, $data, FILE_APPEND);
173
    }
174
175
    /**
176
     * Get or set UNIX mode of a file or directory.
177
     *
178
     * @param string $path
179
     * @param int    $mode
180
     * @return mixed
181
     */
182 9
    public function chmodFile($path, $mode = null)
183
    {
184 9
        if ($mode !== null) {
185 9
            return chmod($path, $mode);
186
        }
187
188 3
        return substr(sprintf('%o', fileperms($path)), -4);
189
    }
190
191
    /**
192
     * Move a file to a new location.
193
     *
194
     * @param string $path
195
     * @param string $target
196
     * @return bool
197
     */
198 3
    public function move($path, $target): bool
199
    {
200 3
        return rename($path, $target);
201
    }
202
203
    /**
204
     * Extract the file name from a file path.
205
     *
206
     * @param string $path
207
     * @return string
208
     */
209 3
    public function name($path): string
210
    {
211 3
        return pathinfo($path, PATHINFO_FILENAME);
212
    }
213
214
    /**
215
     * Extract the trailing name component from a file path.
216
     *
217
     * @param string $path
218
     * @return string
219
     */
220 3
    public function basename($path): string
221
    {
222 3
        return pathinfo($path, PATHINFO_BASENAME);
223
    }
224
225
    /**
226
     * Extract the parent directory from a file path.
227
     *
228
     * @param string $path
229
     * @return string
230
     */
231 3
    public function dirname($path): string
232
    {
233 3
        return pathinfo($path, PATHINFO_DIRNAME);
234
    }
235
236
    /**
237
     * Extract the file extension from a file path.
238
     *
239
     * @param string $path
240
     * @return string
241
     */
242 3
    public function extension($path): string
243
    {
244 3
        return pathinfo($path, PATHINFO_EXTENSION);
245
    }
246
247
    /**
248
     * Get the file type of a given file.
249
     *
250
     * @param string $path
251
     * @return string
252
     */
253 3
    public function type($path): string
254
    {
255 3
        return filetype($path);
256
    }
257
258
    /**
259
     * Get the mime-type of a given file.
260
     *
261
     * @param string $path
262
     * @return string|false
263
     */
264 3
    public function mimeType($path)
265
    {
266 3
        return finfo_file(finfo_open(FILEINFO_MIME_TYPE), $path);
267
    }
268
269
    /**
270
     * Get the file's last modification time.
271
     *
272
     * @param string $path
273
     * @return int
274
     */
275 3
    public function lastModified($path): int
276
    {
277 3
        return filemtime($path);
278
    }
279
280
    /**
281
     * Determine if the given path is readable.
282
     *
283
     * @param string $path
284
     * @return bool
285
     */
286 9
    public function isReadable($path): bool
287
    {
288 9
        return is_readable($path);
289
    }
290
291
    /**
292
     * Determine if the given path is writable.
293
     *
294
     * @param string $path
295
     * @return bool
296
     */
297 9
    public function isWritable($path): bool
298
    {
299 9
        return is_writable($path);
300
    }
301
302
    /**
303
     * Move a directory.
304
     *
305
     * @param string $from
306
     * @param string $to
307
     * @param bool   $overwrite
308
     * @return bool
309
     */
310 6
    public function moveDirectory($from, $to, $overwrite = false): bool
311
    {
312 6
        if ($overwrite && $this->isDirectory($to) && !$this->deleteDirectory($to)) {
313
            return false;
314
        }
315
316 6
        return @rename($from, $to) === true;
317
    }
318
319
    /**
320
     * Determine if the given path is a directory.
321
     *
322
     * @param string $directory
323
     * @return bool
324
     */
325 9
    public function isDirectory($directory): bool
326
    {
327 9
        return is_dir($directory);
328
    }
329
330
    /**
331
     * Recursively delete a directory.
332
     *
333
     * The directory itself may be optionally preserved.
334
     *
335
     * @param string $directory
336
     * @param bool   $preserve
337
     * @return bool
338
     */
339 9
    public function deleteDirectory($directory, $preserve = false): bool
340
    {
341 9
        if (!$this->isDirectory($directory)) {
342 3
            return false;
343
        }
344
345 9
        $items = new FilesystemIterator($directory);
346
347 9
        foreach ($items as $item) {
348 3
            if ($item->isDir() && !$item->isLink()) {
349 3
                $this->deleteDirectory($item->getPathname());
350
            } else {
351 2
                $this->delete($item->getPathname());
352
            }
353
        }
354
355 9
        if (!$preserve) {
356
            /** @scrutinizer ignore-unhandled */
357 9
            @rmdir($directory);
358
        }
359
360 9
        return true;
361
    }
362
363
    /**
364
     * Delete the file at a given path.
365
     *
366
     * @param string|array $paths
367
     * @return bool
368
     */
369 3
    public function delete($paths): bool
370
    {
371 3
        $paths = is_array($paths) ? $paths : func_get_args();
372
373 3
        $success = true;
374
375 3
        foreach ($paths as $path) {
376
            try {
377 3
                if (!@unlink($path)) {
378 3
                    $success = false;
379
                }
380
            } catch (Exception $e) {
381 2
                $success = false;
382
            }
383
        }
384
385 3
        return $success;
386
    }
387
388
    /**
389
     * Copy a directory from one location to another.
390
     *
391
     * @param string $directory
392
     * @param string $destination
393
     * @param int    $options
394
     * @return bool
395
     */
396 6
    public function copyDirectory($directory, $destination, $options = null): bool
397
    {
398 6
        if (!$this->isDirectory($directory)) {
399
            return false;
400
        }
401
402 6
        $options = $options ?: FilesystemIterator::SKIP_DOTS;
403
404 6
        if (!$this->isDirectory($destination)) {
405 6
            $this->makeDirectory($destination, 0777, true);
406
        }
407
408 6
        $items = new FilesystemIterator($directory, $options);
409
410 6
        foreach ($items as $item) {
411 3
            $target = $destination . '/' . $item->getBasename();
412
413 3
            if (!$item->isDir()) {
414
                if (!$this->copyFile($item->getPathname(), $target)) {
415
                    return false;
416
                }
417
            } else {
418 3
                $path = $item->getPathname();
419
420 3
                if (!$this->copyDirectory($path, $target, $options)) {
421 2
                    return false;
422
                }
423
            }
424
        }
425
426 6
        return true;
427
    }
428
429
    /**
430
     * Copy a file to a new location.
431
     *
432
     * @param string $path
433
     * @param string $target
434
     * @return bool
435
     */
436 3
    public function copyFile($path, $target): bool
437
    {
438 3
        return copy($path, $target);
439
    }
440
441
    /**
442
     * Empty the specified directory of all files and folders.
443
     *
444
     * @param string $directory
445
     * @return bool
446
     */
447 3
    public function cleanDirectory($directory): bool
448
    {
449 3
        return $this->deleteDirectory($directory, true);
450
    }
451
452
    /**
453
     * Determine whether the current environment is Windows based.
454
     *
455
     * @return bool
456
     */
457 3
    public function windowsOs(): bool
458
    {
459 3
        return stripos(PHP_OS, 'win') === 0;
460
    }
461
}
462