From 12784e13d41ac580041a8a16aeaa9deb8e57b74d Mon Sep 17 00:00:00 2001 From: Boone Gorges Date: Mon, 16 Mar 2015 14:23:33 +0000 Subject: [PATCH] Improve method consistency in `WP_Comment_Query`. * Introduce a `__construct()` method, which can accept an array of query vars. * Move query logic out of `query()` method and into a new `get_comments()` method. * Ensure that `$this->comments` is set whenever `get_comments()` returns a value. * Introduce a `parse_query()` method, where query vars are parsed with default values and the 'parse_comment_query' action is fired. These changes bring `WP_Comment_Query` syntax closer to that of `WP_Query`. Props westonruter, morganestes, boonebgorges. Fixes #24826. git-svn-id: https://develop.svn.wordpress.org/trunk@31793 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/comment.php | 176 ++++++++++++++++++-------- tests/phpunit/tests/comment/query.php | 45 +++++++ 2 files changed, 167 insertions(+), 54 deletions(-) diff --git a/src/wp-includes/comment.php b/src/wp-includes/comment.php index ada21ec8dd..82e172b309 100644 --- a/src/wp-includes/comment.php +++ b/src/wp-includes/comment.php @@ -220,7 +220,7 @@ function get_comment(&$comment, $output = OBJECT) { * * @global wpdb $wpdb WordPress database abstraction object. * - * @param string|array $args Optional. Array or string of arguments. See {@see WP_Comment_Query::query()} + * @param string|array $args Optional. Array or string of arguments. See {@see WP_Comment_Query::parse_query()} * for information on accepted arguments. Default empty. * @return int|array List of comments or number of found comments if `$count` argument is true. */ @@ -265,11 +265,28 @@ class WP_Comment_Query { public $date_query = false; /** + * Query vars set by the user. + * + * @since 3.1.0 + * @access public * @var array */ public $query_vars; /** + * Default values for query vars. + * + * @since 4.2.0 + * @access public + * @var array + */ + public $query_var_defaults; + + /** + * List of comments located by the query. + * + * @since 4.0.0 + * @access public * @var array */ public $comments; @@ -292,15 +309,68 @@ class WP_Comment_Query { } /** - * Execute the query + * Constructor. * - * @since 3.1.0 - * @since 4.1.0 Introduced 'comment__in', 'comment__not_in', 'post_author__in', - * 'post_author__not_in', 'author__in', 'author__not_in', 'post__in', - * 'post__not_in', 'include_unapproved', 'type__in', and 'type__not_in' - * arguments to $query_vars. + * Sets up the comment query, based on the query vars passed. * - * @param string|array $query_vars { + * @since 4.2.0 + * @access public + * + * @param string $query URL query string. + * @return WP_Comment_Query + */ + public function __construct( $query = '' ) { + $this->query_var_defaults = array( + 'author_email' => '', + 'author__in' => '', + 'author__not_in' => '', + 'include_unapproved' => '', + 'fields' => '', + 'ID' => '', + 'comment__in' => '', + 'comment__not_in' => '', + 'karma' => '', + 'number' => '', + 'offset' => '', + 'orderby' => '', + 'order' => 'DESC', + 'parent' => '', + 'post_author__in' => '', + 'post_author__not_in' => '', + 'post_ID' => '', + 'post_id' => 0, + 'post__in' => '', + 'post__not_in' => '', + 'post_author' => '', + 'post_name' => '', + 'post_parent' => '', + 'post_status' => '', + 'post_type' => '', + 'status' => 'all', + 'type' => '', + 'type__in' => '', + 'type__not_in' => '', + 'user_id' => '', + 'search' => '', + 'count' => false, + 'meta_key' => '', + 'meta_value' => '', + 'meta_query' => '', + 'date_query' => null, // See WP_Date_Query + ); + + if ( ! empty( $query ) ) { + $this->query( $query ); + } + } + + /** + * Parse arguments passed to the comment query with default query parameters. + * + * @since 4.2.0 Extracted from {@link WP_Comment_Query::query()}. + * @access public + * + * @param string|array $query { * Optional. Array or query string of comment query parameters. * * @type string $author_email Comment author email address. Default empty. @@ -363,53 +433,49 @@ class WP_Comment_Query { * @type array $type__not_in Exclude comments from a given array of comment types. Default empty. * @type int $user_id Include comments for a specific user ID. Default empty. * } - * @return int|array Array of comments or number of found comments if `$count` is set to true. */ - public function query( $query_vars ) { - global $wpdb; + public function parse_query( $query = '' ) { + if ( empty( $query ) ) { + $query = $this->query_vars; + } - $defaults = array( - 'author_email' => '', - 'author__in' => '', - 'author__not_in' => '', - 'include_unapproved' => '', - 'fields' => '', - 'ID' => '', - 'comment__in' => '', - 'comment__not_in' => '', - 'karma' => '', - 'number' => '', - 'offset' => '', - 'orderby' => '', - 'order' => 'DESC', - 'parent' => '', - 'post_author__in' => '', - 'post_author__not_in' => '', - 'post_ID' => '', - 'post_id' => 0, - 'post__in' => '', - 'post__not_in' => '', - 'post_author' => '', - 'post_name' => '', - 'post_parent' => '', - 'post_status' => '', - 'post_type' => '', - 'status' => 'all', - 'type' => '', - 'type__in' => '', - 'type__not_in' => '', - 'user_id' => '', - 'search' => '', - 'count' => false, - 'meta_key' => '', - 'meta_value' => '', - 'meta_query' => '', - 'date_query' => null, // See WP_Date_Query - ); + $this->query_vars = wp_parse_args( $query, $this->query_var_defaults ); + do_action_ref_array( 'parse_comment_query', array( &$this ) ); + } + + /** + * Sets up the WordPress query for retrieving comments. + * + * @since 3.1.0 + * @since 4.1.0 Introduced 'comment__in', 'comment__not_in', 'post_author__in', + * 'post_author__not_in', 'author__in', 'author__not_in', 'post__in', + * 'post__not_in', 'include_unapproved', 'type__in', and 'type__not_in' + * arguments to $query_vars. + * @since 4.2.0 Moved parsing to {@link WP_Comment_Query::parse_query()}. + * @access public + * + * @param string|array $query Array or URL query string of parameters. + * @return array List of comments. + */ + public function query( $query ) { + $this->query_vars = wp_parse_args( $query ); + return $this->get_comments(); + } + + /** + * Get a list of comments matching the query vars. + * + * @since 4.2.0 + * @access public + * + * @return array The list of comments. + */ + public function get_comments() { + global $wpdb; $groupby = ''; - $this->query_vars = wp_parse_args( $query_vars, $defaults ); + $this->parse_query(); // Parse meta query $this->meta_query = new WP_Meta_Query(); @@ -428,8 +494,8 @@ class WP_Comment_Query { */ do_action_ref_array( 'pre_get_comments', array( &$this ) ); - // $args can be whatever, only use the args defined in defaults to compute the key - $key = md5( serialize( wp_array_slice_assoc( $this->query_vars, array_keys( $defaults ) ) ) ); + // $args can include anything. Only use the args defined in the query_var_defaults to compute the key. + $key = md5( serialize( wp_array_slice_assoc( $this->query_vars, array_keys( $this->query_var_defaults ) ) ) ); $last_changed = wp_cache_get( 'last_changed', 'comment' ); if ( ! $last_changed ) { $last_changed = microtime(); @@ -438,7 +504,8 @@ class WP_Comment_Query { $cache_key = "get_comments:$key:$last_changed"; if ( $cache = wp_cache_get( $cache_key, 'comment' ) ) { - return $cache; + $this->comments = $cache; + return $this->comments; } $where = array(); @@ -826,7 +893,8 @@ class WP_Comment_Query { wp_cache_add( $cache_key, $comments, 'comment' ); - return $comments; + $this->comments = $comments; + return $this->comments; } /** diff --git a/tests/phpunit/tests/comment/query.php b/tests/phpunit/tests/comment/query.php index 55e7d730e3..19583105c0 100644 --- a/tests/phpunit/tests/comment/query.php +++ b/tests/phpunit/tests/comment/query.php @@ -1587,4 +1587,49 @@ class Tests_Comment_Query extends WP_UnitTestCase { $this->assertEqualSets( array_merge( $c1, $c3 ), $found ); } + + /** + * @ticket 24826 + */ + public function test_comment_query_object() { + $comment_id = $this->factory->comment->create(); + + $query1 = new WP_Comment_Query(); + $this->assertNull( $query1->query_vars ); + $this->assertEmpty( $query1->comments ); + $comments = $query1->query( array( 'status' => 'all' ) ); + $this->assertInternalType( 'array', $query1->query_vars ); + $this->assertNotEmpty( $query1->comments ); + $this->assertInternalType( 'array', $query1->comments ); + + $query2 = new WP_Comment_Query( array( 'status' => 'all' ) ); + $this->assertNotEmpty( $query2->query_vars ); + $this->assertNotEmpty( $query2->comments ); + $this->assertEquals( $query2->comments, $query1->get_comments() ); + } + + /** + * @ticket 22400 + */ + public function test_comment_cache_key_should_ignore_custom_params() { + global $wpdb; + + $p = $this->factory->post->create(); + $c = $this->factory->comment->create( array( 'comment_post_ID' => $p ) ); + + $q1 = new WP_Comment_Query(); + $q1->query( array( + 'post_id' => $p, + ) ); + + $num_queries = $wpdb->num_queries; + + $q2 = new WP_Comment_Query(); + $q2->query( array( + 'post_id' => $p, + 'foo' => 'bar', + ) ); + + $this->assertSame( $num_queries, $wpdb->num_queries ); + } }