0
votes

I have this code, its function is to add a column in woocommerce order details email template, but when I send an invoice I get this error message saying:

Fatal error: Uncaught Error: Call to a member function get() on null in http:\mysite.com\functions.php on line 1245

when using this code:

add_action( 'woocommerce_order_item_meta_end', 'order_custom_field_in_item_meta_end', 10, 4 );
function order_custom_field_in_item_meta_end( $item_id, $item, $order, $cart_item) {
    global $woocommerce;

    do_action( 'woocommerce_review_order_before_cart_contents' );

    foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
        $_product = apply_filters( 'woocommerce_cart_item_product', $cart_item['data'], $cart_item, $cart_item_key );

        if ( $_product && $_product->exists() && $cart_item['quantity'] > 0 && apply_filters( 'woocommerce_checkout_cart_item_visible', true, $cart_item, $cart_item_key ) ) {
            echo '<td class="td">'.$_product->get_price_html().'</td>';
        }
    }

    do_action( 'woocommerce_review_order_after_cart_contents' );

}

This is the result of the email template, I used a plugin called woocommerce email test

My problem here, is that when I send an invoice or any other email notification from the order it gets an error.

What I am doing wrong and how to solve this?

Thanks

2
Please, tell me your line 1245 in function.phpDhruvin Moradiya
@DhruvinMoradiya this is the line: foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {Francis Alvin Tan
Can you please tell me what is your requirement?Dhruvin Moradiya
actually the error only occur when I send an email invoice through order and its pointing to that line, i have used $product->get_cart() and its not working alsoFrancis Alvin Tan
I just need to display the price per product on the email template, see image aboveFrancis Alvin Tan

2 Answers

1
votes

Sorry but you can't use WC()->cart object for the orders or emails as the cart is already processed in checkout and emptied. Instead you can use the variable arguments that your function has when hooked in woocommerce_order_item_meta_end, which are $item_id, $item, $order and $plain_text

You don't need any foreach loop here to get the order items data as you can use directly $item argument to get the ID of your product.

Here is the right code that will work with simple or variable products as well (but see at the end):

add_action( 'woocommerce_order_item_meta_end', 'order_custom_field_in_item_meta_end', 10, 4 );
function order_custom_field_in_item_meta_end( $item_id, $item, $order, $plain_text ) {

    do_action( 'woocommerce_review_order_before_cart_contents' );

    if( $item['variation_id'] > 0 ){
        $product = wc_get_product($item['variation_id']); // variable product
    } else {
        $product = wc_get_product($item['product_id']); // simple product 
    }

    // Be sure to have the corresponding "Cost each" column before using <td> tag
    echo '<td class="td">'.$product->get_price_html().'</td>';

    do_action( 'woocommerce_review_order_after_cart_contents' );

}

You can't use a html <td> tag if your "Cost each" column haven't been created (or defined) before.

Code goes in function.php file of your active child theme (or theme) or also in any plugin file.

The code is tested and works.

0
votes

The problem is that the action woocommerce_order_item_meta_end is get triggered only after placing the order. so that the scope of the WC()->cart is not exists inside your code snippet.

You can use $order->get_items() to get order items.

Please modify your code this way to make it work

add_action( 'woocommerce_order_item_meta_end', 'order_custom_field_in_item_meta_end', 10, 4 );
function order_custom_field_in_item_meta_end( $item_id, $item, $order) {
    do_action( 'woocommerce_review_order_before_cart_contents' );

    foreach ( $order->get_items() as $cart_item_key => $cart_item ) {
        // Do something here
    }

    do_action( 'woocommerce_review_order_after_cart_contents' );

}