diff --git a/wp-includes/rest-api.php b/wp-includes/rest-api.php index 2d6ecde631..58cbcacbfb 100644 --- a/wp-includes/rest-api.php +++ b/wp-includes/rest-api.php @@ -1658,3 +1658,63 @@ function rest_parse_embed_param( $embed ) { return $rels; } + +/** + * Filters the response to remove any fields not available in the given context. + * + * @since 5.5.0 + * + * @param array|object $data The response data to modify. + * @param array $schema The schema for the endpoint used to filter the response. + * @param string $context The requested context. + * @return array|object The filtered response data. + */ +function rest_filter_response_by_context( $data, $schema, $context ) { + if ( ! is_array( $data ) && ! is_object( $data ) ) { + return $data; + } + + if ( isset( $schema['type'] ) ) { + $type = $schema['type']; + } elseif ( isset( $schema['properties'] ) ) { + $type = 'object'; // Back compat if a developer accidentally omitted the type. + } else { + return $data; + } + + foreach ( $data as $key => $value ) { + $check = array(); + + if ( 'array' === $type || ( is_array( $type ) && in_array( 'array', $type, true ) ) ) { + $check = isset( $schema['items'] ) ? $schema['items'] : array(); + } elseif ( 'object' === $type || ( is_array( $type ) && in_array( 'object', $type, true ) ) ) { + if ( isset( $schema['properties'][ $key ] ) ) { + $check = $schema['properties'][ $key ]; + } elseif ( isset( $schema['additionalProperties'] ) && is_array( $schema['additionalProperties'] ) ) { + $check = $schema['additionalProperties']; + } + } + + if ( ! isset( $check['context'] ) ) { + continue; + } + + if ( ! in_array( $context, $check['context'], true ) ) { + if ( is_object( $data ) ) { + unset( $data->$key ); + } else { + unset( $data[ $key ] ); + } + } elseif ( is_array( $value ) || is_object( $value ) ) { + $new_value = rest_filter_response_by_context( $value, $check, $context ); + + if ( is_object( $data ) ) { + $data->$key = $new_value; + } else { + $data[ $key ] = $new_value; + } + } + } + + return $data; +} diff --git a/wp-includes/rest-api/endpoints/class-wp-rest-controller.php b/wp-includes/rest-api/endpoints/class-wp-rest-controller.php index b9c05eb894..da5254a327 100644 --- a/wp-includes/rest-api/endpoints/class-wp-rest-controller.php +++ b/wp-includes/rest-api/endpoints/class-wp-rest-controller.php @@ -288,7 +288,7 @@ abstract class WP_REST_Controller { * * @since 4.7.0 * - * @param array $data Response data to fiter. + * @param array $data Response data to filter. * @param string $context Context defined in the schema. * @return array Filtered response. */ @@ -296,32 +296,7 @@ abstract class WP_REST_Controller { $schema = $this->get_item_schema(); - foreach ( $data as $key => $value ) { - if ( empty( $schema['properties'][ $key ] ) || empty( $schema['properties'][ $key ]['context'] ) ) { - continue; - } - - if ( ! in_array( $context, $schema['properties'][ $key ]['context'], true ) ) { - unset( $data[ $key ] ); - continue; - } - - if ( 'object' === $schema['properties'][ $key ]['type'] && ! empty( $schema['properties'][ $key ]['properties'] ) ) { - foreach ( $schema['properties'][ $key ]['properties'] as $attribute => $details ) { - if ( empty( $details['context'] ) ) { - continue; - } - - if ( ! in_array( $context, $details['context'], true ) ) { - if ( isset( $data[ $key ][ $attribute ] ) ) { - unset( $data[ $key ][ $attribute ] ); - } - } - } - } - } - - return $data; + return rest_filter_response_by_context( $data, $schema, $context ); } /** diff --git a/wp-includes/version.php b/wp-includes/version.php index d0961d8005..0af6e9b2bd 100644 --- a/wp-includes/version.php +++ b/wp-includes/version.php @@ -13,7 +13,7 @@ * * @global string $wp_version */ -$wp_version = '5.5-alpha-47757'; +$wp_version = '5.5-alpha-47758'; /** * Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.