Avoid returning duplicate matches when using a meta query in WP_User_Query.

A meta_query containing an `OR` relation can result in the same record matching
multiple clauses, leading to duplicate results. The previous prevention against
duplicates [18178] #17582 became unreliable in 4.1 when `WP_Meta_Query`
introduced support for nested clauses. The current changeset adds a new method
`WP_Meta_Query::has_or_relation()` for checking whether an `OR` relation
appears anywhere in the query, and uses the new method in `WP_User_Query` to
enforce distinct results as necessary.

Props maxxsnake.
Fixes #32592.

git-svn-id: https://develop.svn.wordpress.org/trunk@32713 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
Boone Gorges
2015-06-09 17:41:35 +00:00
parent 306d8b6a1e
commit c04185a1f2
4 changed files with 172 additions and 1 deletions

View File

@@ -789,4 +789,72 @@ class Tests_User_Query extends WP_UnitTestCase {
$this->assertEqualSets( $expected, $found );
}
/**
* @ticket 32592
*/
public function test_top_level_or_meta_query_should_eliminate_duplicate_matches() {
$users = $this->factory->user->create_many( 3 );
add_user_meta( $users[0], 'foo', 'bar' );
add_user_meta( $users[1], 'foo', 'bar' );
add_user_meta( $users[0], 'foo2', 'bar2' );
$q = new WP_User_Query( array(
'meta_query' => array(
'relation' => 'OR',
array(
'key' => 'foo',
'value' => 'bar',
),
array(
'key' => 'foo2',
'value' => 'bar2',
),
),
) );
$found = wp_list_pluck( $q->get_results(), 'ID' );
$expected = array( $users[0], $users[1] );
$this->assertEqualSets( $expected, $found );
}
/**
* @ticket 32592
*/
public function test_nested_or_meta_query_should_eliminate_duplicate_matches() {
$users = $this->factory->user->create_many( 3 );
add_user_meta( $users[0], 'foo', 'bar' );
add_user_meta( $users[1], 'foo', 'bar' );
add_user_meta( $users[0], 'foo2', 'bar2' );
add_user_meta( $users[1], 'foo3', 'bar3' );
$q = new WP_User_Query( array(
'meta_query' => array(
'relation' => 'AND',
array(
'key' => 'foo',
'value' => 'bar',
),
array(
'relation' => 'OR',
array(
'key' => 'foo',
'value' => 'bar',
),
array(
'key' => 'foo2',
'value' => 'bar2',
),
),
),
) );
$found = wp_list_pluck( $q->get_results(), 'ID' );
$expected = array( $users[0], $users[1] );
$this->assertEqualSets( $expected, $found );
}
}