Skip to content

Commit d3bbb2c

Browse files
authored
Merge pull request #4165 from 10up/fix/4076
Implement "OR filter relationships" in DateQuery
2 parents 19fd9cc + 07f099b commit d3bbb2c

3 files changed

Lines changed: 226 additions & 1 deletion

File tree

includes/classes/Indexable/Post/DateQuery.php

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,6 @@ protected function get_es_filter_for_query( $query, $depth = 0 ) {
8181
}
8282
}
8383

84-
// @todo implement OR filter relationships.
8584
if ( empty( $relation ) ) {
8685
$relation = 'AND';
8786
}
@@ -111,6 +110,33 @@ protected function get_es_filter_for_query( $query, $depth = 0 ) {
111110
'bool' => $this->build_es_date_term_filter( $term_filters ),
112111
);
113112
}
113+
} elseif ( 'OR' === $relation ) {
114+
$should_clauses = [];
115+
foreach ( $filter_chunks['filters'] as $filter ) {
116+
117+
$group = [];
118+
if ( ! empty( $filter['range_filters'] ) ) {
119+
$group[] = [ 'range' => $filter['range_filters'] ];
120+
}
121+
122+
if ( ! empty( $filter['date_terms'] ) ) {
123+
foreach ( $filter['date_terms']['must'] ?? [] as $must_clause ) {
124+
$group[] = $must_clause;
125+
}
126+
}
127+
128+
if ( $group ) {
129+
$should_clauses[] = [ 'bool' => [ 'must' => $group ] ];
130+
}
131+
}
132+
133+
if ( $should_clauses ) {
134+
$filter_array['or'] = [
135+
'bool' => [
136+
'should' => $should_clauses,
137+
],
138+
];
139+
}
114140
}
115141

116142
return $filter_array;

includes/classes/Indexable/Post/Post.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2087,6 +2087,8 @@ protected function parse_date( $args ) {
20872087

20882088
if ( array_key_exists( 'and', $date_filter ) ) {
20892089
return $date_filter['and'];
2090+
} elseif ( array_key_exists( 'or', $date_filter ) ) {
2091+
return $date_filter['or'];
20902092
}
20912093
}
20922094
}

tests/php/indexables/TestPost.php

