From 4b6957c852d2a9abdf0ad6673f1f68b3f7e3ef2f Mon Sep 17 00:00:00 2001 From: Boone Gorges Date: Wed, 14 Jan 2015 16:50:09 +0000 Subject: [PATCH] Support array values in `WP_Date_Query::validate_date_values()`. Introduced in [29925], `validate_date_values()` throws `_doing_it_wrong()` notices when values passed as part of a `WP_Date_Query` do not reflect actual dates. However, the validation did not account properly for the case where an array of multiple values is passed, as when doing IN or BETWEEN queries. Props dlh. Fixes #31001 for trunk. git-svn-id: https://develop.svn.wordpress.org/trunk@31179 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/date.php | 46 ++++++++++++++-------- tests/phpunit/tests/date/query.php | 62 ++++++++++++++++++++++++++++++ 2 files changed, 91 insertions(+), 17 deletions(-) diff --git a/src/wp-includes/date.php b/src/wp-includes/date.php index c023574ed6..d2c8f6971d 100644 --- a/src/wp-includes/date.php +++ b/src/wp-includes/date.php @@ -304,8 +304,17 @@ class WP_Date_Query { // Days per year. if ( array_key_exists( 'year', $date_query ) ) { - // If a year exists in the date query, we can use it to get the days. - $max_days_of_year = date( 'z', mktime( 0, 0, 0, 12, 31, $date_query['year'] ) ) + 1; + /* + * If a year exists in the date query, we can use it to get the days. + * If multiple years are provided (as in a BETWEEN), use the first one. + */ + if ( is_array( $date_query['year'] ) ) { + $_year = reset( $date_query['year'] ); + } else { + $_year = $date_query['year']; + } + + $max_days_of_year = date( 'z', mktime( 0, 0, 0, 12, 31, $_year ) ) + 1; } else { // otherwise we use the max of 366 (leap-year) $max_days_of_year = 366; @@ -335,10 +344,10 @@ class WP_Date_Query { ); // Weeks per year. - if ( array_key_exists( 'year', $date_query ) ) { + if ( isset( $_year ) ) { // If we have a specific year, use it to calculate number of weeks. $date = new DateTime(); - $date->setISODate( $date_query['year'], 53 ); + $date->setISODate( $_year, 53 ); $week_count = $date->format( "W" ) === "53" ? 53 : 52; } else { @@ -381,22 +390,25 @@ class WP_Date_Query { continue; } - $is_between = $date_query[ $key ] >= $check['min'] && $date_query[ $key ] <= $check['max']; + // Throw a notice for each failing value. + $is_between = true; + foreach ( (array) $date_query[ $key ] as $_value ) { + $is_between = $_value >= $check['min'] && $_value <= $check['max']; - if ( ! $is_between ) { + if ( ! $is_between ) { + $error = sprintf( + /* translators: Date query invalid date message: 1: invalid value, 2: type of value, 3: minimum valid value, 4: maximum valid value */ + __( 'Invalid value %1$s for %2$s. Expected value should be between %3$s and %4$s.' ), + '' . esc_html( $_value ) . '', + '' . esc_html( $key ) . '', + '' . esc_html( $check['min'] ) . '', + '' . esc_html( $check['max'] ) . '' + ); - $error = sprintf( - /* translators: Date query invalid date message: 1: invalid value, 2: type of value, 3: minimum valid value, 4: maximum valid value */ - __( 'Invalid value %1$s for %2$s. Expected value should be between %3$s and %4$s.' ), - '' . esc_html( $date_query[ $key ] ) . '', - '' . esc_html( $key ) . '', - '' . esc_html( $check['min'] ) . '', - '' . esc_html( $check['max'] ) . '' - ); + _doing_it_wrong( __CLASS__, $error, '4.1.0' ); - _doing_it_wrong( __CLASS__, $error, '4.1.0' ); - - $valid = false; + $valid = false; + } } } diff --git a/tests/phpunit/tests/date/query.php b/tests/phpunit/tests/date/query.php index 82b6ffaffa..2169d88efb 100644 --- a/tests/phpunit/tests/date/query.php +++ b/tests/phpunit/tests/date/query.php @@ -960,6 +960,68 @@ class Tests_WP_Date_Query extends WP_UnitTestCase { } } + /** + * @ticket 31001 + */ + public function test_validate_date_values_should_process_array_value_for_year() { + $p1 = $this->factory->post->create( array( 'post_date' => '2015-01-12' ) ); + $p2 = $this->factory->post->create( array( 'post_date' => '2013-01-12' ) ); + + $q = new WP_Query( array( + 'date_query' => array( + array( + 'compare' => 'BETWEEN', + 'year' => array( 2012, 2014 ), + ), + ), + 'fields' => 'ids', + ) ); + + $this->assertEquals( array( $p2 ), $q->posts ); + } + + /** + * @ticket 31001 + */ + public function test_validate_date_values_should_process_array_value_for_day() { + $p1 = $this->factory->post->create( array( 'post_date' => '2015-01-12' ) ); + $p2 = $this->factory->post->create( array( 'post_date' => '2015-01-10' ) ); + + $q = new WP_Query( array( + 'date_query' => array( + array( + 'compare' => 'BETWEEN', + 'day' => array( 9, 11 ), + ), + ), + 'fields' => 'ids', + ) ); + + $this->assertEquals( array( $p2 ), $q->posts ); + } + + /** + * @ticket 31001 + * @expectedIncorrectUsage WP_Date_Query + */ + public function test_validate_date_values_should_process_array_value_for_day_when_values_are_invalid() { + $p1 = $this->factory->post->create( array( 'post_date' => '2015-01-12' ) ); + $p2 = $this->factory->post->create( array( 'post_date' => '2015-01-10' ) ); + + $q = new WP_Query( array( + 'date_query' => array( + array( + 'compare' => 'BETWEEN', + 'day' => array( 9, 32 ), + ), + ), + 'fields' => 'ids', + ) ); + + // MySQL ignores the invalid clause. + $this->assertEquals( array( $p1, $p2 ), $q->posts ); + } + /** Helpers **********************************************************/ public function date_query_valid_columns_callback( $columns ) {