1313
1414namespace Exchanger \Service ;
1515
16+ use DateInterval ;
17+ use DateTime ;
18+ use DateTimeInterface ;
19+ use Exception ;
1620use Exchanger \Contract \ExchangeRateQuery ;
1721use Exchanger \Contract \HistoricalExchangeRateQuery ;
1822use Exchanger \Exception \UnsupportedCurrencyPairException ;
@@ -29,11 +33,11 @@ final class EuropeanCentralBank extends HttpService
2933{
3034 use SupportsHistoricalQueries;
3135
32- const DAILY_URL = 'https://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml ' ;
36+ private const DAILY_URL = 'https://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml ' ;
3337
34- const HISTORICAL_URL_LIMITED_TO_90_DAYS_BACK = 'https://www.ecb.europa.eu/stats/eurofxref/eurofxref-hist-90d.xml ' ;
38+ private const HISTORICAL_URL_LIMITED_TO_90_DAYS_BACK = 'https://www.ecb.europa.eu/stats/eurofxref/eurofxref-hist-90d.xml ' ;
3539
36- const HISTORICAL_URL_OLDER_THAN_90_DAYS = 'https://www.ecb.europa.eu/stats/eurofxref/eurofxref-hist.xml ' ;
40+ private const HISTORICAL_URL_OLDER_THAN_90_DAYS = 'https://www.ecb.europa.eu/stats/eurofxref/eurofxref-hist.xml ' ;
3741
3842 /**
3943 * {@inheritdoc}
@@ -48,7 +52,7 @@ protected function getLatestExchangeRate(ExchangeRateQuery $exchangeQuery): Exch
4852
4953 $ quoteCurrency = $ currencyPair ->getQuoteCurrency ();
5054 $ elements = $ element ->xpath ('//xmlns:Cube[@currency=" ' .$ quoteCurrency .'"]/@rate ' );
51- $ date = new \ DateTime ((string ) $ element ->xpath ('//xmlns:Cube[@time]/@time ' )[0 ]);
55+ $ date = new DateTime ((string ) $ element ->xpath ('//xmlns:Cube[@time]/@time ' )[0 ]);
5256
5357 if (empty ($ elements ) || !$ date ) {
5458 throw new UnsupportedCurrencyPairException ($ currencyPair , $ this );
@@ -72,13 +76,22 @@ protected function getHistoricalExchangeRate(HistoricalExchangeRateQuery $exchan
7276 $ formattedDate = $ exchangeQuery ->getDate ()->format ('Y-m-d ' );
7377 $ quoteCurrency = $ currencyPair ->getQuoteCurrency ();
7478
75- $ elements = $ element ->xpath ('//xmlns:Cube[@time=" ' .$ formattedDate .'"]/xmlns:Cube[@currency=" ' .$ quoteCurrency .'"]/@rate ' );
76-
77- if (empty ($ elements )) {
78- if (empty ($ element ->xpath ('//xmlns:Cube[@time=" ' .$ formattedDate .'"] ' ))) {
79+ /**
80+ * if rate do not exist for actual date, try get prev day rate, while ge it
81+ */
82+ $ prevDays = 0 ;
83+ while (empty ($ element ->xpath ('//xmlns:Cube[@time=" ' .$ formattedDate .'"] ' ))) {
84+ $ prevDays ++;
85+ if ($ prevDays > 7 ) {
7986 throw new UnsupportedDateException ($ exchangeQuery ->getDate (), $ this );
8087 }
88+ $ formattedDate = (clone $ exchangeQuery ->getDate ())
89+ ->sub (new DateInterval ('P ' .$ prevDays .'D ' ))
90+ ->format ('Y-m-d ' );
91+ }
92+ $ elements = $ element ->xpath ('//xmlns:Cube[@time=" ' .$ formattedDate .'"]/xmlns:Cube[@currency=" ' .$ quoteCurrency .'"]/@rate ' );
8193
94+ if (empty ($ elements )) {
8295 throw new UnsupportedCurrencyPairException ($ currencyPair , $ this );
8396 }
8497
@@ -102,15 +115,15 @@ public function getName(): string
102115 }
103116
104117 /**
105- * @param \ DateTimeInterface $date
118+ * @param DateTimeInterface $date
106119 *
107120 * @return string
108121 *
109- * @throws \ Exception
122+ * @throws Exception
110123 */
111- private function getHistoricalUrl (\ DateTimeInterface $ date ): string
124+ private function getHistoricalUrl (DateTimeInterface $ date ): string
112125 {
113- $ dateDiffInDays = $ date ->diff (new \ DateTime ('now ' ))->days ;
126+ $ dateDiffInDays = $ date ->diff (new DateTime ('now ' ))->days ;
114127 if ($ dateDiffInDays > 90 ) {
115128 return self ::HISTORICAL_URL_OLDER_THAN_90_DAYS ;
116129 }
0 commit comments