Merge pull request #14278 from woocommerce/fix/14209-alt

Variation Attribute Name Fixes (simplified)
This commit is contained in:
Claudio Sanches 2017-04-11 17:25:28 -03:00 committed by GitHub
commit 627d7a8790
6 changed files with 67 additions and 33 deletions

View File

@ -559,7 +559,7 @@ class WC_Cart {
}
// Check the nicename against the title.
if ( '' === $value || stristr( $cart_item['data']->get_name(), $value ) ) {
if ( '' === $value || wc_is_attribute_in_product_name( $value, $cart_item['data']->get_name() ) ) {
continue;
}

View File

@ -207,9 +207,7 @@ class WC_Order_Item extends WC_Data implements ArrayAccess {
}
// Skip items with values already in the product details area of the product name
$value_in_product_name_regex = "/–.*" . preg_quote( $display_value, '/' ) . "/i";
if ( $product && preg_match( $value_in_product_name_regex, $order_item_name ) ) {
if ( $product && wc_is_attribute_in_product_name( $display_value, $order_item_name ) ) {
continue;
}

View File

@ -179,40 +179,34 @@ class WC_Product_Variation_Data_Store_CPT extends WC_Product_Data_Store_CPT impl
/**
* Generates a title with attribute information for a variation.
* Products with 2+ attributes with one-word values will get a title of the form "Name - Attribute: Value, Attribute: Value"
* All other products will get a title of the form "Name - Value, Value"
* Products will get a title of the form "Name - Value, Value" or just "Name".
*
* @since 3.0.0
* @param WC_Product
* @return string
*/
protected function generate_product_title( $product ) {
$include_attribute_names = false;
$attributes = (array) $product->get_attributes();
// Determine whether to include attribute names through counting the number of one-word attribute values.
$one_word_attributes = 0;
foreach ( $attributes as $name => $value ) {
if ( false === strpos( $value, '-' ) ) {
++$one_word_attributes;
}
if ( $one_word_attributes > 1 ) {
$include_attribute_names = true;
break;
// Don't include attributes if the product has 3+ attributes.
$should_include_attributes = count( $attributes ) < 3;
// Don't include attributes if an attribute name has 2+ words.
if ( $should_include_attributes ) {
foreach ( $attributes as $name => $value ) {
if ( false !== strpos( $name, '-' ) ) {
$should_include_attributes = false;
break;
}
}
}
$include_attribute_names = apply_filters( 'woocommerce_product_variation_title_include_attribute_names', $include_attribute_names, $product );
$title_base_text = get_post_field( 'post_title', $product->get_parent_id() );
$title_attributes_text = wc_get_formatted_variation( $product, true, $include_attribute_names );
$separator = ! empty( $title_attributes_text ) ? ' &ndash; ' : '';
$should_include_attributes = apply_filters( 'woocommerce_product_variation_title_include_attributes', $should_include_attributes, $product );
$separator = apply_filters( 'woocommerce_product_variation_title_attributes_separator', ' - ', $product );
$title_base = get_post_field( 'post_title', $product->get_parent_id() );
$title_suffix = $should_include_attributes ? wc_get_formatted_variation( $product, true, false ) : '';
return apply_filters( 'woocommerce_product_variation_title',
$title_base_text . $separator . $title_attributes_text,
$product,
$title_base_text,
$title_attributes_text
);
return apply_filters( 'woocommerce_product_variation_title', rtrim( $title_base . $separator . $title_suffix, $separator ), $product, $title_base, $title_suffix );
}
/**

View File

@ -321,3 +321,15 @@ function wc_attributes_array_filter_visible( $attribute ) {
function wc_attributes_array_filter_variation( $attribute ) {
return $attribute && is_a( $attribute, 'WC_Product_Attribute' ) && $attribute->get_variation();
}
/**
* Check if an attribute is included in the attributes area of a variation name.
*
* @since 3.0.2
* @param string $attribute Attribute value to check for
* @param string $name Product name to check in
* @return bool
*/
function wc_is_attribute_in_product_name( $attribute, $name ) {
return stristr( $name, ' ' . $attribute . ',' ) || 0 === stripos( strrev( $name ), strrev( ' ' . $attribute ) );
}

View File

@ -417,30 +417,46 @@ class WC_Tests_Product_Data_Store extends WC_Unit_Test_Case {
$one_attribute_variation = new WC_Product_Variation;
$one_attribute_variation->set_parent_id( $product->get_id() );
$one_attribute_variation->set_attributes( array( 'Color' => 'green' ) );
$one_attribute_variation->set_attributes( array( 'color' => 'green' ) );
$one_attribute_variation->save();
$two_attribute_variation = new WC_Product_Variation;
$two_attribute_variation->set_parent_id( $product->get_id() );
$two_attribute_variation->set_attributes( array( 'Color' => 'green', 'Size' => 'large' ) );
$two_attribute_variation->set_attributes( array( 'color' => 'green', 'size' => 'large' ) );
$two_attribute_variation->save();
$multiword_attribute_variation = new WC_Product_Variation;
$multiword_attribute_variation->set_parent_id( $product->get_id() );
$multiword_attribute_variation->set_attributes( array( 'Color' => 'green', 'Mounting Plate' => 'galaxy-s6', 'Support' => 'one-year' ) );
$multiword_attribute_variation->set_attributes( array( 'color' => 'green', 'mounting-plate' => 'galaxy-s6', 'support' => 'one-year' ) );
$multiword_attribute_variation->save();
// Check the one attribute variation title.
$loaded_variation = wc_get_product( $one_attribute_variation->get_id() );
$this->assertEquals( "Test Product &ndash; Green", $loaded_variation->get_name() );
$this->assertEquals( "Test Product - Green", $loaded_variation->get_name() );
// Check the two attribute variation title.
$loaded_variation = wc_get_product( $two_attribute_variation->get_id() );
$this->assertEquals( "Test Product &ndash; Color: Green, Size: Large", $loaded_variation->get_name() );
$this->assertEquals( "Test Product - Green, Large", $loaded_variation->get_name() );
// Check the variation with multiple attributes but only one 1-word attribute.
// Check the variation with a multiword attribute name.
$loaded_variation = wc_get_product( $multiword_attribute_variation->get_id() );
$this->assertEquals( "Test Product &ndash; Green, Galaxy S6, One Year", $loaded_variation->get_name() );
$this->assertEquals( "Test Product", $loaded_variation->get_name() );
}
function test_generate_product_title_disable() {
add_filter( 'woocommerce_product_variation_title_include_attributes', '__return_false' );
$product = new WC_Product;
$product->set_name( 'Test Product' );
$product->save();
$variation = new WC_Product_Variation;
$variation->set_parent_id( $product->get_id() );
$variation->set_attributes( array( 'color' => 'green' ) );
$variation->save();
$loaded_variation = wc_get_product( $variation->get_id() );
$this->assertEquals( "Test Product", $loaded_variation->get_name() );
}
function test_generate_product_title_no_attributes() {

View File

@ -358,4 +358,18 @@ class WC_Tests_Product_Functions extends WC_Unit_Test_Case {
wc_product_force_unique_sku( $product_4_id );
$this->assertEquals( get_post_meta( $product_4_id, '_sku', true ), 'another-custom-sku-2' );
}
/**
* Test wc_is_attribute_in_product_name
*
* @since 3.0.2
*/
public function test_wc_is_attribute_in_product_name() {
$this->assertTrue( wc_is_attribute_in_product_name( 'L', 'Product &ndash; L') );
$this->assertTrue( wc_is_attribute_in_product_name( 'Two Words', 'Product &ndash; L, Two Words' ) );
$this->assertTrue( wc_is_attribute_in_product_name( 'Blue', 'Product &ndash; The Cool One &ndash; Blue, Large' ) );
$this->assertFalse( wc_is_attribute_in_product_name( 'L', 'Product' ) );
$this->assertFalse( wc_is_attribute_in_product_name( 'L', 'Product L Thing' ) );
$this->assertFalse( wc_is_attribute_in_product_name( 'Blue', 'Product &ndash; Large, Blueish' ) );
}
}