Enhance the query for "Any" variations in filter by attribute widget.

The new query fixes a bug where variations were being counted twice:
if a product was included in both the queries then it would be counted
differently and added; e.g. when a product had two variations,
one with "Any" attribute and other with a attribute that has a value.

The new query also optimizes performance, so that filter conditions
can be improved and better indexes can be used.
This commit is contained in:
Nestor Soriano 2020-09-04 11:29:50 +02:00
parent ecb25d7dc8
commit 43642f7835
2 changed files with 8 additions and 9 deletions

View File

@ -417,17 +417,16 @@ class WC_Widget_Layered_Nav extends WC_Widget {
// This one will return products having "Any..." as the value of the attribute.
$query_sql_for_attributes_with_any_value = "
SELECT {$wpdb->posts}.post_parent AS product_id, {$wpdb->term_relationships}.term_taxonomy_id as term_count_id FROM {$wpdb->posts}
LEFT JOIN {$wpdb->postmeta} ON {$wpdb->posts}.ID = {$wpdb->postmeta}.post_id AND {$wpdb->postmeta}.meta_key = 'attribute_$taxonomy'
JOIN {$wpdb->term_relationships} ON {$wpdb->term_relationships}.object_id = {$wpdb->posts}.post_parent
SELECT {$wpdb->posts}.ID AS product_id, {$wpdb->term_relationships}.term_taxonomy_id as term_count_id FROM {$wpdb->posts}
JOIN {$wpdb->posts} variations ON variations.post_parent = {$wpdb->posts}.ID
LEFT JOIN {$wpdb->postmeta} ON variations.ID = {$wpdb->postmeta}.post_id AND {$wpdb->postmeta}.meta_key = 'attribute_$taxonomy'
JOIN {$wpdb->term_relationships} ON {$wpdb->term_relationships}.object_id = {$wpdb->posts}.ID
WHERE ( {$wpdb->postmeta}.meta_key IS NULL OR {$wpdb->postmeta}.meta_value = '')
AND {$wpdb->posts}.post_type = 'product_variation'
AND {$wpdb->posts}.post_type = 'product'
AND {$wpdb->posts}.post_status = 'publish'
AND variations.post_status = 'publish'
AND variations.post_type = 'product_variation'
AND {$wpdb->term_relationships}.term_taxonomy_id in $term_ids_sql
AND NOT EXISTS (
SELECT ID FROM {$wpdb->posts} AS parent
WHERE parent.ID = {$wpdb->posts}.post_parent AND parent.post_status NOT IN ('publish')
)
{$main_tax_query_sql['where']}";
// We have two queries - let's see if cached results of this query already exist.

View File

@ -519,7 +519,6 @@ class WC_Tests_Widget_Layered_Nav extends WC_Unit_Test_Case {
$variation_objects = array();
foreach ( $existing_styles as $style ) {
$variation_attributes = array(
'pa_color' => '',
'pa_style' => $style,
);
$variation_object = WC_Helper_Product::create_product_variation_object(
@ -547,6 +546,7 @@ class WC_Tests_Widget_Layered_Nav extends WC_Unit_Test_Case {
}
$main_product->set_children( $variation_objects );
$main_product->save();
return $main_product;
}