vendor/florianv/exchanger/src/Service/EuropeanCentralBank.php line 44

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. /*
  4.  * This file is part of Exchanger.
  5.  *
  6.  * (c) Florian Voutzinos <florian@voutzinos.com>
  7.  *
  8.  * For the full copyright and license information, please view the LICENSE
  9.  * file that was distributed with this source code.
  10.  */
  11. namespace Exchanger\Service;
  12. use Exchanger\Contract\ExchangeRateQuery;
  13. use Exchanger\Contract\HistoricalExchangeRateQuery;
  14. use Exchanger\Exception\UnsupportedCurrencyPairException;
  15. use Exchanger\Exception\UnsupportedDateException;
  16. use Exchanger\StringUtil;
  17. use Exchanger\Contract\ExchangeRate as ExchangeRateContract;
  18. /**
  19.  * European Central Bank Service.
  20.  *
  21.  * @author Florian Voutzinos <florian@voutzinos.com>
  22.  */
  23. final class EuropeanCentralBank extends HttpService
  24. {
  25.     use SupportsHistoricalQueries;
  26.     const DAILY_URL 'https://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml';
  27.     const HISTORICAL_URL_LIMITED_TO_90_DAYS_BACK 'https://www.ecb.europa.eu/stats/eurofxref/eurofxref-hist-90d.xml';
  28.     const HISTORICAL_URL_OLDER_THAN_90_DAYS 'https://www.ecb.europa.eu/stats/eurofxref/eurofxref-hist.xml';
  29.     /**
  30.      * {@inheritdoc}
  31.      */
  32.     protected function getLatestExchangeRate(ExchangeRateQuery $exchangeQuery): ExchangeRateContract
  33.     {
  34.         $currencyPair $exchangeQuery->getCurrencyPair();
  35.         $content $this->request(self::DAILY_URL);
  36.         $element StringUtil::xmlToElement($content);
  37.         $element->registerXPathNamespace('xmlns''http://www.ecb.int/vocabulary/2002-08-01/eurofxref');
  38.         $quoteCurrency $currencyPair->getQuoteCurrency();
  39.         $elements $element->xpath('//xmlns:Cube[@currency="'.$quoteCurrency.'"]/@rate');
  40.         $date = new \DateTime((string) $element->xpath('//xmlns:Cube[@time]/@time')[0]);
  41.         if (empty($elements) || !$date) {
  42.             throw new UnsupportedCurrencyPairException($currencyPair$this);
  43.         }
  44.         return $this->createRate($currencyPair, (float) ($elements[0]['rate']), $date);
  45.     }
  46.     /**
  47.      * {@inheritdoc}
  48.      */
  49.     protected function getHistoricalExchangeRate(HistoricalExchangeRateQuery $exchangeQuery): ExchangeRateContract
  50.     {
  51.         $currencyPair $exchangeQuery->getCurrencyPair();
  52.         $historicalUrl $this->getHistoricalUrl($exchangeQuery->getDate());
  53.         $content $this->request($historicalUrl);
  54.         $element StringUtil::xmlToElement($content);
  55.         $element->registerXPathNamespace('xmlns''http://www.ecb.int/vocabulary/2002-08-01/eurofxref');
  56.         $formattedDate $exchangeQuery->getDate()->format('Y-m-d');
  57.         $quoteCurrency $currencyPair->getQuoteCurrency();
  58.         $elements $element->xpath('//xmlns:Cube[@time="'.$formattedDate.'"]/xmlns:Cube[@currency="'.$quoteCurrency.'"]/@rate');
  59.         if (empty($elements)) {
  60.             if (empty($element->xpath('//xmlns:Cube[@time="'.$formattedDate.'"]'))) {
  61.                 throw new UnsupportedDateException($exchangeQuery->getDate(), $this);
  62.             }
  63.             throw new UnsupportedCurrencyPairException($currencyPair$this);
  64.         }
  65.         return $this->createRate($currencyPair, (float) ($elements[0]['rate']), $exchangeQuery->getDate());
  66.     }
  67.     /**
  68.      * {@inheritdoc}
  69.      */
  70.     public function supportQuery(ExchangeRateQuery $exchangeQuery): bool
  71.     {
  72.         return 'EUR' === $exchangeQuery->getCurrencyPair()->getBaseCurrency();
  73.     }
  74.     /**
  75.      * {@inheritdoc}
  76.      */
  77.     public function getName(): string
  78.     {
  79.         return 'european_central_bank';
  80.     }
  81.     /**
  82.      * @param \DateTimeInterface $date
  83.      *
  84.      * @return string
  85.      *
  86.      * @throws \Exception
  87.      */
  88.     private function getHistoricalUrl(\DateTimeInterface $date): string
  89.     {
  90.         $dateDiffInDays $date->diff(new \DateTime('now'))->days;
  91.         if ($dateDiffInDays 90) {
  92.             return self::HISTORICAL_URL_OLDER_THAN_90_DAYS;
  93.         }
  94.         return self::HISTORICAL_URL_LIMITED_TO_90_DAYS_BACK;
  95.     }
  96. }