Lines changed: 197 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,20 @@ protected function get_feature() {
8888
protected function create_date_query_posts() {
8989
$post_date = wp_date( 'U', strtotime( 'January 6th, 2012 11:59PM' ) );
9090

91+
/**
92+
* Create dummy posts with the following dates.
93+
*
94+
* 2012-01-05 22:59:00
95+
* 2012-01-04 21:59:00
96+
* 2012-01-03 20:59:00
97+
* 2012-01-02 19:59:00
98+
* 2012-01-01 18:59:00
99+
* 2011-12-31 17:59:00
100+
* 2011-12-30 16:59:00
101+
* 2011-12-29 15:59:00
102+
* 2011-12-28 14:59:00
103+
* 2011-12-27 13:59:00
104+
*/
91105
for ( $i = 0; $i <= 10; ++$i ) {
92106
$this->ep_factory->post->create(
93107
array(
@@ -5474,6 +5488,55 @@ public function test_date_query_within_range() {
54745488
$this->assertEquals( 3, $query->post_count );
54755489
}
54765490

5491+
/**
5492+
* Test a date query with a range and relation OR
5493+
*
5494+
* @since 5.3.0
5495+
* @group post
5496+
*/
5497+
public function test_date_query_with_range_and_relation_or() {
5498+
$this->ep_factory->post->create(
5499+
[
5500+
'post_date' => wp_date( 'Y-m-d H:i:s', strtotime( 'January 1st, 2025 00:01:01' ) ),
5501+
]
5502+
);
5503+
5504+
$this->ep_factory->post->create(
5505+
[
5506+
'post_date' => wp_date( 'Y-m-d H:i:s', strtotime( 'February 1st, 2025 00:01:01' ) ),
5507+
]
5508+
);
5509+
5510+
$this->ep_factory->post->create(
5511+
[
5512+
'post_date' => wp_date( 'Y-m-d H:i:s', strtotime( 'March 1st, 2025 00:01:01' ) ),
5513+
]
5514+
);
5515+
5516+
ElasticPress\Elasticsearch::factory()->refresh_indices();
5517+
5518+
$args = [
5519+
'ep_integrate' => true,
5520+
'date_query' => [
5521+
'relation' => 'OR',
5522+
[
5523+
'year' => 2025,
5524+
'month' => 2,
5525+
],
5526+
[
5527+
'year' => 2025,
5528+
'month' => 3,
5529+
],
5530+
],
5531+
];
5532+
5533+
$query = new \WP_Query( $args );
5534+
5535+
$this->assertTrue( $query->elasticsearch_success );
5536+
$this->assertEquals( 2, $query->post_count );
5537+
$this->assertEquals( 2, $query->found_posts );
5538+
}
5539+
54775540
/**
54785541
* Test a date query with multiple eltries
54795542
*
@@ -5677,6 +5740,65 @@ public function testDateQueryValidateDateDoingItWrong() {
56775740
$this->assertFalse( $valid );
56785741
}
56795742

5743+
/**
5744+
* Test date_query with week and dayofyear, expecting specific post counts.
5745+
*
5746+
* @since 5.3.0
5747+
* @group post
5748+
*/
5749+
public function test_date_query_week_and_day_of_year() {
5750+
$this->create_date_query_posts();
5751+
5752+
$args = [
5753+
's' => 'findme',
5754+
'date_query' => [
5755+
[
5756+
'week' => 1,
5757+
'year' => 2012,
5758+
],
5759+
],
5760+
];
5761+
$query = new \WP_Query( $args );
5762+
$this->assertTrue( $query->elasticsearch_success );
5763+
$this->assertEquals( 5, $query->post_count );
5764+
5765+
$args = [
5766+
's' => 'findme',
5767+
'date_query' => [
5768+
[
5769+
'dayofyear' => 5,
5770+
'year' => 2012,
5771+
],
5772+
],
5773+
];
5774+
$query = new \WP_Query( $args );
5775+
$this->assertTrue( $query->elasticsearch_success );
5776+
$this->assertEquals( 1, $query->post_count );
5777+
}
5778+
5779+
/**
5780+
* Test date_query with compare !=.
5781+
*
5782+
* @since 5.3.0
5783+
* @group post
5784+
*/
5785+
public function test_date_query_not_equals_compare() {
5786+
$this->create_date_query_posts();
5787+
$args = [
5788+
's' => 'findme',
5789+
'date_query' => [
5790+
[
5791+
'compare' => '!=',
5792+
'year' => 2012,
5793+
],
5794+
],
5795+
];
5796+
$query = new \WP_Query( $args );
5797+
5798+
$this->assertTrue( $query->elasticsearch_success );
5799+
$this->assertEquals( 5, $query->post_count );
5800+
}
5801+
56805802
/**
56815803
* Test a date query with BETWEEN comparison
56825804
*
@@ -5968,6 +6090,81 @@ public function testDateQueryWeekdayRange() {
59686090
$this->assertEquals( 9, $query->found_posts );
59696091
}
59706092

6093+
/**
6094+
* Test date query with OR relation.
6095+
*
6096+
* @since 5.3.0
6097+
* @group post
6098+
*/
6099+
public function test_date_query_with_or_relation() {
6100+
$this->create_date_query_posts();
6101+
6102+
$args = [
6103+
'ep_integrate' => true,
6104+
'date_query' => [
6105+
'relation' => 'OR',
6106+
[
6107+
'before' => 'December 29th 2011 00:00:00',
6108+
],
6109+
[
6110+
'after' => 'January 4th 2012 23:59:00',
6111+
],
6112+
],
6113+
];
6114+
$query = new \WP_Query( $args );
6115+
6116+
$this->assertTrue( $query->elasticsearch_success );
6117+
$this->assertEquals( 4, $query->post_count );
6118+
$this->assertEquals( 4, $query->found_posts );
6119+
}
6120+
6121+
/**
6122+
* Test date query with OR relation and year.
6123+
*
6124+
* @since 5.3.0
6125+
* @group post
6126+
*/
6127+
public function test_date_query_with_or_relation_with_year() {
6128+
$this->ep_factory->post->create(
6129+
[
6130+
'post_date' => '2023-01-01 00:00:00',
6131+
]
6132+
);
6133+
6134+
$this->ep_factory->post->create(
6135+
[
6136+
'post_date' => '2024-01-01 00:00:00',
6137+
]
6138+
);
6139+
6140+
$this->ep_factory->post->create(
6141+
[
6142+
'post_date' => '2025-01-01 00:00:00',
6143+
]
6144+
);
6145+
6146+
ElasticPress\Elasticsearch::factory()->refresh_indices();
6147+
6148+
$args = [
6149+
'ep_integrate' => true,
6150+
'date_query' => [
6151+
'relation' => 'OR',
6152+
[
6153+
'year' => 2023,
6154+
],
6155+
[
6156+
'year' => 2025,
6157+
],
6158+
],
6159+
];
6160+
6161+
$query = new \WP_Query( $args );
6162+
6163+
$this->assertTrue( $query->elasticsearch_success );
6164+
$this->assertEquals( 2, $query->post_count );
6165+
$this->assertEquals( 2, $query->found_posts );
6166+
}
6167+
59716168
/**
59726169
* Test a date query with IN comparison
59736170
*

0 commit comments

Comments
 (0)