Friday, March 29, 2024

Fetching Extended Product Attributes using the WooCommerce API

Fetching Extended Product Attributes using the WooCommerce API

WooCommerce is a great eCommerce plugin for WordPress, made even greater by dozens of third-party extensions. The only drawback to using them is that there is no direct way to work with them via the WooCommerce API. In the Using the WooCommerce Rest API tutorial we learned about a client library that facilitates interacting with the WooCommerce Web API. Unfortunately, it cannot possibly take into account the myriad of extensions. So, in today’s follow-up, we’ll have to get creative!

Fetching Categories

Similar to categories on your posts in WordPress, you can add, delete, and edit your product categories from the WooCommerce Products > Categories screen. There are some added options on top of the normal category fields, and you can upload an image to be associated with the category as well.

The WooCommerce Rest API Client v2 makes fetching categories a snap, thanks to the get_categories() function. It returns all of the product categories in an array format. In the app that I worked on, we referred to categories as brand lines. Our app did not required every category’s attributes so I selected the ones that I wanted and appended those to a new array as an object:

$categories = $client->products->get_categories();
$brands_lines = array();
foreach ($categories['product_categories'] as $brands_line) {
  array_push($brands_lines, (object)array('id'    => $brands_line['id'],
                                          'name'  => $brands_line['name'],
                                          'slug'  => $brands_line['slug'],
                                          'image' => $brands_line['image']) );
}
echo count($brands_lines) > 0 ? json_encode( $brands_lines ) : '{"error": "No brand lines found."}';

Fetching All Products for a Given Category

According to the developers of the WooCommerce Rest API Client, the next version (v3) will let you get products in a given category. Until then, Steve Cove recommends using the following filter:

$client->products->get(null,array('filter[category]'=>$slug));

I haven’t had the opportunity to try it myself, but I did come up with my own slightly more verbose solution using the WP_Query object. I basically bypassed WooCommerce entirely and performed a taxonomy query directly on the WordPress database.

Posts_per_page is an undocumented parameter that can be used with get_posts and query_posts functions. WordPress uses a variable named SQL_CALC_FOUND_ROWS in most queries in order to implement pagination – even when you don’t need pagination at all. Counting the total matching rows can add a lot of time to your query execution time if you have a lot of rows in your database. Setting no_found_rows to 1 turns off this behaviour.

Once you’ve got a result set, you can iterate over it to select the fields that you want:

$products = array();
$query_args = array(
    'posts_per_page' => 10000,
    'no_found_rows' => 1,
    'post_status' => 'publish',
    'post_type' => 'product',
    'tax_query' => array(
        array(
            'taxonomy' => 'product_cat',
            'field' => 'id',
            'terms' => $cat_id
)));

$loop = new WP_Query($query_args);
if ( $loop->have_posts() ) {
    foreach ($loop->posts as $post) {
        array_push($products, (object)array('id'   => $post->ID,
                                            'name' => $post->post_title));
    }
    echo json_encode($products);
}
else {
    echo '{"error": "No products found for line."}';
}

Fetching Product Swatches

Product swatches can be tricky to deal with because there are a number of WooCommerce plugins that allow you to use image swatches instead of the standard color ones. The site that I worked on used WooCommerce Extra Product Options.

image_swatches

It stores each product’s options as serialized data in a field named “tm_meta”. Once deserialized, it’s an array containing many nested inner arrays. The attributes we want are in the pa_colours array. The variations_display_as attribute can either be “color” or “image” for color or image swatches respectively. Image swatches are located in the variations_color array while colors are stored in variations_color. These arrays each contain information such as the path to the image or color hex code:

$tm_meta = get_post_meta( $product['id'], 'tm_meta');

$display_as = $tm_meta[0]['tmfbuilder']['variations_options']['pa_colours']['variations_display_as'];
$images     = $tm_meta[0]['tmfbuilder']['variations_options']['pa_colours']['variations_imagep'];
$swatches   = $tm_meta[0]['tmfbuilder']['variations_options']['pa_colours']['variations_color'];

if ( $display_as == 'color' ) {
  $details['Colours'] = array_map(function($name, $swatch, $image){
                                      return (object)array('name'=>$name, 'swatch_image'=>'', 'hex'=>$swatch, 'image'=>$image);
                                  },
                                  array_keys($swatches), $swatches, $images);

}
else if ( $display_as == 'image' ) {
  $swatch_images = $tm_meta[0]['tmfbuilder']['variations_options']['pa_colours']['variations_image'];
  $details['Colours'] = array_map(function($name, $swatch_image, $image){
                                      return (object)array('name'=>$name, 'swatch_image'=>$swatch_image, 'hex'=>'', 'image'=>$image);
                                  },
                                  array_keys($swatches), $swatch_images, $images);

}
else { //return an empty array
  $details['Colours'] = array();
}
//add the swatch type to the beginning of the array
array_unshift($details['Colours'], (object)array('swatch_type'=>$display_as)); 

Conclusion

Both the WooCommerce API and Client are rapidly evolving to facilitate many common operations. In the meantime, don’t be afraid of poking around these products’ java source files as well as the WordPress database. Usually one or the other will hold the key to extracting the data you’re after.

Robert Gravelle
Robert Gravelle
Rob Gravelle resides in Ottawa, Canada, and has been an IT guru for over 20 years. In that time, Rob has built systems for intelligence-related organizations such as Canada Border Services and various commercial businesses. In his spare time, Rob has become an accomplished music artist with several CDs and digital releases to his credit.

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Popular Articles

Featured