1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace CL\CurrencyConvert; |
4
|
|
|
|
5
|
|
|
use SebastianBergmann\Money\Currency; |
6
|
|
|
use CL\PsrCache\CacheItemPoolInterface; |
7
|
|
|
use SimpleXMLElement; |
8
|
|
|
use Exception; |
9
|
|
|
use InvalidArgumentException; |
10
|
|
|
|
11
|
|
|
/** |
12
|
|
|
* @author Ivan Kerin <[email protected]> |
13
|
|
|
* @copyright 2014, Clippings Ltd. |
14
|
|
|
* @license http://spdx.org/licenses/BSD-3-Clause |
15
|
|
|
*/ |
16
|
|
|
class ECBSource implements SourceInterface |
17
|
|
|
{ |
18
|
|
|
/** |
19
|
|
|
* @var array |
20
|
|
|
*/ |
21
|
|
|
private $rates; |
22
|
|
|
|
23
|
|
|
/** |
24
|
|
|
* @var CachedRemoteData |
25
|
|
|
*/ |
26
|
|
|
private $cachedRemoteData; |
27
|
|
|
|
28
|
|
|
/** |
29
|
|
|
* @param CacheItemPoolInterface $cachePool |
30
|
|
|
* @param string $key |
31
|
|
|
*/ |
32
|
1 |
|
public function __construct(CacheItemPoolInterface $cachePool, $key = 'ECBSource') |
33
|
|
|
{ |
34
|
1 |
|
$this->cachedRemoteData = new CachedRemoteData( |
35
|
1 |
|
$cachePool, |
36
|
1 |
|
'http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml', |
37
|
|
|
$key |
38
|
1 |
|
); |
39
|
1 |
|
} |
40
|
|
|
|
41
|
|
|
/** |
42
|
|
|
* @return CachedRemoteData |
43
|
|
|
*/ |
44
|
1 |
|
public function getCachedRemoteData() |
45
|
|
|
{ |
46
|
1 |
|
return $this->cachedRemoteData; |
47
|
|
|
} |
48
|
|
|
|
49
|
|
|
/** |
50
|
|
|
* @return string |
51
|
|
|
* @throws Exception If error retrieving remote data |
52
|
|
|
*/ |
53
|
1 |
|
public function getData() |
54
|
|
|
{ |
55
|
1 |
|
return $this->cachedRemoteData->get(); |
56
|
|
|
} |
57
|
|
|
|
58
|
|
|
/** |
59
|
|
|
* @return array |
60
|
|
|
* @throws Exception If error retrieving remote data |
61
|
|
|
*/ |
62
|
2 |
|
public function getRates() |
63
|
|
|
{ |
64
|
2 |
|
if (! $this->rates) { |
|
|
|
|
65
|
2 |
|
$xml = new SimpleXMLElement($this->getData()); |
66
|
|
|
|
67
|
2 |
|
$rates = json_decode(json_encode($xml)); |
68
|
|
|
|
69
|
2 |
|
$this->rates = array('EUR' => '1'); |
70
|
|
|
|
71
|
2 |
|
if (! isset($rates->Cube->Cube->Cube)) { |
72
|
1 |
|
throw new Exception('Invalid data returned from source. Must have "Cube" tag'); |
73
|
|
|
} |
74
|
|
|
|
75
|
1 |
|
foreach ($rates->Cube->Cube->Cube as $rate) { |
76
|
1 |
|
$this->rates[$rate->{'@attributes'}->currency] = $rate->{'@attributes'}->rate; |
77
|
1 |
|
} |
78
|
1 |
|
} |
79
|
|
|
|
80
|
1 |
|
return $this->rates; |
81
|
|
|
} |
82
|
|
|
|
83
|
|
|
/** |
84
|
|
|
* @param Currency $currency |
85
|
|
|
* @return float |
86
|
|
|
* @throws Exception If error retrieving remote data |
87
|
|
|
*/ |
88
|
1 |
|
public function getRate(Currency $currency) |
89
|
|
|
{ |
90
|
1 |
|
$rates = $this->getRates(); |
91
|
1 |
|
$code = $currency->getCurrencyCode(); |
92
|
|
|
|
93
|
1 |
|
if (empty($rates[$code])) { |
94
|
1 |
|
throw new InvalidArgumentException( |
95
|
1 |
|
sprintf('%s (%s) is not supported by this source', $currency->getDisplayName(), $code) |
96
|
1 |
|
); |
97
|
|
|
} |
98
|
|
|
|
99
|
1 |
|
return (float) $rates[$code]; |
100
|
|
|
} |
101
|
|
|
|
102
|
|
|
/** |
103
|
|
|
* @param Currency $from |
104
|
|
|
* @param Currency $to |
105
|
|
|
* @return float |
106
|
|
|
*/ |
107
|
1 |
|
public function getRateBetween(Currency $from, Currency $to) |
108
|
|
|
{ |
109
|
1 |
|
$from = $this->getRate($from); |
110
|
1 |
|
$to = $this->getRate($to); |
111
|
|
|
|
112
|
1 |
|
return $from / $to; |
113
|
|
|
} |
114
|
|
|
} |
115
|
|
|
|
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.
Consider making the comparison explicit by using
empty(..)
or! empty(...)
instead.