Changeset 29209
- Timestamp:
- 07/17/2014 06:57:26 PM (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-admin/includes/file.php
r29206 r29209 192 192 * and moving the file to the appropriate directory within the uploads directory. 193 193 * 194 * @since 2.0.0 195 * 196 * @uses wp_handle_upload_error 197 * @uses is_multisite 198 * @uses wp_check_filetype_and_ext 199 * @uses current_user_can 200 * @uses wp_upload_dir 201 * @uses wp_unique_filename 202 * @uses delete_transient 203 * @param array $file Reference to a single element of $_FILES. Call the function once for each uploaded file. 204 * @param array $overrides Optional. An associative array of names=>values to override default variables. 205 * @param string $time Optional. Time formatted in 'yyyy/mm'. 206 * @return array On success, returns an associative array of file attributes. On failure, returns $overrides['upload_error_handler'](&$file, $message ) or array( 'error'=>$message ). 207 */ 208 function wp_handle_upload( &$file, $overrides = false, $time = null ) { 194 * @since 4.0.0 195 * 196 * @see wp_handle_upload_error 197 * 198 * @param array $file Reference to a single element of $_FILES. Call the function once for 199 * each uploaded file. 200 * @param array $overrides An associative array of names => values to override default variables. 201 * @param string $time Time formatted in 'yyyy/mm'. 202 * @param string $action Expected value for $_POST['action']. 203 * @return array On success, returns an associative array of file attributes. On failure, returns 204 * $overrides['upload_error_handler'](&$file, $message ) or array( 'error'=>$message ). 205 */ 206 function _wp_handle_upload( &$file, $overrides, $time, $action ) { 209 207 // The default error handler. 210 208 if ( ! function_exists( 'wp_handle_upload_error' ) ) { 211 209 function wp_handle_upload_error( &$file, $message ) { 212 return array( 'error' =>$message );210 return array( 'error' => $message ); 213 211 } 214 212 } 215 213 216 214 /** 217 * Filter data for the current file to upload. 218 * 219 * @since 2.9.0 215 * The dynamic portion of the hook name, $action, refers to the post action. 216 * 217 * @since 2.9.0 as 'wp_handle_upload_prefilter' 218 * @since 4.0.0 Converted to a dynamic hook with $action 220 219 * 221 220 * @param array $file An array of data for a single file. 222 221 */ 223 $file = apply_filters( 'wp_handle_upload_prefilter', $file );222 $file = apply_filters( "{$action}_prefilter", $file ); 224 223 225 224 // You may define your own function and pass the name in $overrides['upload_error_handler'] … … 230 229 231 230 // You may have had one or more 'wp_handle_upload_prefilter' functions error out the file. Handle that gracefully. 232 if ( isset( $file['error'] ) && ! is_numeric( $file['error'] ) && $file['error'] )231 if ( isset( $file['error'] ) && ! is_numeric( $file['error'] ) && $file['error'] ) { 233 232 return $upload_error_handler( $file, $file['error'] ); 233 } 234 234 235 235 // Install user overrides. Did we mention that this voids your warranty? … … 240 240 $unique_filename_callback = $overrides['unique_filename_callback']; 241 241 } 242 243 // $_POST['action'] must be set and its value must equal $overrides['action'] or this:244 $action = 'wp_handle_upload';245 if ( isset( $overrides['action'] ) ) {246 $action = $overrides['action'];247 }248 249 // Courtesy of php.net, the strings that describe the error indicated in $_FILES[{form field}]['error'].250 $upload_error_strings = array( false,251 __( "The uploaded file exceeds the upload_max_filesize directive in php.ini." ),252 __( "The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form." ),253 __( "The uploaded file was only partially uploaded." ),254 __( "No file was uploaded." ),255 '',256 __( "Missing a temporary folder." ),257 __( "Failed to write file to disk." ),258 __( "File upload stopped by extension." ));259 242 260 243 /* … … 264 247 if ( isset( $overrides['upload_error_strings'] ) ) { 265 248 $upload_error_strings = $overrides['upload_error_strings']; 249 } else { 250 // Courtesy of php.net, the strings that describe the error indicated in $_FILES[{form field}]['error']. 251 $upload_error_strings = array( 252 false, 253 __( 'The uploaded file exceeds the upload_max_filesize directive in php.ini.' ), 254 __( 'The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form.' ), 255 __( 'The uploaded file was only partially uploaded.' ), 256 __( 'No file was uploaded.' ), 257 '', 258 __( 'Missing a temporary folder.' ), 259 __( 'Failed to write file to disk.' ), 260 __( 'File upload stopped by extension.' ) 261 ); 266 262 } 267 263 … … 269 265 $test_form = isset( $overrides['test_form'] ) ? $overrides['test_form'] : true; 270 266 $test_size = isset( $overrides['test_size'] ) ? $overrides['test_size'] : true; 271 $test_upload = isset( $overrides['test_upload'] ) ? $overrides['test_upload'] : true;272 267 273 268 // If you override this, you must provide $ext and $type!! … … 275 270 $mimes = isset( $overrides['mimes'] ) ? $overrides['mimes'] : false; 276 271 272 $test_upload = isset( $overrides['test_upload'] ) ? $overrides['test_upload'] : true; 273 277 274 // A correct form post will pass this test. 278 if ( $test_form && ( ! isset( $_POST['action'] ) || ( $_POST['action'] != $action ) ) ) {275 if ( $test_form && ( ! isset( $_POST['action'] ) || ( $_POST['action'] != $action ) ) ) { 279 276 return call_user_func( $upload_error_handler, $file, __( 'Invalid form submission.' ) ); 280 277 } … … 284 281 } 285 282 283 $test_file_size = 'wp_handle_upload' === $action ? $file['size'] : filesize( $file['tmp_name'] ); 286 284 // A non-empty file will pass this test. 287 if ( $test_size && ! ($file['size']> 0 ) ) {288 if ( is_multisite() ) 285 if ( $test_size && ! ( $test_file_size > 0 ) ) { 286 if ( is_multisite() ) { 289 287 $error_msg = __( 'File is empty. Please upload something more substantial.' ); 290 else288 } else { 291 289 $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.' ); 292 return call_user_func($upload_error_handler, $file, $error_msg); 290 } 291 return call_user_func( $upload_error_handler, $file, $error_msg ); 293 292 } 294 293 295 294 // A properly uploaded file will pass this test. There should be no reason to override this one. 296 if ( $test_upload && ! @ is_uploaded_file( $file['tmp_name'] ) ) 297 return call_user_func($upload_error_handler, $file, __( 'Specified file failed upload test.' )); 295 $test_uploaded_file = 'wp_handle_upload' === $action ? @ is_uploaded_file( $file['tmp_name'] ) : @ is_file( $file['tmp_name'] ); 296 if ( $test_upload && ! $test_uploaded_file ) { 297 return call_user_func( $upload_error_handler, $file, __( 'Specified file failed upload test.' ) ); 298 } 298 299 299 300 // A correct MIME type will pass this test. Override $mimes or use the upload_mimes filter. … … 322 323 * overriding this one. 323 324 */ 324 if ( ! ( ( $uploads = wp_upload_dir($time) ) && false === $uploads['error'] ) ) 325 return call_user_func($upload_error_handler, $file, $uploads['error'] ); 325 if ( ! ( ( $uploads = wp_upload_dir( $time ) ) && false === $uploads['error'] ) ) { 326 return call_user_func( $upload_error_handler, $file, $uploads['error'] ); 327 } 326 328 327 329 $filename = wp_unique_filename( $uploads['path'], $file['name'], $unique_filename_callback ); 330 // Strip the query strings. 331 $filename = str_replace( '?', '-', $filename ); 332 $filename = str_replace( '&', '-', $filename ); 328 333 329 334 // Move the file to the uploads dir. 330 335 $new_file = $uploads['path'] . "/$filename"; 331 if ( false === @ move_uploaded_file( $file['tmp_name'], $new_file ) ) { 332 if ( 0 === strpos( $uploads['basedir'], ABSPATH ) ) 336 if ( 'wp_handle_upload' === $action ) { 337 $move_new_file = @ move_uploaded_file( $file['tmp_name'], $new_file ); 338 } else { 339 $move_new_file = @ rename( $file['tmp_name'], $new_file ); 340 } 341 342 if ( false === $move_new_file ) { 343 if ( 0 === strpos( $uploads['basedir'], ABSPATH ) ) { 333 344 $error_path = str_replace( ABSPATH, '', $uploads['basedir'] ) . $uploads['subdir']; 334 else345 } else { 335 346 $error_path = basename( $uploads['basedir'] ) . $uploads['subdir']; 336 347 } 337 348 return $upload_error_handler( $file, sprintf( __('The uploaded file could not be moved to %s.' ), $error_path ) ); 338 349 } … … 346 357 $url = $uploads['url'] . "/$filename"; 347 358 348 if ( is_multisite() ) 359 if ( is_multisite() ) { 349 360 delete_transient( 'dirsize_cache' ); 361 } 350 362 351 363 /** … … 361 373 * @type string $type File type. 362 374 * } 363 * @param string $context The type of upload action. Accepts'upload' or 'sideload'.375 * @param string $context The type of upload action. Values include 'upload' or 'sideload'. 364 376 */ 365 return apply_filters( 'wp_handle_upload', array( 'file' => $new_file, 'url' => $url, 'type' => $type ), 'upload' ); 366 } 367 368 /** 369 * Handle sideloads, which is the process of retrieving a media item from another server instead of 370 * a traditional media upload. This process involves sanitizing the filename, checking extensions 371 * for mime type, and moving the file to the appropriate directory within the uploads directory. 377 return apply_filters( 'wp_handle_upload', array( 378 'file' => $new_file, 379 'url' => $url, 380 'type' => $type 381 ), 'wp_handle_sideload' === $action ? 'sideload' : 'upload' ); } 382 383 /** 384 * Wrapper for _wp_handle_upload(), passes 'wp_handle_upload' action. 385 * 386 * @since 2.0.0 387 * 388 * @see _wp_handle_upload() 389 * 390 * @param array $file Reference to a single element of $_FILES. Call the function once for 391 * each uploaded file. 392 * @param array|bool $overrides Optional. An associative array of names=>values to override default 393 * variables. Default false. 394 * @param string $time Optional. Time formatted in 'yyyy/mm'. Default null. 395 * @return array On success, returns an associative array of file attributes. On failure, returns 396 * $overrides['upload_error_handler'](&$file, $message ) or array( 'error'=>$message ). 397 */ 398 function wp_handle_upload( &$file, $overrides = false, $time = null ) { 399 /* 400 * $_POST['action'] must be set and its value must equal $overrides['action'] 401 * or this: 402 */ 403 $action = 'wp_handle_upload'; 404 if ( isset( $overrides['action'] ) ) { 405 $action = $overrides['action']; 406 } 407 408 return _wp_handle_upload( $file, $overrides, $time, $action ); 409 } 410 411 /** 412 * Wrapper for _wp_handle_upload(), passes 'wp_handle_sideload' action 372 413 * 373 414 * @since 2.6.0 374 415 * 375 * @uses wp_handle_upload_error 376 * @uses wp_check_filetype_and_ext 377 * @uses current_user_can 378 * @uses wp_upload_dir 379 * @uses wp_unique_filename 380 * @param array $file an array similar to that of a PHP $_FILES POST array 381 * @param array $overrides Optional. An associative array of names=>values to override default variables. 382 * @param string $time Optional. Time formatted in 'yyyy/mm'. 383 * @return array On success, returns an associative array of file attributes. On failure, returns $overrides['upload_error_handler'](&$file, $message ) or array( 'error'=>$message ). 416 * @see _wp_handle_upload() 417 * 418 * @param array $file An array similar to that of a PHP $_FILES POST array 419 * @param array|bool $overrides Optional. An associative array of names=>values to override default 420 * variables. Default false. 421 * @param string $time Optional. Time formatted in 'yyyy/mm'. Default null. 422 * @return array On success, returns an associative array of file attributes. On failure, returns 423 * $overrides['upload_error_handler'](&$file, $message ) or array( 'error'=>$message ). 384 424 */ 385 425 function wp_handle_sideload( &$file, $overrides = false, $time = null ) { 386 // The default error handler. 387 if (! function_exists( 'wp_handle_upload_error' ) ) { 388 function wp_handle_upload_error( &$file, $message ) { 389 return array( 'error'=>$message ); 390 } 391 } 392 393 // Install user overrides. Did we mention that this voids your warranty? 394 395 // You may define your own function and pass the name in $overrides['upload_error_handler'] 396 $upload_error_handler = 'wp_handle_upload_error'; 397 if ( isset( $overrides['upload_error_handler'] ) ) { 398 $upload_error_handler = $overrides['upload_error_handler']; 399 } 400 401 // You may define your own function and pass the name in $overrides['unique_filename_callback'] 402 $unique_filename_callback = null; 403 if ( isset( $overrides['unique_filename_callback'] ) ) { 404 $unique_filename_callback = $overrides['unique_filename_callback']; 405 } 406 407 // $_POST['action'] must be set and its value must equal $overrides['action'] or this: 426 /* 427 * $_POST['action'] must be set and its value must equal $overrides['action'] 428 * or this: 429 */ 408 430 $action = 'wp_handle_sideload'; 409 431 if ( isset( $overrides['action'] ) ) { 410 432 $action = $overrides['action']; 411 433 } 412 413 // Courtesy of php.net, the strings that describe the error indicated in $_FILES[{form field}]['error']. 414 $upload_error_strings = array( false, 415 __( "The uploaded file exceeds the <code>upload_max_filesize</code> directive in <code>php.ini</code>." ), 416 __( "The uploaded file exceeds the <em>MAX_FILE_SIZE</em> directive that was specified in the HTML form." ), 417 __( "The uploaded file was only partially uploaded." ), 418 __( "No file was uploaded." ), 419 '', 420 __( "Missing a temporary folder." ), 421 __( "Failed to write file to disk." ), 422 __( "File upload stopped by extension." )); 423 424 // this may not have orignially been intended to be overrideable, but historically has been 425 if ( isset( $overrides['upload_error_strings'] ) ) { 426 $upload_error_strings = $overrides['upload_error_strings']; 427 } 428 429 // All tests are on by default. Most can be turned off by $overrides[{test_name}] = false; 430 $test_form = isset( $overrides['test_form'] ) ? $overrides['test_form'] : true; 431 $test_size = isset( $overrides['test_size'] ) ? $overrides['test_size'] : true; 432 433 // If you override this, you must provide $ext and $type!!!! 434 $test_type = isset( $overrides['test_type'] ) ? $overrides['test_type'] : true; 435 $mimes = isset( $overrides['mimes'] ) ? $overrides['mimes'] : false; 436 437 // A correct form post will pass this test. 438 if ( $test_form && (!isset( $_POST['action'] ) || ($_POST['action'] != $action ) ) ) 439 return $upload_error_handler( $file, __( 'Invalid form submission.' )); 440 441 // A successful upload will pass this test. It makes no sense to override this one. 442 if ( ! empty( $file['error'] ) ) 443 return $upload_error_handler( $file, $upload_error_strings[$file['error']] ); 444 445 // A non-empty file will pass this test. 446 if ( $test_size && !(filesize($file['tmp_name']) > 0 ) ) 447 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.' )); 448 449 // A properly uploaded file will pass this test. There should be no reason to override this one. 450 if (! @ is_file( $file['tmp_name'] ) ) 451 return $upload_error_handler( $file, __( 'Specified file does not exist.' )); 452 453 // A correct MIME type will pass this test. Override $mimes or use the upload_mimes filter. 454 if ( $test_type ) { 455 $wp_filetype = wp_check_filetype_and_ext( $file['tmp_name'], $file['name'], $mimes ); 456 $ext = empty( $wp_filetype['ext'] ) ? '' : $wp_filetype['ext']; 457 $type = empty( $wp_filetype['type'] ) ? '' : $wp_filetype['type']; 458 $proper_filename = empty( $wp_filetype['proper_filename'] ) ? '' : $wp_filetype['proper_filename']; 459 460 // Check to see if wp_check_filetype_and_ext() determined the filename was incorrect 461 if ( $proper_filename ) { 462 $file['name'] = $proper_filename; 463 } 464 if ( ( ! $type || ! $ext ) && ! current_user_can( 'unfiltered_upload' ) ) { 465 return $upload_error_handler( $file, __( 'Sorry, this file type is not permitted for security reasons.' ) ); 466 } 467 if ( ! $type ) { 468 $type = $file['type']; 469 } 470 } else { 471 $type = ''; 472 } 473 474 // A writable uploads dir will pass this test. Again, there's no point overriding this one. 475 if ( ! ( ( $uploads = wp_upload_dir( $time ) ) && false === $uploads['error'] ) ) 476 return $upload_error_handler( $file, $uploads['error'] ); 477 478 $filename = wp_unique_filename( $uploads['path'], $file['name'], $unique_filename_callback ); 479 480 // Strip the query strings. 481 $filename = str_replace('?','-', $filename); 482 $filename = str_replace('&','-', $filename); 483 484 // Move the file to the uploads dir 485 $new_file = $uploads['path'] . "/$filename"; 486 if ( false === @ rename( $file['tmp_name'], $new_file ) ) { 487 if ( 0 === strpos( $uploads['basedir'], ABSPATH ) ) 488 $error_path = str_replace( ABSPATH, '', $uploads['basedir'] ) . $uploads['subdir']; 489 else 490 $error_path = basename( $uploads['basedir'] ) . $uploads['subdir']; 491 return $upload_error_handler( $file, sprintf( __('The uploaded file could not be moved to %s.' ), $error_path ) ); 492 } 493 494 // Set correct file permissions 495 $stat = stat( dirname( $new_file )); 496 $perms = $stat['mode'] & 0000666; 497 @ chmod( $new_file, $perms ); 498 499 // Compute the URL 500 $url = $uploads['url'] . "/$filename"; 501 502 /** This filter is documented in wp-admin/includes/file.php */ 503 $return = apply_filters( 'wp_handle_upload', array( 'file' => $new_file, 'url' => $url, 'type' => $type ), 'sideload' ); 504 505 return $return; 506 } 434 return _wp_handle_upload( $file, $overrides, $time, $action ); 435 } 436 507 437 508 438 /**
Note: See TracChangeset
for help on using the changeset viewer.