Merge pull request #23067 from woocommerce/pr/23043
Allow matching of "any" attributes in find_matching_product_variation…
This commit is contained in:
commit
60c18ce544
|
@ -3929,8 +3929,6 @@ img.help_tip {
|
|||
top: 20px;
|
||||
}
|
||||
|
||||
woocommerce-help-tip
|
||||
|
||||
.select2-container {
|
||||
vertical-align: top;
|
||||
margin-bottom: 3px;
|
||||
|
|
|
@ -1068,14 +1068,7 @@ class WC_Product_Data_Store_CPT extends WC_Data_Store_WP implements WC_Object_Da
|
|||
if ( ! $attribute->get_variation() ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$attribute_field_name = 'attribute_' . sanitize_title( $attribute->get_name() );
|
||||
|
||||
if ( ! isset( $match_attributes[ $attribute_field_name ] ) ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
$meta_attribute_names[] = $attribute_field_name;
|
||||
$meta_attribute_names[] = 'attribute_' . sanitize_title( $attribute->get_name() );
|
||||
}
|
||||
|
||||
// Get the attributes of the variations.
|
||||
|
@ -1117,10 +1110,17 @@ class WC_Product_Data_Store_CPT extends WC_Data_Store_WP implements WC_Object_Da
|
|||
foreach ( $sorted_meta as $variation_id => $variation ) {
|
||||
$match = true;
|
||||
|
||||
foreach ( $match_attributes as $attribute_key => $attribute_value ) {
|
||||
if ( array_key_exists( $attribute_key, $variation ) ) {
|
||||
if ( $variation[ $attribute_key ] !== $attribute_value && ( '0' === $variation[ $attribute_key ] || $variation[ $attribute_key ] ) ) {
|
||||
$match = false;
|
||||
// Loop over the variation meta keys and values i.e. what is saved to the products. Note: $attribute_value is empty when 'any' is in use.
|
||||
foreach ( $variation as $attribute_key => $attribute_value ) {
|
||||
$match_any_value = empty( $attribute_value );
|
||||
|
||||
if ( ! $match_any_value && ! array_key_exists( $attribute_key, $match_attributes ) ) {
|
||||
$match = false; // Requires a selection but no value was provide.
|
||||
}
|
||||
|
||||
if ( array_key_exists( $attribute_key, $match_attributes ) ) { // Value to match was provided.
|
||||
if ( ! $match_any_value && $match_attributes[ $attribute_key ] !== $attribute_value ) {
|
||||
$match = false; // Provided value does not match variation.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1137,6 +1137,8 @@ class WC_Product_Data_Store_CPT extends WC_Data_Store_WP implements WC_Object_Da
|
|||
*/
|
||||
return ( array_map( 'sanitize_title', $match_attributes ) === $match_attributes ) ? 0 : $this->find_matching_product_variation( $product, array_map( 'sanitize_title', $match_attributes ) );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -116,9 +116,20 @@ class WC_Helper_Product {
|
|||
)
|
||||
);
|
||||
|
||||
$attribute_data = self::create_attribute( 'size', array( 'small', 'large' ) ); // Create all attribute related things.
|
||||
$attributes = array();
|
||||
|
||||
$attribute = new WC_Product_Attribute();
|
||||
$attribute_data = self::create_attribute( 'size', array( 'small', 'large' ) );
|
||||
$attribute->set_id( $attribute_data['attribute_id'] );
|
||||
$attribute->set_name( $attribute_data['attribute_taxonomy'] );
|
||||
$attribute->set_options( $attribute_data['term_ids'] );
|
||||
$attribute->set_position( 1 );
|
||||
$attribute->set_visible( true );
|
||||
$attribute->set_variation( true );
|
||||
$attributes[] = $attribute;
|
||||
|
||||
$attribute = new WC_Product_Attribute();
|
||||
$attribute_data = self::create_attribute( 'colour', array( 'red', 'blue' ) );
|
||||
$attribute->set_id( $attribute_data['attribute_id'] );
|
||||
$attribute->set_name( $attribute_data['attribute_taxonomy'] );
|
||||
$attribute->set_options( $attribute_data['term_ids'] );
|
||||
|
|
|
@ -229,7 +229,10 @@ class WC_Tests_Product_Data_Store extends WC_Unit_Test_Case {
|
|||
|
||||
$this->assertEquals( $expected_prices, $product->get_variation_prices() );
|
||||
|
||||
$expected_attributes = array( 'pa_size' => array( 'small', 'large' ) );
|
||||
$expected_attributes = array(
|
||||
'pa_size' => array( 'small', 'large' ),
|
||||
'pa_colour' => array( 'blue', 'red' ),
|
||||
);
|
||||
$this->assertEquals( $expected_attributes, $product->get_variation_attributes() );
|
||||
}
|
||||
|
||||
|
@ -910,4 +913,127 @@ class WC_Tests_Product_Data_Store extends WC_Unit_Test_Case {
|
|||
$count = $data_store->create_all_product_variations( wc_get_product( $product_id ), 10 );
|
||||
$this->assertEquals( 7, $count );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test find_matching_product_variation.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function test_find_matching_product_variation() {
|
||||
$product = WC_Helper_Product::create_variation_product();
|
||||
$data_store = WC_Data_Store::load( 'product' );
|
||||
$children = $product->get_children();
|
||||
|
||||
$match = $data_store->find_matching_product_variation( $product, array() );
|
||||
$this->assertEquals( 0, $match );
|
||||
|
||||
$match = $data_store->find_matching_product_variation(
|
||||
$product,
|
||||
array(
|
||||
'attribute_pa_size' => 'small',
|
||||
)
|
||||
);
|
||||
$this->assertEquals( $children[0], $match );
|
||||
|
||||
$match = $data_store->find_matching_product_variation(
|
||||
$product,
|
||||
array(
|
||||
'attribute_pa_size' => 'large',
|
||||
)
|
||||
);
|
||||
$this->assertEquals( $children[1], $match );
|
||||
|
||||
$match = $data_store->find_matching_product_variation(
|
||||
$product,
|
||||
array(
|
||||
'attribute_pa_size' => 'small',
|
||||
'attribute_pa_colour' => '',
|
||||
)
|
||||
);
|
||||
$this->assertEquals( $children[0], $match );
|
||||
|
||||
$match = $data_store->find_matching_product_variation(
|
||||
$product,
|
||||
array(
|
||||
'attribute_pa_size' => 'large',
|
||||
'attribute_pa_colour' => '',
|
||||
)
|
||||
);
|
||||
$this->assertEquals( $children[1], $match );
|
||||
|
||||
$match = $data_store->find_matching_product_variation(
|
||||
$product,
|
||||
array(
|
||||
'attribute_pa_size' => 'small',
|
||||
'attribute_pa_colour' => 'red',
|
||||
)
|
||||
);
|
||||
$this->assertEquals( $children[0], $match );
|
||||
|
||||
$match = $data_store->find_matching_product_variation(
|
||||
$product,
|
||||
array(
|
||||
'attribute_pa_size' => 'large',
|
||||
'attribute_pa_colour' => 'blue',
|
||||
)
|
||||
);
|
||||
$this->assertEquals( $children[1], $match );
|
||||
|
||||
// Test against non matching colour, should still return first attribute.
|
||||
$match = $data_store->find_matching_product_variation(
|
||||
$product,
|
||||
array(
|
||||
'attribute_pa_size' => 'small',
|
||||
'attribute_pa_colour' => 'pink',
|
||||
)
|
||||
);
|
||||
$this->assertEquals( $children[0], $match );
|
||||
|
||||
// Test against non matching colour, should still return first attribute.
|
||||
$match = $data_store->find_matching_product_variation(
|
||||
$product,
|
||||
array(
|
||||
'attribute_pa_size' => 'large',
|
||||
'attribute_pa_colour' => 'pink',
|
||||
)
|
||||
);
|
||||
$this->assertEquals( $children[1], $match );
|
||||
|
||||
// Test non expected matches.
|
||||
// If second attribute in variation is any and you omit the first attribute it should not match anything.
|
||||
$match = $data_store->find_matching_product_variation(
|
||||
$product,
|
||||
array(
|
||||
'attribute_pa_colour' => 'blue',
|
||||
)
|
||||
);
|
||||
$this->assertEquals( 0, $match );
|
||||
|
||||
// If second attribute in variation is any and you pass a blank in the first attribute it should not match anything.
|
||||
$match = $data_store->find_matching_product_variation(
|
||||
$product,
|
||||
array(
|
||||
'attribute_pa_size' => '',
|
||||
'attribute_pa_colour' => 'red',
|
||||
)
|
||||
);
|
||||
$this->assertEquals( 0, $match );
|
||||
|
||||
// Passing blanks as both attributes should not match anything.
|
||||
$match = $data_store->find_matching_product_variation(
|
||||
$product,
|
||||
array(
|
||||
'attribute_pa_size' => '',
|
||||
'attribute_pa_colour' => '',
|
||||
)
|
||||
);
|
||||
$this->assertEquals( 0, $match );
|
||||
|
||||
// Passing an empty array should not match anything.
|
||||
$match = $data_store->find_matching_product_variation(
|
||||
$product,
|
||||
array()
|
||||
);
|
||||
$this->assertEquals( 0, $match );
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue