Skip to content

Commit

Permalink
Merge pull request #2419 from 10up/feature/wp-query-tax-query-param
Browse files Browse the repository at this point in the history
Instead of interpreting $args['tax_query'] use WP_Query->tax_query
  • Loading branch information
felipeelia authored Mar 1, 2022
2 parents a1fad57 + c65fbdd commit 5af6932
Show file tree
Hide file tree
Showing 3 changed files with 132 additions and 181 deletions.
112 changes: 2 additions & 110 deletions includes/classes/Indexable/Post/Post.php
Original file line number Diff line number Diff line change
Expand Up @@ -1013,116 +1013,8 @@ public function format_args( $args, $wp_query ) {
* terms array
* @since 0.9.1
*/

// Find root level taxonomies.
if ( empty( $args['tax_query'] ) ) {
if ( isset( $args['category_name'] ) && ! empty( $args['category_name'] ) ) {
$args['tax_query'][] = array(
'taxonomy' => 'category',
'terms' => array( $args['category_name'] ),
'field' => 'slug',
);
}

if ( isset( $args['cat'] ) && ! empty( $args['cat'] ) ) {
$args['tax_query'][] = array(
'taxonomy' => 'category',
'terms' => array( $args['cat'] ),
'field' => 'term_id',
);
}
}

if ( isset( $args['tag'] ) && ! empty( $args['tag'] ) ) {
if ( ! is_array( $args['tag'] ) && false !== strpos( $args['tag'], ',' ) ) {
$args['tag'] = explode( ',', $args['tag'] );
}
$args['tax_query'][] = array(
'taxonomy' => 'post_tag',
'terms' => (array) $args['tag'],
'field' => 'slug',
);
}

if ( isset( $args['post_tag'] ) && ! empty( $args['post_tag'] ) ) {
$args['tax_query'][] = array(
'taxonomy' => 'post_tag',
'terms' => array( $args['post_tag'] ),
'field' => 'slug',
);
}

$has_tag__and = false;

if ( isset( $args['tag__and'] ) && ! empty( $args['tag__and'] ) ) {
$args['tax_query'][] = array(
'taxonomy' => 'post_tag',
'terms' => $args['tag__and'],
'field' => 'term_id',
);

$has_tag__and = true;
}

if ( isset( $args['tag_id'] ) && ! empty( $args['tag_id'] ) && ! is_array( $args['tag_id'] ) ) {

// If you pass tag__in as a parameter, core adds the first
// term ID as tag_id, so we only need to append it if we have
// already added term IDs.
if ( $has_tag__and ) {

$args['tax_query'] = array_map(
function( $tax_query ) use ( $args ) {
if ( isset( $tax_query['taxonomy'] ) && 'post_tag' === $tax_query['taxonomy'] && ! in_array( $args['tag_id'], $tax_query['terms'], true ) ) {
$tax_query['terms'][] = $args['tag_id'];
}

return $tax_query;
},
$args['tax_query']
);
} elseif ( empty( $args['tax_query'] ) ) {
$args['tax_query'][] = array(
'taxonomy' => 'post_tag',
'terms' => $args['tag_id'],
'field' => 'term_id',
);
}
}

/**
* Try to find other taxonomies set in the root of WP_Query
*
* @since 3.4
* @since 3.4.2 Test taxonomies with their query_var value.
*/
$taxonomies = get_taxonomies( array(), 'objects' );

/**
* Filter taxonomies to exclude from tax root check.
* Default values prevent duplication of core's default taxonomies post_tag and category in ES query.
*
* @since 3.6.3
* @hook ep_post_tax_excluded_wp_query_root_check
* @param {array} $taxonomies Taxonomies
*/
$excluded_tax_from_root_check = apply_filters(
'ep_post_tax_excluded_wp_query_root_check',
[
'category',
'post_tag',
]
);

foreach ( $taxonomies as $tax_slug => $tax ) {

if ( $tax->query_var && ! empty( $args[ $tax->query_var ] ) && ! in_array( $tax->name, $excluded_tax_from_root_check, true ) ) {
$args['tax_query'][] = array(
'taxonomy' => $tax_slug,
'terms' => (array) $args[ $tax->query_var ],
'field' => 'slug',
);
}
if ( ! empty( $wp_query->tax_query ) && ! empty( $wp_query->tax_query->queries ) ) {
$args['tax_query'] = $wp_query->tax_query->queries;
}

if ( ! empty( $args['tax_query'] ) ) {
Expand Down
7 changes: 6 additions & 1 deletion tests/php/features/TestProtectedContent.php
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,12 @@ public function testAdminCategories() {
$wp_the_query = $query;

$args = array(
'category_name' => 'category one',
/**
* Despite its name, per WP docs `category_name` actually uses the cat slug.
*
* @see https://developer.wordpress.org/reference/classes/wp_query/#category-parameters
*/
'category_name' => 'category-one',
);

$query->query( $args );
Expand Down
194 changes: 124 additions & 70 deletions tests/php/indexables/TestPost.php
Original file line number Diff line number Diff line change
Expand Up @@ -5285,62 +5285,86 @@ public function testTagSlugQuery() {
* @group post
*/
public function testTagQuery() {
$tag1 = wp_insert_category( [ 'cat_name' => 'tag-1', 'taxonomy' => 'post_tag' ] );
$tag2 = wp_insert_category( [ 'cat_name' => 'tag-2', 'taxonomy' => 'post_tag' ] );
$tag3 = wp_insert_category( [ 'cat_name' => 'tag-3', 'taxonomy' => 'post_tag' ] );
$tag4 = wp_insert_category( [ 'cat_name' => 'tag-4', 'taxonomy' => 'post_tag' ] );
$tag5 = wp_insert_category( [ 'cat_name' => 'tag-5', 'taxonomy' => 'post_tag' ] );
$tag6 = wp_insert_category( [ 'cat_name' => 'tag-6', 'taxonomy' => 'post_tag' ] );

$post_id_1 = Functions\create_and_sync_post(
array(
'post_content' => 'findme test 1',
'tags_input' => array( 'one', 'two' ),
'tags_input' => array( $tag1, $tag2 ),
)
);
$post_id_2 = Functions\create_and_sync_post(
array(
'post_content' => 'findme test 2',
'tags_input' => array( 'three', 'four', 'five', 'six' ),
'tags_input' => array( $tag3, $tag4, $tag5, $tag6 ),
)
);

$post_id_3 = Functions\create_and_sync_post(
array(
'post_content' => 'findme test 3',
'tags_input' => array( 'one', 'six' ),
'tags_input' => array( $tag1, $tag2, $tag6 ),
)
);

$post_1_tags = get_the_tags( $post_id_1 );
$post_2_tags = get_the_tags( $post_id_2 );
$post_3_tags = get_the_tags( $post_id_3 );
/*
* | 1 | 2 | 3 | 4 | 5 | 6 |
* post 1 | x | x | | | | |
* post 2 | | | x | x | x | x |
* post 3 | x | x | | | | x |
*/

ElasticPress\Elasticsearch::factory()->refresh_indices();

// Should find only posts with both tags 1 AND 2
$args = array(
's' => 'findme',
'post_type' => 'post',
'tag__and' => array( $post_1_tags[1]->term_id, $post_2_tags[1]->term_id ),
'tag__and' => array( $tag1, $tag2 ),
'fields' => 'ids',
);

$query = new \WP_Query( $args );

$this->assertTrue( $query->elasticsearch_success );
$this->assertEquals( 2, $query->post_count );
$this->assertEquals( 2, $query->found_posts );
$this->assertEqualsCanonicalizing( [ $post_id_1, $post_id_3 ], $query->posts );

// Should find only posts with tag 3
$args = array(
's' => 'findme',
'post_type' => 'post',
'tag_id' => $tag3,
'fields' => 'ids',
);

// Verify we're only getting the posts we requested.
$post_names = wp_list_pluck( $query->posts, 'post_name' );
$query = new \WP_Query( $args );

$this->assertContains( get_post_field( 'post_name', $post_id_1 ), $post_names );
$this->assertContains( get_post_field( 'post_name', $post_id_2 ), $post_names );
$this->assertNotContains( get_post_field( 'post_name', $post_id_3 ), $post_names );
$this->assertTrue( $query->elasticsearch_success );
$this->assertEquals( 1, $query->post_count );
$this->assertEquals( 1, $query->found_posts );
$this->assertEqualsCanonicalizing( [ $post_id_2 ], $query->posts );

// Should find only posts with tags 1 OR 3
$args = array(
's' => 'findme',
'post_type' => 'post',
'tag_id' => $post_3_tags[1]->term_id,
'tag__in' => array( $tag1, $tag3 ),
'fields' => 'ids',
);

$query = new \WP_Query( $args );

$this->assertTrue( $query->elasticsearch_success );
$this->assertEquals( 2, $query->post_count );
$this->assertEquals( 2, $query->found_posts );
$this->assertEquals( 3, $query->post_count );
$this->assertEquals( 3, $query->found_posts );
$this->assertEqualsCanonicalizing( [ $post_id_1, $post_id_2, $post_id_3 ], $query->posts );
}

/**
Expand Down Expand Up @@ -5582,69 +5606,99 @@ public function testPrepareDocumentFallbacks() {
* @group post
*/
public function testFormatArgsRootLevelTaxonomies() {
$cat1 = wp_create_category( 'category one' );
$cat2 = wp_create_category( 'category two' );
$tag1 = wp_insert_category( [ 'cat_name' => 'tag-1', 'taxonomy' => 'post_tag' ] );
$tag2 = wp_insert_category( [ 'cat_name' => 'tag-2', 'taxonomy' => 'post_tag' ] );
$tag3 = wp_insert_category( [ 'cat_name' => 'tag-3', 'taxonomy' => 'post_tag' ] );

$post = new \ElasticPress\Indexable\Post\Post();

$query = new \WP_Query();
$posts_per_page = (int) get_option( 'posts_per_page' );
$post1 = Functions\create_and_sync_post(
array(
'tags_input' => array( $tag1, $tag2 ),
'post_category' => array( $cat1 ),
)
);
$post2 = Functions\create_and_sync_post(
array(
'tags_input' => array( $tag1, $tag2, $tag3 ),
'post_category' => array( $cat2 ),
)
);
$post3 = Functions\create_and_sync_post(
array(
'post_category' => array( $cat1 ),
)
);
$post4 = Functions\create_and_sync_post(
array(
'tags_input' => array( $tag1, $tag3 ),
)
);

$args = $post->format_args(
ElasticPress\Elasticsearch::factory()->refresh_indices();

$query = new \WP_Query(
[
'cat' => 123,
'tag' => 'tag-slug',
'post_tag' => 'post-tag-slug',
],
$query
'ep_integrate' => true,
'cat' => $cat1,
'tag' => 'tag-1',
'fields' => 'ids',
]
);

$this->assertSame( $posts_per_page, $args['size'] );

$this->assertTrue( is_array( $args['post_filter']['bool']['must'][0]['bool']['must'] ) );

$must_terms = $args['post_filter']['bool']['must'][0]['bool']['must'];

$this->assertSame( 123, $must_terms[0]['terms']['terms.category.term_id'][0] );
$this->assertSame( 'tag-slug', $must_terms[1]['terms']['terms.post_tag.slug'][0] );
$this->assertSame( 'post-tag-slug', $must_terms[2]['terms']['terms.post_tag.slug'][0] );

// Verify a bug fix where two different terms.post_tag.term_id
// parameters were being created. Should only be one parameter
// with the two IDs.
$args = $post->format_args(
$this->assertTrue( $query->elasticsearch_success );
$this->assertEqualsCanonicalizing( [ $post1 ], $query->posts );
$this->assertEquals( 1, $query->post_count );
$this->assertEquals( 1, $query->found_posts );

$query = new \WP_Query(
[
'tag__and' => [ 123, 456 ],
'tag_id' => 123,
],
$query
'ep_integrate' => true,
'tag__and' => [ $tag1, $tag2 ],
'tag_id' => $tag1,
'fields' => 'ids',
]
);

$this->assertTrue( is_array( $args['post_filter']['bool']['must'][0]['bool']['must'] ) );

$must_terms = $args['post_filter']['bool']['must'][0]['bool']['must'];

$this->assertCount( 1, $must_terms );
$this->assertCount( 2, $must_terms[0]['terms']['terms.post_tag.term_id'] );
$this->assertContains( 123, $must_terms[0]['terms']['terms.post_tag.term_id'] );
$this->assertContains( 456, $must_terms[0]['terms']['terms.post_tag.term_id'] );

// Verify we're append the tag_id to the array.
$args = $post->format_args(
$this->assertTrue( $query->elasticsearch_success );
$this->assertEqualsCanonicalizing( [ $post1, $post2 ], $query->posts );
$this->assertEquals( 2, $query->post_count );
$this->assertEquals( 2, $query->found_posts );

$query = new \WP_Query(
[
'tag__and' => [ 123, 456 ],
'tag_id' => 789,
],
$query
'ep_integrate' => true,
'tag__and' => [ $tag1, $tag2 ],
'tag_id' => $tag3,
'fields' => 'ids',
]
);

$this->assertTrue( is_array( $args['post_filter']['bool']['must'][0]['bool']['must'] ) );

$must_terms = $args['post_filter']['bool']['must'][0]['bool']['must'];

$this->assertCount( 1, $must_terms );
$this->assertCount( 3, $must_terms[0]['terms']['terms.post_tag.term_id'] );
$this->assertContains( 123, $must_terms[0]['terms']['terms.post_tag.term_id'] );
$this->assertContains( 456, $must_terms[0]['terms']['terms.post_tag.term_id'] );
$this->assertContains( 789, $must_terms[0]['terms']['terms.post_tag.term_id'] );
$this->assertTrue( $query->elasticsearch_success );
$this->assertEqualsCanonicalizing( [ $post2 ], $query->posts );
$this->assertEquals( 1, $query->post_count );
$this->assertEquals( 1, $query->found_posts );

$query = new \WP_Query(
[
'ep_integrate' => true,
'tag__in' => [ $tag1, $tag2, $tag3 ],
'fields' => 'ids',
]
);
$this->assertTrue( $query->elasticsearch_success );
$this->assertEqualsCanonicalizing( [ $post1, $post2, $post4 ], $query->posts );
$this->assertEquals( 3, $query->post_count );
$this->assertEquals( 3, $query->found_posts );

$query = new \WP_Query(
[
'ep_integrate' => true,
'category__in' => [ $cat1, $cat2 ],
'fields' => 'ids',
]
);
$this->assertTrue( $query->elasticsearch_success );
$this->assertEqualsCanonicalizing( [ $post1, $post2, $post3 ], $query->posts );
$this->assertEquals( 3, $query->post_count );
$this->assertEquals( 3, $query->found_posts );
}

/**
Expand Down

0 comments on commit 5af6932

Please sign in to comment.