automatewoo/includes/Order_Helper.php
fei-source 47d3c9a8b6 Update to v6.2.2
Source: GrootMade/Festinger Vault
2026-03-15 08:31:15 +08:00

156 lines
3.9 KiB
PHP

<?php
namespace AutomateWoo;
/**
* @class Order_Helper
*/
class Order_Helper {
/**
* Default constructor.
*/
public function __construct() {
if ( AUTOMATEWOO_DISABLE_ASYNC_ORDER_STATUS_CHANGED ) {
// if not using async status change hook refresh customer totals before triggers fire
add_action( 'woocommerce_order_status_changed', [ $this, 'maybe_refresh_customer_totals' ], 5, 3 );
}
add_action( 'woocommerce_before_order_object_save', [ $this, 'maybe_delete_shop_order_transients' ], 10 );
}
/**
* In WC_Abstract_Order::update_status() customer totals refresh after change status hooks have fired.
* We need access to these for order triggers so manually refresh early.
* In the future order triggers could fire async which should solve this issue
*
* @param int $order_id
* @param string $old_status
* @param string $new_status
*/
public function maybe_refresh_customer_totals( $order_id, $old_status, $new_status ) {
if ( ! in_array( $new_status, [ 'completed', 'processing', 'on-hold', 'cancelled' ], true ) ) {
return;
}
$order = wc_get_order( $order_id );
if ( ! $order ) {
return;
}
$customer = Customer_Factory::get_by_order( $order );
if ( $customer ) {
$customer->delete_meta( 'order_count' );
$customer->delete_meta( 'total_spent' );
}
$user_id = $order->get_user_id();
if ( $user_id ) {
delete_user_meta( $user_id, '_money_spent' );
delete_user_meta( $user_id, '_order_count' );
delete_user_meta( $user_id, '_aw_order_count' );
delete_user_meta( $user_id, '_aw_order_ids' );
}
}
/**
* Delete transients only if some fields have changed.
*
* @param \WC_Order $order
*/
public function maybe_delete_shop_order_transients( $order ) {
// Only delete the transients if one of the following fields has changed
$changes = [
'total',
'status',
'billing',
'customer_id',
];
$new_changes = array_intersect( $changes, array_keys( $order->get_changes() ) );
if ( ! $order || empty( $new_changes ) ) {
return;
}
// If the only change is billings but not email, don't delete the transients
if ( count( $new_changes ) === 1 && isset( $order->get_changes()['billing'] ) && ! isset( $order->get_changes()['billing']['email'] ) ) {
return;
}
// If there have been changes to the customer ID or billing email, remove the transients associated with the previous customer.
if ( isset( $order->get_changes()['customer_id'] ) || ( isset( $order->get_changes()['billing']['email'] ) ) ) {
$old_order = new \WC_Order();
$old_order->set_props( $order->get_base_data() );
$this->delete_shop_order_transients( $old_order );
}
$this->delete_shop_order_transients( $order );
}
/**
* Delete transients for a shop order.
*
* @param \WC_Order $order
*/
public function delete_shop_order_transients( $order ) {
// Set $create param to false to prevent creating a new customer at this point
$customer = Customer_Factory::get_by_order( $order, false );
if ( $customer ) {
$customer->delete_meta( 'order_count' );
$customer->delete_meta( 'total_spent' );
}
$user_id = $order->get_user_id();
if ( $user_id ) {
delete_user_meta( $user_id, '_aw_order_count' );
delete_user_meta( $user_id, '_aw_order_ids' );
}
}
/**
* LEGACY - use Customer object instead of this function
*
* @deprecated
*
* @param \WC_Order $order
* @return Order_Guest|\WP_User|false
*/
public function prepare_user_data_item( $order ) {
if ( ! $order ) {
return false;
}
$user = $order->get_user();
if ( $user ) {
// ensure first and last name are set
if ( ! $user->first_name ) {
$user->first_name = $order->get_billing_first_name();
}
if ( ! $user->last_name ) {
$user->last_name = $order->get_billing_last_name();
}
if ( ! $user->billing_phone ) {
$user->billing_phone = $order->get_billing_phone();
}
} else {
// order placed by a guest
$user = new Order_Guest( $order );
}
return $user;
}
}