Subversion Repositories currency_converter

Rev

Rev 22 | Details | Compare with Previous | Last modification | View Log | RSS feed

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