Skip to content

Commit

Permalink
Merge pull request #21 from florianv/array
Browse files Browse the repository at this point in the history
Implemented historical rates support in the php array service
  • Loading branch information
florianv authored Jun 3, 2017
2 parents b06de0c + 7c8529b commit 978fb4c
Show file tree
Hide file tree
Showing 11 changed files with 214 additions and 33 deletions.
17 changes: 17 additions & 0 deletions .php_cs.dist
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php
return PhpCsFixer\Config::create()
->setRules(array(
'@Symfony' => true,
'@Symfony:risky' => true,
'array_syntax' => array('syntax' => 'short'),
'no_unreachable_default_argument_value' => false,
'heredoc_to_nowdoc' => false,
'phpdoc_annotation_without_dot' => false,
))
->setRiskyAllowed(true)
->setFinder(
PhpCsFixer\Finder::create()
->in(__DIR__.'/src')
->in(__DIR__.'/tests')
)
;
1 change: 0 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ php:
- 5.6
- 7.0
- 7.1
- hhvm

sudo: false

Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ Here is the list of the currently implemented services.
| [Central Bank of the Czech Republic](http://www.cnb.cz) | * | CZK | No |
| [Russian Central Bank](http://http://www.cbr.ru) | * | RUB | Yes |
| [currencylayer](https://currencylayer.com) | USD (free), * (paid) | * | Yes |
| Array | * | * | Yes |

## Credits

Expand Down
15 changes: 14 additions & 1 deletion doc/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,20 @@ $service = new Chain([
new Google(),
new NationalBankOfRomania(),
new OpenExchangeRates($client, null, ['app_id' => 'app_id', 'enterprise' => false]),
new PhpArray(['EUR/USD' => new ExchangeRate('1.5')]),
new PhpArray(
[
'EUR/USD' => new ExchangeRate('1.1'),
'EUR/GBP' => 1.5
],
[
'2017-01-01' => [
'EUR/USD' => new ExchangeRate('1.5')
],
'2017-01-03' => [
'EUR/GBP' => 1.3
],
]
),
new WebserviceX(),
new Xignite($client, null, ['token' => 'token']),
new Yahoo()
Expand Down
2 changes: 1 addition & 1 deletion src/Exception/ChainException.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ class ChainException extends Exception
*/
public function __construct(array $exceptions)
{
$messages = array_map(function(\Exception $exception) {
$messages = array_map(function (\Exception $exception) {
return sprintf(
'%s: %s',
get_class($exception),
Expand Down
2 changes: 1 addition & 1 deletion src/Service/HistoricalService.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
use Exchanger\Exception\UnsupportedCurrencyPairException;

/**
* Base class for historical services.
* Base class for historical http based services.
*
* @author Florian Voutzinos <[email protected]>
*/
Expand Down
103 changes: 85 additions & 18 deletions src/Service/PhpArray.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,10 @@

use Exchanger\Contract\ExchangeRateQuery;
use Exchanger\Contract\ExchangeRateService;
use Exchanger\Contract\HistoricalExchangeRateQuery;
use Exchanger\Exception\InternalException;
use Exchanger\Exception\UnsupportedCurrencyPairException;
use Exchanger\ExchangeRate;
use Exchanger\HistoricalExchangeRateQuery;

/**
* Service that retrieves rates from an array.
Expand All @@ -25,20 +26,29 @@
final class PhpArray implements ExchangeRateService
{
/**
* The rates.
* The latest rates.
*
* @var ExchangeRate[]
* @var ExchangeRate[]|string[]
*/
private $rates;
private $latestRates;

/**
* The historical rates.
*
* @var ExchangeRate[][]|string[][]
*/
private $historicalRates;

/**
* Constructor.
*
* @param ExchangeRate[]|string[] $rates An array of rates indexed by the corresponding currency pair symbol
* @param ExchangeRate[]|string[] $latestRates An array of rates indexed by the corresponding currency pair symbol
* @param ExchangeRate[][]|string[][] $historicalRates An array of rates indexed by the date in Y-m-d format
*/
public function __construct(array $rates)
public function __construct(array $latestRates, array $historicalRates = [])

This comment has been minimized.

Copy link
@b1rdex

b1rdex Aug 8, 2017

Oh man, this is major breaking change! Spent some time debugging what's wrong. There must be check for keys of $historicalRates (they must be date strings) to prevent such situations.

{
$this->rates = $rates;
$this->latestRates = $latestRates;
$this->historicalRates = $historicalRates;
}

/**
Expand All @@ -47,18 +57,47 @@ public function __construct(array $rates)
public function getExchangeRate(ExchangeRateQuery $exchangeQuery)
{
$currencyPair = $exchangeQuery->getCurrencyPair();
$rate = $this->rates[$currencyPair->__toString()];

if (is_scalar($rate)) {
$rate = new ExchangeRate($rate);
} elseif (!$rate instanceof ExchangeRate) {
throw new InternalException(sprintf(
'Rates passed to the PhpArray service must be Rate instances or scalars "%s" given.',
gettype($rate)
));
if ($exchangeQuery instanceof HistoricalExchangeRateQuery) {
if ($rate = $this->getHistoricalExchangeRate($exchangeQuery)) {
return $rate;
}
} elseif ($rate = $this->getLatestExchangeRate($exchangeQuery)) {
return $rate;
}

return $rate;
throw new UnsupportedCurrencyPairException($currencyPair, $this);
}

/**
* Gets the latest rate.
*
* @param ExchangeRateQuery $exchangeQuery
*
* @return ExchangeRate|null
*
* @throws InternalException
*/
private function getLatestExchangeRate(ExchangeRateQuery $exchangeQuery)
{
$currencyPair = $exchangeQuery->getCurrencyPair();

return $this->processRateValue($this->latestRates[(string) $currencyPair]);
}

/**
* Gets an historical rate.
*
* @param HistoricalExchangeRateQuery $exchangeQuery
*
* @return ExchangeRate|null
*/
private function getHistoricalExchangeRate(HistoricalExchangeRateQuery $exchangeQuery)
{
$date = $exchangeQuery->getDate();
$currencyPair = $exchangeQuery->getCurrencyPair();

return $this->processRateValue($this->historicalRates[$date->format('Y-m-d')][(string) $currencyPair]);
}

/**
Expand All @@ -68,7 +107,35 @@ public function supportQuery(ExchangeRateQuery $exchangeQuery)
{
$currencyPair = $exchangeQuery->getCurrencyPair();

return !$exchangeQuery instanceof HistoricalExchangeRateQuery
&& isset($this->rates[$currencyPair->__toString()]);
if ($exchangeQuery instanceof HistoricalExchangeRateQuery) {
$date = $exchangeQuery->getDate();

return isset($this->historicalRates[$date->format('Y-m-d')][(string) $currencyPair]);
}

return isset($this->latestRates[(string) $currencyPair]);
}

/**
* Processes the rate value.
*
* @param mixed $rate
*
* @return ExchangeRate
*
* @throws InternalException
*/
private function processRateValue($rate)
{
if (is_scalar($rate)) {
$rate = new ExchangeRate($rate);
} elseif (!$rate instanceof ExchangeRate) {
throw new InternalException(sprintf(
'Rates passed to the PhpArray service must be Rate instances or scalars "%s" given.',
gettype($rate)
));
}

return $rate;
}
}
4 changes: 1 addition & 3 deletions src/Service/RussianCentralBank.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,10 @@
use Exchanger\Exception\UnsupportedCurrencyPairException;
use Exchanger\Exception\UnsupportedDateException;
use Exchanger\ExchangeRate;
use Exchanger\Service\HistoricalService;
use Exchanger\StringUtil;

/**
* Russian Central Bank Service.
*
*/
class RussianCentralBank extends HistoricalService
{
Expand Down Expand Up @@ -48,7 +46,7 @@ protected function getHistoricalExchangeRate(HistoricalExchangeRateQuery $exchan
$baseCurrency = $exchangeQuery->getCurrencyPair()->getBaseCurrency();
$formattedDate = $exchangeQuery->getDate()->format('d.m.Y');

$content = $this->request(self::URL . '?' . http_build_query(['date_req' => $formattedDate]));
$content = $this->request(self::URL.'?'.http_build_query(['date_req' => $formattedDate]));
$element = StringUtil::xmlToElement($content);

$elements = $element->xpath('./Valute[CharCode="'.$baseCurrency.'"]');
Expand Down
4 changes: 2 additions & 2 deletions src/Service/Service.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
use Exchanger\Contract\ExchangeRateService;

/**
* Base class for services.
* Base class for http based services.
*
* @author Florian Voutzinos <[email protected]>
*/
Expand Down Expand Up @@ -74,7 +74,7 @@ public function processOptions(array &$options)
* Fetches the content of the given url.
*
* @param string $url
* @param array $headers
* @param array $headers
*
* @return string
*/
Expand Down
4 changes: 2 additions & 2 deletions tests/Tests/Exception/ChainExceptionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,10 @@ public function setUp()
$this->exception1 = new InternalException('Something bad happened.');
$this->exception2 = new \Exception('General exception.');

$this->chainException = new ChainException(array(
$this->chainException = new ChainException([
$this->exception1,
$this->exception2,
));
]);
}

/**
Expand Down
Loading

0 comments on commit 978fb4c

Please sign in to comment.