WordPress.org

Make WordPress Core

Ticket #39696: 39696.3.diff

File 39696.3.diff, 6.6 KB (added by rheinardkorf, 4 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 4f5ae76..e312b50 100644
    class WP_REST_Server { 
    381381                        }
    382382
    383383                        // Embed links inside the request.
    384                         $result = $this->response_to_data( $result, isset( $_GET['_embed'] ) );
     384                        $result = $this->response_to_data( $result, isset( $_GET['_embed'] ), $request );
    385385
    386386                        $result = wp_json_encode( $result );
    387387
    class WP_REST_Server { 
    409409         * @since 4.4.0
    410410         * @access public
    411411         *
    412          * @param WP_REST_Response $response Response object.
    413          * @param bool             $embed    Whether links should be embedded.
     412         * @param WP_REST_Response        $response Response object.
     413         * @param bool                    $embed    Whether links should be embedded.
     414         * @param bool | WP_REST_Request  $request  The request to respond to. Not always passed.
    414415         * @return array {
    415416         *     Data with sub-requests embedded.
    416417         *
    class WP_REST_Server { 
    418419         *     @type array [$_embedded] Embeddeds.
    419420         * }
    420421         */
    421         public function response_to_data( $response, $embed ) {
     422        public function response_to_data( $response, $embed, $request = false ) {
    422423                $data  = $response->get_data();
    423424                $links = $this->get_compact_response_links( $response );
    424425
    class WP_REST_Server { 
    429430                if ( $embed ) {
    430431                        // Determine if this is a numeric array.
    431432                        if ( wp_is_numeric_array( $data ) ) {
    432                                 $data = array_map( array( $this, 'embed_links' ), $data );
     433                                foreach ( $data as $key => $link ) {
     434                                        $data[ $key ] = $this->embed_links( $data, $request );
     435                                }
    433436                        } else {
    434                                 $data = $this->embed_links( $data );
     437                                $data = $this->embed_links( $data, $request );
    435438                        }
    436439                }
    437440
    class WP_REST_Server { 
    531534         * @since 4.4.0
    532535         * @access protected
    533536         *
    534          * @param array $data Data from the request.
     537         * @param array                   $data     Data from the request.
     538         * @param bool | WP_REST_Request  $request  The request that contains passed parameters. Not always passed.
    535539         * @return array {
    536540         *     Data with sub-requests embedded.
    537541         *
    class WP_REST_Server { 
    539543         *     @type array [$_embedded] Embeddeds.
    540544         * }
    541545         */
    542         protected function embed_links( $data ) {
     546        protected function embed_links( $data, $request = false ) {
    543547                if ( empty( $data['_links'] ) ) {
    544548                        return $data;
    545549                }
    546550
    547551                $embedded = array();
    548552
     553                // Get link relationships to filter on, but only if not _embed=1 or _embed=true or empty _embed=
     554                $filters = ( empty( $request ) ? false : $request->get_param( '_embed' ) );
     555                $filtered_rels = false;
     556                if ( ! empty( $filters ) && '1' !== $filters && 'true' !== $filters ) {
     557                        $filtered_rels = array_filter( is_array( $filters ) ? $filters : explode( ',', $filters ) );
     558                }
     559
    549560                foreach ( $data['_links'] as $rel => $links ) {
    550561                        // Ignore links to self, for obvious reasons.
    551562                        if ( 'self' === $rel ) {
    552563                                continue;
    553564                        }
    554565
     566                        // If filtered rels are specified and current $rel is not in the list, then continue.
     567                        if ( ! empty( $filtered_rels ) && ! in_array( $rel, $filtered_rels, true ) ) {
     568                                continue;
     569                        }
     570
    555571                        $embeds = array();
    556572
    557573                        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 ca16356..663b4fa 100644
    class WP_Test_REST_Posts_Controller extends WP_Test_REST_Post_Type_Controller_Te 
    994994                $this->assertEquals( rest_url( '/wp/v2/users/' . self::$author_id ), $links['author'][0]['href'] );
    995995        }
    996996
     997        public function test_get_item__embed() {
     998
     999                // Prepare a new post. This will be first item when querying /wp/v2/posts
     1000                wp_set_current_user( self::$editor_id );
     1001                $post_id   = $this->factory->post->create();
     1002                $category1 = wp_insert_term( 'Embed Test Category', 'category' );
     1003                $category2 = wp_insert_term( 'Second Embed Test Category', 'category' );
     1004                wp_set_post_categories( $post_id, array( $category1['term_id'], $category2['term_id'] ) );
     1005                $this->factory->comment->create_post_comments( $post_id, 1 );
     1006
     1007                // ?_embed=1 should return all expected embeds. In this case 'author', 'replies' and 'wp:term'.
     1008                $request  = new WP_REST_Request( 'GET', '/wp/v2/posts' );
     1009                $request->set_param( '_embed', '1' );
     1010                $response = $this->server->dispatch( $request );
     1011                $data     = $response->get_data();
     1012                $data     = array_shift( $data );
     1013                $embeds   = $this->server->embed_links( $data, $request );
     1014
     1015                $this->assertArrayHasKey( 'author', $embeds['_embedded'] );
     1016                $this->assertArrayHasKey( 'replies', $embeds['_embedded'] );
     1017                $this->assertArrayHasKey( 'wp:term', $embeds['_embedded'] );
     1018
     1019                // ?_embed=true should return all expected embeds. In this case 'author', 'replies' and 'wp:term'.
     1020                $request  = new WP_REST_Request( 'GET', '/wp/v2/posts' );
     1021                $request->set_param( '_embed', 'true' );
     1022                $response = $this->server->dispatch( $request );
     1023                $data     = $response->get_data();
     1024                $data     = array_shift( $data );
     1025                $embeds   = $this->server->embed_links( $data, $request );
     1026
     1027                $this->assertArrayHasKey( 'author', $embeds['_embedded'] );
     1028                $this->assertArrayHasKey( 'replies', $embeds['_embedded'] );
     1029                $this->assertArrayHasKey( 'wp:term', $embeds['_embedded'] );
     1030
     1031                // ?_embed=author,wp:term should return only relevant embeds.
     1032                $request  = new WP_REST_Request( 'GET', '/wp/v2/posts' );
     1033                $request->set_param( '_embed', 'author,wp:term' );
     1034                $response = $this->server->dispatch( $request );
     1035                $data     = $response->get_data();
     1036                $data     = array_shift( $data );
     1037                $embeds   = $this->server->embed_links( $data, $request );
     1038
     1039                $this->assertArrayHasKey( 'author', $embeds['_embedded'] );
     1040                $this->assertArrayNotHasKey( 'replies', $embeds['_embedded'] );
     1041                $this->assertArrayHasKey( 'wp:term', $embeds['_embedded'] );
     1042
     1043                // ?_embed[]=author&_embed[]=replies should return only relevant embeds.
     1044                $request  = new WP_REST_Request( 'GET', '/wp/v2/posts' );
     1045                $response = $this->server->dispatch( $request );
     1046                $request->set_param( '_embed', array( 'author', 'replies' ) );
     1047                $data     = $response->get_data();
     1048                $data     = array_shift( $data );
     1049                $embeds   = $this->server->embed_links( $data, $request );
     1050
     1051                $this->assertArrayHasKey( 'author', $embeds['_embedded'] );
     1052                $this->assertArrayHasKey( 'replies', $embeds['_embedded'] );
     1053                $this->assertArrayNotHasKey( 'wp:term', $embeds['_embedded'] );
     1054        }
     1055
    9971056        public function test_get_post_without_permission() {
    9981057                $draft_id = $this->factory->post->create( array(
    9991058                        'post_status' => 'draft',