Make WordPress Core

Changeset 45706


Ignore:
Timestamp:
07/31/2019 08:20:02 PM (5 years ago)
Author:
kadamwhite
Message:

REST API: Skip processing fields which are not present in the selected context.

In WP_REST_Controller::get_fields_for_response(), exclude fields which are not registered to appear in the request's context.

In conjunction with r45705 this prevents the unnecessary computation of the sample permalink when making a request that is not context=edit.

Props dlh.
Fixes #45605.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/rest-api/endpoints/class-wp-rest-controller.php

    r45566 r45706  
    518518     */
    519519    public function get_fields_for_response( $request ) {
    520         $schema = $this->get_item_schema();
    521         $fields = isset( $schema['properties'] ) ? array_keys( $schema['properties'] ) : array();
     520        $schema     = $this->get_item_schema();
     521        $properties = isset( $schema['properties'] ) ? $schema['properties'] : array();
    522522
    523523        $additional_fields = $this->get_additional_fields();
     
    526526            // because it won't be present in $this->get_item_schema().
    527527            if ( is_null( $field_options['schema'] ) ) {
    528                 $fields[] = $field_name;
    529             }
    530         }
     528                $properties[ $field_name ] = $field_options;
     529            }
     530        }
     531
     532        // Exclude fields that specify a different context than the request context.
     533        $context = $request['context'];
     534        if ( $context ) {
     535            foreach ( $properties as $name => $options ) {
     536                if ( ! empty( $options['context'] ) && ! in_array( $context, $options['context'], true ) ) {
     537                    unset( $properties[ $name ] );
     538                }
     539            }
     540        }
     541
     542        $fields = array_keys( $properties );
    531543
    532544        if ( ! isset( $request['_fields'] ) ) {
  • trunk/tests/phpunit/tests/rest-api/rest-controller.php

    r44546 r45706  
    256256    }
    257257
     258    public function test_get_fields_for_response_filters_by_context() {
     259        $controller = new WP_REST_Test_Controller();
     260
     261        $request = new WP_REST_Request( 'GET', '/wp/v2/testroute' );
     262        $request->set_param( 'context', 'view' );
     263
     264        $schema = $controller->get_item_schema();
     265        $field  = 'somefield';
     266
     267        $listener = new MockAction();
     268        $method   = 'action';
     269
     270        register_rest_field(
     271            $schema['title'],
     272            $field,
     273            array(
     274                'schema'       => array(
     275                    'type'    => 'string',
     276                    'context' => array( 'embed' ),
     277                ),
     278                'get_callback' => array( $listener, $method ),
     279            )
     280        );
     281
     282        $controller->prepare_item_for_response( array(), $request );
     283
     284        $this->assertSame( 0, $listener->get_call_count( $method ) );
     285
     286        $request->set_param( 'context', 'embed' );
     287
     288        $controller->prepare_item_for_response( array(), $request );
     289
     290        $this->assertGreaterThan( 0, $listener->get_call_count( $method ) );
     291    }
     292
     293    public function test_filtering_fields_for_response_by_context_returns_fields_with_no_context() {
     294        $controller = new WP_REST_Test_Controller();
     295
     296        $request = new WP_REST_Request( 'GET', '/wp/v2/testroute' );
     297        $request->set_param( 'context', 'view' );
     298
     299        $schema = $controller->get_item_schema();
     300        $field  = 'somefield';
     301
     302        $listener = new MockAction();
     303        $method   = 'action';
     304
     305        register_rest_field(
     306            $schema['title'],
     307            $field,
     308            array(
     309                'schema'       => array(
     310                    'type' => 'string',
     311                ),
     312                'get_callback' => array( $listener, $method ),
     313            )
     314        );
     315
     316        $controller->prepare_item_for_response( array(), $request );
     317
     318        $this->assertGreaterThan( 0, $listener->get_call_count( $method ) );
     319    }
     320
     321    public function test_filtering_fields_for_response_by_context_returns_fields_with_no_schema() {
     322        $controller = new WP_REST_Test_Controller();
     323
     324        $request = new WP_REST_Request( 'GET', '/wp/v2/testroute' );
     325        $request->set_param( 'context', 'view' );
     326
     327        $schema = $controller->get_item_schema();
     328        $field  = 'somefield';
     329
     330        $listener = new MockAction();
     331        $method   = 'action';
     332
     333        register_rest_field(
     334            $schema['title'],
     335            $field,
     336            array(
     337                'get_callback' => array( $listener, $method ),
     338            )
     339        );
     340
     341        $controller->prepare_item_for_response( array(), $request );
     342
     343        $this->assertGreaterThan( 0, $listener->get_call_count( $method ) );
     344    }
     345
    258346    public function test_add_additional_fields_to_object_respects_fields_param() {
    259347        $controller = new WP_REST_Test_Controller();
Note: See TracChangeset for help on using the changeset viewer.