Make WordPress Core


Ignore:
Timestamp:
03/11/2025 02:17:41 PM (3 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/wpRestTemplateAutosavesController.php

    r59899 r59970  
    317317        $response = rest_get_server()->dispatch( $request );
    318318        $this->assertSame( 200, $response->get_status(), 'Response status is 200.' );
    319         $this->assertNull( $response->get_data(), 'The server should not generate a body in response to a HEAD request.' );
     319        $this->assertSame( array(), $response->get_data(), 'The server should not generate a body in response to a HEAD request.' );
    320320    }
    321321
     
    471471        $response = rest_get_server()->dispatch( $request );
    472472        $this->assertSame( 200, $response->get_status(), 'Response status is 200.' );
    473         $this->assertNull( $response->get_data(), 'The server should not generate a body in response to a HEAD request.' );
     473        $this->assertSame( array(), $response->get_data(), 'The server should not generate a body in response to a HEAD request.' );
    474474    }
    475475
     
    484484            'template parts' => array( 'template_part_post', 'template-parts', self::TEST_THEME . '//' . self::TEMPLATE_PART_NAME ),
    485485        );
     486    }
     487
     488    /**
     489     * @dataProvider data_get_item_with_data_provider
     490     * @covers       WP_REST_Template_Autosaves_Controller::get_item
     491     * @ticket 56922
     492     *
     493     * @param string $parent_post_property_name A class property name that contains the parent post object.
     494     * @param string $rest_base Base part of the REST API endpoint to test.
     495     * @param string $template_id Template ID to use in the test.
     496     */
     497    public function test_get_item_head_request_with_specified_fields_returns_success_response( $parent_post_property_name, $rest_base, $template_id ) {
     498        wp_set_current_user( self::$admin_id );
     499
     500        $parent_post = self::$$parent_post_property_name;
     501
     502        $autosave_post_id = wp_create_post_autosave(
     503            array(
     504                'post_content' => 'Autosave content.',
     505                'post_ID'      => $parent_post->ID,
     506                'post_type'    => $parent_post->post_type,
     507            )
     508        );
     509
     510        $request = new WP_REST_Request(
     511            'HEAD',
     512            '/wp/v2/' . $rest_base . '/' . $template_id . '/autosaves/' . $autosave_post_id
     513        );
     514        $request->set_param( '_fields', 'id' );
     515        $server   = rest_get_server();
     516        $response = $server->dispatch( $request );
     517
     518        add_filter( 'rest_post_dispatch', 'rest_filter_response_fields', 10, 3 );
     519        $response = apply_filters( 'rest_post_dispatch', $response, $server, $request );
     520        remove_filter( 'rest_post_dispatch', 'rest_filter_response_fields', 10 );
     521
     522        $this->assertSame( 200, $response->get_status(), 'The response status should be 200.' );
     523    }
     524
     525    /**
     526     * @dataProvider data_get_items_with_data_provider
     527     * @covers       WP_REST_Template_Autosaves_Controller::get_items
     528     * @ticket 56922
     529     *
     530     * @param string $parent_post_property_name A class property name that contains the parent post object.
     531     * @param string $rest_base Base part of the REST API endpoint to test.
     532     * @param string $template_id Template ID to use in the test.
     533     */
     534    public function test_get_items_head_request_with_specified_fields_returns_success_response( $parent_post_property_name, $rest_base, $template_id ) {
     535        wp_set_current_user( self::$admin_id );
     536        // Cannot access this property in the data provider because it is not initialized at the time of execution.
     537        $parent_post = self::$$parent_post_property_name;
     538        wp_create_post_autosave(
     539            array(
     540                'post_content' => 'Autosave content.',
     541                'post_ID'      => $parent_post->ID,
     542                'post_type'    => $parent_post->post_type,
     543            )
     544        );
     545
     546        $request = new WP_REST_Request(
     547            'HEAD',
     548            '/wp/v2/' . $rest_base . '/' . $template_id . '/autosaves'
     549        );
     550        $request->set_param( '_fields', 'id' );
     551        $server   = rest_get_server();
     552        $response = $server->dispatch( $request );
     553
     554        add_filter( 'rest_post_dispatch', 'rest_filter_response_fields', 10, 3 );
     555        $response = apply_filters( 'rest_post_dispatch', $response, $server, $request );
     556        remove_filter( 'rest_post_dispatch', 'rest_filter_response_fields', 10 );
     557
     558        $this->assertSame( 200, $response->get_status(), 'The response status should be 200.' );
    486559    }
    487560
Note: See TracChangeset for help on using the changeset viewer.