From 57b1d5ab28ee616a49f92623c4a45a9aad6d5bdc Mon Sep 17 00:00:00 2001 From: Scott Taylor Date: Wed, 4 Sep 2013 21:32:11 +0000 Subject: [PATCH] Introduce `author__in` and `author__not_in` query vars. Fixes issue with multiple author exclusion when comma-separated string is passed for `author`. Adds a bunch of missing unit tests. Props pollett for initial patch. Fixes #16854. git-svn-id: https://develop.svn.wordpress.org/trunk@25248 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/query.php | 45 ++++++------ tests/phpunit/tests/query/results.php | 98 +++++++++++++++++++++++++++ 2 files changed, 120 insertions(+), 23 deletions(-) diff --git a/src/wp-includes/query.php b/src/wp-includes/query.php index 7dfaae037e..b19b3441e8 100644 --- a/src/wp-includes/query.php +++ b/src/wp-includes/query.php @@ -1396,6 +1396,7 @@ class WP_Query { , 'tag' , 'cat' , 'tag_id' + , 'author' , 'author_name' , 'feed' , 'tb' @@ -1416,7 +1417,8 @@ class WP_Query { } $array_keys = array( 'category__in', 'category__not_in', 'category__and', 'post__in', 'post__not_in', - 'tag__in', 'tag__not_in', 'tag__and', 'tag_slug__in', 'tag_slug__and', 'post_parent__in', 'post_parent__not_in' ); + 'tag__in', 'tag__not_in', 'tag__and', 'tag_slug__in', 'tag_slug__and', 'post_parent__in', 'post_parent__not_in', + 'author__in', 'author__not_in' ); foreach ( $array_keys as $key ) { if ( !isset($array[$key]) ) @@ -1457,6 +1459,7 @@ class WP_Query { $qv['m'] = preg_replace( '|[^0-9]|', '', $qv['m'] ); $qv['paged'] = absint($qv['paged']); $qv['cat'] = preg_replace( '|[^0-9,-]|', '', $qv['cat'] ); // comma separated list of positive or negative integers + $qv['author'] = preg_replace( '|[^0-9,-]|', '', $qv['author'] ); // comma separated list of positive or negative integers $qv['pagename'] = trim( $qv['pagename'] ); $qv['name'] = trim( $qv['name'] ); if ( '' !== $qv['hour'] ) $qv['hour'] = absint($qv['hour']); @@ -1769,9 +1772,9 @@ class WP_Query { $q['category__in'][] = absint( reset( $q['category__and'] ) ); unset( $q['category__and'] ); } - + if ( ! empty( $q['category__in'] ) ) { - $q['category__in'] = array_map( 'absint', array_unique( (array) $q['category__in'] ) ); + $q['category__in'] = array_map( 'absint', array_unique( (array) $q['category__in'] ) ); $tax_query[] = array( 'taxonomy' => 'category', 'terms' => $q['category__in'], @@ -2333,26 +2336,22 @@ class WP_Query { // Author/user stuff - if ( empty($q['author']) || ($q['author'] == '0') ) { - $whichauthor = ''; - } else { - $q['author'] = (string)urldecode($q['author']); - $q['author'] = addslashes_gpc($q['author']); - if ( strpos($q['author'], '-') !== false ) { - $eq = '!='; - $andor = 'AND'; - $q['author'] = explode('-', $q['author']); - $q['author'] = (string)absint($q['author'][1]); - } else { - $eq = '='; - $andor = 'OR'; + if ( ! empty( $q['author'] ) && $q['author'] != '0' ) { + $q['author'] = addslashes_gpc( '' . urldecode( $q['author'] ) ); + $authors = array_unique( array_map( 'intval', preg_split( '/[,\s]+/', $q['author'] ) ) ); + foreach ( $authors as $author ) { + $key = $author > 0 ? 'author__in' : 'author__not_in'; + $q[$key][] = abs( $author ); } - $author_array = preg_split('/[,\s]+/', $q['author']); - $_author_array = array(); - foreach ( $author_array as $key => $_author ) - $_author_array[] = "$wpdb->posts.post_author " . $eq . ' ' . absint($_author); - $whichauthor .= ' AND (' . implode(" $andor ", $_author_array) . ')'; - unset($author_array, $_author_array); + $q['author'] = implode( ',', $authors ); + } + + if ( ! empty( $q['author__not_in'] ) ) { + $author__not_in = implode( ',', array_map( 'absint', array_unique( (array) $q['author__not_in'] ) ) ); + $where .= " AND {$wpdb->posts}.post_author NOT IN ($author__not_in) "; + } elseif ( ! empty( $q['author__in'] ) ) { + $author__in = implode( ',', array_map( 'absint', array_unique( (array) $q['author__in'] ) ) ); + $where .= " AND {$wpdb->posts}.post_author IN ($author__in) "; } // Author stuff for nice URLs @@ -2457,7 +2456,7 @@ class WP_Query { $in_search_post_types = get_post_types( array('exclude_from_search' => false) ); if ( empty( $in_search_post_types ) ) $where .= ' AND 1=0 '; - else + else $where .= " AND $wpdb->posts.post_type IN ('" . join("', '", $in_search_post_types ) . "')"; } elseif ( !empty( $post_type ) && is_array( $post_type ) ) { $where .= " AND $wpdb->posts.post_type IN ('" . join("', '", $post_type) . "')"; diff --git a/tests/phpunit/tests/query/results.php b/tests/phpunit/tests/query/results.php index 4486209466..9b0978edc9 100644 --- a/tests/phpunit/tests/query/results.php +++ b/tests/phpunit/tests/query/results.php @@ -388,4 +388,102 @@ class Tests_Query_Results extends WP_UnitTestCase { $this->assertNotEmpty( $posts2 ); $this->assertNotRegExp( '#AND 1=0#', $this->q->request ); } + + function test_query_author_vars() { + $author_1 = $this->factory->user->create( array( 'user_login' => 'admin1', 'user_pass' => rand_str(), 'role' => 'author' ) ); + $post_1 = $this->factory->post->create( array( 'post_title' => rand_str(), 'post_author' => $author_1, 'post_date' => '2007-01-01 00:00:00' ) ); + + $author_2 = $this->factory->user->create( array( 'user_login' => rand_str(), 'user_pass' => rand_str(), 'role' => 'author' ) ); + $post_2 = $this->factory->post->create( array( 'post_title' => rand_str(), 'post_author' => $author_2, 'post_date' => '2007-01-01 00:00:00' ) ); + + $author_3 = $this->factory->user->create( array( 'user_login' => rand_str(), 'user_pass' => rand_str(), 'role' => 'author' ) ); + $post_3 = $this->factory->post->create( array( 'post_title' => rand_str(), 'post_author' => $author_3, 'post_date' => '2007-01-01 00:00:00' ) ); + + $author_4 = $this->factory->user->create( array( 'user_login' => rand_str(), 'user_pass' => rand_str(), 'role' => 'author' ) ); + $post_4 = $this->factory->post->create( array( 'post_title' => rand_str(), 'post_author' => $author_4, 'post_date' => '2007-01-01 00:00:00' ) ); + + $posts = $this->q->query( array( + 'author' => '', + 'post__in' => array( $post_1, $post_2, $post_3, $post_4 ) + ) ); + $author_ids = array_unique( wp_list_pluck( $posts, 'post_author' ) ); + $this->assertEqualSets( array( $author_1, $author_2, $author_3, $author_4 ), $author_ids ); + + $posts = $this->q->query( array( + 'author' => 0, + 'post__in' => array( $post_1, $post_2, $post_3, $post_4 ) + ) ); + $author_ids = array_unique( wp_list_pluck( $posts, 'post_author' ) ); + $this->assertEqualSets( array( $author_1, $author_2, $author_3, $author_4 ), $author_ids ); + + $posts = $this->q->query( array( + 'author' => '0', + 'post__in' => array( $post_1, $post_2, $post_3, $post_4 ) + ) ); + $author_ids = array_unique( wp_list_pluck( $posts, 'post_author' ) ); + $this->assertEqualSets( array( $author_1, $author_2, $author_3, $author_4 ), $author_ids ); + + $posts = $this->q->query( array( + 'author' => $author_1, + 'post__in' => array( $post_1, $post_2, $post_3, $post_4 ) + ) ); + $author_ids = array_unique( wp_list_pluck( $posts, 'post_author' ) ); + $this->assertEqualSets( array( $author_1 ), $author_ids ); + + $posts = $this->q->query( array( + 'author' => "$author_1", + 'post__in' => array( $post_1, $post_2, $post_3, $post_4 ) + ) ); + $author_ids = array_unique( wp_list_pluck( $posts, 'post_author' ) ); + $this->assertEqualSets( array( $author_1 ), $author_ids ); + + $posts = $this->q->query( array( + 'author' => "{$author_1},{$author_2}", + 'post__in' => array( $post_1, $post_2, $post_3, $post_4 ) + ) ); + $author_ids = array_unique( wp_list_pluck( $posts, 'post_author' ) ); + $this->assertEqualSets( array( $author_1, $author_2 ), $author_ids ); + + $posts = $this->q->query( array( + 'author' => "-{$author_1},{$author_2}", + 'post__in' => array( $post_1, $post_2, $post_3, $post_4 ) + ) ); + $author_ids = array_unique( wp_list_pluck( $posts, 'post_author' ) ); + $this->assertEqualSets( array( $author_2, $author_3, $author_4 ), $author_ids ); + + $posts = $this->q->query( array( + 'author' => "{$author_1},-{$author_2}", + 'post__in' => array( $post_1, $post_2, $post_3, $post_4 ) + ) ); + $author_ids = array_unique( wp_list_pluck( $posts, 'post_author' ) ); + $this->assertEqualSets( array( $author_1, $author_3, $author_4 ), $author_ids ); + + $posts = $this->q->query( array( + 'author' => "-{$author_1},-{$author_2}", + 'post__in' => array( $post_1, $post_2, $post_3, $post_4 ) + ) ); + $author_ids = array_unique( wp_list_pluck( $posts, 'post_author' ) ); + $this->assertEqualSets( array( $author_3, $author_4 ), $author_ids ); + + $posts = $this->q->query( array( + 'author__in' => array( $author_1, $author_2 ), + 'post__in' => array( $post_1, $post_2, $post_3, $post_4 ) + ) ); + $author_ids = array_unique( wp_list_pluck( $posts, 'post_author' ) ); + $this->assertEqualSets( array( $author_1, $author_2 ), $author_ids ); + + $posts = $this->q->query( array( + 'author__not_in' => array( $author_1, $author_2 ), + 'post__in' => array( $post_1, $post_2, $post_3, $post_4 ) + ) ); + $author_ids = array_unique( wp_list_pluck( $posts, 'post_author' ) ); + $this->assertEqualSets( array( $author_3, $author_4 ), $author_ids ); + + $posts = $this->q->query( array( + 'author_name' => 'admin1', + 'post__in' => array( $post_1, $post_2, $post_3, $post_4 ) + ) ); + $author_ids = array_unique( wp_list_pluck( $posts, 'post_author' ) ); + $this->assertEqualSets( array( $author_1 ), $author_ids ); + } }