From bd795a3d1637751d5a8f812bc37f5541496be466 Mon Sep 17 00:00:00 2001 From: Boone Gorges Date: Wed, 29 Oct 2014 21:49:08 +0000 Subject: [PATCH] Better flexibility for 'type' in `WP_Comment_Query`. * Add support for an array of values in 'type'. * Introduce `type__in` parameter. This duplicates 'type' but is added for better consistency with other query classes. * Introduce `type__not_in`. Among other things, these changes will make it easier for plugin authors to manage the appearance of custom comment types in various WP interfaces. Props dancameron, mordauk. See #12668. git-svn-id: https://develop.svn.wordpress.org/trunk@30096 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/comment.php | 45 +++- tests/phpunit/tests/comment/query.php | 366 ++++++++++++++++++++++++++ 2 files changed, 405 insertions(+), 6 deletions(-) diff --git a/src/wp-includes/comment.php b/src/wp-includes/comment.php index 76715f5f1f..0906040cba 100644 --- a/src/wp-includes/comment.php +++ b/src/wp-includes/comment.php @@ -304,6 +304,8 @@ class WP_Comment_Query { 'post_type' => '', 'status' => 'all', 'type' => '', + 'type__in' => '', + 'type__not_in' => '', 'user_id' => '', 'search' => '', 'count' => false, @@ -520,12 +522,43 @@ class WP_Comment_Query { $where[] = $wpdb->prepare( 'comment_karma = %d', $this->query_vars['karma'] ); } - if ( 'comment' == $this->query_vars['type'] ) { - $where[] = "comment_type = ''"; - } elseif( 'pings' == $this->query_vars['type'] ) { - $where[] = 'comment_type IN ("pingback", "trackback")'; - } elseif ( ! empty( $this->query_vars['type'] ) ) { - $where[] = $wpdb->prepare( 'comment_type = %s', $this->query_vars['type'] ); + // Filtering by comment_type: 'type', 'type__in', 'type__not_in'. + $raw_types = array( + 'IN' => array_merge( (array) $this->query_vars['type'], (array) $this->query_vars['type__in'] ), + 'NOT IN' => (array) $this->query_vars['type__not_in'], + ); + + $comment_types = array(); + foreach ( $raw_types as $operator => $_raw_types ) { + $_raw_types = array_unique( $_raw_types ); + + foreach ( $_raw_types as $type ) { + switch ( $type ) { + // An empty translates to 'all', for backward compatibility + case '': + case 'all' : + break; + + case 'comment': + case 'comments': + $comment_types[ $operator ][] = "''"; + break; + + case 'pings': + $comment_types[ $operator ][] = "'pingback'"; + $comment_types[ $operator ][] = "'trackback'"; + break; + + default: + $comment_types[ $operator ][] = $wpdb->prepare( '%s', $type ); + break; + } + } + + if ( ! empty( $comment_types[ $operator ] ) ) { + $types_sql = implode( ', ', $comment_types[ $operator ] ); + $where[] = "comment_type $operator ($types_sql)"; + } } if ( '' !== $this->query_vars['parent'] ) { diff --git a/tests/phpunit/tests/comment/query.php b/tests/phpunit/tests/comment/query.php index 84073b1ed9..e6fcc65357 100644 --- a/tests/phpunit/tests/comment/query.php +++ b/tests/phpunit/tests/comment/query.php @@ -15,6 +15,372 @@ class Tests_Comment_Query extends WP_UnitTestCase { $this->post_id = $this->factory->post->create(); } + public function test_query() { + $c1 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => '1' ) ); + $c2 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => '1', 'comment_type' => 'pingback' ) ); + $c3 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => '1', 'comment_type' => 'trackback' ) ); + $c4 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => '1', 'comment_type' => 'mario' ) ); + $c5 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => '1', 'comment_type' => 'luigi' ) ); + + $q = new WP_Comment_Query(); + $found = $q->query( array( + 'fields' => 'ids', + ) ); + + $this->assertEquals( array( $c1, $c2, $c3, $c4, $c5 ), $found ); + } + + /** + * @ticket 12668 + */ + public function test_query_type_empty_string() { + $c1 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => '1' ) ); + $c2 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => '1', 'comment_type' => 'pingback' ) ); + $c3 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => '1', 'comment_type' => 'trackback' ) ); + $c4 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => '1', 'comment_type' => 'mario' ) ); + $c5 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => '1', 'comment_type' => 'luigi' ) ); + + $q = new WP_Comment_Query(); + $found = $q->query( array( + 'type' => '', + 'fields' => 'ids', + ) ); + + $this->assertEquals( array( $c1, $c2, $c3, $c4, $c5 ), $found ); + } + + /** + * @ticket 12668 + */ + public function test_query_type_comment() { + $c1 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => '1' ) ); + $c2 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => '1', 'comment_type' => 'pingback' ) ); + $c3 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => '1', 'comment_type' => 'trackback' ) ); + $c4 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => '1', 'comment_type' => 'mario' ) ); + $c5 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => '1', 'comment_type' => 'luigi' ) ); + + $q = new WP_Comment_Query(); + $found = $q->query( array( + 'type' => 'comment', + 'fields' => 'ids', + ) ); + + $this->assertEquals( array( $c1 ), $found ); + } + + public function test_query_type_pingback() { + $c1 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => '1' ) ); + $c2 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => '1', 'comment_type' => 'pingback' ) ); + $c3 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => '1', 'comment_type' => 'pingback' ) ); + $c4 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => '1', 'comment_type' => 'trackback' ) ); + + $q = new WP_Comment_Query(); + $found = $q->query( array( + 'type' => 'pingback', + 'fields' => 'ids', + ) ); + + $this->assertEquals( array( $c2, $c3 ), $found ); + + } + + public function test_query_type_trackback() { + $c1 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => '1' ) ); + $c2 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => '1', 'comment_type' => 'trackback' ) ); + $c3 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => '1', 'comment_type' => 'trackback' ) ); + $c4 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => '1', 'comment_type' => 'pingback' ) ); + + $q = new WP_Comment_Query(); + $found = $q->query( array( + 'type' => 'trackback', + 'fields' => 'ids', + ) ); + + $this->assertEquals( array( $c2, $c3 ), $found ); + + } + + /** + * 'pings' is an alias for 'trackback' + 'pingback'. + */ + public function test_query_type_pings() { + $c1 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => '1' ) ); + $c2 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => '1', 'comment_type' => 'pingback' ) ); + $c3 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => '1', 'comment_type' => 'trackback' ) ); + $c4 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => '1', 'comment_type' => 'mario' ) ); + $c5 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => '1', 'comment_type' => 'luigi' ) ); + + $q = new WP_Comment_Query(); + $found = $q->query( array( + 'type' => 'pings', + 'fields' => 'ids', + ) ); + + $this->assertEquals( array( $c2, $c3 ), $found ); + } + + /** + * Comments and custom + * @ticket 12668 + */ + public function test_type_array_comments_and_custom() { + $c1 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => '1' ) ); + $c2 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => '1', 'comment_type' => 'pingback' ) ); + $c3 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => '1', 'comment_type' => 'trackback' ) ); + $c4 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => '1', 'comment_type' => 'mario' ) ); + $c5 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => '1', 'comment_type' => 'luigi' ) ); + $c6 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => '1', 'comment_type' => 'mario' ) ); + + $q = new WP_Comment_Query(); + $found = $q->query( array( + 'type' => array( 'comments', 'mario' ), + 'fields' => 'ids', + ) ); + + $this->assertEquals( array( $c1, $c4, $c6 ), $found ); + } + + /** + * @ticket 12668 + */ + public function test_type_not__in_array_custom() { + $c1 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => '1' ) ); + $c2 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => '1', 'comment_type' => 'pingback' ) ); + $c3 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => '1', 'comment_type' => 'trackback' ) ); + $c4 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => '1', 'comment_type' => 'mario' ) ); + $c5 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => '1', 'comment_type' => 'luigi' ) ); + $c6 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => '1', 'comment_type' => 'mario' ) ); + + $q = new WP_Comment_Query(); + $found = $q->query( array( + 'type__not_in' => array( 'luigi' ), + 'fields' => 'ids', + ) ); + + $this->assertEquals( array( $c1, $c2, $c3, $c4, $c6 ), $found ); + } + + /** + * @ticket 12668 + */ + public function test_type__in_array_and_not_type_array_custom() { + $c1 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => '1' ) ); + $c2 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => '1', 'comment_type' => 'pingback' ) ); + $c3 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => '1', 'comment_type' => 'trackback' ) ); + $c4 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => '1', 'comment_type' => 'mario' ) ); + $c5 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => '1', 'comment_type' => 'luigi' ) ); + $c6 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => '1', 'comment_type' => 'mario' ) ); + + $q = new WP_Comment_Query(); + $found = $q->query( array( + 'type__in' => array( 'comments' ), + 'type__not_in' => array( 'luigi' ), + 'fields' => 'ids', + ) ); + + $this->assertEquals( array( $c1 ), $found ); + } + + /** + * @ticket 12668 + */ + public function test_type_array_and_type__not_in_array_custom() { + $c1 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => '1' ) ); + $c2 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => '1', 'comment_type' => 'pingback' ) ); + $c3 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => '1', 'comment_type' => 'trackback' ) ); + $c4 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => '1', 'comment_type' => 'mario' ) ); + $c5 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => '1', 'comment_type' => 'luigi' ) ); + $c6 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => '1', 'comment_type' => 'mario' ) ); + + $q = new WP_Comment_Query(); + $found = $q->query( array( + 'type' => array( 'pings' ), + 'type__not_in' => array( 'mario' ), + 'fields' => 'ids', + ) ); + + $this->assertEquals( array( $c2, $c3 ), $found ); + } + + /** + * @ticket 12668 + */ + public function test_type__not_in_custom() { + $c1 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => '1' ) ); + $c2 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => '1', 'comment_type' => 'pingback' ) ); + $c3 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => '1', 'comment_type' => 'trackback' ) ); + $c4 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => '1', 'comment_type' => 'mario' ) ); + $c5 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => '1', 'comment_type' => 'luigi' ) ); + $c6 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => '1', 'comment_type' => 'mario' ) ); + + $q = new WP_Comment_Query(); + $found = $q->query( array( + 'type__not_in' => 'luigi', + 'fields' => 'ids', + ) ); + + $this->assertEquals( array( $c1, $c2, $c3, $c4, $c6 ), $found ); + } + + /** + * @ticket 12668 + */ + public function test_type_array_comments_and_pings() { + $c1 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => '1' ) ); + $c2 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => '1', 'comment_type' => 'pingback' ) ); + $c3 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => '1', 'comment_type' => 'trackback' ) ); + $c4 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => '1', 'comment_type' => 'mario' ) ); + $c5 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => '1', 'comment_type' => 'luigi' ) ); + + $q = new WP_Comment_Query(); + $found = $q->query( array( + 'type' => array( 'comments', 'pings' ), + 'fields' => 'ids', + ) ); + + $this->assertEquals( array( $c1, $c2, $c3 ), $found ); + } + + /** + * @ticket 12668 + */ + public function test_type_array_comment_pings() { + $c1 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => '1' ) ); + $c2 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => '1', 'comment_type' => 'pingback' ) ); + $c3 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => '1', 'comment_type' => 'trackback' ) ); + + $q = new WP_Comment_Query(); + $found = $q->query( array( + 'type' => array( 'comment', 'pings' ), + 'fields' => 'ids', + ) ); + + $this->assertEquals( array( $c1, $c2, $c3 ), $found ); + } + + /** + * @ticket 12668 + */ + public function test_type_array_pingback() { + $c1 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => '1' ) ); + $c2 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => '1', 'comment_type' => 'pingback' ) ); + $c3 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => '1', 'comment_type' => 'trackback' ) ); + + $q = new WP_Comment_Query(); + $found = $q->query( array( + 'type' => array( 'pingback' ), + 'fields' => 'ids', + ) ); + + $this->assertEquals( array( $c2 ), $found ); + } + + /** + * @ticket 12668 + */ + public function test_type_array_custom_pingpack() { + $c1 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => '1' ) ); + $c2 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => '1', 'comment_type' => 'pingback' ) ); + $c3 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => '1', 'comment_type' => 'trackback' ) ); + + $q = new WP_Comment_Query(); + $found = $q->query( array( + 'type' => array( 'peach', 'pingback' ), + 'fields' => 'ids', + ) ); + + $this->assertEquals( array( $c2 ), $found ); + } + + /** + * @ticket 12668 + */ + public function test_type_array_pings() { + $c1 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => '1' ) ); + $c2 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => '1', 'comment_type' => 'pingback' ) ); + $c3 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => '1', 'comment_type' => 'pingback' ) ); + + $q = new WP_Comment_Query(); + $found = $q->query( array( + 'type' => array( 'pings' ), + 'fields' => 'ids', + ) ); + + $this->assertEquals( array( $c2, $c3 ), $found ); + } + + /** + * @ticket 12668 + */ + public function test_type_status_approved_array_comment_pings() { + $c1 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => '1' ) ); + $c2 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => '1', 'comment_type' => 'pingback' ) ); + $c3 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => '1', 'comment_type' => 'pingback' ) ); + $c4 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => '0', 'comment_type' => 'pingback' ) ); + + $q = new WP_Comment_Query(); + $found = $q->query( array( + 'status' => 'approve', + 'type' => array( 'pings' ), + 'fields' => 'ids', + ) ); + + $this->assertEquals( array( $c3, $c2 ), $found ); + } + + /** + * @ticket 12668 + */ + public function test_type_array_trackback() { + $c1 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => '1' ) ); + $c2 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => '1', 'comment_type' => 'trackback' ) ); + $c3 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => '1', 'comment_type' => 'pingback' ) ); + + $q = new WP_Comment_Query(); + $found = $q->query( array( + 'type' => array( 'trackback' ), + 'fields' => 'ids', + ) ); + + $this->assertEquals( array( $c2 ), $found ); + } + + /** + * @ticket 12668 + */ + public function test_type_array_custom_trackback() { + $c1 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => '1' ) ); + $c2 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => '1', 'comment_type' => 'trackback' ) ); + $c3 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => '1', 'comment_type' => 'pingback' ) ); + + $q = new WP_Comment_Query(); + $found = $q->query( array( + 'type' => array( 'toad', 'trackback' ), + 'fields' => 'ids', + ) ); + + $this->assertEquals( array( $c2 ), $found ); + } + + /** + * @ticket 12668 + */ + public function test_type_array_pings_approved() { + $c1 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => '1' ) ); + $c2 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => '1', 'comment_type' => 'trackback' ) ); + $c3 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => '1', 'comment_type' => 'trackback' ) ); + $c4 = $this->factory->comment->create( array( 'comment_post_ID' => $this->post_id, 'comment_approved' => '0', 'comment_type' => 'trackback' ) ); + + $q = new WP_Comment_Query(); + $found = $q->query( array( + 'status' => 'approve', + 'type' => array( 'pings' ), + 'fields' => 'ids', + ) ); + + $this->assertEquals( array( $c3, $c2 ), $found ); + } + /** * @ticket 29612 */