web/wp-admin/includes/class-wp-filesystem-ftpext.php
changeset 194 32102edaa81b
parent 136 bde1974c263b
child 204 09a1c134465b
equal deleted inserted replaced
193:2f6f6f7551ca 194:32102edaa81b
    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 $errors = null;
    19 	var $errors = null;
    20 	var $options = array();
    20 	var $options = array();
    21 
    21 
    22 	function WP_Filesystem_FTPext($opt='') {
    22 	function __construct($opt='') {
    23 		$this->method = 'ftpext';
    23 		$this->method = 'ftpext';
    24 		$this->errors = new WP_Error();
    24 		$this->errors = new WP_Error();
    25 
    25 
    26 		//Check if possible to use ftp functions.
    26 		//Check if possible to use ftp functions.
    27 		if ( ! extension_loaded('ftp') ) {
    27 		if ( ! extension_loaded('ftp') ) {
    43 		if ( empty($opt['hostname']) )
    43 		if ( empty($opt['hostname']) )
    44 			$this->errors->add('empty_hostname', __('FTP hostname is required'));
    44 			$this->errors->add('empty_hostname', __('FTP hostname is required'));
    45 		else
    45 		else
    46 			$this->options['hostname'] = $opt['hostname'];
    46 			$this->options['hostname'] = $opt['hostname'];
    47 
    47 
    48 		if ( isset($opt['base']) && ! empty($opt['base']) )
    48 		if ( ! empty($opt['base']) )
    49 			$this->wp_base = $opt['base'];
    49 			$this->wp_base = $opt['base'];
    50 
    50 
    51 		// Check if the options provided are OK.
    51 		// Check if the options provided are OK.
    52 		if ( empty($opt['username']) )
    52 		if ( empty($opt['username']) )
    53 			$this->errors->add('empty_username', __('FTP username is required'));
    53 			$this->errors->add('empty_username', __('FTP username is required'));
    90 
    90 
    91 	function get_contents($file, $type = '', $resumepos = 0 ) {
    91 	function get_contents($file, $type = '', $resumepos = 0 ) {
    92 		if ( empty($type) )
    92 		if ( empty($type) )
    93 			$type = FTP_BINARY;
    93 			$type = FTP_BINARY;
    94 
    94 
    95 		$temp = tmpfile();
    95 		$tempfile = wp_tempnam($file);
       
    96 		$temp = fopen($tempfile, 'w+');
       
    97 
    96 		if ( ! $temp )
    98 		if ( ! $temp )
    97 			return false;
    99 			return false;
    98 
   100 
    99 		if ( ! @ftp_fget($this->link, $temp, $file, $type, $resumepos) )
   101 		if ( ! @ftp_fget($this->link, $temp, $file, $type, $resumepos) )
   100 			return false;
   102 			return false;
   104 
   106 
   105 		while ( ! feof($temp) )
   107 		while ( ! feof($temp) )
   106 			$contents .= fread($temp, 8192);
   108 			$contents .= fread($temp, 8192);
   107 
   109 
   108 		fclose($temp);
   110 		fclose($temp);
       
   111 		unlink($tempfile);
   109 		return $contents;
   112 		return $contents;
   110 	}
   113 	}
   111 	function get_contents_array($file) {
   114 	function get_contents_array($file) {
   112 		return explode("\n", $this->get_contents($file));
   115 		return explode("\n", $this->get_contents($file));
   113 	}
   116 	}
   114 	function put_contents($file, $contents, $type = '' ) {
   117 
   115 		if ( empty($type) )
   118 	function put_contents($file, $contents, $mode = false ) {
   116 			$type = $this->is_binary($contents) ? FTP_BINARY : FTP_ASCII;
   119 		$tempfile = wp_tempnam($file);
   117 
   120 		$temp = fopen($tempfile, 'w+');
   118 		$temp = tmpfile();
       
   119 		if ( ! $temp )
   121 		if ( ! $temp )
   120 			return false;
   122 			return false;
   121 
   123 
   122 		fwrite($temp, $contents);
   124 		fwrite($temp, $contents);
   123 		fseek($temp, 0); //Skip back to the start of the file being written to
   125 		fseek($temp, 0); //Skip back to the start of the file being written to
   124 
   126 
       
   127 		$type = $this->is_binary($contents) ? FTP_BINARY : FTP_ASCII;
   125 		$ret = @ftp_fput($this->link, $file, $temp, $type);
   128 		$ret = @ftp_fput($this->link, $file, $temp, $type);
   126 
   129 
   127 		fclose($temp);
   130 		fclose($temp);
       
   131 		unlink($tempfile);
       
   132 
       
   133 		$this->chmod($file, $mode);
       
   134 
   128 		return $ret;
   135 		return $ret;
   129 	}
   136 	}
   130 	function cwd() {
   137 	function cwd() {
   131 		$cwd = @ftp_pwd($this->link);
   138 		$cwd = @ftp_pwd($this->link);
   132 		if ( $cwd )
   139 		if ( $cwd )
   138 	}
   145 	}
   139 	function chgrp($file, $group, $recursive = false ) {
   146 	function chgrp($file, $group, $recursive = false ) {
   140 		return false;
   147 		return false;
   141 	}
   148 	}
   142 	function chmod($file, $mode = false, $recursive = false) {
   149 	function chmod($file, $mode = false, $recursive = false) {
   143 		if ( ! $this->exists($file) && ! $this->is_dir($file) )
       
   144 			return false;
       
   145 
       
   146 		if ( ! $mode ) {
   150 		if ( ! $mode ) {
   147 			if ( $this->is_file($file) )
   151 			if ( $this->is_file($file) )
   148 				$mode = FS_CHMOD_FILE;
   152 				$mode = FS_CHMOD_FILE;
   149 			elseif ( $this->is_dir($file) )
   153 			elseif ( $this->is_dir($file) )
   150 				$mode = FS_CHMOD_DIR;
   154 				$mode = FS_CHMOD_DIR;
   151 			else
   155 			else
   152 				return false;
   156 				return false;
   153 		}
   157 		}
   154 
   158 
   155 		if ( ! $recursive || ! $this->is_dir($file) ) {
   159 		// chmod any sub-objects if recursive.
   156 			if ( ! function_exists('ftp_chmod') )
   160 		if ( $recursive && $this->is_dir($file) ) {
   157 				return @ftp_site($this->link, sprintf('CHMOD %o %s', $mode, $file));
   161 			$filelist = $this->dirlist($file);
   158 			return @ftp_chmod($this->link, $mode, $file);
   162 			foreach ( (array)$filelist as $filename => $filemeta )
   159 		}
   163 				$this->chmod($file . '/' . $filename, $mode, $recursive);
   160 		//Is a directory, and we want recursive
   164 		}
   161 		$filelist = $this->dirlist($file);
   165 
   162 		foreach ( $filelist as $filename ) {
   166 		// chmod the file or directory
   163 			$this->chmod($file . '/' . $filename, $mode, $recursive);
   167 		if ( ! function_exists('ftp_chmod') )
   164 		}
   168 			return (bool)@ftp_site($this->link, sprintf('CHMOD %o %s', $mode, $file));
   165 		return true;
   169 		return (bool)@ftp_chmod($this->link, $mode, $file);
   166 	}
   170 	}
   167 	function chown($file, $owner, $recursive = false ) {
   171 	function chown($file, $owner, $recursive = false ) {
   168 		return false;
   172 		return false;
   169 	}
   173 	}
   170 	function owner($file) {
   174 	function owner($file) {
   177 	}
   181 	}
   178 	function group($file) {
   182 	function group($file) {
   179 		$dir = $this->dirlist($file);
   183 		$dir = $this->dirlist($file);
   180 		return $dir[$file]['group'];
   184 		return $dir[$file]['group'];
   181 	}
   185 	}
   182 	function copy($source, $destination, $overwrite = false ) {
   186 	function copy($source, $destination, $overwrite = false, $mode = false) {
   183 		if ( ! $overwrite && $this->exists($destination) )
   187 		if ( ! $overwrite && $this->exists($destination) )
   184 			return false;
   188 			return false;
   185 		$content = $this->get_contents($source);
   189 		$content = $this->get_contents($source);
   186 		if ( false === $content)
   190 		if ( false === $content)
   187 			return false;
   191 			return false;
   188 		return $this->put_contents($destination, $content);
   192 		return $this->put_contents($destination, $content, $mode);
   189 	}
   193 	}
   190 	function move($source, $destination, $overwrite = false) {
   194 	function move($source, $destination, $overwrite = false) {
   191 		return ftp_rename($this->link, $source, $destination);
   195 		return ftp_rename($this->link, $source, $destination);
   192 	}
   196 	}
   193 
   197 
   194 	function delete($file, $recursive = false ) {
   198 	function delete($file, $recursive = false, $type = false) {
   195 		if ( empty($file) )
   199 		if ( empty($file) )
   196 			return false;
   200 			return false;
   197 		if ( $this->is_file($file) )
   201 		if ( 'f' == $type || $this->is_file($file) )
   198 			return @ftp_delete($this->link, $file);
   202 			return @ftp_delete($this->link, $file);
   199 		if ( !$recursive )
   203 		if ( !$recursive )
   200 			return @ftp_rmdir($this->link, $file);
   204 			return @ftp_rmdir($this->link, $file);
   201 
   205 
   202 		$filelist = $this->dirlist( trailingslashit($file) );
   206 		$filelist = $this->dirlist( trailingslashit($file) );
   203 		if ( !empty($filelist) )
   207 		if ( !empty($filelist) )
   204 			foreach ( $filelist as $delete_file )
   208 			foreach ( $filelist as $delete_file )
   205 				$this->delete( trailingslashit($file) . $delete_file['name'], $recursive);
   209 				$this->delete( trailingslashit($file) . $delete_file['name'], $recursive, $delete_file['type'] );
   206 		return @ftp_rmdir($this->link, $file);
   210 		return @ftp_rmdir($this->link, $file);
   207 	}
   211 	}
   208 
   212 
   209 	function exists($file) {
   213 	function exists($file) {
   210 		$list = @ftp_nlist($this->link, $file);
   214 		$list = @ftp_nlist($this->link, $file);
   241 	}
   245 	}
   242 	function touch($file, $time = 0, $atime = 0) {
   246 	function touch($file, $time = 0, $atime = 0) {
   243 		return false;
   247 		return false;
   244 	}
   248 	}
   245 	function mkdir($path, $chmod = false, $chown = false, $chgrp = false) {
   249 	function mkdir($path, $chmod = false, $chown = false, $chgrp = false) {
   246 		if  ( !ftp_mkdir($this->link, $path) )
   250 		$path = untrailingslashit($path);
   247 			return false;
   251 		if ( empty($path) )
   248 		if ( ! $chmod )
   252 			return false;
   249 			$chmod = FS_CHMOD_DIR;
   253 
       
   254 		if ( !@ftp_mkdir($this->link, $path) )
       
   255 			return false;
   250 		$this->chmod($path, $chmod);
   256 		$this->chmod($path, $chmod);
   251 		if ( $chown )
   257 		if ( $chown )
   252 			$this->chown($path, $chown);
   258 			$this->chown($path, $chown);
   253 		if ( $chgrp )
   259 		if ( $chgrp )
   254 			$this->chgrp($path, $chgrp);
   260 			$this->chgrp($path, $chgrp);
   259 	}
   265 	}
   260 
   266 
   261 	function parselisting($line) {
   267 	function parselisting($line) {
   262 		static $is_windows;
   268 		static $is_windows;
   263 		if ( is_null($is_windows) )
   269 		if ( is_null($is_windows) )
   264 			$is_windows = strpos( strtolower(ftp_systype($this->link)), 'win') !== false;
   270 			$is_windows = stripos( ftp_systype($this->link), 'win') !== false;
   265 
   271 
   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) ) {
   272 		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) ) {
   267 			$b = array();
   273 			$b = array();
   268 			if ( $lucifer[3] < 70 ) { $lucifer[3] +=2000; } else { $lucifer[3] += 1900; } // 4digit year fix
   274 			if ( $lucifer[3] < 70 )
   269 			$b['isdir'] = ($lucifer[7]=="<DIR>");
   275 				$lucifer[3] +=2000;
       
   276 			else
       
   277 				$lucifer[3] += 1900; // 4digit year fix
       
   278 			$b['isdir'] = ( $lucifer[7] == '<DIR>');
   270 			if ( $b['isdir'] )
   279 			if ( $b['isdir'] )
   271 				$b['type'] = 'd';
   280 				$b['type'] = 'd';
   272 			else
   281 			else
   273 				$b['type'] = 'f';
   282 				$b['type'] = 'f';
   274 			$b['size'] = $lucifer[7];
   283 			$b['size'] = $lucifer[7];
   275 			$b['month'] = $lucifer[1];
   284 			$b['month'] = $lucifer[1];
   276 			$b['day'] = $lucifer[2];
   285 			$b['day'] = $lucifer[2];
   277 			$b['year'] = $lucifer[3];
   286 			$b['year'] = $lucifer[3];
   278 			$b['hour'] = $lucifer[4];
   287 			$b['hour'] = $lucifer[4];
   279 			$b['minute'] = $lucifer[5];
   288 			$b['minute'] = $lucifer[5];
   280 			$b['time'] = @mktime($lucifer[4]+(strcasecmp($lucifer[6],"PM")==0?12:0),$lucifer[5],0,$lucifer[1],$lucifer[2],$lucifer[3]);
   289 			$b['time'] = @mktime($lucifer[4] + (strcasecmp($lucifer[6], "PM") == 0 ? 12 : 0), $lucifer[5], 0, $lucifer[1], $lucifer[2], $lucifer[3]);
   281 			$b['am/pm'] = $lucifer[6];
   290 			$b['am/pm'] = $lucifer[6];
   282 			$b['name'] = $lucifer[8];
   291 			$b['name'] = $lucifer[8];
   283 		} else if (!$is_windows && $lucifer=preg_split("/[ ]/",$line,9,PREG_SPLIT_NO_EMPTY)) {
   292 		} elseif ( !$is_windows && $lucifer = preg_split('/[ ]/', $line, 9, PREG_SPLIT_NO_EMPTY)) {
   284 			//echo $line."\n";
   293 			//echo $line."\n";
   285 			$lcount=count($lucifer);
   294 			$lcount = count($lucifer);
   286 			if ($lcount<8) return '';
   295 			if ( $lcount < 8 )
       
   296 				return '';
   287 			$b = array();
   297 			$b = array();
   288 			$b['isdir'] = $lucifer[0]{0} === "d";
   298 			$b['isdir'] = $lucifer[0]{0} === 'd';
   289 			$b['islink'] = $lucifer[0]{0} === "l";
   299 			$b['islink'] = $lucifer[0]{0} === 'l';
   290 			if ( $b['isdir'] )
   300 			if ( $b['isdir'] )
   291 				$b['type'] = 'd';
   301 				$b['type'] = 'd';
   292 			elseif ( $b['islink'] )
   302 			elseif ( $b['islink'] )
   293 				$b['type'] = 'l';
   303 				$b['type'] = 'l';
   294 			else
   304 			else
   296 			$b['perms'] = $lucifer[0];
   306 			$b['perms'] = $lucifer[0];
   297 			$b['number'] = $lucifer[1];
   307 			$b['number'] = $lucifer[1];
   298 			$b['owner'] = $lucifer[2];
   308 			$b['owner'] = $lucifer[2];
   299 			$b['group'] = $lucifer[3];
   309 			$b['group'] = $lucifer[3];
   300 			$b['size'] = $lucifer[4];
   310 			$b['size'] = $lucifer[4];
   301 			if ($lcount==8) {
   311 			if ( $lcount == 8 ) {
   302 				sscanf($lucifer[5],"%d-%d-%d",$b['year'],$b['month'],$b['day']);
   312 				sscanf($lucifer[5], '%d-%d-%d', $b['year'], $b['month'], $b['day']);
   303 				sscanf($lucifer[6],"%d:%d",$b['hour'],$b['minute']);
   313 				sscanf($lucifer[6], '%d:%d', $b['hour'], $b['minute']);
   304 				$b['time'] = @mktime($b['hour'],$b['minute'],0,$b['month'],$b['day'],$b['year']);
   314 				$b['time'] = @mktime($b['hour'], $b['minute'], 0, $b['month'], $b['day'], $b['year']);
   305 				$b['name'] = $lucifer[7];
   315 				$b['name'] = $lucifer[7];
   306 			} else {
   316 			} else {
   307 				$b['month'] = $lucifer[5];
   317 				$b['month'] = $lucifer[5];
   308 				$b['day'] = $lucifer[6];
   318 				$b['day'] = $lucifer[6];
   309 				if (preg_match("/([0-9]{2}):([0-9]{2})/",$lucifer[7],$l2)) {
   319 				if ( preg_match('/([0-9]{2}):([0-9]{2})/', $lucifer[7], $l2) ) {
   310 					$b['year'] = date("Y");
   320 					$b['year'] = date("Y");
   311 					$b['hour'] = $l2[1];
   321 					$b['hour'] = $l2[1];
   312 					$b['minute'] = $l2[2];
   322 					$b['minute'] = $l2[2];
   313 				} else {
   323 				} else {
   314 					$b['year'] = $lucifer[7];
   324 					$b['year'] = $lucifer[7];
   315 					$b['hour'] = 0;
   325 					$b['hour'] = 0;
   316 					$b['minute'] = 0;
   326 					$b['minute'] = 0;
   317 				}
   327 				}
   318 				$b['time'] = strtotime(sprintf("%d %s %d %02d:%02d",$b['day'],$b['month'],$b['year'],$b['hour'],$b['minute']));
   328 				$b['time'] = strtotime( sprintf('%d %s %d %02d:%02d', $b['day'], $b['month'], $b['year'], $b['hour'], $b['minute']) );
   319 				$b['name'] = $lucifer[8];
   329 				$b['name'] = $lucifer[8];
   320 			}
   330 			}
   321 		}
   331 		}
   322 
   332 
   323 		return $b;
   333 		return $b;
   329 			$path = dirname($path) . '/';
   339 			$path = dirname($path) . '/';
   330 		} else {
   340 		} else {
   331 			$limit_file = false;
   341 			$limit_file = false;
   332 		}
   342 		}
   333 
   343 
   334 		$list = @ftp_rawlist($this->link, '-a ' . $path, false);
   344 		$pwd = @ftp_pwd($this->link);
   335 
   345 		if ( ! @ftp_chdir($this->link, $path) ) // Cant change to folder = folder doesn't exist
   336 		if ( $list === false )
   346 			return false;
       
   347 		$list = @ftp_rawlist($this->link, '-a', false);
       
   348 		@ftp_chdir($this->link, $pwd);
       
   349 
       
   350 		if ( empty($list) ) // Empty array = non-existent folder (real folder will show . at least)
   337 			return false;
   351 			return false;
   338 
   352 
   339 		$dirlist = array();
   353 		$dirlist = array();
   340 		foreach ( $list as $k => $v ) {
   354 		foreach ( $list as $k => $v ) {
   341 			$entry = $this->parselisting($v);
   355 			$entry = $this->parselisting($v);
   351 			if ( $limit_file && $entry['name'] != $limit_file)
   365 			if ( $limit_file && $entry['name'] != $limit_file)
   352 				continue;
   366 				continue;
   353 
   367 
   354 			$dirlist[ $entry['name'] ] = $entry;
   368 			$dirlist[ $entry['name'] ] = $entry;
   355 		}
   369 		}
   356 
       
   357 		if ( ! $dirlist )
       
   358 			return false;
       
   359 
   370 
   360 		$ret = array();
   371 		$ret = array();
   361 		foreach ( (array)$dirlist as $struc ) {
   372 		foreach ( (array)$dirlist as $struc ) {
   362 			if ( 'd' == $struc['type'] ) {
   373 			if ( 'd' == $struc['type'] ) {
   363 				if ( $recursive )
   374 				if ( $recursive )
   374 	function __destruct() {
   385 	function __destruct() {
   375 		if ( $this->link )
   386 		if ( $this->link )
   376 			ftp_close($this->link);
   387 			ftp_close($this->link);
   377 	}
   388 	}
   378 }
   389 }
   379 
       
   380 ?>