3

When adding variations to a WooCommerce product it is adding in a blank attribute. Meaning that when I try to add 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.

Michael M.
  • 10,486
  • 9
  • 18
  • 34
Simon Pollard
  • 2,476
  • 1
  • 17
  • 26

3 Answers3

3

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

LoicTheAztec
  • 229,944
  • 23
  • 356
  • 399
  • Thanks for the help @LoicTheAztec I tried that code and hoped that the sync function was what I was missing. Alas I am still stuck with the same issue that none of the variations are getting assigned the attributes. And I get the following: http://i.imgur.com/TnmTW0I.png – Simon Pollard Dec 06 '17 at 09:52
  • @SimonPollard Your question is not clear and explicit as you are not telling that it's in backend… My answer is related to front end. Now I will update my answer a bit later (for backend)… – LoicTheAztec Dec 06 '17 at 14:44
  • apologies - I have re-written the question to be more clear and added the image - appreciate your help – Simon Pollard Dec 06 '17 at 15:24
  • My issue is the blank item in the attributes array - there should only be 1 record - no idea how / where it gets added – Simon Pollard Dec 06 '17 at 15:29
  • I deleted the 0000 attribute just in case - still no luck – Simon Pollard Dec 06 '17 at 16:27
  • yes all the terms are defined - I just need to assign the relevant one to the variation - it seems as soon as I add a variation it adds the blank attribute – Simon Pollard Dec 06 '17 at 16:50
  • @SimonPollard OK come back later… I might have something, but I need to make some testing before… – LoicTheAztec Dec 06 '17 at 16:55
  • Thanks for your help - turns out the issue was with how I was adding the taxonomy to the product! – Simon Pollard Dec 07 '17 at 15:11
3

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);
Simon Pollard
  • 2,476
  • 1
  • 17
  • 26
1

Since WC 3.0 in order to get the variation selected you should use set_default_attributes.

Instead of

$variation->set_attributes(array('varinfo' => '104-mm'));

Use

$variation->set_default_attributes(array('varinfo' => '104-mm'));
xmpi
  • 11
  • 3