Make WordPress Core

Changeset 29209


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