Wordpress 2.8
[autoinstalls/wordpress.git] / wp-admin / includes / file.php
1 <?php
2 /**
3  * File contains all the administration image manipulation functions.
4  *
5  * @package WordPress
6  * @subpackage Administration
7  */
8
9 /** The descriptions for theme files. */
10 $wp_file_descriptions = array (
11         'index.php' => __( 'Main Index Template' ),
12         'style.css' => __( 'Stylesheet' ),
13         'rtl.css' => __( 'RTL Stylesheet' ),
14         'comments.php' => __( 'Comments' ),
15         'comments-popup.php' => __( 'Popup Comments' ),
16         'footer.php' => __( 'Footer' ),
17         'header.php' => __( 'Header' ),
18         'sidebar.php' => __( 'Sidebar' ),
19         'archive.php' => __( 'Archives' ),
20         'category.php' => __( 'Category Template' ),
21         'page.php' => __( 'Page Template' ),
22         'search.php' => __( 'Search Results' ),
23         'searchform.php' => __( 'Search Form' ),
24         'single.php' => __( 'Single Post' ),
25         '404.php' => __( '404 Template' ),
26         'link.php' => __( 'Links Template' ),
27         'functions.php' => __( 'Theme Functions' ),
28         'attachment.php' => __( 'Attachment Template' ),
29         'image.php' => __('Image Attachment Template'),
30         'video.php' => __('Video Attachment Template'),
31         'audio.php' => __('Audio Attachment Template'),
32         'application.php' => __('Application Attachment Template'),
33         'my-hacks.php' => __( 'my-hacks.php (legacy hacks support)' ),
34         '.htaccess' => __( '.htaccess (for rewrite rules )' ),
35         // Deprecated files
36         'wp-layout.css' => __( 'Stylesheet' ), 'wp-comments.php' => __( 'Comments Template' ), 'wp-comments-popup.php' => __( 'Popup Comments Template' ));
37
38 /**
39  * {@internal Missing Short Description}}
40  *
41  * @since unknown
42  *
43  * @param unknown_type $file
44  * @return unknown
45  */
46 function get_file_description( $file ) {
47         global $wp_file_descriptions;
48
49         if ( isset( $wp_file_descriptions[basename( $file )] ) ) {
50                 return $wp_file_descriptions[basename( $file )];
51         }
52         elseif ( file_exists( WP_CONTENT_DIR . $file ) && is_file( WP_CONTENT_DIR . $file ) ) {
53                 $template_data = implode( '', file( WP_CONTENT_DIR . $file ) );
54                 if ( preg_match( '|Template Name:(.*)$|mi', $template_data, $name ))
55                         return _cleanup_header_comment($name[1]) . ' Page Template';
56         }
57
58         return basename( $file );
59 }
60
61 /**
62  * {@internal Missing Short Description}}
63  *
64  * @since unknown
65  *
66  * @return unknown
67  */
68 function get_home_path() {
69         $home = get_option( 'home' );
70         $siteurl = get_option( 'siteurl' );
71         if ( $home != '' && $home != $siteurl ) {
72                 $wp_path_rel_to_home = str_replace($home, '', $siteurl); /* $siteurl - $home */
73                 $pos = strpos($_SERVER["SCRIPT_FILENAME"], $wp_path_rel_to_home);
74                 $home_path = substr($_SERVER["SCRIPT_FILENAME"], 0, $pos);
75                 $home_path = trailingslashit( $home_path );
76         } else {
77                 $home_path = ABSPATH;
78         }
79
80         return $home_path;
81 }
82
83 /**
84  * {@internal Missing Short Description}}
85  *
86  * @since unknown
87  *
88  * @param unknown_type $file
89  * @return unknown
90  */
91 function get_real_file_to_edit( $file ) {
92         if ('index.php' == $file || '.htaccess' == $file ) {
93                 $real_file = get_home_path() . $file;
94         } else {
95                 $real_file = WP_CONTENT_DIR . $file;
96         }
97
98         return $real_file;
99 }
100
101 /**
102  * {@internal Missing Short Description}}
103  *
104  * @since unknown
105  *
106  * @param string $folder Optional. Full path to folder
107  * @param int $levels Optional. Levels of folders to follow, Default: 100 (PHP Loop limit).
108  * @return bool|array
109  */
110 function list_files( $folder = '', $levels = 100 ) {
111         if( empty($folder) )
112                 return false;
113
114         if( ! $levels )
115                 return false;
116
117         $files = array();
118         if ( $dir = @opendir( $folder ) ) {
119                 while (($file = readdir( $dir ) ) !== false ) {
120                         if ( in_array($file, array('.', '..') ) )
121                                 continue;
122                         if ( is_dir( $folder . '/' . $file ) ) {
123                                 $files2 = list_files( $folder . '/' . $file, $levels - 1);
124                                 if( $files2 )
125                                         $files = array_merge($files, $files2 );
126                                 else
127                                         $files[] = $folder . '/' . $file . '/';
128                         } else {
129                                 $files[] = $folder . '/' . $file;
130                         }
131                 }
132         }
133         @closedir( $dir );
134         return $files;
135 }
136
137 /**
138  * {@internal Missing Short Description}}
139  *
140  * @since unknown
141  *
142  * @return unknown
143  */
144 function get_temp_dir() {
145         if ( defined('WP_TEMP_DIR') )
146                 return trailingslashit(WP_TEMP_DIR);
147
148         $temp = WP_CONTENT_DIR . '/';
149         if ( is_dir($temp) && is_writable($temp) )
150                 return $temp;
151
152         if  ( function_exists('sys_get_temp_dir') )
153                 return trailingslashit(sys_get_temp_dir());
154
155         return '/tmp/';
156 }
157
158 /**
159  * {@internal Missing Short Description}}
160  *
161  * @since unknown
162  *
163  * @param unknown_type $filename
164  * @param unknown_type $dir
165  * @return unknown
166  */
167 function wp_tempnam($filename = '', $dir = ''){
168         if ( empty($dir) )
169                 $dir = get_temp_dir();
170         $filename = basename($filename);
171         if ( empty($filename) )
172                 $filename = time();
173
174         $filename = $dir . wp_unique_filename($dir, $filename);
175         touch($filename);
176         return $filename;
177 }
178
179 /**
180  * {@internal Missing Short Description}}
181  *
182  * @since unknown
183  *
184  * @param unknown_type $file
185  * @param unknown_type $allowed_files
186  * @return unknown
187  */
188 function validate_file_to_edit( $file, $allowed_files = '' ) {
189         $file = stripslashes( $file );
190
191         $code = validate_file( $file, $allowed_files );
192
193         if (!$code )
194                 return $file;
195
196         switch ( $code ) {
197                 case 1 :
198                         wp_die( __('Sorry, can&#8217;t edit files with &#8220;..&#8221; in the name. If you are trying to edit a file in your WordPress home directory, you can just type the name of the file in.' ));
199
200                 case 2 :
201                         wp_die( __('Sorry, can&#8217;t call files with their real path.' ));
202
203                 case 3 :
204                         wp_die( __('Sorry, that file cannot be edited.' ));
205         }
206 }
207
208 /**
209  * {@internal Missing Short Description}}
210  *
211  * @since unknown
212  *
213  * @param array $file Reference to a single element of $_FILES. Call the function once for each uploaded file.
214  * @param array $overrides Optional. An associative array of names=>values to override default variables with extract( $overrides, EXTR_OVERWRITE ).
215  * @return array On success, returns an associative array of file attributes. On failure, returns $overrides['upload_error_handler'](&$file, $message ) or array( 'error'=>$message ).
216  */
217 function wp_handle_upload( &$file, $overrides = false, $time = null ) {
218         // The default error handler.
219         if (! function_exists( 'wp_handle_upload_error' ) ) {
220                 function wp_handle_upload_error( &$file, $message ) {
221                         return array( 'error'=>$message );
222                 }
223         }
224
225         // You may define your own function and pass the name in $overrides['upload_error_handler']
226         $upload_error_handler = 'wp_handle_upload_error';
227
228         // You may define your own function and pass the name in $overrides['unique_filename_callback']
229         $unique_filename_callback = null;
230
231         // $_POST['action'] must be set and its value must equal $overrides['action'] or this:
232         $action = 'wp_handle_upload';
233
234         // Courtesy of php.net, the strings that describe the error indicated in $_FILES[{form field}]['error'].
235         $upload_error_strings = array( false,
236                 __( "The uploaded file exceeds the <code>upload_max_filesize</code> directive in <code>php.ini</code>." ),
237                 __( "The uploaded file exceeds the <em>MAX_FILE_SIZE</em> directive that was specified in the HTML form." ),
238                 __( "The uploaded file was only partially uploaded." ),
239                 __( "No file was uploaded." ),
240                 '',
241                 __( "Missing a temporary folder." ),
242                 __( "Failed to write file to disk." ),
243                 __( "File upload stopped by extension." ));
244
245         // All tests are on by default. Most can be turned off by $override[{test_name}] = false;
246         $test_form = true;
247         $test_size = true;
248
249         // If you override this, you must provide $ext and $type!!!!
250         $test_type = true;
251         $mimes = false;
252
253         // Install user overrides. Did we mention that this voids your warranty?
254         if ( is_array( $overrides ) )
255                 extract( $overrides, EXTR_OVERWRITE );
256
257         // A correct form post will pass this test.
258         if ( $test_form && (!isset( $_POST['action'] ) || ($_POST['action'] != $action ) ) )
259                 return $upload_error_handler( $file, __( 'Invalid form submission.' ));
260
261         // A successful upload will pass this test. It makes no sense to override this one.
262         if ( $file['error'] > 0 )
263                 return $upload_error_handler( $file, $upload_error_strings[$file['error']] );
264
265         // A non-empty file will pass this test.
266         if ( $test_size && !($file['size'] > 0 ) )
267                 return $upload_error_handler( $file, __( 'File is empty. Please upload something more substantial. This error could also be caused by uploads being disabled in your php.ini.' ));
268
269         // A properly uploaded file will pass this test. There should be no reason to override this one.
270         if (! @ is_uploaded_file( $file['tmp_name'] ) )
271                 return $upload_error_handler( $file, __( 'Specified file failed upload test.' ));
272
273         // A correct MIME type will pass this test. Override $mimes or use the upload_mimes filter.
274         if ( $test_type ) {
275                 $wp_filetype = wp_check_filetype( $file['name'], $mimes );
276
277                 extract( $wp_filetype );
278
279                 if ( ( !$type || !$ext ) && !current_user_can( 'unfiltered_upload' ) )
280                         return $upload_error_handler( $file, __( 'File type does not meet security guidelines. Try another.' ));
281
282                 if ( !$ext )
283                         $ext = ltrim(strrchr($file['name'], '.'), '.');
284
285                 if ( !$type )
286                         $type = $file['type'];
287         } else {
288                 $type = '';
289         }
290
291         // A writable uploads dir will pass this test. Again, there's no point overriding this one.
292         if ( ! ( ( $uploads = wp_upload_dir($time) ) && false === $uploads['error'] ) )
293                 return $upload_error_handler( $file, $uploads['error'] );
294
295         $filename = wp_unique_filename( $uploads['path'], $file['name'], $unique_filename_callback );
296
297         // Move the file to the uploads dir
298         $new_file = $uploads['path'] . "/$filename";
299         if ( false === @ move_uploaded_file( $file['tmp_name'], $new_file ) ) {
300                 return $upload_error_handler( $file, sprintf( __('The uploaded file could not be moved to %s.' ), $uploads['path'] ) );
301         }
302
303         // Set correct file permissions
304         $stat = stat( dirname( $new_file ));
305         $perms = $stat['mode'] & 0000666;
306         @ chmod( $new_file, $perms );
307
308         // Compute the URL
309         $url = $uploads['url'] . "/$filename";
310
311         return apply_filters( 'wp_handle_upload', array( 'file' => $new_file, 'url' => $url, 'type' => $type ) );
312 }
313
314 /**
315  * {@internal Missing Short Description}}
316  *
317  * Pass this function an array similar to that of a $_FILES POST array.
318  *
319  * @since unknown
320  *
321  * @param unknown_type $file
322  * @param unknown_type $overrides
323  * @return unknown
324  */
325 function wp_handle_sideload( &$file, $overrides = false ) {
326         // The default error handler.
327         if (! function_exists( 'wp_handle_upload_error' ) ) {
328                 function wp_handle_upload_error( &$file, $message ) {
329                         return array( 'error'=>$message );
330                 }
331         }
332
333         // You may define your own function and pass the name in $overrides['upload_error_handler']
334         $upload_error_handler = 'wp_handle_upload_error';
335
336         // You may define your own function and pass the name in $overrides['unique_filename_callback']
337         $unique_filename_callback = null;
338
339         // $_POST['action'] must be set and its value must equal $overrides['action'] or this:
340         $action = 'wp_handle_sideload';
341
342         // Courtesy of php.net, the strings that describe the error indicated in $_FILES[{form field}]['error'].
343         $upload_error_strings = array( false,
344                 __( "The uploaded file exceeds the <code>upload_max_filesize</code> directive in <code>php.ini</code>." ),
345                 __( "The uploaded file exceeds the <em>MAX_FILE_SIZE</em> directive that was specified in the HTML form." ),
346                 __( "The uploaded file was only partially uploaded." ),
347                 __( "No file was uploaded." ),
348                 '',
349                 __( "Missing a temporary folder." ),
350                 __( "Failed to write file to disk." ),
351                 __( "File upload stopped by extension." ));
352
353         // All tests are on by default. Most can be turned off by $override[{test_name}] = false;
354         $test_form = true;
355         $test_size = true;
356
357         // If you override this, you must provide $ext and $type!!!!
358         $test_type = true;
359         $mimes = false;
360
361         // Install user overrides. Did we mention that this voids your warranty?
362         if ( is_array( $overrides ) )
363                 extract( $overrides, EXTR_OVERWRITE );
364
365         // A correct form post will pass this test.
366         if ( $test_form && (!isset( $_POST['action'] ) || ($_POST['action'] != $action ) ) )
367                 return $upload_error_handler( $file, __( 'Invalid form submission.' ));
368
369         // A successful upload will pass this test. It makes no sense to override this one.
370         if ( $file['error'] > 0 )
371                 return $upload_error_handler( $file, $upload_error_strings[$file['error']] );
372
373         // A non-empty file will pass this test.
374         if ( $test_size && !(filesize($file['tmp_name']) > 0 ) )
375                 return $upload_error_handler( $file, __( 'File is empty. Please upload something more substantial. This error could also be caused by uploads being disabled in your php.ini.' ));
376
377         // A properly uploaded file will pass this test. There should be no reason to override this one.
378         if (! @ is_file( $file['tmp_name'] ) )
379                 return $upload_error_handler( $file, __( 'Specified file does not exist.' ));
380
381         // A correct MIME type will pass this test. Override $mimes or use the upload_mimes filter.
382         if ( $test_type ) {
383                 $wp_filetype = wp_check_filetype( $file['name'], $mimes );
384
385                 extract( $wp_filetype );
386
387                 if ( ( !$type || !$ext ) && !current_user_can( 'unfiltered_upload' ) )
388                         return $upload_error_handler( $file, __( 'File type does not meet security guidelines. Try another.' ));
389
390                 if ( !$ext )
391                         $ext = ltrim(strrchr($file['name'], '.'), '.');
392
393                 if ( !$type )
394                         $type = $file['type'];
395         }
396
397         // A writable uploads dir will pass this test. Again, there's no point overriding this one.
398         if ( ! ( ( $uploads = wp_upload_dir() ) && false === $uploads['error'] ) )
399                 return $upload_error_handler( $file, $uploads['error'] );
400
401         $filename = wp_unique_filename( $uploads['path'], $file['name'], $unique_filename_callback );
402
403         // Strip the query strings.
404         $filename = str_replace('?','-', $filename);
405         $filename = str_replace('&','-', $filename);
406
407         // Move the file to the uploads dir
408         $new_file = $uploads['path'] . "/$filename";
409         if ( false === @ rename( $file['tmp_name'], $new_file ) ) {
410                 return $upload_error_handler( $file, sprintf( __('The uploaded file could not be moved to %s.' ), $uploads['path'] ) );
411         }
412
413         // Set correct file permissions
414         $stat = stat( dirname( $new_file ));
415         $perms = $stat['mode'] & 0000666;
416         @ chmod( $new_file, $perms );
417
418         // Compute the URL
419         $url = $uploads['url'] . "/$filename";
420
421         $return = apply_filters( 'wp_handle_upload', array( 'file' => $new_file, 'url' => $url, 'type' => $type ) );
422
423         return $return;
424 }
425
426 /**
427  * Downloads a url to a local file using the Snoopy HTTP Class.
428  *
429  * @since unknown
430  * @todo Transition over to using the new HTTP Request API (jacob).
431  *
432  * @param string $url the URL of the file to download
433  * @return mixed WP_Error on failure, string Filename on success.
434  */
435 function download_url( $url ) {
436         //WARNING: The file is not automatically deleted, The script must unlink() the file.
437         if ( ! $url )
438                 return new WP_Error('http_no_url', __('Invalid URL Provided'));
439
440         $tmpfname = wp_tempnam($url);
441         if ( ! $tmpfname )
442                 return new WP_Error('http_no_file', __('Could not create Temporary file'));
443
444         $handle = @fopen($tmpfname, 'wb');
445         if ( ! $handle )
446                 return new WP_Error('http_no_file', __('Could not create Temporary file'));
447
448         $response = wp_remote_get($url, array('timeout' => 30));
449
450         if ( is_wp_error($response) ) {
451                 fclose($handle);
452                 unlink($tmpfname);
453                 return $response;
454         }
455
456         if ( $response['response']['code'] != '200' ){
457                 fclose($handle);
458                 unlink($tmpfname);
459                 return new WP_Error('http_404', trim($response['response']['message']));
460         }
461
462         fwrite($handle, $response['body']);
463         fclose($handle);
464
465         return $tmpfname;
466 }
467
468 /**
469  * {@internal Missing Short Description}}
470  *
471  * @since unknown
472  *
473  * @param unknown_type $file
474  * @param unknown_type $to
475  * @return unknown
476  */
477 function unzip_file($file, $to) {
478         global $wp_filesystem;
479
480         if ( ! $wp_filesystem || !is_object($wp_filesystem) )
481                 return new WP_Error('fs_unavailable', __('Could not access filesystem.'));
482
483         // Unzip uses a lot of memory
484         @ini_set('memory_limit', '256M');
485
486         $fs =& $wp_filesystem;
487
488         require_once(ABSPATH . 'wp-admin/includes/class-pclzip.php');
489
490         $archive = new PclZip($file);
491
492         // Is the archive valid?
493         if ( false == ($archive_files = $archive->extract(PCLZIP_OPT_EXTRACT_AS_STRING)) )
494                 return new WP_Error('incompatible_archive', __('Incompatible archive'), $archive->errorInfo(true));
495
496         if ( 0 == count($archive_files) )
497                 return new WP_Error('empty_archive', __('Empty archive'));
498
499         $path = explode('/', untrailingslashit($to));
500         for ( $i = count($path); $i > 0; $i-- ) { //>0 = first element is empty allways for paths starting with '/'
501                 $tmppath = implode('/', array_slice($path, 0, $i) );
502                 if ( $fs->is_dir($tmppath) ) { //Found the highest folder that exists, Create from here(ie +1)
503                         for ( $i = $i + 1; $i <= count($path); $i++ ) {
504                                 $tmppath = implode('/', array_slice($path, 0, $i) );
505                                 if ( ! $fs->mkdir($tmppath, FS_CHMOD_DIR) )
506                                         return new WP_Error('mkdir_failed', __('Could not create directory'), $tmppath);
507                         }
508                         break; //Exit main for loop
509                 }
510         }
511
512         $to = trailingslashit($to);
513         foreach ($archive_files as $file) {
514                 $path = $file['folder'] ? $file['filename'] : dirname($file['filename']);
515                 $path = explode('/', $path);
516                 for ( $i = count($path); $i >= 0; $i-- ) { //>=0 as the first element contains data
517                         if ( empty($path[$i]) )
518                                 continue;
519                         $tmppath = $to . implode('/', array_slice($path, 0, $i) );
520                         if ( $fs->is_dir($tmppath) ) {//Found the highest folder that exists, Create from here
521                                 for ( $i = $i + 1; $i <= count($path); $i++ ) { //< count() no file component please.
522                                         $tmppath = $to . implode('/', array_slice($path, 0, $i) );
523                                         if ( ! $fs->is_dir($tmppath) && ! $fs->mkdir($tmppath, FS_CHMOD_DIR) )
524                                                 return new WP_Error('mkdir_failed', __('Could not create directory'), $tmppath);
525                                 }
526                                 break; //Exit main for loop
527                         }
528                 }
529
530                 // We've made sure the folders are there, so let's extract the file now:
531                 if ( ! $file['folder'] ) {
532                         if ( !$fs->put_contents( $to . $file['filename'], $file['content']) )
533                                 return new WP_Error('copy_failed', __('Could not copy file'), $to . $file['filename']);
534                         $fs->chmod($to . $file['filename'], FS_CHMOD_FILE);
535                 }
536         }
537         return true;
538 }
539
540 /**
541  * {@internal Missing Short Description}}
542  *
543  * @since unknown
544  *
545  * @param unknown_type $from
546  * @param unknown_type $to
547  * @return unknown
548  */
549 function copy_dir($from, $to) {
550         global $wp_filesystem;
551
552         $dirlist = $wp_filesystem->dirlist($from);
553
554         $from = trailingslashit($from);
555         $to = trailingslashit($to);
556
557         foreach ( (array) $dirlist as $filename => $fileinfo ) {
558                 if ( 'f' == $fileinfo['type'] ) {
559                         if ( ! $wp_filesystem->copy($from . $filename, $to . $filename, true) ) {
560                                 // If copy failed, chmod file to 0644 and try again.
561                                 $wp_filesystem->chmod($to . $filename, 0644);
562                                 if ( ! $wp_filesystem->copy($from . $filename, $to . $filename, true) )
563                                         return new WP_Error('copy_failed', __('Could not copy file'), $to . $filename);
564                         }
565                         $wp_filesystem->chmod($to . $filename, FS_CHMOD_FILE);
566                 } elseif ( 'd' == $fileinfo['type'] ) {
567                         if ( !$wp_filesystem->is_dir($to . $filename) ) {
568                                 if ( !$wp_filesystem->mkdir($to . $filename, FS_CHMOD_DIR) )
569                                         return new WP_Error('mkdir_failed', __('Could not create directory'), $to . $filename);
570                         }
571                         $result = copy_dir($from . $filename, $to . $filename);
572                         if ( is_wp_error($result) )
573                                 return $result;
574                 }
575         }
576 }
577
578 /**
579  * {@internal Missing Short Description}}
580  *
581  * @since unknown
582  *
583  * @param unknown_type $args
584  * @return unknown
585  */
586 function WP_Filesystem( $args = false, $context = false ) {
587         global $wp_filesystem;
588
589         require_once(ABSPATH . 'wp-admin/includes/class-wp-filesystem-base.php');
590
591         $method = get_filesystem_method($args, $context);
592
593         if ( ! $method )
594                 return false;
595
596         if ( ! class_exists("WP_Filesystem_$method") ) {
597                 $abstraction_file = apply_filters('filesystem_method_file', ABSPATH . 'wp-admin/includes/class-wp-filesystem-' . $method . '.php', $method);
598                 if( ! file_exists($abstraction_file) )
599                         return;
600         
601                 require_once($abstraction_file);
602         }
603         $method = "WP_Filesystem_$method";
604
605         $wp_filesystem = new $method($args);
606
607         if ( is_wp_error($wp_filesystem->errors) && $wp_filesystem->errors->get_error_code() )
608                 return false;
609
610         if ( !$wp_filesystem->connect() )
611                 return false; //There was an erorr connecting to the server.
612
613         // Set the permission constants if not already set.
614         if ( ! defined('FS_CHMOD_DIR') )
615                 define('FS_CHMOD_DIR', 0755 );
616         if ( ! defined('FS_CHMOD_FILE') )
617                 define('FS_CHMOD_FILE', 0644 );
618
619         return true;
620 }
621
622 /**
623  * {@internal Missing Short Description}}
624  *
625  * @since unknown
626  *
627  * @param unknown_type $args
628  * @param string $context Full path to the directory that is tested for being writable.
629  * @return unknown
630  */
631 function get_filesystem_method($args = array(), $context = false) {
632         $method = defined('FS_METHOD') ? FS_METHOD : false; //Please ensure that this is either 'direct', 'ssh', 'ftpext' or 'ftpsockets'
633
634         if( ! $method && function_exists('getmyuid') && function_exists('fileowner') ){
635                 if ( !$context )
636                         $context = WP_CONTENT_DIR;
637                 $context = trailingslashit($context);
638                 $temp_file_name = $context . '.write-test-' . time();
639                 $temp_handle = @fopen($temp_file_name, 'w');
640                 if ( $temp_handle ) {
641                         if ( getmyuid() == fileowner($temp_file_name) )
642                                 $method = 'direct';
643                         @fclose($temp_handle);
644                         unlink($temp_file_name);
645                 }
646         }
647
648         if ( ! $method && isset($args['connection_type']) && 'ssh' == $args['connection_type'] && extension_loaded('ssh2') && extension_loaded('sockets') ) $method = 'ssh2';
649         if ( ! $method && extension_loaded('ftp') ) $method = 'ftpext';
650         if ( ! $method && ( extension_loaded('sockets') || function_exists('fsockopen') ) ) $method = 'ftpsockets'; //Sockets: Socket extension; PHP Mode: FSockopen / fwrite / fread
651         return apply_filters('filesystem_method', $method, $args);
652 }
653
654 /**
655  * {@internal Missing Short Description}}
656  *
657  * @since unknown
658  *
659  * @param unknown_type $form_post
660  * @param unknown_type $type
661  * @param unknown_type $error
662  * @return unknown
663  */
664 function request_filesystem_credentials($form_post, $type = '', $error = false, $context = false) {
665         $req_cred = apply_filters('request_filesystem_credentials', '', $form_post, $type, $error, $context);
666         if ( '' !== $req_cred )
667                 return $req_cred;
668
669         if ( empty($type) )
670                 $type = get_filesystem_method(array(), $context);
671
672         if ( 'direct' == $type )
673                 return true;
674
675         $credentials = get_option('ftp_credentials', array( 'hostname' => '', 'username' => ''));
676
677         // If defined, set it to that, Else, If POST'd, set it to that, If not, Set it to whatever it previously was(saved details in option)
678         $credentials['hostname'] = defined('FTP_HOST') ? FTP_HOST : (!empty($_POST['hostname']) ? $_POST['hostname'] : $credentials['hostname']);
679         $credentials['username'] = defined('FTP_USER') ? FTP_USER : (!empty($_POST['username']) ? $_POST['username'] : $credentials['username']);
680         $credentials['password'] = defined('FTP_PASS') ? FTP_PASS : (!empty($_POST['password']) ? $_POST['password'] : '');
681
682         // Check to see if we are setting the public/private keys for ssh
683         $credentials['public_key'] = defined('FTP_PUBKEY') ? FTP_PUBKEY : (!empty($_POST['public_key']) ? $_POST['public_key'] : '');
684         $credentials['private_key'] = defined('FTP_PRIKEY') ? FTP_PRIKEY : (!empty($_POST['private_key']) ? $_POST['private_key'] : '');
685
686         //sanitize the hostname, Some people might pass in odd-data:
687         $credentials['hostname'] = preg_replace('|\w+://|', '', $credentials['hostname']); //Strip any schemes off
688
689         if ( strpos($credentials['hostname'], ':') )
690                 list( $credentials['hostname'], $credentials['port'] ) = explode(':', $credentials['hostname'], 2);
691         else
692                 unset($credentials['port']);
693
694         if ( defined('FTP_SSH') || (defined('FS_METHOD') && 'ssh' == FS_METHOD) )
695                 $credentials['connection_type'] = 'ssh';
696         else if ( defined('FTP_SSL') && 'ftpext' == $type ) //Only the FTP Extension understands SSL
697                 $credentials['connection_type'] = 'ftps';
698         else if ( !empty($_POST['connection_type']) )
699                 $credentials['connection_type'] = $_POST['connection_type'];
700         else if ( !isset($credentials['connection_type']) ) //All else fails (And its not defaulted to something else saved), Default to FTP
701                 $credentials['connection_type'] = 'ftp';
702
703         if ( ! $error &&
704                         (
705                                 ( !empty($credentials['password']) && !empty($credentials['username']) && !empty($credentials['hostname']) ) ||
706                                 ( 'ssh' == $credentials['connection_type'] && !empty($credentials['public_key']) && !empty($credentials['private_key']) )
707                         ) ) {
708                 $stored_credentials = $credentials;
709                 if ( !empty($stored_credentials['port']) ) //save port as part of hostname to simplify above code.
710                         $stored_credentials['hostname'] .= ':' . $stored_credentials['port'];
711
712                 unset($stored_credentials['password'], $stored_credentials['port'], $stored_credentials['private_key'], $stored_credentials['public_key']);
713                 update_option('ftp_credentials', $stored_credentials);
714                 return $credentials;
715         }
716         $hostname = '';
717         $username = '';
718         $password = '';
719         $connection_type = '';
720         if ( !empty($credentials) )
721                 extract($credentials, EXTR_OVERWRITE);
722         if ( $error ) {
723                 $error_string = __('<strong>Error:</strong> There was an error connecting to the server, Please verify the settings are correct.');
724                 if ( is_wp_error($error) )
725                         $error_string = $error->get_error_message();
726                 echo '<div id="message" class="error"><p>' . $error_string . '</p></div>';
727         }
728 ?>
729 <script type="text/javascript">
730 <!--
731 jQuery(function($){
732         jQuery("#ssh").click(function () {
733                 jQuery("#ssh_keys").show();
734         });
735         jQuery("#ftp, #ftps").click(function () {
736                 jQuery("#ssh_keys").hide();
737         });
738         jQuery('form input[value=""]:first').focus();
739 });
740 -->
741 </script>
742 <form action="<?php echo $form_post ?>" method="post">
743 <div class="wrap">
744 <?php screen_icon(); ?>
745 <h2><?php _e('Connection Information') ?></h2>
746 <p><?php _e('To perform the requested action, connection information is required.') ?></p>
747
748 <table class="form-table">
749 <tr valign="top">
750 <th scope="row"><label for="hostname"><?php _e('Hostname') ?></label></th>
751 <td><input name="hostname" type="text" id="hostname" value="<?php echo esc_attr($hostname); if ( !empty($port) ) echo ":$port"; ?>"<?php if( defined('FTP_HOST') ) echo ' disabled="disabled"' ?> size="40" /></td>
752 </tr>
753
754 <tr valign="top">
755 <th scope="row"><label for="username"><?php _e('Username') ?></label></th>
756 <td><input name="username" type="text" id="username" value="<?php echo esc_attr($username) ?>"<?php if( defined('FTP_USER') ) echo ' disabled="disabled"' ?> size="40" /></td>
757 </tr>
758
759 <tr valign="top">
760 <th scope="row"><label for="password"><?php _e('Password') ?></label></th>
761 <td><input name="password" type="password" id="password" value="<?php if ( defined('FTP_PASS') ) echo '*****'; ?>"<?php if ( defined('FTP_PASS') ) echo ' disabled="disabled"' ?> size="40" /></td>
762 </tr>
763
764 <?php if ( extension_loaded('ssh2') ) : ?>
765 <tr id="ssh_keys" valign="top" style="<?php if ( 'ssh' != $connection_type ) echo 'display:none' ?>">
766 <th scope="row"><?php _e('Authentication Keys') ?>
767 <div class="key-labels textright">
768 <label for="public_key"><?php _e('Public Key:') ?></label ><br />
769 <label for="private_key"><?php _e('Private Key:') ?></label>
770 </div></th>
771 <td><br /><input name="public_key" type="text" id="public_key" value="<?php echo esc_attr($public_key) ?>"<?php if( defined('FTP_PUBKEY') ) echo ' disabled="disabled"' ?> size="40" /><br /><input name="private_key" type="text" id="private_key" value="<?php echo esc_attr($private_key) ?>"<?php if( defined('FTP_PRIKEY') ) echo ' disabled="disabled"' ?> size="40" />
772 <div><?php _e('Enter the location on the server where the keys are located. If a passphrase is needed, enter that in the password field above.') ?></div></td>
773 </tr>
774 <?php endif; ?>
775
776 <tr valign="top">
777 <th scope="row"><?php _e('Connection Type') ?></th>
778 <td>
779 <fieldset><legend class="screen-reader-text"><span><?php _e('Connection Type') ?></span></legend>
780 <label><input id="ftp" name="connection_type"  type="radio" value="ftp" <?php checked('ftp', $connection_type); if ( defined('FTP_SSL') || defined('FTP_SSH') ) echo ' disabled="disabled"'; ?>/> <?php _e('FTP') ?></label>
781 <?php if ( 'ftpext' == $type ) : ?>
782 <br /><label><input id="ftps" name="connection_type" type="radio" value="ftps" <?php checked('ftps', $connection_type); if ( defined('FTP_SSL') || defined('FTP_SSH') ) echo ' disabled="disabled"';  ?>/> <?php _e('FTPS (SSL)') ?></label>
783 <?php endif; ?>
784 <?php if ( extension_loaded('ssh2') ) : ?>
785 <br /><label><input id="ssh" name="connection_type" type="radio" value="ssh" <?php checked('ssh', $connection_type);  if ( defined('FTP_SSL') || defined('FTP_SSH') ) echo ' disabled="disabled"'; ?>/> <?php _e('SSH') ?></label>
786 <?php endif; ?>
787 </fieldset>
788 </td>
789 </tr>
790 </table>
791
792 <?php if ( isset( $_POST['version'] ) ) : ?>
793 <input type="hidden" name="version" value="<?php echo esc_attr($_POST['version']) ?>" />
794 <?php endif; ?>
795 <?php if ( isset( $_POST['locale'] ) ) : ?>
796 <input type="hidden" name="locale" value="<?php echo esc_attr($_POST['locale']) ?>" />
797 <?php endif; ?>
798 <p class="submit">
799 <input id="upgrade" name="upgrade" type="submit" class="button" value="<?php esc_attr_e('Proceed'); ?>" />
800 </p>
801 </div>
802 </form>
803 <?php
804         return false;
805 }
806
807 ?>