Better "inclusive" support for string values in WP_Date_Query.

The 'inclusive' parameter for WP_Date_Query determines whether non-precise
dates for 'before' and 'after' will be rounded up or down. Previously, this was
supported only when 'before' and 'after' were arrays; string-formatted dates
were run through strtotime(), which rounded them all down (inclusive in the
case of after, non-inclusive in the case of before). Now, we attempt to parse
formats that look like MySQL-formatted date strings, and apply inclusive logic
to them if we recognize them successfully.

Fixes #29908.
string values. Array values support the 'inclusive

git-svn-id: https://develop.svn.wordpress.org/trunk@29936 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
Boone Gorges 2014-10-17 02:27:44 +00:00
parent aee4647da0
commit 00f7ae376a
2 changed files with 419 additions and 4 deletions

View File

@ -815,16 +815,59 @@ class WP_Date_Query {
* @since 3.7.0
* @access public
*
* @param string|array $datetime An array of parameters or a strotime() string
* @param string $default_to Controls what values default to if they are missing from $datetime. Pass "min" or "max".
* @param string|array $datetime An array of parameters or a strotime() string
* @param bool $default_to_max Whether to round up incomplete dates. Supported by values
* of $datetime that are arrays, or string values that are a
* subset of MySQL date format ('Y', 'Y-m', 'Y-m-d', 'Y-m-d H:i').
* Default: false.
* @return string|false A MySQL format date/time or false on failure
*/
public function build_mysql_datetime( $datetime, $default_to_max = false ) {
$now = current_time( 'timestamp' );
if ( ! is_array( $datetime ) ) {
// @todo Timezone issues here possibly
return gmdate( 'Y-m-d H:i:s', strtotime( $datetime, $now ) );
/*
* Try to parse some common date formats, so we can detect
* the level of precision and support the 'inclusive' parameter.
*/
if ( preg_match( '/^(\d{4})$/', $datetime, $matches ) ) {
// Y
$datetime = array(
'year' => intval( $matches[1] ),
);
} else if ( preg_match( '/^(\d{4})\-(\d{2})$/', $datetime, $matches ) ) {
// Y-m
$datetime = array(
'year' => intval( $matches[1] ),
'month' => intval( $matches[2] ),
);
} else if ( preg_match( '/^(\d{4})\-(\d{2})\-(\d{2})$/', $datetime, $matches ) ) {
// Y-m-d
$datetime = array(
'year' => intval( $matches[1] ),
'month' => intval( $matches[2] ),
'day' => intval( $matches[3] ),
);
} else if ( preg_match( '/^(\d{4})\-(\d{2})\-(\d{2}) (\d{2}):(\d{2})$/', $datetime, $matches ) ) {
// Y-m-d H:i
$datetime = array(
'year' => intval( $matches[1] ),
'month' => intval( $matches[2] ),
'day' => intval( $matches[3] ),
'hour' => intval( $matches[4] ),
'minute' => intval( $matches[5] ),
);
}
// If no match is found, we don't support default_to_max.
if ( ! is_array( $datetime ) ) {
// @todo Timezone issues here possibly
return gmdate( 'Y-m-d H:i:s', strtotime( $datetime, $now ) );
}
}
$datetime = array_map( 'absint', $datetime );

View File

@ -271,6 +271,378 @@ class Tests_Query_DateQuery extends WP_UnitTestCase {
$this->assertEquals( $expected_dates, wp_list_pluck( $posts, 'post_date' ) );
}
/**
* @ticket 29908
*/
public function test_beforeafter_with_date_string_Y() {
$p1 = $this->factory->post->create( array(
'post_date' => '2008-05-06 13:00:00',
) );
$p2 = $this->factory->post->create( array(
'post_date' => '2007-05-07 13:00:00',
) );
$before_posts = $this->_get_query_result( array(
'fields' => 'ids',
'update_post_meta_cache' => false,
'update_post_term_cache' => false,
'date_query' => array(
'before' => '2008',
),
) );
$after_posts = $this->_get_query_result( array(
'fields' => 'ids',
'update_post_meta_cache' => false,
'update_post_term_cache' => false,
'date_query' => array(
'after' => '2007',
),
) );
$this->assertEquals( array( $p2 ), $before_posts );
$this->assertEquals( array( $p1 ), $after_posts );
}
/**
* @ticket 29908
*/
public function test_beforeafter_with_date_string_Y_inclusive() {
$p1 = $this->factory->post->create( array(
'post_date' => '2008-05-06 13:00:00',
) );
$p2 = $this->factory->post->create( array(
'post_date' => '2007-05-07 13:00:00',
) );
$before_posts = $this->_get_query_result( array(
'fields' => 'ids',
'update_post_meta_cache' => false,
'update_post_term_cache' => false,
'date_query' => array(
'before' => '2008',
'inclusive' => true,
),
) );
$after_posts = $this->_get_query_result( array(
'fields' => 'ids',
'update_post_meta_cache' => false,
'update_post_term_cache' => false,
'date_query' => array(
'after' => '2007',
'inclusive' => true,
),
) );
$this->assertEqualSets( array( $p1, $p2 ), $before_posts );
$this->assertEqualSets( array( $p1, $p2 ), $after_posts );
}
/**
* @ticket 29908
*/
public function test_beforeafter_with_date_string_Ym() {
$p1 = $this->factory->post->create( array(
'post_date' => '2008-05-06 13:00:00',
) );
$p2 = $this->factory->post->create( array(
'post_date' => '2008-04-07 13:00:00',
) );
$before_posts = $this->_get_query_result( array(
'fields' => 'ids',
'update_post_meta_cache' => false,
'update_post_term_cache' => false,
'date_query' => array(
'before' => '2008-05',
),
) );
$after_posts = $this->_get_query_result( array(
'fields' => 'ids',
'update_post_meta_cache' => false,
'update_post_term_cache' => false,
'date_query' => array(
'after' => '2008-04',
),
) );
$this->assertEquals( array( $p2 ), $before_posts );
$this->assertEquals( array( $p1 ), $after_posts );
}
/**
* @ticket 29908
*/
public function test_beforeafter_with_date_string_Ym_inclusive() {
$p1 = $this->factory->post->create( array(
'post_date' => '2008-05-06 13:00:00',
) );
$p2 = $this->factory->post->create( array(
'post_date' => '2008-04-07 13:00:00',
) );
$before_posts = $this->_get_query_result( array(
'fields' => 'ids',
'update_post_meta_cache' => false,
'update_post_term_cache' => false,
'date_query' => array(
'before' => '2008-05',
'inclusive' => true,
),
) );
$after_posts = $this->_get_query_result( array(
'fields' => 'ids',
'update_post_meta_cache' => false,
'update_post_term_cache' => false,
'date_query' => array(
'after' => '2008-04',
'inclusive' => true,
),
) );
$this->assertEqualSets( array( $p1, $p2 ), $before_posts );
$this->assertEqualSets( array( $p1, $p2 ), $after_posts );
}
/**
* @ticket 29908
*/
public function test_beforeafter_with_date_string_Ymd() {
$p1 = $this->factory->post->create( array(
'post_date' => '2008-05-06 13:00:00',
) );
$p2 = $this->factory->post->create( array(
'post_date' => '2008-05-05 13:00:00',
) );
$before_posts = $this->_get_query_result( array(
'fields' => 'ids',
'update_post_meta_cache' => false,
'update_post_term_cache' => false,
'date_query' => array(
'before' => '2008-05-06',
),
) );
$after_posts = $this->_get_query_result( array(
'fields' => 'ids',
'update_post_meta_cache' => false,
'update_post_term_cache' => false,
'date_query' => array(
'after' => '2008-05-05',
),
) );
$this->assertEquals( array( $p2 ), $before_posts );
$this->assertEquals( array( $p1 ), $after_posts );
}
/**
* @ticket 29908
*/
public function test_beforeafter_with_date_string_Ymd_inclusive() {
$p1 = $this->factory->post->create( array(
'post_date' => '2008-05-06 13:00:00',
) );
$p2 = $this->factory->post->create( array(
'post_date' => '2008-05-05 13:00:00',
) );
$before_posts = $this->_get_query_result( array(
'fields' => 'ids',
'update_post_meta_cache' => false,
'update_post_term_cache' => false,
'date_query' => array(
'before' => '2008-05-06',
'inclusive' => true,
),
) );
$after_posts = $this->_get_query_result( array(
'fields' => 'ids',
'update_post_meta_cache' => false,
'update_post_term_cache' => false,
'date_query' => array(
'after' => '2008-05-05',
'inclusive' => true,
),
) );
$this->assertEqualSets( array( $p1, $p2 ), $before_posts );
$this->assertEqualSets( array( $p1, $p2 ), $after_posts );
}
/**
* @ticket 29908
*/
public function test_beforeafter_with_date_string_YmdHi() {
$p1 = $this->factory->post->create( array(
'post_date' => '2008-05-06 14:05:00',
) );
$p2 = $this->factory->post->create( array(
'post_date' => '2008-05-06 14:04:00',
) );
$before_posts = $this->_get_query_result( array(
'fields' => 'ids',
'update_post_meta_cache' => false,
'update_post_term_cache' => false,
'date_query' => array(
'before' => '2008-05-06 14:05',
),
) );
$after_posts = $this->_get_query_result( array(
'fields' => 'ids',
'update_post_meta_cache' => false,
'update_post_term_cache' => false,
'date_query' => array(
'after' => '2008-05-06 14:04',
),
) );
$this->assertEquals( array( $p2 ), $before_posts );
$this->assertEquals( array( $p1 ), $after_posts );
}
/**
* @ticket 29908
*/
public function test_beforeafter_with_date_string_YmdHi_inclusive() {
$p1 = $this->factory->post->create( array(
'post_date' => '2008-05-06 14:05:00',
) );
$p2 = $this->factory->post->create( array(
'post_date' => '2008-05-06 14:04:00',
) );
$before_posts = $this->_get_query_result( array(
'fields' => 'ids',
'update_post_meta_cache' => false,
'update_post_term_cache' => false,
'date_query' => array(
'before' => '2008-05-06 14:05',
'inclusive' => true,
),
) );
$after_posts = $this->_get_query_result( array(
'fields' => 'ids',
'update_post_meta_cache' => false,
'update_post_term_cache' => false,
'date_query' => array(
'after' => '2008-05-06 14:04',
'inclusive' => true,
),
) );
$this->assertEqualSets( array( $p1, $p2 ), $before_posts );
$this->assertEqualSets( array( $p1, $p2 ), $after_posts );
}
/**
* @ticket 29908
*/
public function test_beforeafter_with_date_string_YmdHis() {
$p1 = $this->factory->post->create( array(
'post_date' => '2008-05-06 14:05:15',
) );
$p2 = $this->factory->post->create( array(
'post_date' => '2008-05-06 14:05:14',
) );
$before_posts = $this->_get_query_result( array(
'fields' => 'ids',
'update_post_meta_cache' => false,
'update_post_term_cache' => false,
'date_query' => array(
'before' => '2008-05-06 14:05:15',
),
) );
$after_posts = $this->_get_query_result( array(
'fields' => 'ids',
'update_post_meta_cache' => false,
'update_post_term_cache' => false,
'date_query' => array(
'after' => '2008-05-06 14:05:14',
),
) );
$this->assertEquals( array( $p2 ), $before_posts );
$this->assertEquals( array( $p1 ), $after_posts );
}
/**
* @ticket 29908
*/
public function test_beforeafter_with_date_string_YmdHis_inclusive() {
$p1 = $this->factory->post->create( array(
'post_date' => '2008-05-06 14:04:15',
) );
$p2 = $this->factory->post->create( array(
'post_date' => '2008-05-06 14:04:14',
) );
$before_posts = $this->_get_query_result( array(
'fields' => 'ids',
'update_post_meta_cache' => false,
'update_post_term_cache' => false,
'date_query' => array(
'before' => '2008-05-06 14:04:15',
'inclusive' => true,
),
) );
$after_posts = $this->_get_query_result( array(
'fields' => 'ids',
'update_post_meta_cache' => false,
'update_post_term_cache' => false,
'date_query' => array(
'after' => '2008-05-06 14:04:14',
'inclusive' => true,
),
) );
$this->assertEqualSets( array( $p1, $p2 ), $before_posts );
$this->assertEqualSets( array( $p1, $p2 ), $after_posts );
}
/**
* @ticket 29908
*/
public function test_beforeafter_with_date_string_non_parseable() {
$p1 = $this->factory->post->create( array(
'post_date' => '2008-05-06 14:05:15',
) );
$p2 = $this->factory->post->create( array(
'post_date' => '2008-05-06 14:05:14',
) );
$before_posts = $this->_get_query_result( array(
'fields' => 'ids',
'update_post_meta_cache' => false,
'update_post_term_cache' => false,
'date_query' => array(
'before' => 'June 12, 2008',
),
) );
$after_posts = $this->_get_query_result( array(
'fields' => 'ids',
'update_post_meta_cache' => false,
'update_post_term_cache' => false,
'date_query' => array(
'after' => 'June 12, 2007',
),
) );
$this->assertEquals( array( $p1, $p2 ), $before_posts );
}
public function test_date_query_year_expecting_results() {
$this->create_posts();