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
This commit is contained in:
parent
e5589727fc
commit
30ecea188f
|
@ -7,10 +7,10 @@
|
||||||
|
|
||||||
namespace Automattic\WooCommerce\Blocks;
|
namespace Automattic\WooCommerce\Blocks;
|
||||||
|
|
||||||
use Automattic\WooCommerce\Blocks\Assets\PaymentMethodAssets;
|
|
||||||
|
|
||||||
defined( 'ABSPATH' ) || exit;
|
defined( 'ABSPATH' ) || exit;
|
||||||
|
|
||||||
|
use Automattic\WooCommerce\Blocks\Package;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Assets class.
|
* 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-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-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 );
|
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__ ), $block_dependencies );
|
||||||
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-cart-block', plugins_url( self::get_block_asset_build_path( 'cart' ), __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 ),
|
'isShippingCostHidden' => filter_var( get_option( 'woocommerce_shipping_cost_requires_address' ), FILTER_VALIDATE_BOOLEAN ),
|
||||||
'wcBlocksAssetUrl' => plugins_url( 'assets/', __DIR__ ),
|
'wcBlocksAssetUrl' => plugins_url( 'assets/', __DIR__ ),
|
||||||
'restApiRoutes' => [
|
'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' ),
|
'storeApiNonce' => wp_create_nonce( 'wc_store_api' ),
|
||||||
'homeUrl' => esc_url( home_url( '/' ) ),
|
'homeUrl' => esc_url( home_url( '/' ) ),
|
||||||
|
@ -215,7 +214,7 @@ class Assets {
|
||||||
$version = self::get_file_version( $relative_src );
|
$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' ) ) {
|
if ( $has_i18n && function_exists( 'wp_set_script_translations' ) ) {
|
||||||
wp_set_script_translations( $handle, 'woo-gutenberg-products-block', dirname( __DIR__ ) . '/languages' );
|
wp_set_script_translations( $handle, 'woo-gutenberg-products-block', dirname( __DIR__ ) . '/languages' );
|
||||||
|
|
|
@ -1,83 +0,0 @@
|
||||||
<?php
|
|
||||||
/**
|
|
||||||
* Handles assets for registered payment types.
|
|
||||||
*
|
|
||||||
* @package WooCommerce/Blocks
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace Automattic\WooCommerce\Blocks\Assets;
|
|
||||||
|
|
||||||
use Automattic\WooCommerce\Blocks\Payments\PaymentMethodRegistry;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* PaymentMethodAssets class.
|
|
||||||
*
|
|
||||||
* @since $VID:$
|
|
||||||
*/
|
|
||||||
class PaymentMethodAssets {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reference to the PaymentMethodRegistry instance
|
|
||||||
*
|
|
||||||
* @var PaymentMethodRegistry
|
|
||||||
*/
|
|
||||||
private $payment_method_registry;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An instance of the AssetDataRegistry
|
|
||||||
*
|
|
||||||
* @var AssetDataRegistry
|
|
||||||
*/
|
|
||||||
private $asset_registry;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor for class
|
|
||||||
*
|
|
||||||
* @param PaymentMethodRegistry $payment_method_registry An instance of Payment Method Registry.
|
|
||||||
* @param AssetDataRegistry $asset_registry Used for registering data to pass along to the request.
|
|
||||||
*/
|
|
||||||
public function __construct( PaymentMethodRegistry $payment_method_registry, AssetDataRegistry $asset_registry ) {
|
|
||||||
$this->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() );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -10,7 +10,6 @@ namespace Automattic\WooCommerce\Blocks\BlockTypes;
|
||||||
use Automattic\WooCommerce\Blocks\Package;
|
use Automattic\WooCommerce\Blocks\Package;
|
||||||
use Automattic\WooCommerce\Blocks\Assets;
|
use Automattic\WooCommerce\Blocks\Assets;
|
||||||
use Automattic\WooCommerce\Blocks\Assets\AssetDataRegistry;
|
use Automattic\WooCommerce\Blocks\Assets\AssetDataRegistry;
|
||||||
use Automattic\WooCommerce\Blocks\Assets\PaymentMethodAssets;
|
|
||||||
|
|
||||||
defined( 'ABSPATH' ) || exit;
|
defined( 'ABSPATH' ) || exit;
|
||||||
|
|
||||||
|
@ -116,7 +115,7 @@ class Checkout extends AbstractBlock {
|
||||||
$this->hydrate_customer_payment_methods( $data_registry );
|
$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.
|
* not in the post content on editor load.
|
||||||
*/
|
*/
|
||||||
protected function enqueue_scripts( array $attributes = [] ) {
|
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' );
|
||||||
|
|
||||||
Assets::register_block_script( $this->block_name . '-frontend', $this->block_name . '-block-frontend', $dependencies );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -7,19 +7,18 @@
|
||||||
|
|
||||||
namespace Automattic\WooCommerce\Blocks\Domain;
|
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\Api as AssetApi;
|
||||||
use Automattic\WooCommerce\Blocks\Assets\AssetDataRegistry;
|
use Automattic\WooCommerce\Blocks\Assets\AssetDataRegistry;
|
||||||
use Automattic\WooCommerce\Blocks\Assets\BackCompatAssetDataRegistry;
|
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\Library;
|
||||||
use Automattic\WooCommerce\Blocks\Registry\Container;
|
use Automattic\WooCommerce\Blocks\Registry\Container;
|
||||||
use Automattic\WooCommerce\Blocks\RestApi;
|
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\Stripe;
|
||||||
use Automattic\WooCommerce\Blocks\Payments\Integrations\Cheque;
|
use Automattic\WooCommerce\Blocks\Payments\Integrations\Cheque;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Takes care of bootstrapping the plugin.
|
* Takes care of bootstrapping the plugin.
|
||||||
*
|
*
|
||||||
|
@ -59,20 +58,92 @@ class Bootstrap {
|
||||||
/**
|
/**
|
||||||
* Init the package - load the blocks library and define constants.
|
* Init the package - load the blocks library and define constants.
|
||||||
*/
|
*/
|
||||||
public function init() {
|
protected function init() {
|
||||||
if ( ! $this->has_dependencies() ) {
|
if ( ! $this->has_core_dependencies() ) {
|
||||||
return;
|
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->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 '<div class="error"><p>';
|
||||||
|
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' ),
|
||||||
|
'<code>npm install</code>',
|
||||||
|
'<code>npm run build</code>',
|
||||||
|
'<code>npm start</code>'
|
||||||
|
);
|
||||||
|
echo '</p></div>';
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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(
|
$this->container->register(
|
||||||
AssetApi::class,
|
AssetApi::class,
|
||||||
function ( Container $container ) {
|
function ( Container $container ) {
|
||||||
|
@ -97,108 +168,28 @@ class Bootstrap {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
$this->container->register(
|
$this->container->register(
|
||||||
PaymentMethodAssets::class,
|
PaymentsApi::class,
|
||||||
function( Container $container ) {
|
function ( Container $container ) {
|
||||||
$payment_method_registry = $container->get( PaymentMethodRegistry::class );
|
$payment_method_registry = $container->get( PaymentMethodRegistry::class );
|
||||||
$asset_data_registry = $container->get( AssetDataRegistry::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 );
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
$this->container->register(
|
||||||
// load AssetDataRegistry.
|
RestApi::class,
|
||||||
$this->container->get( AssetDataRegistry::class );
|
function ( Container $container ) {
|
||||||
|
return new RestApi();
|
||||||
// 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 '<div class="error"><p>';
|
|
||||||
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' ),
|
|
||||||
'<code>npm install</code>',
|
|
||||||
'<code>npm run build</code>',
|
|
||||||
'<code>npm start</code>'
|
|
||||||
);
|
|
||||||
echo '</p></div>';
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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.
|
* @internal Stripe is a temporary method that is used for setting up payment method integrations with Cart and
|
||||||
* This code disables those core classes when running blocks as a feature plugin. Newer versions which use the Blocks package are unaffected.
|
* Checkout blocks. This logic should get moved to the payment gateway extensions.
|
||||||
*
|
|
||||||
* When the feature plugin supports only WooCommerce 3.7+ this method can be removed.
|
|
||||||
*/
|
*/
|
||||||
protected function remove_core_blocks() {
|
protected function register_payment_methods() {
|
||||||
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.
|
|
||||||
$this->container->register(
|
$this->container->register(
|
||||||
Stripe::class,
|
Stripe::class,
|
||||||
function( Container $container ) {
|
function( Container $container ) {
|
||||||
|
@ -206,7 +197,6 @@ class Bootstrap {
|
||||||
return new Stripe( $asset_api );
|
return new Stripe( $asset_api );
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
// cheque registration.
|
|
||||||
$this->container->register(
|
$this->container->register(
|
||||||
Cheque::class,
|
Cheque::class,
|
||||||
function( Container $container ) {
|
function( Container $container ) {
|
||||||
|
@ -214,19 +204,5 @@ class Bootstrap {
|
||||||
return new Cheque( $asset_api );
|
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 )
|
|
||||||
);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,8 +9,6 @@ namespace Automattic\WooCommerce\Blocks;
|
||||||
|
|
||||||
defined( 'ABSPATH' ) || exit;
|
defined( 'ABSPATH' ) || exit;
|
||||||
|
|
||||||
use Automattic\WooCommerce\Blocks\Payments\PaymentMethodRegistry;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Library class.
|
* Library class.
|
||||||
*/
|
*/
|
||||||
|
@ -21,7 +19,6 @@ class Library {
|
||||||
*/
|
*/
|
||||||
public static function init() {
|
public static function init() {
|
||||||
add_action( 'init', array( __CLASS__, 'register_blocks' ) );
|
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__, 'define_tables' ) );
|
||||||
add_action( 'init', array( __CLASS__, 'maybe_create_tables' ) );
|
add_action( 'init', array( __CLASS__, 'maybe_create_tables' ) );
|
||||||
add_action( 'init', array( __CLASS__, 'maybe_create_cronjobs' ) );
|
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.
|
* Register custom order status for orders created via the API during checkout.
|
||||||
*
|
*
|
||||||
|
|
|
@ -0,0 +1,155 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Payment Api class.
|
||||||
|
*
|
||||||
|
* @package WooCommerce/Blocks
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Automattic\WooCommerce\Blocks\Payments;
|
||||||
|
|
||||||
|
defined( 'ABSPATH' ) || exit;
|
||||||
|
|
||||||
|
use Automattic\WooCommerce\Blocks\Package;
|
||||||
|
use Automattic\WooCommerce\Blocks\Assets\AssetDataRegistry;
|
||||||
|
use Automattic\WooCommerce\Blocks\StoreApi\Utilities\NoticeHandler;
|
||||||
|
use Automattic\WooCommerce\Blocks\Payments\Integrations\Stripe;
|
||||||
|
use Automattic\WooCommerce\Blocks\Payments\Integrations\Cheque;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Api class provides an interface to payment method registration.
|
||||||
|
*
|
||||||
|
* @since $VID:$
|
||||||
|
*/
|
||||||
|
class Api {
|
||||||
|
/**
|
||||||
|
* Reference to the PaymentMethodRegistry instance.
|
||||||
|
*
|
||||||
|
* @var PaymentMethodRegistry
|
||||||
|
*/
|
||||||
|
private $payment_method_registry;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reference to the AssetDataRegistry instance.
|
||||||
|
*
|
||||||
|
* @var AssetDataRegistry
|
||||||
|
*/
|
||||||
|
private $asset_registry;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param PaymentMethodRegistry $payment_method_registry An instance of Payment Method Registry.
|
||||||
|
* @param AssetDataRegistry $asset_registry Used for registering data to pass along to the request.
|
||||||
|
*/
|
||||||
|
public function __construct( PaymentMethodRegistry $payment_method_registry, AssetDataRegistry $asset_registry ) {
|
||||||
|
$this->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'] );
|
||||||
|
}
|
||||||
|
}
|
|
@ -115,4 +115,53 @@ final class PaymentMethodRegistry {
|
||||||
public function is_registered( $name ) {
|
public function is_registered( $name ) {
|
||||||
return isset( $this->registered_payment_methods[ $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 );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,30 +11,30 @@ defined( 'ABSPATH' ) || exit;
|
||||||
|
|
||||||
use Automattic\WooCommerce\Blocks\StoreApi\RoutesController;
|
use Automattic\WooCommerce\Blocks\StoreApi\RoutesController;
|
||||||
use Automattic\WooCommerce\Blocks\StoreApi\SchemaController;
|
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.
|
* RestApi class.
|
||||||
*/
|
*/
|
||||||
class RestApi {
|
class RestApi {
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*/
|
||||||
|
public function __construct() {
|
||||||
|
$this->init();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize class features.
|
* Initialize class features.
|
||||||
*/
|
*/
|
||||||
public static function init() {
|
protected function init() {
|
||||||
add_action( 'rest_api_init', array( __CLASS__, 'register_rest_routes' ), 10 );
|
add_action( 'rest_api_init', array( $this, 'register_rest_routes' ), 10 );
|
||||||
add_filter( 'rest_authentication_errors', array( __CLASS__, 'store_api_authentication' ) );
|
add_filter( 'rest_authentication_errors', array( $this, 'store_api_authentication' ) );
|
||||||
add_action( 'woocommerce_rest_checkout_process_payment_with_context', array( __CLASS__, 'process_legacy_payment' ), 999, 2 );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register REST API routes.
|
* Register REST API routes.
|
||||||
*/
|
*/
|
||||||
public static function register_rest_routes() {
|
public function register_rest_routes() {
|
||||||
// Init the Store API.
|
|
||||||
$schemas = new SchemaController();
|
$schemas = new SchemaController();
|
||||||
$routes = new RoutesController( $schemas );
|
$routes = new RoutesController( $schemas );
|
||||||
$routes->register_routes();
|
$routes->register_routes();
|
||||||
|
@ -46,7 +46,7 @@ class RestApi {
|
||||||
* @param string $namespace Namespace to retrieve.
|
* @param string $namespace Namespace to retrieve.
|
||||||
* @return array|null
|
* @return array|null
|
||||||
*/
|
*/
|
||||||
public static function get_routes_from_namespace( $namespace ) {
|
public function get_routes_from_namespace( $namespace ) {
|
||||||
$rest_server = rest_get_server();
|
$rest_server = rest_get_server();
|
||||||
$namespace_index = $rest_server->get_namespace_index(
|
$namespace_index = $rest_server->get_namespace_index(
|
||||||
[
|
[
|
||||||
|
@ -60,12 +60,26 @@ class RestApi {
|
||||||
return isset( $response_data['routes'] ) ? $response_data['routes'] : null;
|
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.
|
* Check if is request to the Store API.
|
||||||
*
|
*
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
protected static function is_request_to_store_api() {
|
protected function is_request_to_store_api() {
|
||||||
if ( empty( $_SERVER['REQUEST_URI'] ) ) {
|
if ( empty( $_SERVER['REQUEST_URI'] ) ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -75,69 +89,4 @@ class RestApi {
|
||||||
|
|
||||||
return false !== strpos( $request_uri, $rest_prefix . 'wc/store' );
|
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'] );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue