diff --git a/includes/admin/meta-boxes/class-wc-meta-box-product-data.php b/includes/admin/meta-boxes/class-wc-meta-box-product-data.php index 363d1d6489e..09acb2e965e 100644 --- a/includes/admin/meta-boxes/class-wc-meta-box-product-data.php +++ b/includes/admin/meta-boxes/class-wc-meta-box-product-data.php @@ -849,10 +849,10 @@ class WC_Meta_Box_Product_Data { } else { - $options = array_map( 'trim', explode( WC_DELIMITER, $attribute['value'] ) ); + $options = wc_get_text_attributes( $attribute['value'] ); foreach ( $options as $option ) { - echo ''; + echo ''; } } @@ -1033,7 +1033,7 @@ class WC_Meta_Box_Product_Data { } elseif ( isset( $attribute_values[ $i ] ) ) { // Text based, separate by pipe - $values = implode( ' ' . WC_DELIMITER . ' ', array_map( 'trim', array_map( 'wp_kses_post', array_map( 'stripslashes', explode( WC_DELIMITER, $attribute_values[ $i ] ) ) ) ) ); + $values = implode( ' ' . WC_DELIMITER . ' ', array_map( 'wc_clean', wc_get_text_attributes( $attribute_values[ $i ] ) ) ); // Custom attribute - Add attribute to array and set the values $attributes[ sanitize_title( $attribute_names[ $i ] ) ] = array( @@ -1564,14 +1564,20 @@ class WC_Meta_Box_Product_Data { $variable_shipping_class[ $i ] = ! empty( $variable_shipping_class[ $i ] ) ? (int) $variable_shipping_class[ $i ] : ''; wp_set_object_terms( $variation_id, $variable_shipping_class[ $i ], 'product_shipping_class'); - // Update taxonomies - don't use wc_clean as it destroys sanitized characters + // Update Attributes $updated_attribute_keys = array(); foreach ( $attributes as $attribute ) { - if ( $attribute['is_variation'] ) { - $attribute_key = 'attribute_' . sanitize_title( $attribute['name'] ); - $value = isset( $_POST[ $attribute_key ][ $i ] ) ? sanitize_title( stripslashes( $_POST[ $attribute_key ][ $i ] ) ) : ''; + $attribute_key = 'attribute_' . sanitize_title( $attribute['name'] ); $updated_attribute_keys[] = $attribute_key; + + if ( $attribute['is_taxonomy'] ) { + // Don't use wc_clean as it destroys sanitized characters + $value = isset( $_POST[ $attribute_key ][ $i ] ) ? sanitize_title( stripslashes( $_POST[ $attribute_key ][ $i ] ) ) : ''; + } else { + $value = isset( $_POST[ $attribute_key ][ $i ] ) ? wc_clean( stripslashes( $_POST[ $attribute_key ][ $i ] ) ) : ''; + } + update_post_meta( $variation_id, $attribute_key, $value ); } } diff --git a/includes/admin/meta-boxes/views/html-variation-admin.php b/includes/admin/meta-boxes/views/html-variation-admin.php index e5d63c6acb9..357f611ca42 100644 --- a/includes/admin/meta-boxes/views/html-variation-admin.php +++ b/includes/admin/meta-boxes/views/html-variation-admin.php @@ -42,10 +42,10 @@ extract( $variation_data ); } else { - $options = array_map( 'trim', explode( WC_DELIMITER, $attribute['value'] ) ); + $options = wc_get_text_attributes( $attribute['value'] ); foreach ( $options as $option ) { - echo ''; + echo ''; } } diff --git a/includes/class-wc-ajax.php b/includes/class-wc-ajax.php index 4d1ff2f9c32..25ca0f77bfa 100644 --- a/includes/class-wc-ajax.php +++ b/includes/class-wc-ajax.php @@ -671,7 +671,7 @@ class WC_AJAX { } elseif ( isset( $attribute_values[ $i ] ) ) { // Text based, separate by pipe - $values = implode( ' ' . WC_DELIMITER . ' ', array_map( 'trim', array_map( 'wp_kses_post', array_map( 'stripslashes', explode( WC_DELIMITER, $attribute_values[ $i ] ) ) ) ) ); + $values = implode( ' ' . WC_DELIMITER . ' ', array_map( 'wc_clean', wc_get_text_attributes( $attribute_values[ $i ] ) ) ); // Custom attribute - Add attribute to array and set the values $attributes[ sanitize_title( $attribute_names[ $i ] ) ] = array( diff --git a/includes/class-wc-form-handler.php b/includes/class-wc-form-handler.php index 7f376f8d9e8..e71438e1b8a 100644 --- a/includes/class-wc-form-handler.php +++ b/includes/class-wc-form-handler.php @@ -609,28 +609,33 @@ class WC_Form_Handler { if ( isset( $_REQUEST[ $taxonomy ] ) ) { // Get value from post data - // Don't use wc_clean as it destroys sanitized characters - $value = sanitize_title( trim( stripslashes( $_REQUEST[ $taxonomy ] ) ) ); + if ( $attribute['is_taxonomy'] ) { + // Don't use wc_clean as it destroys sanitized characters + $value = sanitize_title( stripslashes( $_REQUEST[ $taxonomy ] ) ); + } else { + $value = wc_clean( stripslashes( $_REQUEST[ $taxonomy ] ) ); + } // Get valid value from variation $valid_value = $variation->variation_data[ $taxonomy ]; // Allow if valid - if ( $valid_value == '' || $valid_value == $value ) { - if ( $attribute['is_taxonomy'] ) { - $variations[ $taxonomy ] = $value; - } - else { - // For custom attributes, get the name from the slug - $options = array_map( 'trim', explode( WC_DELIMITER, $attribute['value'] ) ); - foreach ( $options as $option ) { - if ( sanitize_title( $option ) == $value ) { - $value = $option; - break; + if ( '' === $valid_value || $valid_value === $value ) { + + // Pre 2.4 handling where 'slugs' were saved instead of the full text attribute + if ( ! $attribute['is_taxonomy'] ) { + if ( $value === sanitize_title( $value ) ) { + $text_attributes = wc_get_text_attributes( $attribute['value'] ); + foreach ( $text_attributes as $text_attribute ) { + if ( sanitize_title( $text_attribute ) === $value ) { + $value = $text_attribute; + break; + } } } - $variations[ $taxonomy ] = $value; } + + $variations[ $taxonomy ] = $value; continue; } diff --git a/includes/class-wc-product-variable.php b/includes/class-wc-product-variable.php index b65c310c958..db184229f97 100644 --- a/includes/class-wc-product-variable.php +++ b/includes/class-wc-product-variable.php @@ -336,7 +336,6 @@ class WC_Product_Variable extends WC_Product { /** * Return an array of attributes used for variations, as well as their possible values. * - * @access public * @return array of attributes and their available values */ public function get_variation_attributes() { @@ -353,55 +352,52 @@ class WC_Product_Variable extends WC_Product { continue; } - $values = array(); + $values = array(); $attribute_field_name = 'attribute_' . sanitize_title( $attribute['name'] ); + // Get used values from children variations foreach ( $this->get_children() as $child_id ) { - $variation = $this->get_child( $child_id ); if ( ! empty( $variation->variation_id ) ) { - if ( ! $variation->variation_is_visible() ) { continue; // Disabled or hidden } $child_variation_attributes = $variation->get_variation_attributes(); - foreach ( $child_variation_attributes as $name => $value ) { - if ( $name == $attribute_field_name ) { - $values[] = sanitize_title( $value ); - } + if ( isset( $child_variation_attributes[ $attribute_field_name ] ) ) { + $values[] = $child_variation_attributes[ $attribute_field_name ]; } } } // empty value indicates that all options for given attribute are available if ( in_array( '', $values ) ) { - - $values = array(); - - // Get all options - if ( $attribute['is_taxonomy'] ) { - $post_terms = wp_get_post_terms( $this->id, $attribute['name'] ); - foreach ( $post_terms as $term ) - $values[] = $term->slug; - } else { - $values = array_map( 'trim', explode( WC_DELIMITER, $attribute['value'] ) ); - } - - $values = array_unique( $values ); + $values = $attribute['is_taxonomy'] ? wp_get_post_terms( $this->id, $attribute['name'], array( 'fields' => 'slugs' ) ) : wc_get_text_attributes( $attribute['value'] ); // Order custom attributes (non taxonomy) as defined } elseif ( ! $attribute['is_taxonomy'] ) { + $text_attributes = wc_get_text_attributes( $attribute['value'] ); + $assigned_text_attributes = $values; + $values = array(); - $option_names = array_map( 'trim', explode( WC_DELIMITER, $attribute['value'] ) ); - $option_slugs = $values; - $values = array(); - - foreach ( $option_names as $option_name ) { - if ( in_array( sanitize_title( $option_name ), $option_slugs ) ) - $values[] = $option_name; + // Pre 2.4 handling where 'slugs' were saved instead of the full text attribute + if ( $assigned_text_attributes === array_map( 'sanitize_title', $assigned_text_attributes ) ) { + $assigned_text_attributes = array_map( 'sanitize_title', $assigned_text_attributes ); + foreach ( $text_attributes as $text_attribute ) { + if ( in_array( sanitize_title( $text_attribute ), $assigned_text_attributes ) ) { + $values[] = $text_attribute; + continue; + } + } + } else { + foreach ( $text_attributes as $text_attribute ) { + if ( in_array( $text_attribute, $assigned_text_attributes ) ) { + $values[] = $text_attribute; + continue; + } + } } } diff --git a/includes/class-wc-product-variation.php b/includes/class-wc-product-variation.php index 1575241955a..091315f8d9c 100644 --- a/includes/class-wc-product-variation.php +++ b/includes/class-wc-product-variation.php @@ -145,7 +145,7 @@ class WC_Product_Variation extends WC_Product { if ( ! strstr( $name, 'attribute_' ) ) { continue; } - $this->variation_data[ $name ] = sanitize_title( $value[0] ); + $this->variation_data[ $name ] = $value[0]; } return $this->variation_data; diff --git a/templates/single-product/add-to-cart/variable.php b/templates/single-product/add-to-cart/variable.php index ced79718b2b..fdd0ad81d14 100644 --- a/templates/single-product/add-to-cart/variable.php +++ b/templates/single-product/add-to-cart/variable.php @@ -52,11 +52,9 @@ global $product, $post; } } else { - foreach ( $options as $option ) { - echo ''; + echo ''; } - } } ?>