Make WordPress Core


Ignore:
Timestamp:
01/21/2019 04:01:53 PM (6 years ago)
Author:
flixos90
Message:

Bootstrap/Load: Support WP_Error and $args passed to wp_die() consistently in all handlers.

Prior to this change, each wp_die() handler had their own logic for how to parse arguments, causing inconsistencies and even breakage because the arguments possible to pass to wp_die() depended on the request context. Passing a WP_Error as $message for example used to be only support by the default handler, but not the AJAX and XML-RPC handlers.

With the fatal error protection, plus the new wp_die() handlers related to that, improving this support and compatibility has become more significant. Therefore this changeset introduces a private _wp_die_process_input() function that handles all function parameters consistently.

Props spacedmonkey, flixos90, schlessera.
Fixes #45933. See #44458.

File:
1 edited

Legend:

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

    r44627 r44666  
    29562956 *                                  is still loading and the site's locale is not set up yet. Accepts 'rtl'.
    29572957 *                                  Default is the value of is_rtl().
     2958 *     @type string $code           Error code to use. Default is 'wp_die', or the main error code if $message
     2959 *                                  is a WP_Error.
    29582960 * }
    29592961 */
     
    30223024 */
    30233025function _default_wp_die_handler( $message, $title = '', $args = array() ) {
    3024     $defaults = array( 'response' => 500 );
    3025     $r        = wp_parse_args( $args, $defaults );
     3026    list( $message, $title, $r ) = _wp_die_process_input( $message, $title, $args );
     3027
     3028    if ( is_string( $message ) ) {
     3029        if ( ! empty( $r['additional_errors'] ) ) {
     3030            $message = array_merge(
     3031                array( $message ),
     3032                wp_list_pluck( $r['additional_errors'], 'message' )
     3033            );
     3034            $message = "<ul>\n\t\t<li>" . join( "</li>\n\t\t<li>", $message ) . "</li>\n\t</ul>";
     3035        } else {
     3036            $message = "<p>$message</p>";
     3037        }
     3038    }
    30263039
    30273040    $have_gettext = function_exists( '__' );
    3028 
    3029     if ( function_exists( 'is_wp_error' ) && is_wp_error( $message ) ) {
    3030         if ( empty( $title ) ) {
    3031             $error_data = $message->get_error_data();
    3032             if ( is_array( $error_data ) && isset( $error_data['title'] ) ) {
    3033                 $title = $error_data['title'];
    3034             }
    3035         }
    3036         $errors = $message->get_error_messages();
    3037         switch ( count( $errors ) ) {
    3038             case 0:
    3039                 $message = '';
    3040                 break;
    3041             case 1:
    3042                 $message = "<p>{$errors[0]}</p>";
    3043                 break;
    3044             default:
    3045                 $message = "<ul>\n\t\t<li>" . join( "</li>\n\t\t<li>", $errors ) . "</li>\n\t</ul>";
    3046                 break;
    3047         }
    3048     } elseif ( is_string( $message ) ) {
    3049         $message = "<p>$message</p>";
    3050     }
    30513041
    30523042    if ( ! empty( $r['link_url'] ) && ! empty( $r['link_text'] ) ) {
     
    30713061        }
    30723062
    3073         if ( empty( $title ) ) {
    3074             $title = $have_gettext ? __( 'WordPress &rsaquo; Error' ) : 'WordPress &rsaquo; Error';
    3075         }
    3076 
    3077         $text_direction = 'ltr';
    3078         if ( isset( $r['text_direction'] ) && 'rtl' == $r['text_direction'] ) {
    3079             $text_direction = 'rtl';
    3080         } elseif ( function_exists( 'is_rtl' ) && is_rtl() ) {
    3081             $text_direction = 'rtl';
    3082         }
    3083 
     3063        $text_direction = $r['text_direction'];
    30843064        if ( function_exists( 'language_attributes' ) && function_exists( 'is_rtl' ) ) {
    30853065            $dir_attr = get_language_attributes();
     
    32383218 */
    32393219function _json_wp_die_handler( $message, $title = '', $args = array() ) {
    3240     $defaults = array( 'response' => 500 );
    3241 
    3242     $r = wp_parse_args( $args, $defaults );
     3220    list( $message, $title, $r ) = _wp_die_process_input( $message, $title, $args );
    32433221
    32443222    $data = array(
    3245         'code'    => 'wp_die',
    3246         'message' => $message,
    3247         'status'  => $r['response'],
     3223        'code'              => $r['code'],
     3224        'message'           => $message,
     3225        'data'              => array(
     3226            'status' => $r['response'],
     3227        ),
     3228        'additional_errors' => $r['additional_errors'],
    32483229    );
    32493230
     
    32753256function _xmlrpc_wp_die_handler( $message, $title = '', $args = array() ) {
    32763257    global $wp_xmlrpc_server;
    3277     $defaults = array( 'response' => 500 );
    3278 
    3279     $r = wp_parse_args( $args, $defaults );
     3258
     3259    list( $message, $title, $r ) = _wp_die_process_input( $message, $title, $args );
    32803260
    32813261    if ( $wp_xmlrpc_server ) {
     
    32993279 */
    33003280function _ajax_wp_die_handler( $message, $title = '', $args = array() ) {
    3301     $defaults = array(
    3302         'response' => 200,
     3281    // Set default 'response' to 200 for AJAX requests.
     3282    $args = wp_parse_args(
     3283        $args,
     3284        array( 'response' => 200 )
    33033285    );
    3304     $r        = wp_parse_args( $args, $defaults );
     3286
     3287    list( $message, $title, $r ) = _wp_die_process_input( $message, $title, $args );
    33053288
    33063289    if ( ! headers_sent() && null !== $r['response'] ) {
     
    33293312    }
    33303313    die();
     3314}
     3315
     3316/**
     3317 * Processes arguments passed to {@see wp_die()} consistently for its handlers.
     3318 *
     3319 * @since 5.1.0
     3320 * @access private
     3321 *
     3322 * @param string       $message Error message.
     3323 * @param string       $title   Optional. Error title. Default empty.
     3324 * @param string|array $args    Optional. Arguments to control behavior. Default empty array.
     3325 * @return array List of processed $message string, $title string, and $args array.
     3326 */
     3327function _wp_die_process_input( $message, $title = '', $args = array() ) {
     3328    $defaults = array(
     3329        'response'          => 0,
     3330        'code'              => '',
     3331        'back_link'         => false,
     3332        'link_url'          => '',
     3333        'link_text'         => '',
     3334        'text_direction'    => '',
     3335        'additional_errors' => array(),
     3336    );
     3337
     3338    $args = wp_parse_args( $args, $defaults );
     3339
     3340    if ( function_exists( 'is_wp_error' ) && is_wp_error( $message ) ) {
     3341        if ( ! empty( $message->errors ) ) {
     3342            $errors = array();
     3343            foreach ( (array) $message->errors as $error_code => $error_messages ) {
     3344                foreach ( (array) $error_messages as $error_message ) {
     3345                    $errors[] = array(
     3346                        'code'    => $error_code,
     3347                        'message' => $error_message,
     3348                        'data'    => $error->get_error_data( $error_code ),
     3349                    );
     3350                }
     3351            }
     3352
     3353            $message = $errors[0]['message'];
     3354            if ( empty( $args['code'] ) ) {
     3355                $args['code'] = $errors[0]['code'];
     3356            }
     3357            if ( empty( $args['response'] ) && is_array( $errors[0]['data'] ) && ! empty( $errors[0]['data']['status'] ) ) {
     3358                $args['response'] = $errors[0]['data']['status'];
     3359            }
     3360            if ( empty( $title ) && is_array( $errors[0]['data'] ) && ! empty( $errors[0]['data']['title'] ) ) {
     3361                $title = $errors[0]['data']['title'];
     3362            }
     3363
     3364            unset( $errors[0] );
     3365            $args['additional_errors'] = array_values( $errors );
     3366        } else {
     3367            $message = '';
     3368        }
     3369    }
     3370
     3371    $have_gettext = function_exists( '__' );
     3372
     3373    // The $title and these specific $args must always have a non-empty value.
     3374    if ( empty( $args['code'] ) ) {
     3375        $args['code'] = 'wp_die';
     3376    }
     3377    if ( empty( $args['response'] ) ) {
     3378        $args['response'] = 500;
     3379    }
     3380    if ( empty( $title ) ) {
     3381        $title = $have_gettext ? __( 'WordPress &rsaquo; Error' ) : 'WordPress &rsaquo; Error';
     3382    }
     3383    if ( empty( $args['text_direction'] ) || ! in_array( $args['text_direction'], array( 'ltr', 'rtl' ), true ) ) {
     3384        $args['text_direction'] = 'ltr';
     3385        if ( function_exists( 'is_rtl' ) && is_rtl() ) {
     3386            $args['text_direction'] = 'rtl';
     3387        }
     3388    }
     3389
     3390    return array( $message, $title, $args );
    33313391}
    33323392
Note: See TracChangeset for help on using the changeset viewer.