From cc9d558a31f3530d0ade5a1397cbd25573465f79 Mon Sep 17 00:00:00 2001 From: Alex Jones Date: Fri, 9 Aug 2024 20:18:21 +0100 Subject: [PATCH] Fix emptying cart issue for custom order statuses (#44515) * fix: add filter for pre payment order statuses * chore: resolve linting issue * chore: remove comment * chore: add filter comment block * chore: resolve linting issue * fix: replace pre payment status filter with clear cart boolean filter * chore: resolve linting issue * refactor: remove double negation in check Co-authored-by: Leif Singer * tweak changelog message * rename changelog file * tweak changelog format * fix: rework wc_clear_cart_after_payment to clear the cart at the end * fix: remove order as param for clear cart after payment filter * Linting/whitespace. * fix: add after payment flag to prevent calling filter unnecessarily --------- Co-authored-by: Leif Singer Co-authored-by: Barry Hughes <3594411+barryhughes@users.noreply.github.com> --- ...oocommerce-should-clear-cart-after-payment | 5 +++ .../includes/wc-cart-functions.php | 34 +++++++++++++++---- 2 files changed, 33 insertions(+), 6 deletions(-) create mode 100644 plugins/woocommerce/changelog/add-filter-woocommerce-should-clear-cart-after-payment diff --git a/plugins/woocommerce/changelog/add-filter-woocommerce-should-clear-cart-after-payment b/plugins/woocommerce/changelog/add-filter-woocommerce-should-clear-cart-after-payment new file mode 100644 index 00000000000..765d96fd31d --- /dev/null +++ b/plugins/woocommerce/changelog/add-filter-woocommerce-should-clear-cart-after-payment @@ -0,0 +1,5 @@ +Significance: patch +Type: tweak + +Add the `woocommerce_should_clear_cart_after_payment` filter to influence whether the cart should be cleared after payment. + diff --git a/plugins/woocommerce/includes/wc-cart-functions.php b/plugins/woocommerce/includes/wc-cart-functions.php index b2fb32db9a7..cb14a9f2cf4 100644 --- a/plugins/woocommerce/includes/wc-cart-functions.php +++ b/plugins/woocommerce/includes/wc-cart-functions.php @@ -170,6 +170,10 @@ function wc_format_list_of_items( $items ) { function wc_clear_cart_after_payment() { global $wp; + $should_clear_cart_after_payment = false; + $after_payment = false; + + // If the order has been received, clear the cart. if ( ! empty( $wp->query_vars['order-received'] ) ) { $order_id = absint( $wp->query_vars['order-received'] ); @@ -179,21 +183,39 @@ function wc_clear_cart_after_payment() { $order = wc_get_order( $order_id ); if ( $order instanceof WC_Order && hash_equals( $order->get_order_key(), $order_key ) ) { - WC()->cart->empty_cart(); + $should_clear_cart_after_payment = true; + $after_payment = true; } } } - if ( is_object( WC()->session ) && WC()->session->order_awaiting_payment > 0 ) { + // If the order is awaiting payment, and we haven't already decided to clear the cart, check the order status. + if ( is_object( WC()->session ) && WC()->session->order_awaiting_payment > 0 && ! $should_clear_cart_after_payment ) { $order = wc_get_order( WC()->session->order_awaiting_payment ); if ( $order instanceof WC_Order && $order->get_id() > 0 ) { - // If the order has not failed, or is not pending, the order must have gone through. - if ( ! $order->has_status( array( 'failed', 'pending', 'cancelled' ) ) ) { - WC()->cart->empty_cart(); - } + // If the order status is neither pending, failed, nor cancelled, the order must have gone through. + $should_clear_cart_after_payment = ! $order->has_status( array( 'failed', 'pending', 'cancelled' ) ); + $after_payment = true; } } + + // If it doesn't look like a payment happened, bail early. + if ( ! $after_payment ) { + return; + } + + /** + * Determine whether the cart should be cleared after payment. + * + * @since 9.3.0 + * @param bool $should_clear_cart_after_payment Whether the cart should be cleared after payment. + */ + $should_clear_cart_after_payment = apply_filters( 'woocommerce_should_clear_cart_after_payment', $should_clear_cart_after_payment ); + + if ( $should_clear_cart_after_payment ) { + WC()->cart->empty_cart(); + } } add_action( 'template_redirect', 'wc_clear_cart_after_payment', 20 );