Passed
Push — main ( 8aefd5...83f2f3 )
by Andrey
23:12 queued 21:38
created

Directory::ensureDelete()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 1
nc 2
nop 1
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 2
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Helldar\Support\Helpers\Filesystem;
4
5
use DirectoryIterator;
6
use FilesystemIterator;
7
use Helldar\Support\Exceptions\DirectoryNotFoundException;
8
use Helldar\Support\Facades\Helpers\Filesystem\File as FileHelper;
9
use Helldar\Support\Facades\Helpers\Instance;
10
use Helldar\Support\Facades\Helpers\Str;
11
use SplFileInfo;
12
13
class Directory
14
{
15
    /**
16
     * Get a list of files and folders in a directory.
17
     *
18
     * @param  string  $path
19
     *
20
     * @throws \Helldar\Support\Exceptions\DirectoryNotFoundException
21
     *
22
     * @return DirectoryIterator
23
     */
24 18
    public function all(string $path): DirectoryIterator
25
    {
26 18
        if ($this->doesntExist($path)) {
27 4
            throw new DirectoryNotFoundException($path);
28
        }
29
30 14
        return new DirectoryIterator($path);
31
    }
32
33
    /**
34
     * Get a list of directory names along a path.
35
     *
36
     * @param  string  $path
37
     * @param  callable|null  $callback
38
     * @param  bool  $recursive
39
     *
40
     * @throws \Helldar\Support\Exceptions\DirectoryNotFoundException
41
     *
42
     * @return array
43
     */
44 6
    public function names(string $path, callable $callback = null, bool $recursive = false): array
45
    {
46 6
        $items = [];
47
48
        /** @var \DirectoryIterator $directory */
49 6
        foreach ($this->all($path) as $directory) {
50 6
            if ($directory->isDir() && ! $directory->isDot()) {
51 6
                $name = $directory->getFilename();
52
53 6
                if (! is_callable($callback) || $callback($name)) {
54 6
                    $items[] = $name;
55
                }
56
            }
57
58 6
            if ($recursive && $directory->isDir() && ! $directory->isDot()) {
59 2
                $prefix = (string) Str::of($directory->getRealPath())
60 2
                    ->after(realpath($path))
61 2
                    ->trim('\\/');
62
63 2
                foreach ($this->names($directory->getRealPath(), $callback, $recursive) as $value) {
64 2
                    $items[] = $prefix . '/' . $value;
65
                }
66
            }
67
        }
68
69 6
        sort($items);
70
71 6
        return array_values($items);
72
    }
73
74
    /**
75
     * Create a directory at the specified path.
76
     *
77
     * @param  string  $path
78
     * @param  int  $mode
79
     *
80
     * @return bool
81
     */
82 40
    public function make(string $path, int $mode = 0755): bool
83
    {
84 40
        return ! $this->doesntExist($path) || mkdir($path, $mode, true);
85
    }
86
87
    /**
88
     * Delete the directory with all contents in the specified path.
89
     *
90
     * @param  string  $path
91
     *
92
     * @throws \Helldar\Support\Exceptions\DirectoryNotFoundException
93
     *
94
     * @return bool
95
     */
96 42
    public function delete(string $path): bool
97
    {
98 42
        if (! $this->isDirectory($path)) {
99 4
            throw new DirectoryNotFoundException($path);
100
        }
101
102 40
        $items = new FilesystemIterator($path);
103
104 40
        $success = true;
105
106 40
        foreach ($items as $item) {
107 36
            $item->isDir() && ! $item->isLink()
108 36
                ? $this->delete($item->getPathname())
109 24
                : FileHelper::delete($item->getPathname());
110
        }
111
112 40
        @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

112
        /** @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...
113
114 40
        return $success;
115
    }
116
117
    /**
118
     * Ensure the directory has been deleted.
119
     *
120
     * @throws \Helldar\Support\Exceptions\DirectoryNotFoundException
121
     */
122 2
    public function ensureDelete(string $path): bool
123
    {
124 2
        return $this->doesntExist($path) || $this->delete($path);
125
    }
126
127
    /**
128
     * Ensure created directory exists.
129
     *
130
     * @param  string  $path
131
     * @param  int  $mode
132
     * @param  bool  $can_delete
133
     *
134
     * @throws \Helldar\Support\Exceptions\DirectoryNotFoundException
135
     */
136 2
    public function ensureDirectory(string $path, int $mode = 0755, bool $can_delete = false): void
137
    {
138 2
        if ($can_delete && $this->exists($path)) {
139 2
            $this->delete($path);
140
        }
141
142 2
        if ($this->doesntExist($path)) {
143 2
            $this->make($path, $mode);
144
        }
145 2
    }
146
147
    /**
148
     * Check if the directory exists.
149
     *
150
     * @param  string  $path
151
     *
152
     * @return bool
153
     */
154 617
    public function exists(string $path): bool
155
    {
156 617
        return file_exists($path) && is_dir($path);
157
    }
158
159
    /**
160
     * Check if the directory doesn't exists.
161
     *
162
     * @param  string  $path
163
     *
164
     * @return bool
165
     */
166 60
    public function doesntExist(string $path): bool
167
    {
168 60
        return ! $this->exists($path);
169
    }
170
171
    /**
172
     * Check if object or path is a directory.
173
     *
174
     * @param  DirectoryIterator|\SplFileInfo|string  $value
175
     *
176
     * @return bool
177
     */
178 54
    public function isDirectory($value): bool
179
    {
180 54
        if (Instance::of($value, [SplFileInfo::class, DirectoryIterator::class])) {
181 2
            return $value->isDir();
182
        }
183
184 52
        return is_dir($value);
185
    }
186
187
    /**
188
     * Checks the existence of a directory.
189
     *
190
     * @param  DirectoryIterator|\SplFileInfo|string  $path
191
     *
192
     * @throws \Helldar\Support\Exceptions\DirectoryNotFoundException
193
     */
194 8
    public function validate($path): void
195
    {
196 8
        if (! $this->isDirectory($path)) {
197 4
            throw new DirectoryNotFoundException($path);
198
        }
199 4
    }
200
201
    /**
202
     * Checks the existence of a directory and return full path if exist.
203
     *
204
     * @param  DirectoryIterator|\SplFileInfo|string  $path
205
     *
206
     * @throws \Helldar\Support\Exceptions\DirectoryNotFoundException
207
     *
208
     * @return string
209
     */
210 4
    public function validated($path): string
211
    {
212 4
        $this->validate($path);
213
214 2
        return realpath($path);
215
    }
216
}
217