1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace ntentan\utils\filesystem; |
4
|
|
|
|
5
|
|
|
use ntentan\utils\exceptions\FileAlreadyExistsException; |
6
|
|
|
use ntentan\utils\exceptions\FileNotFoundException; |
7
|
|
|
use ntentan\utils\exceptions\FileNotReadableException; |
8
|
|
|
use ntentan\utils\exceptions\FileNotWriteableException; |
9
|
|
|
use ntentan\utils\Filesystem; |
10
|
|
|
use ntentan\utils\exceptions\FilesystemException; |
11
|
|
|
|
12
|
|
|
/** |
13
|
|
|
* Represents a directory from the filesystem. |
14
|
|
|
* |
15
|
|
|
* @package ntentan\utils\filesystem |
16
|
|
|
* |
17
|
|
|
*/ |
18
|
|
|
class Directory implements FileInterface |
19
|
|
|
{ |
20
|
|
|
const OVERWRITE_MERGE = 4; |
21
|
|
|
const OVERWRITE_SKIP = 8; |
22
|
|
|
|
23
|
|
|
/** |
24
|
|
|
* Full path to the directory. |
25
|
|
|
* |
26
|
|
|
* @var string |
27
|
|
|
*/ |
28
|
|
|
private $path; |
29
|
|
|
|
30
|
|
|
/** |
31
|
|
|
* Create a new instance with a path. |
32
|
|
|
* |
33
|
|
|
* @param string $path Optional path pointed to by new instance. Path does not have to exist. |
34
|
|
|
*/ |
35
|
6 |
|
public function __construct(string $path = null) |
36
|
|
|
{ |
37
|
6 |
|
$this->path = $path; |
38
|
6 |
|
} |
39
|
|
|
|
40
|
|
|
/** |
41
|
|
|
* Recursively copies directory and its contents to destination. |
42
|
|
|
* |
43
|
|
|
* @param string $destination |
44
|
|
|
* @param int $overwrite |
45
|
|
|
* @throws FileNotFoundException |
46
|
|
|
* @throws FileNotReadableException |
47
|
|
|
* @throws FilesystemException |
48
|
|
|
*/ |
49
|
1 |
View Code Duplication |
public function copyTo(string $destination, int $overwrite = self::OVERWRITE_MERGE): void |
|
|
|
|
50
|
|
|
{ |
51
|
1 |
|
if(file_exists($destination) && ($overwrite & self::OVERWRITE_SKIP)) { |
52
|
|
|
return; |
53
|
|
|
} |
54
|
1 |
|
Filesystem::directory($destination)->createIfNotExists(true); |
55
|
1 |
|
$this->getFiles()->copyTo($destination, $overwrite); |
56
|
1 |
|
} |
57
|
|
|
|
58
|
|
|
/** |
59
|
|
|
* Recursively get the size of all contents in the directory. |
60
|
|
|
* |
61
|
|
|
* @return integer |
62
|
|
|
* @throws FileNotFoundException |
63
|
|
|
* @throws FilesystemException |
64
|
|
|
* @throws FileNotReadableException |
65
|
|
|
*/ |
66
|
1 |
|
public function getSize() : int |
67
|
|
|
{ |
68
|
1 |
|
return $this->getFiles()->getSize(); |
69
|
|
|
} |
70
|
|
|
|
71
|
|
|
/** |
72
|
|
|
* Recursively move a directory and its contents to another location. |
73
|
|
|
* |
74
|
|
|
* @param string $destination |
75
|
|
|
* @param int $overwrite |
76
|
|
|
* @throws FileNotFoundException |
77
|
|
|
* @throws FileNotReadableException |
78
|
|
|
* @throws FilesystemException |
79
|
|
|
*/ |
80
|
1 |
View Code Duplication |
public function moveTo(string $destination, int $overwrite = self::OVERWRITE_MERGE) : void |
|
|
|
|
81
|
|
|
{ |
82
|
1 |
|
if(file_exists($destination) && ($overwrite & self::OVERWRITE_SKIP)) { |
83
|
|
|
return; |
84
|
|
|
} |
85
|
1 |
|
Filesystem::directory($destination)->createIfNotExists(true); |
86
|
1 |
|
$this->getFiles()->moveTo($destination, $overwrite); |
87
|
1 |
|
$this->delete(); |
88
|
1 |
|
$this->path = $destination; |
89
|
1 |
|
} |
90
|
|
|
|
91
|
|
|
/** |
92
|
|
|
* Create the directory pointed to by path. |
93
|
|
|
* |
94
|
|
|
* @param int $permissions |
95
|
|
|
* @return Directory |
96
|
|
|
* @throws FileAlreadyExistsException |
97
|
|
|
* @throws FileNotWriteableException |
98
|
|
|
*/ |
99
|
2 |
|
public function create($recursive=false, $permissions = 0755) |
100
|
|
|
{ |
101
|
2 |
|
Filesystem::checkNotExists($this->path); |
102
|
2 |
|
$parent = $this->path; |
103
|
2 |
|
if($recursive) { |
104
|
2 |
|
$segments = explode(DIRECTORY_SEPARATOR, $this->path); |
105
|
2 |
|
$parent = ""; |
106
|
2 |
|
foreach($segments as $segment) { |
107
|
2 |
|
$parent .= $segment . DIRECTORY_SEPARATOR; |
108
|
2 |
|
if(!is_dir($parent)) { |
109
|
2 |
|
break; |
110
|
|
|
} |
111
|
|
|
} |
112
|
|
|
} |
113
|
2 |
|
$parent = dirname($parent); |
114
|
2 |
|
Filesystem::checkWritable($parent == "" ? '.' : $parent); |
115
|
2 |
|
mkdir($this->path, $permissions, true); |
116
|
|
|
|
117
|
2 |
|
return $this; |
118
|
|
|
} |
119
|
|
|
|
120
|
2 |
|
public function createIfNotExists($recursive=false, $permissions = 0755) |
121
|
|
|
{ |
122
|
|
|
try { |
123
|
2 |
|
$this->create($recursive, $permissions); |
124
|
|
|
} catch (FileAlreadyExistsException $exception) { |
125
|
|
|
// Do nothing |
126
|
|
|
} |
127
|
2 |
|
return $this; |
128
|
|
|
} |
129
|
|
|
|
130
|
|
|
/** |
131
|
|
|
* Recursively delete the directory and all its contents. |
132
|
|
|
* |
133
|
|
|
* @throws FileNotFoundException |
134
|
|
|
* @throws FilesystemException |
135
|
|
|
* @throws FileNotReadableException |
136
|
|
|
*/ |
137
|
2 |
|
public function delete() : void |
138
|
|
|
{ |
139
|
2 |
|
$this->getFiles()->delete(); |
140
|
2 |
|
rmdir($this->path); |
141
|
2 |
|
} |
142
|
|
|
|
143
|
|
|
/** |
144
|
|
|
* Get the path of the directory. |
145
|
|
|
* |
146
|
|
|
* @return string |
147
|
|
|
*/ |
148
|
1 |
|
public function getPath() : string |
149
|
|
|
{ |
150
|
1 |
|
return $this->path; |
151
|
|
|
} |
152
|
|
|
|
153
|
|
|
/** |
154
|
|
|
* Get the files in the directory. |
155
|
|
|
* |
156
|
|
|
* @throws FilesystemException |
157
|
|
|
* @throws FileNotFoundException |
158
|
|
|
* @throws FileNotReadableException |
159
|
|
|
* @return FileCollection | array<string> |
160
|
|
|
*/ |
161
|
5 |
|
public function getFiles($recursive=false, $returnStrings=false) |
162
|
|
|
{ |
163
|
5 |
|
Filesystem::checkExists($this->path); |
164
|
5 |
|
Filesystem::checkReadable($this->path); |
165
|
5 |
|
$paths = []; |
166
|
|
|
|
167
|
5 |
|
$files = scandir($this->path); |
168
|
5 |
|
foreach ($files as $file) { |
169
|
5 |
|
if($file == '.' || $file == '..') continue; |
170
|
5 |
|
$path = "$this->path/$file"; |
171
|
5 |
|
if(is_dir($path) && $recursive) { |
172
|
|
|
$paths = array_merge($paths, Filesystem::directory($path)->getFiles(true, true)); |
173
|
|
|
} |
174
|
5 |
|
$paths[] = $path; |
175
|
|
|
} |
176
|
5 |
|
return $returnStrings ? $paths : new FileCollection($paths); |
177
|
|
|
} |
178
|
|
|
|
179
|
3 |
|
public function __toString() |
180
|
|
|
{ |
181
|
3 |
|
return $this->path; |
182
|
|
|
} |
183
|
|
|
} |
184
|
|
|
|
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.