I have an global attribute pa_status
with values such as new
, old
, custom
.
This attribute is used in my products.
I would like to remove the old
value from a product using the CRUD operations available in WooCommerce.
The current code looks like this and doesn't work:
$id_product = 77233;
$attribute_name = 'pa_status';
$attribute_value_to_remove_by_id = 57;
$product = wc_get_product($id_product);
$attributes = $product->get_attributes();
if (isset($attributes[$attribute_name])) {
$attributes[$attribute_name]['options'] = array_filter(
$attributes[$attribute_name]['options'],
function ($value) use ($attribute_value_to_remove_by_id) {
return $value !== $attribute_value_to_remove_by_id;
}
);
}
$product->set_attributes($attributes);
$product->save();
I traced through xDebug what is happening in the save()
method and it looks like the get_changes()
method from WC_Product
returns nothing. So no change is taking place in the DB
We need to create an instance of the WC_Product_Attribute
class, and then perform operations on this object.
Now it seems to be working properly. Corrected code:
$id_product = 77233;
$attribute_name = 'pa_status';
$attribute_value_to_remove_by_id = 57;
$product = wc_get_product($id_product);
$attributes = $product->get_attributes();
$options = [];
if (isset($attributes[$attribute_name])) {
$options = array_filter(
$attributes[$attribute_name]['options'],
function ($value) use ($attribute_value_to_remove_by_id) {
return $value !== $attribute_value_to_remove_by_id;
}
);
}
$attribute = new WC_Product_Attribute();
$attribute->set_id(wc_attribute_taxonomy_id_by_name($attribute_name));
$attribute->set_name($attribute_name);
$attribute->set_options($options);
$attributes[$attribute_name] = $attribute;
$product->set_attributes($attributes);
$product->save();