From 30ecea188f0cc10ab0b612da4aa5a0990a33960d Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Mon, 27 Apr 2020 16:51:50 +0100 Subject: [PATCH] Avoid loading Assets API during REST requests (https://github.com/woocommerce/woocommerce-blocks/pull/2286) * Move is built to method * Moved payment related logic into single controller class for better organization * Only load assets on non-rest requests --- plugins/woocommerce-blocks/src/Assets.php | 11 +- .../src/Assets/PaymentMethodAssets.php | 83 ------- .../src/BlockTypes/Checkout.php | 7 +- .../src/Domain/Bootstrap.php | 208 ++++++++---------- plugins/woocommerce-blocks/src/Library.php | 10 - .../woocommerce-blocks/src/Payments/Api.php | 155 +++++++++++++ .../src/Payments/PaymentMethodRegistry.php | 49 +++++ plugins/woocommerce-blocks/src/RestApi.php | 103 +++------ 8 files changed, 329 insertions(+), 297 deletions(-) delete mode 100644 plugins/woocommerce-blocks/src/Assets/PaymentMethodAssets.php create mode 100644 plugins/woocommerce-blocks/src/Payments/Api.php diff --git a/plugins/woocommerce-blocks/src/Assets.php b/plugins/woocommerce-blocks/src/Assets.php index 750c0a337de..8331731c77d 100644 --- a/plugins/woocommerce-blocks/src/Assets.php +++ b/plugins/woocommerce-blocks/src/Assets.php @@ -7,10 +7,10 @@ namespace Automattic\WooCommerce\Blocks; -use Automattic\WooCommerce\Blocks\Assets\PaymentMethodAssets; - defined( 'ABSPATH' ) || exit; +use Automattic\WooCommerce\Blocks\Package; + /** * Assets class. */ @@ -72,8 +72,7 @@ class Assets { self::register_script( 'wc-price-filter', plugins_url( self::get_block_asset_build_path( 'price-filter' ), __DIR__ ), $block_dependencies ); self::register_script( 'wc-attribute-filter', plugins_url( self::get_block_asset_build_path( 'attribute-filter' ), __DIR__ ), $block_dependencies ); self::register_script( 'wc-active-filters', plugins_url( self::get_block_asset_build_path( 'active-filters' ), __DIR__ ), $block_dependencies ); - $payment_method_handles = Package::container()->get( PaymentMethodAssets::class )->get_all_registered_payment_method_script_handles(); - self::register_script( 'wc-checkout-block', plugins_url( self::get_block_asset_build_path( 'checkout' ), __DIR__ ), array_merge( $block_dependencies, $payment_method_handles ) ); + self::register_script( 'wc-checkout-block', plugins_url( self::get_block_asset_build_path( 'checkout' ), __DIR__ ), $block_dependencies ); self::register_script( 'wc-cart-block', plugins_url( self::get_block_asset_build_path( 'cart' ), __DIR__ ), $block_dependencies ); } @@ -141,7 +140,7 @@ class Assets { 'isShippingCostHidden' => filter_var( get_option( 'woocommerce_shipping_cost_requires_address' ), FILTER_VALIDATE_BOOLEAN ), 'wcBlocksAssetUrl' => plugins_url( 'assets/', __DIR__ ), 'restApiRoutes' => [ - '/wc/store' => array_keys( \Automattic\WooCommerce\Blocks\RestApi::get_routes_from_namespace( 'wc/store' ) ), + '/wc/store' => array_keys( Package::container()->get( RestApi::class )->get_routes_from_namespace( 'wc/store' ) ), ], 'storeApiNonce' => wp_create_nonce( 'wc_store_api' ), 'homeUrl' => esc_url( home_url( '/' ) ), @@ -215,7 +214,7 @@ class Assets { $version = self::get_file_version( $relative_src ); } - wp_register_script( $handle, $src, $dependencies, $version, true ); + wp_register_script( $handle, $src, apply_filters( 'woocommerce_blocks_register_script_dependencies', $dependencies, $handle ), $version, true ); if ( $has_i18n && function_exists( 'wp_set_script_translations' ) ) { wp_set_script_translations( $handle, 'woo-gutenberg-products-block', dirname( __DIR__ ) . '/languages' ); diff --git a/plugins/woocommerce-blocks/src/Assets/PaymentMethodAssets.php b/plugins/woocommerce-blocks/src/Assets/PaymentMethodAssets.php deleted file mode 100644 index 88c4cb0a8d0..00000000000 --- a/plugins/woocommerce-blocks/src/Assets/PaymentMethodAssets.php +++ /dev/null @@ -1,83 +0,0 @@ -payment_method_registry = $payment_method_registry; - $this->asset_registry = $asset_registry; - } - - /** - * Gets an array of all registered payment method script handles. - * - * @return string[] - */ - public function get_all_registered_payment_method_script_handles() { - $script_handles = []; - $payment_methods = $this->payment_method_registry->get_all_registered(); - - foreach ( $payment_methods as $payment_method ) { - if ( ! $payment_method->is_active() ) { - continue; - } - $script_handles = array_merge( - $script_handles, - is_admin() ? $payment_method->get_payment_method_script_handles_for_admin() : $payment_method->get_payment_method_script_handles() - ); - } - - return array_unique( array_filter( $script_handles ) ); - } - - /** - * Adds data from payment methods to the asset registry. - */ - public function register_payment_method_data() { - $payment_methods = $this->payment_method_registry->get_all_registered(); - - foreach ( $payment_methods as $payment_method ) { - if ( ! $payment_method->is_active() ) { - continue; - } - $asset_data_key = $payment_method->get_name() . '_data'; - - if ( ! $this->asset_registry->exists( $asset_data_key ) ) { - $this->asset_registry->add( $asset_data_key, $payment_method->get_payment_method_data() ); - } - } - } -} diff --git a/plugins/woocommerce-blocks/src/BlockTypes/Checkout.php b/plugins/woocommerce-blocks/src/BlockTypes/Checkout.php index e0a62e39ad5..16e88344cba 100644 --- a/plugins/woocommerce-blocks/src/BlockTypes/Checkout.php +++ b/plugins/woocommerce-blocks/src/BlockTypes/Checkout.php @@ -10,7 +10,6 @@ namespace Automattic\WooCommerce\Blocks\BlockTypes; use Automattic\WooCommerce\Blocks\Package; use Automattic\WooCommerce\Blocks\Assets; use Automattic\WooCommerce\Blocks\Assets\AssetDataRegistry; -use Automattic\WooCommerce\Blocks\Assets\PaymentMethodAssets; defined( 'ABSPATH' ) || exit; @@ -116,7 +115,7 @@ class Checkout extends AbstractBlock { $this->hydrate_customer_payment_methods( $data_registry ); } - Package::container()->get( PaymentMethodAssets::class )->register_payment_method_data(); + do_action( 'woocommerce_blocks_checkout_enqueue_data' ); } /** @@ -127,9 +126,7 @@ class Checkout extends AbstractBlock { * not in the post content on editor load. */ protected function enqueue_scripts( array $attributes = [] ) { - $dependencies = Package::container()->get( PaymentMethodAssets::class )->get_all_registered_payment_method_script_handles(); - - Assets::register_block_script( $this->block_name . '-frontend', $this->block_name . '-block-frontend', $dependencies ); + Assets::register_block_script( $this->block_name . '-frontend', $this->block_name . '-block-frontend' ); } /** diff --git a/plugins/woocommerce-blocks/src/Domain/Bootstrap.php b/plugins/woocommerce-blocks/src/Domain/Bootstrap.php index 75106b8ea9c..0e0bc403cef 100644 --- a/plugins/woocommerce-blocks/src/Domain/Bootstrap.php +++ b/plugins/woocommerce-blocks/src/Domain/Bootstrap.php @@ -7,19 +7,18 @@ namespace Automattic\WooCommerce\Blocks\Domain; -use Automattic\WooCommerce\Blocks\Assets as OldAssets; +use Automattic\WooCommerce\Blocks\Assets as BlockAssets; 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\Payments\PaymentMethodRegistry; use Automattic\WooCommerce\Blocks\Library; use Automattic\WooCommerce\Blocks\Registry\Container; use Automattic\WooCommerce\Blocks\RestApi; +use Automattic\WooCommerce\Blocks\Payments\Api as PaymentsApi; +use Automattic\WooCommerce\Blocks\Payments\PaymentMethodRegistry; use Automattic\WooCommerce\Blocks\Payments\Integrations\Stripe; use Automattic\WooCommerce\Blocks\Payments\Integrations\Cheque; - /** * Takes care of bootstrapping the plugin. * @@ -59,20 +58,92 @@ class Bootstrap { /** * Init the package - load the blocks library and define constants. */ - public function init() { - if ( ! $this->has_dependencies() ) { + protected function init() { + if ( ! $this->has_core_dependencies() ) { return; } + $this->register_dependencies(); + $this->register_payment_methods(); - $this->remove_core_blocks(); + $is_rest = wc()->is_rest_api_request(); - if ( ! $this->is_built() ) { + // Load assets in admin and on the frontend. + if ( ! $is_rest ) { $this->add_build_notice(); + $this->define_feature_flag(); + $this->container->get( AssetDataRegistry::class ); + BlockAssets::init(); } - $this->define_feature_flag(); + $this->container->get( PaymentsApi::class ); + $this->container->get( RestApi::class ); + Library::init(); + } - // register core dependencies with the container. + /** + * Check core dependencies exist. + * + * @return boolean + */ + protected function has_core_dependencies() { + return class_exists( 'WooCommerce' ) && function_exists( 'register_block_type' ); + } + + /** + * See if files have been built or not. + * + * @return bool + */ + protected function is_built() { + return file_exists( + $this->package->get_path( 'build/featured-product.js' ) + ); + } + + /** + * 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() { + echo '

'; + printf( + /* Translators: %1$s is the install command, %2$s is the build command, %3$s is the watch command. */ + esc_html__( 'WooCommerce Blocks development mode requires files to be built. From the plugin directory, run %1$s to install dependencies, %2$s to build the files or %3$s to build the files and watch for changes.', 'woo-gutenberg-products-block' ), + 'npm install', + 'npm run build', + 'npm start' + ); + echo '

'; + } + ); + } + + /** + * Define the global feature flag. + */ + protected function define_feature_flag() { + $allowed_flags = [ 'experimental', 'stable' ]; + $flag = getenv( 'WOOCOMMERCE_BLOCKS_PHASE' ); + if ( ! in_array( $flag, $allowed_flags, true ) ) { + if ( file_exists( __DIR__ . '/../../blocks.ini' ) ) { + $woo_options = parse_ini_file( __DIR__ . '/../../blocks.ini' ); + $flag = is_array( $woo_options ) && 'experimental' === $woo_options['woocommerce_blocks_phase'] ? 'experimental' : 'stable'; + } else { + $flag = 'stable'; + } + } + define( 'WOOCOMMERCE_BLOCKS_PHASE', $flag ); + } + + /** + * Register core dependencies with the container. + */ + protected function register_dependencies() { $this->container->register( AssetApi::class, function ( Container $container ) { @@ -97,108 +168,28 @@ class Bootstrap { } ); $this->container->register( - PaymentMethodAssets::class, - function( Container $container ) { + PaymentsApi::class, + function ( Container $container ) { $payment_method_registry = $container->get( PaymentMethodRegistry::class ); $asset_data_registry = $container->get( AssetDataRegistry::class ); - return new PaymentMethodAssets( $payment_method_registry, $asset_data_registry ); + return new PaymentsApi( $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(); - } - - /** - * Check dependencies exist. - * - * @return boolean - */ - protected function has_dependencies() { - return class_exists( 'WooCommerce' ) && function_exists( 'register_block_type' ); - } - - /** - * See if files have been built or not. - * - * @return bool - */ - protected function is_built() { - return file_exists( - $this->package->get_path( 'build/featured-product.js' ) - ); - } - - /** - * Add a notice stating that the build has not been done yet. - */ - protected function add_build_notice() { - add_action( - 'admin_notices', - function() { - echo '

'; - printf( - /* Translators: %1$s is the install command, %2$s is the build command, %3$s is the watch command. */ - esc_html__( 'WooCommerce Blocks development mode requires files to be built. From the plugin directory, run %1$s to install dependencies, %2$s to build the files or %3$s to build the files and watch for changes.', 'woo-gutenberg-products-block' ), - 'npm install', - 'npm run build', - 'npm start' - ); - echo '

'; + $this->container->register( + RestApi::class, + function ( Container $container ) { + return new RestApi(); } ); } /** - * Remove core blocks. + * Register payment method integrations with the container. * - * Older installs of WooCommerce (3.6 and below) did not use the blocks package and instead included classes directly. - * This code disables those core classes when running blocks as a feature plugin. Newer versions which use the Blocks package are unaffected. - * - * When the feature plugin supports only WooCommerce 3.7+ this method can be removed. + * @internal Stripe is a temporary method that is used for setting up payment method integrations with Cart and + * Checkout blocks. This logic should get moved to the payment gateway extensions. */ - protected function remove_core_blocks() { - remove_action( 'init', array( 'WC_Block_Library', 'init' ) ); - remove_action( 'init', array( 'WC_Block_Library', 'register_blocks' ) ); - remove_action( 'init', array( 'WC_Block_Library', 'register_assets' ) ); - remove_filter( 'block_categories', array( 'WC_Block_Library', 'add_block_category' ) ); - remove_action( 'admin_print_footer_scripts', array( 'WC_Block_Library', 'print_script_settings' ), 1 ); - remove_action( 'init', array( 'WGPB_Block_Library', 'init' ) ); - } - - /** - * Define the global feature flag - */ - protected function define_feature_flag() { - $allowed_flags = [ 'experimental', 'stable' ]; - $flag = getenv( 'WOOCOMMERCE_BLOCKS_PHASE' ); - if ( ! in_array( $flag, $allowed_flags, true ) ) { - if ( file_exists( __DIR__ . '/../../blocks.ini' ) ) { - $woo_options = parse_ini_file( __DIR__ . '/../../blocks.ini' ); - $flag = is_array( $woo_options ) && 'experimental' === $woo_options['woocommerce_blocks_phase'] ? 'experimental' : 'stable'; - } else { - $flag = 'stable'; - } - } - define( 'WOOCOMMERCE_BLOCKS_PHASE', $flag ); - } - - /** - * This is a temporary method that is used for setting up payment method - * integrations with Cart and Checkout blocks. This logic should get moved - * to the payment gateway extensions. - */ - protected function load_payment_method_integrations() { - // stripe registration. + protected function register_payment_methods() { $this->container->register( Stripe::class, function( Container $container ) { @@ -206,7 +197,6 @@ class Bootstrap { return new Stripe( $asset_api ); } ); - // cheque registration. $this->container->register( Cheque::class, function( Container $container ) { @@ -214,19 +204,5 @@ class Bootstrap { return new Cheque( $asset_api ); } ); - add_action( - 'woocommerce_blocks_payment_method_type_registration', - function( $payment_method_registry ) { - // This is temporarily registering Stripe until it's moved to the extension. - if ( class_exists( 'WC_Stripe' ) && ! $payment_method_registry->is_registered( 'stripe' ) ) { - $payment_method_registry->register( - $this->container->get( Stripe::class ) - ); - } - $payment_method_registry->register( - $this->container->get( Cheque::class ) - ); - } - ); } } diff --git a/plugins/woocommerce-blocks/src/Library.php b/plugins/woocommerce-blocks/src/Library.php index ea0572576a2..d7615654123 100644 --- a/plugins/woocommerce-blocks/src/Library.php +++ b/plugins/woocommerce-blocks/src/Library.php @@ -9,8 +9,6 @@ namespace Automattic\WooCommerce\Blocks; defined( 'ABSPATH' ) || exit; -use Automattic\WooCommerce\Blocks\Payments\PaymentMethodRegistry; - /** * Library class. */ @@ -21,7 +19,6 @@ 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' ) ); @@ -133,13 +130,6 @@ 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. * diff --git a/plugins/woocommerce-blocks/src/Payments/Api.php b/plugins/woocommerce-blocks/src/Payments/Api.php new file mode 100644 index 00000000000..9e9eb7d7811 --- /dev/null +++ b/plugins/woocommerce-blocks/src/Payments/Api.php @@ -0,0 +1,155 @@ +payment_method_registry = $payment_method_registry; + $this->asset_registry = $asset_registry; + $this->init(); + } + + /** + * Initialize class features. + */ + protected function init() { + add_action( 'init', array( $this->payment_method_registry, 'initialize' ) ); + add_filter( 'woocommerce_blocks_register_script_dependencies', array( $this, 'add_payment_method_script_dependencies' ), 10, 2 ); + add_action( 'woocommerce_blocks_checkout_enqueue_data', array( $this, 'add_payment_method_script_data' ) ); + add_action( 'woocommerce_blocks_payment_method_type_registration', array( $this, 'register_payment_method_integrations' ) ); + add_action( 'woocommerce_rest_checkout_process_payment_with_context', array( $this, 'process_legacy_payment' ), 999, 2 ); + } + + /** + * Add payment method script handles as script dependencies. + * + * @param array $dependencies Array of script dependencies. + * @param string $handle Script handle. + * @return array + */ + public function add_payment_method_script_dependencies( $dependencies, $handle ) { + if ( ! in_array( $handle, [ 'wc-checkout-block', 'wc-checkout-block-frontend' ], true ) ) { + return $dependencies; + } + return array_merge( $dependencies, $this->payment_method_registry->get_all_registered_script_handles() ); + } + + /** + * Add payment method data to Asset Registry. + */ + public function add_payment_method_script_data() { + $script_data = $this->payment_method_registry->get_all_registered_script_data(); + + foreach ( $script_data as $asset_data_key => $asset_data_value ) { + if ( ! $this->asset_registry->exists( $asset_data_key ) ) { + $this->asset_registry->add( $asset_data_key, $asset_data_value ); + } + } + } + + /** + * Register payment method integrations bundled with blocks. + * + * @param PaymentMethodRegistry $payment_method_registry Payment method registry instance. + */ + public function register_payment_method_integrations( PaymentMethodRegistry $payment_method_registry ) { + // This is temporarily registering Stripe until it's moved to the extension. + if ( class_exists( '\WC_Stripe' ) && ! $payment_method_registry->is_registered( 'stripe' ) ) { + $payment_method_registry->register( + Package::container()->get( Stripe::class ) + ); + } + $payment_method_registry->register( + Package::container()->get( Cheque::class ) + ); + } + + /** + * 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 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 gateway. + $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/Payments/PaymentMethodRegistry.php b/plugins/woocommerce-blocks/src/Payments/PaymentMethodRegistry.php index b5df00684c3..4d017582fdf 100644 --- a/plugins/woocommerce-blocks/src/Payments/PaymentMethodRegistry.php +++ b/plugins/woocommerce-blocks/src/Payments/PaymentMethodRegistry.php @@ -115,4 +115,53 @@ final class PaymentMethodRegistry { public function is_registered( $name ) { return isset( $this->registered_payment_methods[ $name ] ); } + + /** + * Retrieves all registered payment methods that are also active. + * + * @return PaymentMethodTypeInterface[] + */ + public function get_all_active_registered() { + return array_filter( + $this->get_all_registered(), + function( $payment_method ) { + return $payment_method->is_active(); + } + ); + } + + /** + * Gets an array of all registered payment method script handles. + * + * @return string[] + */ + public function get_all_registered_script_handles() { + $script_handles = []; + $payment_methods = $this->get_all_active_registered(); + + foreach ( $payment_methods as $payment_method ) { + $script_handles = array_merge( + $script_handles, + is_admin() ? $payment_method->get_payment_method_script_handles_for_admin() : $payment_method->get_payment_method_script_handles() + ); + } + + return array_unique( array_filter( $script_handles ) ); + } + + /** + * Gets an array of all registered payment method script data. + * + * @return array + */ + public function get_all_registered_script_data() { + $script_data = []; + $payment_methods = $this->get_all_active_registered(); + + foreach ( $payment_methods as $payment_method ) { + $script_data[ $payment_method->get_name() . '_data' ] = $payment_method->get_payment_method_data(); + } + + return array_filter( $script_data ); + } } diff --git a/plugins/woocommerce-blocks/src/RestApi.php b/plugins/woocommerce-blocks/src/RestApi.php index 28451700dee..ee612e99586 100644 --- a/plugins/woocommerce-blocks/src/RestApi.php +++ b/plugins/woocommerce-blocks/src/RestApi.php @@ -11,30 +11,30 @@ defined( 'ABSPATH' ) || exit; use Automattic\WooCommerce\Blocks\StoreApi\RoutesController; use Automattic\WooCommerce\Blocks\StoreApi\SchemaController; -use Automattic\WooCommerce\Blocks\Payments\PaymentResult; -use Automattic\WooCommerce\Blocks\Payments\PaymentContext; -use Automattic\WooCommerce\Blocks\Payments\PaymentMethodRegistry; -use Automattic\WooCommerce\Blocks\StoreApi\Utilities\NoticeHandler; /** * RestApi class. */ class RestApi { + /** + * Constructor + */ + public function __construct() { + $this->init(); + } /** * Initialize class features. */ - public static function init() { - add_action( 'rest_api_init', array( __CLASS__, 'register_rest_routes' ), 10 ); - 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 ); + protected function init() { + add_action( 'rest_api_init', array( $this, 'register_rest_routes' ), 10 ); + add_filter( 'rest_authentication_errors', array( $this, 'store_api_authentication' ) ); } /** * Register REST API routes. */ - public static function register_rest_routes() { - // Init the Store API. + public function register_rest_routes() { $schemas = new SchemaController(); $routes = new RoutesController( $schemas ); $routes->register_routes(); @@ -46,7 +46,7 @@ class RestApi { * @param string $namespace Namespace to retrieve. * @return array|null */ - public static function get_routes_from_namespace( $namespace ) { + public function get_routes_from_namespace( $namespace ) { $rest_server = rest_get_server(); $namespace_index = $rest_server->get_namespace_index( [ @@ -60,12 +60,26 @@ class RestApi { return isset( $response_data['routes'] ) ? $response_data['routes'] : null; } + /** + * The Store API does not require authentication. + * + * @param \WP_Error|mixed $result Error from another authentication handler, null if we should handle it, or another value if not. + * @return \WP_Error|null|bool + */ + public function store_api_authentication( $result ) { + // Pass through errors from other authentication methods used before this one. + if ( ! empty( $result ) || ! self::is_request_to_store_api() ) { + return $result; + } + return true; + } + /** * Check if is request to the Store API. * * @return bool */ - protected static function is_request_to_store_api() { + protected function is_request_to_store_api() { if ( empty( $_SERVER['REQUEST_URI'] ) ) { return false; } @@ -75,69 +89,4 @@ class RestApi { return false !== strpos( $request_uri, $rest_prefix . 'wc/store' ); } - - /** - * The Store API does not require authentication. - * - * @param \WP_Error|mixed $result Error from another authentication handler, null if we should handle it, or another value if not. - * @return \WP_Error|null|bool - */ - public static function store_api_authentication( $result ) { - // Pass through errors from other authentication methods used before this one. - if ( ! empty( $result ) || ! self::is_request_to_store_api() ) { - return $result; - } - return true; - } - - /** - * 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'] ); - } }