Use a transaction during checkout's order creation method to ensure all data gets set

Closes #5368
This commit is contained in:
Mike Jolley 2014-06-18 16:03:46 +01:00
parent 94549e1462
commit f2ca5e76bd
1 changed files with 162 additions and 128 deletions

View File

@ -155,14 +155,20 @@ class WC_Checkout {
* create_order function.
* @access public
* @throws Exception
* @return int
* @return int|WP_ERROR
*/
public function create_order() {
global $wpdb;
// Give plugins the opportunity to create an order themselves
if ( $order_id = apply_filters( 'woocommerce_create_order', null, $this ) ) {
return $order_id;
}
try {
// Start transaction if available
$wpdb->query( 'START TRANSACTION' );
$order_data = array(
'status' => apply_filters( 'woocommerce_default_order_status', 'pending' ),
'customer_id' => $this->customer_id,
@ -179,7 +185,7 @@ class WC_Checkout {
$order = wc_update_order( $order_data );
if ( is_wp_error( $order ) ) {
throw new Exception( 'Error: Unable to update order. Please try again.' );
throw new Exception( __( 'Error: Unable to create order. Please try again.', 'woocommerce' ) );
} else {
$order->remove_order_items();
do_action( 'woocommerce_resume_order', $order_id );
@ -190,7 +196,7 @@ class WC_Checkout {
$order = wc_create_order( $order_data );
if ( is_wp_error( $order ) ) {
throw new Exception( 'Error: Unable to create order. Please try again.' );
throw new Exception( __( 'Error: Unable to create order. Please try again.', 'woocommerce' ) );
} else {
$order_id = $order->id;
do_action( 'woocommerce_new_order', $order_id );
@ -213,6 +219,10 @@ class WC_Checkout {
)
);
if ( ! $item_id ) {
throw new Exception( __( 'Error: Unable to create order. Please try again.', 'woocommerce' ) );
}
// Allow plugins to add order item meta
do_action( 'woocommerce_add_order_item_meta', $item_id, $values, $cart_item_key );
}
@ -221,6 +231,10 @@ class WC_Checkout {
foreach ( WC()->cart->get_fees() as $fee_key => $fee ) {
$item_id = $order->add_fee( $fee );
if ( ! $item_id ) {
throw new Exception( __( 'Error: Unable to create order. Please try again.', 'woocommerce' ) );
}
// Allow plugins to add order item meta to fees
do_action( 'woocommerce_add_order_fee_meta', $order_id, $item_id, $fee, $fee_key );
}
@ -230,6 +244,10 @@ class WC_Checkout {
if ( isset( $package['rates'][ $this->shipping_methods[ $package_key ] ] ) ) {
$item_id = $order->add_shipping( $package['rates'][ $this->shipping_methods[ $package_key ] ] );
if ( ! $item_id ) {
throw new Exception( __( 'Error: Unable to create order. Please try again.', 'woocommerce' ) );
}
// Allows plugins to add order item meta to shipping
do_action( 'woocommerce_add_shipping_order_item', $order_id, $item_id, $package_key );
}
@ -237,12 +255,16 @@ class WC_Checkout {
// Store tax rows
foreach ( array_keys( WC()->cart->taxes + WC()->cart->shipping_taxes ) as $tax_rate_id ) {
$order->add_tax( $tax_rate_id, WC()->cart->get_tax_amount( $tax_rate_id ), WC()->cart->get_shipping_tax_amount( $tax_rate_id ) );
if ( ! $order->add_tax( $tax_rate_id, WC()->cart->get_tax_amount( $tax_rate_id ), WC()->cart->get_shipping_tax_amount( $tax_rate_id ) ) ) {
throw new Exception( __( 'Error: Unable to create order. Please try again.', 'woocommerce' ) );
}
}
// Store coupons
foreach ( WC()->cart->get_coupons() as $code => $coupon ) {
$order->add_coupon( $code, WC()->cart->get_coupon_discount_amount( $code ) );
if ( ! $order->add_coupon( $code, WC()->cart->get_coupon_discount_amount( $code ) ) ) {
throw new Exception( __( 'Error: Unable to create order. Please try again.', 'woocommerce' ) );
}
}
// Billing address
@ -298,6 +320,15 @@ class WC_Checkout {
// Let plugins add meta
do_action( 'woocommerce_checkout_update_order_meta', $order_id, $this->posted );
// If we got here, the order was created without problems!
$wpdb->query( 'COMMIT' );
} catch ( Exception $e ) {
// There was an error adding order data!
$wpdb->query( 'ROLLBACK' );
return new WP_Error( 'checkout-error', $e->getMessage() );
}
return $order_id;
}
@ -568,6 +599,10 @@ class WC_Checkout {
$order_id = $this->create_order();
if ( is_wp_error( $order_id ) ) {
throw new Exception( $order_id->get_error_message() );
}
do_action( 'woocommerce_checkout_order_processed', $order_id, $this->posted );
// Process payment
@ -627,10 +662,9 @@ class WC_Checkout {
}
} catch ( Exception $e ) {
if ( ! empty( $e ) )
if ( ! empty( $e ) ) {
wc_add_notice( $e->getMessage(), 'error' );
}
}
} // endif