Initial commit.
This commit is contained in:
@@ -0,0 +1,177 @@
|
||||
<?php
|
||||
/**
|
||||
* Class WC_Payments_Currency_Manager
|
||||
*
|
||||
* @package WooCommerce\Payments
|
||||
*/
|
||||
|
||||
namespace WCPay;
|
||||
|
||||
use WC_Payment_Gateway_WCPay;
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
/**
|
||||
* It ensures that when a payment method is added and multi-currency is enabled, the needed currency is also added.
|
||||
*/
|
||||
class WC_Payments_Currency_Manager {
|
||||
/**
|
||||
* The WCPay gateway class instance.
|
||||
*
|
||||
* @var WC_Payment_Gateway_WCPay
|
||||
*/
|
||||
private $gateway;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param WC_Payment_Gateway_WCPay $gateway The WCPay gateway class instance.
|
||||
*/
|
||||
public function __construct( WC_Payment_Gateway_WCPay $gateway ) {
|
||||
$this->gateway = $gateway;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes this class' WP hooks.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function init_hooks() {
|
||||
add_action( 'update_option_woocommerce_woocommerce_payments_settings', [ $this, 'maybe_add_missing_currencies' ] );
|
||||
add_action( 'admin_head', [ $this, 'add_payment_method_currency_dependencies_script' ] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the multi-currency instance or returns null if it's not available.
|
||||
* This method allows for easier testing by allowing the multi-currency instance to be mocked.
|
||||
*
|
||||
* @return \WCPay\MultiCurrency\MultiCurrency|null
|
||||
*/
|
||||
public function get_multi_currency_instance() {
|
||||
if ( ! function_exists( 'WC_Payments_Multi_Currency' ) ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ( ! WC_Payments_Multi_Currency()->is_initialized() ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return WC_Payments_Multi_Currency();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the currencies needed per enabled payment method
|
||||
*
|
||||
* @return array The currencies keyed with the related payment method
|
||||
*/
|
||||
public function get_enabled_payment_method_currencies() {
|
||||
$enabled_payment_method_ids = $this->gateway->get_upe_enabled_payment_method_ids();
|
||||
// getting all the payment methods that are also present in `$enabled_payment_method_ids`.
|
||||
$enabled_payment_methods = array_values( array_intersect_key( $this->gateway->wc_payments_get_payment_method_map(), array_flip( $enabled_payment_method_ids ) ) );
|
||||
$account_currency = $this->gateway->get_account_domestic_currency();
|
||||
$payment_methods_needing_currency = array_reduce(
|
||||
$enabled_payment_methods,
|
||||
function ( $result, $payment_method_instance ) use ( $account_currency ) {
|
||||
$method = $payment_method_instance->get_id();
|
||||
if ( in_array( $method, [ 'card', 'card_present', 'link' ], true ) ) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
$result[ $method ] = [
|
||||
'currencies' => $payment_method_instance->has_domestic_transactions_restrictions() ? [ $account_currency ] : $payment_method_instance->get_currencies(),
|
||||
'title' => $payment_method_instance->get_title( $this->gateway->get_account_country() ),
|
||||
];
|
||||
|
||||
return $result;
|
||||
},
|
||||
[]
|
||||
);
|
||||
|
||||
return $payment_methods_needing_currency;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that when a payment method is added from the settings, the needed currency is also added.
|
||||
*/
|
||||
public function maybe_add_missing_currencies() {
|
||||
$multi_currency = $this->get_multi_currency_instance();
|
||||
if ( is_null( $multi_currency ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$payment_methods_needing_currency = $this->get_enabled_payment_method_currencies();
|
||||
if ( empty( $payment_methods_needing_currency ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$enabled_currencies = $multi_currency->get_enabled_currencies();
|
||||
$available_currencies = $multi_currency->get_available_currencies();
|
||||
|
||||
$missing_currency_codes = [];
|
||||
|
||||
// TODO: we need to find something about having a currency not available for the method in case of having disabled currencies in the future.
|
||||
// First option, not do display it if the available currency is blocked by something else (Stripe, merchant, WCPay etc.)
|
||||
// Second option, showing a notice that it can't be selected because the currency is not available to use.
|
||||
|
||||
// we have payments needing some currency being enabled, let's ensure the currency is present.
|
||||
foreach ( $payment_methods_needing_currency as $payment_method_data ) {
|
||||
$needed_currency_codes = $payment_method_data['currencies'];
|
||||
foreach ( $needed_currency_codes as $needed_currency_code ) {
|
||||
if ( ! isset( $available_currencies[ $needed_currency_code ] ) ) {
|
||||
continue;
|
||||
}
|
||||
if ( isset( $enabled_currencies[ $needed_currency_code ] ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$missing_currency_codes[] = $needed_currency_code;
|
||||
}
|
||||
}
|
||||
|
||||
$missing_currency_codes = array_unique( $missing_currency_codes );
|
||||
|
||||
if ( empty( $missing_currency_codes ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* The set_enabled_currencies method throws an exception if any currencies passed are not found in the current available currencies.
|
||||
* Any currencies not found are filtered out above, so we shouldn't need a try/catch here.
|
||||
*/
|
||||
$multi_currency->set_enabled_currencies( array_merge( array_keys( $enabled_currencies ), $missing_currency_codes ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the `multiCurrencyPaymentMethodsMap` JS object to the multi-currency settings page.
|
||||
*
|
||||
* This object maps currencies to payment methods that require them, so the multi-currency settings page displays a notice in case of dependencies.
|
||||
*/
|
||||
public function add_payment_method_currency_dependencies_script() {
|
||||
$multi_currency = $this->get_multi_currency_instance();
|
||||
|
||||
if ( is_null( $multi_currency ) || ! $multi_currency->is_multi_currency_settings_page() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$payment_methods_needing_currency = $this->get_enabled_payment_method_currencies();
|
||||
if ( empty( $payment_methods_needing_currency ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$currency_methods_map = [];
|
||||
foreach ( $payment_methods_needing_currency as $method => $data ) {
|
||||
foreach ( $data['currencies'] as $currency ) {
|
||||
if ( ! isset( $currency_methods_map[ $currency ] ) ) {
|
||||
$currency_methods_map[ $currency ] = [];
|
||||
}
|
||||
$currency_methods_map[ $currency ][ $method ] = $data['title'];
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
<script type='text/javascript'>
|
||||
window.multiCurrencyPaymentMethodsMap = <?php echo wp_json_encode( $currency_methods_map ); ?>;
|
||||
</script>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
<?php
|
||||
/**
|
||||
* Main functions to start MultiCurrency class.
|
||||
*
|
||||
* @package WooCommerce\Payments
|
||||
*/
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
/**
|
||||
* Load customer multi-currency if feature is enabled or if it is the setup page.
|
||||
*/
|
||||
function wcpay_multi_currency_onboarding_check() {
|
||||
$is_setup_page = false;
|
||||
|
||||
// Skip checking the HTTP referer if it is a cron job.
|
||||
if ( ! defined( 'DOING_CRON' ) ) {
|
||||
$http_referer = sanitize_text_field( wp_unslash( $_SERVER['HTTP_REFERER'] ?? '' ) );
|
||||
if ( ! empty( $http_referer ) ) {
|
||||
$is_setup_page = strpos( $http_referer, 'multi-currency-setup' ) !== false;
|
||||
}
|
||||
}
|
||||
|
||||
return $is_setup_page;
|
||||
}
|
||||
|
||||
if ( ! WC_Payments_Features::is_customer_multi_currency_enabled() && ! wcpay_multi_currency_onboarding_check() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the MultiCurrency singleton.
|
||||
*
|
||||
* @return WCPay\MultiCurrency\MultiCurrency
|
||||
*/
|
||||
function WC_Payments_Multi_Currency() { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName.FunctionNameInvalid
|
||||
static $instance = null;
|
||||
|
||||
if ( is_null( $instance ) ) {
|
||||
$instance = new WCPay\MultiCurrency\MultiCurrency(
|
||||
WC_Payments::get_settings_service(),
|
||||
WC_Payments::get_payments_api_client(),
|
||||
WC_Payments::get_account_service(),
|
||||
WC_Payments::get_localization_service(),
|
||||
WC_Payments::get_database_cache()
|
||||
);
|
||||
$instance->init_hooks();
|
||||
}
|
||||
|
||||
return $instance;
|
||||
}
|
||||
|
||||
add_action( 'plugins_loaded', 'WC_Payments_Multi_Currency', 12 );
|
||||
|
||||
register_deactivation_hook( WCPAY_PLUGIN_FILE, 'wcpay_multi_currency_deactivated' );
|
||||
|
||||
/**
|
||||
* Plugin deactivation hook.
|
||||
*/
|
||||
function wcpay_multi_currency_deactivated() {
|
||||
WCPay\MultiCurrency\MultiCurrency::remove_woo_admin_notes();
|
||||
}
|
||||
|
||||
if ( ! function_exists( 'wc_get_currency_switcher_markup' ) ) {
|
||||
/**
|
||||
* Gets the switcher widget markup.
|
||||
*
|
||||
* @param array $instance The widget's instance settings.
|
||||
* @param array $args The widget's arguments.
|
||||
*
|
||||
* @return string The widget markup.
|
||||
*/
|
||||
function wc_get_currency_switcher_markup( array $instance = [], array $args = [] ): string {
|
||||
return WC_Payments_Multi_Currency()->get_switcher_widget_markup( $instance, $args );
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user