Ticket #38504: 38504.diff
| File 38504.diff, 5.3 KB (added by , 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 { 189 189 $prepared_args = apply_filters( "rest_{$this->taxonomy}_query", $prepared_args, $request ); 190 190 191 191 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']; 194 196 } else { 195 197 $query_result = get_terms( $this->taxonomy, $prepared_args ); 198 } 196 199 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 ); 200 203 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; 205 207 } 208 206 209 $response = array(); 207 210 foreach ( $query_result as $term ) { 208 211 $data = $this->prepare_item_for_response( $term, $request ); … … class WP_REST_Terms_Controller extends WP_REST_Controller { 238 241 } 239 242 240 243 /** 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 not245 * supported, notably `include`, `exclude`. In `self::get_items()` these246 * 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 default260 * 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 protected294 *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 /**312 244 * Checks if a request has access to read the specified term. 313 245 * 314 246 * @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 { 668 668 $wp_rest_additional_fields = array(); 669 669 } 670 670 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 671 699 public function additional_field_get_callback( $object, $request ) { 672 700 return 123; 673 701 }