2

I am trying to add 2 product variations programmatically for a variable product. Based on this answer thread, I am using the following shortened function:

function create_product_variation( $product_id, $variation_data ){

    $product = wc_get_product($product_id);
    
    $variation_post = array(
        'post_title'  => $product->get_name(),
        'post_name'   => 'product-'.$product_id.'-variation',
        'post_status' => 'publish',
        'post_parent' => $product_id,
        'post_type'   => 'product_variation',
        'guid'        => $product->get_permalink()
    );
    
    $variation_id = wp_insert_post( $variation_post );
    $variation = new WC_Product_Variation( $variation_id );
    
    foreach($variation_data as $_variation_data){
        foreach($_variation_data['attributes'] as $attribute => $term_name){
            $taxonomy = 'pa_'.$attribute;

            if( !taxonomy_exists( $taxonomy ) ){
                register_taxonomy(
                    $taxonomy,
                   'product_variation',
                    array(
                        'hierarchical' => false,
                        'label' => ucfirst($attribute),
                        'query_var' => true,
                        'rewrite' => array( 'slug' => sanitize_title($attribute)),
                    )
                );
            }

            if( ! term_exists( $term_name, $taxonomy ) )
                wp_insert_term( $term_name, $taxonomy );

            $term_slug = get_term_by('name', $term_name, $taxonomy )->slug;

            $post_term_names =  wp_get_post_terms( $product_id, $taxonomy, array('fields' => 'names') );

            if( ! in_array( $term_name, $post_term_names ) )
                wp_set_post_terms( $product_id, $term_name, $taxonomy, true );
            
            update_post_meta( $variation_id, 'attribute_'.$taxonomy, $term_slug );
        }       
    }
    
    
    $variation->save();
}

I use the following data array:

$variations_data = array( 
    array( 
        'attributes' => array( 
            'color' => 'Blue',
            'warranty-and-insurance' => 'W1',
         ),
        'sku' => ,
        'regular_price' => 2000,
        'sale_price' => 1800,
        'stock_qty' => 5,
    ),
    array( 
        'attributes' => array( 
            'color' => 'Red',
            'warranty-and-insurance' => 'W1',
        ),
        'sku' => ,
        'regular_price' => 3000,
        'sale_price' => 2800,
        'stock_qty' => 3,
    )
);

Then I run the function with the following:

create_product_variation( $variable_product_id, $variations_data ); 
    

where $variable_product_id is the id of the variable product which I want to make variations for it and $variations_data the data array defined above.

My problem is that the update_post_meta() function just insert the last data from the foreach in function.

i.e. in product variation in woocommerce there are:

Red W1

Red W1

but I want:

Blue W1

Red W1

LoicTheAztec
  • 229,944
  • 23
  • 356
  • 399
Web Design
  • 77
  • 2
  • 19

1 Answers1

1

In your code, the first foreach loop need to be just before the following line of code:

$variation_id = wp_insert_post( $variation_post );

like:

function create_product_variations( $product_id, $variations_data ){
    $product = wc_get_product($product_id);
    
    $variation_post = array(
        'post_title'  => $product->get_name(),
        'post_name'   => 'product-'.$product_id.'-variation',
        'post_status' => 'publish',
        'post_parent' => $product_id,
        'post_type'   => 'product_variation',
        'guid'        => $product->get_permalink()
    );

    foreach( $variations_data as $variation_data ){
        
        $variation_id = wp_insert_post( $variation_post );
        
        $variation = new WC_Product_Variation( $variation_id );

        foreach($_variation_data['attributes'] as $attribute => $term_name){
            $taxonomy = 'pa_'.$attribute;

            if( ! taxonomy_exists( $taxonomy ) ){
                register_taxonomy(
                    $taxonomy,
                   'product_variation',
                    array(
                        'hierarchical' => false,
                        'label' => ucfirst($attribute),
                        'query_var' => true,
                        'rewrite' => array( 'slug' => sanitize_title($attribute)),
                    )
                );
            }

            if( ! term_exists( $term_name, $taxonomy ) )
                wp_insert_term( $term_name, $taxonomy );

            $term_slug = get_term_by('name', $term_name, $taxonomy )->slug;

            $post_term_names =  wp_get_post_terms( $product_id, $taxonomy, array('fields' => 'names') );

            if( ! in_array( $term_name, $post_term_names ) )
                wp_set_post_terms( $product_id, $term_name, $taxonomy, true );
            
            update_post_meta( $variation_id, 'attribute_'.$taxonomy, $term_slug );      
        }
        $variation->save();
    }
}

As wp_insert_post() create a product variation in database, with a unique variation ID, so it need to be done for each variation in your data array.

This should solve your main related problem.


Related:

LoicTheAztec
  • 229,944
  • 23
  • 356
  • 399
  • thank you. it works properly. I use the function in ajax form. So it repeats the process. i.e. based on my question example the out put is: Blue W1 Red W1 Blue W1 Red W1 – Web Design Jun 28 '20 at 08:44
  • as you see in array of data in question the function logically creates two variable products. but the output is duplicated. i.e. there are two set of variable product for each. I google a lot, some say because of administrator role! I didn't understand where the problem is. I use the code in wordpress dashboard not frontend – Web Design Jun 28 '20 at 10:12
  • @WebDesign How you are using it… the best thing is to ask a new question with the code that you are using in backend with it. – LoicTheAztec Jun 28 '20 at 10:23