| 1 |
<?php |
| 2 |
|
| 3 |
namespace Give\Framework\Support\Facades; |
| 4 |
|
| 5 |
use Give\Framework\Support\Currencies\GiveCurrencies; |
| 6 |
use Give\Log\Log; |
| 7 |
use Money\Converter; |
| 8 |
use Money\Currencies; |
| 9 |
use Money\Currencies\AggregateCurrencies; |
| 10 |
use Money\Currencies\BitcoinCurrencies; |
| 11 |
use Money\Currencies\ISOCurrencies; |
| 12 |
use Money\Currency; |
| 13 |
use Money\Exchange\FixedExchange; |
| 14 |
use Money\Formatter\DecimalMoneyFormatter; |
| 15 |
use Money\Formatter\IntlMoneyFormatter; |
| 16 |
use Money\Money; |
| 17 |
use Money\Parser\DecimalMoneyParser; |
| 18 |
use NumberFormatter; |
| 19 |
|
| 20 |
|
| 21 |
class CurrencyFacade |
| 22 |
{ |
| 23 |
/** |
| 24 |
* Immutably converts the given amount into the system currency. |
| 25 |
* |
| 26 |
* @since 2.27.3 updated to use aggregated currency list. |
| 27 |
* |
| 28 |
* @since 2.20.0 |
| 29 |
* |
| 30 |
* @param Money $amount |
| 31 |
* @param int|float $exchangeRate |
| 32 |
*/ |
| 33 |
public function convertToBaseCurrency(Money $amount, $exchangeRate = 1): Money |
| 34 |
{ |
| 35 |
$baseCurrency = $this->getBaseCurrency(); |
| 36 |
|
| 37 |
if ($amount->getCurrency()->equals($baseCurrency)) { |
| 38 |
return $amount; |
| 39 |
} |
| 40 |
|
| 41 |
$converter = new Converter( |
| 42 |
$this->getCurrenciesList(), new FixedExchange([ |
| 43 |
$amount->getCurrency()->getCode() => [ |
| 44 |
give_get_option('currency', 'USD') => $exchangeRate, |
| 45 |
], |
| 46 |
]) |
| 47 |
); |
| 48 |
|
| 49 |
return $converter->convert($amount, $baseCurrency); |
| 50 |
} |
| 51 |
|
| 52 |
/** |
| 53 |
* Creates a new Money instance from a decimal amount |
| 54 |
* |
| 55 |
* @since 2.27.3 updated to use aggregated currency list. |
| 56 |
* |
| 57 |
* @since 2.20.0 |
| 58 |
* |
| 59 |
* @param string|float|int $amount |
| 60 |
*/ |
| 61 |
public function parseFromDecimal($amount, string $currency): Money |
| 62 |
{ |
| 63 |
return (new DecimalMoneyParser($this->getCurrenciesList()))->parse((string)$amount, new Currency($currency)); |
| 64 |
} |
| 65 |
|
| 66 |
/** |
| 67 |
* Returns the amount in a decimal format, not including any currency symbols: |
| 68 |
* - $1,500.25 -> 1500.25 |
| 69 |
* |
| 70 |
* @since 2.20.0 |
| 71 |
*/ |
| 72 |
public function formatToDecimal(Money $amount): string |
| 73 |
{ |
| 74 |
return (new DecimalMoneyFormatter($this->getCurrenciesList()))->format($amount); |
| 75 |
} |
| 76 |
|
| 77 |
/** |
| 78 |
* Formats the amount to a currency format, including currency symbols, in the given locale. |
| 79 |
* |
| 80 |
* @since 2.27.3 updated to use aggregated currency list. |
| 81 |
* |
| 82 |
* @since 2.24.2 fallback on give formatting system if intl extension is not available |
| 83 |
* @since 2.20.0 |
| 84 |
* |
| 85 |
* @param Money $amount |
| 86 |
* @param string|null $locale |
| 87 |
* |
| 88 |
* @return string |
| 89 |
*/ |
| 90 |
public function formatToLocale(Money $amount, $locale = null): string |
| 91 |
{ |
| 92 |
$useAutoFormatting = give_get_option('auto_format_currency'); |
| 93 |
if (!class_exists(NumberFormatter::class) || !$useAutoFormatting) { |
| 94 |
if ($useAutoFormatting) { |
| 95 |
Log::warning( |
| 96 |
'Auto-formatting is enabled at Donations > Settings > General > Currency but the INTL extension for PHP is not available. Please install the INTL extension to enable auto-formatting, or disable the Auto-formatting setting to prevent this error message. Most web hosts can help with installing and activating INTL. GiveWP is falling back to formatting based on the legacy settings.' |
| 97 |
); |
| 98 |
} |
| 99 |
|
| 100 |
return give_currency_filter( |
| 101 |
$this->formatToDecimal($amount), |
| 102 |
['currency' => $amount->getCurrency()->getCode()] |
| 103 |
); |
| 104 |
} |
| 105 |
|
| 106 |
if ($locale === null) { |
| 107 |
$locale = get_locale(); |
| 108 |
} |
| 109 |
|
| 110 |
$numberFormatter = new NumberFormatter($locale, NumberFormatter::CURRENCY); |
| 111 |
$moneyFormatter = new IntlMoneyFormatter($numberFormatter, $this->getCurrenciesList()); |
| 112 |
|
| 113 |
return $moneyFormatter->format($amount); |
| 114 |
} |
| 115 |
|
| 116 |
/** |
| 117 |
* Retrieves the system's base currency |
| 118 |
* |
| 119 |
* @since 2.20.0 |
| 120 |
* |
| 121 |
* @return Currency |
| 122 |
*/ |
| 123 |
public function getBaseCurrency(): Currency |
| 124 |
{ |
| 125 |
return new Currency(give_get_option('currency', 'USD')); |
| 126 |
} |
| 127 |
|
| 128 |
/** |
| 129 |
* Retrieves a list for all supported currencies. |
| 130 |
* |
| 131 |
* @since 4.10.0 Updated to use GiveCurrencies as the primary source of currencies |
| 132 |
* @since 2.27.3 |
| 133 |
*/ |
| 134 |
private function getCurrenciesList(): Currencies |
| 135 |
{ |
| 136 |
return new AggregateCurrencies([ |
| 137 |
new GiveCurrencies(), |
| 138 |
new ISOCurrencies(), |
| 139 |
new BitcoinCurrencies(), |
| 140 |
]); |
| 141 |
} |
| 142 |
} |
| 143 |
|