WordPress.org

Make WordPress Core

Ticket #38420: 38420.4.diff

File 38420.4.diff, 5.4 KB (added by kadamwhite, 5 years ago)

Refreshed patch to apply cleanly, and fixed test name in the process

  • src/wp-includes/rest-api.php

    diff --git src/wp-includes/rest-api.php src/wp-includes/rest-api.php
    index 1a7da17..cea7218 100644
    function rest_validate_request_arg( $value, $request, $param ) { 
    825825                }
    826826        }
    827827
     828        // Handle enum arrays.
     829        if ( 'array' === $args['type'] && ! empty( $args['items']['enum'] ) && ! empty( $args['items']['type'] ) && 'string' === $args['items']['type'] ) {
     830                $values = wp_parse_slug_list( $value );
     831                $wrong_params = array();
     832                foreach ( $values as $val ) {
     833                        if ( ! in_array( $val, $args['items']['enum'], true ) ) {
     834                                $wrong_params[] = $val;
     835                        }
     836                }
     837
     838                if ( count( $wrong_params ) > 0 ) {
     839                        return new WP_Error( 'rest_invalid_param', sprintf( /* translators: 1: parameter, 2: list of valid values */ __( '%1$s contains values not of %2$s.' ), $param, implode( ', ', $args['items']['enum'] ) ) );
     840                }
     841        }
     842
    828843        if ( 'integer' === $args['type'] && ! is_numeric( $value ) ) {
    829844                return new WP_Error( 'rest_invalid_param', sprintf( /* translators: 1: parameter, 2: type name */ __( '%1$s is not of type %2$s.' ), $param, 'integer' ) );
    830845        }
  • src/wp-includes/rest-api/class-wp-rest-server.php

    diff --git src/wp-includes/rest-api/class-wp-rest-server.php src/wp-includes/rest-api/class-wp-rest-server.php
    index 391f549..957a436 100644
    class WP_REST_Server { 
    11811181                                        if ( isset( $opts['description'] ) ) {
    11821182                                                $arg_data['description'] = $opts['description'];
    11831183                                        }
     1184                                        if ( isset( $opts['items'] ) ) {
     1185                                                if ( isset( $opts['items']['enum'] ) ) {
     1186                                                        $arg_data['items']['enum'] = $opts['items']['enum'];
     1187                                                }
     1188                                                if ( isset( $opts['items']['type'] ) ) {
     1189                                                        $arg_data['items']['type'] = $opts['items']['type'];
     1190                                                }
     1191                                        }
    11841192                                        $endpoint_data['args'][ $key ] = $arg_data;
    11851193                                }
    11861194                        }
  • src/wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php

    diff --git src/wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php src/wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php
    index 6812c13..64f5933 100644
    class WP_REST_Posts_Controller extends WP_REST_Controller { 
    19051905                $params['status'] = array(
    19061906                        'default'           => 'publish',
    19071907                        'description'       => __( 'Limit result set to posts assigned a specific status; can be comma-delimited list of status types.' ),
    1908                         'enum'              => array_merge( array_keys( get_post_stati() ), array( 'any' ) ),
    1909                         'sanitize_callback' => 'sanitize_key',
    1910                         'type'              => 'string',
     1908                        'sanitize_callback' => 'wp_parse_slug_list',
     1909                        'type'              => 'array',
     1910                        'items'             => array(
     1911                                'enum' => array_merge( array_keys( get_post_stati() ), array( 'any' ) ),
     1912                                'type' => 'string',
     1913                        ),
    19111914                        'validate_callback' => array( $this, 'validate_user_can_query_private_statuses' ),
    19121915                );
    19131916                $params['filter'] = array(
    class WP_REST_Posts_Controller extends WP_REST_Controller { 
    19461949         * @return WP_Error|boolean
    19471950         */
    19481951        public function validate_user_can_query_private_statuses( $value, $request, $parameter ) {
    1949                 if ( 'publish' === $value ) {
     1952                // "publish" and array( "publish" ) are equivalent, and always queryable.
     1953                if ( 'publish' === $value || is_array( $value ) && count( 1 === $value ) && in_array( 'publish', $value, true ) ) {
    19501954                        return rest_validate_request_arg( $value, $request, $parameter );
    19511955                }
    19521956                $post_type_obj = get_post_type_object( $this->post_type );
  • tests/phpunit/tests/rest-api/rest-posts-controller.php

    diff --git tests/phpunit/tests/rest-api/rest-posts-controller.php tests/phpunit/tests/rest-api/rest-posts-controller.php
    index dd86f94..d1c1d59 100644
    class WP_Test_REST_Posts_Controller extends WP_Test_REST_Post_Type_Controller_Te 
    248248                $this->assertErrorResponse( 'rest_invalid_param', $response, 400 );
    249249        }
    250250
     251        public function test_get_items_multiple_status_query() {
     252                wp_set_current_user( 0 );
     253                $this->factory->post->create( array( 'post_status' => 'draft' ) );
     254
     255                $request = new WP_REST_Request( 'GET', '/wp/v2/posts' );
     256                $request->set_param( 'status', array( 'publish' ) );
     257                $response = $this->server->dispatch( $request );
     258                $this->assertEquals( 200, $response->get_status() );
     259                $this->assertEquals( 1, count( $response->get_data() ) );
     260
     261                $request = new WP_REST_Request( 'GET', '/wp/v2/posts' );
     262                $request->set_param( 'status', array( 'draft', 'post' ) );
     263                $response = $this->server->dispatch( $request );
     264                $this->assertErrorResponse( 'rest_invalid_param', $response, 400 );
     265
     266                wp_set_current_user( $this->editor_id );
     267
     268                $request = new WP_REST_Request( 'GET', '/wp/v2/posts' );
     269                $request->set_param( 'status', 'draft,publish' );
     270                $response = $this->server->dispatch( $request );
     271                $this->assertEquals( 200, $response->get_status() );
     272                $this->assertEquals( 2, count( $response->get_data() ) );
     273
     274                $request = new WP_REST_Request( 'GET', '/wp/v2/posts' );
     275                $request->set_param( 'status', array( 'draft', 'publish' ) );
     276                $response = $this->server->dispatch( $request );
     277                $this->assertEquals( 200, $response->get_status() );
     278                $this->assertEquals( 2, count( $response->get_data() ) );
     279        }
     280
    251281        public function test_get_items_status_without_permissions() {
    252282                $draft_id = $this->factory->post->create( array(
    253283                        'post_status' => 'draft',