Search code examples
wordpresswoocommerceattributescrudhook-woocommerce

Remove attribute value from WooCommerce product using CRUD operation


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();

Solution

  • 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();