Make WordPress Core

Ticket #38504: 38504.diff

File 38504.diff, 5.3 KB (added by boonebgorges, 10 years ago)
  • src/wp-includes/rest-api/endpoints/class-wp-rest-terms-controller.php

    diff --git src/wp-includes/rest-api/endpoints/class-wp-rest-terms-controller.php src/wp-includes/rest-api/endpoints/class-wp-rest-terms-controller.php
    index cf131ad..8a066f0 100644
    class WP_REST_Terms_Controller extends WP_REST_Controller { 
    189189                $prepared_args = apply_filters( "rest_{$this->taxonomy}_query", $prepared_args, $request );
    190190
    191191                if ( ! empty( $prepared_args['post'] )  ) {
    192                         $query_result = $this->get_terms_for_post( $prepared_args );
    193                         $total_terms = $this->total_terms;
     192                        $query_result = wp_get_object_terms( $prepared_args['post'], $this->taxonomy, $prepared_args );
     193
     194                        // Used when calling wp_count_terms() below.
     195                        $prepared_args['object_ids'] = $prepared_args['post'];
    194196                } else {
    195197                        $query_result = get_terms( $this->taxonomy, $prepared_args );
     198                }
    196199
    197                         $count_args = $prepared_args;
    198                         unset( $count_args['number'], $count_args['offset'] );
    199                         $total_terms = wp_count_terms( $this->taxonomy, $count_args );
     200                $count_args = $prepared_args;
     201                unset( $count_args['number'], $count_args['offset'] );
     202                $total_terms = wp_count_terms( $this->taxonomy, $count_args );
    200203
    201                         // wp_count_terms can return a falsy value when the term has no children
    202                         if ( ! $total_terms ) {
    203                                 $total_terms = 0;
    204                         }
     204                // wp_count_terms can return a falsy value when the term has no children
     205                if ( ! $total_terms ) {
     206                        $total_terms = 0;
    205207                }
     208
    206209                $response = array();
    207210                foreach ( $query_result as $term ) {
    208211                        $data = $this->prepare_item_for_response( $term, $request );
    class WP_REST_Terms_Controller extends WP_REST_Controller { 
    238241        }
    239242
    240243        /**
    241          * Gets the terms attached to a post.
    242          *
    243          * This is an alternative to get_terms() that uses get_the_terms()
    244          * instead, which hits the object cache. There are a few things not
    245          * supported, notably `include`, `exclude`. In `self::get_items()` these
    246          * are instead treated as a full query.
    247          *
    248          * @param array $prepared_args Arguments for get_terms().
    249          * @return array List of term objects. (Total count in `$this->total_terms`)
    250          */
    251         protected function get_terms_for_post( $prepared_args ) {
    252                 $query_result = get_the_terms( $prepared_args['post'], $this->taxonomy );
    253                 if ( empty( $query_result ) ) {
    254                         $this->total_terms = 0;
    255                         return array();
    256                 }
    257 
    258                 /*
    259                  * get_items() verifies that we don't have `include` set, and default
    260                  * ordering is by `name`.
    261                  */
    262                 if ( ! in_array( $prepared_args['orderby'], array( 'name', 'none', 'include' ), true ) ) {
    263                         switch ( $prepared_args['orderby'] ) {
    264                                 case 'id':
    265                                         $this->sort_column = 'term_id';
    266                                         break;
    267 
    268                                 case 'slug':
    269                                 case 'term_group':
    270                                 case 'description':
    271                                 case 'count':
    272                                         $this->sort_column = $prepared_args['orderby'];
    273                                         break;
    274                         }
    275                         usort( $query_result, array( $this, 'compare_terms' ) );
    276                 }
    277                 if ( strtolower( $prepared_args['order'] ) !== 'asc' ) {
    278                         $query_result = array_reverse( $query_result );
    279                 }
    280 
    281                 // Pagination.
    282                 $this->total_terms = count( $query_result );
    283                 $query_result = array_slice( $query_result, $prepared_args['offset'], $prepared_args['number'] );
    284 
    285                 return $query_result;
    286         }
    287 
    288         /**
    289          * Comparison function for sorting terms by a column.
    290          *
    291          * Uses `$this->sort_column` to determine field to sort by.
    292          *
    293          * @access protected
    294          *
    295          * @param stdClass $left Term object.
    296          * @param stdClass $right Term object.
    297          * @return int <0 if left is higher "priority" than right, 0 if equal, >0 if right is higher "priority" than left.
    298          */
    299         protected function compare_terms( $left, $right ) {
    300                 $col = $this->sort_column;
    301                 $left_val = $left->$col;
    302                 $right_val = $right->$col;
    303 
    304                 if ( is_int( $left_val ) && is_int( $right_val ) ) {
    305                         return $left_val - $right_val;
    306                 }
    307 
    308                 return strcmp( $left_val, $right_val );
    309         }
    310 
    311         /**
    312244         * Checks if a request has access to read the specified term.
    313245         *
    314246         * @param  WP_REST_Request $request Full details about the request.
  • tests/phpunit/tests/rest-api/rest-tags-controller.php

    diff --git tests/phpunit/tests/rest-api/rest-tags-controller.php tests/phpunit/tests/rest-api/rest-tags-controller.php
    index d7dcf22..5890663 100644
    class WP_Test_REST_Tags_Controller extends WP_Test_REST_Controller_Testcase { 
    668668                $wp_rest_additional_fields = array();
    669669        }
    670670
     671        /**
     672         * @ticket 38504
     673         */
     674        public function test_object_term_queries_are_cached() {
     675                global $wpdb;
     676
     677                $tags = $this->factory->tag->create_many( 2 );
     678                $p = $this->factory->post->create();
     679                wp_set_object_terms( $p, $tags[0], 'post_tag' );
     680
     681                $request = new WP_REST_Request( 'GET', '/wp/v2/tags' );
     682                $request->set_param( 'post', $p );
     683                $response = $this->server->dispatch( $request );
     684                $found_1 = wp_list_pluck( $response->data, 'id' );
     685
     686                unset( $request, $response );
     687
     688                $num_queries = $wpdb->num_queries;
     689
     690                $request = new WP_REST_Request( 'GET', '/wp/v2/tags' );
     691                $request->set_param( 'post', $p );
     692                $response = $this->server->dispatch( $request );
     693                $found_2 = wp_list_pluck( $response->data, 'id' );
     694
     695                $this->assertEqualSets( $found_1, $found_2 );
     696                $this->assertSame( $num_queries, $wpdb->num_queries );
     697        }
     698
    671699        public function additional_field_get_callback( $object, $request ) {
    672700                return 123;
    673701        }