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); |