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 */ |