Reputation: 544
I'm working on a way to display default variations value for the SAME product according to the category he is. For example, I sell a card with option blue & red. When the user comes by the category ONE, I want the default value is blue. If he comes by the category TWO, the value will be red.
I found a hook woocommerce_product_default_attributes
, but I don't know how to use it .
Note : It seems that woocommerce recognize only one category per product even if your product is in two category.
Example (edit):
I have a product P
.
Product P
is in two categories : Cat 1
& Cat 2
.
Also, product P
has two variables : Blue
& Red
When the user comes by Cat 1
, I want the default value is Blue
.
If he comes by Cat 2
, the value will be Red
.
The answer code of @LoicTheAztech (below) works, BUT:
When I go to
Cat 1
orCat 2
, I can see that for Woocommerce, the product is only inCat 1
, even if we can access by both category.
So before everything, I need to solve the woocommerce issue.
Upvotes: 3
Views: 5384
Reputation: 253901
New updated answer HERE with the replacement filter hook, as since WooCommerce 3, get_variation_default_attributes()
method is replaced by get_default_attributes()
and woocommerce_product_get_default_attributes
is the new related filter hook to be used.
Before WooCommerce 3, the filter hook woocommerce_product_default_attributes
was located in get_variation_default_attributes()
deprecated method, so it's not really the right hook to achieve what you want.
You can achieve your conditional function in woocommerce_before_add_to_cart_form
action hook, for example.
Notes:
- Product Attribute taxonomy always begin by 'pa_' + the attribute slug
- You need to set in for variable products the default value for this attribute in the variation tab settings.
The code:
add_action( 'woocommerce_before_add_to_cart_form', function(){
global $product;
// We EXIT if it's not a variable product
if( ! $product->is_type('variable') ) return;
## DEFINE HERE the desired product attribute taxonomy
$pa_attribute = 'pa_color';
$default_attribute_for_variation = $product->get_variation_default_attribute( $pa_attribute );
// We EXIT if Product Attribute Color is not set as variation usage
if( empty( $default_attribute_for_variation ) ) return;
// Get the array of default attributes
$default_attributes = $product->get_default_attributes();
// For product category 'ONE => Attribute "blue" slug value
if( has_term( 'clothing', 'product_cat', $product->get_id() ) )
$default_attributes[$pa_attribute] = 'blue';
// For product category 'TWO' => Attribute "blue" slug value
elseif( has_term( 'TWO', 'product_cat', $product->get_id() ) )
$default_attributes[$pa_attribute] = 'red';
else return; // If no product categories match we exit
// If a product category match we set the default attribute
$product->set_default_attributes( $default_attributes );
}, 80, 0 );
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
This code is tested and works.
Upvotes: 2
Reputation: 253901
Since Woocommerce 3 you can use woocommerce_product_get_default_attributes
filter hook… So your code for your 2 product categories will be something like this:
add_filter( 'woocommerce_product_get_default_attributes', 'filtering_product_get_default_attributes', 10, 2 );
function filtering_product_get_default_attributes( $default_attributes, $product ){
// We EXIT if it's not a variable product
if( ! $product->is_type('variable') ) return $default_attributes;
## --- YOUR SETTINGS (below) --- ##
// The desired product attribute taxonomy (always start with "pa_")
$taxonomy = 'pa_color';
$category1 = 'one' // The 1st product category (can be an ID, a slug or a name)
$value1 = 'blue' // The corresponding desired attribute slug value for $category1
$category2 = 'two' // The 2nd product category (can be an ID, a slug or a name)
$value2 = 'red' // The corresponding desired attribute slug value for $category2
## --- The code --- ##
// Get the default attribute used for variations for the defined taxonomy
$default_attribute = $product->get_variation_default_attribute( $taxonomy );
// We EXIT if define Product Attribute is not set for variation usage
if( empty( $default_attribute ) ) return $default_attributes;
// For product category slug 'one' => attribute slug value "blue"
if( has_term( 'one', 'product_cat', $product->get_id() ) )
$default_attributes[$taxonomy] = 'blue';
// For product category slug 'two' => attribute slug value "red"
elseif( has_term( 'two', 'product_cat', $product->get_id() ) )
$default_attributes[$taxonomy] = 'red';
else return $default_attributes; // If no product categories match we exit
return $default_attributes; // Always return the values in a filter hook
}
Code goes in function.php file of your active child theme (or active theme). Not tested yet, but it should work.
Explanations:
Since Woocommerce 3 and new introduced CRUDS setter methods, when a method is using
get_prop()
WC_Data
method, a dynamic hook based on the object type and the method name can be used (essentially for frontend: "view" context)…
See this line $value = apply_filters( $this->get_hook_prefix() . $prop, $value, $this );
in
and this linereturn 'woocommerce_' . $this->object_type . '_get_';
in
So the filter hook is dynamically made this way (where $this->object_type
is equal to 'product'
):
'woocommerce_' . $this->object_type . '_get_' . 'default_attributes'
with 2 arguments:
$attributes
(the property value that replace $value
)$product
(the class instance object that replace $this
)…See it on Woocommerce Github closed and solved issue
Upvotes: 2