165 lines
5.4 KiB
PHP
165 lines
5.4 KiB
PHP
<?php
|
|
/**
|
|
* Class WC_Payments_Explicit_Price_Formatter
|
|
*
|
|
* @package WooCommerce\Payments
|
|
*/
|
|
|
|
use WCPay\MultiCurrency\MultiCurrency;
|
|
|
|
if ( ! defined( 'ABSPATH' ) ) {
|
|
exit; // Exit if accessed directly.
|
|
}
|
|
|
|
/**
|
|
* Class for displaying the explicit prices on total amounts.
|
|
*
|
|
* Also used for consistent rendering of price values with currency (get_explicit_price_with_currency()).
|
|
*/
|
|
class WC_Payments_Explicit_Price_Formatter {
|
|
|
|
/**
|
|
* The Multi-Currency instance for checking the number of enabled currencies
|
|
*
|
|
* @var MultiCurrency
|
|
*/
|
|
private static $multi_currency_instance = null;
|
|
|
|
/**
|
|
* Inits the formatter, registering the necessary hooks.
|
|
*/
|
|
public static function init() {
|
|
add_filter( 'woocommerce_cart_total', [ __CLASS__, 'get_explicit_price' ], 100 );
|
|
add_filter( 'woocommerce_get_formatted_order_total', [ __CLASS__, 'get_explicit_price' ], 100, 2 );
|
|
add_action( 'woocommerce_admin_order_totals_after_tax', [ __CLASS__, 'register_formatted_woocommerce_price_filter' ] );
|
|
add_action( 'woocommerce_admin_order_totals_after_total', [ __CLASS__, 'unregister_formatted_woocommerce_price_filter' ] );
|
|
}
|
|
|
|
/**
|
|
* Overrides the MultiCurrency instance that the class uses.
|
|
* Mostly for testing purposes.
|
|
*
|
|
* @param MultiCurrency $multi_currency MultCurrency class.
|
|
*
|
|
* @return void
|
|
*/
|
|
public static function set_multi_currency_instance( MultiCurrency $multi_currency ) {
|
|
self::$multi_currency_instance = $multi_currency;
|
|
}
|
|
|
|
/**
|
|
* Checks if the method should output explicit price
|
|
*
|
|
* @return bool Whether if it should return explicit price or not
|
|
*/
|
|
public static function should_output_explicit_price() {
|
|
// If customer Multi-Currency is disabled, don't use explicit currencies.
|
|
// Because it'll have only the store currency active, same as count == 1.
|
|
if ( ! WC_Payments_Features::is_customer_multi_currency_enabled() ) {
|
|
return false;
|
|
}
|
|
|
|
// If the MultiCurrency instance hasn't been defined yet, fetch the instance.
|
|
if ( null === self::$multi_currency_instance ) {
|
|
self::$multi_currency_instance = WC_Payments_Multi_Currency();
|
|
}
|
|
|
|
// If the instance isn't initialized yet, skip the checks.
|
|
if ( ! self::$multi_currency_instance->is_initialized() ) {
|
|
return false;
|
|
}
|
|
|
|
// If no additional currencies are enabled, skip it.
|
|
if ( ! self::$multi_currency_instance->has_additional_currencies_enabled() ) {
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Registers the get_explicit_price filter for the order details screen.
|
|
*
|
|
* There are no hooks that enable us to filter the output on the order details screen.
|
|
* So, we need to add a filter to formatted_woocommerce_price. We use specific actions
|
|
* to register and unregister the filter, so that only the appropriate prices are affected.
|
|
*/
|
|
public static function register_formatted_woocommerce_price_filter() {
|
|
add_filter( 'wc_price_args', [ __CLASS__, 'get_explicit_price_args' ], 100 );
|
|
}
|
|
|
|
/**
|
|
* Unregisters the get_explicit_price filter for the order details screen.
|
|
*
|
|
* There are no hooks that enable us to filter the output on the order details screen.
|
|
* So, we need to add a filter to formatted_woocommerce_price. We use specific actions
|
|
* to register and unregister the filter, so that only the appropriate prices are affected.
|
|
*/
|
|
public static function unregister_formatted_woocommerce_price_filter() {
|
|
remove_filter( 'wc_price_args', [ __CLASS__, 'get_explicit_price_args' ], 100 );
|
|
}
|
|
|
|
/**
|
|
* Returns the price suffixed with the appropriate currency code, if not already.
|
|
*
|
|
* @param string $price The price.
|
|
* @param WC_Abstract_Order|null $order The order.
|
|
*
|
|
* @return string
|
|
*/
|
|
public static function get_explicit_price( string $price, ?WC_Abstract_Order $order = null ) {
|
|
if ( null === $order ) {
|
|
$currency_code = get_woocommerce_currency();
|
|
} else {
|
|
$currency_code = $order->get_currency();
|
|
}
|
|
|
|
return static::get_explicit_price_with_currency( $price, $currency_code );
|
|
}
|
|
|
|
/**
|
|
* Returns a formatted price string suffixed with the appropriate currency code (if necessary).
|
|
*
|
|
* In multi-currency stores, order and price values are rendered with currency suffix.
|
|
* This method only renders the currency suffix if appropriate (see `should_output_explicit_price`).
|
|
*
|
|
* @param string $price A price value (as a string).
|
|
* @param ?string $currency_code Currency of the price.
|
|
*
|
|
* @return string Price value with currency code suffix if necessary.
|
|
*/
|
|
public static function get_explicit_price_with_currency( string $price, ?string $currency_code ) {
|
|
if ( false === static::should_output_explicit_price() ) {
|
|
return $price;
|
|
}
|
|
if ( empty( $currency_code ) ) {
|
|
return $price;
|
|
}
|
|
|
|
$price_to_check = html_entity_decode( wp_strip_all_tags( $price ), ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401 );
|
|
|
|
if ( false === strpos( $price_to_check, trim( $currency_code ) ) ) {
|
|
return $price . ' ' . $currency_code;
|
|
}
|
|
|
|
return $price;
|
|
}
|
|
|
|
/**
|
|
* Alters the price formatting arguments to include explicit format
|
|
*
|
|
* @param array $args Price formatting args passed through `wc_price_args` filter.
|
|
*
|
|
* @return array The modified arguments
|
|
*/
|
|
public static function get_explicit_price_args( $args ) {
|
|
if ( false === static::should_output_explicit_price() ) {
|
|
return $args;
|
|
}
|
|
if ( false === strpos( $args['price_format'], $args['currency'] ) ) {
|
|
$args['price_format'] = sprintf( '%s %s', $args['price_format'], $args['currency'] );
|
|
}
|
|
return $args;
|
|
}
|
|
}
|