WordPress.org

Make WordPress Core

Ticket #39696: 39696.2.diff

File 39696.2.diff, 6.5 KB (added by rheinardkorf, 3 years ago)
  • src/wp-includes/rest-api/class-wp-rest-server.php

    diff --git src/wp-includes/rest-api/class-wp-rest-server.php src/wp-includes/rest-api/class-wp-rest-server.php
    index ec8d2a0..af0810e 100644
    class WP_REST_Server { 
    379379                        }
    380380
    381381                        // Embed links inside the request.
    382                         $result = $this->response_to_data( $result, isset( $_GET['_embed'] ) );
     382                        $result = $this->response_to_data( $result, isset( $_GET['_embed'] ), $request );
    383383
    384384                        $result = wp_json_encode( $result );
    385385
    class WP_REST_Server { 
    407407         * @since 4.4.0
    408408         * @access public
    409409         *
    410          * @param WP_REST_Response $response Response object.
    411          * @param bool             $embed    Whether links should be embedded.
     410         * @param WP_REST_Response        $response Response object.
     411         * @param bool                    $embed    Whether links should be embedded.
     412         * @param bool | WP_REST_Request  $request  The request to respond to. Not always passed.
    412413         * @return array {
    413414         *     Data with sub-requests embedded.
    414415         *
    class WP_REST_Server { 
    416417         *     @type array [$_embedded] Embeddeds.
    417418         * }
    418419         */
    419         public function response_to_data( $response, $embed ) {
     420        public function response_to_data( $response, $embed, $request = false ) {
    420421                $data  = $response->get_data();
    421422                $links = $this->get_compact_response_links( $response );
    422423
    class WP_REST_Server { 
    429430                        if ( wp_is_numeric_array( $data ) ) {
    430431                                $data = array_map( array( $this, 'embed_links' ), $data );
    431432                        } else {
    432                                 $data = $this->embed_links( $data );
     433                                $data = $this->embed_links( $data, $request );
    433434                        }
    434435                }
    435436
    class WP_REST_Server { 
    529530         * @since 4.4.0
    530531         * @access protected
    531532         *
    532          * @param array $data Data from the request.
     533         * @param array                   $data     Data from the request.
     534         * @param bool | WP_REST_Request  $request  The request that contains passed parameters. Not always passed.
    533535         * @return array {
    534536         *     Data with sub-requests embedded.
    535537         *
    class WP_REST_Server { 
    537539         *     @type array [$_embedded] Embeddeds.
    538540         * }
    539541         */
    540         protected function embed_links( $data ) {
     542        protected function embed_links( $data, $request = false ) {
    541543                if ( empty( $data['_links'] ) ) {
    542544                        return $data;
    543545                }
    544546
    545547                $embedded = array();
    546548
     549                // Get link relationships to filter on, but only if not _embed=1 or _embed=true or empty _embed=
     550                $params = false !== $request ? $request->get_query_params() : false;
     551                $filtered_rels = false;
     552                if ( false !== $params && isset( $params['_embed'] ) && '1' !== $params['_embed'] && 'true' !== $params['_embed'] ) {
     553                        $filtered_rels = array_filter( is_array( $params['_embed'] ) ? $params['_embed'] : explode( ',', $params['_embed'] ) );
     554                }
     555
    547556                foreach ( $data['_links'] as $rel => $links ) {
    548557                        // Ignore links to self, for obvious reasons.
    549558                        if ( 'self' === $rel ) {
    550559                                continue;
    551560                        }
    552561
     562                        // If filtered rels are specified and current $rel is not in the list, then continue.
     563                        if ( ! empty( $filtered_rels ) && ! in_array( $rel, $filtered_rels, true ) ) {
     564                                continue;
     565                        }
     566
    553567                        $embeds = array();
    554568
    555569                        foreach ( $links as $item ) {
  • tests/phpunit/tests/rest-api/rest-posts-controller.php

    diff --git tests/phpunit/tests/rest-api/rest-posts-controller.php tests/phpunit/tests/rest-api/rest-posts-controller.php
    index f48709e..2779e5d 100644
    class WP_Test_REST_Posts_Controller extends WP_Test_REST_Post_Type_Controller_Te 
    942942                $this->assertEquals( rest_url( '/wp/v2/users/' . self::$author_id ), $links['author'][0]['href'] );
    943943        }
    944944
     945        public function test_get_item__embed() {
     946
     947                // Prepare a new post. This will be first item when querying /wp/v2/posts
     948                wp_set_current_user( self::$editor_id );
     949                $post_id   = $this->factory->post->create();
     950                $category1 = wp_insert_term( 'Embed Test Category', 'category' );
     951                $category2 = wp_insert_term( 'Second Embed Test Category', 'category' );
     952                wp_set_post_categories( $post_id, array( $category1['term_id'], $category2['term_id'] ) );
     953                $this->factory->comment->create_post_comments( $post_id, 1 );
     954
     955                // ?_embed=1 should return all expected embeds. In this case 'author', 'replies' and 'wp:term'.
     956                $request  = new WP_REST_Request( 'GET', '/wp/v2/posts' );
     957                $request->set_param( '_embed', '1' );
     958                $response = $this->server->dispatch( $request );
     959                $data     = $response->get_data();
     960                $data     = array_shift( $data );
     961                $embeds   = $this->server->embed_links( $data, $request );
     962
     963                $this->assertArrayHasKey( 'author', $embeds['_embedded'] );
     964                $this->assertArrayHasKey( 'replies', $embeds['_embedded'] );
     965                $this->assertArrayHasKey( 'wp:term', $embeds['_embedded'] );
     966
     967                // ?_embed=true should return all expected embeds. In this case 'author', 'replies' and 'wp:term'.
     968                $request  = new WP_REST_Request( 'GET', '/wp/v2/posts' );
     969                $request->set_param( '_embed', 'true' );
     970                $response = $this->server->dispatch( $request );
     971                $data     = $response->get_data();
     972                $data     = array_shift( $data );
     973                $embeds   = $this->server->embed_links( $data, $request );
     974
     975                $this->assertArrayHasKey( 'author', $embeds['_embedded'] );
     976                $this->assertArrayHasKey( 'replies', $embeds['_embedded'] );
     977                $this->assertArrayHasKey( 'wp:term', $embeds['_embedded'] );
     978
     979                // ?_embed=author,wp:term should return only relevant embeds.
     980                $request  = new WP_REST_Request( 'GET', '/wp/v2/posts' );
     981                $request->set_param( '_embed', 'author,wp:term' );
     982                $response = $this->server->dispatch( $request );
     983                $data     = $response->get_data();
     984                $data     = array_shift( $data );
     985                $embeds   = $this->server->embed_links( $data, $request );
     986
     987                $this->assertArrayHasKey( 'author', $embeds['_embedded'] );
     988                $this->assertArrayNotHasKey( 'replies', $embeds['_embedded'] );
     989                $this->assertArrayHasKey( 'wp:term', $embeds['_embedded'] );
     990
     991                // ?_embed[]=author&_embed[]=replies should return only relevant embeds.
     992                $request  = new WP_REST_Request( 'GET', '/wp/v2/posts' );
     993                $response = $this->server->dispatch( $request );
     994                $request->set_param( '_embed', array( 'author', 'replies' ) );
     995                $data     = $response->get_data();
     996                $data     = array_shift( $data );
     997                $embeds   = $this->server->embed_links( $data, $request );
     998
     999                $this->assertArrayHasKey( 'author', $embeds['_embedded'] );
     1000                $this->assertArrayHasKey( 'replies', $embeds['_embedded'] );
     1001                $this->assertArrayNotHasKey( 'wp:term', $embeds['_embedded'] );
     1002        }
     1003
    9451004        public function test_get_post_without_permission() {
    9461005                $draft_id = $this->factory->post->create( array(
    9471006                        'post_status' => 'draft',