From a822fa27b45c6cb5782ebcf98abf9424bb944f23 Mon Sep 17 00:00:00 2001 From: psegatori Date: Sun, 13 Oct 2024 14:13:34 +0200 Subject: [PATCH] Allows custom CurrencyProvider Introduce the ability to provide a list of supported currencies that can be different than the hardcoded ISO 4217 ones (e.g. Crypto) --- crypto-currency-provider.php | 43 +++++++++++++++++++++++++++++++ src/Currency.php | 11 +++++--- src/CurrencyProviderInterface.php | 18 +++++++++++++ src/ISOCurrencyProvider.php | 2 +- src/Money.php | 17 +++++++----- 5 files changed, 81 insertions(+), 10 deletions(-) create mode 100644 crypto-currency-provider.php create mode 100644 src/CurrencyProviderInterface.php diff --git a/crypto-currency-provider.php b/crypto-currency-provider.php new file mode 100644 index 00000000..cfc32a65 --- /dev/null +++ b/crypto-currency-provider.php @@ -0,0 +1,43 @@ + new \Brick\Money\Currency('BTC', 0, 'Bitcoin', 8 ), + ]; + + return $cryptoCurrency[$currencyCode] ?? throw UnknownCurrencyException::unknownCurrency($currencyCode); + } + + public function getCurrencyForCountry(string $currencyCode): \Brick\Money\Currency + { + throw new UnknownCurrencyException('Crypto Currency don\'t have a country code.'); + } +} + +class CryptoCurrency extends \Brick\Money\Currency { + protected static function getCurrencyProvider(): \Brick\Money\CurrencyProviderInterface + { + return new CryptoCurrencyProvider(); + } +} + +\Brick\Money\Money::of(2, CryptoCurrency::of('BTC')); +\Brick\Money\Money::of(2, \Brick\Money\Currency::of('EUR')); + +class CryptoMoney extends \Brick\Money\Money { + protected static function getCurrencyProvider(): \Brick\Money\CurrencyProviderInterface + { + return new CryptoCurrencyProvider(); + } +} + +CryptoMoney::of(2, 'BTC')->plus(CryptoMoney::of(2, 'BTC')); +CryptoMoney::of(2, 'BTC')->plus(\Brick\Money\Money::of(2, \Brick\Money\Currency::of('EUR'))); \ No newline at end of file diff --git a/src/Currency.php b/src/Currency.php index c8c6b1d8..385da509 100644 --- a/src/Currency.php +++ b/src/Currency.php @@ -11,7 +11,7 @@ /** * A currency. This class is immutable. */ -final class Currency implements Stringable, JsonSerializable +class Currency implements Stringable, JsonSerializable { /** * The currency code. @@ -71,6 +71,11 @@ public function __construct(string $currencyCode, int $numericCode, string $name $this->defaultFractionDigits = $defaultFractionDigits; } + protected static function getCurrencyProvider() : CurrencyProviderInterface + { + return ISOCurrencyProvider::getInstance(); + } + /** * Returns a Currency instance matching the given ISO currency code. * @@ -80,7 +85,7 @@ public function __construct(string $currencyCode, int $numericCode, string $name */ public static function of(string|int $currencyCode) : Currency { - return ISOCurrencyProvider::getInstance()->getCurrency($currencyCode); + return static::getCurrencyProvider()->getCurrency($currencyCode); } /** @@ -94,7 +99,7 @@ public static function of(string|int $currencyCode) : Currency */ public static function ofCountry(string $countryCode) : Currency { - return ISOCurrencyProvider::getInstance()->getCurrencyForCountry($countryCode); + return static::getCurrencyProvider()->getCurrencyForCountry($countryCode); } /** diff --git a/src/CurrencyProviderInterface.php b/src/CurrencyProviderInterface.php new file mode 100644 index 00000000..26a4dea5 --- /dev/null +++ b/src/CurrencyProviderInterface.php @@ -0,0 +1,18 @@ +getCurrency($currency); } if ($context === null) { @@ -193,6 +193,11 @@ public static function of( return self::create($amount, $currency, $context, $roundingMode); } + protected static function getCurrencyProvider() : CurrencyProviderInterface + { + return ISOCurrencyProvider::getInstance(); + } + /** * Returns a Money from a number of minor units. * @@ -219,7 +224,7 @@ public static function ofMinor( RoundingMode $roundingMode = RoundingMode::UNNECESSARY, ) : Money { if (! $currency instanceof Currency) { - $currency = Currency::of($currency); + $currency = static::getCurrencyProvider()->getCurrency($currency); } if ($context === null) { @@ -245,7 +250,7 @@ public static function ofMinor( public static function zero(Currency|string|int $currency, ?Context $context = null) : Money { if (! $currency instanceof Currency) { - $currency = Currency::of($currency); + $currency = static::getCurrencyProvider()->getCurrency($currency); } if ($context === null) { @@ -729,7 +734,7 @@ public function convertedTo( RoundingMode $roundingMode = RoundingMode::UNNECESSARY, ) : Money { if (! $currency instanceof Currency) { - $currency = Currency::of($currency); + $currency = static::getCurrencyProvider()->getCurrency($currency); } if ($context === null) { @@ -836,4 +841,4 @@ protected function checkContext(Context $context, string $method) : void throw MoneyMismatchException::contextMismatch($method); } } -} +} \ No newline at end of file