phpwordpresswoocommerceproductstock

Get the product ID from woocommerce_add_to_cart action hook


I do not understand how to pass the current post's ID to a hook custom function.

The scenario in the code is this: upon adding a simple product ID=13 then the stock level of two other products (ID = 14 & 15) is decreased programmatically.

This IDs and quantities are extracted from a bespoke SQL table (not meta data) using an SQL query.

This query returns an array only element array[0 & 1][0] is the ID, element [1] the quantity

array(2) { [0]=> array(3) { [0]=> string(2) "14" [1]=> string(1) "5" [2]=> string(1) "5" } [1]=> array(3) { [0]=> string(2) "15" [1]=> string(1) "2" [2]=> string(1) "8" } }

The code

add_action( 'woocommerce_add_to_cart', 'wiz_stock_deduct', 10, 1 );


function wiz_stock_deduct( $product ) 
{
    // retrieve the parts in an array WP query
    $thispost_id = $product->ID;

    // retrieve parts and quantities
    $parts = wiz_checkpoststock ($thispost_id);

    if ($parts) 
    {
        for($i=0; $i < count($parts); $i++)
        {
            $part_id = $parts[$i][0];
            $part_quant = $parts[$i][1];
            // adjust quantity in stock
            //change_part_stock_ammounts ($part_id, $part_quant, 1);
            wc_update_product_stock($part_id, $part_quant, 'decrease', false);
        }       
    }   
}

Adding this array manually $parts[] into the code works. Also adding $thispost_id = 13;, works.

I assume that the SQL search is returning an empty array.

How do I Get the product ID added to cart?


Solution

  • There is a mistake in your code for woocommerce_add_to_cart action hook (located line 1287):

    do_action( 'woocommerce_add_to_cart', $cart_item_key, $product_id, $quantity, $variation_id, $variation, $cart_item_data );
    

    As you can see, the first hook argument is $cart_item_key (but not the WC_Product object). That's why you are not able to get the product ID. You can get directly the product ID from $product_id (or $variation_id) argument.

    Try the following revised code instead;

    add_action( 'woocommerce_add_to_cart', 'wiz_stock_deduct', 10, 4 );
    function wiz_stock_deduct( $cart_item_key, $product_id, $quantity, $variation_id ) {
        // Get related product data (ID and stock quantity)
        if ( $parts = wiz_checkpoststock( $product_id ) ) 
        {
            // Loop through related products data (ID and stock quantity)
            foreach( $parts as $key => $values )
            {
                if ( isset($values[0], $values[1]) ) 
                {
                    // Adjust stock quantity of related products
                    wc_update_product_stock( intval($values[0]), intval($values[1]), 'decrease', false);
                } 
            }       
        }   
    }
    

    Code goes in functions.php file of your child theme (or in a plugin). It should work.


    To handle variable products with product variations (stock managed at variation level):

    If you are using variable products (with stock managed at product variation level), and you want to update the related variations stock quantity, replace the code line:

    if ( $parts = wiz_checkpoststock( $product_id ) ) 
    

    with the following:

    if ( $parts = wiz_checkpoststock( $variation_id ?: $product_id ) ) 
    

    This way, your code will handle both simple and variable products.