wp/wp-admin/includes/class-wp-filesystem-ftpext.php
changeset 7 cf61fcea0001
parent 5 5e2f62d02dcd
child 9 177826044cd9
equal deleted inserted replaced
6:490d5cc509ed 7:cf61fcea0001
     8 
     8 
     9 /**
     9 /**
    10  * WordPress Filesystem Class for implementing FTP.
    10  * WordPress Filesystem Class for implementing FTP.
    11  *
    11  *
    12  * @since 2.5.0
    12  * @since 2.5.0
    13  * @package WordPress
    13  *
    14  * @subpackage Filesystem
    14  * @see WP_Filesystem_Base
    15  * @uses WP_Filesystem_Base Extends class
       
    16  */
    15  */
    17 class WP_Filesystem_FTPext extends WP_Filesystem_Base {
    16 class WP_Filesystem_FTPext extends WP_Filesystem_Base {
    18 	public $link;
    17 	public $link;
    19 
    18 
    20 	public function __construct($opt='') {
    19 	/**
       
    20 	 *
       
    21 	 * @param array $opt
       
    22 	 */
       
    23 	public function __construct( $opt = '' ) {
    21 		$this->method = 'ftpext';
    24 		$this->method = 'ftpext';
    22 		$this->errors = new WP_Error();
    25 		$this->errors = new WP_Error();
    23 
    26 
    24 		// Check if possible to use ftp functions.
    27 		// Check if possible to use ftp functions.
    25 		if ( ! extension_loaded('ftp') ) {
    28 		if ( ! extension_loaded('ftp') ) {
    56 		$this->options['ssl'] = false;
    59 		$this->options['ssl'] = false;
    57 		if ( isset($opt['connection_type']) && 'ftps' == $opt['connection_type'] )
    60 		if ( isset($opt['connection_type']) && 'ftps' == $opt['connection_type'] )
    58 			$this->options['ssl'] = true;
    61 			$this->options['ssl'] = true;
    59 	}
    62 	}
    60 
    63 
       
    64 	/**
       
    65 	 *
       
    66 	 * @return bool
       
    67 	 */
    61 	public function connect() {
    68 	public function connect() {
    62 		if ( isset($this->options['ssl']) && $this->options['ssl'] && function_exists('ftp_ssl_connect') )
    69 		if ( isset($this->options['ssl']) && $this->options['ssl'] && function_exists('ftp_ssl_connect') )
    63 			$this->link = @ftp_ssl_connect($this->options['hostname'], $this->options['port'], FS_CONNECT_TIMEOUT);
    70 			$this->link = @ftp_ssl_connect($this->options['hostname'], $this->options['port'], FS_CONNECT_TIMEOUT);
    64 		else
    71 		else
    65 			$this->link = @ftp_connect($this->options['hostname'], $this->options['port'], FS_CONNECT_TIMEOUT);
    72 			$this->link = @ftp_connect($this->options['hostname'], $this->options['port'], FS_CONNECT_TIMEOUT);
    66 
    73 
    67 		if ( ! $this->link ) {
    74 		if ( ! $this->link ) {
    68 			$this->errors->add('connect', sprintf(__('Failed to connect to FTP Server %1$s:%2$s'), $this->options['hostname'], $this->options['port']));
    75 			$this->errors->add( 'connect',
    69 			return false;
    76 				/* translators: %s: hostname:port */
    70 		}
    77 				sprintf( __( 'Failed to connect to FTP Server %s' ),
    71 
    78 					$this->options['hostname'] . ':' . $this->options['port']
    72 		if ( ! @ftp_login($this->link,$this->options['username'], $this->options['password']) ) {
    79 				)
    73 			$this->errors->add('auth', sprintf(__('Username/Password incorrect for %s'), $this->options['username']));
    80 			);
       
    81 			return false;
       
    82 		}
       
    83 
       
    84 		if ( ! @ftp_login( $this->link,$this->options['username'], $this->options['password'] ) ) {
       
    85 			$this->errors->add( 'auth',
       
    86 				/* translators: %s: username */
       
    87 				sprintf( __( 'Username/Password incorrect for %s' ),
       
    88 					$this->options['username']
       
    89 				)
       
    90 			);
    74 			return false;
    91 			return false;
    75 		}
    92 		}
    76 
    93 
    77 		// Set the Connection to use Passive FTP
    94 		// Set the Connection to use Passive FTP
    78 		@ftp_pasv( $this->link, true );
    95 		@ftp_pasv( $this->link, true );
    81 
    98 
    82 		return true;
    99 		return true;
    83 	}
   100 	}
    84 
   101 
    85 	/**
   102 	/**
    86 	 * @param string $file
   103 	 * Retrieves the file contents.
    87 	 * @return false|string
   104 	 *
       
   105 	 * @since 2.5.0
       
   106 	 *
       
   107 	 * @param string $file Filename.
       
   108 	 * @return string|false File contents on success, false if no temp file could be opened,
       
   109 	 *                      or if the file couldn't be retrieved.
    88 	 */
   110 	 */
    89 	public function get_contents( $file ) {
   111 	public function get_contents( $file ) {
    90 		$tempfile = wp_tempnam($file);
   112 		$tempfile = wp_tempnam($file);
    91 		$temp = fopen($tempfile, 'w+');
   113 		$temp = fopen($tempfile, 'w+');
    92 
   114 
    93 		if ( ! $temp )
   115 		if ( ! $temp ) {
    94 			return false;
   116 			unlink( $tempfile );
    95 
   117 			return false;
    96 		if ( ! @ftp_fget($this->link, $temp, $file, FTP_BINARY ) )
   118 		}
    97 			return false;
   119 
       
   120 		if ( ! @ftp_fget( $this->link, $temp, $file, FTP_BINARY ) ) {
       
   121 			fclose( $temp );
       
   122 			unlink( $tempfile );
       
   123 			return false;
       
   124 		}
    98 
   125 
    99 		fseek( $temp, 0 ); // Skip back to the start of the file being written to
   126 		fseek( $temp, 0 ); // Skip back to the start of the file being written to
   100 		$contents = '';
   127 		$contents = '';
   101 
   128 
   102 		while ( ! feof($temp) )
   129 		while ( ! feof($temp) )
   106 		unlink($tempfile);
   133 		unlink($tempfile);
   107 		return $contents;
   134 		return $contents;
   108 	}
   135 	}
   109 
   136 
   110 	/**
   137 	/**
       
   138 	 *
   111 	 * @param string $file
   139 	 * @param string $file
   112 	 * @return array
   140 	 * @return array
   113 	 */
   141 	 */
   114 	public function get_contents_array($file) {
   142 	public function get_contents_array($file) {
   115 		return explode("\n", $this->get_contents($file));
   143 		return explode("\n", $this->get_contents($file));
   116 	}
   144 	}
   117 
   145 
   118 	/**
   146 	/**
       
   147 	 *
   119 	 * @param string $file
   148 	 * @param string $file
   120 	 * @param string $contents
   149 	 * @param string $contents
   121 	 * @param bool|int $mode
   150 	 * @param bool|int $mode
   122 	 * @return bool
   151 	 * @return bool
   123 	 */
   152 	 */
   124 	public function put_contents($file, $contents, $mode = false ) {
   153 	public function put_contents($file, $contents, $mode = false ) {
   125 		$tempfile = wp_tempnam($file);
   154 		$tempfile = wp_tempnam($file);
   126 		$temp = fopen( $tempfile, 'wb+' );
   155 		$temp = fopen( $tempfile, 'wb+' );
   127 		if ( ! $temp )
   156 
   128 			return false;
   157 		if ( ! $temp ) {
       
   158 			unlink( $tempfile );
       
   159 			return false;
       
   160 		}
   129 
   161 
   130 		mbstring_binary_safe_encoding();
   162 		mbstring_binary_safe_encoding();
   131 
   163 
   132 		$data_length = strlen( $contents );
   164 		$data_length = strlen( $contents );
   133 		$bytes_written = fwrite( $temp, $contents );
   165 		$bytes_written = fwrite( $temp, $contents );
   151 
   183 
   152 		return $ret;
   184 		return $ret;
   153 	}
   185 	}
   154 
   186 
   155 	/**
   187 	/**
       
   188 	 *
   156 	 * @return string
   189 	 * @return string
   157 	 */
   190 	 */
   158 	public function cwd() {
   191 	public function cwd() {
   159 		$cwd = @ftp_pwd($this->link);
   192 		$cwd = @ftp_pwd($this->link);
   160 		if ( $cwd )
   193 		if ( $cwd )
   161 			$cwd = trailingslashit($cwd);
   194 			$cwd = trailingslashit($cwd);
   162 		return $cwd;
   195 		return $cwd;
   163 	}
   196 	}
   164 
   197 
   165 	/**
   198 	/**
       
   199 	 *
   166 	 * @param string $dir
   200 	 * @param string $dir
   167 	 * @return bool
   201 	 * @return bool
   168 	 */
   202 	 */
   169 	public function chdir($dir) {
   203 	public function chdir($dir) {
   170 		return @ftp_chdir($this->link, $dir);
   204 		return @ftp_chdir($this->link, $dir);
   171 	}
   205 	}
   172 
   206 
   173 	/**
   207 	/**
       
   208 	 *
   174 	 * @param string $file
   209 	 * @param string $file
   175 	 * @param int $mode
   210 	 * @param int $mode
   176 	 * @param bool $recursive
   211 	 * @param bool $recursive
   177 	 * @return bool
   212 	 * @return bool
   178 	 */
   213 	 */
   198 			return (bool)@ftp_site($this->link, sprintf('CHMOD %o %s', $mode, $file));
   233 			return (bool)@ftp_site($this->link, sprintf('CHMOD %o %s', $mode, $file));
   199 		return (bool)@ftp_chmod($this->link, $mode, $file);
   234 		return (bool)@ftp_chmod($this->link, $mode, $file);
   200 	}
   235 	}
   201 
   236 
   202 	/**
   237 	/**
       
   238 	 *
   203 	 * @param string $file
   239 	 * @param string $file
   204 	 * @return string
   240 	 * @return string
   205 	 */
   241 	 */
   206 	public function owner($file) {
   242 	public function owner($file) {
   207 		$dir = $this->dirlist($file);
   243 		$dir = $this->dirlist($file);
   208 		return $dir[$file]['owner'];
   244 		return $dir[$file]['owner'];
   209 	}
   245 	}
   210 	/**
   246 	/**
       
   247 	 *
   211 	 * @param string $file
   248 	 * @param string $file
   212 	 * @return string
   249 	 * @return string
   213 	 */
   250 	 */
   214 	public function getchmod($file) {
   251 	public function getchmod($file) {
   215 		$dir = $this->dirlist($file);
   252 		$dir = $this->dirlist($file);
   216 		return $dir[$file]['permsn'];
   253 		return $dir[$file]['permsn'];
   217 	}
   254 	}
   218 	/**
   255 
       
   256 	/**
       
   257 	 *
   219 	 * @param string $file
   258 	 * @param string $file
   220 	 * @return string
   259 	 * @return string
   221 	 */
   260 	 */
   222 	public function group($file) {
   261 	public function group($file) {
   223 		$dir = $this->dirlist($file);
   262 		$dir = $this->dirlist($file);
   238 		$content = $this->get_contents($source);
   277 		$content = $this->get_contents($source);
   239 		if ( false === $content )
   278 		if ( false === $content )
   240 			return false;
   279 			return false;
   241 		return $this->put_contents($destination, $content, $mode);
   280 		return $this->put_contents($destination, $content, $mode);
   242 	}
   281 	}
   243 	/**
   282 
       
   283 	/**
       
   284 	 *
   244 	 * @param string $source
   285 	 * @param string $source
   245 	 * @param string $destination
   286 	 * @param string $destination
   246 	 * @param bool $overwrite
   287 	 * @param bool $overwrite
   247 	 * @return bool
   288 	 * @return bool
   248 	 */
   289 	 */
   249 	public function move($source, $destination, $overwrite = false) {
   290 	public function move($source, $destination, $overwrite = false) {
   250 		return ftp_rename($this->link, $source, $destination);
   291 		return ftp_rename($this->link, $source, $destination);
   251 	}
   292 	}
   252 	/**
   293 
       
   294 	/**
       
   295 	 *
   253 	 * @param string $file
   296 	 * @param string $file
   254 	 * @param bool $recursive
   297 	 * @param bool $recursive
   255 	 * @param string $type
   298 	 * @param string $type
   256 	 * @return bool
   299 	 * @return bool
   257 	 */
   300 	 */
   267 		if ( !empty($filelist) )
   310 		if ( !empty($filelist) )
   268 			foreach ( $filelist as $delete_file )
   311 			foreach ( $filelist as $delete_file )
   269 				$this->delete( trailingslashit($file) . $delete_file['name'], $recursive, $delete_file['type'] );
   312 				$this->delete( trailingslashit($file) . $delete_file['name'], $recursive, $delete_file['type'] );
   270 		return @ftp_rmdir($this->link, $file);
   313 		return @ftp_rmdir($this->link, $file);
   271 	}
   314 	}
   272 	/**
   315 
       
   316 	/**
       
   317 	 *
   273 	 * @param string $file
   318 	 * @param string $file
   274 	 * @return bool
   319 	 * @return bool
   275 	 */
   320 	 */
   276 	public function exists($file) {
   321 	public function exists($file) {
   277 		$list = @ftp_nlist($this->link, $file);
   322 		$list = @ftp_nlist($this->link, $file);
   280 			return true; // File is an empty directory.
   325 			return true; // File is an empty directory.
   281 		}
   326 		}
   282 
   327 
   283 		return !empty($list); //empty list = no file, so invert.
   328 		return !empty($list); //empty list = no file, so invert.
   284 	}
   329 	}
   285 	/**
   330 
       
   331 	/**
       
   332 	 *
   286 	 * @param string $file
   333 	 * @param string $file
   287 	 * @return bool
   334 	 * @return bool
   288 	 */
   335 	 */
   289 	public function is_file($file) {
   336 	public function is_file($file) {
   290 		return $this->exists($file) && !$this->is_dir($file);
   337 		return $this->exists($file) && !$this->is_dir($file);
   291 	}
   338 	}
   292 	/**
   339 
       
   340 	/**
       
   341 	 *
   293 	 * @param string $path
   342 	 * @param string $path
   294 	 * @return bool
   343 	 * @return bool
   295 	 */
   344 	 */
   296 	public function is_dir($path) {
   345 	public function is_dir($path) {
   297 		$cwd = $this->cwd();
   346 		$cwd = $this->cwd();
   302 		}
   351 		}
   303 		return false;
   352 		return false;
   304 	}
   353 	}
   305 
   354 
   306 	/**
   355 	/**
       
   356 	 *
   307 	 * @param string $file
   357 	 * @param string $file
   308 	 * @return bool
   358 	 * @return bool
   309 	 */
   359 	 */
   310 	public function is_readable($file) {
   360 	public function is_readable($file) {
   311 		return true;
   361 		return true;
   312 	}
   362 	}
   313 	/**
   363 
       
   364 	/**
       
   365 	 *
   314 	 * @param string $file
   366 	 * @param string $file
   315 	 * @return bool
   367 	 * @return bool
   316 	 */
   368 	 */
   317 	public function is_writable($file) {
   369 	public function is_writable($file) {
   318 		return true;
   370 		return true;
   319 	}
   371 	}
   320 	/**
   372 
       
   373 	/**
       
   374 	 *
   321 	 * @param string $file
   375 	 * @param string $file
   322 	 * @return bool
   376 	 * @return bool
   323 	 */
   377 	 */
   324 	public function atime($file) {
   378 	public function atime($file) {
   325 		return false;
   379 		return false;
   326 	}
   380 	}
   327 	/**
   381 
       
   382 	/**
       
   383 	 *
   328 	 * @param string $file
   384 	 * @param string $file
   329 	 * @return int
   385 	 * @return int
   330 	 */
   386 	 */
   331 	public function mtime($file) {
   387 	public function mtime($file) {
   332 		return ftp_mdtm($this->link, $file);
   388 		return ftp_mdtm($this->link, $file);
   333 	}
   389 	}
   334 	/**
   390 
       
   391 	/**
       
   392 	 *
   335 	 * @param string $file
   393 	 * @param string $file
   336 	 * @return int
   394 	 * @return int
   337 	 */
   395 	 */
   338 	public function size($file) {
   396 	public function size($file) {
   339 		return ftp_size($this->link, $file);
   397 		return ftp_size($this->link, $file);
   340 	}
   398 	}
   341 	/**
   399 
       
   400 	/**
       
   401 	 *
   342 	 * @param string $file
   402 	 * @param string $file
   343 	 * @return bool
   403 	 * @return bool
   344 	 */
   404 	 */
   345 	public function touch($file, $time = 0, $atime = 0) {
   405 	public function touch($file, $time = 0, $atime = 0) {
   346 		return false;
   406 		return false;
   347 	}
   407 	}
   348 
   408 
   349 	/**
   409 	/**
       
   410 	 *
   350 	 * @param string $path
   411 	 * @param string $path
   351 	 * @param mixed $chmod
   412 	 * @param mixed $chmod
   352 	 * @param mixed $chown
   413 	 * @param mixed $chown
   353 	 * @param mixed $chgrp
   414 	 * @param mixed $chgrp
   354 	 * @return bool
   415 	 * @return bool
   363 		$this->chmod($path, $chmod);
   424 		$this->chmod($path, $chmod);
   364 		return true;
   425 		return true;
   365 	}
   426 	}
   366 
   427 
   367 	/**
   428 	/**
       
   429 	 *
   368 	 * @param string $path
   430 	 * @param string $path
   369 	 * @param bool $recursive
   431 	 * @param bool $recursive
   370 	 * @return bool
   432 	 * @return bool
   371 	 */
   433 	 */
   372 	public function rmdir($path, $recursive = false) {
   434 	public function rmdir($path, $recursive = false) {
   373 		return $this->delete($path, $recursive);
   435 		return $this->delete($path, $recursive);
   374 	}
   436 	}
   375 
   437 
   376 	/**
   438 	/**
       
   439 	 *
   377 	 * @staticvar bool $is_windows
   440 	 * @staticvar bool $is_windows
   378 	 * @param string $line
   441 	 * @param string $line
   379 	 * @return string
   442 	 * @return array
   380 	 */
   443 	 */
   381 	public function parselisting($line) {
   444 	public function parselisting($line) {
   382 		static $is_windows;
   445 		static $is_windows = null;
   383 		if ( is_null($is_windows) )
   446 		if ( is_null($is_windows) )
   384 			$is_windows = stripos( ftp_systype($this->link), 'win') !== false;
   447 			$is_windows = stripos( ftp_systype($this->link), 'win') !== false;
   385 
   448 
   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) ) {
   449 		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) ) {
   387 			$b = array();
   450 			$b = array();
   416 			elseif ( $b['islink'] )
   479 			elseif ( $b['islink'] )
   417 				$b['type'] = 'l';
   480 				$b['type'] = 'l';
   418 			else
   481 			else
   419 				$b['type'] = 'f';
   482 				$b['type'] = 'f';
   420 			$b['perms'] = $lucifer[0];
   483 			$b['perms'] = $lucifer[0];
       
   484 			$b['permsn'] = $this->getnumchmodfromh( $b['perms'] );
   421 			$b['number'] = $lucifer[1];
   485 			$b['number'] = $lucifer[1];
   422 			$b['owner'] = $lucifer[2];
   486 			$b['owner'] = $lucifer[2];
   423 			$b['group'] = $lucifer[3];
   487 			$b['group'] = $lucifer[3];
   424 			$b['size'] = $lucifer[4];
   488 			$b['size'] = $lucifer[4];
   425 			if ( $lcount == 8 ) {
   489 			if ( $lcount == 8 ) {
   443 				$b['name'] = $lucifer[8];
   507 				$b['name'] = $lucifer[8];
   444 			}
   508 			}
   445 		}
   509 		}
   446 
   510 
   447 		// Replace symlinks formatted as "source -> target" with just the source name
   511 		// Replace symlinks formatted as "source -> target" with just the source name
   448 		if ( $b['islink'] )
   512 		if ( isset( $b['islink'] ) && $b['islink'] ) {
   449 			$b['name'] = preg_replace( '/(\s*->\s*.*)$/', '', $b['name'] );
   513 			$b['name'] = preg_replace( '/(\s*->\s*.*)$/', '', $b['name'] );
       
   514 		}
   450 
   515 
   451 		return $b;
   516 		return $b;
   452 	}
   517 	}
   453 
   518 
   454 	/**
   519 	/**
       
   520 	 *
   455 	 * @param string $path
   521 	 * @param string $path
   456 	 * @param bool $include_hidden
   522 	 * @param bool $include_hidden
   457 	 * @param bool $recursive
   523 	 * @param bool $recursive
   458 	 * @return bool|array
   524 	 * @return bool|array
   459 	 */
   525 	 */
   504 			$ret[ $struc['name'] ] = $struc;
   570 			$ret[ $struc['name'] ] = $struc;
   505 		}
   571 		}
   506 		return $ret;
   572 		return $ret;
   507 	}
   573 	}
   508 
   574 
       
   575 	/**
       
   576 	 */
   509 	public function __destruct() {
   577 	public function __destruct() {
   510 		if ( $this->link )
   578 		if ( $this->link )
   511 			ftp_close($this->link);
   579 			ftp_close($this->link);
   512 	}
   580 	}
   513 }
   581 }