Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can not get the product details from order_id on the new order hook function

With WooCommerce, I have the following hook in my function.php after the new order is submitted:

add_action( 'woocommerce_new_order', 'create_job_openings');
function create_job_openings($order_id) {

    $order = new WC_Order($order_id);
    $items = $order->get_items();

    foreach ($order->get_items() as $key => $item) {
        $product_name = $item['name'];
        var_dump($product_name);
    }
}

The above code is not giving me any output i'e it is not entering inside the foreach loop that's why var_dump() not giving me any output, but if I mention the order_id specifically like create_job_openings($order_id=517) it works, even I tried echo $order_id before foreach loop, it is giving me the order_id, then why it is not entering the foreach loop?

note: when I try var_dump($items); before foreach loop its giving me

array(0) {
} 

Why it is not able to get the product details even if there are products in it after new order is made?

like image 972
sam Avatar asked Mar 11 '23 04:03

sam


2 Answers

Update 2 — The working solution (using an email notification hook)

The problem is when using email notification hook can fire an action 2 times, for example when a new order is made (notification for the Shop manager and notification for the customer).

You want to use this "New Order" event for Orders that are in "processing" status.

To avoid your action to be fired 2 times using New order notification WooCommerce event, we use 'customer_processing_order' instead of 'new_order' email ID (notification event).

Here we don't need to get the $order object, as we got it as an argument in this hooked function.

So here is your final functional code:

add_action( 'woocommerce_email_before_order_table', 'custom_action_on_completed_customer_email_notification', 10, 4 );
function custom_action_on_completed_customer_email_notification( $order, $sent_to_admin, $plain_text, $email ) {

    if( 'customer_processing_order' == $email->id ){ // for processing order status customer notification…
        foreach ($order->get_items() as $item_id => $item_values) {
            $product_name = $item_values['name'];
            echo $product_name;
            break; // (optional) stop loop to first item
        }
    }
}

This is the validated and working answer to this question

Related Working Answers:

  • Sending an SMS for specific email notifications and order statuses
  • Avoid repetitive emails notification on some auto completed orders
  • Change the user role on purchase for specific products when order status is completed

Update 1 (hook alternative)

Trying using woocommerce_thankyou hook, that is fired on review order after order has been processed:

add_action( 'woocommerce_thankyou', 'create_job_openings', 10, 1 );
function create_job_openings( $order_id ) {
    if ( ! $order_id )
        return;
    
    $order = wc_get_order( $order_id );
    
    foreach ($order->get_items() as $item_id => $item_values) {
        $product_name = $item_values['name'];
        var_dump($product_name);
        break; // (optional) stop loop to first item
    }
}

(Not working for the OP)


You should try this instead wc_get_order() function this way and your code will be:

add_action( 'woocommerce_new_order', 'create_job_openings', 10, 1);
function create_job_openings($order_id) {

    $order = wc_get_order( $order_id );
    $order_items = $order->get_items();

    foreach ($order_items as $item_id => $item_values) {
        $product_name = $item_values['name'];
        var_dump($product_name);
        break; // (optional) stops on first item
    }
}

You can have a look to How to get WooCommerce order details where a lot of things are explained…

(Not working for the OP)

like image 76
LoicTheAztec Avatar answered Apr 27 '23 00:04

LoicTheAztec


you can use save_post action when post is added in wordpress. for more visit: Link

function wc_order_add_action($post_id, $post, $update)
{
    $post_type = get_post_type($post_id);

    // If this isn't a 'shop_order' post, don't update it.
    if ("shop_order" != $post_type) return;

    $order = wc_get_order($post_id);

    foreach($order -> get_items() as $key => $item)
    {
        $product_name = $item['name'];
        var_dump($product_name);
    }
}
add_action('save_post', 'wc_order_add_action');
like image 29
vrajesh Avatar answered Apr 27 '23 01:04

vrajesh