-
Notifications
You must be signed in to change notification settings - Fork 81
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
16 changed files
with
459 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
/* | ||
* This file is part of Exchanger. | ||
* | ||
* (c) Florian Voutzinos <florian@voutzinos.com> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
namespace Exchanger\Service\ApiLayer; | ||
|
||
use Exchanger\Contract\CurrencyPair; | ||
use Exchanger\Contract\ExchangeRate as ExchangeRateContract; | ||
use Exchanger\Contract\ExchangeRateQuery; | ||
use Exchanger\Contract\HistoricalExchangeRateQuery; | ||
use Exchanger\Exception\Exception; | ||
use Exchanger\Exception\NonBreakingInvalidArgumentException; | ||
use Exchanger\Exception\UnsupportedCurrencyPairException; | ||
use Exchanger\ExchangeRate; | ||
use Exchanger\Service\HttpService; | ||
use Exchanger\Service\SupportsHistoricalQueries; | ||
use Exchanger\StringUtil; | ||
|
||
/** | ||
* ApiLayer Exchange Rates Data API. | ||
* | ||
* @see https://apilayer.com/marketplace/exchangerates_data-api | ||
* | ||
* @author Florian Voutzinos <florian@voutzinos.com> | ||
*/ | ||
final class ExchangeRatesData extends HttpService | ||
{ | ||
use SupportsHistoricalQueries; | ||
|
||
const API_KEY_OPTION = 'api_key'; | ||
|
||
const LATEST_URL = 'https://api.apilayer.com/exchangerates_data/latest?base=%s&apikey=%s&symbols=%s'; | ||
|
||
const HISTORICAL_URL = 'https://api.apilayer.com/exchangerates_data/%s?base=%s&apikey=%s&symbols=%s'; | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function processOptions(array &$options): void | ||
{ | ||
if (!isset($options[self::API_KEY_OPTION])) { | ||
throw new NonBreakingInvalidArgumentException('The "api_key" option must be provided to use Exchange Rates Data (https://apilayer.com/marketplace/exchangerates_data-api).'); | ||
} | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
protected function getLatestExchangeRate(ExchangeRateQuery $exchangeQuery): ExchangeRateContract | ||
{ | ||
$currencyPair = $exchangeQuery->getCurrencyPair(); | ||
|
||
$url = sprintf( | ||
self::LATEST_URL, | ||
$currencyPair->getBaseCurrency(), | ||
$this->options[self::API_KEY_OPTION], | ||
$currencyPair->getQuoteCurrency() | ||
); | ||
|
||
return $this->doCreateRate($url, $currencyPair); | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
protected function getHistoricalExchangeRate(HistoricalExchangeRateQuery $exchangeQuery): ExchangeRateContract | ||
{ | ||
$currencyPair = $exchangeQuery->getCurrencyPair(); | ||
|
||
$url = sprintf( | ||
self::HISTORICAL_URL, | ||
$exchangeQuery->getDate()->format('Y-m-d'), | ||
$exchangeQuery->getCurrencyPair()->getBaseCurrency(), | ||
$this->options[self::API_KEY_OPTION], | ||
$currencyPair->getQuoteCurrency() | ||
); | ||
|
||
return $this->doCreateRate($url, $currencyPair); | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function supportQuery(ExchangeRateQuery $exchangeQuery): bool | ||
{ | ||
return true; | ||
} | ||
|
||
/** | ||
* Creates a rate. | ||
* | ||
* @param string $url | ||
* | ||
* @throws Exception | ||
*/ | ||
private function doCreateRate($url, CurrencyPair $currencyPair): ExchangeRate | ||
{ | ||
$content = $this->request($url); | ||
$data = StringUtil::jsonToArray($content); | ||
|
||
if (isset($data['error'])) { | ||
if (isset($data['error']['code'])) { | ||
if (\in_array($data['error']['code'], [ | ||
'invalid_currency_codes', | ||
'invalid_base_currency', | ||
'no_rates_available', | ||
], true)) { | ||
throw new UnsupportedCurrencyPairException($currencyPair, $this); | ||
} | ||
if (isset($data['error']['message'])) { | ||
throw new Exception($data['error']['message']); | ||
} else { | ||
throw new Exception('Service return error code: '.$data['error']['code']); | ||
} | ||
} else { | ||
throw new Exception('Service return unhandled error'); | ||
} | ||
} | ||
|
||
if (isset($data['rates'][$currencyPair->getQuoteCurrency()])) { | ||
$date = new \DateTime($data['date']); | ||
$rate = $data['rates'][$currencyPair->getQuoteCurrency()]; | ||
|
||
return $this->createRate($currencyPair, (float) $rate, $date); | ||
} | ||
|
||
throw new UnsupportedCurrencyPairException($currencyPair, $this); | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function getName(): string | ||
{ | ||
return 'apilayer_exchange_rates_data'; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
6 changes: 6 additions & 0 deletions
6
tests/Fixtures/Service/ApiLayer/ExchangeRatesData/base_currency_access_restricted.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
{ | ||
"error":{ | ||
"code":"base_currency_access_restricted", | ||
"message":"An unexpected error ocurred. [Technical Support: support@apilayer.com]" | ||
} | ||
} |
10 changes: 10 additions & 0 deletions
10
tests/Fixtures/Service/ApiLayer/ExchangeRatesData/historical.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
{ | ||
"success":true, | ||
"timestamp":1618531199, | ||
"historical":true, | ||
"base":"EUR", | ||
"date":"2021-04-15", | ||
"rates":{ | ||
"USD":1.196953 | ||
} | ||
} |
6 changes: 6 additions & 0 deletions
6
tests/Fixtures/Service/ApiLayer/ExchangeRatesData/https_access_restricted.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
{ | ||
"error":{ | ||
"code":"https_access_restricted", | ||
"message":"Access Restricted - Your current Subscription Plan does not support HTTPS Encryption." | ||
} | ||
} |
6 changes: 6 additions & 0 deletions
6
tests/Fixtures/Service/ApiLayer/ExchangeRatesData/invalid_access_key.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
{ | ||
"error":{ | ||
"code":"invalid_access_key", | ||
"message":"You have not supplied a valid API Access Key. [Technical Support: support@apilayer.com]" | ||
} | ||
} |
6 changes: 6 additions & 0 deletions
6
tests/Fixtures/Service/ApiLayer/ExchangeRatesData/invalid_base_currency.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
{ | ||
"error":{ | ||
"code":"invalid_base_currency", | ||
"message":"An unexpected error ocurred. [Technical Support: support@apilayer.com]" | ||
} | ||
} |
6 changes: 6 additions & 0 deletions
6
tests/Fixtures/Service/ApiLayer/ExchangeRatesData/invalid_currency_codes.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
{ | ||
"error":{ | ||
"code":"invalid_currency_codes", | ||
"message":"You have provided one or more invalid Currency Codes. [Required format: currencies=EUR,USD,GBP,...]" | ||
} | ||
} |
6 changes: 6 additions & 0 deletions
6
tests/Fixtures/Service/ApiLayer/ExchangeRatesData/invalid_date.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
{ | ||
"error":{ | ||
"code":"invalid_date", | ||
"message":"You have entered an invalid date. [Required format: date=YYYY-MM-DD]" | ||
} | ||
} |
9 changes: 9 additions & 0 deletions
9
tests/Fixtures/Service/ApiLayer/ExchangeRatesData/latest.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
{ | ||
"success":true, | ||
"timestamp":1619171643, | ||
"base":"EUR", | ||
"date":"2021-04-23", | ||
"rates":{ | ||
"USD":1.20555 | ||
} | ||
} |
6 changes: 6 additions & 0 deletions
6
tests/Fixtures/Service/ApiLayer/ExchangeRatesData/no_rates_available.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
{ | ||
"error":{ | ||
"code":"no_rates_available", | ||
"message":"Your query did not return any results. Please try again." | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.