WordPress.org

Make WordPress Core

Changeset 29209


Ignore:
Timestamp:
07/17/14 18:57:26 (3 years ago)
Author:
wonderboymusic
Message:

Merge wp_handle_upload() and wp_handle_sideload() by making them each wrap a new function: _wp_handle_upload().

Props DrewAPicture for docs.
Fixes #23686.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-admin/includes/file.php

    r29206 r29209  
    192192 * and moving the file to the appropriate directory within the uploads directory. 
    193193 * 
    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*/ 
     206function _wp_handle_upload( &$file, $overrides, $time, $action ) { 
    209207    // The default error handler. 
    210208    if ( ! function_exists( 'wp_handle_upload_error' ) ) { 
    211209        function wp_handle_upload_error( &$file, $message ) { 
    212             return array( 'error'=>$message ); 
     210            return array( 'error' => $message ); 
    213211        } 
    214212    } 
    215213 
    216214    /** 
    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 
    220219     * 
    221220     * @param array $file An array of data for a single file. 
    222221     */ 
    223     $file = apply_filters( 'wp_handle_upload_prefilter', $file ); 
     222    $file = apply_filters( "{$action}_prefilter", $file ); 
    224223 
    225224    // You may define your own function and pass the name in $overrides['upload_error_handler'] 
     
    230229 
    231230    // 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'] ) { 
    233232        return $upload_error_handler( $file, $file['error'] ); 
     233    } 
    234234 
    235235    // Install user overrides. Did we mention that this voids your warranty? 
     
    240240        $unique_filename_callback = $overrides['unique_filename_callback']; 
    241241    } 
    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." )); 
    259242 
    260243    /* 
     
    264247    if ( isset( $overrides['upload_error_strings'] ) ) { 
    265248        $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        ); 
    266262    } 
    267263 
     
    269265    $test_form = isset( $overrides['test_form'] ) ? $overrides['test_form'] : true; 
    270266    $test_size = isset( $overrides['test_size'] ) ? $overrides['test_size'] : true; 
    271     $test_upload = isset( $overrides['test_upload'] ) ? $overrides['test_upload'] : true; 
    272267 
    273268    // If you override this, you must provide $ext and $type!! 
     
    275270    $mimes = isset( $overrides['mimes'] ) ? $overrides['mimes'] : false; 
    276271 
     272    $test_upload = isset( $overrides['test_upload'] ) ? $overrides['test_upload'] : true; 
     273 
    277274    // 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 ) ) ) { 
    279276        return call_user_func( $upload_error_handler, $file, __( 'Invalid form submission.' ) ); 
    280277    } 
     
    284281    } 
    285282 
     283    $test_file_size = 'wp_handle_upload' === $action ? $file['size'] : filesize( $file['tmp_name'] ); 
    286284    // 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() ) { 
    289287            $error_msg = __( 'File is empty. Please upload something more substantial.' ); 
    290         else 
     288        } else { 
    291289            $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 ); 
    293292    } 
    294293 
    295294    // 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    } 
    298299 
    299300    // A correct MIME type will pass this test. Override $mimes or use the upload_mimes filter. 
     
    322323     * overriding this one. 
    323324     */ 
    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    } 
    326328 
    327329    $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 ); 
    328333 
    329334    // Move the file to the uploads dir. 
    330335    $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 ) ) { 
    333344            $error_path = str_replace( ABSPATH, '', $uploads['basedir'] ) . $uploads['subdir']; 
    334         else 
     345        } else { 
    335346            $error_path = basename( $uploads['basedir'] ) . $uploads['subdir']; 
    336  
     347        } 
    337348        return $upload_error_handler( $file, sprintf( __('The uploaded file could not be moved to %s.' ), $error_path ) ); 
    338349    } 
     
    346357    $url = $uploads['url'] . "/$filename"; 
    347358 
    348     if ( is_multisite() ) 
     359    if ( is_multisite() ) { 
    349360        delete_transient( 'dirsize_cache' ); 
     361    } 
    350362 
    351363    /** 
     
    361373     *     @type string $type File type. 
    362374     * } 
    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'. 
    364376     */ 
    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 */ 
     398function 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 
    372413 * 
    373414 * @since 2.6.0 
    374415 * 
    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 ). 
    384424 */ 
    385425function 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     */ 
    408430    $action = 'wp_handle_sideload'; 
    409431    if ( isset( $overrides['action'] ) ) { 
    410432        $action = $overrides['action']; 
    411433    } 
    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 
    507437 
    508438/** 
Note: See TracChangeset for help on using the changeset viewer.