1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Padosoft\Io; |
4
|
|
|
|
5
|
|
|
/** |
6
|
|
|
* Helper Class DirHelper |
7
|
|
|
* @package Padosoft\Io |
8
|
|
|
*/ |
9
|
|
|
class DirHelper |
10
|
|
|
{ |
11
|
|
|
/** |
12
|
|
|
* Check if passed path exists or not. |
13
|
|
|
* @param string $filePath |
14
|
|
|
* @return bool |
15
|
|
|
*/ |
16
|
|
|
public static function isDirSafe(string $filePath) : bool |
17
|
|
|
{ |
18
|
|
|
if (!$filePath) { |
19
|
|
|
return false; |
20
|
|
|
} |
21
|
|
|
|
22
|
|
|
return is_dir($filePath); |
23
|
|
|
} |
24
|
|
|
|
25
|
|
|
/** |
26
|
|
|
* Check if passed path exists or try to create it. |
27
|
|
|
* Return false if it fails to create it or if a file (and not a dir) passed as argument. |
28
|
|
|
* @param string $filePath |
29
|
|
|
* @param string $modeMask default '0755' |
30
|
|
|
* @return bool |
31
|
|
|
*/ |
32
|
|
|
public static function checkDirExistOrCreate(string $filePath, string $modeMask = '0755') : bool |
33
|
|
|
{ |
34
|
|
|
if (self::isDirSafe($filePath)) { |
35
|
|
|
return true; |
36
|
|
|
} |
37
|
|
|
|
38
|
|
|
//controllo adesso che non sia un file |
39
|
|
|
if (FileHelper::fileExistsSafe($filePath)) { |
40
|
|
|
return false; |
41
|
|
|
} |
42
|
|
|
|
43
|
|
|
return mkdir($filePath, $modeMask, true) && self::isDirSafe($filePath); |
44
|
|
|
} |
45
|
|
|
|
46
|
|
|
/** |
47
|
|
|
* If dir passed, check if finishes with '/' otherwise append a slash to path. |
48
|
|
|
* If wrong or empty string passed, return '/'. |
49
|
|
|
* @param string $path |
50
|
|
|
* @return string |
51
|
|
|
*/ |
52
|
|
|
public static function addFinalSlash(string $path) : string |
53
|
|
|
{ |
54
|
|
|
if ($path === null || $path == '') { |
55
|
|
|
return '/'; |
56
|
|
|
} |
57
|
|
|
|
58
|
|
|
$quoted = preg_quote('/', '/'); |
59
|
|
|
$path = preg_replace('/(?:' . $quoted . ')+$/', '', $path) . '/'; |
60
|
|
|
|
61
|
|
|
return $path; |
62
|
|
|
} |
63
|
|
|
|
64
|
|
|
/** |
65
|
|
|
* for each dir passed in array, check if it finishes with '/' otherwise append a slash to path. |
66
|
|
|
* If not dir, leave the element untouched. |
67
|
|
|
* @param array $paths |
68
|
|
|
* @return array |
69
|
|
|
*/ |
70
|
|
|
public static function addFinalSlashToAllPaths(array $paths) : array |
71
|
|
|
{ |
72
|
|
|
if (empty($paths)) { |
73
|
|
|
return []; |
74
|
|
|
} |
75
|
|
|
|
76
|
|
|
return array_map('self::addFinalSlash', $paths); |
77
|
|
|
} |
78
|
|
|
|
79
|
|
|
/** |
80
|
|
|
* Check if path ends with slash '/' |
81
|
|
|
* @param string $paths |
82
|
|
|
* @return bool |
83
|
|
|
*/ |
84
|
|
|
public static function endsWithSlash(string $paths) : bool |
85
|
|
|
{ |
86
|
|
|
return self::endsWith($paths, '/'); |
87
|
|
|
} |
88
|
|
|
|
89
|
|
|
/** |
90
|
|
|
* Check if path ends with star '*' |
91
|
|
|
* @param string $paths |
92
|
|
|
* @return bool |
93
|
|
|
*/ |
94
|
|
|
public static function endsWithStar(string $paths) : bool |
95
|
|
|
{ |
96
|
|
|
return self::endsWith($paths, '*'); |
97
|
|
|
} |
98
|
|
|
|
99
|
|
|
/** |
100
|
|
|
* Check if path ends with $needle |
101
|
|
|
* @param string $paths |
102
|
|
|
* @param string $needle |
103
|
|
|
* @return bool |
104
|
|
|
*/ |
105
|
|
|
public static function endsWith(string $paths, string $needle) : bool |
106
|
|
|
{ |
107
|
|
|
if ($paths === null || $paths == '') { |
108
|
|
|
return false; |
109
|
|
|
} |
110
|
|
|
if ($needle === null || $needle == '') { |
111
|
|
|
return false; |
112
|
|
|
} |
113
|
|
|
|
114
|
|
|
// search forward starting from end minus needle length characters |
115
|
|
|
// see: http://stackoverflow.com/questions/834303/startswith-and-endswith-functions-in-php |
116
|
|
|
return (($temp = strlen($paths) - strlen($needle)) >= 0 && strpos($paths, $needle, $temp) !== false); |
117
|
|
|
} |
118
|
|
|
|
119
|
|
|
/** |
120
|
|
|
* Check if path starts with slash '/' |
121
|
|
|
* @param string $paths |
122
|
|
|
* @return bool |
123
|
|
|
*/ |
124
|
|
|
public static function startsWithSlash(string $paths) : bool |
125
|
|
|
{ |
126
|
|
|
return self::startsWith($paths, '/'); |
127
|
|
|
} |
128
|
|
|
|
129
|
|
|
/** |
130
|
|
|
* Check if path starts with slash $needle |
131
|
|
|
* @param string $paths |
132
|
|
|
* @param string $needle |
133
|
|
|
* @return bool |
134
|
|
|
*/ |
135
|
|
|
public static function startsWith(string $paths, string $needle) : bool |
136
|
|
|
{ |
137
|
|
|
if ($paths === null || $paths == '') { |
138
|
|
|
return false; |
139
|
|
|
} |
140
|
|
|
if ($needle === null || $needle == '') { |
141
|
|
|
return false; |
142
|
|
|
} |
143
|
|
|
|
144
|
|
|
// search backwards starting from haystack length characters from the end |
145
|
|
|
// see: http://stackoverflow.com/questions/834303/startswith-and-endswith-functions-in-php |
146
|
|
|
return strrpos($paths, $needle, -strlen($paths)) !== false; |
147
|
|
|
} |
148
|
|
|
|
149
|
|
|
/** |
150
|
|
|
* Find dirs matching a pattern (recursive with subdirs). |
151
|
|
|
* Returns an array containing the matched dirs (full path and not files), |
152
|
|
|
* an empty array if no dir matched or on error. |
153
|
|
|
* @param string $pathPattern if is null it set to base_path()/* if exists otherwise __DIR__/*. It support glob() string pattern. |
154
|
|
|
* @return array of dirs |
155
|
|
|
*/ |
156
|
|
|
public static function findDirs(string $pathPattern) |
157
|
|
|
{ |
158
|
|
|
if (($pathPattern === null || $pathPattern == '') && function_exists('base_path')) { |
159
|
|
|
$pathPattern = base_path() . '/*'; |
160
|
|
|
} elseif ($pathPattern === null || $pathPattern == '') { |
161
|
|
|
$pathPattern = __DIR__ . '/*'; |
162
|
|
|
} elseif (!self::endsWithStar($pathPattern)) { |
163
|
|
|
$pathPattern = DirHelper::addFinalSlash($pathPattern); |
164
|
|
|
} |
165
|
|
|
|
166
|
|
|
$files = glob($pathPattern, GLOB_ONLYDIR); |
167
|
|
|
|
168
|
|
|
foreach (glob(dirname($pathPattern) . '/*', GLOB_ONLYDIR | GLOB_NOSORT) as $dir) { |
169
|
|
|
$files = array_merge($files, self::findDirs($dir . '/' . basename($pathPattern))); |
170
|
|
|
} |
171
|
|
|
|
172
|
|
|
return $files; |
173
|
|
|
} |
174
|
|
|
|
175
|
|
|
/** |
176
|
|
|
* Dir::Delete() |
177
|
|
|
* get a dir path and remove all files and subdir in this dir. |
178
|
|
|
* if $not_remove_dir==TRUE then when finish DO NOT REMOVE THE $directory dir. |
179
|
|
|
* @param string $directory directory to empty |
180
|
|
|
* @param bool $not_remove_dir TRUE if DO NOT REMOVE THE $directory dir but only files. |
181
|
|
|
* @return bool true if success, otherwise false |
182
|
|
|
**/ |
183
|
|
|
public static function delete($directory, bool $not_remove_dir = false) : bool |
184
|
|
|
{ |
185
|
|
|
$directory = self::removeFinalSlash($directory); |
186
|
|
|
|
187
|
|
|
if (!self::isDirSafe($directory) || !is_readable($directory)) { |
188
|
|
|
return false; |
189
|
|
|
} |
190
|
|
|
|
191
|
|
|
$directoryHandle = opendir($directory); |
192
|
|
|
while (false !== ($contents = readdir($directoryHandle))) { |
193
|
|
|
if ($contents == '.' || $contents == '..') { |
194
|
|
|
continue; |
195
|
|
|
} |
196
|
|
|
$path = $directory . "/" . $contents; |
197
|
|
|
|
198
|
|
|
if (is_dir($path)) { |
199
|
|
|
self::delete($path, $not_remove_dir); |
200
|
|
|
} else { |
201
|
|
|
unlink($path); |
202
|
|
|
} |
203
|
|
|
} |
204
|
|
|
closedir($directoryHandle); |
205
|
|
|
|
206
|
|
|
if (!$not_remove_dir) { |
207
|
|
|
return true; |
208
|
|
|
} |
209
|
|
|
return rmdir($directory); |
210
|
|
|
} |
211
|
|
|
|
212
|
|
|
/** |
213
|
|
|
* Remove final slash ('/') char in dir if ends with slash. |
214
|
|
|
* @param $directory |
215
|
|
|
* @return string |
216
|
|
|
*/ |
217
|
|
|
public static function removeFinalSlash($directory) : string |
218
|
|
|
{ |
219
|
|
|
if (self::endsWithSlash($directory)) { |
220
|
|
|
$directory = substr($directory, 0, -1); |
221
|
|
|
} |
222
|
|
|
return $directory; |
223
|
|
|
} |
224
|
|
|
|
225
|
|
|
/** |
226
|
|
|
* For each dir passed in array, check if not finishes with '/' otherwise remove a slash to path. |
227
|
|
|
* If not dir, leave the element untouched. |
228
|
|
|
* @param array $paths |
229
|
|
|
* @return array |
230
|
|
|
*/ |
231
|
|
|
public static function removeFinalSlashToAllPaths(array $paths) : array |
232
|
|
|
{ |
233
|
|
|
if (empty($paths)) { |
234
|
|
|
return []; |
235
|
|
|
} |
236
|
|
|
|
237
|
|
|
return array_map('self::removeFinalSlash', $paths); |
238
|
|
|
} |
239
|
|
|
|
240
|
|
|
/** |
241
|
|
|
* Remove start slash ('/') char in dir if starts with slash. |
242
|
|
|
* @param $directory |
243
|
|
|
* @return string |
244
|
|
|
*/ |
245
|
|
|
public static function removeStartSlash($directory) : string |
246
|
|
|
{ |
247
|
|
|
if (self::startsWithSlash($directory)) { |
248
|
|
|
$directory = substr($directory, 1); |
249
|
|
|
} |
250
|
|
|
return $directory; |
251
|
|
|
} |
252
|
|
|
|
253
|
|
|
/** |
254
|
|
|
* For each dir passed in array, check if not started with '/' otherwise remove a slash to path. |
255
|
|
|
* If not dir, leave the element untouched. |
256
|
|
|
* @param array $paths |
257
|
|
|
* @return array |
258
|
|
|
*/ |
259
|
|
|
public static function removeStartSlashToAllPaths(array $paths) : array |
260
|
|
|
{ |
261
|
|
|
if (empty($paths)) { |
262
|
|
|
return []; |
263
|
|
|
} |
264
|
|
|
|
265
|
|
|
return array_map('self::removeStartSlash', $paths); |
266
|
|
|
} |
267
|
|
|
|
268
|
|
|
/** |
269
|
|
|
* Dir::copy() |
270
|
|
|
* Copy a source directory (files and all subdirectories) to destination directory. |
271
|
|
|
* If Destination directory doesn't exists try to create it. |
272
|
|
|
* @param $directorySource |
273
|
|
|
* @param $directoryDestination |
274
|
|
|
* @param array $excludedDirectory array of path to be escluded (i.e. it will not copied to destination folder) |
275
|
|
|
* @param \Closure|null $copied a function with two arguments ($directorySource,$directoryDestination). |
276
|
|
|
* @return bool true if success, otherwise false |
277
|
|
|
*/ |
278
|
|
|
public static function copy( |
279
|
|
|
$directorySource, |
280
|
|
|
$directoryDestination, |
281
|
|
|
array $excludedDirectory = [], |
282
|
|
|
\Closure $copied = null |
283
|
|
|
) : bool |
284
|
|
|
{ |
285
|
|
|
$directorySource = self::removeFinalSlash($directorySource); |
286
|
|
|
if (!self::isDirSafe($directorySource) || !is_readable($directorySource)) { |
287
|
|
|
return false; |
288
|
|
|
} |
289
|
|
|
|
290
|
|
|
$directoryDestination = self::removeFinalSlash($directoryDestination); |
291
|
|
|
if (!self::checkDirExistOrCreate($directoryDestination)) { |
292
|
|
|
return false; |
293
|
|
|
} |
294
|
|
|
is_callable($copied) ? $copied($directorySource, $directoryDestination) : ''; |
295
|
|
|
|
296
|
|
|
$excludedDirectory = self::removeFinalSlashToAllPaths($excludedDirectory); |
297
|
|
|
|
298
|
|
|
$directorySourceHandle = opendir($directorySource); |
299
|
|
|
while (false !== ($contents = readdir($directorySourceHandle))) { |
300
|
|
|
if ($contents == '.' || $contents == '..') { |
301
|
|
|
continue; |
302
|
|
|
} |
303
|
|
|
$path = $directorySource . "/" . $contents; |
304
|
|
|
if (in_array(DirHelper::removeFinalSlash($path), $excludedDirectory)) { |
305
|
|
|
continue; |
306
|
|
|
} |
307
|
|
|
$pathDest = $directoryDestination . "/" . $contents; |
308
|
|
|
|
309
|
|
|
if (is_dir($path)) { |
310
|
|
|
self::copy($path, $pathDest, $excludedDirectory); |
311
|
|
|
} else { |
312
|
|
|
copy($path, $pathDest); |
313
|
|
|
is_callable($copied) ? $copied($path, $pathDest) : ''; |
314
|
|
|
} |
315
|
|
|
} |
316
|
|
|
closedir($directorySourceHandle); |
317
|
|
|
return true; |
318
|
|
|
} |
319
|
|
|
|
320
|
|
|
/** |
321
|
|
|
* Returns whether the given path is on the local filesystem. |
322
|
|
|
* |
323
|
|
|
* @param string $path A path string |
324
|
|
|
* |
325
|
|
|
* @return boolean Returns true if the path is local, false for a URL |
326
|
|
|
* @see https://github.com/laradic/support/blob/master/src/Path.php |
327
|
|
|
*/ |
328
|
|
|
public static function isLocal($path) |
329
|
|
|
{ |
330
|
|
|
return is_string($path) && '' !== $path && false === strpos($path, '://'); |
331
|
|
|
} |
332
|
|
|
|
333
|
|
|
/** |
334
|
|
|
* Returns whether a path is absolute Unix path. |
335
|
|
|
* |
336
|
|
|
* @param string $path A path string |
337
|
|
|
* |
338
|
|
|
* @return boolean Returns true if the path is absolute unix path, false if it is |
339
|
|
|
* relative or empty |
340
|
|
|
*/ |
341
|
|
|
public static function isAbsoluteUnix($path) |
342
|
|
|
{ |
343
|
|
|
return '' !== $path && '/' === $path[ 0 ]; |
344
|
|
|
} |
345
|
|
|
|
346
|
|
|
/** |
347
|
|
|
* Returns whether a path is absolute Windows Path. |
348
|
|
|
* |
349
|
|
|
* @param string $path A path string |
350
|
|
|
* |
351
|
|
|
* @return boolean Returns true if the path is absolute, false if it is |
352
|
|
|
* relative or empty |
353
|
|
|
* @see https://github.com/laradic/support/blob/master/src/Path.php |
354
|
|
|
*/ |
355
|
|
|
public static function isAbsoluteWindows($path) |
356
|
|
|
{ |
357
|
|
|
if ('' === $path) { |
358
|
|
|
return false; |
359
|
|
|
} |
360
|
|
|
if ('\\' === $path[ 0 ]) { |
361
|
|
|
return true; |
362
|
|
|
} |
363
|
|
|
// Windows root |
364
|
|
|
if (strlen($path) > 1 && ctype_alpha($path[ 0 ]) && ':' === $path[ 1 ]) { |
365
|
|
|
// Special case: "C:" |
|
|
|
|
366
|
|
|
if (2 === strlen($path)) { |
367
|
|
|
return true; |
368
|
|
|
} |
369
|
|
|
// Normal case: "C:/ or "C:\" |
370
|
|
|
if ('/' === $path[ 2 ] || '\\' === $path[ 2 ]) { |
371
|
|
|
return true; |
372
|
|
|
} |
373
|
|
|
} |
374
|
|
|
return false; |
375
|
|
|
} |
376
|
|
|
|
377
|
|
|
/** |
378
|
|
|
* Returns whether a path is absolute. |
379
|
|
|
* |
380
|
|
|
* @param string $path A path string |
381
|
|
|
* |
382
|
|
|
* @return boolean Returns true if the path is absolute, false if it is |
383
|
|
|
* relative or empty |
384
|
|
|
*/ |
385
|
|
|
public static function isAbsolute($path) |
386
|
|
|
{ |
387
|
|
|
return self::isAbsoluteUnix($path) || self::isAbsoluteWindows($path); |
388
|
|
|
} |
389
|
|
|
|
390
|
|
|
/** |
391
|
|
|
* Returns whether a path is relative. |
392
|
|
|
* |
393
|
|
|
* @param string $path A path string |
394
|
|
|
* |
395
|
|
|
* @return boolean Returns true if the path is relative or empty, false if |
396
|
|
|
* it is absolute |
397
|
|
|
* @see https://github.com/laradic/support/blob/master/src/Path.php |
398
|
|
|
*/ |
399
|
|
|
public static function isRelative($path) |
400
|
|
|
{ |
401
|
|
|
return !self::isAbsolute($path); |
402
|
|
|
} |
403
|
|
|
|
404
|
|
|
/** |
405
|
|
|
* Joins a split file system path. |
406
|
|
|
* |
407
|
|
|
* @param array|string $paths |
408
|
|
|
* |
409
|
|
|
* @return string |
410
|
|
|
* @see https://github.com/laradic/support/blob/master/src/Path.php |
411
|
|
|
*/ |
412
|
|
|
public static function join(...$paths) : string |
413
|
|
|
{ |
414
|
|
|
foreach ($paths as $key => &$argument) { |
415
|
|
|
if (is_array($argument)) { |
416
|
|
|
$argument = self::join($argument); |
417
|
|
|
} |
418
|
|
|
$argument = self::removeFinalSlash($argument); |
419
|
|
|
if ($key > 0) { |
420
|
|
|
$argument = self::removeStartSlash($argument); |
421
|
|
|
} |
422
|
|
|
$paths[ $key ] = $argument; |
423
|
|
|
} |
424
|
|
|
return implode(DIRECTORY_SEPARATOR, $paths); |
425
|
|
|
} |
426
|
|
|
/** |
427
|
|
|
* Similar to the join() method, but also normalize()'s the result |
428
|
|
|
* |
429
|
|
|
* @param string|array ...$paths |
430
|
|
|
* |
431
|
|
|
* @return string |
432
|
|
|
* @see https://github.com/laradic/support/blob/master/src/Path.php |
433
|
|
|
*/ |
434
|
|
|
public static function njoin(...$paths) : string |
435
|
|
|
{ |
436
|
|
|
return self::canonicalize(self::join($paths)); |
437
|
|
|
} |
438
|
|
|
|
439
|
|
|
/** |
440
|
|
|
* Canonicalizes the given path. |
441
|
|
|
* |
442
|
|
|
* During normalization, all slashes are replaced by forward slashes ("/"). |
443
|
|
|
* Furthermore, all "." and ".." segments are removed as far as possible. |
444
|
|
|
* ".." segments at the beginning of relative paths are not removed. |
445
|
|
|
* |
446
|
|
|
* ```php |
447
|
|
|
* echo DirHelper::canonicalize("\webmozart\puli\..\css\style.css"); |
448
|
|
|
* // => /webmozart/style.css |
449
|
|
|
* |
450
|
|
|
* echo DirHelper::canonicalize("../css/./style.css"); |
451
|
|
|
* // => ../css/style.css |
452
|
|
|
* ``` |
453
|
|
|
* |
454
|
|
|
* This method is able to deal with both UNIX and Windows paths. |
455
|
|
|
* |
456
|
|
|
* @param string $path A path string |
457
|
|
|
* |
458
|
|
|
* @return string The canonical path |
459
|
|
|
* @see https://github.com/laradic/support/blob/master/src/Path.php |
460
|
|
|
*/ |
461
|
|
|
public static function canonicalize($path) |
462
|
|
|
{ |
463
|
|
|
$path = (string)$path; |
464
|
|
|
if ('' === $path) { |
465
|
|
|
return ''; |
466
|
|
|
} |
467
|
|
|
$path = str_replace('\\', '/', $path); |
468
|
|
|
list ($root, $path) = self::split($path); |
469
|
|
|
$parts = array_filter(explode('/', $path), 'strlen'); |
470
|
|
|
$canonicalParts = [ ]; |
471
|
|
|
// Collapse "." and "..", if possible |
|
|
|
|
472
|
|
|
foreach ($parts as $part) { |
473
|
|
|
if ('.' === $part) { |
474
|
|
|
continue; |
475
|
|
|
} |
476
|
|
|
// Collapse ".." with the previous part, if one exists |
477
|
|
|
// Don't collapse ".." if the previous part is also ".." |
478
|
|
|
if ('..' === $part && count($canonicalParts) > 0 |
479
|
|
|
&& '..' !== $canonicalParts[ count($canonicalParts) - 1 ] |
480
|
|
|
) { |
481
|
|
|
array_pop($canonicalParts); |
482
|
|
|
continue; |
483
|
|
|
} |
484
|
|
|
// Only add ".." prefixes for relative paths |
485
|
|
|
if ('..' !== $part || '' === $root) { |
486
|
|
|
$canonicalParts[] = $part; |
487
|
|
|
} |
488
|
|
|
} |
489
|
|
|
// Add the root directory again |
490
|
|
|
return $root . implode('/', $canonicalParts); |
491
|
|
|
} |
492
|
|
|
|
493
|
|
|
/** |
494
|
|
|
* Splits a part into its root directory and the remainder. |
495
|
|
|
* |
496
|
|
|
* If the path has no root directory, an empty root directory will be |
497
|
|
|
* returned. |
498
|
|
|
* |
499
|
|
|
* If the root directory is a Windows style partition, the resulting root |
500
|
|
|
* will always contain a trailing slash. |
501
|
|
|
* |
502
|
|
|
* list ($root, $path) = DirHelpersplit("C:/webmozart") |
503
|
|
|
* // => array("C:/", "webmozart") |
504
|
|
|
* |
505
|
|
|
* list ($root, $path) = DirHelpersplit("C:") |
506
|
|
|
* // => array("C:/", "") |
507
|
|
|
* |
508
|
|
|
* @param string $path The canonical path to split |
509
|
|
|
* |
510
|
|
|
* @return array An array with the root directory and the remaining relative |
511
|
|
|
* path |
512
|
|
|
* @see https://github.com/laradic/support/blob/master/src/Path.php |
513
|
|
|
*/ |
514
|
|
|
private static function split($path) |
515
|
|
|
{ |
516
|
|
|
if ('' === $path) { |
517
|
|
|
return [ '', '' ]; |
518
|
|
|
} |
519
|
|
|
$root = ''; |
520
|
|
|
$length = strlen($path); |
521
|
|
|
// Remove and remember root directory |
522
|
|
|
if ('/' === $path[ 0 ]) { |
523
|
|
|
$root = '/'; |
524
|
|
|
$path = $length > 1 ? substr($path, 1) : ''; |
525
|
|
|
} elseif ($length > 1 && ctype_alpha($path[ 0 ]) && ':' === $path[ 1 ]) { |
526
|
|
|
if (2 === $length) { |
527
|
|
|
// Windows special case: "C:" |
528
|
|
|
$root = $path . '/'; |
529
|
|
|
$path = ''; |
530
|
|
|
} elseif ('/' === $path[ 2 ]) { |
531
|
|
|
// Windows normal case: "C:/".. |
532
|
|
|
$root = substr($path, 0, 3); |
533
|
|
|
$path = $length > 3 ? substr($path, 3) : ''; |
534
|
|
|
} |
535
|
|
|
} |
536
|
|
|
return [ $root, $path ]; |
537
|
|
|
} |
538
|
|
|
} |
539
|
|
|
|
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.
The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.
This check looks for comments that seem to be mostly valid code and reports them.