From 903b176b99c5de2dbfbb4b4d3164fa98403c7760 Mon Sep 17 00:00:00 2001 From: Claudiu Lodromanean Date: Mon, 10 Apr 2017 13:16:58 -0700 Subject: [PATCH 1/3] Attribute title tweaks --- ...ss-wc-product-variation-data-store-cpt.php | 28 +++++++++---------- tests/unit-tests/product/data-store.php | 28 +++++++++++++++---- 2 files changed, 36 insertions(+), 20 deletions(-) diff --git a/includes/data-stores/class-wc-product-variation-data-store-cpt.php b/includes/data-stores/class-wc-product-variation-data-store-cpt.php index 2bf80bbe813..b3b838e69fd 100644 --- a/includes/data-stores/class-wc-product-variation-data-store-cpt.php +++ b/includes/data-stores/class-wc-product-variation-data-store-cpt.php @@ -179,32 +179,32 @@ 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 ); + $should_include_attributes = apply_filters( 'woocommerce_product_variation_title_include_attributes', $should_include_attributes, $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 ); + $title_attributes_text = $should_include_attributes ? wc_get_formatted_variation( $product, true, false ) : ''; $separator = ! empty( $title_attributes_text ) ? ' – ' : ''; return apply_filters( 'woocommerce_product_variation_title', diff --git a/tests/unit-tests/product/data-store.php b/tests/unit-tests/product/data-store.php index 306e297468a..9fe906c0365 100644 --- a/tests/unit-tests/product/data-store.php +++ b/tests/unit-tests/product/data-store.php @@ -417,17 +417,17 @@ 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. @@ -436,11 +436,27 @@ class WC_Tests_Product_Data_Store extends WC_Unit_Test_Case { // Check the two attribute variation title. $loaded_variation = wc_get_product( $two_attribute_variation->get_id() ); - $this->assertEquals( "Test Product – 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 – 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() { From 715656921d5a95e98c1750c85d20dd461de50342 Mon Sep 17 00:00:00 2001 From: Claudiu Lodromanean Date: Mon, 10 Apr 2017 14:35:16 -0700 Subject: [PATCH 2/3] wc_is_attribute_in_product_name --- includes/class-wc-cart.php | 2 +- includes/class-wc-order-item.php | 4 +--- includes/wc-attribute-functions.php | 24 ++++++++++++++++++++++++ tests/unit-tests/product/functions.php | 14 ++++++++++++++ 4 files changed, 40 insertions(+), 4 deletions(-) diff --git a/includes/class-wc-cart.php b/includes/class-wc-cart.php index d815f3d6f17..d4681b8036e 100644 --- a/includes/class-wc-cart.php +++ b/includes/class-wc-cart.php @@ -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; } diff --git a/includes/class-wc-order-item.php b/includes/class-wc-order-item.php index bd5d445a5d9..12f284db4a6 100644 --- a/includes/class-wc-order-item.php +++ b/includes/class-wc-order-item.php @@ -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; } diff --git a/includes/wc-attribute-functions.php b/includes/wc-attribute-functions.php index e9b1eb3a161..74a023ad249 100644 --- a/includes/wc-attribute-functions.php +++ b/includes/wc-attribute-functions.php @@ -321,3 +321,27 @@ 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 product 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 ) { + $attribute = strtolower( $attribute ); + $name = strtolower( $name ); + $product_name_sections = explode( '–', $name ); + + // Only one main area exists, so no attribute area exists. + if ( count( $product_name_sections ) < 2 ) { + return false; + } + + $product_attributes_section = end( $product_name_sections ); + $product_attributes = array_map( 'trim', explode( ',', $product_attributes_section ) ); + + return in_array( $attribute, $product_attributes ); +} diff --git a/tests/unit-tests/product/functions.php b/tests/unit-tests/product/functions.php index d1662777884..7fed230c52b 100644 --- a/tests/unit-tests/product/functions.php +++ b/tests/unit-tests/product/functions.php @@ -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 – L') ); + $this->assertTrue( wc_is_attribute_in_product_name( 'Two Words', 'Product – L, Two Words' ) ); + $this->assertTrue( wc_is_attribute_in_product_name( 'Blue', 'Product – The Cool One – 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 – Large, Blueish' ) ); + } } From 5cfed7569c5492a3de6b8de1bc10ccf5c71e0f09 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Tue, 11 Apr 2017 21:12:30 +0100 Subject: [PATCH 3/3] Simplify wc_is_attribute_in_product_name and change separator --- ...class-wc-product-variation-data-store-cpt.php | 16 +++++----------- includes/wc-attribute-functions.php | 16 ++-------------- tests/unit-tests/product/data-store.php | 4 ++-- 3 files changed, 9 insertions(+), 27 deletions(-) diff --git a/includes/data-stores/class-wc-product-variation-data-store-cpt.php b/includes/data-stores/class-wc-product-variation-data-store-cpt.php index b3b838e69fd..54d472e8bb8 100644 --- a/includes/data-stores/class-wc-product-variation-data-store-cpt.php +++ b/includes/data-stores/class-wc-product-variation-data-store-cpt.php @@ -193,7 +193,7 @@ class WC_Product_Variation_Data_Store_CPT extends WC_Product_Data_Store_CPT impl // Don't include attributes if an attribute name has 2+ words. if ( $should_include_attributes ) { - foreach( $attributes as $name => $value ) { + foreach ( $attributes as $name => $value ) { if ( false !== strpos( $name, '-' ) ) { $should_include_attributes = false; break; @@ -202,17 +202,11 @@ class WC_Product_Variation_Data_Store_CPT extends WC_Product_Data_Store_CPT impl } $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 ) : ''; - $title_base_text = get_post_field( 'post_title', $product->get_parent_id() ); - $title_attributes_text = $should_include_attributes ? wc_get_formatted_variation( $product, true, false ) : ''; - $separator = ! empty( $title_attributes_text ) ? ' – ' : ''; - - 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 ); } /** diff --git a/includes/wc-attribute-functions.php b/includes/wc-attribute-functions.php index 74a023ad249..423dfd5e4c9 100644 --- a/includes/wc-attribute-functions.php +++ b/includes/wc-attribute-functions.php @@ -323,7 +323,7 @@ function wc_attributes_array_filter_variation( $attribute ) { } /** - * Check if an attribute is included in the attributes area of a product name. + * 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 @@ -331,17 +331,5 @@ function wc_attributes_array_filter_variation( $attribute ) { * @return bool */ function wc_is_attribute_in_product_name( $attribute, $name ) { - $attribute = strtolower( $attribute ); - $name = strtolower( $name ); - $product_name_sections = explode( '–', $name ); - - // Only one main area exists, so no attribute area exists. - if ( count( $product_name_sections ) < 2 ) { - return false; - } - - $product_attributes_section = end( $product_name_sections ); - $product_attributes = array_map( 'trim', explode( ',', $product_attributes_section ) ); - - return in_array( $attribute, $product_attributes ); + return stristr( $name, ' ' . $attribute . ',' ) || 0 === stripos( strrev( $name ), strrev( ' ' . $attribute ) ); } diff --git a/tests/unit-tests/product/data-store.php b/tests/unit-tests/product/data-store.php index 9fe906c0365..1de43388f29 100644 --- a/tests/unit-tests/product/data-store.php +++ b/tests/unit-tests/product/data-store.php @@ -432,11 +432,11 @@ class WC_Tests_Product_Data_Store extends WC_Unit_Test_Case { // Check the one attribute variation title. $loaded_variation = wc_get_product( $one_attribute_variation->get_id() ); - $this->assertEquals( "Test Product – 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 – Green, Large", $loaded_variation->get_name() ); + $this->assertEquals( "Test Product - Green, Large", $loaded_variation->get_name() ); // Check the variation with a multiword attribute name. $loaded_variation = wc_get_product( $multiword_attribute_variation->get_id() );