Initial commit.

This commit is contained in:
2025-11-24 21:33:55 +00:00
parent 14b7ade051
commit d6e9d316bc
8974 changed files with 1423277 additions and 0 deletions

View File

@@ -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
}
}

View File

@@ -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 );
}
}