Ticket #45800: 45800.diff
File 45800.diff, 6.8 KB (added by , 6 years ago) |
---|
-
src/wp-includes/class-wp-comment-query.php
379 379 $this->meta_query_clauses = $this->meta_query->get_sql( 'comment', $wpdb->comments, 'comment_ID', $this ); 380 380 } 381 381 382 /* 383 * Only use the args defined in the query_var_defaults to compute the key, 384 * but ignore 'fields', which does not affect query results. 382 /** 383 * Filters the comments array before the query takes place. 384 * 385 * Return a non-null value to bypass WordPress's default comment queries. 386 * 387 * @since x.x.x 388 * 389 * @param array|int|null $results Return null to allow WP to run its normal queries. 390 * Otherwise, return an array of comment data, 391 * an array of int if `fields=ids` or 392 * an int if `count=true` to short-circuit WP's comment query. 393 * @param WP_Comment_Query $this The WP_Comment_Query instance (passed by reference). 385 394 */ 386 $_args = wp_array_slice_assoc( $this->query_vars, array_keys( $this->query_var_defaults ) ); 387 unset( $_args['fields'] ); 395 $this->comments = apply_filters_ref_array( 'comments_pre_query', array( null, &$this ) ); 388 396 389 $key = md5( serialize( $_args ) ); 390 $last_changed = wp_cache_get_last_changed( 'comment' ); 397 $comment_ids = array(); 391 398 392 $cache_key = "get_comments:$key:$last_changed"; 393 $cache_value = wp_cache_get( $cache_key, 'comment' ); 394 if ( false === $cache_value ) { 395 $comment_ids = $this->get_comment_ids(); 396 if ( $comment_ids ) { 397 $this->set_found_comments(); 399 if ( null === $this->comments ) { 400 // $args can include anything. Only use the args defined in the query_var_defaults to compute the key. 401 $_args = wp_array_slice_assoc( $this->query_vars, array_keys( $this->query_var_defaults ) ); 402 403 // Ignore the $fields argument as the queried result will be the same regardless. 404 unset( $_args['fields'] ); 405 406 $key = md5( serialize( $_args ) ); 407 $last_changed = wp_cache_get_last_changed( 'comment' ); 408 409 $cache_key = "get_comments:$key:$last_changed"; 410 $cache_value = wp_cache_get( $cache_key, 'comment' ); 411 if ( false === $cache_value ) { 412 $comment_ids = $this->get_comment_ids(); 413 if ( $comment_ids ) { 414 $this->set_found_comments(); 415 } 416 417 $cache_value = array( 418 'comment_ids' => $comment_ids, 419 'found_comments' => $this->found_comments, 420 ); 421 wp_cache_add( $cache_key, $cache_value, 'comment' ); 422 } else { 423 $comment_ids = $cache_value['comment_ids']; 424 $this->found_comments = $cache_value['found_comments']; 398 425 } 399 400 $cache_value = array(401 'comment_ids' => $comment_ids,402 'found_comments' => $this->found_comments,403 );404 wp_cache_add( $cache_key, $cache_value, 'comment' );405 } else {406 $comment_ids = $cache_value['comment_ids'];407 $this->found_comments = $cache_value['found_comments'];408 426 } 409 427 410 428 if ( $this->found_comments && $this->query_vars['number'] ) { … … 413 431 414 432 // If querying for a count only, there's nothing more to do. 415 433 if ( $this->query_vars['count'] ) { 416 // $comment_ids is actually a count in this case. 417 return intval( $comment_ids ); 434 if ( null === $this->comments ) { 435 // $comment_ids is actually a count in this case. 436 return intval( $comment_ids ); 437 } 438 // The comments_pre_query callback should be smart enough to test it and return the right result. 439 return intval( $this->comments ); 418 440 } 419 441 420 442 $comment_ids = array_map( 'intval', $comment_ids ); 421 443 422 444 if ( 'ids' == $this->query_vars['fields'] ) { 423 $this->comments = $comment_ids; 445 if ( null === $this->comments ) { 446 $this->comments = $comment_ids; 447 } 424 448 return $this->comments; 425 449 } 426 450 427 _prime_comment_caches( $comment_ids, $this->query_vars['update_comment_meta_cache'] ); 451 if ( null === $this->comments ) { 452 _prime_comment_caches( $comment_ids, $this->query_vars['update_comment_meta_cache'] ); 428 453 429 // Fetch full comment objects from the primed cache. 430 $_comments = array(); 431 foreach ( $comment_ids as $comment_id ) { 432 if ( $_comment = get_comment( $comment_id ) ) { 433 $_comments[] = $_comment; 454 // Fetch full comment objects from the primed cache. 455 $_comments = array(); 456 foreach ( $comment_ids as $comment_id ) { 457 if ( $_comment = get_comment( $comment_id ) ) { 458 $_comments[] = $_comment; 459 } 434 460 } 435 }436 461 437 // Prime comment post caches. 438 if ( $this->query_vars['update_comment_post_cache'] ) { 439 $comment_post_ids = array(); 440 foreach ( $_comments as $_comment ) { 441 $comment_post_ids[] = $_comment->comment_post_ID; 462 // Prime comment post caches. 463 if ( $this->query_vars['update_comment_post_cache'] ) { 464 $comment_post_ids = array(); 465 foreach ( $_comments as $_comment ) { 466 $comment_post_ids[] = $_comment->comment_post_ID; 467 } 468 469 _prime_post_caches( $comment_post_ids, false, false ); 442 470 } 443 444 _prime_post_caches( $comment_post_ids, false, false );471 } else { 472 $_comments = $this->comments; 445 473 } 446 474 447 475 /** … … 457 485 // Convert to WP_Comment instances 458 486 $comments = array_map( 'get_comment', $_comments ); 459 487 460 if ( $this->query_vars['hierarchical'] ) { 461 $comments = $this->fill_descendants( $comments ); 488 if ( null === $this->comments ) { 489 if ( $this->query_vars['hierarchical'] ) { 490 $comments = $this->fill_descendants( $comments ); 491 } 462 492 } 463 493 464 494 $this->comments = $comments; -
tests/phpunit/tests/comment/query.php
4882 4882 4883 4883 $this->assertEqualSets( $c1, $found ); 4884 4884 } 4885 4886 /** 4887 * @ticket 45800 4888 */ 4889 public function test_comments_pre_query_filter_should_bypass_database_query() { 4890 global $wpdb; 4891 4892 add_filter( 'comments_pre_query', array( __CLASS__, 'filter_comments_pre_query' ), 10, 2 ); 4893 4894 $num_queries = $wpdb->num_queries; 4895 $q = new WP_Comment_Query( 4896 array( 4897 'fields' => 'ids', 4898 ) 4899 ); 4900 4901 remove_filter( 'comments_pre_query', array( __CLASS__, 'filter_comments_pre_query' ), 10, 2 ); 4902 4903 // Make sure no queries were executed. 4904 $this->assertSame( $num_queries, $wpdb->num_queries ); 4905 4906 // We manually inserted a non-existing comment ID and overrode the results with it. 4907 $this->assertSame( array( 555 ), $q->comments ); 4908 4909 // Make sure manually setting found_comments doesn't get overwritten. 4910 $this->assertEquals( 1, $q->found_comments ); 4911 } 4912 4913 public static function filter_comments_pre_query( $comments, $query ) { 4914 $query->found_comments = 1; 4915 4916 return array( 555 ); 4917 } 4885 4918 }