How to get order object in my filter hook

Viewed 252

I have some difficulties to get something simple like the order object in my code. This is how it SHOULD work.

But for some reason, I don't get the order object, (it is NULL) out of this filter, so I think I have to get it myself. But here, I am stuck :(

I am testing it by clicking on "Recalculate sums" in the order - it should then remove or add the taxes to the order. It works when I just return true in my filter but I need some more logic.

add_filter("woocommerce_order_is_vat_exempt", 'tax_exempted_user');

function tax_exempted_user(){
    global $order; // returns NULL
    $user = $order->get_user();
    if( $user->get_id() && get_field( 'field_60dd7434e8426', 'user_' . $user->get_id() ) == true )  {
       return true;
    } else {
       return false;
    }
}
1 Answers

There is no global order object in WooCommerce at this point. If you check the WooCommerce code where the hook gets applied, you would have seen this without spending your time asking a question you can answer yourself!

wp-content/plugins/woocommerce/includes/abstracts/abstract-wc-order.php | line 1562

$is_vat_exempt = apply_filters( 'woocommerce_order_is_vat_exempt', 'yes' === $this->get_meta( 'is_vat_exempt' ), $this );

Since the class defined in this file is an abstract class of an order, $this is your $order since it's referencing the object/class.

As a recommendation, I would suggest you checkout filters and hooks in the WordPress developer documentation. Normally you find a lot of answers there:

https://developer.wordpress.org/reference/functions/add_filter/ https://developer.wordpress.org/reference/functions/add_action/

Also, you can just search where the hooks get applied in your IDE with the knowledge from the documentation links above in the future.

So instead, you code needs to be changed to this:

add_filter( 'woocommerce_order_is_vat_exempt', 'filter_woocommerce_order_is_vat_exempt', 10, 2 );
function filter_woocommerce_order_is_vat_exempt( bool $is_exempt, WC_Order $order ) {
    $user = $order->get_user();
    
    error_log( $order->get_id() ); // <-- Check error log for the id of an order - this way you can be sure its working

    if ( $user->get_id() && get_field( 'field_60dd7434e8426', 'user_' . $user->get_id() ) == true ) {
        return true;
    } else {
        return false;
    }
}

You can remove the error_log() function again when you are sure everything works. If you don't know how to enable or use logging on WordPress during your development, you can check out this source:

https://wordpress.org/support/article/debugging-in-wordpress/

Related