Search code examples
phpwordpresswoocommercemetadataorders

Get last old order status before updated status in Woocommerce


I'm currently looking for a way to get the order status before an updated order status.


So for example my order has the status in-progress and I change the order status programmatically with this function here to wc-completed:

$order->update_status( 'wc-completed' );

When the order status is wc-completed I've a trigger which sends an email. But I need to check now if the status before the current one was in-progress. If this is true, I need to skip the trigger:

$latest_status = get_order_status_before_current_one($order_id);
if ($latest_status !== 'in-progress') {
    // Triggers for this email.
    add_action( 'woocommerce_order_status_completed_notification', array( $this, 'trigger' ), 1, 2 );
}

How can I reach this?


Solution

  • For that before updating the order status with $order->update_status( 'wc-completed' );, you will need to add a kind of status history on each status change event, using the following:

    add_action( 'woocommerce_order_status_changed', 'grab_order_old_status', 10, 4 );
    function grab_order_old_status( $order_id, $status_from, $status_to, $order ) {
        if ( $order->get_meta('_old_status') ) {
            // Grab order status before it's updated
            update_post_meta( $order_id, '_old_status', $status_from );
        } else {
            // Starting status in Woocommerce (empty history)
            update_post_meta( $order_id, '_old_status', 'pending' );
        }
    }
    

    Code goes in function.php file of your active child theme (or active theme). Tested and works.


    USAGE - Then now you can use one of the following IF statements (with the Order ID):

    if( get_post_meta( $order_id, '_old_status', true ) !== 'in-progress' ) { 
        // Your code
    }
    

    Or (with the Order Object):

    if( $order->get_meta('_old_status') !== 'in-progress' ) { 
        // Your code
    }