12 * @since 2.5.0 |
12 * @since 2.5.0 |
13 * |
13 * |
14 * @see WP_Filesystem_Base |
14 * @see WP_Filesystem_Base |
15 */ |
15 */ |
16 class WP_Filesystem_ftpsockets extends WP_Filesystem_Base { |
16 class WP_Filesystem_ftpsockets extends WP_Filesystem_Base { |
17 /** |
17 |
|
18 /** |
|
19 * @since 2.5.0 |
18 * @var ftp |
20 * @var ftp |
19 */ |
21 */ |
20 public $ftp; |
22 public $ftp; |
21 |
23 |
22 /** |
24 /** |
|
25 * Constructor. |
|
26 * |
|
27 * @since 2.5.0 |
23 * |
28 * |
24 * @param array $opt |
29 * @param array $opt |
25 */ |
30 */ |
26 public function __construct( $opt = '' ) { |
31 public function __construct( $opt = '' ) { |
27 $this->method = 'ftpsockets'; |
32 $this->method = 'ftpsockets'; |
28 $this->errors = new WP_Error(); |
33 $this->errors = new WP_Error(); |
29 |
34 |
30 // Check if possible to use ftp functions. |
35 // Check if possible to use ftp functions. |
31 if ( ! @include_once( ABSPATH . 'wp-admin/includes/class-ftp.php' ) ) { |
36 if ( ! @include_once( ABSPATH . 'wp-admin/includes/class-ftp.php' ) ) { |
32 return; |
37 return; |
33 } |
38 } |
34 $this->ftp = new ftp(); |
39 $this->ftp = new ftp(); |
35 |
40 |
36 if ( empty($opt['port']) ) |
41 if ( empty( $opt['port'] ) ) { |
37 $this->options['port'] = 21; |
42 $this->options['port'] = 21; |
38 else |
43 } else { |
39 $this->options['port'] = (int) $opt['port']; |
44 $this->options['port'] = (int) $opt['port']; |
40 |
45 } |
41 if ( empty($opt['hostname']) ) |
46 |
42 $this->errors->add('empty_hostname', __('FTP hostname is required')); |
47 if ( empty( $opt['hostname'] ) ) { |
43 else |
48 $this->errors->add( 'empty_hostname', __( 'FTP hostname is required' ) ); |
|
49 } else { |
44 $this->options['hostname'] = $opt['hostname']; |
50 $this->options['hostname'] = $opt['hostname']; |
|
51 } |
45 |
52 |
46 // Check if the options provided are OK. |
53 // Check if the options provided are OK. |
47 if ( empty ($opt['username']) ) |
54 if ( empty( $opt['username'] ) ) { |
48 $this->errors->add('empty_username', __('FTP username is required')); |
55 $this->errors->add( 'empty_username', __( 'FTP username is required' ) ); |
49 else |
56 } else { |
50 $this->options['username'] = $opt['username']; |
57 $this->options['username'] = $opt['username']; |
51 |
58 } |
52 if ( empty ($opt['password']) ) |
59 |
53 $this->errors->add('empty_password', __('FTP password is required')); |
60 if ( empty( $opt['password'] ) ) { |
54 else |
61 $this->errors->add( 'empty_password', __( 'FTP password is required' ) ); |
|
62 } else { |
55 $this->options['password'] = $opt['password']; |
63 $this->options['password'] = $opt['password']; |
56 } |
64 } |
57 |
65 } |
58 /** |
66 |
59 * |
67 /** |
60 * @return bool |
68 * Connects filesystem. |
|
69 * |
|
70 * @since 2.5.0 |
|
71 * |
|
72 * @return bool True on success, false on failure. |
61 */ |
73 */ |
62 public function connect() { |
74 public function connect() { |
63 if ( ! $this->ftp ) |
75 if ( ! $this->ftp ) { |
64 return false; |
76 return false; |
65 |
77 } |
66 $this->ftp->setTimeout(FS_CONNECT_TIMEOUT); |
78 |
|
79 $this->ftp->setTimeout( FS_CONNECT_TIMEOUT ); |
67 |
80 |
68 if ( ! $this->ftp->SetServer( $this->options['hostname'], $this->options['port'] ) ) { |
81 if ( ! $this->ftp->SetServer( $this->options['hostname'], $this->options['port'] ) ) { |
69 $this->errors->add( 'connect', |
82 $this->errors->add( |
|
83 'connect', |
70 /* translators: %s: hostname:port */ |
84 /* translators: %s: hostname:port */ |
71 sprintf( __( 'Failed to connect to FTP Server %s' ), |
85 sprintf( |
|
86 __( 'Failed to connect to FTP Server %s' ), |
72 $this->options['hostname'] . ':' . $this->options['port'] |
87 $this->options['hostname'] . ':' . $this->options['port'] |
73 ) |
88 ) |
74 ); |
89 ); |
75 return false; |
90 return false; |
76 } |
91 } |
77 |
92 |
78 if ( ! $this->ftp->connect() ) { |
93 if ( ! $this->ftp->connect() ) { |
79 $this->errors->add( 'connect', |
94 $this->errors->add( |
|
95 'connect', |
80 /* translators: %s: hostname:port */ |
96 /* translators: %s: hostname:port */ |
81 sprintf( __( 'Failed to connect to FTP Server %s' ), |
97 sprintf( |
|
98 __( 'Failed to connect to FTP Server %s' ), |
82 $this->options['hostname'] . ':' . $this->options['port'] |
99 $this->options['hostname'] . ':' . $this->options['port'] |
83 ) |
100 ) |
84 ); |
101 ); |
85 return false; |
102 return false; |
86 } |
103 } |
87 |
104 |
88 if ( ! $this->ftp->login( $this->options['username'], $this->options['password'] ) ) { |
105 if ( ! $this->ftp->login( $this->options['username'], $this->options['password'] ) ) { |
89 $this->errors->add( 'auth', |
106 $this->errors->add( |
|
107 'auth', |
90 /* translators: %s: username */ |
108 /* translators: %s: username */ |
91 sprintf( __( 'Username/Password incorrect for %s' ), |
109 sprintf( |
|
110 __( 'Username/Password incorrect for %s' ), |
92 $this->options['username'] |
111 $this->options['username'] |
93 ) |
112 ) |
94 ); |
113 ); |
95 return false; |
114 return false; |
96 } |
115 } |
181 return false; |
209 return false; |
182 } |
210 } |
183 |
211 |
184 fseek( $temphandle, 0 ); // Skip back to the start of the file being written to |
212 fseek( $temphandle, 0 ); // Skip back to the start of the file being written to |
185 |
213 |
186 $ret = $this->ftp->fput($file, $temphandle); |
214 $ret = $this->ftp->fput( $file, $temphandle ); |
187 |
215 |
188 reset_mbstring_encoding(); |
216 reset_mbstring_encoding(); |
189 |
217 |
190 fclose($temphandle); |
218 fclose( $temphandle ); |
191 unlink($temp); |
219 unlink( $temp ); |
192 |
220 |
193 $this->chmod($file, $mode); |
221 $this->chmod( $file, $mode ); |
194 |
222 |
195 return $ret; |
223 return $ret; |
196 } |
224 } |
197 |
225 |
198 /** |
226 /** |
199 * |
227 * Gets the current working directory. |
200 * @return string |
228 * |
|
229 * @since 2.5.0 |
|
230 * |
|
231 * @return string|false The current working directory on success, false on failure. |
201 */ |
232 */ |
202 public function cwd() { |
233 public function cwd() { |
203 $cwd = $this->ftp->pwd(); |
234 $cwd = $this->ftp->pwd(); |
204 if ( $cwd ) |
235 if ( $cwd ) { |
205 $cwd = trailingslashit($cwd); |
236 $cwd = trailingslashit( $cwd ); |
|
237 } |
206 return $cwd; |
238 return $cwd; |
207 } |
239 } |
208 |
240 |
209 /** |
241 /** |
210 * |
242 * Changes current directory. |
211 * @param string $file |
243 * |
212 * @return bool |
244 * @since 2.5.0 |
213 */ |
245 * |
214 public function chdir($file) { |
246 * @param string $dir The new current directory. |
215 return $this->ftp->chdir($file); |
247 * @return bool True on success, false on failure. |
216 } |
248 */ |
217 |
249 public function chdir( $dir ) { |
218 /** |
250 return $this->ftp->chdir( $dir ); |
219 * |
251 } |
220 * @param string $file |
252 |
221 * @param int|bool $mode |
253 /** |
222 * @param bool $recursive |
254 * Changes filesystem permissions. |
223 * @return bool |
255 * |
224 */ |
256 * @since 2.5.0 |
225 public function chmod($file, $mode = false, $recursive = false ) { |
257 * |
|
258 * @param string $file Path to the file. |
|
259 * @param int|false $mode Optional. The permissions as octal number, usually 0644 for files, |
|
260 * 0755 for directories. Default false. |
|
261 * @param bool $recursive Optional. If set to true, changes file group recursively. |
|
262 * Default false. |
|
263 * @return bool True on success, false on failure. |
|
264 */ |
|
265 public function chmod( $file, $mode = false, $recursive = false ) { |
226 if ( ! $mode ) { |
266 if ( ! $mode ) { |
227 if ( $this->is_file($file) ) |
267 if ( $this->is_file( $file ) ) { |
228 $mode = FS_CHMOD_FILE; |
268 $mode = FS_CHMOD_FILE; |
229 elseif ( $this->is_dir($file) ) |
269 } elseif ( $this->is_dir( $file ) ) { |
230 $mode = FS_CHMOD_DIR; |
270 $mode = FS_CHMOD_DIR; |
231 else |
271 } else { |
232 return false; |
272 return false; |
|
273 } |
233 } |
274 } |
234 |
275 |
235 // chmod any sub-objects if recursive. |
276 // chmod any sub-objects if recursive. |
236 if ( $recursive && $this->is_dir($file) ) { |
277 if ( $recursive && $this->is_dir( $file ) ) { |
237 $filelist = $this->dirlist($file); |
278 $filelist = $this->dirlist( $file ); |
238 foreach ( (array)$filelist as $filename => $filemeta ) |
279 foreach ( (array) $filelist as $filename => $filemeta ) { |
239 $this->chmod($file . '/' . $filename, $mode, $recursive); |
280 $this->chmod( $file . '/' . $filename, $mode, $recursive ); |
|
281 } |
240 } |
282 } |
241 |
283 |
242 // chmod the file or directory |
284 // chmod the file or directory |
243 return $this->ftp->chmod($file, $mode); |
285 return $this->ftp->chmod( $file, $mode ); |
244 } |
286 } |
245 |
287 |
246 /** |
288 /** |
247 * |
289 * Gets the file owner. |
248 * @param string $file |
290 * |
249 * @return string |
291 * @since 2.5.0 |
250 */ |
292 * |
251 public function owner($file) { |
293 * @param string $file Path to the file. |
252 $dir = $this->dirlist($file); |
294 * @return string|false Username of the owner on success, false on failure. |
253 return $dir[$file]['owner']; |
295 */ |
254 } |
296 public function owner( $file ) { |
255 |
297 $dir = $this->dirlist( $file ); |
256 /** |
298 return $dir[ $file ]['owner']; |
257 * |
299 } |
258 * @param string $file |
300 |
259 * @return string |
301 /** |
260 */ |
302 * Gets the permissions of the specified file or filepath in their octal format. |
261 public function getchmod($file) { |
303 * |
262 $dir = $this->dirlist($file); |
304 * @since 2.5.0 |
263 return $dir[$file]['permsn']; |
305 * |
264 } |
306 * @param string $file Path to the file. |
265 |
307 * @return string Mode of the file (the last 3 digits). |
266 /** |
308 */ |
267 * |
309 public function getchmod( $file ) { |
268 * @param string $file |
310 $dir = $this->dirlist( $file ); |
269 * @return string |
311 return $dir[ $file ]['permsn']; |
270 */ |
312 } |
271 public function group($file) { |
313 |
272 $dir = $this->dirlist($file); |
314 /** |
273 return $dir[$file]['group']; |
315 * Gets the file's group. |
274 } |
316 * |
275 |
317 * @since 2.5.0 |
276 /** |
318 * |
277 * |
319 * @param string $file Path to the file. |
278 * @param string $source |
320 * @return string|false The group on success, false on failure. |
279 * @param string $destination |
321 */ |
280 * @param bool $overwrite |
322 public function group( $file ) { |
281 * @param int|bool $mode |
323 $dir = $this->dirlist( $file ); |
282 * @return bool |
324 return $dir[ $file ]['group']; |
283 */ |
325 } |
284 public function copy($source, $destination, $overwrite = false, $mode = false) { |
326 |
285 if ( ! $overwrite && $this->exists($destination) ) |
327 /** |
286 return false; |
328 * Copies a file. |
287 |
329 * |
288 $content = $this->get_contents($source); |
330 * @since 2.5.0 |
289 if ( false === $content ) |
331 * |
290 return false; |
332 * @param string $source Path to the source file. |
291 |
333 * @param string $destination Path to the destination file. |
292 return $this->put_contents($destination, $content, $mode); |
334 * @param bool $overwrite Optional. Whether to overwrite the destination file if it exists. |
293 } |
335 * Default false. |
294 |
336 * @param int|false $mode Optional. The permissions as octal number, usually 0644 for files, |
295 /** |
337 * 0755 for dirs. Default false. |
296 * |
338 * @return bool True on success, false on failure. |
297 * @param string $source |
339 */ |
298 * @param string $destination |
340 public function copy( $source, $destination, $overwrite = false, $mode = false ) { |
299 * @param bool $overwrite |
341 if ( ! $overwrite && $this->exists( $destination ) ) { |
300 * @return bool |
342 return false; |
301 */ |
343 } |
302 public function move($source, $destination, $overwrite = false ) { |
344 |
303 return $this->ftp->rename($source, $destination); |
345 $content = $this->get_contents( $source ); |
304 } |
346 if ( false === $content ) { |
305 |
347 return false; |
306 /** |
348 } |
307 * |
349 |
308 * @param string $file |
350 return $this->put_contents( $destination, $content, $mode ); |
309 * @param bool $recursive |
351 } |
310 * @param string $type |
352 |
311 * @return bool |
353 /** |
312 */ |
354 * Moves a file. |
313 public function delete($file, $recursive = false, $type = false) { |
355 * |
314 if ( empty($file) ) |
356 * @since 2.5.0 |
315 return false; |
357 * |
316 if ( 'f' == $type || $this->is_file($file) ) |
358 * @param string $source Path to the source file. |
317 return $this->ftp->delete($file); |
359 * @param string $destination Path to the destination file. |
318 if ( !$recursive ) |
360 * @param bool $overwrite Optional. Whether to overwrite the destination file if it exists. |
319 return $this->ftp->rmdir($file); |
361 * Default false. |
320 |
362 * @return bool True on success, false on failure. |
321 return $this->ftp->mdel($file); |
363 */ |
322 } |
364 public function move( $source, $destination, $overwrite = false ) { |
323 |
365 return $this->ftp->rename( $source, $destination ); |
324 /** |
366 } |
325 * |
367 |
326 * @param string $file |
368 /** |
327 * @return bool |
369 * Deletes a file or directory. |
|
370 * |
|
371 * @since 2.5.0 |
|
372 * |
|
373 * @param string $file Path to the file or directory. |
|
374 * @param bool $recursive Optional. If set to true, changes file group recursively. |
|
375 * Default false. |
|
376 * @param string|false $type Type of resource. 'f' for file, 'd' for directory. |
|
377 * Default false. |
|
378 * @return bool True on success, false on failure. |
|
379 */ |
|
380 public function delete( $file, $recursive = false, $type = false ) { |
|
381 if ( empty( $file ) ) { |
|
382 return false; |
|
383 } |
|
384 if ( 'f' == $type || $this->is_file( $file ) ) { |
|
385 return $this->ftp->delete( $file ); |
|
386 } |
|
387 if ( ! $recursive ) { |
|
388 return $this->ftp->rmdir( $file ); |
|
389 } |
|
390 |
|
391 return $this->ftp->mdel( $file ); |
|
392 } |
|
393 |
|
394 /** |
|
395 * Checks if a file or directory exists. |
|
396 * |
|
397 * @since 2.5.0 |
|
398 * |
|
399 * @param string $file Path to file or directory. |
|
400 * @return bool Whether $file exists or not. |
328 */ |
401 */ |
329 public function exists( $file ) { |
402 public function exists( $file ) { |
330 $list = $this->ftp->nlist( $file ); |
403 $list = $this->ftp->nlist( $file ); |
331 |
404 |
332 if ( empty( $list ) && $this->is_dir( $file ) ) { |
405 if ( empty( $list ) && $this->is_dir( $file ) ) { |
333 return true; // File is an empty directory. |
406 return true; // File is an empty directory. |
334 } |
407 } |
335 |
408 |
336 return !empty( $list ); //empty list = no file, so invert. |
409 return ! empty( $list ); //empty list = no file, so invert. |
337 // Return $this->ftp->is_exists($file); has issues with ABOR+426 responses on the ncFTPd server. |
410 // Return $this->ftp->is_exists($file); has issues with ABOR+426 responses on the ncFTPd server. |
338 } |
411 } |
339 |
412 |
340 /** |
413 /** |
341 * |
414 * Checks if resource is a file. |
342 * @param string $file |
415 * |
343 * @return bool |
416 * @since 2.5.0 |
344 */ |
417 * |
345 public function is_file($file) { |
418 * @param string $file File path. |
346 if ( $this->is_dir($file) ) |
419 * @return bool Whether $file is a file. |
347 return false; |
420 */ |
348 if ( $this->exists($file) ) |
421 public function is_file( $file ) { |
|
422 if ( $this->is_dir( $file ) ) { |
|
423 return false; |
|
424 } |
|
425 if ( $this->exists( $file ) ) { |
349 return true; |
426 return true; |
|
427 } |
350 return false; |
428 return false; |
351 } |
429 } |
352 |
430 |
353 /** |
431 /** |
354 * |
432 * Checks if resource is a directory. |
355 * @param string $path |
433 * |
356 * @return bool |
434 * @since 2.5.0 |
357 */ |
435 * |
358 public function is_dir($path) { |
436 * @param string $path Directory path. |
|
437 * @return bool Whether $path is a directory. |
|
438 */ |
|
439 public function is_dir( $path ) { |
359 $cwd = $this->cwd(); |
440 $cwd = $this->cwd(); |
360 if ( $this->chdir($path) ) { |
441 if ( $this->chdir( $path ) ) { |
361 $this->chdir($cwd); |
442 $this->chdir( $cwd ); |
362 return true; |
443 return true; |
363 } |
444 } |
364 return false; |
445 return false; |
365 } |
446 } |
366 |
447 |
367 /** |
448 /** |
368 * |
449 * Checks if a file is readable. |
369 * @param string $file |
450 * |
370 * @return bool |
451 * @since 2.5.0 |
371 */ |
452 * |
372 public function is_readable($file) { |
453 * @param string $file Path to file. |
|
454 * @return bool Whether $file is readable. |
|
455 */ |
|
456 public function is_readable( $file ) { |
373 return true; |
457 return true; |
374 } |
458 } |
375 |
459 |
376 /** |
460 /** |
377 * |
461 * Checks if a file or directory is writable. |
378 * @param string $file |
462 * |
379 * @return bool |
463 * @since 2.5.0 |
380 */ |
464 * |
381 public function is_writable($file) { |
465 * @param string $file Path to file or directory. |
|
466 * @return bool Whether $file is writable. |
|
467 */ |
|
468 public function is_writable( $file ) { |
382 return true; |
469 return true; |
383 } |
470 } |
384 |
471 |
385 /** |
472 /** |
386 * |
473 * Gets the file's last access time. |
387 * @param string $file |
474 * |
388 * @return bool |
475 * @since 2.5.0 |
389 */ |
476 * |
390 public function atime($file) { |
477 * @param string $file Path to file. |
|
478 * @return int|false Unix timestamp representing last access time, false on failure. |
|
479 */ |
|
480 public function atime( $file ) { |
391 return false; |
481 return false; |
392 } |
482 } |
393 |
483 |
394 /** |
484 /** |
395 * |
485 * Gets the file modification time. |
396 * @param string $file |
486 * |
397 * @return int |
487 * @since 2.5.0 |
398 */ |
488 * |
399 public function mtime($file) { |
489 * @param string $file Path to file. |
400 return $this->ftp->mdtm($file); |
490 * @return int|false Unix timestamp representing modification time, false on failure. |
401 } |
491 */ |
402 |
492 public function mtime( $file ) { |
403 /** |
493 return $this->ftp->mdtm( $file ); |
404 * @param string $file |
494 } |
405 * @return int |
495 |
406 */ |
496 /** |
407 public function size($file) { |
497 * Gets the file size (in bytes). |
408 return $this->ftp->filesize($file); |
498 * |
409 } |
499 * @since 2.5.0 |
410 |
500 * |
411 /** |
501 * @param string $file Path to file. |
412 * |
502 * @return int|false Size of the file in bytes on success, false on failure. |
413 * @param string $file |
503 */ |
414 * @param int $time |
504 public function size( $file ) { |
415 * @param int $atime |
505 return $this->ftp->filesize( $file ); |
416 * @return bool |
506 } |
417 */ |
507 |
418 public function touch($file, $time = 0, $atime = 0 ) { |
508 /** |
|
509 * Sets the access and modification times of a file. |
|
510 * |
|
511 * Note: If $file doesn't exist, it will be created. |
|
512 * |
|
513 * @since 2.5.0 |
|
514 * |
|
515 * @param string $file Path to file. |
|
516 * @param int $time Optional. Modified time to set for file. |
|
517 * Default 0. |
|
518 * @param int $atime Optional. Access time to set for file. |
|
519 * Default 0. |
|
520 * @return bool True on success, false on failure. |
|
521 */ |
|
522 public function touch( $file, $time = 0, $atime = 0 ) { |
419 return false; |
523 return false; |
420 } |
524 } |
421 |
525 |
422 /** |
526 /** |
423 * |
527 * Creates a directory. |
424 * @param string $path |
528 * |
425 * @param mixed $chmod |
529 * @since 2.5.0 |
426 * @param mixed $chown |
530 * |
427 * @param mixed $chgrp |
531 * @param string $path Path for new directory. |
428 * @return bool |
532 * @param int|false $chmod Optional. The permissions as octal number (or false to skip chmod). |
429 */ |
533 * Default false. |
430 public function mkdir($path, $chmod = false, $chown = false, $chgrp = false ) { |
534 * @param string|int $chown Optional. A user name or number (or false to skip chown). |
431 $path = untrailingslashit($path); |
535 * Default false. |
432 if ( empty($path) ) |
536 * @param string|int $chgrp Optional. A group name or number (or false to skip chgrp). |
433 return false; |
537 * Default false. |
434 |
538 * @return bool True on success, false on failure. |
435 if ( ! $this->ftp->mkdir($path) ) |
539 */ |
436 return false; |
540 public function mkdir( $path, $chmod = false, $chown = false, $chgrp = false ) { |
437 if ( ! $chmod ) |
541 $path = untrailingslashit( $path ); |
|
542 if ( empty( $path ) ) { |
|
543 return false; |
|
544 } |
|
545 |
|
546 if ( ! $this->ftp->mkdir( $path ) ) { |
|
547 return false; |
|
548 } |
|
549 if ( ! $chmod ) { |
438 $chmod = FS_CHMOD_DIR; |
550 $chmod = FS_CHMOD_DIR; |
439 $this->chmod($path, $chmod); |
551 } |
|
552 $this->chmod( $path, $chmod ); |
440 return true; |
553 return true; |
441 } |
554 } |
442 |
555 |
443 /** |
556 /** |
444 * |
557 * Deletes a directory. |
445 * @param string $path |
558 * |
446 * @param bool $recursive |
559 * @since 2.5.0 |
447 * @return bool |
560 * |
448 */ |
561 * @param string $path Path to directory. |
449 public function rmdir($path, $recursive = false ) { |
562 * @param bool $recursive Optional. Whether to recursively remove files/directories. |
450 return $this->delete($path, $recursive); |
563 * Default false. |
451 } |
564 * @return bool True on success, false on failure. |
452 |
565 */ |
453 /** |
566 public function rmdir( $path, $recursive = false ) { |
454 * |
567 return $this->delete( $path, $recursive ); |
455 * @param string $path |
568 } |
456 * @param bool $include_hidden |
569 |
457 * @param bool $recursive |
570 /** |
458 * @return bool|array |
571 * Gets details for files in a directory or a specific file. |
459 */ |
572 * |
460 public function dirlist($path = '.', $include_hidden = true, $recursive = false ) { |
573 * @since 2.5.0 |
461 if ( $this->is_file($path) ) { |
574 * |
462 $limit_file = basename($path); |
575 * @param string $path Path to directory or file. |
463 $path = dirname($path) . '/'; |
576 * @param bool $include_hidden Optional. Whether to include details of hidden ("." prefixed) files. |
|
577 * Default true. |
|
578 * @param bool $recursive Optional. Whether to recursively include file details in nested directories. |
|
579 * Default false. |
|
580 * @return array|false { |
|
581 * Array of files. False if unable to list directory contents. |
|
582 * |
|
583 * @type string $name Name of the file or directory. |
|
584 * @type string $perms *nix representation of permissions. |
|
585 * @type int $permsn Octal representation of permissions. |
|
586 * @type string $owner Owner name or ID. |
|
587 * @type int $size Size of file in bytes. |
|
588 * @type int $lastmodunix Last modified unix timestamp. |
|
589 * @type mixed $lastmod Last modified month (3 letter) and day (without leading 0). |
|
590 * @type int $time Last modified time. |
|
591 * @type string $type Type of resource. 'f' for file, 'd' for directory. |
|
592 * @type mixed $files If a directory and $recursive is true, contains another array of files. |
|
593 * } |
|
594 */ |
|
595 public function dirlist( $path = '.', $include_hidden = true, $recursive = false ) { |
|
596 if ( $this->is_file( $path ) ) { |
|
597 $limit_file = basename( $path ); |
|
598 $path = dirname( $path ) . '/'; |
464 } else { |
599 } else { |
465 $limit_file = false; |
600 $limit_file = false; |
466 } |
601 } |
467 |
602 |
468 mbstring_binary_safe_encoding(); |
603 mbstring_binary_safe_encoding(); |
469 |
604 |
470 $list = $this->ftp->dirlist($path); |
605 $list = $this->ftp->dirlist( $path ); |
471 if ( empty( $list ) && ! $this->exists( $path ) ) { |
606 if ( empty( $list ) && ! $this->exists( $path ) ) { |
472 |
607 |
473 reset_mbstring_encoding(); |
608 reset_mbstring_encoding(); |
474 |
609 |
475 return false; |
610 return false; |
476 } |
611 } |
477 |
612 |
478 $ret = array(); |
613 $ret = array(); |
479 foreach ( $list as $struc ) { |
614 foreach ( $list as $struc ) { |
480 |
615 |
481 if ( '.' == $struc['name'] || '..' == $struc['name'] ) |
616 if ( '.' == $struc['name'] || '..' == $struc['name'] ) { |
482 continue; |
617 continue; |
483 |
618 } |
484 if ( ! $include_hidden && '.' == $struc['name'][0] ) |
619 |
|
620 if ( ! $include_hidden && '.' == $struc['name'][0] ) { |
485 continue; |
621 continue; |
486 |
622 } |
487 if ( $limit_file && $struc['name'] != $limit_file ) |
623 |
|
624 if ( $limit_file && $struc['name'] != $limit_file ) { |
488 continue; |
625 continue; |
|
626 } |
489 |
627 |
490 if ( 'd' == $struc['type'] ) { |
628 if ( 'd' == $struc['type'] ) { |
491 if ( $recursive ) |
629 if ( $recursive ) { |
492 $struc['files'] = $this->dirlist($path . '/' . $struc['name'], $include_hidden, $recursive); |
630 $struc['files'] = $this->dirlist( $path . '/' . $struc['name'], $include_hidden, $recursive ); |
493 else |
631 } else { |
494 $struc['files'] = array(); |
632 $struc['files'] = array(); |
|
633 } |
495 } |
634 } |
496 |
635 |
497 // Replace symlinks formatted as "source -> target" with just the source name |
636 // Replace symlinks formatted as "source -> target" with just the source name |
498 if ( $struc['islink'] ) |
637 if ( $struc['islink'] ) { |
499 $struc['name'] = preg_replace( '/(\s*->\s*.*)$/', '', $struc['name'] ); |
638 $struc['name'] = preg_replace( '/(\s*->\s*.*)$/', '', $struc['name'] ); |
|
639 } |
500 |
640 |
501 // Add the Octal representation of the file permissions |
641 // Add the Octal representation of the file permissions |
502 $struc['permsn'] = $this->getnumchmodfromh( $struc['perms'] ); |
642 $struc['permsn'] = $this->getnumchmodfromh( $struc['perms'] ); |
503 |
643 |
504 $ret[ $struc['name'] ] = $struc; |
644 $ret[ $struc['name'] ] = $struc; |