diff --git a/modules/ppcp-button/src/Endpoint/AbstractCartEndpoint.php b/modules/ppcp-button/src/Endpoint/AbstractCartEndpoint.php index d74d59c55..3133cf544 100644 --- a/modules/ppcp-button/src/Endpoint/AbstractCartEndpoint.php +++ b/modules/ppcp-button/src/Endpoint/AbstractCartEndpoint.php @@ -153,9 +153,10 @@ abstract class AbstractCartEndpoint implements EndpointInterface { /** * Handles errors. * + * @param bool $send_response If this error handling should return the response. * @return void */ - private function handle_error(): void { + protected function handle_error( bool $send_response = true ): void { $message = __( 'Something went wrong. Action aborted', @@ -173,14 +174,16 @@ abstract class AbstractCartEndpoint implements EndpointInterface { wc_clear_notices(); } - wp_send_json_error( - array( - 'name' => '', - 'message' => $message, - 'code' => 0, - 'details' => array(), - ) - ); + if ( $send_response ) { + wp_send_json_error( + array( + 'name' => '', + 'message' => $message, + 'code' => 0, + 'details' => array(), + ) + ); + } } /** @@ -259,7 +262,9 @@ abstract class AbstractCartEndpoint implements EndpointInterface { private function add_product( \WC_Product $product, int $quantity ): bool { $cart_item_key = $this->cart->add_to_cart( $product->get_id(), $quantity ); - $this->cart_item_keys[] = $cart_item_key; + if ( $cart_item_key ) { + $this->cart_item_keys[] = $cart_item_key; + } return false !== $cart_item_key; } @@ -294,7 +299,9 @@ abstract class AbstractCartEndpoint implements EndpointInterface { $variations ); - $this->cart_item_keys[] = $cart_item_key; + if ( $cart_item_key ) { + $this->cart_item_keys[] = $cart_item_key; + } return false !== $cart_item_key; } @@ -322,7 +329,9 @@ abstract class AbstractCartEndpoint implements EndpointInterface { $cart_item_key = $this->cart->add_to_cart( $product->get_id(), 1, 0, array(), $cart_item_data ); - $this->cart_item_keys[] = $cart_item_key; + if ( $cart_item_key ) { + $this->cart_item_keys[] = $cart_item_key; + } return false !== $cart_item_key; } @@ -333,6 +342,9 @@ abstract class AbstractCartEndpoint implements EndpointInterface { */ protected function remove_cart_items(): void { foreach ( $this->cart_item_keys as $cart_item_key ) { + if ( ! $cart_item_key ) { + continue; + } $this->cart->remove_cart_item( $cart_item_key ); } } diff --git a/modules/ppcp-button/src/Endpoint/SimulateCartEndpoint.php b/modules/ppcp-button/src/Endpoint/SimulateCartEndpoint.php index 5e3796dbb..ead2f4229 100644 --- a/modules/ppcp-button/src/Endpoint/SimulateCartEndpoint.php +++ b/modules/ppcp-button/src/Endpoint/SimulateCartEndpoint.php @@ -27,6 +27,13 @@ class SimulateCartEndpoint extends AbstractCartEndpoint { */ private $smart_button; + /** + * The WooCommerce real active cart. + * + * @var \WC_Cart|null + */ + private $real_cart = null; + /** * ChangeCartEndpoint constructor. * @@ -65,24 +72,14 @@ class SimulateCartEndpoint extends AbstractCartEndpoint { return false; } - // Set WC default cart as the clone. - // Store a reference to the real cart. - $active_cart = WC()->cart; - WC()->cart = $this->cart; + $this->replace_real_cart(); - if ( ! $this->add_products( $products ) ) { - return false; - } + $this->add_products( $products ); $this->cart->calculate_totals(); $total = (float) $this->cart->get_total( 'numeric' ); - // Remove from cart because some plugins reserve resources internally when adding to cart. - $this->remove_cart_items(); - - // Restore cart and unset cart clone. - WC()->cart = $active_cart; - unset( $this->cart ); + $this->restore_real_cart(); // Process filters. $pay_later_enabled = true; @@ -119,4 +116,44 @@ class SimulateCartEndpoint extends AbstractCartEndpoint { return true; } + /** + * Handles errors. + * + * @param bool $send_response If this error handling should return the response. + * @return void + * + * phpcs:disable Generic.CodeAnalysis.UselessOverridingMethod.Found + */ + protected function handle_error( bool $send_response = false ): void { + parent::handle_error( $send_response ); + } + + /** + * Replaces the real cart with the clone. + * + * @return void + */ + private function replace_real_cart() { + // Set WC default cart as the clone. + // Store a reference to the real cart. + $this->real_cart = WC()->cart; + WC()->cart = $this->cart; + } + + /** + * Restores the real cart. + * + * @return void + */ + private function restore_real_cart() { + // Remove from cart because some plugins reserve resources internally when adding to cart. + $this->remove_cart_items(); + + // Restore cart and unset cart clone. + if ( null !== $this->real_cart ) { + WC()->cart = $this->real_cart; + } + unset( $this->cart ); + } + }