WooCommerce

Cleanup session in WooCommerce

There are some pretty simple ways to clear a session with WooCommerce that can be used with code when you need a user to get a brand new session with nothing old getting in the way. Can be used if you by code set a country or currency that’s not the WooCommerce default for example.

The most brutal (and sometimes most officiant way) is to destroy the session completely.

WC()->session->destroy_session()

https://woocommerce.github.io/code-reference/classes/WC-Session-Handler.html#method_destroy_session

This line cleans the session and clears the cookies for you and should be called early in WordPress since it tampers with cookies and session variables. For example:

// clear WC session if argument do_cleanup is true is passed
add_action( 'wp_loaded', 'my_cleanup_session');
function my_cleanup_session() {
  if ($_REQUEST['do_cleanup'] == 'true') {
    // cleanup old session
    WC()->session->destroy_session();
    // force redirect (needed in some cases) 
    //wp_safe_redirect( '/' );
  }
}

There are other alternatives as well if you don’t need to completely destroy the session. You could try one of these instead:

// clears session, but keeps cookies
WC()->session->cleanup_session()

// clear specific users session
WC()->session->delete_session($customer_id)

// forgets the session without destroying it
WC()->session->forget_session()

Check for more details in the code reference.

Check if one variation is enabled or disabled in WooCommerce

One of my clients had the need to sometime disable one variation of many, but to avoid deleting and adding again they use en little checkbox Enable in the variation setting. Really simple!

But not equally simple to find out how to check that status in code it turned out. But after digging in the WooCommerce source I found out it uses the actual status of the “product”, i.e. every variation is kind of a product, but with a parent and some other stuff. So this is how you check that Enable checkbox:

$variation = wc_get_product($variation_id);
if ($variation->get_status( 'edit' ) == 'publish') {
  // do something if enabled
}
if ($variation->get_status( 'edit' ) == 'private') {
  // do something if NOT enabled
}       

So as you can see, the code is REALLY simple, a smart way of the WooCommerce team to reuse already built functionality. But it took a little while to find after googling for attributes, properties, meta-data and other stuff. Not so much on the web on this topic.

WooCommerce – really slow wc_get_product_class

In my investigation and work to make WooCommerce perform a little bit better i found this little surprise! The little helper wc_get_product_class to print correct class names in the wrapper element in html for me took over 100ms per product. With over 100 products it’s really bad! I have quite complex products with many variations. But REALLY slowing down.

So this little code is now removed from my code.

wc_get_product_class('my-product', $product)

Yes, for me this was a good solution. I just added “product” as class instead. And saved 100ms per product! Good enough for my purpose, but it might not be sufficient for everyone.

If you don’t overwrite the product with a template, here is one way that might help you override this:

add_filter( 'woocommerce_attribute_taxonomies', 'remove_slowdowns_caused_by_taxonomies', 10, 1); function remove_slowdowns_caused_by_taxonomies($attribute_taxonomies){ return array('product'); }

Or read more here for more solutions:

https://github.com/woocommerce/woocommerce/issues/20262

WooCommerce – find default variation performance

My shop page was very slow when I had over 100 products, REALLY slow. So I had to investigate what happened. So here are some points.

Find default variation

One thing I did for every product was to find the default variation to show correct image, and the code I used was this. My products have 15 variations, and this was really bad for performance.

$default_attributes = $product->get_default_attributes();
$available_variations = $product->get_available_variations();

foreach($available_variations as $variation_values ) {
  $found_variations = 0;
  foreach($default_attributes as $key => $default_attribute_value ) {
                
    if ($variation_values['attributes']['attribute_'.$key] == $default_attribute_value) {
      $found_variations++;
    }
  }
  // return variation_id if found all of the default variations 
  if (count($default_attributes) == $found_variations) {
    return $variation_values['variation_id'];
  }
}

Instead i found the neat little function find_matching_product_variation, so instead of the nested foreach loops, I use the Data_Store_CPT to do the same.

$default_attributes = $product->get_default_attributes();
$attributes = [];
foreach ($default_attributes as $key => $value) {
  $attributes['attribute_'.$key] = $value;
}
return (new \WC_Product_Data_Store_CPT())->find_matching_product_variation(
        new \WC_Product($product->get_id()),
        $attributes
);

The same procedure that on my machine in the first foreach loops took 70-90 ms now take around 2 ms instead!

WooCommerce zero trimming decimal

I found this little neat thing when messing around with decimals in WooCommerce.

// Trim only when decimal is zero in price
add_filter( 'woocommerce_price_trim_zeros', '__return_true' );

Nice of them to provide this little filter! But even better if it was a setting in wp-admin, but until that is added, this is a quite simple solution. Just put the above code in your functions.php.

If you can’t access your functions.php or don’t know howto do it, there is of course a plugin for that. It’s made by Therichpost, and it only does exactly the above small filter snippet above. So really simple and not bloated with other crap 😉