Make WordPress Core


Ignore:
Timestamp:
03/11/2025 02:17:41 PM (12 months ago)
Author:
TimothyBlynJacobs
Message:

REST API: Fix fatal error when making HEAD requests with _fields filter.

In [59889] the REST API controllers were adjusted to perform less work when responding to HEAD requests. The WP_REST_Response body would now be null, which caused issues with filters that expected the response body to be an array.

This commit sets the response body to be an empty array when preparing the response instead. The body will still be discarded, but this provides better backward comppatibility with code that assumes an array will be used.

See #56481.
Props antonvlasenko, timothyblynjacobs, mamaduka, wildworks.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/tests/phpunit/tests/rest-api/rest-posts-controller.php

    r59899 r59970  
    296296        $this->assertSame( 0, $filter->get_call_count(), 'The "' . $hook_name . '" filter was called when it should not be for HEAD requests.' );
    297297        $this->assertArrayHasKey( 'Link', $headers, 'The "Link" header should be present in the response.' );
    298         $this->assertNull( $response->get_data(), 'The server should not generate a body in response to a HEAD request.' );
     298        $this->assertSame( array(), $response->get_data(), 'The server should not generate a body in response to a HEAD request.' );
    299299    }
    300300
     
    321321
    322322        if ( $request->is_method( 'HEAD' ) ) {
    323             $this->assertNull( $response->get_data(), 'Failed asserting that response data is null for HEAD request.' );
     323            $this->assertSame( array(), $response->get_data(), 'Failed asserting that response data is null for HEAD request.' );
    324324        } else {
    325325            $this->assertSame( array(), $response->get_data(), 'Failed asserting that response data is an empty array for GET request.' );
     
    352352
    353353        } else {
    354             $this->assertNull( $response->get_data(), 'Failed asserting that response data is null for HEAD request.' );
     354            $this->assertSame( array(), $response->get_data(), 'Failed asserting that response data is null for HEAD request.' );
    355355            $headers = $response->get_headers();
    356356            $this->assertSame( $total_posts, $headers['X-WP-Total'] );
     
    367367            $this->assertSameSets( array( self::$editor_id, self::$author_id ), wp_list_pluck( $data, 'author' ) );
    368368        } else {
    369             $this->assertNull( $data, 'Failed asserting that response data is null for HEAD request.' );
     369            $this->assertSame( array(), $data, 'Failed asserting that response data is null for HEAD request.' );
    370370            $headers = $response->get_headers();
    371371            $this->assertSame( 2, $headers['X-WP-Total'], 'Failed asserting that X-WP-Total header is 2.' );
     
    382382            $this->assertSame( self::$editor_id, $data[0]['author'] );
    383383        } else {
    384             $this->assertNull( $data, 'Failed asserting that response data is null for HEAD request.' );
     384            $this->assertSame( array(), $data, 'Failed asserting that response data is null for HEAD request.' );
    385385            $headers = $response->get_headers();
    386386            $this->assertSame( 1, $headers['X-WP-Total'], 'Failed asserting that X-WP-Total header is 1.' );
     
    408408            $this->assertCount( $total_posts, $response->get_data() );
    409409        } else {
    410             $this->assertNull( $response->get_data(), 'Failed asserting that response data is null for HEAD request.' );
     410            $this->assertSame( array(), $response->get_data(), 'Failed asserting that response data is null for HEAD request.' );
    411411            $headers = $response->get_headers();
    412412            $this->assertSame( $total_posts, $headers['X-WP-Total'], 'Failed asserting that the number of posts is correct.' );
     
    425425            $this->assertNotEquals( self::$author_id, $data[0]['author'] );
    426426        } else {
    427             $this->assertNull( $response->get_data(), 'Failed asserting that response data is null for HEAD request.' );
     427            $this->assertSame( array(), $response->get_data(), 'Failed asserting that response data is null for HEAD request.' );
    428428            $headers = $response->get_headers();
    429429            $this->assertSame( $total_posts - 2, $headers['X-WP-Total'], 'Failed asserting that the number of posts is correct.' );
     
    442442            $this->assertNotEquals( self::$editor_id, $data[1]['author'] );
    443443        } else {
    444             $this->assertNull( $response->get_data(), 'Failed asserting that response data is null for HEAD request.' );
     444            $this->assertSame( array(), $response->get_data(), 'Failed asserting that response data is null for HEAD request.' );
    445445            $headers = $response->get_headers();
    446446            $this->assertSame( $total_posts - 1, $headers['X-WP-Total'], 'Failed asserting that the number of posts is correct.' );
     
    484484            $this->assertSame( $id2, $data[0]['id'] );
    485485        } else {
    486             $this->assertNull( $data, 'Failed asserting that response data is null for HEAD request.' );
     486            $this->assertSame( array(), $data, 'Failed asserting that response data is null for HEAD request.' );
    487487            $headers = $response->get_headers();
    488488            $this->assertSame( 2, $headers['X-WP-Total'], 'Failed asserting that the number of posts is correct.' );
     
    499499            $this->assertSame( $id1, $data[0]['id'] );
    500500        } else {
    501             $this->assertNull( $data, 'Failed asserting that response data is null for HEAD request.' );
     501            $this->assertSame( array(), $data, 'Failed asserting that response data is null for HEAD request.' );
    502502            $headers = $response->get_headers();
    503503            $this->assertSame( 2, $headers['X-WP-Total'], 'Failed asserting that the number of posts is correct.' );
     
    21942194            return null;
    21952195        }
    2196         $this->assertNull( $response->get_data(), 'The server should not generate a body in response to a HEAD request.' );
     2196        $this->assertSame( array(), $response->get_data(), 'The server should not generate a body in response to a HEAD request.' );
     2197    }
     2198
     2199    /**
     2200     * @dataProvider data_head_request_with_specified_fields_returns_success_response
     2201     * @ticket 56481
     2202     *
     2203     * @param string $path The path to test.
     2204     */
     2205    public function test_head_request_with_specified_fields_returns_success_response( $path ) {
     2206        $request = new WP_REST_Request( 'HEAD', sprintf( $path, self::$post_id ) );
     2207        $request->set_param( '_fields', 'id' );
     2208        $server   = rest_get_server();
     2209        $response = $server->dispatch( $request );
     2210        add_filter( 'rest_post_dispatch', 'rest_filter_response_fields', 10, 3 );
     2211        $response = apply_filters( 'rest_post_dispatch', $response, $server, $request );
     2212        remove_filter( 'rest_post_dispatch', 'rest_filter_response_fields', 10 );
     2213
     2214        $this->assertSame( 200, $response->get_status(), 'The response status should be 200.' );
     2215    }
     2216
     2217    /**
     2218     * Data provider intended to provide paths for testing HEAD requests.
     2219     *
     2220     * @return array
     2221     */
     2222    public static function data_head_request_with_specified_fields_returns_success_response() {
     2223        return array(
     2224            'get_item request'  => array( '/wp/v2/posts/%d' ),
     2225            'get_items request' => array( '/wp/v2/posts' ),
     2226        );
    21972227    }
    21982228
Note: See TracChangeset for help on using the changeset viewer.