REST API: Normalize WP_REST_Server::dispatch() to return a response object.

Previously, the `rest_pre_dispatch` filter could be used to return a `WP_Error` instance. This would cause a fatal error for `rest_post_dispath` 
filters that were rightly expecting a `WP_REST_Response` object to be passed instead.

Props DaveFX, felipeelia.
Fixes #56566.


git-svn-id: https://develop.svn.wordpress.org/trunk@55361 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
Timothy Jacobs
2023-02-17 15:43:47 +00:00
parent ad78d0c932
commit a6d2904cb1
2 changed files with 37 additions and 4 deletions

View File

@@ -984,6 +984,15 @@ class WP_REST_Server {
$result = apply_filters( 'rest_pre_dispatch', null, $this, $request );
if ( ! empty( $result ) ) {
// Normalize to either WP_Error or WP_REST_Response...
$result = rest_ensure_response( $result );
// ...then convert WP_Error across.
if ( is_wp_error( $result ) ) {
$result = $this->error_to_response( $result );
}
return $result;
}

View File

@@ -922,11 +922,35 @@ class Tests_REST_Server extends WP_Test_REST_TestCase {
$data = array(
'untouched' => 'data',
);
$result = rest_get_server()->embed_links( $data );
$result = rest_get_server()->embed_links( $data, true );
$this->assertArrayNotHasKey( '_links', $data );
$this->assertArrayNotHasKey( '_embedded', $data );
$this->assertSame( 'data', $data['untouched'] );
$this->assertArrayNotHasKey( '_links', $result );
$this->assertArrayNotHasKey( '_embedded', $result );
$this->assertSame( 'data', $result['untouched'] );
}
/**
* Ensure embed_links handles WP_Error objects returned by dispatch
*
* @ticket 56566
*/
public function test_link_embedding_returning_wp_error() {
$return_wp_error = function() {
return new WP_Error( 'some-error', 'This is not valid!' );
};
add_filter( 'rest_pre_dispatch', $return_wp_error );
$mock = new MockAction();
add_filter( 'rest_post_dispatch', array( $mock, 'filter' ) );
$response = new WP_REST_Response();
$response->add_link( 'author', rest_url( 'test' ), array( 'embeddable' => true ) );
$data = rest_get_server()->response_to_data( $response, true );
$this->assertArrayHasKey( '_links', $data );
$this->assertCount( 1, $mock->get_events() );
$this->assertSame( 'some-error', $data['_embedded']['author'][0]['code'] );
}
public function embedded_response_callback( $request ) {