WooCommerce Products attribute overwrites over older attributes when saved

Viewed 139

I am trying to create product attribute on user input, but whenever i send the request the attribute gets created but it overrides the previous attributes linked to the product.

public static function create_variable_product(){
        $variant_data = wp_clean(isset($_POST['data']) ? wp_unslash($_POST['data']) : '');
        $product_id = wp_clean(isset($_POST['product_id']) ? wp_unslash($_POST['product_id']) : '');
        $variant_data = json_decode($variant_data);
        $product = wc_get_product($product_id);
        if($product->has_child() == false){
            $product = new WC_Product_Variable($product_id);
        }
        $attribute = self::create_product_attribute($product,$variant_data);
        
        wp_send_json($attribute);
    }
    
public static function create_product_attribute($product,$variant_data){
        
        $id = [];
        for($i=0; $i<count($variant_data); $i++){
            $attribute = new WC_Product_Attribute();
            $attribute->set_id(0);
            foreach($variant_data[$i] as $key => $value){
                
                if($key == 'attribute_name'){
                    $attribute->set_name($value);
                }
                if($key == 'options'){
                    $attribute->set_options($value);
                }
    
            }   
                $attribute->set_position( 1 );

                $attribute->set_visible( 1 );

                $attribute->set_variation( 1 );
                $attribute->is_taxonomy(0);

                $product->set_attributes(array($attribute));
                array_push($id,$product->save());
            
        }
        return $id;
}

The data being passed to $_POST['data'] is:

[{
  attribute_name: 'Color',
  options: ['red','yellow','blue']
}]
1 Answers

There are some mistakes in your code. Try the following instead (untested):

public static function create_variable_product(){
    $data       = wp_clean(isset($_POST['data'] ? wp_unslash($_POST['data']) : '');
    $product_id = wp_clean(isset($_POST['product_id']) ? wp_clean( wp_unslash($_POST['product_id']) ) : '');
    $product    = wc_get_product($product_id);
    
    if( is_a($product, 'WC_Product') && ! $product->is_type('variable') && isset($_POST['data']) ){
        $product = new WC_Product_Variable($product_id);
    }
    
    $attribute = self::create_product_attribute($product, $data);
    $product->save()
    
    wp_send_json($attribute);
}

public static function create_product_attribute( $product, $data ) {
    $attributes = $product->get_attributes();
    $attribute  = new WC_Product_Attribute();

    foreach($variant_data[$i] as $key => $values){
        if( $key === 'attribute_name'){
            $attribute->set_name($values);
        } elseif( $key === 'options' ){
            $attribute->set_options($values);
        }
    }
    $attribute->set_position( 1 );
    $attribute->set_visible( 1 );
    $attribute->set_variation( 1 );
    $attribute->is_taxonomy(0);
    
    $attributes[$attribute->get_name()] = $attribute;

    $product->set_attributes($attributes);
}

It should better work.

Related