wp/wp-admin/includes/class-wp-filesystem-ssh2.php
changeset 21 48c4eec2b7e6
parent 19 3d72ae0968f4
equal deleted inserted replaced
20:7b1b88e27a20 21:48c4eec2b7e6
     2 /**
     2 /**
     3  * WordPress Filesystem Class for implementing SSH2
     3  * WordPress Filesystem Class for implementing SSH2
     4  *
     4  *
     5  * To use this class you must follow these steps for PHP 5.2.6+
     5  * To use this class you must follow these steps for PHP 5.2.6+
     6  *
     6  *
     7  * @contrib http://kevin.vanzonneveld.net/techblog/article/make_ssh_connections_with_php/ - Installation Notes
     7  * {@link http://kevin.vanzonneveld.net/techblog/article/make_ssh_connections_with_php/ - Installation Notes}
     8  *
     8  *
     9  * Compile libssh2 (Note: Only 0.14 is officaly working with PHP 5.2.6+ right now, But many users have found the latest versions work)
     9  * Compile libssh2 (Note: Only 0.14 is officially working with PHP 5.2.6+ right now, But many users have found the latest versions work)
    10  *
    10  *
    11  * cd /usr/src
    11  * cd /usr/src
    12  * wget https://www.libssh2.org/download/libssh2-0.14.tar.gz
    12  * wget https://www.libssh2.org/download/libssh2-0.14.tar.gz
    13  * tar -zxvf libssh2-0.14.tar.gz
    13  * tar -zxvf libssh2-0.14.tar.gz
    14  * cd libssh2-0.14/
    14  * cd libssh2-0.14/
   101 
   101 
   102 		if ( empty( $opt['password'] ) ) {
   102 		if ( empty( $opt['password'] ) ) {
   103 			// Password can be blank if we are using keys.
   103 			// Password can be blank if we are using keys.
   104 			if ( ! $this->keys ) {
   104 			if ( ! $this->keys ) {
   105 				$this->errors->add( 'empty_password', __( 'SSH2 password is required' ) );
   105 				$this->errors->add( 'empty_password', __( 'SSH2 password is required' ) );
       
   106 			} else {
       
   107 				$this->options['password'] = null;
   106 			}
   108 			}
   107 		} else {
   109 		} else {
   108 			$this->options['password'] = $opt['password'];
   110 			$this->options['password'] = $opt['password'];
   109 		}
   111 		}
   110 	}
   112 	}
   494 
   496 
   495 		return $this->put_contents( $destination, $content, $mode );
   497 		return $this->put_contents( $destination, $content, $mode );
   496 	}
   498 	}
   497 
   499 
   498 	/**
   500 	/**
   499 	 * Moves a file.
   501 	 * Moves a file or directory.
   500 	 *
   502 	 *
   501 	 * @since 2.7.0
   503 	 * After moving files or directories, OPcache will need to be invalidated.
   502 	 *
   504 	 *
   503 	 * @param string $source      Path to the source file.
   505 	 * If moving a directory fails, `copy_dir()` can be used for a recursive copy.
   504 	 * @param string $destination Path to the destination file.
   506 	 *
   505 	 * @param bool   $overwrite   Optional. Whether to overwrite the destination file if it exists.
   507 	 * Use `move_dir()` for moving directories with OPcache invalidation and a
       
   508 	 * fallback to `copy_dir()`.
       
   509 	 *
       
   510 	 * @since 2.7.0
       
   511 	 *
       
   512 	 * @param string $source      Path to the source file or directory.
       
   513 	 * @param string $destination Path to the destination file or directory.
       
   514 	 * @param bool   $overwrite   Optional. Whether to overwrite the destination if it exists.
   506 	 *                            Default false.
   515 	 *                            Default false.
   507 	 * @return bool True on success, false on failure.
   516 	 * @return bool True on success, false on failure.
   508 	 */
   517 	 */
   509 	public function move( $source, $destination, $overwrite = false ) {
   518 	public function move( $source, $destination, $overwrite = false ) {
   510 		if ( $this->exists( $destination ) ) {
   519 		if ( $this->exists( $destination ) ) {
   511 			if ( $overwrite ) {
   520 			if ( $overwrite ) {
   512 				// We need to remove the destination file before we can rename the source.
   521 				// We need to remove the destination before we can rename the source.
   513 				$this->delete( $destination, false, 'f' );
   522 				$this->delete( $destination, false, 'f' );
   514 			} else {
   523 			} else {
   515 				// If we're not overwriting, the rename will fail, so return early.
   524 				// If we're not overwriting, the rename will fail, so return early.
   516 				return false;
   525 				return false;
   517 			}
   526 			}
   555 	/**
   564 	/**
   556 	 * Checks if a file or directory exists.
   565 	 * Checks if a file or directory exists.
   557 	 *
   566 	 *
   558 	 * @since 2.7.0
   567 	 * @since 2.7.0
   559 	 *
   568 	 *
   560 	 * @param string $file Path to file or directory.
   569 	 * @param string $path Path to file or directory.
   561 	 * @return bool Whether $file exists or not.
   570 	 * @return bool Whether $path exists or not.
   562 	 */
   571 	 */
   563 	public function exists( $file ) {
   572 	public function exists( $path ) {
   564 		return file_exists( $this->sftp_path( $file ) );
   573 		return file_exists( $this->sftp_path( $path ) );
   565 	}
   574 	}
   566 
   575 
   567 	/**
   576 	/**
   568 	 * Checks if resource is a file.
   577 	 * Checks if resource is a file.
   569 	 *
   578 	 *
   603 	/**
   612 	/**
   604 	 * Checks if a file or directory is writable.
   613 	 * Checks if a file or directory is writable.
   605 	 *
   614 	 *
   606 	 * @since 2.7.0
   615 	 * @since 2.7.0
   607 	 *
   616 	 *
   608 	 * @param string $file Path to file or directory.
   617 	 * @param string $path Path to file or directory.
   609 	 * @return bool Whether $file is writable.
   618 	 * @return bool Whether $path is writable.
   610 	 */
   619 	 */
   611 	public function is_writable( $file ) {
   620 	public function is_writable( $path ) {
   612 		// PHP will base its writable checks on system_user === file_owner, not ssh_user === file_owner.
   621 		// PHP will base its writable checks on system_user === file_owner, not ssh_user === file_owner.
   613 		return true;
   622 		return true;
   614 	}
   623 	}
   615 
   624 
   616 	/**
   625 	/**
   732 	 * @param bool   $include_hidden Optional. Whether to include details of hidden ("." prefixed) files.
   741 	 * @param bool   $include_hidden Optional. Whether to include details of hidden ("." prefixed) files.
   733 	 *                               Default true.
   742 	 *                               Default true.
   734 	 * @param bool   $recursive      Optional. Whether to recursively include file details in nested directories.
   743 	 * @param bool   $recursive      Optional. Whether to recursively include file details in nested directories.
   735 	 *                               Default false.
   744 	 *                               Default false.
   736 	 * @return array|false {
   745 	 * @return array|false {
   737 	 *     Array of files. False if unable to list directory contents.
   746 	 *     Array of arrays containing file information. False if unable to list directory contents.
   738 	 *
   747 	 *
   739 	 *     @type string $name        Name of the file or directory.
   748 	 *     @type array ...$0 {
   740 	 *     @type string $perms       *nix representation of permissions.
   749 	 *         Array of file information. Note that some elements may not be available on all filesystems.
   741 	 *     @type string $permsn      Octal representation of permissions.
   750 	 *
   742 	 *     @type string $owner       Owner name or ID.
   751 	 *         @type string           $name        Name of the file or directory.
   743 	 *     @type int    $size        Size of file in bytes.
   752 	 *         @type string           $perms       *nix representation of permissions.
   744 	 *     @type int    $lastmodunix Last modified unix timestamp.
   753 	 *         @type string           $permsn      Octal representation of permissions.
   745 	 *     @type mixed  $lastmod     Last modified month (3 letter) and day (without leading 0).
   754 	 *         @type false            $number      File number. Always false in this context.
   746 	 *     @type int    $time        Last modified time.
   755 	 *         @type string|false     $owner       Owner name or ID, or false if not available.
   747 	 *     @type string $type        Type of resource. 'f' for file, 'd' for directory.
   756 	 *         @type string|false     $group       File permissions group, or false if not available.
   748 	 *     @type mixed  $files       If a directory and `$recursive` is true, contains another array of files.
   757 	 *         @type int|string|false $size        Size of file in bytes. May be a numeric string.
       
   758 	 *                                             False if not available.
       
   759 	 *         @type int|string|false $lastmodunix Last modified unix timestamp. May be a numeric string.
       
   760 	 *                                             False if not available.
       
   761 	 *         @type string|false     $lastmod     Last modified month (3 letters) and day (without leading 0), or
       
   762 	 *                                             false if not available.
       
   763 	 *         @type string|false     $time        Last modified time, or false if not available.
       
   764 	 *         @type string           $type        Type of resource. 'f' for file, 'd' for directory, 'l' for link.
       
   765 	 *         @type array|false      $files       If a directory and `$recursive` is true, contains another array of
       
   766 	 *                                             files. False if unable to list directory contents.
       
   767 	 *     }
   749 	 * }
   768 	 * }
   750 	 */
   769 	 */
   751 	public function dirlist( $path, $include_hidden = true, $recursive = false ) {
   770 	public function dirlist( $path, $include_hidden = true, $recursive = false ) {
   752 		if ( $this->is_file( $path ) ) {
   771 		if ( $this->is_file( $path ) ) {
   753 			$limit_file = basename( $path );
   772 			$limit_file = basename( $path );
   765 
   784 
   766 		if ( ! $dir ) {
   785 		if ( ! $dir ) {
   767 			return false;
   786 			return false;
   768 		}
   787 		}
   769 
   788 
       
   789 		$path = trailingslashit( $path );
       
   790 
   770 		while ( false !== ( $entry = $dir->read() ) ) {
   791 		while ( false !== ( $entry = $dir->read() ) ) {
   771 			$struc         = array();
   792 			$struc         = array();
   772 			$struc['name'] = $entry;
   793 			$struc['name'] = $entry;
   773 
   794 
   774 			if ( '.' === $struc['name'] || '..' === $struc['name'] ) {
   795 			if ( '.' === $struc['name'] || '..' === $struc['name'] ) {
   781 
   802 
   782 			if ( $limit_file && $struc['name'] !== $limit_file ) {
   803 			if ( $limit_file && $struc['name'] !== $limit_file ) {
   783 				continue;
   804 				continue;
   784 			}
   805 			}
   785 
   806 
   786 			$struc['perms']       = $this->gethchmod( $path . '/' . $entry );
   807 			$struc['perms']       = $this->gethchmod( $path . $entry );
   787 			$struc['permsn']      = $this->getnumchmodfromh( $struc['perms'] );
   808 			$struc['permsn']      = $this->getnumchmodfromh( $struc['perms'] );
   788 			$struc['number']      = false;
   809 			$struc['number']      = false;
   789 			$struc['owner']       = $this->owner( $path . '/' . $entry );
   810 			$struc['owner']       = $this->owner( $path . $entry );
   790 			$struc['group']       = $this->group( $path . '/' . $entry );
   811 			$struc['group']       = $this->group( $path . $entry );
   791 			$struc['size']        = $this->size( $path . '/' . $entry );
   812 			$struc['size']        = $this->size( $path . $entry );
   792 			$struc['lastmodunix'] = $this->mtime( $path . '/' . $entry );
   813 			$struc['lastmodunix'] = $this->mtime( $path . $entry );
   793 			$struc['lastmod']     = gmdate( 'M j', $struc['lastmodunix'] );
   814 			$struc['lastmod']     = gmdate( 'M j', $struc['lastmodunix'] );
   794 			$struc['time']        = gmdate( 'h:i:s', $struc['lastmodunix'] );
   815 			$struc['time']        = gmdate( 'h:i:s', $struc['lastmodunix'] );
   795 			$struc['type']        = $this->is_dir( $path . '/' . $entry ) ? 'd' : 'f';
   816 			$struc['type']        = $this->is_dir( $path . $entry ) ? 'd' : 'f';
   796 
   817 
   797 			if ( 'd' === $struc['type'] ) {
   818 			if ( 'd' === $struc['type'] ) {
   798 				if ( $recursive ) {
   819 				if ( $recursive ) {
   799 					$struc['files'] = $this->dirlist( $path . '/' . $struc['name'], $include_hidden, $recursive );
   820 					$struc['files'] = $this->dirlist( $path . $struc['name'], $include_hidden, $recursive );
   800 				} else {
   821 				} else {
   801 					$struc['files'] = array();
   822 					$struc['files'] = array();
   802 				}
   823 				}
   803 			}
   824 			}
   804 
   825