wp/wp-admin/includes/class-wp-filesystem-ftpext.php
changeset 5 5e2f62d02dcd
parent 0 d970ebf37754
child 7 cf61fcea0001
equal deleted inserted replaced
4:346c88efed21 5:5e2f62d02dcd
     7  */
     7  */
     8 
     8 
     9 /**
     9 /**
    10  * WordPress Filesystem Class for implementing FTP.
    10  * WordPress Filesystem Class for implementing FTP.
    11  *
    11  *
    12  * @since 2.5
    12  * @since 2.5.0
    13  * @package WordPress
    13  * @package WordPress
    14  * @subpackage Filesystem
    14  * @subpackage Filesystem
    15  * @uses WP_Filesystem_Base Extends class
    15  * @uses WP_Filesystem_Base Extends class
    16  */
    16  */
    17 class WP_Filesystem_FTPext extends WP_Filesystem_Base {
    17 class WP_Filesystem_FTPext extends WP_Filesystem_Base {
    18 	var $link;
    18 	public $link;
    19 	var $errors = null;
    19 
    20 	var $options = array();
    20 	public function __construct($opt='') {
    21 
       
    22 	function __construct($opt='') {
       
    23 		$this->method = 'ftpext';
    21 		$this->method = 'ftpext';
    24 		$this->errors = new WP_Error();
    22 		$this->errors = new WP_Error();
    25 
    23 
    26 		// Check if possible to use ftp functions.
    24 		// Check if possible to use ftp functions.
    27 		if ( ! extension_loaded('ftp') ) {
    25 		if ( ! extension_loaded('ftp') ) {
    28 			$this->errors->add('no_ftp_ext', __('The ftp PHP extension is not available'));
    26 			$this->errors->add('no_ftp_ext', __('The ftp PHP extension is not available'));
    29 			return false;
    27 			return;
    30 		}
    28 		}
    31 
    29 
    32 		// This Class uses the timeout on a per-connection basis, Others use it on a per-action basis.
    30 		// This Class uses the timeout on a per-connection basis, Others use it on a per-action basis.
    33 
    31 
    34 		if ( ! defined('FS_TIMEOUT') )
    32 		if ( ! defined('FS_TIMEOUT') )
    41 
    39 
    42 		if ( empty($opt['hostname']) )
    40 		if ( empty($opt['hostname']) )
    43 			$this->errors->add('empty_hostname', __('FTP hostname is required'));
    41 			$this->errors->add('empty_hostname', __('FTP hostname is required'));
    44 		else
    42 		else
    45 			$this->options['hostname'] = $opt['hostname'];
    43 			$this->options['hostname'] = $opt['hostname'];
    46 
       
    47 		if ( ! empty($opt['base']) )
       
    48 			$this->wp_base = $opt['base'];
       
    49 
    44 
    50 		// Check if the options provided are OK.
    45 		// Check if the options provided are OK.
    51 		if ( empty($opt['username']) )
    46 		if ( empty($opt['username']) )
    52 			$this->errors->add('empty_username', __('FTP username is required'));
    47 			$this->errors->add('empty_username', __('FTP username is required'));
    53 		else
    48 		else
    61 		$this->options['ssl'] = false;
    56 		$this->options['ssl'] = false;
    62 		if ( isset($opt['connection_type']) && 'ftps' == $opt['connection_type'] )
    57 		if ( isset($opt['connection_type']) && 'ftps' == $opt['connection_type'] )
    63 			$this->options['ssl'] = true;
    58 			$this->options['ssl'] = true;
    64 	}
    59 	}
    65 
    60 
    66 	function connect() {
    61 	public function connect() {
    67 		if ( isset($this->options['ssl']) && $this->options['ssl'] && function_exists('ftp_ssl_connect') )
    62 		if ( isset($this->options['ssl']) && $this->options['ssl'] && function_exists('ftp_ssl_connect') )
    68 			$this->link = @ftp_ssl_connect($this->options['hostname'], $this->options['port'], FS_CONNECT_TIMEOUT);
    63 			$this->link = @ftp_ssl_connect($this->options['hostname'], $this->options['port'], FS_CONNECT_TIMEOUT);
    69 		else
    64 		else
    70 			$this->link = @ftp_connect($this->options['hostname'], $this->options['port'], FS_CONNECT_TIMEOUT);
    65 			$this->link = @ftp_connect($this->options['hostname'], $this->options['port'], FS_CONNECT_TIMEOUT);
    71 
    66 
    85 			@ftp_set_option($this->link, FTP_TIMEOUT_SEC, FS_TIMEOUT);
    80 			@ftp_set_option($this->link, FTP_TIMEOUT_SEC, FS_TIMEOUT);
    86 
    81 
    87 		return true;
    82 		return true;
    88 	}
    83 	}
    89 
    84 
    90 	function get_contents( $file ) {
    85 	/**
       
    86 	 * @param string $file
       
    87 	 * @return false|string
       
    88 	 */
       
    89 	public function get_contents( $file ) {
    91 		$tempfile = wp_tempnam($file);
    90 		$tempfile = wp_tempnam($file);
    92 		$temp = fopen($tempfile, 'w+');
    91 		$temp = fopen($tempfile, 'w+');
    93 
    92 
    94 		if ( ! $temp )
    93 		if ( ! $temp )
    95 			return false;
    94 			return false;
   106 		fclose($temp);
   105 		fclose($temp);
   107 		unlink($tempfile);
   106 		unlink($tempfile);
   108 		return $contents;
   107 		return $contents;
   109 	}
   108 	}
   110 
   109 
   111 	function get_contents_array($file) {
   110 	/**
       
   111 	 * @param string $file
       
   112 	 * @return array
       
   113 	 */
       
   114 	public function get_contents_array($file) {
   112 		return explode("\n", $this->get_contents($file));
   115 		return explode("\n", $this->get_contents($file));
   113 	}
   116 	}
   114 
   117 
   115 	function put_contents($file, $contents, $mode = false ) {
   118 	/**
       
   119 	 * @param string $file
       
   120 	 * @param string $contents
       
   121 	 * @param bool|int $mode
       
   122 	 * @return bool
       
   123 	 */
       
   124 	public function put_contents($file, $contents, $mode = false ) {
   116 		$tempfile = wp_tempnam($file);
   125 		$tempfile = wp_tempnam($file);
   117 		$temp = fopen( $tempfile, 'wb+' );
   126 		$temp = fopen( $tempfile, 'wb+' );
   118 		if ( ! $temp )
   127 		if ( ! $temp )
   119 			return false;
   128 			return false;
   120 
   129 
   141 		$this->chmod($file, $mode);
   150 		$this->chmod($file, $mode);
   142 
   151 
   143 		return $ret;
   152 		return $ret;
   144 	}
   153 	}
   145 
   154 
   146 	function cwd() {
   155 	/**
       
   156 	 * @return string
       
   157 	 */
       
   158 	public function cwd() {
   147 		$cwd = @ftp_pwd($this->link);
   159 		$cwd = @ftp_pwd($this->link);
   148 		if ( $cwd )
   160 		if ( $cwd )
   149 			$cwd = trailingslashit($cwd);
   161 			$cwd = trailingslashit($cwd);
   150 		return $cwd;
   162 		return $cwd;
   151 	}
   163 	}
   152 
   164 
   153 	function chdir($dir) {
   165 	/**
       
   166 	 * @param string $dir
       
   167 	 * @return bool
       
   168 	 */
       
   169 	public function chdir($dir) {
   154 		return @ftp_chdir($this->link, $dir);
   170 		return @ftp_chdir($this->link, $dir);
   155 	}
   171 	}
   156 
   172 
   157 	function chgrp($file, $group, $recursive = false ) {
   173 	/**
   158 		return false;
   174 	 * @param string $file
   159 	}
   175 	 * @param int $mode
   160 
   176 	 * @param bool $recursive
   161 	function chmod($file, $mode = false, $recursive = false) {
   177 	 * @return bool
       
   178 	 */
       
   179 	public function chmod($file, $mode = false, $recursive = false) {
   162 		if ( ! $mode ) {
   180 		if ( ! $mode ) {
   163 			if ( $this->is_file($file) )
   181 			if ( $this->is_file($file) )
   164 				$mode = FS_CHMOD_FILE;
   182 				$mode = FS_CHMOD_FILE;
   165 			elseif ( $this->is_dir($file) )
   183 			elseif ( $this->is_dir($file) )
   166 				$mode = FS_CHMOD_DIR;
   184 				$mode = FS_CHMOD_DIR;
   179 		if ( ! function_exists('ftp_chmod') )
   197 		if ( ! function_exists('ftp_chmod') )
   180 			return (bool)@ftp_site($this->link, sprintf('CHMOD %o %s', $mode, $file));
   198 			return (bool)@ftp_site($this->link, sprintf('CHMOD %o %s', $mode, $file));
   181 		return (bool)@ftp_chmod($this->link, $mode, $file);
   199 		return (bool)@ftp_chmod($this->link, $mode, $file);
   182 	}
   200 	}
   183 
   201 
   184 	function owner($file) {
   202 	/**
       
   203 	 * @param string $file
       
   204 	 * @return string
       
   205 	 */
       
   206 	public function owner($file) {
   185 		$dir = $this->dirlist($file);
   207 		$dir = $this->dirlist($file);
   186 		return $dir[$file]['owner'];
   208 		return $dir[$file]['owner'];
   187 	}
   209 	}
   188 
   210 	/**
   189 	function getchmod($file) {
   211 	 * @param string $file
       
   212 	 * @return string
       
   213 	 */
       
   214 	public function getchmod($file) {
   190 		$dir = $this->dirlist($file);
   215 		$dir = $this->dirlist($file);
   191 		return $dir[$file]['permsn'];
   216 		return $dir[$file]['permsn'];
   192 	}
   217 	}
   193 
   218 	/**
   194 	function group($file) {
   219 	 * @param string $file
       
   220 	 * @return string
       
   221 	 */
       
   222 	public function group($file) {
   195 		$dir = $this->dirlist($file);
   223 		$dir = $this->dirlist($file);
   196 		return $dir[$file]['group'];
   224 		return $dir[$file]['group'];
   197 	}
   225 	}
   198 
   226 
   199 	function copy($source, $destination, $overwrite = false, $mode = false) {
   227 	/**
       
   228 	 *
       
   229 	 * @param string $source
       
   230 	 * @param string $destination
       
   231 	 * @param bool   $overwrite
       
   232 	 * @param string|bool $mode
       
   233 	 * @return bool
       
   234 	 */
       
   235 	public function copy($source, $destination, $overwrite = false, $mode = false) {
   200 		if ( ! $overwrite && $this->exists($destination) )
   236 		if ( ! $overwrite && $this->exists($destination) )
   201 			return false;
   237 			return false;
   202 		$content = $this->get_contents($source);
   238 		$content = $this->get_contents($source);
   203 		if ( false === $content )
   239 		if ( false === $content )
   204 			return false;
   240 			return false;
   205 		return $this->put_contents($destination, $content, $mode);
   241 		return $this->put_contents($destination, $content, $mode);
   206 	}
   242 	}
   207 
   243 	/**
   208 	function move($source, $destination, $overwrite = false) {
   244 	 * @param string $source
       
   245 	 * @param string $destination
       
   246 	 * @param bool $overwrite
       
   247 	 * @return bool
       
   248 	 */
       
   249 	public function move($source, $destination, $overwrite = false) {
   209 		return ftp_rename($this->link, $source, $destination);
   250 		return ftp_rename($this->link, $source, $destination);
   210 	}
   251 	}
   211 
   252 	/**
   212 	function delete($file, $recursive = false, $type = false) {
   253 	 * @param string $file
       
   254 	 * @param bool $recursive
       
   255 	 * @param string $type
       
   256 	 * @return bool
       
   257 	 */
       
   258 	public function delete($file, $recursive = false, $type = false) {
   213 		if ( empty($file) )
   259 		if ( empty($file) )
   214 			return false;
   260 			return false;
   215 		if ( 'f' == $type || $this->is_file($file) )
   261 		if ( 'f' == $type || $this->is_file($file) )
   216 			return @ftp_delete($this->link, $file);
   262 			return @ftp_delete($this->link, $file);
   217 		if ( !$recursive )
   263 		if ( !$recursive )
   221 		if ( !empty($filelist) )
   267 		if ( !empty($filelist) )
   222 			foreach ( $filelist as $delete_file )
   268 			foreach ( $filelist as $delete_file )
   223 				$this->delete( trailingslashit($file) . $delete_file['name'], $recursive, $delete_file['type'] );
   269 				$this->delete( trailingslashit($file) . $delete_file['name'], $recursive, $delete_file['type'] );
   224 		return @ftp_rmdir($this->link, $file);
   270 		return @ftp_rmdir($this->link, $file);
   225 	}
   271 	}
   226 
   272 	/**
   227 	function exists($file) {
   273 	 * @param string $file
       
   274 	 * @return bool
       
   275 	 */
       
   276 	public function exists($file) {
   228 		$list = @ftp_nlist($this->link, $file);
   277 		$list = @ftp_nlist($this->link, $file);
       
   278 
       
   279 		if ( empty( $list ) && $this->is_dir( $file ) ) {
       
   280 			return true; // File is an empty directory.
       
   281 		}
       
   282 
   229 		return !empty($list); //empty list = no file, so invert.
   283 		return !empty($list); //empty list = no file, so invert.
   230 	}
   284 	}
   231 
   285 	/**
   232 	function is_file($file) {
   286 	 * @param string $file
       
   287 	 * @return bool
       
   288 	 */
       
   289 	public function is_file($file) {
   233 		return $this->exists($file) && !$this->is_dir($file);
   290 		return $this->exists($file) && !$this->is_dir($file);
   234 	}
   291 	}
   235 
   292 	/**
   236 	function is_dir($path) {
   293 	 * @param string $path
       
   294 	 * @return bool
       
   295 	 */
       
   296 	public function is_dir($path) {
   237 		$cwd = $this->cwd();
   297 		$cwd = $this->cwd();
   238 		$result = @ftp_chdir($this->link, trailingslashit($path) );
   298 		$result = @ftp_chdir($this->link, trailingslashit($path) );
   239 		if ( $result && $path == $this->cwd() || $this->cwd() != $cwd ) {
   299 		if ( $result && $path == $this->cwd() || $this->cwd() != $cwd ) {
   240 			@ftp_chdir($this->link, $cwd);
   300 			@ftp_chdir($this->link, $cwd);
   241 			return true;
   301 			return true;
   242 		}
   302 		}
   243 		return false;
   303 		return false;
   244 	}
   304 	}
   245 
   305 
   246 	function is_readable($file) {
   306 	/**
       
   307 	 * @param string $file
       
   308 	 * @return bool
       
   309 	 */
       
   310 	public function is_readable($file) {
   247 		return true;
   311 		return true;
   248 	}
   312 	}
   249 
   313 	/**
   250 	function is_writable($file) {
   314 	 * @param string $file
       
   315 	 * @return bool
       
   316 	 */
       
   317 	public function is_writable($file) {
   251 		return true;
   318 		return true;
   252 	}
   319 	}
   253 
   320 	/**
   254 	function atime($file) {
   321 	 * @param string $file
       
   322 	 * @return bool
       
   323 	 */
       
   324 	public function atime($file) {
   255 		return false;
   325 		return false;
   256 	}
   326 	}
   257 
   327 	/**
   258 	function mtime($file) {
   328 	 * @param string $file
       
   329 	 * @return int
       
   330 	 */
       
   331 	public function mtime($file) {
   259 		return ftp_mdtm($this->link, $file);
   332 		return ftp_mdtm($this->link, $file);
   260 	}
   333 	}
   261 
   334 	/**
   262 	function size($file) {
   335 	 * @param string $file
       
   336 	 * @return int
       
   337 	 */
       
   338 	public function size($file) {
   263 		return ftp_size($this->link, $file);
   339 		return ftp_size($this->link, $file);
   264 	}
   340 	}
   265 
   341 	/**
   266 	function touch($file, $time = 0, $atime = 0) {
   342 	 * @param string $file
       
   343 	 * @return bool
       
   344 	 */
       
   345 	public function touch($file, $time = 0, $atime = 0) {
   267 		return false;
   346 		return false;
   268 	}
   347 	}
   269 
   348 
   270 	function mkdir($path, $chmod = false, $chown = false, $chgrp = false) {
   349 	/**
       
   350 	 * @param string $path
       
   351 	 * @param mixed $chmod
       
   352 	 * @param mixed $chown
       
   353 	 * @param mixed $chgrp
       
   354 	 * @return bool
       
   355 	 */
       
   356 	public function mkdir($path, $chmod = false, $chown = false, $chgrp = false) {
   271 		$path = untrailingslashit($path);
   357 		$path = untrailingslashit($path);
   272 		if ( empty($path) )
   358 		if ( empty($path) )
   273 			return false;
   359 			return false;
   274 
   360 
   275 		if ( !@ftp_mkdir($this->link, $path) )
   361 		if ( !@ftp_mkdir($this->link, $path) )
   276 			return false;
   362 			return false;
   277 		$this->chmod($path, $chmod);
   363 		$this->chmod($path, $chmod);
   278 		if ( $chown )
       
   279 			$this->chown($path, $chown);
       
   280 		if ( $chgrp )
       
   281 			$this->chgrp($path, $chgrp);
       
   282 		return true;
   364 		return true;
   283 	}
   365 	}
   284 
   366 
   285 	function rmdir($path, $recursive = false) {
   367 	/**
       
   368 	 * @param string $path
       
   369 	 * @param bool $recursive
       
   370 	 * @return bool
       
   371 	 */
       
   372 	public function rmdir($path, $recursive = false) {
   286 		return $this->delete($path, $recursive);
   373 		return $this->delete($path, $recursive);
   287 	}
   374 	}
   288 
   375 
   289 	function parselisting($line) {
   376 	/**
       
   377 	 * @staticvar bool $is_windows
       
   378 	 * @param string $line
       
   379 	 * @return string
       
   380 	 */
       
   381 	public function parselisting($line) {
   290 		static $is_windows;
   382 		static $is_windows;
   291 		if ( is_null($is_windows) )
   383 		if ( is_null($is_windows) )
   292 			$is_windows = stripos( ftp_systype($this->link), 'win') !== false;
   384 			$is_windows = stripos( ftp_systype($this->link), 'win') !== false;
   293 
   385 
   294 		if ( $is_windows && preg_match('/([0-9]{2})-([0-9]{2})-([0-9]{2}) +([0-9]{2}):([0-9]{2})(AM|PM) +([0-9]+|<DIR>) +(.+)/', $line, $lucifer) ) {
   386 		if ( $is_windows && preg_match('/([0-9]{2})-([0-9]{2})-([0-9]{2}) +([0-9]{2}):([0-9]{2})(AM|PM) +([0-9]+|<DIR>) +(.+)/', $line, $lucifer) ) {
   357 			$b['name'] = preg_replace( '/(\s*->\s*.*)$/', '', $b['name'] );
   449 			$b['name'] = preg_replace( '/(\s*->\s*.*)$/', '', $b['name'] );
   358 
   450 
   359 		return $b;
   451 		return $b;
   360 	}
   452 	}
   361 
   453 
   362 	function dirlist($path = '.', $include_hidden = true, $recursive = false) {
   454 	/**
       
   455 	 * @param string $path
       
   456 	 * @param bool $include_hidden
       
   457 	 * @param bool $recursive
       
   458 	 * @return bool|array
       
   459 	 */
       
   460 	public function dirlist($path = '.', $include_hidden = true, $recursive = false) {
   363 		if ( $this->is_file($path) ) {
   461 		if ( $this->is_file($path) ) {
   364 			$limit_file = basename($path);
   462 			$limit_file = basename($path);
   365 			$path = dirname($path) . '/';
   463 			$path = dirname($path) . '/';
   366 		} else {
   464 		} else {
   367 			$limit_file = false;
   465 			$limit_file = false;
   406 			$ret[ $struc['name'] ] = $struc;
   504 			$ret[ $struc['name'] ] = $struc;
   407 		}
   505 		}
   408 		return $ret;
   506 		return $ret;
   409 	}
   507 	}
   410 
   508 
   411 	function __destruct() {
   509 	public function __destruct() {
   412 		if ( $this->link )
   510 		if ( $this->link )
   413 			ftp_close($this->link);
   511 			ftp_close($this->link);
   414 	}
   512 	}
   415 }
   513 }