Subversion Repositories currency_converter

Rev

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

  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'];
  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) {
  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.  
  148. }
  149.