Make WordPress Core


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

    r59899 r59970  
    473473                $this->assertSame( 200, $response->get_status(), 'The response status should be 200.' );
    474474                $this->assertSame( 0, $filter->get_call_count(), 'The "' . $hook_name . '" filter was called when it should not be for HEAD requests.' );
    475                 $this->assertNull( $response->get_data(), 'The server should not generate a body in response to a HEAD request.' );
     475                $this->assertSame( array(), $response->get_data(), 'The server should not generate a body in response to a HEAD request.' );
    476476        }
    477477
    … …  
    645645                        return null;
    646646                }
    647                 $this->assertNull( $response->get_data(), 'The server should not generate a body in response to a HEAD request.' );
     647                $this->assertSame( array(), $response->get_data(), 'The server should not generate a body in response to a HEAD request.' );
     648        }
     649
     650        /**
     651         * @dataProvider data_head_request_with_specified_fields_returns_success_response
     652         * @ticket 56481
     653         *
     654         * @param string $path The path to test.
     655         */
     656        public function test_head_request_with_specified_fields_returns_success_response( $path ) {
     657                add_filter( 'pre_http_request', array( $this, 'mocked_rss_response' ) );
     658                global $wp_widget_factory;
     659
     660                $wp_widget_factory->widgets['WP_Widget_RSS']->widget_options['show_instance_in_rest'] = false;
     661
     662                $block_content = '<!-- wp:paragraph --><p>Block test</p><!-- /wp:paragraph -->';
     663
     664                $this->setup_widget(
     665                        'rss',
     666                        1,
     667                        array(
     668                                'title' => 'RSS test',
     669                                'url'   => 'https://wordpress.org/news/feed',
     670                        )
     671                );
     672                $this->setup_widget(
     673                        'block',
     674                        1,
     675                        array(
     676                                'content' => $block_content,
     677                        )
     678                );
     679                $this->setup_sidebar(
     680                        'sidebar-1',
     681                        array(
     682                                'name' => 'Test sidebar',
     683                        ),
     684                        array( 'block-1', 'rss-1', 'testwidget' )
     685                );
     686
     687                $request = new WP_REST_Request( 'HEAD', $path );
     688                $request->set_param( '_fields', 'id' );
     689                $server   = rest_get_server();
     690                $response = $server->dispatch( $request );
     691                add_filter( 'rest_post_dispatch', 'rest_filter_response_fields', 10, 3 );
     692                $response = apply_filters( 'rest_post_dispatch', $response, $server, $request );
     693                remove_filter( 'rest_post_dispatch', 'rest_filter_response_fields', 10 );
     694                remove_filter( 'pre_http_request', array( $this, 'mocked_rss_response' ) );
     695
     696                $this->assertSame( 200, $response->get_status(), 'The response status should be 200.' );
     697        }
     698
     699        /**
     700         * Data provider intended to provide paths for testing HEAD requests.
     701         *
     702         * @return array
     703         */
     704        public static function data_head_request_with_specified_fields_returns_success_response() {
     705                return array(
     706                        'get_item request'  => array( '/wp/v2/widgets/block-1' ),
     707                        'get_items request' => array( '/wp/v2/widgets' ),
     708                );
    648709        }
    649710
Note: See TracChangeset for help on using the changeset viewer.