DirectoryHelper::rmdirs()   A
last analyzed

Complexity

Conditions 4
Paths 4

Size

Total Lines 11
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 4
eloc 7
c 1
b 0
f 0
nc 4
nop 2
dl 0
loc 11
rs 10
1
<?php
2
namespace suda\framework\filesystem;
3
4
use Iterator;
5
use RecursiveDirectoryIterator;
6
use RecursiveIteratorIterator;
7
use RecursiveRegexIterator;
8
use suda\framework\loader\Path;
9
use suda\framework\loader\PathTrait;
10
11
/**
12
 * 文件夹辅助
13
 */
14
trait DirectoryHelper
15
{
16
    /**
17
     * 创建目录
18
     *
19
     * @param string $path
20
     * @param int $mode
21
     * @param bool $recursive
22
     * @return boolean
23
     */
24
    public static function make(string $path, int $mode = 0777, bool $recursive = true):bool
25
    {
26
        if (!file_exists($path)) {
27
            $mk = mkdir($path, $mode, $recursive);
28
            if ($mk) {
29
                chmod($path, $mode);
30
            }
31
            return $mk;
32
        }
33
        return true;
34
    }
35
36
    /**
37
     * 删除空目录
38
     *
39
     * @param string $path
40
     * @return boolean
41
     */
42
    public static function rm(string $path):bool
43
    {
44
        if (!is_writable($path)) {
45
            return false;
46
        }
47
        return rmdir($path);
48
    }
49
50
    /**
51
     * 删除非空目录
52
     *
53
     * @param string $path
54
     * @param string|null $regex
55
     * @return bool
56
     */
57
    public static function rmdirs(string $path, ?string $regex = null):bool
58
    {
59
        foreach (static::read($path, false, $regex, true) as $subpath) {
60
            if (is_dir($subpath)) {
61
                static::rmdirs($subpath, $regex);
62
            } elseif (is_file($subpath)) {
63
                FileHelper::delete($subpath);
64
            }
65
        }
66
        static::rm($path);
67
        return true;
68
    }
69
70
71
    /**
72
     * 读目录下文件
73
     *
74
     * @param string $path
75
     * @param boolean $recursive
76
     * @param string|null $regex
77
     * @param boolean $full
78
     * @param int $mode
79
     * @return Iterator
80
     */
81
    public static function readFiles(string $path, bool $recursive = false, ?string $regex = null, bool $full = true, int $mode = RecursiveIteratorIterator::LEAVES_ONLY) : Iterator
82
    {
83
        $parent = Path::format($path);
84
        foreach (static::read($path, $recursive, $regex, false, $mode) as $subpath) {
85
            $path = $parent.DIRECTORY_SEPARATOR.$subpath;
86
            if (is_file($path)) {
87
                if ($full) {
88
                    yield $path;
89
                } else {
90
                    yield $subpath;
91
                }
92
            }
93
        }
94
    }
95
96
    /**
97
     * 读目录下文件夹
98
     *
99
     * @param string $path
100
     * @param boolean $recursive
101
     * @param string|null $regex
102
     * @param boolean $full
103
     * @param int $mode
104
     * @return Iterator
105
     */
106
    public static function readDirs(string $path, bool $recursive = false, ?string $regex = null, bool $full = false, int $mode = RecursiveIteratorIterator::LEAVES_ONLY): Iterator
107
    {
108
        $parent = Path::format($path);
109
        foreach (static::read($path, $recursive, $regex, false, $mode) as $subpath) {
110
            $path = $parent.DIRECTORY_SEPARATOR.$subpath;
111
            if (is_file($path)) {
112
                if ($full) {
113
                    yield $path;
114
                } else {
115
                    yield $subpath;
116
                }
117
            }
118
        }
119
    }
120
121
    /**
122
     * 读目录,包括文件,文件夹
123
     *
124
     * @param string $path
125
     * @param boolean $recursive
126
     * @param string|null $regex
127
     * @param boolean $full
128
     * @param int $mode
129
     * @return Iterator
130
     */
131
    public static function read(string $path, bool $recursive = false, ?string $regex = null, bool $full = true, int $mode = RecursiveIteratorIterator::LEAVES_ONLY): Iterator
132
    {
133
        $directory = Path::format($path);
134
        if ($directory && is_dir($directory)) {
135
            $it = static::buildIterator($directory, $recursive, $regex, $mode);
136
            foreach ($it as $key => $item) {
137
                if ($full) {
138
                    yield $key;
139
                } else {
140
                    yield static::cut($key, $directory);
141
                }
142
            }
143
        }
144
    }
145
146
    protected static function buildIterator(string $directory, bool $recursive, ?string $regex, int $mode): Iterator
147
    {
148
        $it = new RecursiveDirectoryIterator($directory, RecursiveDirectoryIterator::SKIP_DOTS);
149
        if ($regex !== null) {
150
            $it = new RecursiveRegexIterator($it, $regex);
151
        }
152
        if ($recursive) {
153
            $it = new RecursiveIteratorIterator($it, $mode);
154
        }
155
        return $it;
156
    }
157
158
    /**
159
     * 截断部分目录
160
     *
161
     * @param string $path
162
     * @param string $basepath
163
     * @return string
164
     */
165
    public static function cut(string $path, string $basepath):string
166
    {
167
        $path = PathTrait::toAbsolutePath($path);
168
        $basepath = PathTrait::toAbsolutePath($basepath);
169
        if (strpos($path, $basepath.DIRECTORY_SEPARATOR) === 0) {
170
            return substr($path, strlen($basepath) + 1);
171
        }
172
        return $path;
173
    }
174
175
    /**
176
     * 复制文件
177
     *
178
     * @param string $path
179
     * @param string $toPath
180
     * @param string|null $regex
181
     * @param boolean $move
182
     * @return boolean
183
     */
184
    public static function copy(string $path, string $toPath, ?string $regex = null, bool $move = false):bool
185
    {
186
        $directory = Path::format($path);
187
        static::make($toPath);
188
        if ($directory && is_writable($toPath)) {
189
            foreach (static::read($directory, true, $regex, false, RecursiveIteratorIterator::CHILD_FIRST) as $subpath) {
190
                $srcpath = $directory.DIRECTORY_SEPARATOR.$subpath;
191
                $destpath = $toPath.DIRECTORY_SEPARATOR.$subpath;
192
                static::processPath($srcpath, $destpath, $move);
193
            }
194
            return true;
195
        }
196
        return false;
197
    }
198
199
    protected static function processPath(string $srcpath, string $destpath, bool $move)
200
    {
201
        if (is_dir($srcpath)) {
202
            static::make($destpath);
203
            if ($move) {
204
                static::rm($srcpath);
205
            }
206
        } else {
207
            static::make(dirname($destpath));
208
            FileHelper::copy($srcpath, $destpath);
209
            if ($move) {
210
                FileHelper::delete($srcpath);
211
            }
212
        }
213
    }
214
215
    /**
216
     * 移动文件
217
     *
218
     * @param string $path
219
     * @param string $toPath
220
     * @param string|null $regex
221
     * @return boolean
222
     */
223
    public static function move(string $path, string $toPath, ?string $regex = null):bool
224
    {
225
        return static::copy($path, $toPath, $regex, true);
226
    }
227
}
228