38 return; |
38 return; |
39 } |
39 } |
40 |
40 |
41 // This class uses the timeout on a per-connection basis, others use it on a per-action basis. |
41 // This class uses the timeout on a per-connection basis, others use it on a per-action basis. |
42 if ( ! defined( 'FS_TIMEOUT' ) ) { |
42 if ( ! defined( 'FS_TIMEOUT' ) ) { |
43 define( 'FS_TIMEOUT', 240 ); |
43 define( 'FS_TIMEOUT', 4 * MINUTE_IN_SECONDS ); |
44 } |
44 } |
45 |
45 |
46 if ( empty( $opt['port'] ) ) { |
46 if ( empty( $opt['port'] ) ) { |
47 $this->options['port'] = 21; |
47 $this->options['port'] = 21; |
48 } else { |
48 } else { |
356 |
356 |
357 return $this->put_contents( $destination, $content, $mode ); |
357 return $this->put_contents( $destination, $content, $mode ); |
358 } |
358 } |
359 |
359 |
360 /** |
360 /** |
361 * Moves a file. |
361 * Moves a file or directory. |
362 * |
362 * |
363 * @since 2.5.0 |
363 * After moving files or directories, OPcache will need to be invalidated. |
364 * |
364 * |
365 * @param string $source Path to the source file. |
365 * If moving a directory fails, `copy_dir()` can be used for a recursive copy. |
366 * @param string $destination Path to the destination file. |
366 * |
367 * @param bool $overwrite Optional. Whether to overwrite the destination file if it exists. |
367 * Use `move_dir()` for moving directories with OPcache invalidation and a |
|
368 * fallback to `copy_dir()`. |
|
369 * |
|
370 * @since 2.5.0 |
|
371 * |
|
372 * @param string $source Path to the source file or directory. |
|
373 * @param string $destination Path to the destination file or directory. |
|
374 * @param bool $overwrite Optional. Whether to overwrite the destination if it exists. |
368 * Default false. |
375 * Default false. |
369 * @return bool True on success, false on failure. |
376 * @return bool True on success, false on failure. |
370 */ |
377 */ |
371 public function move( $source, $destination, $overwrite = false ) { |
378 public function move( $source, $destination, $overwrite = false ) { |
372 return ftp_rename( $this->link, $source, $destination ); |
379 return ftp_rename( $this->link, $source, $destination ); |
410 |
417 |
411 /** |
418 /** |
412 * Checks if a file or directory exists. |
419 * Checks if a file or directory exists. |
413 * |
420 * |
414 * @since 2.5.0 |
421 * @since 2.5.0 |
415 * |
422 * @since 6.3.0 Returns false for an empty path. |
416 * @param string $file Path to file or directory. |
423 * |
417 * @return bool Whether $file exists or not. |
424 * @param string $path Path to file or directory. |
418 */ |
425 * @return bool Whether $path exists or not. |
419 public function exists( $file ) { |
426 */ |
420 $list = ftp_nlist( $this->link, $file ); |
427 public function exists( $path ) { |
421 |
428 /* |
422 if ( empty( $list ) && $this->is_dir( $file ) ) { |
429 * Check for empty path. If ftp_nlist() receives an empty path, |
|
430 * it checks the current working directory and may return true. |
|
431 * |
|
432 * See https://core.trac.wordpress.org/ticket/33058. |
|
433 */ |
|
434 if ( '' === $path ) { |
|
435 return false; |
|
436 } |
|
437 |
|
438 $list = ftp_nlist( $this->link, $path ); |
|
439 |
|
440 if ( empty( $list ) && $this->is_dir( $path ) ) { |
423 return true; // File is an empty directory. |
441 return true; // File is an empty directory. |
424 } |
442 } |
425 |
443 |
426 return ! empty( $list ); // Empty list = no file, so invert. |
444 return ! empty( $list ); // Empty list = no file, so invert. |
427 } |
445 } |
513 * |
531 * |
514 * @param string $file Path to file. |
532 * @param string $file Path to file. |
515 * @return int|false Size of the file in bytes on success, false on failure. |
533 * @return int|false Size of the file in bytes on success, false on failure. |
516 */ |
534 */ |
517 public function size( $file ) { |
535 public function size( $file ) { |
518 return ftp_size( $this->link, $file ); |
536 $size = ftp_size( $this->link, $file ); |
|
537 |
|
538 return ( $size > -1 ) ? $size : false; |
519 } |
539 } |
520 |
540 |
521 /** |
541 /** |
522 * Sets the access and modification times of a file. |
542 * Sets the access and modification times of a file. |
523 * |
543 * |
580 return $this->delete( $path, $recursive ); |
600 return $this->delete( $path, $recursive ); |
581 } |
601 } |
582 |
602 |
583 /** |
603 /** |
584 * @param string $line |
604 * @param string $line |
585 * @return array |
605 * @return array { |
|
606 * Array of file information. |
|
607 * |
|
608 * @type string $name Name of the file or directory. |
|
609 * @type string $perms *nix representation of permissions. |
|
610 * @type string $permsn Octal representation of permissions. |
|
611 * @type string|false $number File number as a string, or false if not available. |
|
612 * @type string|false $owner Owner name or ID, or false if not available. |
|
613 * @type string|false $group File permissions group, or false if not available. |
|
614 * @type string|false $size Size of file in bytes as a string, or false if not available. |
|
615 * @type string|false $lastmodunix Last modified unix timestamp as a string, or false if not available. |
|
616 * @type string|false $lastmod Last modified month (3 letters) and day (without leading 0), or |
|
617 * false if not available. |
|
618 * @type string|false $time Last modified time, or false if not available. |
|
619 * @type string $type Type of resource. 'f' for file, 'd' for directory, 'l' for link. |
|
620 * @type array|false $files If a directory and `$recursive` is true, contains another array of files. |
|
621 * False if unable to list directory contents. |
|
622 * } |
586 */ |
623 */ |
587 public function parselisting( $line ) { |
624 public function parselisting( $line ) { |
588 static $is_windows = null; |
625 static $is_windows = null; |
589 |
626 |
590 if ( is_null( $is_windows ) ) { |
627 if ( is_null( $is_windows ) ) { |
690 * @param bool $include_hidden Optional. Whether to include details of hidden ("." prefixed) files. |
727 * @param bool $include_hidden Optional. Whether to include details of hidden ("." prefixed) files. |
691 * Default true. |
728 * Default true. |
692 * @param bool $recursive Optional. Whether to recursively include file details in nested directories. |
729 * @param bool $recursive Optional. Whether to recursively include file details in nested directories. |
693 * Default false. |
730 * Default false. |
694 * @return array|false { |
731 * @return array|false { |
695 * Array of files. False if unable to list directory contents. |
732 * Array of arrays containing file information. False if unable to list directory contents. |
696 * |
733 * |
697 * @type string $name Name of the file or directory. |
734 * @type array ...$0 { |
698 * @type string $perms *nix representation of permissions. |
735 * Array of file information. Note that some elements may not be available on all filesystems. |
699 * @type string $permsn Octal representation of permissions. |
736 * |
700 * @type string $owner Owner name or ID. |
737 * @type string $name Name of the file or directory. |
701 * @type int $size Size of file in bytes. |
738 * @type string $perms *nix representation of permissions. |
702 * @type int $lastmodunix Last modified unix timestamp. |
739 * @type string $permsn Octal representation of permissions. |
703 * @type mixed $lastmod Last modified month (3 letter) and day (without leading 0). |
740 * @type int|string|false $number File number. May be a numeric string. False if not available. |
704 * @type int $time Last modified time. |
741 * @type string|false $owner Owner name or ID, or false if not available. |
705 * @type string $type Type of resource. 'f' for file, 'd' for directory. |
742 * @type string|false $group File permissions group, or false if not available. |
706 * @type mixed $files If a directory and `$recursive` is true, contains another array of files. |
743 * @type int|string|false $size Size of file in bytes. May be a numeric string. |
|
744 * False if not available. |
|
745 * @type int|string|false $lastmodunix Last modified unix timestamp. May be a numeric string. |
|
746 * False if not available. |
|
747 * @type string|false $lastmod Last modified month (3 letters) and day (without leading 0), or |
|
748 * false if not available. |
|
749 * @type string|false $time Last modified time, or false if not available. |
|
750 * @type string $type Type of resource. 'f' for file, 'd' for directory, 'l' for link. |
|
751 * @type array|false $files If a directory and `$recursive` is true, contains another array of |
|
752 * files. False if unable to list directory contents. |
|
753 * } |
707 * } |
754 * } |
708 */ |
755 */ |
709 public function dirlist( $path = '.', $include_hidden = true, $recursive = false ) { |
756 public function dirlist( $path = '.', $include_hidden = true, $recursive = false ) { |
710 if ( $this->is_file( $path ) ) { |
757 if ( $this->is_file( $path ) ) { |
711 $limit_file = basename( $path ); |
758 $limit_file = basename( $path ); |
750 } |
797 } |
751 |
798 |
752 $dirlist[ $entry['name'] ] = $entry; |
799 $dirlist[ $entry['name'] ] = $entry; |
753 } |
800 } |
754 |
801 |
755 $ret = array(); |
802 $path = trailingslashit( $path ); |
|
803 $ret = array(); |
756 |
804 |
757 foreach ( (array) $dirlist as $struc ) { |
805 foreach ( (array) $dirlist as $struc ) { |
758 if ( 'd' === $struc['type'] ) { |
806 if ( 'd' === $struc['type'] ) { |
759 if ( $recursive ) { |
807 if ( $recursive ) { |
760 $struc['files'] = $this->dirlist( $path . '/' . $struc['name'], $include_hidden, $recursive ); |
808 $struc['files'] = $this->dirlist( $path . $struc['name'], $include_hidden, $recursive ); |
761 } else { |
809 } else { |
762 $struc['files'] = array(); |
810 $struc['files'] = array(); |
763 } |
811 } |
764 } |
812 } |
765 |
813 |