Introduce nested query support to WP_Date_Query.

This enhancement makes it possible to filter post, comment, and other queries
by date in ways that are arbitrarily complex, using mixed AND and OR relations.

Includes unit tests for the new syntax. In a few places, the existing unit
tests were slightly too strict (such as when checking the exact syntax of a SQL
string); these existing tests have been narrowed.

Props boonebgorges.
Fixes #29822.

git-svn-id: https://develop.svn.wordpress.org/trunk@29923 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
Boone Gorges
2014-10-16 19:33:24 +00:00
parent c845692fb4
commit a3e0c08f2f
3 changed files with 468 additions and 61 deletions

View File

@@ -629,9 +629,8 @@ class Tests_Query_DateQuery extends WP_UnitTestCase {
$this->assertEquals( $expected_dates, wp_list_pluck( $posts, 'post_date' ) );
$this->assertContains( "AND ( ( MONTH( post_date ) = 5 ) ) AND", $this->q->request );
$this->assertNotContains( "AND ( ( MONTH( post_date ) = 5 AND MONTH( post_date ) = 9 ) ) AND", $this->q->request );
$this->assertContains( "MONTH( post_date ) = 5", $this->q->request );
$this->assertNotContains( "MONTH( post_date ) = 9", $this->q->request );
}
public function test_date_params_week_w_duplicate() {
@@ -653,9 +652,158 @@ class Tests_Query_DateQuery extends WP_UnitTestCase {
$this->assertEquals( $expected_dates, wp_list_pluck( $posts, 'post_date' ) );
$this->assertContains( "AND ( ( WEEK( post_date, 1 ) = 21 ) ) AND", $this->q->request );
$this->assertContains( "WEEK( post_date, 1 ) = 21", $this->q->request );
$this->assertNotContains( "WEEK( post_date, 1 ) = 22", $this->q->request );
}
$this->assertNotContains( "AND ( ( WEEK( post_date, 1 ) = 21 AND WEEK( post_date, 1 ) = 22 ) ) AND", $this->q->request );
/**
* @ticket 29822
*/
public function test_date_query_one_nested_query() {
$this->create_posts();
$posts = $this->_get_query_result( array(
'date_query' => array(
'relation' => 'OR',
array(
'relation' => 'AND',
array(
'year' => 2004,
),
array(
'month' => 1,
),
),
array(
'year' => 1984,
),
),
) );
$expected_dates = array(
'1984-07-28 19:28:56',
'2004-01-03 08:54:10',
);
$this->assertEquals( $expected_dates, wp_list_pluck( $posts, 'post_date' ) );
}
/**
* @ticket 29822
*/
public function test_date_query_one_nested_query_multiple_columns_relation_and() {
$p1 = $this->factory->post->create( array(
'post_date' => '2012-03-05 15:30:55',
) );
$this->update_post_modified( $p1, '2014-11-03 14:43:00' );
$p2 = $this->factory->post->create( array(
'post_date' => '2012-05-05 15:30:55',
) );
$this->update_post_modified( $p2, '2014-10-03 14:43:00' );
$p3 = $this->factory->post->create( array(
'post_date' => '2013-05-05 15:30:55',
) );
$this->update_post_modified( $p3, '2014-10-03 14:43:00' );
$p4 = $this->factory->post->create( array(
'post_date' => '2012-02-05 15:30:55',
) );
$this->update_post_modified( $p4, '2012-12-03 14:43:00' );
$q = new WP_Query( array(
'date_query' => array(
'relation' => 'AND',
array(
'column' => 'post_date',
array(
'year' => 2012,
),
),
array(
'column' => 'post_modified',
array(
'year' => 2014,
),
),
),
'fields' => 'ids',
'update_post_meta_cache' => false,
'update_post_term_cache' => false,
'post_status' => 'publish',
) );
$expected = array( $p1, $p2, );
$this->assertEqualSets( $expected, $q->posts );
}
/**
* @ticket 29822
*/
public function test_date_query_nested_query_multiple_columns_mixed_relations() {
$p1 = $this->factory->post->create( array(
'post_date' => '2012-03-05 15:30:55',
) );
$this->update_post_modified( $p1, '2014-11-03 14:43:00' );
$p2 = $this->factory->post->create( array(
'post_date' => '2012-05-05 15:30:55',
) );
$this->update_post_modified( $p2, '2014-10-03 14:43:00' );
$p3 = $this->factory->post->create( array(
'post_date' => '2013-05-05 15:30:55',
) );
$this->update_post_modified( $p3, '2014-10-03 14:43:00' );
$p4 = $this->factory->post->create( array(
'post_date' => '2012-02-05 15:30:55',
) );
$this->update_post_modified( $p4, '2012-12-03 14:43:00' );
$p5 = $this->factory->post->create( array(
'post_date' => '2014-02-05 15:30:55',
) );
$this->update_post_modified( $p5, '2013-12-03 14:43:00' );
$q = new WP_Query( array(
'date_query' => array(
'relation' => 'OR',
array(
'relation' => 'AND',
array(
'column' => 'post_date',
array(
'day' => 05,
),
),
array(
'column' => 'post_date',
array(
'before' => array(
'year' => 2012,
'month' => 4,
),
),
),
),
array(
'column' => 'post_modified',
array(
'month' => 12,
),
),
),
'fields' => 'ids',
'update_post_meta_cache' => false,
'update_post_term_cache' => false,
'post_status' => 'publish',
) );
$expected = array( $p1, $p4, $p5, );
$this->assertEqualSets( $expected, $q->posts );
}
/** Helpers **********************************************************/
@@ -692,4 +840,28 @@ class Tests_Query_DateQuery extends WP_UnitTestCase {
$this->factory->post->create( array( 'post_date' => $post_date ) );
}
}
/**
* There's no way to change post_modified through the API.
*/
protected function update_post_modified( $post_id, $date ) {
global $wpdb;
return $wpdb->update(
$wpdb->posts,
array(
'post_modified' => $date,
'post_modified_gmt' => $date,
),
array(
'ID' => $post_id,
),
array(
'%s',
'%s',
),
array(
'%d',
)
);
}
}