Directory   A
last analyzed

Complexity

Total Complexity 33

Size/Duplication

Total Lines 202
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 43
dl 0
loc 202
ccs 55
cts 55
cp 1
rs 9.76
c 1
b 0
f 0
wmc 33

11 Methods

Rating   Name   Duplication   Size   Complexity  
A ensureDelete() 0 3 2
A doesntExist() 0 3 1
A make() 0 3 2
A validate() 0 4 2
A isDirectory() 0 7 2
A all() 0 7 2
A ensureDirectory() 0 8 4
A validated() 0 5 1
A exists() 0 3 2
A delete() 0 19 5
B names() 0 28 10
1
<?php
2
/*
3
 * This file is part of the "andrey-helldar/support" project.
4
 *
5
 * For the full copyright and license information, please view the LICENSE
6
 * file that was distributed with this source code.
7
 *
8
 * @author Andrey Helldar <[email protected]>
9
 *
10
 * @copyright 2021 Andrey Helldar
11
 *
12
 * @license MIT
13
 *
14
 * @see https://github.com/andrey-helldar/support
15
 */
16
17
namespace Helldar\Support\Helpers\Filesystem;
18
19
use DirectoryIterator;
20
use FilesystemIterator;
21
use Helldar\Support\Exceptions\DirectoryNotFoundException;
22
use Helldar\Support\Facades\Helpers\Filesystem\File as FileHelper;
23
use Helldar\Support\Facades\Helpers\Instance;
24
use Helldar\Support\Facades\Helpers\Str;
25
use SplFileInfo;
26
27
class Directory
28
{
29
    /**
30
     * Get a list of files and folders in a directory.
31
     *
32
     * @param  string  $path
33
     *
34
     * @throws \Helldar\Support\Exceptions\DirectoryNotFoundException
35
     *
36
     * @return DirectoryIterator
37
     */
38 18
    public function all(string $path): DirectoryIterator
39
    {
40 18
        if ($this->doesntExist($path)) {
41 4
            throw new DirectoryNotFoundException($path);
42
        }
43
44 14
        return new DirectoryIterator($path);
45
    }
46
47
    /**
48
     * Get a list of directory names along a path.
49
     *
50
     * @param  string  $path
51
     * @param  callable|null  $callback
52
     * @param  bool  $recursive
53
     *
54
     * @throws \Helldar\Support\Exceptions\DirectoryNotFoundException
55
     *
56
     * @return array
57
     */
58 6
    public function names(string $path, callable $callback = null, bool $recursive = false): array
59
    {
60 6
        $items = [];
61
62
        /** @var \DirectoryIterator $directory */
63 6
        foreach ($this->all($path) as $directory) {
64 6
            if ($directory->isDir() && ! $directory->isDot()) {
65 6
                $name = $directory->getFilename();
66
67 6
                if (! is_callable($callback) || $callback($name)) {
68 6
                    $items[] = $name;
69
                }
70
            }
71
72 6
            if ($recursive && $directory->isDir() && ! $directory->isDot()) {
73 2
                $prefix = (string) Str::of($directory->getRealPath())
74 2
                    ->after(realpath($path))
75 2
                    ->trim('\\/');
76
77 2
                foreach ($this->names($directory->getRealPath(), $callback, $recursive) as $value) {
78 2
                    $items[] = $prefix . '/' . $value;
79
                }
80
            }
81
        }
82
83 6
        sort($items);
84
85 6
        return array_values($items);
86
    }
87
88
    /**
89
     * Create a directory at the specified path.
90
     *
91
     * @param  string  $path
92
     * @param  int  $mode
93
     *
94
     * @return bool
95
     */
96 38
    public function make(string $path, int $mode = 0755): bool
97
    {
98 38
        return ! $this->doesntExist($path) || mkdir($path, $mode, true);
99
    }
100
101
    /**
102
     * Delete the directory with all contents in the specified path.
103
     *
104
     * @param  string  $path
105
     *
106
     * @throws \Helldar\Support\Exceptions\DirectoryNotFoundException
107
     *
108
     * @return bool
109
     */
110 40
    public function delete(string $path): bool
111
    {
112 40
        if (! $this->isDirectory($path)) {
113 4
            throw new DirectoryNotFoundException($path);
114
        }
115
116 38
        $items = new FilesystemIterator($path);
117
118 38
        $success = true;
119
120 38
        foreach ($items as $item) {
121 34
            $item->isDir() && ! $item->isLink()
122 34
                ? $this->delete($item->getPathname())
123 22
                : FileHelper::delete($item->getPathname());
124
        }
125
126 38
        @rmdir($path);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for rmdir(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unhandled  annotation

126
        /** @scrutinizer ignore-unhandled */ @rmdir($path);

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
127
128 38
        return $success;
129
    }
130
131
    /**
132
     * Ensure the directory has been deleted.
133
     *
134
     * @throws \Helldar\Support\Exceptions\DirectoryNotFoundException
135
     */
136 2
    public function ensureDelete(string $path): bool
137
    {
138 2
        return $this->doesntExist($path) || $this->delete($path);
139
    }
140
141
    /**
142
     * Ensure created directory exists.
143
     *
144
     * @param  string  $path
145
     * @param  int  $mode
146
     * @param  bool  $can_delete
147
     *
148
     * @throws \Helldar\Support\Exceptions\DirectoryNotFoundException
149
     */
150 32
    public function ensureDirectory(string $path, int $mode = 0755, bool $can_delete = false): void
151
    {
152 32
        if ($can_delete && $this->exists($path)) {
153 2
            $this->delete($path);
154
        }
155
156 32
        if ($this->doesntExist($path)) {
157 32
            $this->make($path, $mode);
158
        }
159 32
    }
160
161
    /**
162
     * Check if the directory exists.
163
     *
164
     * @param  string  $path
165
     *
166
     * @return bool
167
     */
168 677
    public function exists(string $path): bool
169
    {
170 677
        return file_exists($path) && is_dir($path);
171
    }
172
173
    /**
174
     * Check if the directory doesn't exists.
175
     *
176
     * @param  string  $path
177
     *
178
     * @return bool
179
     */
180 58
    public function doesntExist(string $path): bool
181
    {
182 58
        return ! $this->exists($path);
183
    }
184
185
    /**
186
     * Check if object or path is a directory.
187
     *
188
     * @param  DirectoryIterator|\SplFileInfo|string  $value
189
     *
190
     * @return bool
191
     */
192 52
    public function isDirectory($value): bool
193
    {
194 52
        if (Instance::of($value, [SplFileInfo::class, DirectoryIterator::class])) {
195 2
            return $value->isDir();
196
        }
197
198 50
        return is_dir($value);
199
    }
200
201
    /**
202
     * Checks the existence of a directory.
203
     *
204
     * @param  DirectoryIterator|\SplFileInfo|string  $path
205
     *
206
     * @throws \Helldar\Support\Exceptions\DirectoryNotFoundException
207
     */
208 8
    public function validate($path): void
209
    {
210 8
        if (! $this->isDirectory($path)) {
211 4
            throw new DirectoryNotFoundException($path);
212
        }
213 4
    }
214
215
    /**
216
     * Checks the existence of a directory and return full path if exist.
217
     *
218
     * @param  DirectoryIterator|\SplFileInfo|string  $path
219
     *
220
     * @throws \Helldar\Support\Exceptions\DirectoryNotFoundException
221
     *
222
     * @return string
223
     */
224 4
    public function validated($path): string
225
    {
226 4
        $this->validate($path);
227
228 2
        return realpath($path);
229
    }
230
}
231