Fix: bad counters in the filter by attribute widget for OR.

When a filter by attribute widget was configured as OR, the query
to return the product counts was overfiltering and returning
less results than it should. It now works as in the case of not
using the lookup table.
This commit is contained in:
Nestor Soriano 2021-12-03 12:22:52 +01:00
parent 5253a1adae
commit fd81e477d2
No known key found for this signature in database
GPG Key ID: 08110F3518C12CAD
2 changed files with 8 additions and 57 deletions

View File

@ -226,17 +226,15 @@ class Filterer {
if ( ! empty( $attributes_to_filter_by ) ) { if ( ! empty( $attributes_to_filter_by ) ) {
$and_term_ids = array(); $and_term_ids = array();
$or_term_ids = array();
foreach ( $attributes_to_filter_by as $taxonomy => $data ) { foreach ( $attributes_to_filter_by as $taxonomy => $data ) {
if ( 'and' !== $data['query_type'] ) {
continue;
}
$all_terms = get_terms( $taxonomy, array( 'hide_empty' => false ) ); $all_terms = get_terms( $taxonomy, array( 'hide_empty' => false ) );
$term_ids_by_slug = wp_list_pluck( $all_terms, 'term_id', 'slug' ); $term_ids_by_slug = wp_list_pluck( $all_terms, 'term_id', 'slug' );
$term_ids_to_filter_by = array_values( array_intersect_key( $term_ids_by_slug, array_flip( $data['terms'] ) ) ); $term_ids_to_filter_by = array_values( array_intersect_key( $term_ids_by_slug, array_flip( $data['terms'] ) ) );
if ( 'and' === $data['query_type'] ) {
$and_term_ids = array_merge( $and_term_ids, $term_ids_to_filter_by ); $and_term_ids = array_merge( $and_term_ids, $term_ids_to_filter_by );
} else {
$or_term_ids = array_merge( $or_term_ids, $term_ids_to_filter_by );
}
} }
if ( ! empty( $and_term_ids ) ) { if ( ! empty( $and_term_ids ) ) {
@ -261,17 +259,6 @@ class Filterer {
AND term_id in {$term_ids_list} AND term_id in {$term_ids_list}
) temp )"; ) temp )";
} }
if ( ! empty( $or_term_ids ) ) {
$term_ids_list = '(' . join( ',', $or_term_ids ) . ')';
$query['where'] .= "
AND product_or_parent_id IN ( SELECT product_or_parent_id FROM (
SELECT product_or_parent_id FROM {$this->lookup_table_name}
WHERE term_id in {$term_ids_list}
{$in_stock_clause}
) temp )";
}
} else { } else {
$query['where'] .= $in_stock_clause; $query['where'] .= $in_stock_clause;
} }

View File

@ -545,16 +545,7 @@ class FiltererTest extends \WC_Unit_Test_Case {
$this->assertEmpty( $filtered_product_ids ); $this->assertEmpty( $filtered_product_ids );
} }
/*
* If a variable product defines an attribute value that isn't used by any variation:
* When using the lookup table: that value is not included in the count.
* When not using the lookup table: the value is included in the count since it is part of the parent product.
*/
if ( $using_lookup_table && 'or' === $filter_type && array( 'Green' ) === $attributes ) {
$expected_to_be_included_in_count = false;
} else {
$expected_to_be_included_in_count = 'or' === $filter_type || $expected_to_be_visible; $expected_to_be_included_in_count = 'or' === $filter_type || $expected_to_be_visible;
}
$this->assert_counters( 'Color', $expected_to_be_included_in_count ? array( 'Blue', 'Red' ) : array(), $filter_type ); $this->assert_counters( 'Color', $expected_to_be_included_in_count ? array( 'Blue', 'Red' ) : array(), $filter_type );
} }
@ -822,16 +813,7 @@ class FiltererTest extends \WC_Unit_Test_Case {
$this->assertEmpty( $filtered_product_ids ); $this->assertEmpty( $filtered_product_ids );
} }
/*
* If a variable product defines an attribute value that isn't used by any variation:
* When using the lookup table: that value is not included in the count.
* When not using the lookup table: the value is included in the count since it is part of the parent product.
*/
if ( $using_lookup_table && 'or' === $filter_type && array( 'Elastic' ) === $attributes ) {
$expected_to_be_included_in_count = false;
} else {
$expected_to_be_included_in_count = 'or' === $filter_type || $expected_to_be_visible; $expected_to_be_included_in_count = 'or' === $filter_type || $expected_to_be_visible;
}
$this->assert_counters( 'Features', $expected_to_be_included_in_count ? array( 'Washable', 'Ironable' ) : array(), $filter_type ); $this->assert_counters( 'Features', $expected_to_be_included_in_count ? array( 'Washable', 'Ironable' ) : array(), $filter_type );
} }
@ -1075,16 +1057,7 @@ class FiltererTest extends \WC_Unit_Test_Case {
$this->assertEmpty( $filtered_product_ids ); $this->assertEmpty( $filtered_product_ids );
} }
/*
* If a variable product defines an attribute value that isn't used by any variation:
* When using the lookup table: that value is not included in the count.
* When not using the lookup table: the value is included in the count since it is part of the parent product.
*/
if ( $using_lookup_table && 'or' === $filter_type && array( 'Green' ) === $attributes ) {
$expected_counted_attributes = array();
} else {
$expected_counted_attributes = 'or' === $filter_type || $expected_to_be_visible ? array( 'Blue', 'Red' ) : array(); $expected_counted_attributes = 'or' === $filter_type || $expected_to_be_visible ? array( 'Blue', 'Red' ) : array();
}
$this->assert_counters( 'Color', $expected_counted_attributes, $filter_type ); $this->assert_counters( 'Color', $expected_counted_attributes, $filter_type );
} }
@ -1208,16 +1181,7 @@ class FiltererTest extends \WC_Unit_Test_Case {
$this->assertEmpty( $filtered_product_ids ); $this->assertEmpty( $filtered_product_ids );
} }
/*
* If a variable product defines an attribute value that isn't used by any variation:
* When using the lookup table: that value is not included in the count.
* When not using the lookup table: the value is included in the count since it is part of the parent product.
*/
if ( $using_lookup_table && 'or' === $filter_type && array( 'White' ) === $attributes ) {
$expected_to_be_included_in_count = false;
} else {
$expected_to_be_included_in_count = 'or' === $filter_type || $expected_to_be_visible; $expected_to_be_included_in_count = 'or' === $filter_type || $expected_to_be_visible;
}
$this->assert_counters( 'Color', $expected_to_be_included_in_count ? array( 'Blue', 'Red', 'Green' ) : array(), $filter_type ); $this->assert_counters( 'Color', $expected_to_be_included_in_count ? array( 'Blue', 'Red', 'Green' ) : array(), $filter_type );
} }