Added the parent's SKU to product searches for variations

Since the parent's SKU is used when the variation does not have one, we should fall back when searching for consistency.
This commit is contained in:
Christopher Allford 2020-07-29 16:19:15 -07:00
parent d5bedd82b2
commit 78bff3b2da
2 changed files with 59 additions and 2 deletions

View File

@ -1559,10 +1559,17 @@ class WC_Product_Data_Store_CPT extends WC_Data_Store_WP implements WC_Object_Da
}
$post_types = $include_variations ? array( 'product', 'product_variation' ) : array( 'product' );
$join_query = '';
$type_where = '';
$status_where = '';
$limit_query = '';
// When searching variations we should include the parent's meta table for use in searches.
if ( $include_variations ) {
$join_query = " LEFT JOIN {$wpdb->wc_product_meta_lookup} parent_wc_product_meta_lookup
ON posts.post_type = 'product_variation' AND parent_wc_product_meta_lookup.product_id = posts.post_parent ";
}
/**
* Hook woocommerce_search_products_post_statuses.
*
@ -1602,8 +1609,16 @@ class WC_Product_Data_Store_CPT extends WC_Data_Store_WP implements WC_Object_Da
$searchand = '';
foreach ( $search_terms as $search_term ) {
$like = '%' . $wpdb->esc_like( $search_term ) . '%';
$term_group_query .= $wpdb->prepare( " {$searchand} ( ( posts.post_title LIKE %s) OR ( posts.post_excerpt LIKE %s) OR ( posts.post_content LIKE %s ) OR ( wc_product_meta_lookup.sku LIKE %s ) )", $like, $like, $like, $like ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
$like = '%' . $wpdb->esc_like( $search_term ) . '%';
// Variations should also search the parent's meta table for fallback fields.
if ( $include_variations ) {
$variation_query = $wpdb->prepare( ' OR ( wc_product_meta_lookup.sku = "" AND parent_wc_product_meta_lookup.sku LIKE %s ) ', $like );
} else {
$variation_query = '';
}
$term_group_query .= $wpdb->prepare( " {$searchand} ( ( posts.post_title LIKE %s) OR ( posts.post_excerpt LIKE %s) OR ( posts.post_content LIKE %s ) OR ( wc_product_meta_lookup.sku LIKE %s ) $variation_query)", $like, $like, $like, $like ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
$searchand = ' AND ';
}
@ -1643,6 +1658,7 @@ class WC_Product_Data_Store_CPT extends WC_Data_Store_WP implements WC_Object_Da
// phpcs:disable
"SELECT DISTINCT posts.ID as product_id, posts.post_parent as parent_id FROM {$wpdb->posts} posts
LEFT JOIN {$wpdb->wc_product_meta_lookup} wc_product_meta_lookup ON posts.ID = wc_product_meta_lookup.product_id
$join_query
WHERE posts.post_type IN ('" . implode( "','", $post_types ) . "')
$search_where
$status_where

View File

@ -0,0 +1,41 @@
<?php
/**
* Class WC_Product_Data_Store_CPT_Test
*/
class WC_Product_Data_Store_CPT_Test extends WC_Unit_Test_Case {
/**
* @testdox Variations should appear when searching for parent product's SKU.
*/
public function test_variation_searches_parent_sku() {
$parent = new WC_Product_Variable();
$parent->set_name( 'Blue widget' );
$parent->set_sku( 'blue-widget-1' );
$parent->save();
$variation = new WC_Product_Variation();
$variation->set_parent_id( $parent->get_id() );
$variation->set_sku( '' );
$variation->save();
$data_store = WC_Data_Store::load( 'product' );
// No variations should be found searching for just the parent.
$results = $data_store->search_products( 'blue-widget-1', '', false, true );
$this->assertContains( $parent->get_id(), $results );
$this->assertNotContains( $variation->get_id(), $results );
// Variation should be found when searching for it.
$results = $data_store->search_products( 'blue-widget-1', '', true, true );
$this->assertContains( $parent->get_id(), $results );
$this->assertContains( $variation->get_id(), $results );
$variation->set_sku( 'test-widget' );
$variation->save();
// Variations should be found when searching for their specific SKU.
$results = $data_store->search_products( 'test-widget', '', true, true );
$this->assertContains( $variation->get_id(), $results );
}
}