Woocommerce: Updating A Product Before It is Displayed Or Added To Cart

Summary:

In this blog post we are going to look at the hook and filter that we can add to update a product when it's page is opened and before it is added to cart. You might do that for several reasons; personally I have had to do it because my stock is managed by a third party and I need to update it or validate the stock before a purchase.

Note: This post applies to Woocommerce Version: 3.0.x, it might not work as expected if you are using a previous version.

Short Steps:

1. Define a function to modify a product or/and validate some criteria
2. add_action( 'woocommerce_before_single_product_summary', 'the_function', 10 );
3. add_filter( 'woocommerce_add_to_cart_validation', 'the_validate_function', 10, 5 );

Woocommerce Internal API Documentation

Browse and research the woocommerce internal api docs https://docs.woocommerce.com/wc-apidocs/ . Here you will be able to find all the relevant functions, objects, hooks etc.

For our use-case we are going to update our stock when a user clicks on the product or before he adds it to cart.

Simple Plugin/Hooks/Filters

It is always a wise decision to make a child theme or a simple plugin to do your development. You can always disable/enable or migrate your code. For the purpose of this tutorial we are going to just make a folder in our wp-content/plugins and slap in a updateproduct.php file without any description. This is bad practice and you should learn about the proper way to do it here when you have the time https://developer.wordpress.org/plugins/intro/

Hooks

Forgive my poor mspaint skills

Just to be clear we are going to use 2 hooks: 
One action woocommerce_before_single_product_summary and 
One filter woocommerce_add_to_cart_validation


woocommerce_before_single_product_summary 

Inside your updateproduct.php you can start by defining a minimum structure as follows:
<?php
/*
Plugin Name: Update Product
*/

function act_update_product() {
    try{
        global $product;
        global $woocommerce;
        $product->set_stock_quantity(rand(10,100));
        $product->set_price(rand(10,100));
        $product->set_sale_price(rand(10,100));
        $product->set_regular_price(rand(10,100));
        $product->save();
    }
    catch(Exception $exception){
        error_log("Update Product Action: ".$exception);
    }
}
add_action( 'woocommerce_before_single_product_summary', 'act_update_product', 10 );
?>
Important things to notice is that you need to declare $woocommerce and the $product. Once you have the product you have all the access required to do any kind of modification that you want to the product. There is a lot more than you can do, check the doc https://docs.woocommerce.com/wc-apidocs/class-WC_Product_Simple.html

Second important thing to notice is the try catch. I have no idea whether this is good practice or not but this is what I usually do even on development servers because I hate crashes even if I will be 
tail -f /var/log/apache2/error.log most of the time. Also error_log function logs to, you guessed it, the error log.

woocommerce_add_to_cart_validation

<?php
function fil_validate_product( $passed, $product_id) {
    $passed = true;
    try{
        global $woocommerce;
        $product = wc_get_product( $product_id ); //unlike above you might have to get the product from it's id
        $random_number = rand(0,100);
        if ($random_number < 50){
            $passed = false;
            wc_add_notice( __( 'Random Stopping You From Checking Out Hah!', 'textdomain' ), 'error' );
        }
    }catch(Exception $exception){
        error_log("Update Product Action: ".$exception);
    }
    return $passed;
}
add_filter( 'woocommerce_add_to_cart_validation', 'fil_validate_product', 10, 2 );
?>

The add_filter method definition is as follows:

add_filter( string $tagcallable $function_to_addint $priority = 10,int $accepted_args = 1 )

For example if you need more parameters like quantity
add_filter( 'woocommerce_add_to_cart_validation', 'fil_validate_product', 10, 3 );

function fil_validate_product( $passed, $product_id, $quantity) 

Other important points to notice:
1. We have the product id(not sure if there is a way to get the product directly) from which we can get the product.
2. Notice that the function returns a boolean based on which add to cart is going to fail or succeed.
3. The Red and Green bar that you see is the wc_add_notice used.

Final Words

And I hope that you can kickstart development using the code. 
Thank you for reading and please comment if you are having any kind of trouble!

Comments

Popular Posts