WordPress.org

Make WordPress Core

Changeset 29936


Ignore:
Timestamp:
10/17/2014 02:27:44 AM (6 years ago)
Author:
boonebgorges
Message:

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

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/date.php

    r29934 r29936  
    816816     * @access public
    817817     *
    818      * @param string|array $datetime An array of parameters or a strotime() string
    819      * @param string $default_to Controls what values default to if they are missing from $datetime. Pass "min" or "max".
     818     * @param string|array $datetime       An array of parameters or a strotime() string
     819     * @param bool         $default_to_max Whether to round up incomplete dates. Supported by values
     820     *                                     of $datetime that are arrays, or string values that are a
     821     *                                     subset of MySQL date format ('Y', 'Y-m', 'Y-m-d', 'Y-m-d H:i').
     822     *                                     Default: false.
    820823     * @return string|false A MySQL format date/time or false on failure
    821824     */
     
    824827
    825828        if ( ! is_array( $datetime ) ) {
    826             // @todo Timezone issues here possibly
    827             return gmdate( 'Y-m-d H:i:s', strtotime( $datetime, $now ) );
     829
     830            /*
     831             * Try to parse some common date formats, so we can detect
     832             * the level of precision and support the 'inclusive' parameter.
     833             */
     834            if ( preg_match( '/^(\d{4})$/', $datetime, $matches ) ) {
     835                // Y
     836                $datetime = array(
     837                    'year' => intval( $matches[1] ),
     838                );
     839
     840            } else if ( preg_match( '/^(\d{4})\-(\d{2})$/', $datetime, $matches ) ) {
     841                // Y-m
     842                $datetime = array(
     843                    'year'  => intval( $matches[1] ),
     844                    'month' => intval( $matches[2] ),
     845                );
     846
     847            } else if ( preg_match( '/^(\d{4})\-(\d{2})\-(\d{2})$/', $datetime, $matches ) ) {
     848                // Y-m-d
     849                $datetime = array(
     850                    'year'  => intval( $matches[1] ),
     851                    'month' => intval( $matches[2] ),
     852                    'day'   => intval( $matches[3] ),
     853                );
     854
     855            } else if ( preg_match( '/^(\d{4})\-(\d{2})\-(\d{2}) (\d{2}):(\d{2})$/', $datetime, $matches ) ) {
     856                // Y-m-d H:i
     857                $datetime = array(
     858                    'year'   => intval( $matches[1] ),
     859                    'month'  => intval( $matches[2] ),
     860                    'day'    => intval( $matches[3] ),
     861                    'hour'   => intval( $matches[4] ),
     862                    'minute' => intval( $matches[5] ),
     863                );
     864            }
     865
     866            // If no match is found, we don't support default_to_max.
     867            if ( ! is_array( $datetime ) ) {
     868                // @todo Timezone issues here possibly
     869                return gmdate( 'Y-m-d H:i:s', strtotime( $datetime, $now ) );
     870            }
    828871        }
    829872
  • trunk/tests/phpunit/tests/query/dateQuery.php

    r29933 r29936  
    270270
    271271        $this->assertEquals( $expected_dates, wp_list_pluck( $posts, 'post_date' ) );
     272    }
     273
     274    /**
     275     * @ticket 29908
     276     */
     277    public function test_beforeafter_with_date_string_Y() {
     278        $p1 = $this->factory->post->create( array(
     279            'post_date' => '2008-05-06 13:00:00',
     280        ) );
     281        $p2 = $this->factory->post->create( array(
     282            'post_date' => '2007-05-07 13:00:00',
     283        ) );
     284
     285        $before_posts = $this->_get_query_result( array(
     286            'fields' => 'ids',
     287            'update_post_meta_cache' => false,
     288            'update_post_term_cache' => false,
     289            'date_query' => array(
     290                'before' => '2008',
     291            ),
     292        ) );
     293
     294        $after_posts = $this->_get_query_result( array(
     295            'fields' => 'ids',
     296            'update_post_meta_cache' => false,
     297            'update_post_term_cache' => false,
     298            'date_query' => array(
     299                'after' => '2007',
     300            ),
     301        ) );
     302
     303        $this->assertEquals( array( $p2 ), $before_posts );
     304        $this->assertEquals( array( $p1 ), $after_posts );
     305    }
     306
     307    /**
     308     * @ticket 29908
     309     */
     310    public function test_beforeafter_with_date_string_Y_inclusive() {
     311        $p1 = $this->factory->post->create( array(
     312            'post_date' => '2008-05-06 13:00:00',
     313        ) );
     314        $p2 = $this->factory->post->create( array(
     315            'post_date' => '2007-05-07 13:00:00',
     316        ) );
     317
     318        $before_posts = $this->_get_query_result( array(
     319            'fields' => 'ids',
     320            'update_post_meta_cache' => false,
     321            'update_post_term_cache' => false,
     322            'date_query' => array(
     323                'before' => '2008',
     324                'inclusive' => true,
     325            ),
     326        ) );
     327
     328        $after_posts = $this->_get_query_result( array(
     329            'fields' => 'ids',
     330            'update_post_meta_cache' => false,
     331            'update_post_term_cache' => false,
     332            'date_query' => array(
     333                'after' => '2007',
     334                'inclusive' => true,
     335            ),
     336        ) );
     337
     338        $this->assertEqualSets( array( $p1, $p2 ), $before_posts );
     339        $this->assertEqualSets( array( $p1, $p2 ), $after_posts );
     340    }
     341
     342    /**
     343     * @ticket 29908
     344     */
     345    public function test_beforeafter_with_date_string_Ym() {
     346        $p1 = $this->factory->post->create( array(
     347            'post_date' => '2008-05-06 13:00:00',
     348        ) );
     349        $p2 = $this->factory->post->create( array(
     350            'post_date' => '2008-04-07 13:00:00',
     351        ) );
     352
     353        $before_posts = $this->_get_query_result( array(
     354            'fields' => 'ids',
     355            'update_post_meta_cache' => false,
     356            'update_post_term_cache' => false,
     357            'date_query' => array(
     358                'before' => '2008-05',
     359            ),
     360        ) );
     361
     362        $after_posts = $this->_get_query_result( array(
     363            'fields' => 'ids',
     364            'update_post_meta_cache' => false,
     365            'update_post_term_cache' => false,
     366            'date_query' => array(
     367                'after' => '2008-04',
     368            ),
     369        ) );
     370
     371        $this->assertEquals( array( $p2 ), $before_posts );
     372        $this->assertEquals( array( $p1 ), $after_posts );
     373    }
     374
     375    /**
     376     * @ticket 29908
     377     */
     378    public function test_beforeafter_with_date_string_Ym_inclusive() {
     379        $p1 = $this->factory->post->create( array(
     380            'post_date' => '2008-05-06 13:00:00',
     381        ) );
     382        $p2 = $this->factory->post->create( array(
     383            'post_date' => '2008-04-07 13:00:00',
     384        ) );
     385
     386        $before_posts = $this->_get_query_result( array(
     387            'fields' => 'ids',
     388            'update_post_meta_cache' => false,
     389            'update_post_term_cache' => false,
     390            'date_query' => array(
     391                'before' => '2008-05',
     392                'inclusive' => true,
     393            ),
     394        ) );
     395
     396        $after_posts = $this->_get_query_result( array(
     397            'fields' => 'ids',
     398            'update_post_meta_cache' => false,
     399            'update_post_term_cache' => false,
     400            'date_query' => array(
     401                'after' => '2008-04',
     402                'inclusive' => true,
     403            ),
     404        ) );
     405
     406        $this->assertEqualSets( array( $p1, $p2 ), $before_posts );
     407        $this->assertEqualSets( array( $p1, $p2 ), $after_posts );
     408    }
     409
     410    /**
     411     * @ticket 29908
     412     */
     413    public function test_beforeafter_with_date_string_Ymd() {
     414        $p1 = $this->factory->post->create( array(
     415            'post_date' => '2008-05-06 13:00:00',
     416        ) );
     417        $p2 = $this->factory->post->create( array(
     418            'post_date' => '2008-05-05 13:00:00',
     419        ) );
     420
     421        $before_posts = $this->_get_query_result( array(
     422            'fields' => 'ids',
     423            'update_post_meta_cache' => false,
     424            'update_post_term_cache' => false,
     425            'date_query' => array(
     426                'before' => '2008-05-06',
     427            ),
     428        ) );
     429
     430        $after_posts = $this->_get_query_result( array(
     431            'fields' => 'ids',
     432            'update_post_meta_cache' => false,
     433            'update_post_term_cache' => false,
     434            'date_query' => array(
     435                'after' => '2008-05-05',
     436            ),
     437        ) );
     438
     439        $this->assertEquals( array( $p2 ), $before_posts );
     440        $this->assertEquals( array( $p1 ), $after_posts );
     441    }
     442
     443    /**
     444     * @ticket 29908
     445     */
     446    public function test_beforeafter_with_date_string_Ymd_inclusive() {
     447        $p1 = $this->factory->post->create( array(
     448            'post_date' => '2008-05-06 13:00:00',
     449        ) );
     450        $p2 = $this->factory->post->create( array(
     451            'post_date' => '2008-05-05 13:00:00',
     452        ) );
     453
     454        $before_posts = $this->_get_query_result( array(
     455            'fields' => 'ids',
     456            'update_post_meta_cache' => false,
     457            'update_post_term_cache' => false,
     458            'date_query' => array(
     459                'before' => '2008-05-06',
     460                'inclusive' => true,
     461            ),
     462        ) );
     463
     464        $after_posts = $this->_get_query_result( array(
     465            'fields' => 'ids',
     466            'update_post_meta_cache' => false,
     467            'update_post_term_cache' => false,
     468            'date_query' => array(
     469                'after' => '2008-05-05',
     470                'inclusive' => true,
     471            ),
     472        ) );
     473
     474        $this->assertEqualSets( array( $p1, $p2 ), $before_posts );
     475        $this->assertEqualSets( array( $p1, $p2 ), $after_posts );
     476    }
     477
     478    /**
     479     * @ticket 29908
     480     */
     481    public function test_beforeafter_with_date_string_YmdHi() {
     482        $p1 = $this->factory->post->create( array(
     483            'post_date' => '2008-05-06 14:05:00',
     484        ) );
     485        $p2 = $this->factory->post->create( array(
     486            'post_date' => '2008-05-06 14:04:00',
     487        ) );
     488
     489        $before_posts = $this->_get_query_result( array(
     490            'fields' => 'ids',
     491            'update_post_meta_cache' => false,
     492            'update_post_term_cache' => false,
     493            'date_query' => array(
     494                'before' => '2008-05-06 14:05',
     495            ),
     496        ) );
     497
     498        $after_posts = $this->_get_query_result( array(
     499            'fields' => 'ids',
     500            'update_post_meta_cache' => false,
     501            'update_post_term_cache' => false,
     502            'date_query' => array(
     503                'after' => '2008-05-06 14:04',
     504            ),
     505        ) );
     506
     507        $this->assertEquals( array( $p2 ), $before_posts );
     508        $this->assertEquals( array( $p1 ), $after_posts );
     509    }
     510
     511    /**
     512     * @ticket 29908
     513     */
     514    public function test_beforeafter_with_date_string_YmdHi_inclusive() {
     515        $p1 = $this->factory->post->create( array(
     516            'post_date' => '2008-05-06 14:05:00',
     517        ) );
     518        $p2 = $this->factory->post->create( array(
     519            'post_date' => '2008-05-06 14:04:00',
     520        ) );
     521
     522        $before_posts = $this->_get_query_result( array(
     523            'fields' => 'ids',
     524            'update_post_meta_cache' => false,
     525            'update_post_term_cache' => false,
     526            'date_query' => array(
     527                'before' => '2008-05-06 14:05',
     528                'inclusive' => true,
     529            ),
     530        ) );
     531
     532        $after_posts = $this->_get_query_result( array(
     533            'fields' => 'ids',
     534            'update_post_meta_cache' => false,
     535            'update_post_term_cache' => false,
     536            'date_query' => array(
     537                'after' => '2008-05-06 14:04',
     538                'inclusive' => true,
     539            ),
     540        ) );
     541
     542        $this->assertEqualSets( array( $p1, $p2 ), $before_posts );
     543        $this->assertEqualSets( array( $p1, $p2 ), $after_posts );
     544    }
     545
     546    /**
     547     * @ticket 29908
     548     */
     549    public function test_beforeafter_with_date_string_YmdHis() {
     550        $p1 = $this->factory->post->create( array(
     551            'post_date' => '2008-05-06 14:05:15',
     552        ) );
     553        $p2 = $this->factory->post->create( array(
     554            'post_date' => '2008-05-06 14:05:14',
     555        ) );
     556
     557        $before_posts = $this->_get_query_result( array(
     558            'fields' => 'ids',
     559            'update_post_meta_cache' => false,
     560            'update_post_term_cache' => false,
     561            'date_query' => array(
     562                'before' => '2008-05-06 14:05:15',
     563            ),
     564        ) );
     565
     566        $after_posts = $this->_get_query_result( array(
     567            'fields' => 'ids',
     568            'update_post_meta_cache' => false,
     569            'update_post_term_cache' => false,
     570            'date_query' => array(
     571                'after' => '2008-05-06 14:05:14',
     572            ),
     573        ) );
     574
     575        $this->assertEquals( array( $p2 ), $before_posts );
     576        $this->assertEquals( array( $p1 ), $after_posts );
     577    }
     578
     579    /**
     580     * @ticket 29908
     581     */
     582    public function test_beforeafter_with_date_string_YmdHis_inclusive() {
     583        $p1 = $this->factory->post->create( array(
     584            'post_date' => '2008-05-06 14:04:15',
     585        ) );
     586        $p2 = $this->factory->post->create( array(
     587            'post_date' => '2008-05-06 14:04:14',
     588        ) );
     589
     590        $before_posts = $this->_get_query_result( array(
     591            'fields' => 'ids',
     592            'update_post_meta_cache' => false,
     593            'update_post_term_cache' => false,
     594            'date_query' => array(
     595                'before' => '2008-05-06 14:04:15',
     596                'inclusive' => true,
     597            ),
     598        ) );
     599
     600        $after_posts = $this->_get_query_result( array(
     601            'fields' => 'ids',
     602            'update_post_meta_cache' => false,
     603            'update_post_term_cache' => false,
     604            'date_query' => array(
     605                'after' => '2008-05-06 14:04:14',
     606                'inclusive' => true,
     607            ),
     608        ) );
     609
     610        $this->assertEqualSets( array( $p1, $p2 ), $before_posts );
     611        $this->assertEqualSets( array( $p1, $p2 ), $after_posts );
     612    }
     613
     614    /**
     615     * @ticket 29908
     616     */
     617    public function test_beforeafter_with_date_string_non_parseable() {
     618        $p1 = $this->factory->post->create( array(
     619            'post_date' => '2008-05-06 14:05:15',
     620        ) );
     621        $p2 = $this->factory->post->create( array(
     622            'post_date' => '2008-05-06 14:05:14',
     623        ) );
     624
     625        $before_posts = $this->_get_query_result( array(
     626            'fields' => 'ids',
     627            'update_post_meta_cache' => false,
     628            'update_post_term_cache' => false,
     629            'date_query' => array(
     630                'before' => 'June 12, 2008',
     631            ),
     632        ) );
     633
     634        $after_posts = $this->_get_query_result( array(
     635            'fields' => 'ids',
     636            'update_post_meta_cache' => false,
     637            'update_post_term_cache' => false,
     638            'date_query' => array(
     639                'after' => 'June 12, 2007',
     640            ),
     641        ) );
     642
     643        $this->assertEquals( array( $p1, $p2 ), $before_posts );
    272644    }
    273645
Note: See TracChangeset for help on using the changeset viewer.