Rev 22 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 22 | Rev 23 | ||
---|---|---|---|
1 | <?php |
1 | <?php |
2 | 2 | ||
3 | // PHP library for CurrencyLayer |
3 | // PHP library for CurrencyLayer |
4 | // (C) 2017-2022 ViaThinkSoft, Daniel Marschall |
4 | // (C) 2017-2022 ViaThinkSoft, Daniel Marschall |
5 | // Revision: 2022-08-06 |
5 | // Revision: 2022-08-06 |
6 | // |
6 | // |
7 | // More information at https://currencylayer.com/documentation |
7 | // More information at https://currencylayer.com/documentation |
8 | 8 | ||
9 | # EXAMPLE |
9 | # EXAMPLE |
10 | /* |
10 | /* |
11 | $x = new CurCalc('cache.json', 'YOUR API KEY HERE', false); |
11 | $x = new CurCalc('cache.json', 'YOUR API KEY HERE', false); |
12 | if ($x->needs_download(1*60*60)) $x->download_exchange_rates(); // refresh data every hour |
12 | if ($x->needs_download(1*60*60)) $x->download_exchange_rates(); // refresh data every hour |
13 | $val = $x->convert_cur(100, 'EUR', 'RUB'); |
13 | $val = $x->convert_cur(100, 'EUR', 'RUB'); |
14 | echo "100 EUR are $val RUB.\n"; |
14 | echo "100 EUR are $val RUB.\n"; |
15 | */ |
15 | */ |
16 | 16 | ||
17 | # --- |
17 | # --- |
18 | 18 | ||
19 | class CurCalcException extends Exception {} |
19 | class CurCalcException extends Exception {} |
20 | class CurrencyLayerException extends CurCalcException {} |
20 | class CurrencyLayerException extends CurCalcException {} |
21 | 21 | ||
22 | class CurCalc { |
22 | class CurCalc { |
23 | 23 | ||
24 | protected $jsonfile = null; |
24 | protected $jsonfile = null; |
25 | protected $apikey = null; |
25 | protected $apikey = null; |
26 | protected $use_https = null; |
26 | protected $use_https = null; |
27 | function __construct($jsonfile, $apikey, $use_https=true) { |
27 | function __construct($jsonfile, $apikey, $use_https=true) { |
28 | $this->jsonfile = $jsonfile; |
28 | $this->jsonfile = $jsonfile; |
29 | $this->apikey = $apikey; |
29 | $this->apikey = $apikey; |
30 | $this->use_https = $use_https; |
30 | $this->use_https = $use_https; |
31 | } |
31 | } |
32 | 32 | ||
33 | public function exchange_rates_age() { |
33 | public function exchange_rates_age() { |
34 | $this->check_json_file_exists(); |
34 | $this->check_json_file_exists(); |
35 | 35 | ||
36 | // return time() - filemtime($this->jsonfile); |
36 | // return time() - filemtime($this->jsonfile); |
37 | 37 | ||
38 | $cont = file_get_contents($this->jsonfile); |
38 | $cont = file_get_contents($this->jsonfile); |
39 | $data = json_decode($cont, true); |
39 | $data = json_decode($cont, true); |
40 | $this->check_data_ok($data); |
40 | $this->check_data_ok($data); |
41 | return time() - $data['timestamp']; |
41 | return time() - $data['timestamp']; |
42 | } |
42 | } |
43 | 43 | ||
44 | public function needs_download($max_age=-1) { |
44 | public function needs_download($max_age=-1) { |
45 | if (!$this->check_json_file_exists(false)) { |
45 | if (!$this->check_json_file_exists(false)) { |
46 | return true; |
46 | return true; |
47 | } else if (!$this->check_data_ok(null, false)) { |
47 | } else if (!$this->check_data_ok(null, false)) { |
48 | return true; |
48 | return true; |
49 | } else if ($max_age == -1) { |
49 | } else if ($max_age == -1) { |
50 | return false; |
50 | return false; |
51 | } else { |
51 | } else { |
52 | return $this->exchange_rates_age() > $max_age; |
52 | return $this->exchange_rates_age() > $max_age; |
53 | } |
53 | } |
54 | } |
54 | } |
55 | 55 | ||
56 | private function check_json_file_exists($raise_exception=true) { |
56 | private function check_json_file_exists($raise_exception=true) { |
57 | if (!file_exists($this->jsonfile)) { |
57 | if (!file_exists($this->jsonfile)) { |
58 | if ($raise_exception) { |
58 | if ($raise_exception) { |
59 | throw new CurCalcException('JSON file '.$this->jsonfile.' not found. Please download it first.'); |
59 | throw new CurCalcException('JSON file '.$this->jsonfile.' not found. Please download it first.'); |
60 | } else { |
60 | } else { |
61 | return false; |
61 | return false; |
62 | } |
62 | } |
63 | } else { |
63 | } else { |
64 | return true; |
64 | return true; |
65 | } |
65 | } |
66 | } |
66 | } |
67 | 67 | ||
68 | private function check_data_ok($data, $raise_exception=true) { |
68 | private function check_data_ok($data, $raise_exception=true) { |
69 | if (is_null($data)) { |
69 | if (is_null($data)) { |
70 | $ret = $this->check_json_file_exists($raise_exception); |
70 | $ret = $this->check_json_file_exists($raise_exception); |
71 | if ((!$raise_exception) && (!$ret)) return $ret; |
71 | if ((!$raise_exception) && (!$ret)) return $ret; |
72 | $cont = file_get_contents($this->jsonfile); |
72 | $cont = file_get_contents($this->jsonfile); |
73 | $data = json_decode($cont, true); |
73 | $data = json_decode($cont, true); |
74 | } |
74 | } |
75 | 75 | ||
76 | if ((!isset($data['success'])) || ($data['success'] !== true)) { |
76 | if ((!isset($data['success'])) || ($data['success'] !== true)) { |
77 | if ($raise_exception) { |
77 | if ($raise_exception) { |
78 | if (isset($data['error'])) throw new CurrencyLayerException($data['error']['code'] . ' : ' . $data['error']['info']); |
78 | if (isset($data['error'])) throw new CurrencyLayerException($data['error']['code'] . ' : ' . $data['error']['info']); |
79 | throw new CurCalcException('JSON file '.$this->jsonfile.' does not contain valid request data. Please download it again.'); |
79 | throw new CurCalcException('JSON file '.$this->jsonfile.' does not contain valid request data. Please download it again.'); |
80 | } else { |
80 | } else { |
81 | return false; |
81 | return false; |
82 | } |
82 | } |
83 | } |
83 | } |
84 | 84 | ||
85 | return true; |
85 | return true; |
86 | } |
86 | } |
87 | 87 | ||
88 | public function download_exchange_rates() { |
88 | public function download_exchange_rates() { |
89 | // 1. Download |
89 | // 1. Download |
90 | $protocol = $this->use_https ? 'https' : 'http'; |
90 | $protocol = $this->use_https ? 'https' : 'http'; |
91 | $cont = file_get_contents($protocol.'://www.apilayer.net/api/live?access_key='.$this->apikey); |
91 | $cont = file_get_contents($protocol.'://www.apilayer.net/api/live?access_key='.$this->apikey); |
92 | if (!$cont) throw new CurCalcException('Failed to download from CurrencyLayer.'); |
92 | if (!$cont) throw new CurCalcException('Failed to download from CurrencyLayer.'); |
93 | 93 | ||
94 | // 2. Test result |
94 | // 2. Test result |
95 | $test_data = json_decode($cont, true); |
95 | $test_data = json_decode($cont, true); |
96 | $this->check_data_ok($test_data); |
96 | $this->check_data_ok($test_data); |
97 | 97 | ||
98 | // 3. Save |
98 | // 3. Save |
99 | if (!file_put_contents($this->jsonfile, $cont)) throw new CurCalcException('Saving to '.$this->jsonfile.' failed.'); |
99 | if (!file_put_contents($this->jsonfile, $cont)) throw new CurCalcException('Saving to '.$this->jsonfile.' failed.'); |
100 | 100 | ||
101 | // 4. OK |
101 | // 4. OK |
102 | $this->cache_exchange_rates_ary = null; |
102 | $this->cache_exchange_rates_ary = null; |
103 | return 0; |
103 | return 0; |
104 | } |
104 | } |
105 | 105 | ||
106 | private $cache_exchange_rates_ary = null; |
106 | private $cache_exchange_rates_ary = null; |
107 | private function get_exchange_rates_ary() { |
107 | private function get_exchange_rates_ary() { |
108 | if (!is_null($this->cache_exchange_rates_ary)) return $this->cache_exchange_rates_ary; |
108 | if (!is_null($this->cache_exchange_rates_ary)) return $this->cache_exchange_rates_ary; |
109 | 109 | ||
110 | $this->check_json_file_exists(); |
110 | $this->check_json_file_exists(); |
111 | $data = json_decode(file_get_contents($this->jsonfile), true); |
111 | $data = json_decode(file_get_contents($this->jsonfile), true); |
112 | $this->check_data_ok($data); |
112 | $this->check_data_ok($data); |
113 | 113 | ||
114 | $exchange_rates_ary = array(); |
114 | $exchange_rates_ary = array(); |
115 | $source = $data['source']; |
115 | $source = $data['source']; |
116 | $quotes = $data['quotes']; |
116 | $quotes = $data['quotes']; |
117 | $quotes['USDUSD'] = 1; // missing 06 Aug 2022. A bug?? Reported https://github.com/apilayer/currencylayer-API/issues/16 |
117 | $quotes[$source.$source] = 1; // "USDUSD" missing 06 Aug 2022. A bug?? Reported https://github.com/apilayer/currencylayer-API/issues/16 |
118 | foreach ($quotes as $n => $v) { |
118 | foreach ($quotes as $n => $v) { |
119 | if ($source == substr($n, 0, 3)) { |
119 | if ($source == substr($n, 0, 3)) { |
120 | $exchange_rates_ary[substr($n, 3, 3)] = $v; // key: USDxxx=12.345 |
120 | $exchange_rates_ary[substr($n, 3, 3)] = $v; // key: USDxxx=12.345 |
121 | } |
121 | } |
122 | } |
122 | } |
123 | unset($quotes); |
123 | unset($quotes); |
124 | 124 | ||
125 | asort($exchange_rates_ary); |
125 | asort($exchange_rates_ary); |
126 | $this->cache_exchange_rates_ary = $exchange_rates_ary; |
126 | $this->cache_exchange_rates_ary = $exchange_rates_ary; |
127 | return $exchange_rates_ary; |
127 | return $exchange_rates_ary; |
128 | } |
128 | } |
129 | 129 | ||
130 | public function get_supported_currencies() { |
130 | public function get_supported_currencies() { |
131 | return array_keys($this->get_exchange_rates_ary()); |
131 | return array_keys($this->get_exchange_rates_ary()); |
132 | } |
132 | } |
133 | 133 | ||
134 | public function convert_cur($value, $from_cur, $to_cur) { |
134 | public function convert_cur($value, $from_cur, $to_cur) { |
135 | $from_cur = strtoupper(trim($from_cur)); |
135 | $from_cur = strtoupper(trim($from_cur)); |
136 | $to_cur = strtoupper(trim($to_cur)); |
136 | $to_cur = strtoupper(trim($to_cur)); |
137 | 137 | ||
138 | if ($from_cur == $to_cur) return $value; |
138 | if ($from_cur == $to_cur) return $value; |
139 | 139 | ||
140 | $exchange_rates_ary = $this->get_exchange_rates_ary(); |
140 | $exchange_rates_ary = $this->get_exchange_rates_ary(); |
141 | 141 | ||
142 | if (!isset($exchange_rates_ary[$from_cur])) throw new CurCalcException("Source curreny $from_cur not found in exchange data."); |
142 | if (!isset($exchange_rates_ary[$from_cur])) throw new CurCalcException("Source curreny $from_cur not found in exchange data."); |
143 | if (!isset($exchange_rates_ary[$to_cur])) throw new CurCalcException("Destination curreny $to_cur not found in exchange data."); |
143 | if (!isset($exchange_rates_ary[$to_cur])) throw new CurCalcException("Destination curreny $to_cur not found in exchange data."); |
144 | 144 | ||
145 | return $value * $exchange_rates_ary[$to_cur]/$exchange_rates_ary[$from_cur]; |
145 | return $value * $exchange_rates_ary[$to_cur]/$exchange_rates_ary[$from_cur]; |
146 | } |
146 | } |
147 | 147 | ||
148 | } |
148 | } |
149 | 149 |