AeliaWCEU_VAT_AssistantExchange_Rates_ECB_Model

Retrieves the exchange rates from the European Central Bank.

Defined (1)

The class is defined in the following location(s).

/src/lib/classes/exchange_rates/aelia-wc-exchangerates-ecb.php  
  1. class Exchange_Rates_ECB_Model extends \Aelia\WC\ExchangeRatesModel { 
  2. // @var string The URL template to use to query ECB 
  3. private $ecb_api_rates_url = 'http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml'; 
  4.  
  5. /** 
  6. * Tranforms the exchange rates received from ECB into an array of 
  7. * currency code => exchange rate pairs. 
  8. * @param string ecb_rates The XML received from ECB. 
  9. * @retur array 
  10. */ 
  11. protected function decode_rates($ecb_rates) { 
  12. $exchange_rates = array(); 
  13.  
  14. foreach($ecb_rates->Cube->Cube->Cube as $rate) { 
  15. $exchange_rates[(string)$rate['currency']] = (float)$rate['rate']; 
  16. // ECB feed is based against EUR, but it doesn't contain such currency. We 
  17. // can safely add it manually, with an exchange rate of 1 
  18. $exchange_rates['EUR'] = 1; 
  19. return $exchange_rates; 
  20.  
  21. /** 
  22. * Fetches all exchange rates from ECB API. 
  23. * @return object|bool An object containing the response from Open Exchange, or 
  24. * False in case of failure. 
  25. */ 
  26. private function fetch_all_rates() { 
  27. try { 
  28. $response = \Httpful\Request::get($this->ecb_api_rates_url) 
  29. ->expectsXml() 
  30. ->send(); 
  31.  
  32. // Debug 
  33. //var_dump("ECB RATES RESPONSE:", $response); die(); 
  34. if($response->hasErrors()) { 
  35. // OpenExchangeRates sends error details in response body 
  36. if($response->hasBody()) { 
  37. $response_data = $response->body; 
  38.  
  39. $this->add_error(self::ERR_ERROR_RETURNED,  
  40. sprintf(__('Error returned by ECB. ' . 
  41. 'Error code: %s. Error message: %s - %s.',  
  42. Definitions::TEXT_DOMAIN),  
  43. $response_data->status,  
  44. $response_data->message,  
  45. $response_data->description)); 
  46. return false; 
  47. return $response->body; 
  48. catch(Exception $e) { 
  49. $this->add_error(self::ERR_EXCEPTION_OCCURRED,  
  50. sprintf(__('Exception occurred while retrieving the exchange rates from ECB. ' . 
  51. 'Error message: %s.',  
  52. Definitions::TEXT_DOMAIN),  
  53. $e->getMessage())); 
  54. return null; 
  55.  
  56. /** 
  57. * Returns current exchange rates for the specified currency. 
  58. * @param string base_currency The base currency. 
  59. * @return array An array of Currency => Exchange Rate pairs. 
  60. */ 
  61. private function current_rates($base_currency) { 
  62. if(empty($this->_current_rates) || 
  63. $this->_base_currency != $base_currency) { 
  64.  
  65. $cache_key = md5(get_class($this)) . $base_currency; 
  66. // Try to get the cached rates for the specified base currency, if any 
  67. $this->_current_rates = $this->get_cached_exchange_rates($cache_key); 
  68. if(!empty($this->_current_rates)) { 
  69. return $this->_current_rates; 
  70.  
  71. // Fetch exchange rates 
  72. $ecb_exchange_rates = $this->fetch_all_rates(); 
  73. if($ecb_exchange_rates === false) { 
  74. return null; 
  75.  
  76. // Debug 
  77. //var_dump($ecb_exchange_rates);die(); 
  78.  
  79. // ECB rates are returned as JSON representation of an array of objects. 
  80. // We need to transform it into an array of currency => rate pairs 
  81. $exchange_rates = $this->decode_rates($ecb_exchange_rates); 
  82. if(!is_array($exchange_rates)) { 
  83. $this->add_error(self::ERR_UNEXPECTED_ERROR_FETCHING_EXCHANGE_RATES,  
  84. __('An unexpected error occurred while fetching exchange rates ' . 
  85. 'from ECB. The most common cause of this issue is the ' . 
  86. 'absence of PHP CURL extension. Please make sure that ' . 
  87. 'PHP CURL is installed and configured in your system.',  
  88. Definitions::TEXT_DOMAIN)); 
  89. return array(); 
  90.  
  91. // Since we didn't get the exchange rates related to the base currency,  
  92. // but in the default base currency used by OpenExchange, we need to 
  93. // recalculate them against the base currency we would like to use 
  94. $this->_current_rates = $this->rebase_rates($exchange_rates, $base_currency); 
  95. $this->_base_currency = $base_currency; 
  96.  
  97. // Cache the exchange rates 
  98. $this->cache_exchange_rates($cache_key, $this->_current_rates); 
  99. return $this->_current_rates; 
  100.  
  101. /** 
  102. * Recaculates the exchange rates using another base currency. This method 
  103. * is invoked because the rates fetched from ECB are relative to BitCoin,  
  104. * but another currency is most likely is used by WooCommerce. 
  105. * @param array exchange_rates The exchange rates retrieved from ECB. 
  106. * @param string base_currency The base currency against which the rates should 
  107. * be recalculated. 
  108. * @return array An array of currency => exchange rate pairs. 
  109. */ 
  110. private function rebase_rates(array $exchange_rates, $base_currency) { 
  111. $recalc_rate = get_value($base_currency, $exchange_rates); 
  112. //var_dump($base_currency, $exchange_rates); 
  113.  
  114. if(empty($recalc_rate)) { 
  115. $this->add_error(self::ERR_BASE_CURRENCY_NOT_FOUND,  
  116. sprintf(__('Could not rebase rates against base currency "%s". ' . 
  117. 'Currency not found in data returned by ECB.',  
  118. Definitions::TEXT_DOMAIN),  
  119. $base_currency)); 
  120. return null; 
  121.  
  122. $result = array(); 
  123. foreach($exchange_rates as $currency => $rate) { 
  124. $result[$currency] = $rate / $recalc_rate; 
  125.  
  126. // Debug 
  127. //var_dump($result); die(); 
  128. return $result; 
  129.  
  130. /** 
  131. * Returns the exchange rate of a currency in respect to a base currency. 
  132. * @param string base_currency The code of the base currency. 
  133. * @param string currency The code of the currency for which to find the 
  134. * Exchange Rate. 
  135. * @return float 
  136. */ 
  137. protected function get_rate($base_currency, $currency) { 
  138. $current_rates = $this->current_rates($base_currency); 
  139. return get_value($currency, $current_rates); 
  140.  
  141. /** 
  142. * Class constructor. 
  143. * @param array An array of Settings that can be used to override the ones 
  144. * currently saved in the configuration. 
  145. * @return Exchange_Rates_ECB_Model. 
  146. */ 
  147. public function __construct($settings = null) { 
  148. parent::__construct($settings);