web/wp-admin/includes/class-wp-filesystem-ftpext.php
branchwordpress
changeset 132 4d4862461b8d
parent 109 03b0d1493584
equal deleted inserted replaced
131:a4642baaf829 132:4d4862461b8d
    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 	var $link;
    19 	var $timeout = 5;
       
    20 	var $errors = null;
    19 	var $errors = null;
    21 	var $options = array();
    20 	var $options = array();
    22 
       
    23 	var $permission = null;
       
    24 
    21 
    25 	function WP_Filesystem_FTPext($opt='') {
    22 	function WP_Filesystem_FTPext($opt='') {
    26 		$this->method = 'ftpext';
    23 		$this->method = 'ftpext';
    27 		$this->errors = new WP_Error();
    24 		$this->errors = new WP_Error();
    28 
    25 
    31 			$this->errors->add('no_ftp_ext', __('The ftp PHP extension is not available'));
    28 			$this->errors->add('no_ftp_ext', __('The ftp PHP extension is not available'));
    32 			return false;
    29 			return false;
    33 		}
    30 		}
    34 
    31 
    35 		// Set defaults:
    32 		// Set defaults:
       
    33 		//This Class uses the timeout on a per-connection basis, Others use it on a per-action basis.
       
    34 
       
    35 		if ( ! defined('FS_TIMEOUT') )
       
    36 			define('FS_TIMEOUT', 240);
       
    37 
    36 		if ( empty($opt['port']) )
    38 		if ( empty($opt['port']) )
    37 			$this->options['port'] = 21;
    39 			$this->options['port'] = 21;
    38 		else
    40 		else
    39 			$this->options['port'] = $opt['port'];
    41 			$this->options['port'] = $opt['port'];
    40 
    42 
    62 			$this->options['ssl'] = true;
    64 			$this->options['ssl'] = true;
    63 	}
    65 	}
    64 
    66 
    65 	function connect() {
    67 	function connect() {
    66 		if ( isset($this->options['ssl']) && $this->options['ssl'] && function_exists('ftp_ssl_connect') )
    68 		if ( isset($this->options['ssl']) && $this->options['ssl'] && function_exists('ftp_ssl_connect') )
    67 			$this->link = @ftp_ssl_connect($this->options['hostname'], $this->options['port'], $this->timeout);
    69 			$this->link = @ftp_ssl_connect($this->options['hostname'], $this->options['port'], FS_CONNECT_TIMEOUT);
    68 		else
    70 		else
    69 			$this->link = @ftp_connect($this->options['hostname'], $this->options['port'], $this->timeout);
    71 			$this->link = @ftp_connect($this->options['hostname'], $this->options['port'], FS_CONNECT_TIMEOUT);
    70 
    72 
    71 		if ( ! $this->link ) {
    73 		if ( ! $this->link ) {
    72 			$this->errors->add('connect', sprintf(__('Failed to connect to FTP Server %1$s:%2$s'), $this->options['hostname'], $this->options['port']));
    74 			$this->errors->add('connect', sprintf(__('Failed to connect to FTP Server %1$s:%2$s'), $this->options['hostname'], $this->options['port']));
    73 			return false;
    75 			return false;
    74 		}
    76 		}
    78 			return false;
    80 			return false;
    79 		}
    81 		}
    80 
    82 
    81 		//Set the Connection to use Passive FTP
    83 		//Set the Connection to use Passive FTP
    82 		@ftp_pasv( $this->link, true );
    84 		@ftp_pasv( $this->link, true );
    83 
    85 		if ( @ftp_get_option($this->link, FTP_TIMEOUT_SEC) < FS_TIMEOUT )
    84 		return true;
    86 			@ftp_set_option($this->link, FTP_TIMEOUT_SEC, FS_TIMEOUT);
    85 	}
    87 
    86 
    88 		return true;
    87 	function setDefaultPermissions($perm) {
    89 	}
    88 		$this->permission = $perm;
    90 
    89 	}
    91 	function get_contents($file, $type = '', $resumepos = 0 ) {
    90 
    92 		if ( empty($type) )
    91 	function get_contents($file, $type = '', $resumepos = 0 ){
       
    92 		if( empty($type) )
       
    93 			$type = FTP_BINARY;
    93 			$type = FTP_BINARY;
    94 
    94 
    95 		$temp = tmpfile();
    95 		$temp = tmpfile();
    96 		if ( ! $temp )
    96 		if ( ! $temp )
    97 			return false;
    97 			return false;
    98 
    98 
    99 		if( ! @ftp_fget($this->link, $temp, $file, $type, $resumepos) )
    99 		if ( ! @ftp_fget($this->link, $temp, $file, $type, $resumepos) )
   100 			return false;
   100 			return false;
   101 
   101 
   102 		fseek($temp, 0); //Skip back to the start of the file being written to
   102 		fseek($temp, 0); //Skip back to the start of the file being written to
   103 		$contents = '';
   103 		$contents = '';
   104 
   104 
   110 	}
   110 	}
   111 	function get_contents_array($file) {
   111 	function get_contents_array($file) {
   112 		return explode("\n", $this->get_contents($file));
   112 		return explode("\n", $this->get_contents($file));
   113 	}
   113 	}
   114 	function put_contents($file, $contents, $type = '' ) {
   114 	function put_contents($file, $contents, $type = '' ) {
   115 		if( empty($type) )
   115 		if ( empty($type) )
   116 			$type = $this->is_binary($contents) ? FTP_BINARY : FTP_ASCII;
   116 			$type = $this->is_binary($contents) ? FTP_BINARY : FTP_ASCII;
   117 
   117 
   118 		$temp = tmpfile();
   118 		$temp = tmpfile();
   119 		if ( ! $temp )
   119 		if ( ! $temp )
   120 			return false;
   120 			return false;
   127 		fclose($temp);
   127 		fclose($temp);
   128 		return $ret;
   128 		return $ret;
   129 	}
   129 	}
   130 	function cwd() {
   130 	function cwd() {
   131 		$cwd = @ftp_pwd($this->link);
   131 		$cwd = @ftp_pwd($this->link);
   132 		if( $cwd )
   132 		if ( $cwd )
   133 			$cwd = trailingslashit($cwd);
   133 			$cwd = trailingslashit($cwd);
   134 		return $cwd;
   134 		return $cwd;
   135 	}
   135 	}
   136 	function chdir($dir) {
   136 	function chdir($dir) {
   137 		return @ftp_chdir($dir);
   137 		return @ftp_chdir($this->link, $dir);
   138 	}
   138 	}
   139 	function chgrp($file, $group, $recursive = false ) {
   139 	function chgrp($file, $group, $recursive = false ) {
   140 		return false;
   140 		return false;
   141 	}
   141 	}
   142 	function chmod($file, $mode = false, $recursive = false) {
   142 	function chmod($file, $mode = false, $recursive = false) {
   143 		if( ! $mode )
       
   144 			$mode = $this->permission;
       
   145 		if( ! $mode )
       
   146 			return false;
       
   147 		if ( ! $this->exists($file) && ! $this->is_dir($file) )
   143 		if ( ! $this->exists($file) && ! $this->is_dir($file) )
   148 			return false;
   144 			return false;
       
   145 
       
   146 		if ( ! $mode ) {
       
   147 			if ( $this->is_file($file) )
       
   148 				$mode = FS_CHMOD_FILE;
       
   149 			elseif ( $this->is_dir($file) )
       
   150 				$mode = FS_CHMOD_DIR;
       
   151 			else
       
   152 				return false;
       
   153 		}
       
   154 
   149 		if ( ! $recursive || ! $this->is_dir($file) ) {
   155 		if ( ! $recursive || ! $this->is_dir($file) ) {
   150 			if ( ! function_exists('ftp_chmod') )
   156 			if ( ! function_exists('ftp_chmod') )
   151 				return @ftp_site($this->link, sprintf('CHMOD %o %s', $mode, $file));
   157 				return @ftp_site($this->link, sprintf('CHMOD %o %s', $mode, $file));
   152 			return @ftp_chmod($this->link, $mode, $file);
   158 			return @ftp_chmod($this->link, $mode, $file);
   153 		}
   159 		}
   154 		//Is a directory, and we want recursive
   160 		//Is a directory, and we want recursive
   155 		$filelist = $this->dirlist($file);
   161 		$filelist = $this->dirlist($file);
   156 		foreach($filelist as $filename){
   162 		foreach ( $filelist as $filename ) {
   157 			$this->chmod($file . '/' . $filename, $mode, $recursive);
   163 			$this->chmod($file . '/' . $filename, $mode, $recursive);
   158 		}
   164 		}
   159 		return true;
   165 		return true;
   160 	}
   166 	}
   161 	function chown($file, $owner, $recursive = false ) {
   167 	function chown($file, $owner, $recursive = false ) {
   172 	function group($file) {
   178 	function group($file) {
   173 		$dir = $this->dirlist($file);
   179 		$dir = $this->dirlist($file);
   174 		return $dir[$file]['group'];
   180 		return $dir[$file]['group'];
   175 	}
   181 	}
   176 	function copy($source, $destination, $overwrite = false ) {
   182 	function copy($source, $destination, $overwrite = false ) {
   177 		if( ! $overwrite && $this->exists($destination) )
   183 		if ( ! $overwrite && $this->exists($destination) )
   178 			return false;
   184 			return false;
   179 		$content = $this->get_contents($source);
   185 		$content = $this->get_contents($source);
   180 		if( false === $content)
   186 		if ( false === $content)
   181 			return false;
   187 			return false;
   182 		return $this->put_contents($destination, $content);
   188 		return $this->put_contents($destination, $content);
   183 	}
   189 	}
   184 	function move($source, $destination, $overwrite = false) {
   190 	function move($source, $destination, $overwrite = false) {
   185 		return ftp_rename($this->link, $source, $destination);
   191 		return ftp_rename($this->link, $source, $destination);
   199 				$this->delete( trailingslashit($file) . $delete_file['name'], $recursive);
   205 				$this->delete( trailingslashit($file) . $delete_file['name'], $recursive);
   200 		return @ftp_rmdir($this->link, $file);
   206 		return @ftp_rmdir($this->link, $file);
   201 	}
   207 	}
   202 
   208 
   203 	function exists($file) {
   209 	function exists($file) {
   204 		$list = @ftp_rawlist($this->link, $file, false);
   210 		$list = @ftp_nlist($this->link, $file);
   205 		return !empty($list); //empty list = no file, so invert.
   211 		return !empty($list); //empty list = no file, so invert.
   206 	}
   212 	}
   207 	function is_file($file) {
   213 	function is_file($file) {
   208 		return $this->exists($file) && !$this->is_dir($file);
   214 		return $this->exists($file) && !$this->is_dir($file);
   209 	}
   215 	}
   210 	function is_dir($path) {
   216 	function is_dir($path) {
   211 		$cwd = $this->cwd();
   217 		$cwd = $this->cwd();
   212 		$result = @ftp_chdir($this->link, trailingslashit($path) );
   218 		$result = @ftp_chdir($this->link, trailingslashit($path) );
   213 		if( $result && $path == $this->cwd() || $this->cwd() != $cwd ) {
   219 		if ( $result && $path == $this->cwd() || $this->cwd() != $cwd ) {
   214 			@ftp_chdir($this->link, $cwd);
   220 			@ftp_chdir($this->link, $cwd);
   215 			return true;
   221 			return true;
   216 		}
   222 		}
   217 		return false;
   223 		return false;
   218 	}
   224 	}
   235 	}
   241 	}
   236 	function touch($file, $time = 0, $atime = 0) {
   242 	function touch($file, $time = 0, $atime = 0) {
   237 		return false;
   243 		return false;
   238 	}
   244 	}
   239 	function mkdir($path, $chmod = false, $chown = false, $chgrp = false) {
   245 	function mkdir($path, $chmod = false, $chown = false, $chgrp = false) {
   240 		if( !ftp_mkdir($this->link, $path) )
   246 		if  ( !ftp_mkdir($this->link, $path) )
   241 			return false;
   247 			return false;
   242 		if( $chmod )
   248 		if ( ! $chmod )
   243 			$this->chmod($path, $chmod);
   249 			$chmod = FS_CHMOD_DIR;
   244 		if( $chown )
   250 		$this->chmod($path, $chmod);
       
   251 		if ( $chown )
   245 			$this->chown($path, $chown);
   252 			$this->chown($path, $chown);
   246 		if( $chgrp )
   253 		if ( $chgrp )
   247 			$this->chgrp($path, $chgrp);
   254 			$this->chgrp($path, $chgrp);
   248 		return true;
   255 		return true;
   249 	}
   256 	}
   250 	function rmdir($path, $recursive = false) {
   257 	function rmdir($path, $recursive = false) {
   251 		return $this->delete($path, $recursive);
   258 		return $this->delete($path, $recursive);
   254 	function parselisting($line) {
   261 	function parselisting($line) {
   255 		static $is_windows;
   262 		static $is_windows;
   256 		if ( is_null($is_windows) )
   263 		if ( is_null($is_windows) )
   257 			$is_windows = strpos( strtolower(ftp_systype($this->link)), 'win') !== false;
   264 			$is_windows = strpos( strtolower(ftp_systype($this->link)), 'win') !== false;
   258 
   265 
   259 		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)) {
   266 		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) ) {
   260 			$b = array();
   267 			$b = array();
   261 			if ($lucifer[3]<70) { $lucifer[3] +=2000; } else { $lucifer[3]+=1900; } // 4digit year fix
   268 			if ( $lucifer[3] < 70 ) { $lucifer[3] +=2000; } else { $lucifer[3] += 1900; } // 4digit year fix
   262 			$b['isdir'] = ($lucifer[7]=="<DIR>");
   269 			$b['isdir'] = ($lucifer[7]=="<DIR>");
   263 			if ( $b['isdir'] )
   270 			if ( $b['isdir'] )
   264 				$b['type'] = 'd';
   271 				$b['type'] = 'd';
   265 			else
   272 			else
   266 				$b['type'] = 'f';
   273 				$b['type'] = 'f';
   314 		}
   321 		}
   315 
   322 
   316 		return $b;
   323 		return $b;
   317 	}
   324 	}
   318 
   325 
   319 	function dirlist($path = '.', $incdot = false, $recursive = false) {
   326 	function dirlist($path = '.', $include_hidden = true, $recursive = false) {
   320 		if( $this->is_file($path) ) {
   327 		if ( $this->is_file($path) ) {
   321 			$limitFile = basename($path);
   328 			$limit_file = basename($path);
   322 			$path = dirname($path) . '/';
   329 			$path = dirname($path) . '/';
   323 		} else {
   330 		} else {
   324 			$limitFile = false;
   331 			$limit_file = false;
   325 		}
   332 		}
   326 
   333 
   327 		$list = @ftp_rawlist($this->link, '-a ' . $path, false);
   334 		$list = @ftp_rawlist($this->link, '-a ' . $path, false);
   328 
   335 
   329 		if ( $list === false )
   336 		if ( $list === false )
   333 		foreach ( $list as $k => $v ) {
   340 		foreach ( $list as $k => $v ) {
   334 			$entry = $this->parselisting($v);
   341 			$entry = $this->parselisting($v);
   335 			if ( empty($entry) )
   342 			if ( empty($entry) )
   336 				continue;
   343 				continue;
   337 
   344 
   338 			if ( '.' == $entry["name"] || '..' == $entry["name"] )
   345 			if ( '.' == $entry['name'] || '..' == $entry['name'] )
   339 				continue;
   346 				continue;
   340 
   347 
       
   348 			if ( ! $include_hidden && '.' == $entry['name'][0] )
       
   349 				continue;
       
   350 
       
   351 			if ( $limit_file && $entry['name'] != $limit_file)
       
   352 				continue;
       
   353 
   341 			$dirlist[ $entry['name'] ] = $entry;
   354 			$dirlist[ $entry['name'] ] = $entry;
   342 		}
   355 		}
   343 
   356 
   344 		if ( ! $dirlist )
   357 		if ( ! $dirlist )
   345 			return false;
   358 			return false;
   346 		if ( empty($dirlist) )
       
   347 			return array();
       
   348 
   359 
   349 		$ret = array();
   360 		$ret = array();
   350 		foreach ( $dirlist as $struc ) {
   361 		foreach ( (array)$dirlist as $struc ) {
   351 
       
   352 			if ( 'd' == $struc['type'] ) {
   362 			if ( 'd' == $struc['type'] ) {
   353 				$struc['files'] = array();
   363 				if ( $recursive )
   354 
   364 					$struc['files'] = $this->dirlist($path . '/' . $struc['name'], $include_hidden, $recursive);
   355 				if ( $incdot ){
   365 				else
   356 					//We're including the doted starts
   366 					$struc['files'] = array();
   357 					if( '.' != $struc['name'] && '..' != $struc['name'] ){ //Ok, It isnt a special folder
       
   358 						if ($recursive)
       
   359 							$struc['files'] = $this->dirlist($path . '/' . $struc['name'], $incdot, $recursive);
       
   360 					}
       
   361 				} else { //No dots
       
   362 					if ($recursive)
       
   363 						$struc['files'] = $this->dirlist($path . '/' . $struc['name'], $incdot, $recursive);
       
   364 				}
       
   365 			}
   367 			}
   366 			//File
   368 
   367 			$ret[$struc['name']] = $struc;
   369 			$ret[ $struc['name'] ] = $struc;
   368 		}
   370 		}
   369 		return $ret;
   371 		return $ret;
   370 	}
   372 	}
   371 
   373 
   372 	function __destruct(){
   374 	function __destruct() {
   373 		if( $this->link )
   375 		if ( $this->link )
   374 			ftp_close($this->link);
   376 			ftp_close($this->link);
   375 	}
   377 	}
   376 }
   378 }
   377 
   379 
   378 ?>
   380 ?>