diff --git a/src/Internal/ProductAttributesLookup/Filterer.php b/src/Internal/ProductAttributesLookup/Filterer.php index 4971a5b1d3c..6f34dc02b7a 100644 --- a/src/Internal/ProductAttributesLookup/Filterer.php +++ b/src/Internal/ProductAttributesLookup/Filterer.php @@ -213,42 +213,51 @@ class Filterer { $attributes_to_filter_by = \WC_Query::get_layered_nav_chosen_attributes(); if ( ! empty( $attributes_to_filter_by ) ) { - $all_terms_to_filter_by = array(); - foreach ( $attributes_to_filter_by as $taxonomy => $data ) { - $all_terms = get_terms( $taxonomy, array( 'hide_empty' => false ) ); - $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'] ) ) ); - $all_terms_to_filter_by = array_merge( $all_terms_to_filter_by, $term_ids_to_filter_by ); - $term_ids_to_filter_by_list = '(' . join( ',', $term_ids_to_filter_by ) . ')'; + $and_term_ids = array(); + $or_term_ids = array(); - $count = count( $term_ids_to_filter_by ); - if ( 0 !== $count ) { - $query['where'] .= ' AND product_or_parent_id IN ('; - if ( 'and' === $attributes_to_filter_by[ $taxonomy ]['query_type'] ) { - $query['where'] .= " - SELECT product_or_parent_id - FROM {$this->lookup_table_name} lt - WHERE is_variation_attribute=0 - {$in_stock_clause} - AND term_id in {$term_ids_to_filter_by_list} - GROUP BY product_id - HAVING COUNT(product_id)={$count} - UNION - SELECT product_or_parent_id - FROM {$this->lookup_table_name} lt - WHERE is_variation_attribute=1 - {$in_stock_clause} - AND term_id in {$term_ids_to_filter_by_list} - )"; - } else { - $query['where'] .= " - SELECT product_or_parent_id FROM {$this->lookup_table_name} - WHERE term_id in {$term_ids_to_filter_by_list} - {$in_stock_clause} - )"; - } + foreach ( $attributes_to_filter_by as $taxonomy => $data ) { + $all_terms = get_terms( $taxonomy, array( 'hide_empty' => false ) ); + $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'] ) ) ); + if ( 'and' === $data['query_type'] ) { + $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 ) ) { + $terms_count = count( $and_term_ids ); + $term_ids_list = '(' . join( ',', $and_term_ids ) . ')'; + $query['where'] .= " + AND product_or_parent_id IN ( + SELECT product_or_parent_id + FROM {$this->lookup_table_name} lt + WHERE is_variation_attribute=0 + {$in_stock_clause} + AND term_id in {$term_ids_list} + GROUP BY product_id + HAVING COUNT(product_id)={$terms_count} + UNION + SELECT product_or_parent_id + FROM {$this->lookup_table_name} lt + WHERE is_variation_attribute=1 + {$in_stock_clause} + AND term_id in {$term_ids_list} + )"; + } + + 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 {$this->lookup_table_name} + WHERE term_id in {$term_ids_list} + {$in_stock_clause} + )"; + + } } else { $query['where'] .= $in_stock_clause; }