Make WordPress Core


Ignore:
Timestamp:
10/16/2014 07:33:24 PM (10 years ago)
Author:
boonebgorges
Message:

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.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/tests/phpunit/tests/query/dateQuery.php

    r29885 r29923  
    630630        $this->assertEquals( $expected_dates, wp_list_pluck( $posts, 'post_date' ) );
    631631
    632         $this->assertContains( "AND ( ( MONTH( post_date ) = 5 ) ) AND", $this->q->request );
    633 
    634         $this->assertNotContains( "AND ( ( MONTH( post_date ) = 5 AND MONTH( post_date ) = 9 ) ) AND", $this->q->request );
     632        $this->assertContains( "MONTH( post_date ) = 5", $this->q->request );
     633        $this->assertNotContains( "MONTH( post_date ) = 9", $this->q->request );
    635634    }
    636635
     
    654653        $this->assertEquals( $expected_dates, wp_list_pluck( $posts, 'post_date' ) );
    655654
    656         $this->assertContains( "AND ( ( WEEK( post_date, 1 ) = 21 ) ) AND", $this->q->request );
    657 
    658         $this->assertNotContains( "AND ( ( WEEK( post_date, 1 ) = 21 AND WEEK( post_date, 1 ) = 22 ) ) AND", $this->q->request );
     655        $this->assertContains( "WEEK( post_date, 1 ) = 21", $this->q->request );
     656        $this->assertNotContains( "WEEK( post_date, 1 ) = 22", $this->q->request );
     657    }
     658
     659    /**
     660     * @ticket 29822
     661     */
     662    public function test_date_query_one_nested_query() {
     663        $this->create_posts();
     664
     665        $posts = $this->_get_query_result( array(
     666            'date_query' => array(
     667                'relation' => 'OR',
     668                array(
     669                    'relation' => 'AND',
     670                    array(
     671                        'year' => 2004,
     672                    ),
     673                    array(
     674                        'month' => 1,
     675                    ),
     676                ),
     677                array(
     678                    'year' => 1984,
     679                ),
     680            ),
     681        ) );
     682
     683        $expected_dates = array(
     684            '1984-07-28 19:28:56',
     685            '2004-01-03 08:54:10',
     686        );
     687
     688        $this->assertEquals( $expected_dates, wp_list_pluck( $posts, 'post_date' ) );
     689    }
     690
     691    /**
     692     * @ticket 29822
     693     */
     694    public function test_date_query_one_nested_query_multiple_columns_relation_and() {
     695        $p1 = $this->factory->post->create( array(
     696            'post_date' => '2012-03-05 15:30:55',
     697        ) );
     698        $this->update_post_modified( $p1, '2014-11-03 14:43:00' );
     699
     700        $p2 = $this->factory->post->create( array(
     701            'post_date' => '2012-05-05 15:30:55',
     702        ) );
     703        $this->update_post_modified( $p2, '2014-10-03 14:43:00' );
     704
     705        $p3 = $this->factory->post->create( array(
     706            'post_date' => '2013-05-05 15:30:55',
     707        ) );
     708        $this->update_post_modified( $p3, '2014-10-03 14:43:00' );
     709
     710        $p4 = $this->factory->post->create( array(
     711            'post_date' => '2012-02-05 15:30:55',
     712        ) );
     713        $this->update_post_modified( $p4, '2012-12-03 14:43:00' );
     714
     715        $q = new WP_Query( array(
     716            'date_query' => array(
     717                'relation' => 'AND',
     718                array(
     719                    'column' => 'post_date',
     720                    array(
     721                        'year' => 2012,
     722                    ),
     723                ),
     724                array(
     725                    'column' => 'post_modified',
     726                    array(
     727                        'year' => 2014,
     728                    ),
     729                ),
     730            ),
     731            'fields' => 'ids',
     732            'update_post_meta_cache' => false,
     733            'update_post_term_cache' => false,
     734            'post_status' => 'publish',
     735        ) );
     736
     737        $expected = array( $p1, $p2, );
     738
     739        $this->assertEqualSets( $expected, $q->posts );
     740    }
     741
     742    /**
     743     * @ticket 29822
     744     */
     745    public function test_date_query_nested_query_multiple_columns_mixed_relations() {
     746        $p1 = $this->factory->post->create( array(
     747            'post_date' => '2012-03-05 15:30:55',
     748        ) );
     749        $this->update_post_modified( $p1, '2014-11-03 14:43:00' );
     750
     751        $p2 = $this->factory->post->create( array(
     752            'post_date' => '2012-05-05 15:30:55',
     753        ) );
     754        $this->update_post_modified( $p2, '2014-10-03 14:43:00' );
     755
     756        $p3 = $this->factory->post->create( array(
     757            'post_date' => '2013-05-05 15:30:55',
     758        ) );
     759        $this->update_post_modified( $p3, '2014-10-03 14:43:00' );
     760
     761        $p4 = $this->factory->post->create( array(
     762            'post_date' => '2012-02-05 15:30:55',
     763        ) );
     764        $this->update_post_modified( $p4, '2012-12-03 14:43:00' );
     765
     766        $p5 = $this->factory->post->create( array(
     767            'post_date' => '2014-02-05 15:30:55',
     768        ) );
     769        $this->update_post_modified( $p5, '2013-12-03 14:43:00' );
     770
     771        $q = new WP_Query( array(
     772            'date_query' => array(
     773                'relation' => 'OR',
     774                array(
     775                    'relation' => 'AND',
     776                    array(
     777                        'column' => 'post_date',
     778                        array(
     779                            'day' => 05,
     780                        ),
     781                    ),
     782                    array(
     783                        'column' => 'post_date',
     784                        array(
     785                            'before' => array(
     786                                'year' => 2012,
     787                                'month' => 4,
     788                            ),
     789                        ),
     790                    ),
     791                ),
     792                array(
     793                    'column' => 'post_modified',
     794                    array(
     795                        'month' => 12,
     796                    ),
     797                ),
     798            ),
     799            'fields' => 'ids',
     800            'update_post_meta_cache' => false,
     801            'update_post_term_cache' => false,
     802            'post_status' => 'publish',
     803        ) );
     804
     805        $expected = array( $p1, $p4, $p5, );
     806        $this->assertEqualSets( $expected, $q->posts );
    659807    }
    660808
     
    693841        }
    694842    }
     843
     844    /**
     845     * There's no way to change post_modified through the API.
     846     */
     847    protected function update_post_modified( $post_id, $date ) {
     848        global $wpdb;
     849        return $wpdb->update(
     850            $wpdb->posts,
     851            array(
     852                'post_modified' => $date,
     853                'post_modified_gmt' => $date,
     854            ),
     855            array(
     856                'ID' => $post_id,
     857            ),
     858            array(
     859                '%s',
     860                '%s',
     861            ),
     862            array(
     863                '%d',
     864            )
     865        );
     866    }
    695867}
Note: See TracChangeset for help on using the changeset viewer.