From 5396752cebbe323df5a74c592cee76cd9f485a6f Mon Sep 17 00:00:00 2001 From: Daniel Subiabre Date: Tue, 26 Nov 2024 13:54:08 +0100 Subject: [PATCH 1/2] Update ExchangeLocator method names --- src/Library/Economy/Currency/ExchangeLocator.php | 12 ++++++------ src/Library/Economy/MoneyService.php | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Library/Economy/Currency/ExchangeLocator.php b/src/Library/Economy/Currency/ExchangeLocator.php index f125071..00a715f 100644 --- a/src/Library/Economy/Currency/ExchangeLocator.php +++ b/src/Library/Economy/Currency/ExchangeLocator.php @@ -7,7 +7,7 @@ class ExchangeLocator { /** - * @var ExchangeInterface[] + * @var array */ private array $exchanges; @@ -33,9 +33,9 @@ public function __construct(iterable $exchanges) } /** - * @return ExchangeInterface[] + * @return array */ - public function getExchanges(): array + public function getAll(): array { return $this->exchanges; } @@ -45,10 +45,10 @@ public function getExchanges(): array * * @throws \Exception When the $name does not match to that of an implemented Exchange */ - public function getExchange(string $name): ExchangeInterface + public function getByName(string $name): ExchangeInterface { if (!\array_key_exists($name, $this->exchanges)) { - throw new \Exception("No such Exchange with the name $name"); + throw new \Exception("No such Exchange with the name '$name'"); } return $this->exchanges[$name]; @@ -60,7 +60,7 @@ public function getExchange(string $name): ExchangeInterface * * @throws CurrencyConversionException If the exchange rate is not available */ - public function getExchangeFor(string $source, string $target): ExchangeInterface + public function get(string $source, string $target): ExchangeInterface { foreach ($this->exchanges as $exchange) { try { diff --git a/src/Library/Economy/MoneyService.php b/src/Library/Economy/MoneyService.php index c6649fc..e7078f8 100644 --- a/src/Library/Economy/MoneyService.php +++ b/src/Library/Economy/MoneyService.php @@ -78,7 +78,7 @@ private function convert(Money $money, string $toCurrency): Brick\Money return self::toBrick($money); } - $exchange = $this->exchangeLocator->getExchangeFor($fromCurrency, $toCurrency); + $exchange = $this->exchangeLocator->get($fromCurrency, $toCurrency); return self::toBrick($exchange->convert(self::toBrick($money), $toCurrency)); } From e6be82a3efc448d2958223a69b539df6ed0b8e02 Mon Sep 17 00:00:00 2001 From: Daniel Subiabre Date: Tue, 26 Nov 2024 13:56:50 +0100 Subject: [PATCH 2/2] Update ExchangeInterface --- .../Currency/EuropeanCentralBankExchange.php | 107 +++++++++--------- .../Economy/Currency/ExchangeInterface.php | 7 +- src/Library/Economy/MoneyService.php | 2 +- 3 files changed, 59 insertions(+), 57 deletions(-) diff --git a/src/Library/Economy/Currency/EuropeanCentralBankExchange.php b/src/Library/Economy/Currency/EuropeanCentralBankExchange.php index c1e260b..7fc7508 100644 --- a/src/Library/Economy/Currency/EuropeanCentralBankExchange.php +++ b/src/Library/Economy/Currency/EuropeanCentralBankExchange.php @@ -2,13 +2,13 @@ namespace App\Library\Economy\Currency; -use App\Entity\Money as EntityMoney; +use App\Entity\Money; +use App\Library\Economy\MoneyService; use Brick\Math\RoundingMode; use Brick\Money\CurrencyConverter; use Brick\Money\ExchangeRateProvider; use Brick\Money\ExchangeRateProvider\BaseCurrencyProvider; use Brick\Money\ExchangeRateProvider\ConfigurableProvider; -use Brick\Money\MoneyContainer; use Symfony\Component\Cache\Adapter\FilesystemAdapter; use Symfony\Contracts\Cache\CacheInterface; use Symfony\Contracts\Cache\ItemInterface; @@ -20,6 +20,9 @@ */ class EuropeanCentralBankExchange implements ExchangeInterface { + public const NAME = 'european_central_bank'; + public const WEIGHT = 100; + public const ISO_4217 = 'EUR'; /** @@ -53,59 +56,62 @@ public function __construct() $provider->setExchangeRate(self::ISO_4217, $rate['currency'], $rate['rate']); } - $this->date = $this->getDataUpdatedDate($data['@attributes']['time']); + $this->date = $this->parseECBTime($data['@attributes']['time']); $this->provider = new BaseCurrencyProvider($provider, self::ISO_4217); $this->converter = new CurrencyConverter($this->provider); } - private function getDataLatest(): array + public function getName(): string { - $data = \simplexml_load_file(self::ECB_DATA); - if (!$data) { - throw new \Exception('Could not retrieve XML data'); - } - - return \json_decode(\json_encode($data), true)['Cube']['Cube']; + return self::NAME; } - private function getDataCached(): array + public function getWeight(): int { - $data = $this->cache->get($this->getName(), function (ItemInterface $item): array { - $item->expiresAfter(self::ECB_DATA_TTL); + return self::WEIGHT; + } - return $this->getDataLatest(); - }); + public function convert(Money $money, string $toCurrency): Money + { + $converted = $this->converter->convert( + MoneyService::toBrick($money), + $toCurrency, + null, + RoundingMode::HALF_EVEN + ); - if (!$data) { - throw new \Exception('Could not retrieve cached data'); - } + return new Money( + $converted->getMinorAmount()->toInt(), + $converted->getCurrency()->getCurrencyCode() + ); + } - return $data; + public function getConversionRate(string $fromCurrency, string $toCurrency): float + { + return $this->provider->getExchangeRate($fromCurrency, $toCurrency)->toFloat(); } - private function getDataUpdatedDate(string $time): \DateTimeInterface + public function getConversionDate(string $fromCurrency, string $toCurrency): \DateTimeInterface { - return \DateTime::createFromFormat( - \DateTimeInterface::RFC3339, - sprintf('%sT16:00:00+01:00', $time), - new \DateTimeZone(self::ECB_TIMEZONE) - ); + $this->provider->getExchangeRate($fromCurrency, $toCurrency); + + return $this->date; } public function getData(): array { try { $cachedData = $this->getDataCached(); + $cachedDate = $this->parseECBTime($cachedData['@attributes']['time']); $currentDate = new \DateTime('now', new \DateTimeZone(self::ECB_TIMEZONE)); $currentDayAt16 = (new \DateTime('now', new \DateTimeZone(self::ECB_TIMEZONE)))->setTime(16, 0); - $cachedDate = $this->getDataUpdatedDate($cachedData['@attributes']['time']); if ( $currentDate > $currentDayAt16 && $cachedDate < $currentDayAt16 ) { - $this->cache->delete($this->getName()); + $this->cache->delete(self::NAME); $cachedData = $this->getDataCached(); } @@ -115,40 +121,37 @@ public function getData(): array } } - public function getName(): string - { - return 'european_central_bank'; - } - - public function getWeight(): int + private function parseECBTime(string $time): \DateTimeInterface { - return 100; + return \DateTime::createFromFormat( + \DateTimeInterface::RFC3339, + \sprintf('%sT16:00:00+01:00', $time), + new \DateTimeZone(self::ECB_TIMEZONE) + ); } - public function convert(MoneyContainer $money, string $toCurrency): EntityMoney + private function getDataLatest(): array { - $converted = $this->converter->convert( - $money, - $toCurrency, - null, - RoundingMode::HALF_EVEN - ); + $data = \simplexml_load_file(self::ECB_DATA); + if (!$data) { + throw new \Exception('Could not retrieve XML data'); + } - return new EntityMoney( - $converted->getMinorAmount()->toInt(), - $converted->getCurrency()->getCurrencyCode() - ); + return \json_decode(\json_encode($data), true)['Cube']['Cube']; } - public function getConversionRate(string $fromCurrency, string $toCurrency): float + private function getDataCached(): array { - return $this->provider->getExchangeRate($fromCurrency, $toCurrency)->toFloat(); - } + $data = $this->cache->get(self::NAME, function (ItemInterface $item): array { + $item->expiresAfter(self::ECB_DATA_TTL); - public function getConversionDate(string $fromCurrency, string $toCurrency): \DateTimeInterface - { - $this->provider->getExchangeRate($fromCurrency, $toCurrency); + return $this->getDataLatest(); + }); - return $this->date; + if (!$data) { + throw new \Exception('Could not retrieve cached data'); + } + + return $data; } } diff --git a/src/Library/Economy/Currency/ExchangeInterface.php b/src/Library/Economy/Currency/ExchangeInterface.php index d2e2f17..a4c2aee 100644 --- a/src/Library/Economy/Currency/ExchangeInterface.php +++ b/src/Library/Economy/Currency/ExchangeInterface.php @@ -4,7 +4,6 @@ use App\Entity\Money; use Brick\Money\Exception\CurrencyConversionException; -use Brick\Money\MoneyContainer; interface ExchangeInterface { @@ -19,14 +18,14 @@ public function getName(): string; public function getWeight(): int; /** - * @param MoneyContainer $money The money to be converted - * @param string $toCurrency The currency to convert to + * @param Money $money The money to be converted + * @param string $toCurrency The currency to convert to * * @return Money The converted Money * * @throws CurrencyConversionException If the exchange rate is not available */ - public function convert(MoneyContainer $money, string $toCurrency): Money; + public function convert(Money $money, string $toCurrency): Money; /** * @param string $fromCurrency The currency to convert from diff --git a/src/Library/Economy/MoneyService.php b/src/Library/Economy/MoneyService.php index e7078f8..3b0a17f 100644 --- a/src/Library/Economy/MoneyService.php +++ b/src/Library/Economy/MoneyService.php @@ -80,6 +80,6 @@ private function convert(Money $money, string $toCurrency): Brick\Money $exchange = $this->exchangeLocator->get($fromCurrency, $toCurrency); - return self::toBrick($exchange->convert(self::toBrick($money), $toCurrency)); + return self::toBrick($exchange->convert($money, $toCurrency)); } }