There is a native, handy way to get a WooCommerce customer’s last order: wc_get_customer_last_order( $customer_id )
This time, I want to write some custom code to get the second last order instead. We will indeed reuse most of the above function code and change it slightly. Enjoy!
PHP Snippet: Get WooCommerce Customer Second Last Order
Please note below the only minor difference from the “last order” code:
LIMIT 1 , 1
This gets the second last record inside the database (the second “1” is the offset).
To return the second last order, use bbloomer_get_second_last_order_cot( 123 ), where “123” is the customer ID. This snippet is already compatible with HPOS.
/**
* @snippet Get Customer Second Last Order
* @how-to Get CustomizeWoo.com FREE
* @author Rodolfo Melogli
* @compatible WooCommerce 8
* @community https://businessbloomer.com/club/
*/
use Automattic\WooCommerce\Utilities\OrderUtil;
function bbloomer_get_second_last_order_cot( $customer_id ) {
global $wpdb;
$order_statuses_sql = "( '" . implode( "','", array_map( 'esc_sql', array_keys( wc_get_order_statuses() ) ) ) . "' )";
if ( OrderUtil::custom_orders_table_usage_is_enabled() ) {
$sql = $wpdb->prepare(
'SELECT id FROM ' . OrdersTableDataStore::get_orders_table_name() . "
WHERE customer_id = %d
AND status in $order_statuses_sql
ORDER BY id DESC
LIMIT 1 , 1",
$customer_id
);
$second_last_order_id = $wpdb->get_var( $sql );
} else {
$second_last_order_id = $wpdb->get_var(
"SELECT posts.ID
FROM $wpdb->posts AS posts
LEFT JOIN {$wpdb->postmeta} AS meta on posts.ID = meta.post_id
WHERE meta.meta_key = '_customer_user'
AND meta.meta_value = '" . esc_sql( $customer_id ) . "'
AND posts.post_type = 'shop_order'
AND posts.post_status IN $order_statuses_sql
ORDER BY posts.ID DESC
LIMIT 1 , 1"
);
}
if ( ! $second_last_order_id ) {
return false;
}
return wc_get_order( absint( $second_last_order_id ) );
}