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') ) |
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) ) { |