diff --git a/src/wp-includes/rest-api/class-wp-rest-server.php b/src/wp-includes/rest-api/class-wp-rest-server.php index 056447f545..c38914c7bf 100644 --- a/src/wp-includes/rest-api/class-wp-rest-server.php +++ b/src/wp-includes/rest-api/class-wp-rest-server.php @@ -438,7 +438,8 @@ class WP_REST_Server { // Wrap the response in an envelope if asked for. if ( isset( $_GET['_envelope'] ) ) { - $result = $this->envelope_response( $result, isset( $_GET['_embed'] ) ); + $embed = isset( $_GET['_embed'] ) ? rest_parse_embed_param( $_GET['_embed'] ) : false; + $result = $this->envelope_response( $result, $embed ); } // Send extra data from response objects. @@ -730,9 +731,10 @@ class WP_REST_Server { * data instead. * * @since 4.4.0 + * @since 6.0.0 The $embed parameter can now contain a list of link relations to include * * @param WP_REST_Response $response Response object. - * @param bool $embed Whether links should be embedded. + * @param bool|string[] $embed Whether to embed all links, a filtered list of link relations, or no links. * @return WP_REST_Response New response with wrapped data */ public function envelope_response( $response, $embed ) { diff --git a/tests/phpunit/tests/rest-api/rest-server.php b/tests/phpunit/tests/rest-api/rest-server.php index 6c453c051c..52198addec 100644 --- a/tests/phpunit/tests/rest-api/rest-server.php +++ b/tests/phpunit/tests/rest-api/rest-server.php @@ -77,6 +77,62 @@ class Tests_REST_Server extends WP_Test_REST_TestCase { $this->assertSame( $headers, $enveloped['headers'] ); } + /** + * @dataProvider data_envelope_params + * @ticket 54015 + */ + public function test_envelope_param( $_embed ) { + // Register our testing route. + rest_get_server()->register_route( + 'test', + '/test/embeddable', + array( + 'methods' => 'GET', + 'callback' => array( $this, 'embedded_response_callback' ), + ) + ); + $data = array( + 'amount of arbitrary data' => 'alot', + ); + $status = 987; + $headers = array( + 'Arbitrary-Header' => 'value', + 'Multiple' => 'maybe, yes', + ); + + $response = new WP_REST_Response( $data, $status ); + $response->header( 'Arbitrary-Header', 'value' ); + + // Check header concatenation as well. + $response->header( 'Multiple', 'maybe' ); + $response->header( 'Multiple', 'yes', false ); + + // All others should be embedded. + $response->add_link( 'alternate', rest_url( '/test/embeddable' ), array( 'embeddable' => true ) ); + + $embed = rest_parse_embed_param( $_embed ); + $envelope_response = rest_get_server()->envelope_response( $response, $embed ); + + // The envelope should still be a response, but with defaults. + $this->assertInstanceOf( WP_REST_Response::class, $envelope_response ); + $this->assertSame( 200, $envelope_response->get_status() ); + $this->assertEmpty( $envelope_response->get_headers() ); + $this->assertEmpty( $envelope_response->get_links() ); + + $enveloped = $envelope_response->get_data(); + + $this->assertArrayHasKey( 'body', $enveloped ); + $this->assertArrayHasKey( '_links', $enveloped['body'] ); + $this->assertArrayHasKey( '_embedded', $enveloped['body'] ); + $this->assertArrayHasKey( 'alternate', $enveloped['body']['_embedded'] ); + + $alternate = $enveloped['body']['_embedded']['alternate']; + $this->assertCount( 1, $alternate ); + + $this->assertSame( $status, $enveloped['status'] ); + $this->assertSame( $headers, $enveloped['headers'] ); + } + public function test_default_param() { register_rest_route( @@ -2173,4 +2229,19 @@ class Tests_REST_Server extends WP_Test_REST_TestCase { return rest_get_server()->sent_headers; } + + /** + * Data provider. + * + * @return array + */ + public function data_envelope_params() { + return array( + array( '1' ), + array( 'true' ), + array( false ), + array( 'alternate' ), + array( array( 'alternate' ) ), + ); + } }