Make WordPress Core

Changeset 29209


Ignore:
Timestamp:
07/17/2014 06:57:26 PM (8 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.