183 lines
5.4 KiB
PHP
183 lines
5.4 KiB
PHP
<?php
|
|
/**
|
|
* WooCommerce Payments Multi-Currency Backend Currencies
|
|
*
|
|
* @package WooCommerce\Payments
|
|
*/
|
|
|
|
namespace WCPay\MultiCurrency;
|
|
|
|
use WCPay\MultiCurrency\Interfaces\MultiCurrencyLocalizationInterface;
|
|
|
|
defined( 'ABSPATH' ) || exit;
|
|
|
|
/**
|
|
* Class that formats Multi-Currency currencies on the backend.
|
|
*/
|
|
class BackendCurrencies {
|
|
/**
|
|
* Multi-Currency instance.
|
|
*
|
|
* @var MultiCurrency
|
|
*/
|
|
protected $multi_currency;
|
|
|
|
/**
|
|
* MultiCurrencyLocalizationInterface instance.
|
|
*
|
|
* @var MultiCurrencyLocalizationInterface
|
|
*/
|
|
protected $localization_service;
|
|
|
|
/**
|
|
* Multi-Currency currency formatting map.
|
|
*
|
|
* @var array
|
|
*/
|
|
protected $currency_format = [];
|
|
|
|
/**
|
|
* Constructor.
|
|
*
|
|
* @param MultiCurrency $multi_currency The MultiCurrency instance.
|
|
* @param MultiCurrencyLocalizationInterface $localization_service The Localization Service instance.
|
|
*/
|
|
public function __construct( MultiCurrency $multi_currency, MultiCurrencyLocalizationInterface $localization_service ) {
|
|
$this->multi_currency = $multi_currency;
|
|
$this->localization_service = $localization_service;
|
|
}
|
|
|
|
/**
|
|
* Initializes this class' WP hooks.
|
|
*
|
|
* @return void
|
|
*/
|
|
public function init_hooks() {
|
|
// Skip if no additional currencies are enabled.
|
|
if ( ! $this->multi_currency->has_additional_currencies_enabled() ) {
|
|
return;
|
|
}
|
|
|
|
// We need to check first if it's a request coming from the backend, frontend REST requests shouldn't be
|
|
// affected by this.
|
|
$is_backend_request = 0 === stripos( wp_get_referer(), admin_url() );
|
|
|
|
// Add the filter if it's an admin request or a REST request from the admin side.
|
|
if ( ( is_admin() || ( WC()->is_rest_api_request() && $is_backend_request ) ) && ! defined( 'DOING_CRON' ) ) {
|
|
// Currency hooks. Be aware that this should not run after Explicit Price hook, its priority should be less
|
|
// than explicit price hooks to run before them.
|
|
add_filter( 'wc_price_args', [ $this, 'build_wc_price_args' ], 50 );
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returns the store currency code.
|
|
*
|
|
* @return string The store currency code
|
|
*/
|
|
public function get_store_currency(): string {
|
|
return get_woocommerce_currency();
|
|
}
|
|
|
|
/**
|
|
* Returns the currency code to be used by the formatter.
|
|
*
|
|
* @param array $args The arguments containing the currency code.
|
|
*
|
|
* @return string The code of the currency to be used.
|
|
*/
|
|
public function get_price_currency( $args ): string {
|
|
return $args['currency'] ?? $this->get_store_currency();
|
|
}
|
|
|
|
/**
|
|
* Returns the number of decimals to be used by the formatter.
|
|
*
|
|
* @param string $currency_code The currency code to fetch formatting specs.
|
|
*
|
|
* @return int The number of decimals.
|
|
*/
|
|
public function get_price_decimals( $currency_code ): int {
|
|
return absint( $this->localization_service->get_currency_format( $currency_code )['num_decimals'] );
|
|
}
|
|
|
|
/**
|
|
* Returns if the currency is a zero decimal point currency.
|
|
*
|
|
* @param string $currency_code The currency code to fetch formatting specs.
|
|
*
|
|
* @return bool Whether the currency is a zero decimal point currency or not.
|
|
*/
|
|
public function is_zero_decimal_currency( $currency_code ): bool {
|
|
return 0 === $this->get_price_decimals( $currency_code );
|
|
}
|
|
|
|
/**
|
|
* Returns the decimal separator to be used by the formatter.
|
|
*
|
|
* @param string $currency_code The currency code to fetch formatting specs.
|
|
*
|
|
* @return string The decimal separator.
|
|
*/
|
|
public function get_price_decimal_separator( $currency_code ): string {
|
|
return $this->localization_service->get_currency_format( $currency_code )['decimal_sep'];
|
|
}
|
|
|
|
/**
|
|
* Returns the thousand separator to be used by the formatter.
|
|
*
|
|
* @param string $currency_code The currency code to fetch formatting specs.
|
|
*
|
|
* @return string The thousand separator.
|
|
*/
|
|
public function get_price_thousand_separator( $currency_code ): string {
|
|
return $this->localization_service->get_currency_format( $currency_code )['thousand_sep'];
|
|
}
|
|
|
|
/**
|
|
* Returns the currency format to be used by the formatter.
|
|
*
|
|
* @param string $currency_code The currency code to fetch formatting specs.
|
|
*
|
|
* @return string The currency format.
|
|
*/
|
|
public function get_woocommerce_price_format( $currency_code ): string {
|
|
$currency_pos = $this->localization_service->get_currency_format( $currency_code )['currency_pos'];
|
|
|
|
switch ( $currency_pos ) {
|
|
case 'left':
|
|
return '%1$s%2$s';
|
|
case 'right':
|
|
return '%2$s%1$s';
|
|
case 'left_space':
|
|
return '%1$s %2$s';
|
|
case 'right_space':
|
|
return '%2$s %1$s';
|
|
default:
|
|
return '%1$s%2$s';
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returns the formatting arguments for the given currency using the locale-info
|
|
*
|
|
* @param array $args Currency formatter original arguments.
|
|
*
|
|
* @return array New arguments matching with the locale-info
|
|
*/
|
|
public function build_wc_price_args( $args ) {
|
|
$currency_code = $this->get_price_currency( $args );
|
|
|
|
return wp_parse_args(
|
|
[
|
|
'currency' => $currency_code,
|
|
'decimal_separator' => $this->get_price_decimal_separator( $this->get_store_currency() ),
|
|
'thousand_separator' => $this->get_price_thousand_separator( $this->get_store_currency() ),
|
|
'decimals' => $this->is_zero_decimal_currency( $currency_code ) ? 0 : $this->get_price_decimals( $currency_code ),
|
|
'price_format' => $this->get_woocommerce_price_format( $currency_code ),
|
|
],
|
|
$args
|
|
);
|
|
}
|
|
}
|