--- a/wp/wp-includes/rest-api/class-wp-rest-request.php Tue Oct 22 16:11:46 2019 +0200
+++ b/wp/wp-includes/rest-api/class-wp-rest-request.php Tue Dec 15 13:49:49 2020 +0100
@@ -24,7 +24,7 @@
*
* @since 4.4.0
*
- * @see ArrayAccess
+ * @link https://www.php.net/manual/en/class.arrayaccess.php
*/
class WP_REST_Request implements ArrayAccess {
@@ -294,7 +294,9 @@
*
* @since 4.4.0
*
- * @return array Map containing 'value' and 'parameters' keys.
+ * @return array|null Map containing 'value' and 'parameters' keys
+ * or null when no valid content-type header was
+ * available.
*/
public function get_content_type() {
$value = $this->get_header( 'content-type' );
@@ -308,7 +310,7 @@
}
$value = strtolower( $value );
- if ( strpos( $value, '/' ) === false ) {
+ if ( false === strpos( $value, '/' ) ) {
return null;
}
@@ -328,13 +330,13 @@
*
* @since 4.4.0
*
- * @return array List of types to check, in order of priority.
+ * @return string[] Array of types to check, in order of priority.
*/
protected function get_parameter_order() {
$order = array();
$content_type = $this->get_content_type();
- if ( $content_type['value'] === 'application/json' ) {
+ if ( isset( $content_type['value'] ) && 'application/json' === $content_type['value'] ) {
$order[] = 'JSON';
}
@@ -348,7 +350,7 @@
}
$accepts_body_data = array( 'POST', 'PUT', 'PATCH', 'DELETE' );
- if ( in_array( $this->method, $accepts_body_data ) ) {
+ if ( in_array( $this->method, $accepts_body_data, true ) ) {
$order[] = 'POST';
}
@@ -364,12 +366,8 @@
*
* @since 4.4.0
*
- * @param array $order {
- * An array of types to check, in order of priority.
- *
- * @param string $type The type to check.
- * }
- * @param WP_REST_Request $this The request object.
+ * @param string[] $order Array of types to check, in order of priority.
+ * @param WP_REST_Request $this The request object.
*/
return apply_filters( 'rest_request_parameter_order', $order, $this );
}
@@ -396,16 +394,54 @@
}
/**
+ * Checks if a parameter exists in the request.
+ *
+ * This allows distinguishing between an omitted parameter,
+ * and a parameter specifically set to null.
+ *
+ * @since 5.3.0
+ *
+ * @param string $key Parameter name.
+ * @return bool True if a param exists for the given key.
+ */
+ public function has_param( $key ) {
+ $order = $this->get_parameter_order();
+
+ foreach ( $order as $type ) {
+ if ( is_array( $this->params[ $type ] ) && array_key_exists( $key, $this->params[ $type ] ) ) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
* Sets a parameter on the request.
*
+ * If the given parameter key exists in any parameter type an update will take place,
+ * otherwise a new param will be created in the first parameter type (respecting
+ * get_parameter_order()).
+ *
* @since 4.4.0
*
* @param string $key Parameter name.
* @param mixed $value Parameter value.
*/
public function set_param( $key, $value ) {
- $order = $this->get_parameter_order();
- $this->params[ $order[0] ][ $key ] = $value;
+ $order = $this->get_parameter_order();
+ $found_key = false;
+
+ foreach ( $order as $type ) {
+ if ( 'defaults' !== $type && is_array( $this->params[ $type ] ) && array_key_exists( $key, $this->params[ $type ] ) ) {
+ $this->params[ $type ][ $key ] = $value;
+ $found_key = true;
+ }
+ }
+
+ if ( ! $found_key ) {
+ $this->params[ $order[0] ][ $key ] = $value;
+ }
}
/**
@@ -424,7 +460,7 @@
$params = array();
foreach ( $order as $type ) {
- // array_merge / the "+" operator will mess up
+ // array_merge() / the "+" operator will mess up
// numeric keys, so instead do a manual foreach.
foreach ( (array) $this->params[ $type ] as $key => $value ) {
$params[ $key ] = $value;
@@ -637,26 +673,22 @@
/*
* Check for a parsing error.
- *
- * Note that due to WP's JSON compatibility functions, json_last_error
- * might not be defined: https://core.trac.wordpress.org/ticket/27799
*/
- if ( null === $params && ( ! function_exists( 'json_last_error' ) || JSON_ERROR_NONE !== json_last_error() ) ) {
+ if ( null === $params && JSON_ERROR_NONE !== json_last_error() ) {
// Ensure subsequent calls receive error instance.
$this->parsed_json = false;
$error_data = array(
- 'status' => WP_Http::BAD_REQUEST,
+ 'status' => WP_Http::BAD_REQUEST,
+ 'json_error_code' => json_last_error(),
+ 'json_error_message' => json_last_error_msg(),
);
- if ( function_exists( 'json_last_error' ) ) {
- $error_data['json_error_code'] = json_last_error();
- $error_data['json_error_message'] = json_last_error_msg();
- }
return new WP_Error( 'rest_invalid_json', __( 'Invalid JSON body passed.' ), $error_data );
}
$this->params['JSON'] = $params;
+
return true;
}
@@ -688,15 +720,6 @@
parse_str( $this->get_body(), $params );
/*
- * Amazingly, parse_str follows magic quote rules. Sigh.
- *
- * NOTE: Do not refactor to use `wp_unslash`.
- */
- if ( get_magic_quotes_gpc() ) {
- $params = stripslashes_deep( $params );
- }
-
- /*
* Add to the POST parameters stored internally. If a user has already
* set these manually (via `set_body_params`), don't override them.
*/
@@ -775,10 +798,12 @@
if ( empty( $this->params[ $type ] ) ) {
continue;
}
+
foreach ( $this->params[ $type ] as $key => $value ) {
if ( ! isset( $attributes['args'][ $key ] ) ) {
continue;
}
+
$param_args = $attributes['args'][ $key ];
// If the arg has a type but no sanitize_callback attribute, default to rest_parse_request_arg.
@@ -803,6 +828,7 @@
if ( $invalid_params ) {
return new WP_Error(
'rest_invalid_param',
+ /* translators: %s: List of invalid parameters. */
sprintf( __( 'Invalid parameter(s): %s' ), implode( ', ', array_keys( $invalid_params ) ) ),
array(
'status' => 400,
@@ -848,6 +874,7 @@
if ( ! empty( $required ) ) {
return new WP_Error(
'rest_missing_callback_param',
+ /* translators: %s: List of required parameters. */
sprintf( __( 'Missing parameter(s): %s' ), implode( ', ', $required ) ),
array(
'status' => 400,
@@ -883,6 +910,7 @@
if ( $invalid_params ) {
return new WP_Error(
'rest_invalid_param',
+ /* translators: %s: List of invalid parameters. */
sprintf( __( 'Invalid parameter(s): %s' ), implode( ', ', array_keys( $invalid_params ) ) ),
array(
'status' => 400,
@@ -977,7 +1005,7 @@
$api_url_part = substr( $url, strlen( untrailingslashit( $api_root ) ) );
$route = parse_url( $api_url_part, PHP_URL_PATH );
} elseif ( ! empty( $query_params['rest_route'] ) ) {
- // ?rest_route=... set directly
+ // ?rest_route=... set directly.
$route = $query_params['rest_route'];
unset( $query_params['rest_route'] );
}