| [ Root ] [ Search ] [ Index ] |
PHP Cross Reference of WordPress 3.0Provided by Yoast |
[Summary view] [Print] [Text view]
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 'editor-style.css' => __( 'Visual Editor Stylesheet' ), 14 'rtl.css' => __( 'RTL Stylesheet' ), 15 'comments.php' => __( 'Comments' ), 16 'comments-popup.php' => __( 'Popup Comments' ), 17 'footer.php' => __( 'Footer' ), 18 'header.php' => __( 'Header' ), 19 'sidebar.php' => __( 'Sidebar' ), 20 'archive.php' => __( 'Archives' ), 21 'author.php' => __( 'Author Template' ), 22 'tag.php' => __( 'Tag Template' ), 23 'category.php' => __( 'Category Template' ), 24 'page.php' => __( 'Page Template' ), 25 'search.php' => __( 'Search Results' ), 26 'searchform.php' => __( 'Search Form' ), 27 'single.php' => __( 'Single Post' ), 28 '404.php' => __( '404 Template' ), 29 'link.php' => __( 'Links Template' ), 30 'functions.php' => __( 'Theme Functions' ), 31 'attachment.php' => __( 'Attachment Template' ), 32 'image.php' => __('Image Attachment Template'), 33 'video.php' => __('Video Attachment Template'), 34 'audio.php' => __('Audio Attachment Template'), 35 'application.php' => __('Application Attachment Template'), 36 'my-hacks.php' => __( 'my-hacks.php (legacy hacks support)' ), 37 '.htaccess' => __( '.htaccess (for rewrite rules )' ), 38 // Deprecated files 39 'wp-layout.css' => __( 'Stylesheet' ), 'wp-comments.php' => __( 'Comments Template' ), 'wp-comments-popup.php' => __( 'Popup Comments Template' )); 40 41 /** 42 * {@internal Missing Short Description}} 43 * 44 * @since unknown 45 * 46 * @param unknown_type $file 47 * @return unknown 48 */ 49 function get_file_description( $file ) { 50 global $wp_file_descriptions; 51 52 if ( isset( $wp_file_descriptions[basename( $file )] ) ) { 53 return $wp_file_descriptions[basename( $file )]; 54 } 55 elseif ( file_exists( $file ) && is_file( $file ) ) { 56 $template_data = implode( '', file( $file ) ); 57 if ( preg_match( '|Template Name:(.*)$|mi', $template_data, $name )) 58 return _cleanup_header_comment($name[1]) . ' Page Template'; 59 } 60 61 return basename( $file ); 62 } 63 64 /** 65 * {@internal Missing Short Description}} 66 * 67 * @since unknown 68 * 69 * @return unknown 70 */ 71 function get_home_path() { 72 $home = get_option( 'home' ); 73 $siteurl = get_option( 'siteurl' ); 74 if ( $home != '' && $home != $siteurl ) { 75 $wp_path_rel_to_home = str_replace($home, '', $siteurl); /* $siteurl - $home */ 76 $pos = strpos($_SERVER["SCRIPT_FILENAME"], $wp_path_rel_to_home); 77 $home_path = substr($_SERVER["SCRIPT_FILENAME"], 0, $pos); 78 $home_path = trailingslashit( $home_path ); 79 } else { 80 $home_path = ABSPATH; 81 } 82 83 return $home_path; 84 } 85 86 /** 87 * {@internal Missing Short Description}} 88 * 89 * @since unknown 90 * 91 * @param unknown_type $file 92 * @return unknown 93 */ 94 function get_real_file_to_edit( $file ) { 95 if ('index.php' == $file || '.htaccess' == $file ) { 96 $real_file = get_home_path() . $file; 97 } else { 98 $real_file = WP_CONTENT_DIR . $file; 99 } 100 101 return $real_file; 102 } 103 104 /** 105 * Returns a listing of all files in the specified folder and all subdirectories up to 100 levels deep. 106 * The depth of the recursiveness can be controlled by the $levels param. 107 * 108 * @since 2.6.0 109 * 110 * @param string $folder Full path to folder 111 * @param int $levels (optional) Levels of folders to follow, Default: 100 (PHP Loop limit). 112 * @return bool|array False on failure, Else array of files 113 */ 114 function list_files( $folder = '', $levels = 100 ) { 115 if ( empty($folder) ) 116 return false; 117 118 if ( ! $levels ) 119 return false; 120 121 $files = array(); 122 if ( $dir = @opendir( $folder ) ) { 123 while (($file = readdir( $dir ) ) !== false ) { 124 if ( in_array($file, array('.', '..') ) ) 125 continue; 126 if ( is_dir( $folder . '/' . $file ) ) { 127 $files2 = list_files( $folder . '/' . $file, $levels - 1); 128 if ( $files2 ) 129 $files = array_merge($files, $files2 ); 130 else 131 $files[] = $folder . '/' . $file . '/'; 132 } else { 133 $files[] = $folder . '/' . $file; 134 } 135 } 136 } 137 @closedir( $dir ); 138 return $files; 139 } 140 141 /** 142 * Determines a writable directory for temporary files. 143 * Function's preference is to WP_CONTENT_DIR followed by the return value of <code>sys_get_temp_dir()</code>, before finally defaulting to /tmp/ 144 * 145 * In the event that this function does not find a writable location, It may be overridden by the <code>WP_TEMP_DIR</code> constant in your <code>wp-config.php</code> file. 146 * 147 * @since 2.5.0 148 * 149 * @return string Writable temporary directory 150 */ 151 function get_temp_dir() { 152 static $temp; 153 if ( defined('WP_TEMP_DIR') ) 154 return trailingslashit(WP_TEMP_DIR); 155 156 if ( $temp ) 157 return trailingslashit($temp); 158 159 $temp = WP_CONTENT_DIR . '/'; 160 if ( is_dir($temp) && @is_writable($temp) ) 161 return $temp; 162 163 if ( function_exists('sys_get_temp_dir') ) { 164 $temp = sys_get_temp_dir(); 165 if ( @is_writable($temp) ) 166 return trailingslashit($temp); 167 } 168 169 $temp = ini_get('upload_tmp_dir'); 170 if ( is_dir($temp) && @is_writable($temp) ) 171 return trailingslashit($temp); 172 173 $temp = '/tmp/'; 174 return $temp; 175 } 176 177 /** 178 * Returns a filename of a Temporary unique file. 179 * Please note that the calling function must unlink() this itself. 180 * 181 * The filename is based off the passed parameter or defaults to the current unix timestamp, 182 * while the directory can either be passed as well, or by leaving it blank, default to a writable temporary directory. 183 * 184 * @since 2.6.0 185 * 186 * @param string $filename (optional) Filename to base the Unique file off 187 * @param string $dir (optional) Directory to store the file in 188 * @return string a writable filename 189 */ 190 function wp_tempnam($filename = '', $dir = '') { 191 if ( empty($dir) ) 192 $dir = get_temp_dir(); 193 $filename = basename($filename); 194 if ( empty($filename) ) 195 $filename = time(); 196 197 $filename = preg_replace('|\..*$|', '.tmp', $filename); 198 $filename = $dir . wp_unique_filename($dir, $filename); 199 touch($filename); 200 return $filename; 201 } 202 203 /** 204 * {@internal Missing Short Description}} 205 * 206 * @since unknown 207 * 208 * @param unknown_type $file 209 * @param unknown_type $allowed_files 210 * @return unknown 211 */ 212 function validate_file_to_edit( $file, $allowed_files = '' ) { 213 $code = validate_file( $file, $allowed_files ); 214 215 if (!$code ) 216 return $file; 217 218 switch ( $code ) { 219 case 1 : 220 wp_die( __('Sorry, can’t edit files with “..” 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.' )); 221 222 //case 2 : 223 // wp_die( __('Sorry, can’t call files with their real path.' )); 224 225 case 3 : 226 wp_die( __('Sorry, that file cannot be edited.' )); 227 } 228 } 229 230 /** 231 * {@internal Missing Short Description}} 232 * 233 * @since unknown 234 * 235 * @param array $file Reference to a single element of $_FILES. Call the function once for each uploaded file. 236 * @param array $overrides Optional. An associative array of names=>values to override default variables with extract( $overrides, EXTR_OVERWRITE ). 237 * @return array On success, returns an associative array of file attributes. On failure, returns $overrides['upload_error_handler'](&$file, $message ) or array( 'error'=>$message ). 238 */ 239 function wp_handle_upload( &$file, $overrides = false, $time = null ) { 240 // The default error handler. 241 if ( ! function_exists( 'wp_handle_upload_error' ) ) { 242 function wp_handle_upload_error( &$file, $message ) { 243 return array( 'error'=>$message ); 244 } 245 } 246 247 $file = apply_filters( 'wp_handle_upload_prefilter', $file ); 248 249 // You may define your own function and pass the name in $overrides['upload_error_handler'] 250 $upload_error_handler = 'wp_handle_upload_error'; 251 252 // You may have had one or more 'wp_handle_upload_prefilter' functions error out the file. Handle that gracefully. 253 if ( isset( $file['error'] ) && !is_numeric( $file['error'] ) && $file['error'] ) 254 return $upload_error_handler( $file, $file['error'] ); 255 256 // You may define your own function and pass the name in $overrides['unique_filename_callback'] 257 $unique_filename_callback = null; 258 259 // $_POST['action'] must be set and its value must equal $overrides['action'] or this: 260 $action = 'wp_handle_upload'; 261 262 // Courtesy of php.net, the strings that describe the error indicated in $_FILES[{form field}]['error']. 263 $upload_error_strings = array( false, 264 __( "The uploaded file exceeds the <code>upload_max_filesize</code> directive in <code>php.ini</code>." ), 265 __( "The uploaded file exceeds the <em>MAX_FILE_SIZE</em> directive that was specified in the HTML form." ), 266 __( "The uploaded file was only partially uploaded." ), 267 __( "No file was uploaded." ), 268 '', 269 __( "Missing a temporary folder." ), 270 __( "Failed to write file to disk." ), 271 __( "File upload stopped by extension." )); 272 273 // All tests are on by default. Most can be turned off by $override[{test_name}] = false; 274 $test_form = true; 275 $test_size = true; 276 $test_upload = true; 277 278 // If you override this, you must provide $ext and $type!!!! 279 $test_type = true; 280 $mimes = false; 281 282 // Install user overrides. Did we mention that this voids your warranty? 283 if ( is_array( $overrides ) ) 284 extract( $overrides, EXTR_OVERWRITE ); 285 286 // A correct form post will pass this test. 287 if ( $test_form && (!isset( $_POST['action'] ) || ($_POST['action'] != $action ) ) ) 288 return call_user_func($upload_error_handler, $file, __( 'Invalid form submission.' )); 289 290 // A successful upload will pass this test. It makes no sense to override this one. 291 if ( $file['error'] > 0 ) 292 return call_user_func($upload_error_handler, $file, $upload_error_strings[$file['error']] ); 293 294 // A non-empty file will pass this test. 295 if ( $test_size && !($file['size'] > 0 ) ) { 296 if ( is_multisite() ) 297 $error_msg = __( 'File is empty. Please upload something more substantial.' ); 298 else 299 $error_msg = __( 'File is empty. Please upload something more substantial. This error could also be caused by uploads being disabled in your php.ini or by post_max_size being defined as smaller than upload_max_filesize in php.ini.' ); 300 return call_user_func($upload_error_handler, $file, $error_msg); 301 } 302 303 // A properly uploaded file will pass this test. There should be no reason to override this one. 304 if ( $test_upload && ! @ is_uploaded_file( $file['tmp_name'] ) ) 305 return call_user_func($upload_error_handler, $file, __( 'Specified file failed upload test.' )); 306 307 // A correct MIME type will pass this test. Override $mimes or use the upload_mimes filter. 308 if ( $test_type ) { 309 $wp_filetype = wp_check_filetype_and_ext( $file['tmp_name'], $file['name'], $mimes ); 310 311 extract( $wp_filetype ); 312 313 // Check to see if wp_check_filetype_and_ext() determined the filename was incorrect 314 if ( $proper_filename ) 315 $file['name'] = $proper_filename; 316 317 if ( ( !$type || !$ext ) && !current_user_can( 'unfiltered_upload' ) ) 318 return call_user_func($upload_error_handler, $file, __( 'File type does not meet security guidelines. Try another.' )); 319 320 if ( !$ext ) 321 $ext = ltrim(strrchr($file['name'], '.'), '.'); 322 323 if ( !$type ) 324 $type = $file['type']; 325 } else { 326 $type = ''; 327 } 328 329 // A writable uploads dir will pass this test. Again, there's no point overriding this one. 330 if ( ! ( ( $uploads = wp_upload_dir($time) ) && false === $uploads['error'] ) ) 331 return call_user_func($upload_error_handler, $file, $uploads['error'] ); 332 333 $filename = wp_unique_filename( $uploads['path'], $file['name'], $unique_filename_callback ); 334 335 // Move the file to the uploads dir 336 $new_file = $uploads['path'] . "/$filename"; 337 if ( false === @ move_uploaded_file( $file['tmp_name'], $new_file ) ) 338 return $upload_error_handler( $file, sprintf( __('The uploaded file could not be moved to %s.' ), $uploads['path'] ) ); 339 340 // Set correct file permissions 341 $stat = stat( dirname( $new_file )); 342 $perms = $stat['mode'] & 0000666; 343 @ chmod( $new_file, $perms ); 344 345 // Compute the URL 346 $url = $uploads['url'] . "/$filename"; 347 348 if ( is_multisite() ) 349 delete_transient( 'dirsize_cache' ); 350 351 return apply_filters( 'wp_handle_upload', array( 'file' => $new_file, 'url' => $url, 'type' => $type ), 'upload' ); 352 } 353 354 /** 355 * {@internal Missing Short Description}} 356 * 357 * Pass this function an array similar to that of a $_FILES POST array. 358 * 359 * @since unknown 360 * 361 * @param unknown_type $file 362 * @param unknown_type $overrides 363 * @return unknown 364 */ 365 function wp_handle_sideload( &$file, $overrides = false ) { 366 // The default error handler. 367 if (! function_exists( 'wp_handle_upload_error' ) ) { 368 function wp_handle_upload_error( &$file, $message ) { 369 return array( 'error'=>$message ); 370 } 371 } 372 373 // You may define your own function and pass the name in $overrides['upload_error_handler'] 374 $upload_error_handler = 'wp_handle_upload_error'; 375 376 // You may define your own function and pass the name in $overrides['unique_filename_callback'] 377 $unique_filename_callback = null; 378 379 // $_POST['action'] must be set and its value must equal $overrides['action'] or this: 380 $action = 'wp_handle_sideload'; 381 382 // Courtesy of php.net, the strings that describe the error indicated in $_FILES[{form field}]['error']. 383 $upload_error_strings = array( false, 384 __( "The uploaded file exceeds the <code>upload_max_filesize</code> directive in <code>php.ini</code>." ), 385 __( "The uploaded file exceeds the <em>MAX_FILE_SIZE</em> directive that was specified in the HTML form." ), 386 __( "The uploaded file was only partially uploaded." ), 387 __( "No file was uploaded." ), 388 '', 389 __( "Missing a temporary folder." ), 390 __( "Failed to write file to disk." ), 391 __( "File upload stopped by extension." )); 392 393 // All tests are on by default. Most can be turned off by $override[{test_name}] = false; 394 $test_form = true; 395 $test_size = true; 396 397 // If you override this, you must provide $ext and $type!!!! 398 $test_type = true; 399 $mimes = false; 400 401 // Install user overrides. Did we mention that this voids your warranty? 402 if ( is_array( $overrides ) ) 403 extract( $overrides, EXTR_OVERWRITE ); 404 405 // A correct form post will pass this test. 406 if ( $test_form && (!isset( $_POST['action'] ) || ($_POST['action'] != $action ) ) ) 407 return $upload_error_handler( $file, __( 'Invalid form submission.' )); 408 409 // A successful upload will pass this test. It makes no sense to override this one. 410 if ( ! empty( $file['error'] ) ) 411 return $upload_error_handler( $file, $upload_error_strings[$file['error']] ); 412 413 // A non-empty file will pass this test. 414 if ( $test_size && !(filesize($file['tmp_name']) > 0 ) ) 415 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.' )); 416 417 // A properly uploaded file will pass this test. There should be no reason to override this one. 418 if (! @ is_file( $file['tmp_name'] ) ) 419 return $upload_error_handler( $file, __( 'Specified file does not exist.' )); 420 421 // A correct MIME type will pass this test. Override $mimes or use the upload_mimes filter. 422 if ( $test_type ) { 423 $wp_filetype = wp_check_filetype_and_ext( $file['tmp_name'], $file['name'], $mimes ); 424 425 extract( $wp_filetype ); 426 427 // Check to see if wp_check_filetype_and_ext() determined the filename was incorrect 428 if ( $proper_filename ) 429 $file['name'] = $proper_filename; 430 431 if ( ( !$type || !$ext ) && !current_user_can( 'unfiltered_upload' ) ) 432 return $upload_error_handler( $file, __( 'File type does not meet security guidelines. Try another.' )); 433 434 if ( !$ext ) 435 $ext = ltrim(strrchr($file['name'], '.'), '.'); 436 437 if ( !$type ) 438 $type = $file['type']; 439 } 440 441 // A writable uploads dir will pass this test. Again, there's no point overriding this one. 442 if ( ! ( ( $uploads = wp_upload_dir() ) && false === $uploads['error'] ) ) 443 return $upload_error_handler( $file, $uploads['error'] ); 444 445 $filename = wp_unique_filename( $uploads['path'], $file['name'], $unique_filename_callback ); 446 447 // Strip the query strings. 448 $filename = str_replace('?','-', $filename); 449 $filename = str_replace('&','-', $filename); 450 451 // Move the file to the uploads dir 452 $new_file = $uploads['path'] . "/$filename"; 453 if ( false === @ rename( $file['tmp_name'], $new_file ) ) { 454 return $upload_error_handler( $file, sprintf( __('The uploaded file could not be moved to %s.' ), $uploads['path'] ) ); 455 } 456 457 // Set correct file permissions 458 $stat = stat( dirname( $new_file )); 459 $perms = $stat['mode'] & 0000666; 460 @ chmod( $new_file, $perms ); 461 462 // Compute the URL 463 $url = $uploads['url'] . "/$filename"; 464 465 $return = apply_filters( 'wp_handle_upload', array( 'file' => $new_file, 'url' => $url, 'type' => $type ), 'sideload' ); 466 467 return $return; 468 } 469 470 /** 471 * Downloads a url to a local temporary file using the WordPress HTTP Class. 472 * Please note, That the calling function must unlink() the file. 473 * 474 * @since 2.5.0 475 * 476 * @param string $url the URL of the file to download 477 * @return mixed WP_Error on failure, string Filename on success. 478 */ 479 function download_url( $url ) { 480 //WARNING: The file is not automatically deleted, The script must unlink() the file. 481 if ( ! $url ) 482 return new WP_Error('http_no_url', __('Invalid URL Provided.')); 483 484 $tmpfname = wp_tempnam($url); 485 if ( ! $tmpfname ) 486 return new WP_Error('http_no_file', __('Could not create Temporary file.')); 487 488 $handle = @fopen($tmpfname, 'wb'); 489 if ( ! $handle ) 490 return new WP_Error('http_no_file', __('Could not create Temporary file.')); 491 492 $response = wp_remote_get($url, array('timeout' => 300)); 493 494 if ( is_wp_error($response) ) { 495 fclose($handle); 496 unlink($tmpfname); 497 return $response; 498 } 499 500 if ( $response['response']['code'] != '200' ){ 501 fclose($handle); 502 unlink($tmpfname); 503 return new WP_Error('http_404', trim($response['response']['message'])); 504 } 505 506 fwrite($handle, $response['body']); 507 fclose($handle); 508 509 return $tmpfname; 510 } 511 512 /** 513 * Unzip's a specified ZIP file to a location on the Filesystem via the WordPress Filesystem Abstraction. 514 * Assumes that WP_Filesystem() has already been called and set up. Does not extract a root-level __MACOSX directory, if present. 515 * 516 * Attempts to increase the PHP Memory limit to 256M before uncompressing, 517 * However, The most memory required shouldn't be much larger than the Archive itself. 518 * 519 * @since 2.5.0 520 * 521 * @param string $file Full path and filename of zip archive 522 * @param string $to Full path on the filesystem to extract archive to 523 * @return mixed WP_Error on failure, True on success 524 */ 525 function unzip_file($file, $to) { 526 global $wp_filesystem; 527 528 if ( ! $wp_filesystem || !is_object($wp_filesystem) ) 529 return new WP_Error('fs_unavailable', __('Could not access filesystem.')); 530 531 // Unzip can use a lot of memory, but not this much hopefully 532 @ini_set('memory_limit', '256M'); 533 534 $needed_dirs = array(); 535 $to = trailingslashit($to); 536 537 // Determine any parent dir's needed (of the upgrade directory) 538 if ( ! $wp_filesystem->is_dir($to) ) { //Only do parents if no children exist 539 $path = preg_split('![/\\\]!', untrailingslashit($to)); 540 for ( $i = count($path); $i >= 0; $i-- ) { 541 if ( empty($path[$i]) ) 542 continue; 543 544 $dir = implode('/', array_slice($path, 0, $i+1) ); 545 if ( preg_match('!^[a-z]:$!i', $dir) ) // Skip it if it looks like a Windows Drive letter. 546 continue; 547 548 if ( ! $wp_filesystem->is_dir($dir) ) 549 $needed_dirs[] = $dir; 550 else 551 break; // A folder exists, therefor, we dont need the check the levels below this 552 } 553 } 554 555 if ( class_exists('ZipArchive') && apply_filters('unzip_file_use_ziparchive', true ) ) { 556 $result = _unzip_file_ziparchive($file, $to, $needed_dirs); 557 if ( true === $result ) { 558 return $result; 559 } elseif ( is_wp_error($result) ) { 560 if ( 'incompatible_archive' != $result->get_error_code() ) 561 return $result; 562 } 563 } 564 // Fall through to PclZip if ZipArchive is not available, or encountered an error opening the file. 565 return _unzip_file_pclzip($file, $to, $needed_dirs); 566 } 567 568 /** 569 * This function should not be called directly, use unzip_file instead. Attempts to unzip an archive using the ZipArchive class. 570 * Assumes that WP_Filesystem() has already been called and set up. 571 * 572 * @since 3.0.0 573 * @see unzip_file 574 * @access private 575 * 576 * @param string $file Full path and filename of zip archive 577 * @param string $to Full path on the filesystem to extract archive to 578 * @param array $needed_dirs A partial list of required folders needed to be created. 579 * @return mixed WP_Error on failure, True on success 580 */ 581 function _unzip_file_ziparchive($file, $to, $needed_dirs = array() ) { 582 global $wp_filesystem; 583 584 $z = new ZipArchive(); 585 586 // PHP4-compat - php4 classes can't contain constants 587 $zopen = $z->open($file, /* ZIPARCHIVE::CHECKCONS */ 4); 588 if ( true !== $zopen ) 589 return new WP_Error('incompatible_archive', __('Incompatible Archive.')); 590 591 for ( $i = 0; $i < $z->numFiles; $i++ ) { 592 if ( ! $info = $z->statIndex($i) ) 593 return new WP_Error('stat_failed', __('Could not retrieve file from archive.')); 594 595 if ( '__MACOSX/' === substr($info['name'], 0, 9) ) // Skip the OS X-created __MACOSX directory 596 continue; 597 598 if ( '/' == substr($info['name'], -1) ) // directory 599 $needed_dirs[] = $to . untrailingslashit($info['name']); 600 else 601 $needed_dirs[] = $to . untrailingslashit(dirname($info['name'])); 602 } 603 604 $needed_dirs = array_unique($needed_dirs); 605 foreach ( $needed_dirs as $dir ) { 606 // Check the parent folders of the folders all exist within the creation array. 607 if ( untrailingslashit($to) == $dir ) // Skip over the working directory, We know this exists (or will exist) 608 continue; 609 if ( strpos($dir, $to) === false ) // If the directory is not within the working directory, Skip it 610 continue; 611 612 $parent_folder = dirname($dir); 613 while ( !empty($parent_folder) && untrailingslashit($to) != $parent_folder && !in_array($parent_folder, $needed_dirs) ) { 614 $needed_dirs[] = $parent_folder; 615 $parent_folder = dirname($parent_folder); 616 } 617 } 618 asort($needed_dirs); 619 620 // Create those directories if need be: 621 foreach ( $needed_dirs as $_dir ) { 622 if ( ! $wp_filesystem->mkdir($_dir, FS_CHMOD_DIR) && ! $wp_filesystem->is_dir($_dir) ) // Only check to see if the Dir exists upon creation failure. Less I/O this way. 623 return new WP_Error('mkdir_failed', __('Could not create directory.'), $_dir); 624 } 625 unset($needed_dirs); 626 627 for ( $i = 0; $i < $z->numFiles; $i++ ) { 628 if ( ! $info = $z->statIndex($i) ) 629 return new WP_Error('stat_failed', __('Could not retrieve file from archive.')); 630 631 if ( '/' == substr($info['name'], -1) ) // directory 632 continue; 633 634 if ( '__MACOSX/' === substr($info['name'], 0, 9) ) // Don't extract the OS X-created __MACOSX directory files 635 continue; 636 637 $contents = $z->getFromIndex($i); 638 if ( false === $contents ) 639 return new WP_Error('extract_failed', __('Could not extract file from archive.'), $info['name']); 640 641 if ( ! $wp_filesystem->put_contents( $to . $info['name'], $contents, FS_CHMOD_FILE) ) 642 return new WP_Error('copy_failed', __('Could not copy file.'), $to . $info['filename']); 643 } 644 645 $z->close(); 646 647 return true; 648 } 649 650 /** 651 * This function should not be called directly, use unzip_file instead. Attempts to unzip an archive using the PclZip library. 652 * Assumes that WP_Filesystem() has already been called and set up. 653 * 654 * @since 3.0.0 655 * @see unzip_file 656 * @access private 657 * 658 * @param string $file Full path and filename of zip archive 659 * @param string $to Full path on the filesystem to extract archive to 660 * @param array $needed_dirs A partial list of required folders needed to be created. 661 * @return mixed WP_Error on failure, True on success 662 */ 663 function _unzip_file_pclzip($file, $to, $needed_dirs = array()) { 664 global $wp_filesystem; 665 666 require_once (ABSPATH . 'wp-admin/includes/class-pclzip.php'); 667 668 $archive = new PclZip($file); 669 670 // Is the archive valid? 671 if ( false == ($archive_files = $archive->extract(PCLZIP_OPT_EXTRACT_AS_STRING)) ) 672 return new WP_Error('incompatible_archive', __('Incompatible Archive.'), $archive->errorInfo(true)); 673 674 if ( 0 == count($archive_files) ) 675 return new WP_Error('empty_archive', __('Empty archive.')); 676 677 // Determine any children directories needed (From within the archive) 678 foreach ( $archive_files as $file ) { 679 if ( '__MACOSX/' === substr($file['filename'], 0, 9) ) // Skip the OS X-created __MACOSX directory 680 continue; 681 682 $needed_dirs[] = $to . untrailingslashit( $file['folder'] ? $file['filename'] : dirname($file['filename']) ); 683 } 684 685 $needed_dirs = array_unique($needed_dirs); 686 foreach ( $needed_dirs as $dir ) { 687 // Check the parent folders of the folders all exist within the creation array. 688 if ( untrailingslashit($to) == $dir ) // Skip over the working directory, We know this exists (or will exist) 689 continue; 690 if ( strpos($dir, $to) === false ) // If the directory is not within the working directory, Skip it 691 continue; 692 693 $parent_folder = dirname($dir); 694 while ( !empty($parent_folder) && untrailingslashit($to) != $parent_folder && !in_array($parent_folder, $needed_dirs) ) { 695 $needed_dirs[] = $parent_folder; 696 $parent_folder = dirname($parent_folder); 697 } 698 } 699 asort($needed_dirs); 700 701 // Create those directories if need be: 702 foreach ( $needed_dirs as $_dir ) { 703 if ( ! $wp_filesystem->mkdir($_dir, FS_CHMOD_DIR) && ! $wp_filesystem->is_dir($_dir) ) // Only check to see if the dir exists upon creation failure. Less I/O this way. 704 return new WP_Error('mkdir_failed', __('Could not create directory.'), $_dir); 705 } 706 unset($needed_dirs); 707 708 // Extract the files from the zip 709 foreach ( $archive_files as $file ) { 710 if ( $file['folder'] ) 711 continue; 712 713 if ( '__MACOSX/' === substr($file['filename'], 0, 9) ) // Don't extract the OS X-created __MACOSX directory files 714 continue; 715 716 if ( ! $wp_filesystem->put_contents( $to . $file['filename'], $file['content'], FS_CHMOD_FILE) ) 717 return new WP_Error('copy_failed', __('Could not copy file.'), $to . $file['filename']); 718 } 719 return true; 720 } 721 722 /** 723 * Copies a directory from one location to another via the WordPress Filesystem Abstraction. 724 * Assumes that WP_Filesystem() has already been called and setup. 725 * 726 * @since 2.5.0 727 * 728 * @param string $from source directory 729 * @param string $to destination directory 730 * @return mixed WP_Error on failure, True on success. 731 */ 732 function copy_dir($from, $to) { 733 global $wp_filesystem; 734 735 $dirlist = $wp_filesystem->dirlist($from); 736 737 $from = trailingslashit($from); 738 $to = trailingslashit($to); 739 740 foreach ( (array) $dirlist as $filename => $fileinfo ) { 741 if ( 'f' == $fileinfo['type'] ) { 742 if ( ! $wp_filesystem->copy($from . $filename, $to . $filename, true) ) { 743 // If copy failed, chmod file to 0644 and try again. 744 $wp_filesystem->chmod($to . $filename, 0644); 745 if ( ! $wp_filesystem->copy($from . $filename, $to . $filename, true) ) 746 return new WP_Error('copy_failed', __('Could not copy file.'), $to . $filename); 747 } 748 $wp_filesystem->chmod($to . $filename, FS_CHMOD_FILE); 749 } elseif ( 'd' == $fileinfo['type'] ) { 750 if ( !$wp_filesystem->is_dir($to . $filename) ) { 751 if ( !$wp_filesystem->mkdir($to . $filename, FS_CHMOD_DIR) ) 752 return new WP_Error('mkdir_failed', __('Could not create directory.'), $to . $filename); 753 } 754 $result = copy_dir($from . $filename, $to . $filename); 755 if ( is_wp_error($result) ) 756 return $result; 757 } 758 } 759 return true; 760 } 761 762 /** 763 * Initialises and connects the WordPress Filesystem Abstraction classes. 764 * This function will include the chosen transport and attempt connecting. 765 * 766 * Plugins may add extra transports, And force WordPress to use them by returning the filename via the 'filesystem_method_file' filter. 767 * 768 * @since 2.5.0 769 * 770 * @param array $args (optional) Connection args, These are passed directly to the WP_Filesystem_*() classes. 771 * @param string $context (optional) Context for get_filesystem_method(), See function declaration for more information. 772 * @return boolean false on failure, true on success 773 */ 774 function WP_Filesystem( $args = false, $context = false ) { 775 global $wp_filesystem; 776 777 require_once (ABSPATH . 'wp-admin/includes/class-wp-filesystem-base.php'); 778 779 $method = get_filesystem_method($args, $context); 780 781 if ( ! $method ) 782 return false; 783 784 if ( ! class_exists("WP_Filesystem_$method") ) { 785 $abstraction_file = apply_filters('filesystem_method_file', ABSPATH . 'wp-admin/includes/class-wp-filesystem-' . $method . '.php', $method); 786 if ( ! file_exists($abstraction_file) ) 787 return; 788 789 require_once($abstraction_file); 790 } 791 $method = "WP_Filesystem_$method"; 792 793 $wp_filesystem = new $method($args); 794 795 //Define the timeouts for the connections. Only available after the construct is called to allow for per-transport overriding of the default. 796 if ( ! defined('FS_CONNECT_TIMEOUT') ) 797 define('FS_CONNECT_TIMEOUT', 30); 798 if ( ! defined('FS_TIMEOUT') ) 799 define('FS_TIMEOUT', 30); 800 801 if ( is_wp_error($wp_filesystem->errors) && $wp_filesystem->errors->get_error_code() ) 802 return false; 803 804 if ( !$wp_filesystem->connect() ) 805 return false; //There was an erorr connecting to the server. 806 807 // Set the permission constants if not already set. 808 if ( ! defined('FS_CHMOD_DIR') ) 809 define('FS_CHMOD_DIR', 0755 ); 810 if ( ! defined('FS_CHMOD_FILE') ) 811 define('FS_CHMOD_FILE', 0644 ); 812 813 return true; 814 } 815 816 /** 817 * Determines which Filesystem Method to use. 818 * The priority of the Transports are: Direct, SSH2, FTP PHP Extension, FTP Sockets (Via Sockets class, or fsoxkopen()) 819 * 820 * Note that the return value of this function can be overridden in 2 ways 821 * - By defining FS_METHOD in your <code>wp-config.php</code> file 822 * - By using the filesystem_method filter 823 * Valid values for these are: 'direct', 'ssh', 'ftpext' or 'ftpsockets' 824 * Plugins may also define a custom transport handler, See the WP_Filesystem function for more information. 825 * 826 * @since 2.5.0 827 * 828 * @param array $args Connection details. 829 * @param string $context Full path to the directory that is tested for being writable. 830 * @return string The transport to use, see description for valid return values. 831 */ 832 function get_filesystem_method($args = array(), $context = false) { 833 $method = defined('FS_METHOD') ? FS_METHOD : false; //Please ensure that this is either 'direct', 'ssh', 'ftpext' or 'ftpsockets' 834 835 if ( ! $method && function_exists('getmyuid') && function_exists('fileowner') ){ 836 if ( !$context ) 837 $context = WP_CONTENT_DIR; 838 $context = trailingslashit($context); 839 $temp_file_name = $context . 'temp-write-test-' . time(); 840 $temp_handle = @fopen($temp_file_name, 'w'); 841 if ( $temp_handle ) { 842 if ( getmyuid() == @fileowner($temp_file_name) ) 843 $method = 'direct'; 844 @fclose($temp_handle); 845 @unlink($temp_file_name); 846 } 847 } 848 849 if ( ! $method && isset($args['connection_type']) && 'ssh' == $args['connection_type'] && extension_loaded('ssh2') && function_exists('stream_get_contents') ) $method = 'ssh2'; 850 if ( ! $method && extension_loaded('ftp') ) $method = 'ftpext'; 851 if ( ! $method && ( extension_loaded('sockets') || function_exists('fsockopen') ) ) $method = 'ftpsockets'; //Sockets: Socket extension; PHP Mode: FSockopen / fwrite / fread 852 return apply_filters('filesystem_method', $method, $args); 853 } 854 855 /** 856 * Displays a form to the user to request for their FTP/SSH details in order to connect to the filesystem. 857 * All chosen/entered details are saved, Excluding the Password. 858 * 859 * Hostnames may be in the form of hostname:portnumber (eg: wordpress.org:2467) to specify an alternate FTP/SSH port. 860 * 861 * Plugins may override this form by returning true|false via the <code>request_filesystem_credentials</code> filter. 862 * 863 * @since 2.5.0 864 * 865 * @param string $form_post the URL to post the form to 866 * @param string $type the chosen Filesystem method in use 867 * @param boolean $error if the current request has failed to connect 868 * @param string $context The directory which is needed access to, The write-test will be performed on this directory by get_filesystem_method() 869 * @param string $extra_fields Extra POST fields which should be checked for to be included in the post. 870 * @return boolean False on failure. True on success. 871 */ 872 function request_filesystem_credentials($form_post, $type = '', $error = false, $context = false, $extra_fields = null) { 873 $req_cred = apply_filters( 'request_filesystem_credentials', '', $form_post, $type, $error, $context, $extra_fields ); 874 if ( '' !== $req_cred ) 875 return $req_cred; 876 877 if ( empty($type) ) 878 $type = get_filesystem_method(array(), $context); 879 880 if ( 'direct' == $type ) 881 return true; 882 883 if ( is_null( $extra_fields ) ) 884 $extra_fields = array( 'version', 'locale' ); 885 886 $credentials = get_option('ftp_credentials', array( 'hostname' => '', 'username' => '')); 887 888 // 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) 889 $credentials['hostname'] = defined('FTP_HOST') ? FTP_HOST : (!empty($_POST['hostname']) ? stripslashes($_POST['hostname']) : $credentials['hostname']); 890 $credentials['username'] = defined('FTP_USER') ? FTP_USER : (!empty($_POST['username']) ? stripslashes($_POST['username']) : $credentials['username']); 891 $credentials['password'] = defined('FTP_PASS') ? FTP_PASS : (!empty($_POST['password']) ? stripslashes($_POST['password']) : ''); 892 893 // Check to see if we are setting the public/private keys for ssh 894 $credentials['public_key'] = defined('FTP_PUBKEY') ? FTP_PUBKEY : (!empty($_POST['public_key']) ? stripslashes($_POST['public_key']) : ''); 895 $credentials['private_key'] = defined('FTP_PRIKEY') ? FTP_PRIKEY : (!empty($_POST['private_key']) ? stripslashes($_POST['private_key']) : ''); 896 897 //sanitize the hostname, Some people might pass in odd-data: 898 $credentials['hostname'] = preg_replace('|\w+://|', '', $credentials['hostname']); //Strip any schemes off 899 900 if ( strpos($credentials['hostname'], ':') ) { 901 list( $credentials['hostname'], $credentials['port'] ) = explode(':', $credentials['hostname'], 2); 902 if ( ! is_numeric($credentials['port']) ) 903 unset($credentials['port']); 904 } else { 905 unset($credentials['port']); 906 } 907 908 if ( (defined('FTP_SSH') && FTP_SSH) || (defined('FS_METHOD') && 'ssh' == FS_METHOD) ) 909 $credentials['connection_type'] = 'ssh'; 910 else if ( (defined('FTP_SSL') && FTP_SSL) && 'ftpext' == $type ) //Only the FTP Extension understands SSL 911 $credentials['connection_type'] = 'ftps'; 912 else if ( !empty($_POST['connection_type']) ) 913 $credentials['connection_type'] = stripslashes($_POST['connection_type']); 914 else if ( !isset($credentials['connection_type']) ) //All else fails (And its not defaulted to something else saved), Default to FTP 915 $credentials['connection_type'] = 'ftp'; 916 917 if ( ! $error && 918 ( 919 ( !empty($credentials['password']) && !empty($credentials['username']) && !empty($credentials['hostname']) ) || 920 ( 'ssh' == $credentials['connection_type'] && !empty($credentials['public_key']) && !empty($credentials['private_key']) ) 921 ) ) { 922 $stored_credentials = $credentials; 923 if ( !empty($stored_credentials['port']) ) //save port as part of hostname to simplify above code. 924 $stored_credentials['hostname'] .= ':' . $stored_credentials['port']; 925 926 unset($stored_credentials['password'], $stored_credentials['port'], $stored_credentials['private_key'], $stored_credentials['public_key']); 927 update_option('ftp_credentials', $stored_credentials); 928 return $credentials; 929 } 930 $hostname = ''; 931 $username = ''; 932 $password = ''; 933 $connection_type = ''; 934 if ( !empty($credentials) ) 935 extract($credentials, EXTR_OVERWRITE); 936 if ( $error ) { 937 $error_string = __('<strong>Error:</strong> There was an error connecting to the server, Please verify the settings are correct.'); 938 if ( is_wp_error($error) ) 939 $error_string = $error->get_error_message(); 940 echo '<div id="message" class="error"><p>' . $error_string . '</p></div>'; 941 } 942 943 $types = array(); 944 if ( extension_loaded('ftp') || extension_loaded('sockets') || function_exists('fsockopen') ) 945 $types[ 'ftp' ] = __('FTP'); 946 if ( extension_loaded('ftp') ) //Only this supports FTPS 947 $types[ 'ftps' ] = __('FTPS (SSL)'); 948 if ( extension_loaded('ssh2') && function_exists('stream_get_contents') ) 949 $types[ 'ssh' ] = __('SSH2'); 950 951 $types = apply_filters('fs_ftp_connection_types', $types, $credentials, $type, $error, $context); 952 953 ?> 954 <script type="text/javascript"> 955 <!-- 956 jQuery(function($){ 957 jQuery("#ssh").click(function () { 958 jQuery("#ssh_keys").show(); 959 }); 960 jQuery("#ftp, #ftps").click(function () { 961 jQuery("#ssh_keys").hide(); 962 }); 963 jQuery('form input[value=""]:first').focus(); 964 }); 965 --> 966 </script> 967 <form action="<?php echo $form_post ?>" method="post"> 968 <div class="wrap"> 969 <?php screen_icon(); ?> 970 <h2><?php _e('Connection Information') ?></h2> 971 <p><?php 972 $label_user = __('Username'); 973 $label_pass = __('Password'); 974 _e('To perform the requested action, WordPress needs to access to your web server.'); 975 echo ' '; 976 if ( ( isset( $types['ftp'] ) || isset( $types['ftps'] ) ) ) { 977 if ( isset( $types['ssh'] ) ) { 978 _e('Please enter your FTP or SSH credentials to proceed.'); 979 $label_user = __('FTP/SSH Username'); 980 $label_pass = __('FTP/SSH Password'); 981 } else { 982 _e('Please enter your FTP credentials to proceed.'); 983 $label_user = __('FTP Username'); 984 $label_pass = __('FTP Password'); 985 } 986 echo ' '; 987 } 988 _e('If you do not remember your credentials, you should contact your web host.'); 989 ?></p> 990 <table class="form-table"> 991 <tr valign="top"> 992 <th scope="row"><label for="hostname"><?php _e('Hostname') ?></label></th> 993 <td><input name="hostname" type="text" id="hostname" value="<?php echo esc_attr($hostname); if ( !empty($port) ) echo ":$port"; ?>"<?php disabled( defined('FTP_HOST') ); ?> size="40" /></td> 994 </tr> 995 996 <tr valign="top"> 997 <th scope="row"><label for="username"><?php echo $label_user; ?></label></th> 998 <td><input name="username" type="text" id="username" value="<?php echo esc_attr($username) ?>"<?php disabled( defined('FTP_USER') ); ?> size="40" /></td> 999 </tr> 1000 1001 <tr valign="top"> 1002 <th scope="row"><label for="password"><?php echo $label_pass; ?></label></th> 1003 <td><input name="password" type="password" id="password" value="<?php if ( defined('FTP_PASS') ) echo '*****'; ?>"<?php disabled( defined('FTP_PASS') ); ?> size="40" /></td> 1004 </tr> 1005 1006 <?php if ( isset($types['ssh']) ) : ?> 1007 <tr id="ssh_keys" valign="top" style="<?php if ( 'ssh' != $connection_type ) echo 'display:none' ?>"> 1008 <th scope="row"><?php _e('Authentication Keys') ?> 1009 <div class="key-labels textright"> 1010 <label for="public_key"><?php _e('Public Key:') ?></label ><br /> 1011 <label for="private_key"><?php _e('Private Key:') ?></label> 1012 </div></th> 1013 <td><br /><input name="public_key" type="text" id="public_key" value="<?php echo esc_attr($public_key) ?>"<?php disabled( defined('FTP_PUBKEY') ); ?> size="40" /><br /><input name="private_key" type="text" id="private_key" value="<?php echo esc_attr($private_key) ?>"<?php disabled( defined('FTP_PRIKEY') ); ?> size="40" /> 1014 <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> 1015 </tr> 1016 <?php endif; ?> 1017 1018 <tr valign="top"> 1019 <th scope="row"><?php _e('Connection Type') ?></th> 1020 <td> 1021 <fieldset><legend class="screen-reader-text"><span><?php _e('Connection Type') ?></span></legend> 1022 <?php 1023 $disabled = disabled( (defined('FTP_SSL') && FTP_SSL) || (defined('FTP_SSH') && FTP_SSH), true, false ); 1024 foreach ( $types as $name => $text ) : ?> 1025 <label for="<?php echo esc_attr($name) ?>"> 1026 <input type="radio" name="connection_type" id="<?php echo esc_attr($name) ?>" value="<?php echo esc_attr($name) ?>"<?php checked($name, $connection_type); echo $disabled; ?> /> 1027 <?php echo $text ?> 1028 </label> 1029 <?php endforeach; ?> 1030 </fieldset> 1031 </td> 1032 </tr> 1033 </table> 1034 1035 <?php 1036 foreach ( (array) $extra_fields as $field ) { 1037 if ( isset( $_POST[ $field ] ) ) 1038 echo '<input type="hidden" name="' . esc_attr( $field ) . '" value="' . esc_attr( stripslashes( $_POST[ $field ] ) ) . '" />'; 1039 } 1040 ?> 1041 <p class="submit"> 1042 <input id="upgrade" name="upgrade" type="submit" class="button" value="<?php esc_attr_e('Proceed'); ?>" /> 1043 </p> 1044 </div> 1045 </form> 1046 <?php 1047 return false; 1048 } 1049 1050 ?>
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated: Thu Oct 14 05:11:12 2010 | Cross-referenced by PHPXref 0.7 |