From a074260266a7e40334ad8a066d42074fe1dd8246 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Mon, 20 Apr 2020 14:59:17 +0100 Subject: [PATCH] Revert "Improvements to REST API performance (https://github.com/woocommerce/woocommerce-blocks/pull/2248)" (https://github.com/woocommerce/woocommerce-blocks/pull/2259) This reverts commit 30c0182fbe1e4f0f99b4b70633dc4420a4d6c1af. --- .../src/Domain/Bootstrap.php | 65 ++++----------- plugins/woocommerce-blocks/src/Library.php | 83 +++++++++++++++++++ plugins/woocommerce-blocks/src/RestApi.php | 75 +++-------------- .../Routes/CartSelectShippingRate.php | 2 - .../StoreApi/Utilities/OrderController.php | 5 -- 5 files changed, 111 insertions(+), 119 deletions(-) diff --git a/plugins/woocommerce-blocks/src/Domain/Bootstrap.php b/plugins/woocommerce-blocks/src/Domain/Bootstrap.php index 3f9ca07074e..c3c16d26125 100644 --- a/plugins/woocommerce-blocks/src/Domain/Bootstrap.php +++ b/plugins/woocommerce-blocks/src/Domain/Bootstrap.php @@ -12,12 +12,13 @@ use Automattic\WooCommerce\Blocks\Assets\Api as AssetApi; use Automattic\WooCommerce\Blocks\Assets\AssetDataRegistry; use Automattic\WooCommerce\Blocks\Assets\BackCompatAssetDataRegistry; use Automattic\WooCommerce\Blocks\Assets\PaymentMethodAssets; -use Automattic\WooCommerce\Blocks\Library; use Automattic\WooCommerce\Blocks\Payments\PaymentMethodRegistry; -use Automattic\WooCommerce\Blocks\Payments\Integrations\Stripe; -use Automattic\WooCommerce\Blocks\Payments\Integrations\Cheque; +use Automattic\WooCommerce\Blocks\Library; use Automattic\WooCommerce\Blocks\Registry\Container; use Automattic\WooCommerce\Blocks\RestApi; +use Automattic\WooCommerce\Blocks\Payments\Integrations\Stripe; +use Automattic\WooCommerce\Blocks\Payments\Integrations\Cheque; + /** * Takes care of bootstrapping the plugin. @@ -64,40 +65,14 @@ class Bootstrap { } $this->remove_core_blocks(); - $this->add_build_notice(); + + if ( ! $this->is_built() ) { + $this->add_build_notice(); + } + $this->define_feature_flag(); - $this->define_tables(); - Library::init(); - RestApi::init(); - - if ( ! wc()->is_rest_api_request() ) { - $this->init_block_assets(); - $this->init_payment_method_assets(); - OldAssets::init(); - } - } - /** - * Define tables in $wpdb; - */ - protected function define_tables() { - global $wpdb; - - // List of tables without prefixes. - $tables = array( - 'wc_reserved_stock' => 'wc_reserved_stock', - ); - - foreach ( $tables as $name => $table ) { - $wpdb->$name = $wpdb->prefix . $table; - $wpdb->tables[] = $table; - } - } - - /** - * Add asset classes to the container during init. - */ - protected function init_block_assets() { + // register core dependencies with the container. $this->container->register( AssetApi::class, function ( Container $container ) { @@ -115,14 +90,6 @@ class Bootstrap { : new AssetDataRegistry( $asset_api ); } ); - // load AssetDataRegistry. - $this->container->get( AssetDataRegistry::class ); - } - - /** - * Add payment method classes to the container during init. - */ - protected function init_payment_method_assets() { $this->container->register( PaymentMethodRegistry::class, function( Container $container ) { @@ -137,10 +104,18 @@ class Bootstrap { return new PaymentMethodAssets( $payment_method_registry, $asset_data_registry ); } ); + + // load AssetDataRegistry. + $this->container->get( AssetDataRegistry::class ); + // load PaymentMethodAssets. $this->container->get( PaymentMethodAssets::class ); $this->load_payment_method_integrations(); + + Library::init(); + OldAssets::init(); + RestApi::init(); } /** @@ -167,9 +142,6 @@ class Bootstrap { * Add a notice stating that the build has not been done yet. */ protected function add_build_notice() { - if ( $this->is_built() ) { - return; - } add_action( 'admin_notices', function() { @@ -252,6 +224,5 @@ class Bootstrap { ); } ); - add_action( 'init', [ $this->container->get( PaymentMethodRegistry::class ), 'initialize' ] ); } } diff --git a/plugins/woocommerce-blocks/src/Library.php b/plugins/woocommerce-blocks/src/Library.php index c9fcd9291cc..c153f1dbdcd 100644 --- a/plugins/woocommerce-blocks/src/Library.php +++ b/plugins/woocommerce-blocks/src/Library.php @@ -9,6 +9,11 @@ namespace Automattic\WooCommerce\Blocks; defined( 'ABSPATH' ) || exit; +use Automattic\WooCommerce\Blocks\Payments\PaymentResult; +use Automattic\WooCommerce\Blocks\Payments\PaymentContext; +use Automattic\WooCommerce\Blocks\Payments\PaymentMethodRegistry; +use Automattic\WooCommerce\Blocks\RestApi\StoreApi\Utilities\NoticeHandler; + /** * Library class. */ @@ -19,12 +24,32 @@ class Library { */ public static function init() { add_action( 'init', array( __CLASS__, 'register_blocks' ) ); + add_action( 'init', array( __CLASS__, 'register_payment_methods' ) ); + add_action( 'init', array( __CLASS__, 'define_tables' ) ); add_action( 'init', array( __CLASS__, 'maybe_create_tables' ) ); add_action( 'init', array( __CLASS__, 'maybe_create_cronjobs' ) ); add_filter( 'wc_order_statuses', array( __CLASS__, 'register_draft_order_status' ) ); add_filter( 'woocommerce_register_shop_order_post_statuses', array( __CLASS__, 'register_draft_order_post_status' ) ); add_filter( 'woocommerce_valid_order_statuses_for_payment', array( __CLASS__, 'append_draft_order_post_status' ) ); add_action( 'woocommerce_cleanup_draft_orders', array( __CLASS__, 'delete_expired_draft_orders' ) ); + add_action( 'woocommerce_rest_checkout_process_payment_with_context', array( __CLASS__, 'process_legacy_payment' ), 999, 2 ); + } + + /** + * Register custom tables within $wpdb object. + */ + public static function define_tables() { + global $wpdb; + + // List of tables without prefixes. + $tables = array( + 'wc_reserved_stock' => 'wc_reserved_stock', + ); + + foreach ( $tables as $name => $table ) { + $wpdb->$name = $wpdb->prefix . $table; + $wpdb->tables[] = $table; + } } /** @@ -115,6 +140,13 @@ class Library { } } + /** + * Register payment methods. + */ + public static function register_payment_methods() { + Package::container()->get( PaymentMethodRegistry::class )->initialize(); + } + /** * Register custom order status for orders created via the API during checkout. * @@ -177,4 +209,55 @@ class Library { " ); } + + /** + * Attempt to process a payment for the checkout API if no payment methods support the + * woocommerce_rest_checkout_process_payment_with_context action. + * + * @param PaymentContext $context Holds context for the payment. + * @param PaymentResult $result Result of the payment. + */ + public static function process_legacy_payment( PaymentContext $context, PaymentResult &$result ) { + if ( $result->status ) { + return; + } + + // phpcs:ignore WordPress.Security.NonceVerification + $post_data = $_POST; + + // Set constants. + wc_maybe_define_constant( 'WOOCOMMERCE_CHECKOUT', true ); + + // Add the payment data from the API to the POST global. + $_POST = $context->payment_data; + + // Call the process payment method of the chosen gatway. + $payment_method_object = $context->get_payment_method_instance(); + + if ( ! $payment_method_object instanceof \WC_Payment_Gateway ) { + return; + } + + $payment_method_object->validate_fields(); + + // If errors were thrown, we need to abort. + NoticeHandler::convert_notices_to_exceptions( 'woocommerce_rest_payment_error' ); + + // Process Payment. + $gateway_result = $payment_method_object->process_payment( $context->order->get_id() ); + + // Restore $_POST data. + $_POST = $post_data; + + // If `process_payment` added notices, clear them. Notices are not displayed from the API -- payment should fail, + // and a generic notice will be shown instead if payment failed. + wc_clear_notices(); + + // Handle result. + $result->set_status( isset( $gateway_result['result'] ) && 'success' === $gateway_result['result'] ? 'success' : 'failure' ); + + // set payment_details from result. + $result->set_payment_details( array_merge( $result->payment_details, $gateway_result ) ); + $result->set_redirect_url( $gateway_result['redirect'] ); + } } diff --git a/plugins/woocommerce-blocks/src/RestApi.php b/plugins/woocommerce-blocks/src/RestApi.php index 03fefd80c2e..a51935e7ea5 100644 --- a/plugins/woocommerce-blocks/src/RestApi.php +++ b/plugins/woocommerce-blocks/src/RestApi.php @@ -11,10 +11,6 @@ defined( 'ABSPATH' ) || exit; use \Automattic\WooCommerce\Blocks\RestApi\StoreApi\RoutesController; use \Automattic\WooCommerce\Blocks\RestApi\StoreApi\SchemaController; -use \Automattic\WooCommerce\Blocks\Payments\PaymentResult; -use \Automattic\WooCommerce\Blocks\Payments\PaymentContext; -use \Automattic\WooCommerce\Blocks\Payments\PaymentMethodRegistry; -use \Automattic\WooCommerce\Blocks\RestApi\StoreApi\Utilities\NoticeHandler; /** * RestApi class. @@ -28,7 +24,6 @@ class RestApi { add_action( 'rest_api_init', array( __CLASS__, 'register_rest_routes' ), 10 ); add_filter( 'rest_authentication_errors', array( __CLASS__, 'maybe_init_cart_session' ), 1 ); add_filter( 'rest_authentication_errors', array( __CLASS__, 'store_api_authentication' ) ); - add_action( 'woocommerce_rest_checkout_process_payment_with_context', array( __CLASS__, 'process_legacy_payment' ), 999, 2 ); } /** @@ -109,18 +104,19 @@ class RestApi { * @return mixed */ public static function maybe_init_cart_session( $return ) { - if ( ! function_exists( 'wc_load_cart' ) || \is_wp_error( $return ) || ! self::is_request_to_store_api() ) { + $wc_instance = wc(); + // if WooCommerce instance isn't available or already have an + // authentication error, just return. + if ( ! method_exists( $wc_instance, 'initialize_session' ) || \is_wp_error( $return ) || ! self::is_request_to_store_api() ) { return $return; } - // @todo Core should ensure these functions load with wc_load_cart(). See https://github.com/woocommerce/woocommerce/pull/26219 - include_once WC_ABSPATH . 'includes/wc-cart-functions.php'; - include_once WC_ABSPATH . 'includes/wc-notice-functions.php'; + $wc_instance->frontend_includes(); + $wc_instance->initialize_session(); + $wc_instance->initialize_cart(); - // Initializes the cart and session. - wc_load_cart(); - - // @todo Core should also do this inside wc_load_cart so the cart is loaded from session. See https://github.com/woocommerce/woocommerce/pull/26219 - wc()->cart->get_cart(); + // Ensure cart is up to date. + $wc_instance->cart->calculate_shipping(); + $wc_instance->cart->calculate_totals(); return $return; } @@ -141,55 +137,4 @@ class RestApi { 'product-reviews' => __NAMESPACE__ . '\RestApi\Controllers\ProductReviews', ]; } - - /** - * Attempt to process a payment for the checkout API if no payment methods support the - * woocommerce_rest_checkout_process_payment_with_context action. - * - * @param PaymentContext $context Holds context for the payment. - * @param PaymentResult $result Result of the payment. - */ - public static function process_legacy_payment( PaymentContext $context, PaymentResult &$result ) { - if ( $result->status ) { - return; - } - - // phpcs:ignore WordPress.Security.NonceVerification - $post_data = $_POST; - - // Set constants. - wc_maybe_define_constant( 'WOOCOMMERCE_CHECKOUT', true ); - - // Add the payment data from the API to the POST global. - $_POST = $context->payment_data; - - // Call the process payment method of the chosen gatway. - $payment_method_object = $context->get_payment_method_instance(); - - if ( ! $payment_method_object instanceof \WC_Payment_Gateway ) { - return; - } - - $payment_method_object->validate_fields(); - - // If errors were thrown, we need to abort. - NoticeHandler::convert_notices_to_exceptions( 'woocommerce_rest_payment_error' ); - - // Process Payment. - $gateway_result = $payment_method_object->process_payment( $context->order->get_id() ); - - // Restore $_POST data. - $_POST = $post_data; - - // If `process_payment` added notices, clear them. Notices are not displayed from the API -- payment should fail, - // and a generic notice will be shown instead if payment failed. - wc_clear_notices(); - - // Handle result. - $result->set_status( isset( $gateway_result['result'] ) && 'success' === $gateway_result['result'] ? 'success' : 'failure' ); - - // set payment_details from result. - $result->set_payment_details( array_merge( $result->payment_details, $gateway_result ) ); - $result->set_redirect_url( $gateway_result['redirect'] ); - } } diff --git a/plugins/woocommerce-blocks/src/RestApi/StoreApi/Routes/CartSelectShippingRate.php b/plugins/woocommerce-blocks/src/RestApi/StoreApi/Routes/CartSelectShippingRate.php index 7099cfc7ea8..1476d8a0983 100644 --- a/plugins/woocommerce-blocks/src/RestApi/StoreApi/Routes/CartSelectShippingRate.php +++ b/plugins/woocommerce-blocks/src/RestApi/StoreApi/Routes/CartSelectShippingRate.php @@ -80,8 +80,6 @@ class CartSelectShippingRate extends AbstractCartRoute { throw new RouteException( $e->getErrorCode(), $e->getMessage(), $e->getCode() ); } } - - $cart->calculate_shipping(); $cart->calculate_totals(); return rest_ensure_response( $this->schema->get_item_response( $cart ) ); diff --git a/plugins/woocommerce-blocks/src/RestApi/StoreApi/Utilities/OrderController.php b/plugins/woocommerce-blocks/src/RestApi/StoreApi/Utilities/OrderController.php index 15bf4f7fe7b..63191146d6f 100644 --- a/plugins/woocommerce-blocks/src/RestApi/StoreApi/Utilities/OrderController.php +++ b/plugins/woocommerce-blocks/src/RestApi/StoreApi/Utilities/OrderController.php @@ -50,11 +50,6 @@ class OrderController { * @param \WC_Order $order The order object to update. */ public function update_order_from_cart( \WC_Order $order ) { - // Ensure cart is current. - wc()->cart->calculate_shipping(); - wc()->cart->calculate_totals(); - - // Update the current order to match the current cart. $this->update_line_items_from_cart( $order ); $this->update_addresses_from_cart( $order ); $order->set_currency( get_woocommerce_currency() );