1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/** |
4
|
|
|
* This file is part of the miBadger package. |
5
|
|
|
* |
6
|
|
|
* @author Michael Webbers <[email protected]> |
7
|
|
|
* @license http://opensource.org/licenses/Apache-2.0 Apache v2 License |
8
|
|
|
* @version 1.0.0 |
9
|
|
|
*/ |
10
|
|
|
|
11
|
|
|
namespace miBadger\File; |
12
|
|
|
|
13
|
|
|
/** |
14
|
|
|
* The file class. |
15
|
|
|
* |
16
|
|
|
* @since 1.0.0 |
17
|
|
|
*/ |
18
|
|
|
class File implements \Countable |
19
|
|
|
{ |
20
|
|
|
const DIRECTORY_SEPARATOR = \DIRECTORY_SEPARATOR; |
21
|
|
|
|
22
|
|
|
/** @var string the file path. */ |
23
|
|
|
private $path; |
24
|
|
|
|
25
|
|
|
/** |
26
|
|
|
* Constructs a File object with the given path. |
27
|
|
|
* |
28
|
|
|
* @param string $path |
29
|
|
|
*/ |
30
|
32 |
|
public function __construct($path) |
31
|
|
|
{ |
32
|
32 |
|
if (substr($path, -1) === static::DIRECTORY_SEPARATOR) { |
33
|
1 |
|
$this->path = substr($path, 0, -1); |
34
|
1 |
|
} else { |
35
|
32 |
|
$this->path = $path; |
36
|
|
|
} |
37
|
32 |
|
} |
38
|
|
|
|
39
|
|
|
/** |
40
|
|
|
* Returns the string representation of the File object. |
41
|
|
|
* |
42
|
|
|
* @return string the string representation of the File object. |
43
|
|
|
*/ |
44
|
2 |
|
public function __toString() |
45
|
|
|
{ |
46
|
2 |
|
return $this->getPath(); |
47
|
|
|
} |
48
|
|
|
|
49
|
|
|
/** |
50
|
|
|
* Returns the path of the file. |
51
|
|
|
* |
52
|
|
|
* @return string the path of the file. |
53
|
|
|
*/ |
54
|
5 |
|
public function getPath() |
55
|
|
|
{ |
56
|
5 |
|
return $this->path; |
57
|
|
|
} |
58
|
|
|
|
59
|
|
|
/** |
60
|
|
|
* Returns the parent directory of the file. |
61
|
|
|
* |
62
|
|
|
* @return string the parent directory of the file. |
63
|
|
|
*/ |
64
|
2 |
|
public function getDirectory() |
65
|
|
|
{ |
66
|
2 |
|
return dirname($this->path); |
67
|
|
|
} |
68
|
|
|
|
69
|
|
|
/** |
70
|
|
|
* Returns the name of the file. |
71
|
|
|
* |
72
|
|
|
* @return string the name of the file. |
73
|
|
|
*/ |
74
|
1 |
|
public function getName() |
75
|
|
|
{ |
76
|
1 |
|
return basename($this->path); |
77
|
|
|
} |
78
|
|
|
|
79
|
|
|
/** |
80
|
|
|
* Returns true if the file exists. |
81
|
|
|
* |
82
|
|
|
* @return bool true if the file exists. |
83
|
|
|
*/ |
84
|
7 |
|
public function exists() |
85
|
|
|
{ |
86
|
7 |
|
return file_exists($this->path); |
87
|
|
|
} |
88
|
|
|
|
89
|
|
|
/** |
90
|
|
|
* Returns true if you can execute the file. |
91
|
|
|
* |
92
|
|
|
* @return bool true if you can execute the file. |
93
|
|
|
*/ |
94
|
1 |
|
public function canExecute() |
95
|
|
|
{ |
96
|
1 |
|
return is_executable($this->path); |
97
|
|
|
} |
98
|
|
|
|
99
|
|
|
/** |
100
|
|
|
* Returns true if you can read the file. |
101
|
|
|
* |
102
|
|
|
* @return bool true if you can read the file. |
103
|
|
|
*/ |
104
|
1 |
|
public function canRead() |
105
|
|
|
{ |
106
|
1 |
|
return is_readable($this->path); |
107
|
|
|
} |
108
|
|
|
|
109
|
|
|
/** |
110
|
|
|
* Returns true if you can write the file. |
111
|
|
|
* |
112
|
|
|
* @return bool true if you can write the file. |
113
|
|
|
*/ |
114
|
1 |
|
public function canWrite() |
115
|
|
|
{ |
116
|
1 |
|
return is_writeable($this->path); |
117
|
|
|
} |
118
|
|
|
|
119
|
|
|
/** |
120
|
|
|
* Returns true if the file is a file. |
121
|
|
|
* |
122
|
|
|
* @return bool true if the file is a file. |
123
|
|
|
*/ |
124
|
2 |
|
public function isFile() |
125
|
|
|
{ |
126
|
2 |
|
return is_file($this->path); |
127
|
|
|
} |
128
|
|
|
|
129
|
|
|
/** |
130
|
|
|
* Returns true if the file is a directory. |
131
|
|
|
* |
132
|
|
|
* @return bool true if the file is a directory. |
133
|
|
|
*/ |
134
|
5 |
|
public function isDirectory() |
135
|
|
|
{ |
136
|
5 |
|
return is_dir($this->path); |
137
|
|
|
} |
138
|
|
|
|
139
|
|
|
/** |
140
|
|
|
* Returns the numer of bytes in the file, or -1 on failure. |
141
|
|
|
* |
142
|
|
|
* @return int the number of bytes in the file, or -1 on failure. |
143
|
|
|
*/ |
144
|
1 |
View Code Duplication |
public function count() |
|
|
|
|
145
|
|
|
{ |
146
|
1 |
|
if (!$this->exists()) { |
147
|
1 |
|
return -1; |
148
|
|
|
} |
149
|
|
|
|
150
|
1 |
|
return ($result = filesize($this->path)) !== false ? $result : -1; |
151
|
|
|
} |
152
|
|
|
|
153
|
|
|
/** |
154
|
|
|
* Returns the time of the last modification as a unixtimestap, or -1 on failure. |
155
|
|
|
* |
156
|
|
|
* @return int the time of the last modification as a unixtimestap, or -1 on failure. |
157
|
|
|
*/ |
158
|
1 |
View Code Duplication |
public function lastModified() |
|
|
|
|
159
|
|
|
{ |
160
|
1 |
|
if (!$this->exists()) { |
161
|
1 |
|
return -1; |
162
|
|
|
} |
163
|
|
|
|
164
|
1 |
|
return ($result = filemtime($this->path)) !== false ? $result : -1; |
165
|
|
|
} |
166
|
|
|
|
167
|
|
|
/** |
168
|
|
|
* Returns an iterator with the files and directories in the current directory. |
169
|
|
|
* |
170
|
|
|
* @param bool $recursive = false |
171
|
|
|
* @param bool $showHidden = false |
172
|
|
|
* @return \ArrayIterator|\FilesystemIterator|\RecursiveIteratorIterator an iterator with the files and directories in the current directory. |
173
|
|
|
*/ |
174
|
4 |
|
private function listAllIterator($recursive = false, $showHidden = false) |
175
|
|
|
{ |
176
|
4 |
|
if (!$this->isDirectory()) { |
177
|
4 |
|
return new \ArrayIterator([]); |
178
|
|
|
} |
179
|
|
|
|
180
|
4 |
|
$flags = \FilesystemIterator::KEY_AS_PATHNAME | \FilesystemIterator::CURRENT_AS_FILEINFO; |
181
|
|
|
|
182
|
4 |
|
if (!$showHidden) { |
183
|
4 |
|
$flags = $flags | \FilesystemIterator::SKIP_DOTS; |
184
|
4 |
|
} |
185
|
|
|
|
186
|
4 |
|
if ($recursive) { |
187
|
1 |
|
return new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($this->path, $flags), \RecursiveIteratorIterator::SELF_FIRST); |
188
|
|
|
} |
189
|
|
|
|
190
|
3 |
|
return new \FilesystemIterator($this->path, $flags); |
191
|
|
|
} |
192
|
|
|
|
193
|
|
|
/** |
194
|
|
|
* Returns an array with the files and directories in the current directory. |
195
|
|
|
* |
196
|
|
|
* @param bool $recursive = false |
197
|
|
|
* @param bool $showHidden = false |
198
|
|
|
* @return string[] an array with the files and directories in the current directory. |
199
|
|
|
*/ |
200
|
2 |
View Code Duplication |
public function listAll($recursive = false, $showHidden = false) |
|
|
|
|
201
|
|
|
{ |
202
|
2 |
|
$result = []; |
203
|
|
|
|
204
|
2 |
|
foreach ($this->listAllIterator($recursive, $showHidden) as $element) { |
205
|
2 |
|
$result[] = $element->getFilename(); |
206
|
2 |
|
} |
207
|
|
|
|
208
|
2 |
|
return $result; |
209
|
|
|
} |
210
|
|
|
|
211
|
|
|
/** |
212
|
|
|
* Returns an array with the directories in the current directory. |
213
|
|
|
* |
214
|
|
|
* @param bool $recursive = false |
215
|
|
|
* @param bool $showHidden = false |
216
|
|
|
* @return string[] an array with the directories in the current directory. |
217
|
|
|
*/ |
218
|
1 |
View Code Duplication |
public function listDirectories($recursive = false, $showHidden = false) |
|
|
|
|
219
|
|
|
{ |
220
|
1 |
|
$result = []; |
221
|
|
|
|
222
|
1 |
|
foreach ($this->listAllIterator($recursive, $showHidden) as $element) { |
223
|
1 |
|
if ($element->isDir()) { |
224
|
1 |
|
$result[] = $element->getFilename(); |
225
|
1 |
|
} |
226
|
1 |
|
} |
227
|
|
|
|
228
|
1 |
|
return $result; |
229
|
|
|
} |
230
|
|
|
|
231
|
|
|
/** |
232
|
|
|
* Returns an array with the files in the current directory. |
233
|
|
|
* |
234
|
|
|
* @param bool $recursive = false |
235
|
|
|
* @param bool $showHidden = false |
236
|
|
|
* @return string[] an array with the files in the current directory. |
237
|
|
|
*/ |
238
|
1 |
View Code Duplication |
public function listFiles($recursive = false, $showHidden = false) |
|
|
|
|
239
|
|
|
{ |
240
|
1 |
|
$result = []; |
241
|
|
|
|
242
|
1 |
|
foreach ($this->listAllIterator($recursive, $showHidden) as $element) { |
243
|
1 |
|
if ($element->isFile()) { |
244
|
1 |
|
$result[] = $element->getFilename(); |
245
|
1 |
|
} |
246
|
1 |
|
} |
247
|
|
|
|
248
|
1 |
|
return $result; |
249
|
|
|
} |
250
|
|
|
|
251
|
|
|
/** |
252
|
|
|
* Returns true if the file has been created. |
253
|
|
|
* |
254
|
|
|
* @param bool $override = false |
255
|
|
|
* @return bool true if the file has been created. |
256
|
|
|
*/ |
257
|
1 |
|
public function makeFile($override = false) |
258
|
|
|
{ |
259
|
1 |
|
if ($this->exists() && !$override) { |
260
|
1 |
|
return false; |
261
|
|
|
} |
262
|
|
|
|
263
|
1 |
|
return file_put_contents($this->path, '') !== false; |
264
|
|
|
} |
265
|
|
|
|
266
|
|
|
/** |
267
|
|
|
* Returns true if the directory has been created. |
268
|
|
|
* |
269
|
|
|
* @param bool $recursive = false |
270
|
|
|
* @param int $permissions = 0755 |
271
|
|
|
* @return bool true if the directory has been created. |
272
|
|
|
*/ |
273
|
1 |
|
public function makeDirectory($recursive = false, $permissions = 0775) |
274
|
|
|
{ |
275
|
1 |
|
if ($this->exists()) { |
276
|
1 |
|
return false; |
277
|
|
|
} |
278
|
|
|
|
279
|
1 |
|
$old = umask(0777 - $permissions); |
280
|
1 |
|
$result = mkdir($this->path, $permissions, $recursive); |
281
|
1 |
|
umask($old); |
282
|
|
|
|
283
|
1 |
|
return $result; |
284
|
|
|
} |
285
|
|
|
|
286
|
|
|
/** |
287
|
|
|
* Returns true if the file is succesfully moved. |
288
|
|
|
* |
289
|
|
|
* @param string $path |
290
|
|
|
* @param bool $override = false |
291
|
|
|
* @return bool true if the file is succesfully moved. |
292
|
|
|
*/ |
293
|
2 |
|
public function move($path, $override = false) |
294
|
|
|
{ |
295
|
2 |
|
if (!$this->exists()) { |
296
|
2 |
|
return false; |
297
|
|
|
} |
298
|
|
|
|
299
|
2 |
|
$file = new File($path); |
300
|
|
|
|
301
|
2 |
|
if (($file->exists() && !$override) || !rename($this->path, $file->getPath())) { |
302
|
1 |
|
return false; |
303
|
|
|
} |
304
|
|
|
|
305
|
2 |
|
$this->path = $file->getPath(); |
306
|
|
|
|
307
|
2 |
|
return true; |
308
|
|
|
} |
309
|
|
|
|
310
|
|
|
/** |
311
|
|
|
* Returns true if the file is succesfully renamed. |
312
|
|
|
* |
313
|
|
|
* @param string $file |
314
|
|
|
* @param bool $override = false |
315
|
|
|
* @return bool true if the file is succesfully renamed. |
316
|
|
|
*/ |
317
|
1 |
|
public function rename($file, $override = false) |
318
|
|
|
{ |
319
|
1 |
|
return $this->move($this->getDirectory() . static::DIRECTORY_SEPARATOR . basename($file), $override); |
320
|
|
|
} |
321
|
|
|
|
322
|
|
|
/** |
323
|
|
|
* Returns true if the directory is succesfully removed. |
324
|
|
|
* |
325
|
|
|
* @param bool $recursive = false |
326
|
|
|
* @return bool true if the directory is succesfully removed. |
327
|
|
|
*/ |
328
|
1 |
|
public function removeDirectory($recursive = false) |
329
|
|
|
{ |
330
|
1 |
|
if (!$recursive) { |
331
|
1 |
|
return rmdir($this->path); |
332
|
|
|
} |
333
|
|
|
|
334
|
1 |
|
foreach (new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($this->path, \FilesystemIterator::SKIP_DOTS), \RecursiveIteratorIterator::CHILD_FIRST) as $path) { |
335
|
1 |
|
$path->isFile() ? unlink($path->getPathname()) : rmdir($path->getPathname()); |
336
|
1 |
|
} |
337
|
|
|
|
338
|
1 |
|
return true; |
339
|
|
|
} |
340
|
|
|
|
341
|
|
|
/** |
342
|
|
|
* Returns true if the file is succesfully removed. |
343
|
|
|
* |
344
|
|
|
* @return bool true if the file is succesfully removed. |
345
|
|
|
*/ |
346
|
1 |
|
public function removeFile() |
347
|
|
|
{ |
348
|
1 |
|
if (!$this->isFile()) { |
349
|
1 |
|
return false; |
350
|
|
|
} |
351
|
|
|
|
352
|
1 |
|
return unlink($this->path); |
353
|
|
|
} |
354
|
|
|
|
355
|
|
|
/** |
356
|
|
|
* Returns the content of the file. |
357
|
|
|
* |
358
|
|
|
* @return string the content of the file. |
359
|
|
|
* @throws FileException on failure. |
360
|
|
|
*/ |
361
|
7 |
|
public function read() |
362
|
|
|
{ |
363
|
7 |
|
$result = file_get_contents($this->path); |
364
|
|
|
|
365
|
7 |
|
if ($result === false) { |
366
|
2 |
|
throw new FileException('Can\'t read the content.'); |
367
|
|
|
} |
368
|
|
|
|
369
|
5 |
|
return $result; |
370
|
|
|
} |
371
|
|
|
|
372
|
|
|
/** |
373
|
|
|
* Append the given content. |
374
|
|
|
* |
375
|
|
|
* @param string $content |
376
|
|
|
* @return null |
377
|
|
|
* @throws FileException on failure. |
378
|
|
|
*/ |
379
|
3 |
|
public function append($content) |
380
|
|
|
{ |
381
|
3 |
|
if (file_put_contents($this->path, $content, \FILE_APPEND) === false) { |
382
|
1 |
|
throw new FileException('Can\'t append the given content.'); |
383
|
|
|
} |
384
|
2 |
|
} |
385
|
|
|
|
386
|
|
|
/** |
387
|
|
|
* Write the given content. |
388
|
|
|
* |
389
|
|
|
* @param string $content |
390
|
|
|
* @return null |
391
|
|
|
* @throws FileException on failure. |
392
|
|
|
*/ |
393
|
3 |
|
public function write($content) |
394
|
|
|
{ |
395
|
3 |
|
if (file_put_contents($this->path, $content) === false) { |
396
|
1 |
|
throw new FileException('Can\'t write the given content.'); |
397
|
|
|
} |
398
|
2 |
|
} |
399
|
|
|
} |
400
|
|
|
|
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.