1
votes

When adding variations to a WooCommerce product it is adding in a blank attribute. Meaning that when I try to add in my own attribute it gets appended to an existing array.

Example code I am running:

$product_variation = wc_get_product( $variation_id );
$product_variation->set_attributes(array('attribute_pa_varinfo' => 'blue'));
$product_variation->save();

Then when I var_dump($product_variation); I get the following:

["attributes"]=>
array(2) {
  [0]=>
  string(0) ""
  ["pa_varinfo"]=>
  string(4) "5034"
}

So when I view the product in WooCommerce admin all my variations are there but the attribute is stuck at "any option" for all of them.

no option selected

The weird thing is when I then "update" the product from wp-admin all of the variations then get the correct attribute selected.

Has anyone encountered this before or got any ideas of what I can do?

As another example if I run the following:

$product_variation = wc_get_product( $variation_id );
$product_variation->set_attributes( array ( 'simon' => 'confused' ) );
$product_variation->save();
var_dump($product_variation->get_attributes());

This returns:

array(2) {
 [0]=> string(0) ""
 ["simon"]=> string(8) "confused"
}

Where does the first item come from? I can't seem to clear it.

2
Ok I have updated my answer… You can check - LoicTheAztec

2 Answers

2
votes

So it turns out the problem was with the actual setting up of the attribute against the main parent product, I was passing through an unnamed array, by adding wc_attribute_taxonomy_name('varinfo') => (line 2 below) this correctly saves the data and removes the blank array I had.

      $product_attributes = array(
      wc_attribute_taxonomy_name('varinfo') => 
      array (
        'name'         => wc_attribute_taxonomy_name( 'varinfo' ), // set attribute name
        'value'        => '', // set attribute values
        'position'     => 1,
        'is_visible'   => 1,
        'is_variation' => 1,
        'is_taxonomy'  => 1
      )
    );

    update_post_meta($post_id, '_product_attributes', $product_attributes);
2
votes

Update (related to your update and comments)

To resume (our comments): The product attribute exist. Also all terms for this attribute are defined and set in the parent variable product (in the "Attribute" settings tab)

I have made some tests:

  1. I have create a new 'Varinfo" attribute (pa_varinfo) with 4 values (term names):
    104 mm, 110 mm, 130 mm and 140 mm (so term slugs are like 104-mm…).
  2. I have created a new variable product with one empty variation (nothing defined for this variation) and alter saving the select field shows:
    enter image description here

When using this code (similar to yours):

$parent_product = wc_get_product( 738 ); // Get the variable product
$variation_ids = $parent_product->get_children(); // Get all children variations (Here only one)

// Iterating through each variation
foreach( $variation_ids as $variation_id ){
    $variation = wc_get_product($variation_id);
    $variation->set_attributes(array('pa_varinfo' => '104-mm'));
    $variation->save();
}

it's just working for me and I get the selected value in backend for this variation: enter image description here

Note that I am using the taxonomy name for the attribute and the term SLUG in the array…

So I don't know where you are doing something wrong


This happens when you set an attribute term that doesn't exist and/or is not registered as a post term of the parent variable product. You can try this:

// Get an instance of the WC_Product_Variation object
$variation = wc_get_product( $variation_id );

// Initialising variables
$taxonomy = 'pa_varinfo'; // The taxonomy
$term_name = 'Blue'; // The term "NAME"

// Check if the term exist and if not we create it.
if( ! term_exists( $term_name, $taxonomy ) )
    wp_insert_term( $term_name, $taxonomy );
    
// Get an instance of the WP_Term object
$term = get_term_by( 'name', $term_name, $taxonomy );

// Get the post terms names from the parent variable product.
$post_term_names =  wp_get_post_terms( $variation->get_parent_id(), $taxonomy, array('fields' => 'names') );

// Check if the post term exist and if not we set it in the parent variable product.
if( ! in_array( $term_name, $post_term_names ) )
    wp_set_post_terms( $variation->get_parent_id(), $term_name, $taxonomy, true );

// Now you can set the term for the attribute in your variation
$variation->set_attributes( array( $taxonomy => $term->slug ) );
$variation->save(); // Registering the data

// Get an instance of the parent WC_Product_Variable object
$parent_product = wc_get_product( $variation->get_parent_id() );

// Sync the data of the variation in the parent variable product
$parent_product->sync( $variation_id );

This is tested and works

Assuming that you have already created the appended attribute in WooCommerce…, you will get:

enter image description here