diff --git a/src/wp-includes/functions.php b/src/wp-includes/functions.php index 9552455d05..00ebbe9c62 100644 --- a/src/wp-includes/functions.php +++ b/src/wp-includes/functions.php @@ -2955,6 +2955,8 @@ function wp_nonce_ays( $action ) { * @type string $text_direction The text direction. This is only useful internally, when WordPress * is still loading and the site's locale is not set up yet. Accepts 'rtl'. * Default is the value of is_rtl(). + * @type string $code Error code to use. Default is 'wp_die', or the main error code if $message + * is a WP_Error. * } */ function wp_die( $message = '', $title = '', $args = array() ) { @@ -3021,34 +3023,22 @@ function wp_die( $message = '', $title = '', $args = array() ) { * @param string|array $args Optional. Arguments to control behavior. Default empty array. */ function _default_wp_die_handler( $message, $title = '', $args = array() ) { - $defaults = array( 'response' => 500 ); - $r = wp_parse_args( $args, $defaults ); + list( $message, $title, $r ) = _wp_die_process_input( $message, $title, $args ); + + if ( is_string( $message ) ) { + if ( ! empty( $r['additional_errors'] ) ) { + $message = array_merge( + array( $message ), + wp_list_pluck( $r['additional_errors'], 'message' ) + ); + $message = "<ul>\n\t\t<li>" . join( "</li>\n\t\t<li>", $message ) . "</li>\n\t</ul>"; + } else { + $message = "<p>$message</p>"; + } + } $have_gettext = function_exists( '__' ); - if ( function_exists( 'is_wp_error' ) && is_wp_error( $message ) ) { - if ( empty( $title ) ) { - $error_data = $message->get_error_data(); - if ( is_array( $error_data ) && isset( $error_data['title'] ) ) { - $title = $error_data['title']; - } - } - $errors = $message->get_error_messages(); - switch ( count( $errors ) ) { - case 0: - $message = ''; - break; - case 1: - $message = "<p>{$errors[0]}</p>"; - break; - default: - $message = "<ul>\n\t\t<li>" . join( "</li>\n\t\t<li>", $errors ) . "</li>\n\t</ul>"; - break; - } - } elseif ( is_string( $message ) ) { - $message = "<p>$message</p>"; - } - if ( ! empty( $r['link_url'] ) && ! empty( $r['link_text'] ) ) { $link_url = $r['link_url']; if ( function_exists( 'esc_url' ) ) { @@ -3070,17 +3060,7 @@ function _default_wp_die_handler( $message, $title = '', $args = array() ) { header( 'Content-Type: text/html; charset=utf-8' ); } - if ( empty( $title ) ) { - $title = $have_gettext ? __( 'WordPress › Error' ) : 'WordPress › Error'; - } - - $text_direction = 'ltr'; - if ( isset( $r['text_direction'] ) && 'rtl' == $r['text_direction'] ) { - $text_direction = 'rtl'; - } elseif ( function_exists( 'is_rtl' ) && is_rtl() ) { - $text_direction = 'rtl'; - } - + $text_direction = $r['text_direction']; if ( function_exists( 'language_attributes' ) && function_exists( 'is_rtl' ) ) { $dir_attr = get_language_attributes(); } else { @@ -3237,14 +3217,15 @@ function _default_wp_die_handler( $message, $title = '', $args = array() ) { * @param string|array $args Optional. Arguments to control behavior. Default empty array. */ function _json_wp_die_handler( $message, $title = '', $args = array() ) { - $defaults = array( 'response' => 500 ); - - $r = wp_parse_args( $args, $defaults ); + list( $message, $title, $r ) = _wp_die_process_input( $message, $title, $args ); $data = array( - 'code' => 'wp_die', - 'message' => $message, - 'status' => $r['response'], + 'code' => $r['code'], + 'message' => $message, + 'data' => array( + 'status' => $r['response'], + ), + 'additional_errors' => $r['additional_errors'], ); if ( ! headers_sent() ) { @@ -3274,9 +3255,8 @@ function _json_wp_die_handler( $message, $title = '', $args = array() ) { */ function _xmlrpc_wp_die_handler( $message, $title = '', $args = array() ) { global $wp_xmlrpc_server; - $defaults = array( 'response' => 500 ); - $r = wp_parse_args( $args, $defaults ); + list( $message, $title, $r ) = _wp_die_process_input( $message, $title, $args ); if ( $wp_xmlrpc_server ) { $error = new IXR_Error( $r['response'], $message ); @@ -3298,10 +3278,13 @@ function _xmlrpc_wp_die_handler( $message, $title = '', $args = array() ) { * @param string|array $args Optional. Arguments to control behavior. Default empty array. */ function _ajax_wp_die_handler( $message, $title = '', $args = array() ) { - $defaults = array( - 'response' => 200, + // Set default 'response' to 200 for AJAX requests. + $args = wp_parse_args( + $args, + array( 'response' => 200 ) ); - $r = wp_parse_args( $args, $defaults ); + + list( $message, $title, $r ) = _wp_die_process_input( $message, $title, $args ); if ( ! headers_sent() && null !== $r['response'] ) { status_header( $r['response'] ); @@ -3330,6 +3313,83 @@ function _scalar_wp_die_handler( $message = '' ) { die(); } +/** + * Processes arguments passed to {@see wp_die()} consistently for its handlers. + * + * @since 5.1.0 + * @access private + * + * @param string $message Error message. + * @param string $title Optional. Error title. Default empty. + * @param string|array $args Optional. Arguments to control behavior. Default empty array. + * @return array List of processed $message string, $title string, and $args array. + */ +function _wp_die_process_input( $message, $title = '', $args = array() ) { + $defaults = array( + 'response' => 0, + 'code' => '', + 'back_link' => false, + 'link_url' => '', + 'link_text' => '', + 'text_direction' => '', + 'additional_errors' => array(), + ); + + $args = wp_parse_args( $args, $defaults ); + + if ( function_exists( 'is_wp_error' ) && is_wp_error( $message ) ) { + if ( ! empty( $message->errors ) ) { + $errors = array(); + foreach ( (array) $message->errors as $error_code => $error_messages ) { + foreach ( (array) $error_messages as $error_message ) { + $errors[] = array( + 'code' => $error_code, + 'message' => $error_message, + 'data' => $error->get_error_data( $error_code ), + ); + } + } + + $message = $errors[0]['message']; + if ( empty( $args['code'] ) ) { + $args['code'] = $errors[0]['code']; + } + if ( empty( $args['response'] ) && is_array( $errors[0]['data'] ) && ! empty( $errors[0]['data']['status'] ) ) { + $args['response'] = $errors[0]['data']['status']; + } + if ( empty( $title ) && is_array( $errors[0]['data'] ) && ! empty( $errors[0]['data']['title'] ) ) { + $title = $errors[0]['data']['title']; + } + + unset( $errors[0] ); + $args['additional_errors'] = array_values( $errors ); + } else { + $message = ''; + } + } + + $have_gettext = function_exists( '__' ); + + // The $title and these specific $args must always have a non-empty value. + if ( empty( $args['code'] ) ) { + $args['code'] = 'wp_die'; + } + if ( empty( $args['response'] ) ) { + $args['response'] = 500; + } + if ( empty( $title ) ) { + $title = $have_gettext ? __( 'WordPress › Error' ) : 'WordPress › Error'; + } + if ( empty( $args['text_direction'] ) || ! in_array( $args['text_direction'], array( 'ltr', 'rtl' ), true ) ) { + $args['text_direction'] = 'ltr'; + if ( function_exists( 'is_rtl' ) && is_rtl() ) { + $args['text_direction'] = 'rtl'; + } + } + + return array( $message, $title, $args ); +} + /** * Encode a variable into JSON, with some sanity checks. *