8
votes

I'm facing a big problem with product variations and their attributes in woocommerce. I'm trying to display a table with each attribute for each availabe product variation. But Woocommerce saves the attributes in post meta complete in lowercase, replaces slashes and german special characters like ü,ö,ä etc. I get the attributes with $variation->get_variation_attributes(). I've searched the database for the save values you can see for example in the dropdown in the admin panel, but they are saved like this without a link to the variation they are assigned to:

a:5:{s:10:"bestell-nr";a:6:{s:4:"name";s:11:"Bestell-Nr.";s:5:"value";s:9:"1 | 2 | and so on...

How can i get the attributes in their correct format to display?

Thanks for your help!

6

6 Answers

14
votes

Actually product attributes are actually terms in custom taxonomies, so you just need to get the terms in that particular taxonomy. All attribute taxonomies are prefaced with 'pa_'. So a size attribute would be a 'pa_size' taxonomy. And the variation ID is the post ID for a variation.

But depending on how you want to display it, WooCommerce has a built-in function for displaying all a variation's attributes:

The following will display a definition list of all of a variations attributes.

echo wc_get_formatted_variation( $product->get_variation_attributes() );

And passing a second parameter of true will display a flat list:

echo wc_get_formatted_variation( $product->get_variation_attributes(), true );
5
votes

This seems to work for me. Hope this helps.

$post = get_post();
$id =  $post->ID;
$product_variations = new WC_Product_Variable( $id );
$product_variations = $product_variations->get_available_variations();
print_r($product_variations);

This can be found in the class-wc-product-variable.php

So basically if you look around on that page you can find a bunch of useful functions.

Here is something i put together.

 $product_children = $product_variations->get_children();

 $child_variations = array();

 foreach ($product_children as $child){

 $child_variations[] = $product_variations->get_available_variation($child);

 }

 print_r($child_variations);
3
votes

I only wanted to publish one of the variation attributes rather than all of them; contributing this code in case it's helpful to anyone else.

get_variation_attributes() gets all the attributes

wc_get_formatted_variation() returns a formatted version of the array it's handed

$attributes =  $productVariation->get_variation_attributes() ;
if ( $attributes [ 'attribute_pa_colour' ] ) {
    $colour = [ 'attribute_pa_colour' => $attributes [ 'attribute_pa_colour'] ];
    echo wc_get_formatted_variation ( $colour );
}
2
votes

The way I do it is by using "get_post_meta":

echo get_post_meta( $variation_id, 'attribute_name_field', true);

Hopes this helps someone.

0
votes

I used wp_get_post_terms to get correct variance attributes.

    global $product;
    $variations = $product->get_available_variations();
    $var = [];
    foreach ($variations as $variation) {
        $var[] = $variation['attributes'];
    }
    var_dump($var);
    //xxx to get attribute values with correct lower-upper-mixed-case
    foreach ($var as $key => $arr) {
      foreach ($arr as $orig_code => $lowercase_value) {
        $terms_arr = wp_get_post_terms( $product->id, str_replace('attribute_','',$orig_code), array( 'fields' => 'names' ) );
        foreach ($terms_arr as $term) {
            if (strtolower($term) == $lowercase_value) {
                $var[$key][$orig_code] = $term;
                break;
            }
        }
      }
    }
    var_dump($var);

The results:

Before hard code

array (size=1)
  0 => 
    array (size=2)
      'attribute_pa_width' => string 'none' (length=4)
      'attribute_pa_code' => string 'valancese' (length=9)

After hard code:

array (size=1)
  0 => 
    array (size=2)
      'attribute_pa_width' => string 'None' (length=4)
      'attribute_pa_code' => string 'ValanceSe' (length=9)
0
votes

Just went through this ...here is my solution. It handles multiple attributes and all the variations. You just have to know the attribute slug.

 $items  = $order->get_items();     
 foreach( $items as $item_id => $product ) 
 {  
 $ProductName = $product->get_name();        /

 if($product->is_type( 'simple' ))
   $CoreProductName = $ProductName;             // No variance   
 else
   {
   list($CoreProductName, $ThrowAway) = explode(" - ",$ProductName, 2); 

   $variation_id       = $product['variation_id'];
   $variation          = new WC_Product_Variation($variation_id);
   $attributes         = $variation->get_variation_attributes();
   $SelectedAttribute1 = $attributes['attribute_YOUR_SLUG1_PER_PRODUCT'];
   $SelectedAttribute2 = $attributes['attribute_YOUR_SLUG2_PER_PRODUCT'];
  }
 }