1 | <?php |
---|
2 | /** |
---|
3 | * File/Directory manipulation |
---|
4 | * |
---|
5 | * PHP versions 4 and 5 |
---|
6 | * |
---|
7 | * @category pear |
---|
8 | * @package System |
---|
9 | * @author Tomas V.V.Cox <cox@idecnet.com> |
---|
10 | * @copyright 1997-2009 The Authors |
---|
11 | * @license http://opensource.org/licenses/bsd-license.php New BSD License |
---|
12 | * @version CVS: $Id: System.php 313024 2011-07-06 19:51:24Z dufuz $ |
---|
13 | * @link http://pear.php.net/package/PEAR |
---|
14 | * @since File available since Release 0.1 |
---|
15 | */ |
---|
16 | |
---|
17 | /** |
---|
18 | * base class |
---|
19 | */ |
---|
20 | require_once 'PEAR.php'; |
---|
21 | require_once 'Console/Getopt.php'; |
---|
22 | |
---|
23 | $GLOBALS['_System_temp_files'] = array(); |
---|
24 | |
---|
25 | /** |
---|
26 | * System offers cross plattform compatible system functions |
---|
27 | * |
---|
28 | * Static functions for different operations. Should work under |
---|
29 | * Unix and Windows. The names and usage has been taken from its respectively |
---|
30 | * GNU commands. The functions will return (bool) false on error and will |
---|
31 | * trigger the error with the PHP trigger_error() function (you can silence |
---|
32 | * the error by prefixing a '@' sign after the function call, but this |
---|
33 | * is not recommended practice. Instead use an error handler with |
---|
34 | * {@link set_error_handler()}). |
---|
35 | * |
---|
36 | * Documentation on this class you can find in: |
---|
37 | * http://pear.php.net/manual/ |
---|
38 | * |
---|
39 | * Example usage: |
---|
40 | * if (!@System::rm('-r file1 dir1')) { |
---|
41 | * print "could not delete file1 or dir1"; |
---|
42 | * } |
---|
43 | * |
---|
44 | * In case you need to to pass file names with spaces, |
---|
45 | * pass the params as an array: |
---|
46 | * |
---|
47 | * System::rm(array('-r', $file1, $dir1)); |
---|
48 | * |
---|
49 | * @category pear |
---|
50 | * @package System |
---|
51 | * @author Tomas V.V. Cox <cox@idecnet.com> |
---|
52 | * @copyright 1997-2006 The PHP Group |
---|
53 | * @license http://opensource.org/licenses/bsd-license.php New BSD License |
---|
54 | * @version Release: 1.9.4 |
---|
55 | * @link http://pear.php.net/package/PEAR |
---|
56 | * @since Class available since Release 0.1 |
---|
57 | * @static |
---|
58 | */ |
---|
59 | class System |
---|
60 | { |
---|
61 | /** |
---|
62 | * returns the commandline arguments of a function |
---|
63 | * |
---|
64 | * @param string $argv the commandline |
---|
65 | * @param string $short_options the allowed option short-tags |
---|
66 | * @param string $long_options the allowed option long-tags |
---|
67 | * @return array the given options and there values |
---|
68 | * @static |
---|
69 | * @access private |
---|
70 | */ |
---|
71 | function _parseArgs($argv, $short_options, $long_options = null) |
---|
72 | { |
---|
73 | if (!is_array($argv) && $argv !== null) { |
---|
74 | // Find all items, quoted or otherwise |
---|
75 | preg_match_all("/(?:[\"'])(.*?)(?:['\"])|([^\s]+)/", $argv, $av); |
---|
76 | $argv = $av[1]; |
---|
77 | foreach ($av[2] as $k => $a) { |
---|
78 | if (empty($a)) { |
---|
79 | continue; |
---|
80 | } |
---|
81 | $argv[$k] = trim($a) ; |
---|
82 | } |
---|
83 | } |
---|
84 | return Console_Getopt::getopt2($argv, $short_options, $long_options); |
---|
85 | } |
---|
86 | |
---|
87 | /** |
---|
88 | * Output errors with PHP trigger_error(). You can silence the errors |
---|
89 | * with prefixing a "@" sign to the function call: @System::mkdir(..); |
---|
90 | * |
---|
91 | * @param mixed $error a PEAR error or a string with the error message |
---|
92 | * @return bool false |
---|
93 | * @static |
---|
94 | * @access private |
---|
95 | */ |
---|
96 | function raiseError($error) |
---|
97 | { |
---|
98 | if (PEAR::isError($error)) { |
---|
99 | $error = $error->getMessage(); |
---|
100 | } |
---|
101 | trigger_error($error, E_USER_WARNING); |
---|
102 | return false; |
---|
103 | } |
---|
104 | |
---|
105 | /** |
---|
106 | * Creates a nested array representing the structure of a directory |
---|
107 | * |
---|
108 | * System::_dirToStruct('dir1', 0) => |
---|
109 | * Array |
---|
110 | * ( |
---|
111 | * [dirs] => Array |
---|
112 | * ( |
---|
113 | * [0] => dir1 |
---|
114 | * ) |
---|
115 | * |
---|
116 | * [files] => Array |
---|
117 | * ( |
---|
118 | * [0] => dir1/file2 |
---|
119 | * [1] => dir1/file3 |
---|
120 | * ) |
---|
121 | * ) |
---|
122 | * @param string $sPath Name of the directory |
---|
123 | * @param integer $maxinst max. deep of the lookup |
---|
124 | * @param integer $aktinst starting deep of the lookup |
---|
125 | * @param bool $silent if true, do not emit errors. |
---|
126 | * @return array the structure of the dir |
---|
127 | * @static |
---|
128 | * @access private |
---|
129 | */ |
---|
130 | function _dirToStruct($sPath, $maxinst, $aktinst = 0, $silent = false) |
---|
131 | { |
---|
132 | $struct = array('dirs' => array(), 'files' => array()); |
---|
133 | if (($dir = @opendir($sPath)) === false) { |
---|
134 | if (!$silent) { |
---|
135 | System::raiseError("Could not open dir $sPath"); |
---|
136 | } |
---|
137 | return $struct; // XXX could not open error |
---|
138 | } |
---|
139 | |
---|
140 | $struct['dirs'][] = $sPath = realpath($sPath); // XXX don't add if '.' or '..' ? |
---|
141 | $list = array(); |
---|
142 | while (false !== ($file = readdir($dir))) { |
---|
143 | if ($file != '.' && $file != '..') { |
---|
144 | $list[] = $file; |
---|
145 | } |
---|
146 | } |
---|
147 | |
---|
148 | closedir($dir); |
---|
149 | natsort($list); |
---|
150 | if ($aktinst < $maxinst || $maxinst == 0) { |
---|
151 | foreach ($list as $val) { |
---|
152 | $path = $sPath . DIRECTORY_SEPARATOR . $val; |
---|
153 | if (is_dir($path) && !is_link($path)) { |
---|
154 | $tmp = System::_dirToStruct($path, $maxinst, $aktinst+1, $silent); |
---|
155 | $struct = array_merge_recursive($struct, $tmp); |
---|
156 | } else { |
---|
157 | $struct['files'][] = $path; |
---|
158 | } |
---|
159 | } |
---|
160 | } |
---|
161 | |
---|
162 | return $struct; |
---|
163 | } |
---|
164 | |
---|
165 | /** |
---|
166 | * Creates a nested array representing the structure of a directory and files |
---|
167 | * |
---|
168 | * @param array $files Array listing files and dirs |
---|
169 | * @return array |
---|
170 | * @static |
---|
171 | * @see System::_dirToStruct() |
---|
172 | */ |
---|
173 | function _multipleToStruct($files) |
---|
174 | { |
---|
175 | $struct = array('dirs' => array(), 'files' => array()); |
---|
176 | settype($files, 'array'); |
---|
177 | foreach ($files as $file) { |
---|
178 | if (is_dir($file) && !is_link($file)) { |
---|
179 | $tmp = System::_dirToStruct($file, 0); |
---|
180 | $struct = array_merge_recursive($tmp, $struct); |
---|
181 | } else { |
---|
182 | if (!in_array($file, $struct['files'])) { |
---|
183 | $struct['files'][] = $file; |
---|
184 | } |
---|
185 | } |
---|
186 | } |
---|
187 | return $struct; |
---|
188 | } |
---|
189 | |
---|
190 | /** |
---|
191 | * The rm command for removing files. |
---|
192 | * Supports multiple files and dirs and also recursive deletes |
---|
193 | * |
---|
194 | * @param string $args the arguments for rm |
---|
195 | * @return mixed PEAR_Error or true for success |
---|
196 | * @static |
---|
197 | * @access public |
---|
198 | */ |
---|
199 | function rm($args) |
---|
200 | { |
---|
201 | $opts = System::_parseArgs($args, 'rf'); // "f" does nothing but I like it :-) |
---|
202 | if (PEAR::isError($opts)) { |
---|
203 | return System::raiseError($opts); |
---|
204 | } |
---|
205 | foreach ($opts[0] as $opt) { |
---|
206 | if ($opt[0] == 'r') { |
---|
207 | $do_recursive = true; |
---|
208 | } |
---|
209 | } |
---|
210 | $ret = true; |
---|
211 | if (isset($do_recursive)) { |
---|
212 | $struct = System::_multipleToStruct($opts[1]); |
---|
213 | foreach ($struct['files'] as $file) { |
---|
214 | if (!@unlink($file)) { |
---|
215 | $ret = false; |
---|
216 | } |
---|
217 | } |
---|
218 | |
---|
219 | rsort($struct['dirs']); |
---|
220 | foreach ($struct['dirs'] as $dir) { |
---|
221 | if (!@rmdir($dir)) { |
---|
222 | $ret = false; |
---|
223 | } |
---|
224 | } |
---|
225 | } else { |
---|
226 | foreach ($opts[1] as $file) { |
---|
227 | $delete = (is_dir($file)) ? 'rmdir' : 'unlink'; |
---|
228 | if (!@$delete($file)) { |
---|
229 | $ret = false; |
---|
230 | } |
---|
231 | } |
---|
232 | } |
---|
233 | return $ret; |
---|
234 | } |
---|
235 | |
---|
236 | /** |
---|
237 | * Make directories. |
---|
238 | * |
---|
239 | * The -p option will create parent directories |
---|
240 | * @param string $args the name of the director(y|ies) to create |
---|
241 | * @return bool True for success |
---|
242 | * @static |
---|
243 | * @access public |
---|
244 | */ |
---|
245 | function mkDir($args) |
---|
246 | { |
---|
247 | $opts = System::_parseArgs($args, 'pm:'); |
---|
248 | if (PEAR::isError($opts)) { |
---|
249 | return System::raiseError($opts); |
---|
250 | } |
---|
251 | |
---|
252 | $mode = 0777; // default mode |
---|
253 | foreach ($opts[0] as $opt) { |
---|
254 | if ($opt[0] == 'p') { |
---|
255 | $create_parents = true; |
---|
256 | } elseif ($opt[0] == 'm') { |
---|
257 | // if the mode is clearly an octal number (starts with 0) |
---|
258 | // convert it to decimal |
---|
259 | if (strlen($opt[1]) && $opt[1]{0} == '0') { |
---|
260 | $opt[1] = octdec($opt[1]); |
---|
261 | } else { |
---|
262 | // convert to int |
---|
263 | $opt[1] += 0; |
---|
264 | } |
---|
265 | $mode = $opt[1]; |
---|
266 | } |
---|
267 | } |
---|
268 | |
---|
269 | $ret = true; |
---|
270 | if (isset($create_parents)) { |
---|
271 | foreach ($opts[1] as $dir) { |
---|
272 | $dirstack = array(); |
---|
273 | while ((!file_exists($dir) || !is_dir($dir)) && |
---|
274 | $dir != DIRECTORY_SEPARATOR) { |
---|
275 | array_unshift($dirstack, $dir); |
---|
276 | $dir = dirname($dir); |
---|
277 | } |
---|
278 | |
---|
279 | while ($newdir = array_shift($dirstack)) { |
---|
280 | if (!is_writeable(dirname($newdir))) { |
---|
281 | $ret = false; |
---|
282 | break; |
---|
283 | } |
---|
284 | |
---|
285 | if (!mkdir($newdir, $mode)) { |
---|
286 | $ret = false; |
---|
287 | } |
---|
288 | } |
---|
289 | } |
---|
290 | } else { |
---|
291 | foreach($opts[1] as $dir) { |
---|
292 | if ((@file_exists($dir) || !is_dir($dir)) && !mkdir($dir, $mode)) { |
---|
293 | $ret = false; |
---|
294 | } |
---|
295 | } |
---|
296 | } |
---|
297 | |
---|
298 | return $ret; |
---|
299 | } |
---|
300 | |
---|
301 | /** |
---|
302 | * Concatenate files |
---|
303 | * |
---|
304 | * Usage: |
---|
305 | * 1) $var = System::cat('sample.txt test.txt'); |
---|
306 | * 2) System::cat('sample.txt test.txt > final.txt'); |
---|
307 | * 3) System::cat('sample.txt test.txt >> final.txt'); |
---|
308 | * |
---|
309 | * Note: as the class use fopen, urls should work also (test that) |
---|
310 | * |
---|
311 | * @param string $args the arguments |
---|
312 | * @return boolean true on success |
---|
313 | * @static |
---|
314 | * @access public |
---|
315 | */ |
---|
316 | function &cat($args) |
---|
317 | { |
---|
318 | $ret = null; |
---|
319 | $files = array(); |
---|
320 | if (!is_array($args)) { |
---|
321 | $args = preg_split('/\s+/', $args, -1, PREG_SPLIT_NO_EMPTY); |
---|
322 | } |
---|
323 | |
---|
324 | $count_args = count($args); |
---|
325 | for ($i = 0; $i < $count_args; ++$i) { |
---|
326 | if ($args[$i] == '>') { |
---|
327 | $mode = 'wb'; |
---|
328 | $outputfile = $args[$i+1]; |
---|
329 | break; |
---|
330 | } elseif ($args[$i] == '>>') { |
---|
331 | $mode = 'ab+'; |
---|
332 | $outputfile = $args[$i+1]; |
---|
333 | break; |
---|
334 | } else { |
---|
335 | $files[] = $args[$i]; |
---|
336 | } |
---|
337 | } |
---|
338 | $outputfd = false; |
---|
339 | if (isset($mode)) { |
---|
340 | if (!$outputfd = fopen($outputfile, $mode)) { |
---|
341 | $err = System::raiseError("Could not open $outputfile"); |
---|
342 | return $err; |
---|
343 | } |
---|
344 | $ret = true; |
---|
345 | } |
---|
346 | foreach ($files as $file) { |
---|
347 | if (!$fd = fopen($file, 'r')) { |
---|
348 | System::raiseError("Could not open $file"); |
---|
349 | continue; |
---|
350 | } |
---|
351 | while ($cont = fread($fd, 2048)) { |
---|
352 | if (is_resource($outputfd)) { |
---|
353 | fwrite($outputfd, $cont); |
---|
354 | } else { |
---|
355 | $ret .= $cont; |
---|
356 | } |
---|
357 | } |
---|
358 | fclose($fd); |
---|
359 | } |
---|
360 | if (is_resource($outputfd)) { |
---|
361 | fclose($outputfd); |
---|
362 | } |
---|
363 | return $ret; |
---|
364 | } |
---|
365 | |
---|
366 | /** |
---|
367 | * Creates temporary files or directories. This function will remove |
---|
368 | * the created files when the scripts finish its execution. |
---|
369 | * |
---|
370 | * Usage: |
---|
371 | * 1) $tempfile = System::mktemp("prefix"); |
---|
372 | * 2) $tempdir = System::mktemp("-d prefix"); |
---|
373 | * 3) $tempfile = System::mktemp(); |
---|
374 | * 4) $tempfile = System::mktemp("-t /var/tmp prefix"); |
---|
375 | * |
---|
376 | * prefix -> The string that will be prepended to the temp name |
---|
377 | * (defaults to "tmp"). |
---|
378 | * -d -> A temporary dir will be created instead of a file. |
---|
379 | * -t -> The target dir where the temporary (file|dir) will be created. If |
---|
380 | * this param is missing by default the env vars TMP on Windows or |
---|
381 | * TMPDIR in Unix will be used. If these vars are also missing |
---|
382 | * c:\windows\temp or /tmp will be used. |
---|
383 | * |
---|
384 | * @param string $args The arguments |
---|
385 | * @return mixed the full path of the created (file|dir) or false |
---|
386 | * @see System::tmpdir() |
---|
387 | * @static |
---|
388 | * @access public |
---|
389 | */ |
---|
390 | function mktemp($args = null) |
---|
391 | { |
---|
392 | static $first_time = true; |
---|
393 | $opts = System::_parseArgs($args, 't:d'); |
---|
394 | if (PEAR::isError($opts)) { |
---|
395 | return System::raiseError($opts); |
---|
396 | } |
---|
397 | |
---|
398 | foreach ($opts[0] as $opt) { |
---|
399 | if ($opt[0] == 'd') { |
---|
400 | $tmp_is_dir = true; |
---|
401 | } elseif ($opt[0] == 't') { |
---|
402 | $tmpdir = $opt[1]; |
---|
403 | } |
---|
404 | } |
---|
405 | |
---|
406 | $prefix = (isset($opts[1][0])) ? $opts[1][0] : 'tmp'; |
---|
407 | if (!isset($tmpdir)) { |
---|
408 | $tmpdir = System::tmpdir(); |
---|
409 | } |
---|
410 | |
---|
411 | if (!System::mkDir(array('-p', $tmpdir))) { |
---|
412 | return false; |
---|
413 | } |
---|
414 | |
---|
415 | $tmp = tempnam($tmpdir, $prefix); |
---|
416 | if (isset($tmp_is_dir)) { |
---|
417 | unlink($tmp); // be careful possible race condition here |
---|
418 | if (!mkdir($tmp, 0700)) { |
---|
419 | return System::raiseError("Unable to create temporary directory $tmpdir"); |
---|
420 | } |
---|
421 | } |
---|
422 | |
---|
423 | $GLOBALS['_System_temp_files'][] = $tmp; |
---|
424 | if (isset($tmp_is_dir)) { |
---|
425 | //$GLOBALS['_System_temp_files'][] = dirname($tmp); |
---|
426 | } |
---|
427 | |
---|
428 | if ($first_time) { |
---|
429 | PEAR::registerShutdownFunc(array('System', '_removeTmpFiles')); |
---|
430 | $first_time = false; |
---|
431 | } |
---|
432 | |
---|
433 | return $tmp; |
---|
434 | } |
---|
435 | |
---|
436 | /** |
---|
437 | * Remove temporary files created my mkTemp. This function is executed |
---|
438 | * at script shutdown time |
---|
439 | * |
---|
440 | * @static |
---|
441 | * @access private |
---|
442 | */ |
---|
443 | function _removeTmpFiles() |
---|
444 | { |
---|
445 | if (count($GLOBALS['_System_temp_files'])) { |
---|
446 | $delete = $GLOBALS['_System_temp_files']; |
---|
447 | array_unshift($delete, '-r'); |
---|
448 | System::rm($delete); |
---|
449 | $GLOBALS['_System_temp_files'] = array(); |
---|
450 | } |
---|
451 | } |
---|
452 | |
---|
453 | /** |
---|
454 | * Get the path of the temporal directory set in the system |
---|
455 | * by looking in its environments variables. |
---|
456 | * Note: php.ini-recommended removes the "E" from the variables_order setting, |
---|
457 | * making unavaible the $_ENV array, that s why we do tests with _ENV |
---|
458 | * |
---|
459 | * @static |
---|
460 | * @return string The temporary directory on the system |
---|
461 | */ |
---|
462 | function tmpdir() |
---|
463 | { |
---|
464 | if (OS_WINDOWS) { |
---|
465 | if ($var = isset($_ENV['TMP']) ? $_ENV['TMP'] : getenv('TMP')) { |
---|
466 | return $var; |
---|
467 | } |
---|
468 | if ($var = isset($_ENV['TEMP']) ? $_ENV['TEMP'] : getenv('TEMP')) { |
---|
469 | return $var; |
---|
470 | } |
---|
471 | if ($var = isset($_ENV['USERPROFILE']) ? $_ENV['USERPROFILE'] : getenv('USERPROFILE')) { |
---|
472 | return $var; |
---|
473 | } |
---|
474 | if ($var = isset($_ENV['windir']) ? $_ENV['windir'] : getenv('windir')) { |
---|
475 | return $var; |
---|
476 | } |
---|
477 | return getenv('SystemRoot') . '\temp'; |
---|
478 | } |
---|
479 | if ($var = isset($_ENV['TMPDIR']) ? $_ENV['TMPDIR'] : getenv('TMPDIR')) { |
---|
480 | return $var; |
---|
481 | } |
---|
482 | return realpath('/tmp'); |
---|
483 | } |
---|
484 | |
---|
485 | /** |
---|
486 | * The "which" command (show the full path of a command) |
---|
487 | * |
---|
488 | * @param string $program The command to search for |
---|
489 | * @param mixed $fallback Value to return if $program is not found |
---|
490 | * |
---|
491 | * @return mixed A string with the full path or false if not found |
---|
492 | * @static |
---|
493 | * @author Stig Bakken <ssb@php.net> |
---|
494 | */ |
---|
495 | function which($program, $fallback = false) |
---|
496 | { |
---|
497 | // enforce API |
---|
498 | if (!is_string($program) || '' == $program) { |
---|
499 | return $fallback; |
---|
500 | } |
---|
501 | |
---|
502 | // full path given |
---|
503 | if (basename($program) != $program) { |
---|
504 | $path_elements[] = dirname($program); |
---|
505 | $program = basename($program); |
---|
506 | } else { |
---|
507 | // Honor safe mode |
---|
508 | if (!ini_get('safe_mode') || !$path = ini_get('safe_mode_exec_dir')) { |
---|
509 | $path = getenv('PATH'); |
---|
510 | if (!$path) { |
---|
511 | $path = getenv('Path'); // some OSes are just stupid enough to do this |
---|
512 | } |
---|
513 | } |
---|
514 | $path_elements = explode(PATH_SEPARATOR, $path); |
---|
515 | } |
---|
516 | |
---|
517 | if (OS_WINDOWS) { |
---|
518 | $exe_suffixes = getenv('PATHEXT') |
---|
519 | ? explode(PATH_SEPARATOR, getenv('PATHEXT')) |
---|
520 | : array('.exe','.bat','.cmd','.com'); |
---|
521 | // allow passing a command.exe param |
---|
522 | if (strpos($program, '.') !== false) { |
---|
523 | array_unshift($exe_suffixes, ''); |
---|
524 | } |
---|
525 | // is_executable() is not available on windows for PHP4 |
---|
526 | $pear_is_executable = (function_exists('is_executable')) ? 'is_executable' : 'is_file'; |
---|
527 | } else { |
---|
528 | $exe_suffixes = array(''); |
---|
529 | $pear_is_executable = 'is_executable'; |
---|
530 | } |
---|
531 | |
---|
532 | foreach ($exe_suffixes as $suff) { |
---|
533 | foreach ($path_elements as $dir) { |
---|
534 | $file = $dir . DIRECTORY_SEPARATOR . $program . $suff; |
---|
535 | if (@$pear_is_executable($file)) { |
---|
536 | return $file; |
---|
537 | } |
---|
538 | } |
---|
539 | } |
---|
540 | return $fallback; |
---|
541 | } |
---|
542 | |
---|
543 | /** |
---|
544 | * The "find" command |
---|
545 | * |
---|
546 | * Usage: |
---|
547 | * |
---|
548 | * System::find($dir); |
---|
549 | * System::find("$dir -type d"); |
---|
550 | * System::find("$dir -type f"); |
---|
551 | * System::find("$dir -name *.php"); |
---|
552 | * System::find("$dir -name *.php -name *.htm*"); |
---|
553 | * System::find("$dir -maxdepth 1"); |
---|
554 | * |
---|
555 | * Params implmented: |
---|
556 | * $dir -> Start the search at this directory |
---|
557 | * -type d -> return only directories |
---|
558 | * -type f -> return only files |
---|
559 | * -maxdepth <n> -> max depth of recursion |
---|
560 | * -name <pattern> -> search pattern (bash style). Multiple -name param allowed |
---|
561 | * |
---|
562 | * @param mixed Either array or string with the command line |
---|
563 | * @return array Array of found files |
---|
564 | * @static |
---|
565 | * |
---|
566 | */ |
---|
567 | function find($args) |
---|
568 | { |
---|
569 | if (!is_array($args)) { |
---|
570 | $args = preg_split('/\s+/', $args, -1, PREG_SPLIT_NO_EMPTY); |
---|
571 | } |
---|
572 | $dir = realpath(array_shift($args)); |
---|
573 | if (!$dir) { |
---|
574 | return array(); |
---|
575 | } |
---|
576 | $patterns = array(); |
---|
577 | $depth = 0; |
---|
578 | $do_files = $do_dirs = true; |
---|
579 | $args_count = count($args); |
---|
580 | for ($i = 0; $i < $args_count; ++$i) { |
---|
581 | switch ($args[$i]) { |
---|
582 | case '-type': |
---|
583 | if (in_array($args[$i+1], array('d', 'f'))) { |
---|
584 | if ($args[$i+1] == 'd') { |
---|
585 | $do_files = false; |
---|
586 | } else { |
---|
587 | $do_dirs = false; |
---|
588 | } |
---|
589 | } |
---|
590 | ++$i; |
---|
591 | break; |
---|
592 | case '-name': |
---|
593 | $name = preg_quote($args[$i+1], '#'); |
---|
594 | // our magic characters ? and * have just been escaped, |
---|
595 | // so now we change the escaped versions to PCRE operators |
---|
596 | $name = strtr($name, array('\?' => '.', '\*' => '.*')); |
---|
597 | $patterns[] = '('.$name.')'; |
---|
598 | ++$i; |
---|
599 | break; |
---|
600 | case '-maxdepth': |
---|
601 | $depth = $args[$i+1]; |
---|
602 | break; |
---|
603 | } |
---|
604 | } |
---|
605 | $path = System::_dirToStruct($dir, $depth, 0, true); |
---|
606 | if ($do_files && $do_dirs) { |
---|
607 | $files = array_merge($path['files'], $path['dirs']); |
---|
608 | } elseif ($do_dirs) { |
---|
609 | $files = $path['dirs']; |
---|
610 | } else { |
---|
611 | $files = $path['files']; |
---|
612 | } |
---|
613 | if (count($patterns)) { |
---|
614 | $dsq = preg_quote(DIRECTORY_SEPARATOR, '#'); |
---|
615 | $pattern = '#(^|'.$dsq.')'.implode('|', $patterns).'($|'.$dsq.')#'; |
---|
616 | $ret = array(); |
---|
617 | $files_count = count($files); |
---|
618 | for ($i = 0; $i < $files_count; ++$i) { |
---|
619 | // only search in the part of the file below the current directory |
---|
620 | $filepart = basename($files[$i]); |
---|
621 | if (preg_match($pattern, $filepart)) { |
---|
622 | $ret[] = $files[$i]; |
---|
623 | } |
---|
624 | } |
---|
625 | return $ret; |
---|
626 | } |
---|
627 | return $files; |
---|
628 | } |
---|
629 | } |
---|