Merge pull request #27589 from woocommerce/enhance-query-for-filtering-attributes-with-any-value
Enhance the query for "Any" variations in filter by attribute widget
This commit is contained in:
commit
168698cd91
|
@ -368,7 +368,7 @@ class WC_Widget_Layered_Nav extends WC_Widget {
|
|||
// Generate the first part of the query.
|
||||
// This one will return non-variable products and variable products with concrete values for the attributes.
|
||||
$query = array();
|
||||
$query['select'] = "SELECT IF({$wpdb->posts}.post_type='variable_product', {$wpdb->posts}.post_parent, {$wpdb->posts}.ID) AS product_id, terms.term_id AS term_count_id";
|
||||
$query['select'] = "SELECT IF({$wpdb->posts}.post_type='product_variation', {$wpdb->posts}.post_parent, {$wpdb->posts}.ID) AS product_id, terms.term_id AS term_count_id";
|
||||
$query['from'] = "FROM {$wpdb->posts}";
|
||||
$query['join'] = "
|
||||
INNER JOIN {$wpdb->term_relationships} AS tr ON {$wpdb->posts}.ID = tr.object_id
|
||||
|
@ -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.
|
||||
|
@ -455,38 +454,25 @@ class WC_Widget_Layered_Nav extends WC_Widget {
|
|||
/**
|
||||
* Get the count of terms for products, using a set of SQL queries that are return pairs of product id - term id.
|
||||
*
|
||||
* @param string ...$queries SQL queries to use, each must return a "product_id" column and a "terms_count_id" column.
|
||||
* @param string $main_query_sql The SQL query to use in order to count products with concrete values for attributes, must return a "product_id" column and a "terms_count_id" column.
|
||||
* @param string $query_sql_for_attributes_with_any_value The SQL query to use in order to count products with "Any" values for attributes, must return a "product_id" column and a "terms_count_id" column.
|
||||
*
|
||||
* @return array An array where the keys are term ids, and the values are term counts.
|
||||
*/
|
||||
private function get_term_product_counts_from_queries( ...$queries ) {
|
||||
private function get_term_product_counts_from_queries( $main_query_sql, $query_sql_for_attributes_with_any_value ) {
|
||||
global $wpdb;
|
||||
|
||||
$total_counts = null;
|
||||
|
||||
foreach ( $queries as $query ) {
|
||||
$query = "
|
||||
$query = "
|
||||
SELECT COUNT(DISTINCT(product_id)) AS term_count, term_count_id FROM (
|
||||
{$query}
|
||||
{$main_query_sql}
|
||||
UNION ALL
|
||||
{$query_sql_for_attributes_with_any_value}
|
||||
) AS x GROUP BY term_count_id";
|
||||
|
||||
$results = $wpdb->get_results( $query, ARRAY_A ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
|
||||
$counts = array_map( 'absint', wp_list_pluck( $results, 'term_count', 'term_count_id' ) );
|
||||
|
||||
if ( is_null( $total_counts ) ) {
|
||||
$total_counts = $counts;
|
||||
} else {
|
||||
foreach ( $counts as $term_id => $term_count ) {
|
||||
if ( array_key_exists( $term_id, $total_counts ) ) {
|
||||
$total_counts[ $term_id ] += $term_count;
|
||||
} else {
|
||||
$total_counts[ $term_id ] = $term_count;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $total_counts;
|
||||
$results = $wpdb->get_results( $query, ARRAY_A ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
|
||||
return array_map( 'absint', wp_list_pluck( $results, 'term_count', 'term_count_id' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue