| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408 |
- <?php
- /**
- * Other webservices:
- * - http://www.webservicex.net/WS/WSDetails.aspx?WSID=10 (XML)
- * - http://www.webserviceshare.com/business/financial/currency/service/Noon-Foreign-Exchange-Rates.htm (XML)
- */
- App::uses('HttpSocket', 'Network/Http');
- App::uses('Xml', 'Utility');
- /**
- * Component to retreive calculate currencies
- *
- * example:
- * $result = $this->Currency->convert(2.5, 'EUR', 'USD');
- *
- * from: http://www.studiocanaria.com/articles/cakephp_currency_conversion_component
- * alternativly: http://www.currencyserver.de/webservice/CurrencyServerWebService.asmx/getXmlStream?provider=AVERAGE
- *
- * @author Mark Scherer
- * @license http://opensource.org/licenses/mit-license.php MIT
- */
- class CurrencyLib {
- const URL = 'http://www.ecb.int/stats/eurofxref/eurofxref-daily.xml';
- const URL_HISTORY = 'http://www.ecb.int/stats/eurofxref/eurofxref-hist.xml';
- //TODO: get information about a currency (name, ...)
- const URL_TABLE = 'http://www.ecb.int/rss/fxref-{currency}.html';
- public $baseCurrency = 'EUR';
- public $includeBitcoin = true;
- public $cacheFileUsed = false;
- public $cacheTime = DAY;
- /**
- * Converts the $amount from $fromCurrency to $toCurrency, formatted to
- * $decimals decimal places.
- *
- * @return float [Converted Currency Amount] or boolean FALSE on failure
- * @param $amount float
- * @param $fromCurrency string
- * @param $toCurrency string
- * @param $decimals integer[optional]default=2
- */
- public function convert($amount, $fromCurrency, $toCurrency, $decimals = 2) {
- //Get the rate table
- $rates = $this->_retrieveCurrencies();
- //Return result of conversion
- if (!array_key_exists($fromCurrency, $rates) || !array_key_exists($toCurrency, $rates)) {
- return false;
- }
- return number_format($amount / $rates[$fromCurrency] * $rates[$toCurrency], $decimals);
- }
- /**
- * Returns an array of rates in comparison the the $base currency given to $decimals
- * number of decimal places.
- *
- * @param $base string[optional]default='EUR'
- * @param $decimals integer[optional]default=2
- * @return array table or boolean FALSE on failure
- */
- public function table($base = 'EUR', $decimals = 2) {
- //Create array to holds rates
- $rateTable = [];
- //Get rate table array
- $rates = $this->_retrieveCurrencies();
- if (!array_key_exists($base, $rates)) {
- return false;
- }
- //Iterate throught each rate converting it against $base
- foreach ($rates as $key => $value) {
- $rate = 0;
- if ($value > 0) {
- $rate = 1 / $rates[$base] * $rates[$key];
- }
- $rateTable[$key] = number_format($rate, $decimals);
- }
- //Return result array
- return $rateTable;
- }
- /**
- * CurrencyLib::history()
- *
- * @param string $date Date in Format XXXX-XX-XX
- * @return array
- */
- public function history($date = null) {
- $history = $this->_retrieveHistory();
- if ($date) {
- if (!empty($history[$date])) {
- return $history[$date];
- }
- return [];
- }
- return $history;
- }
- /**
- * CurrencyComponent::isAvailable()
- *
- * @param mixed $currency
- * @return bool Success.
- */
- public function isAvailable($currency) {
- $rates = $this->_retrieveCurrencies();
- return array_key_exists($currency, $rates);
- }
- /**
- * @param string $name: "" (none), "history", "full" (both)
- * @return bool Success.
- */
- public function reset($name = 'full') {
- if ($name === 'full') {
- $name = '';
- Cache::delete('currencyListHistory');
- }
- return Cache::delete('currencyList' . ucfirst($name));
- }
- public function cacheFileUsed() {
- return $this->cacheFileUsed;
- }
- /**
- * @param string $code (3digit - e.g. EUR)
- * @param mixed $default (defaults to bool false)
- */
- public function getName($currency, $default = false) {
- if (empty($currency)) {
- return $default;
- }
- $currency = strtoupper($currency);
- $currencies = $this->currencies;
- if ($this->includeBitcoin) {
- $currencies['BTC'] = 'Bitcoin';
- }
- if (array_key_exists($currency, $currencies)) {
- return $currencies[$currency];
- }
- return $default;
- }
- /**
- * CurrencyComponent::_retrieveHistory()
- *
- * @return array
- */
- protected function _retrieveHistory() {
- if ($historyList = $this->_retrieve('history')) {
- return $historyList;
- }
- $currencies = $this->_loadXml(static::URL_HISTORY);
- // Filter down to just the rates
- $dates = $currencies['Envelope']['Cube']['Cube'];
- $historyList = [];
- foreach ($dates as $date) {
- $time = $date['@time'];
- foreach ($date['Cube'] as $currency) {
- $historyList[$time][$currency['@currency']] = $currency['@rate'];
- // European Central bank gives us everything against Euro so add this manually
- $historyList[$time][$this->baseCurrency] = 1;
- }
- }
- $this->_store($historyList, 'history');
- return $historyList;
- }
- /**
- * CurrencyComponent::_retrieveCurrencies()
- *
- * @return array
- */
- protected function _retrieveCurrencies() {
- if ($currencyList = $this->_retrieve()) {
- return $currencyList;
- }
- // Retrieve rates as an XML object
- $currencies = $this->_loadXml(static::URL);
- //Filter down to just the rates
- $currencies = $currencies['Envelope']['Cube']['Cube']['Cube'];
- //Create an array to hold the rates
- $currencyList = [];
- //European Central bank gives us everything against Euro so add this manually
- $currencyList[$this->baseCurrency] = 1;
- //Now iterate through and add the rates provided
- foreach ($currencies as $currency) {
- $currencyList[$currency['@currency']] = $currency['@rate'];
- }
- if ($this->includeBitcoin && ($res = $this->_getBitcoin())) {
- $currencyList['BTC'] = $res;
- }
- //Cache
- $this->_store($currencyList);
- return $currencyList;
- }
- protected function _getBitcoin() {
- App::uses('CurrencyBitcoinLib', 'Tools.Lib');
- $Btc = new CurrencyBitcoinLib();
- return $Btc->rate(['currency' => $this->baseCurrency]);
- }
- /**
- * @param string $name: "" (none), "history", "full" (both)
- */
- protected function _store($currencyList, $name = '') {
- $this->cacheFileUsed = false;
- Cache::write('currencyList' . ucfirst($name), serialize($currencyList));
- }
- /**
- * @param string $name: "" (none), "history", "full" (both)
- */
- protected function _retrieve($name = '') {
- $res = Cache::read('currencyList' . ucfirst($name));
- if ($res !== false) {
- $this->cacheFileUsed = true;
- return unserialize($res);
- }
- return false;
- }
- /**
- * CurrencyLib::_loadXml()
- *
- * @param string $url
- * @return array
- */
- protected function _loadXml($url) {
- $CurrencyXml = Xml::build($url);
- return Xml::toArray($CurrencyXml);
- }
- public $currencies = [
- 'AFA' => 'Afghanistan Afghani',
- 'ALL' => 'Albanian Lek',
- 'DZD' => 'Algerian Dinar',
- 'ARS' => 'Argentine Peso',
- 'AWG' => 'Aruba Florin',
- 'AUD' => 'Australian Dollar',
- 'BSD' => 'Bahamian Dollar',
- 'BHD' => 'Bahraini Dinar',
- 'BDT' => 'Bangladesh Taka',
- 'BBD' => 'Barbados Dollar',
- 'BZD' => 'Belize Dollar',
- 'BMD' => 'Bermuda Dollar',
- 'BTN' => 'Bhutan Ngultrum',
- 'BOB' => 'Bolivian Boliviano',
- 'BWP' => 'Botswana Pula',
- 'BRL' => 'Brazilian Real',
- 'GBP' => 'British Pound',
- 'BND' => 'Brunei Dollar',
- 'BIF' => 'Burundi Franc',
- 'XOF' => 'CFA Franc (BCEAO)',
- 'XAF' => 'CFA Franc (BEAC)',
- 'KHR' => 'Cambodia Riel',
- 'CAD' => 'Canadian Dollar',
- 'CVE' => 'Cape Verde Escudo',
- 'KYD' => 'Cayman Islands Dollar',
- 'CLP' => 'Chilean Peso',
- 'CNY' => 'Chinese Yuan',
- 'COP' => 'Colombian Peso',
- 'KMF' => 'Comoros Franc',
- 'CRC' => 'Costa Rica Colon',
- 'HRK' => 'Croatian Kuna',
- 'CUP' => 'Cuban Peso',
- 'CYP' => 'Cyprus Pound',
- 'CZK' => 'Czech Koruna',
- 'DKK' => 'Danish Krone',
- 'DJF' => 'Dijibouti Franc',
- 'DOP' => 'Dominican Peso',
- 'XCD' => 'East Caribbean Dollar',
- 'EGP' => 'Egyptian Pound',
- 'SVC' => 'El Salvador Colon',
- 'EEK' => 'Estonian Kroon',
- 'ETB' => 'Ethiopian Birr',
- 'EUR' => 'Euro',
- 'FKP' => 'Falkland Islands Pound',
- 'GMD' => 'Gambian Dalasi',
- 'GHC' => 'Ghanian Cedi',
- 'GIP' => 'Gibraltar Pound',
- 'XAU' => 'Gold Ounces',
- 'GTQ' => 'Guatemala Quetzal',
- 'GNF' => 'Guinea Franc',
- 'GYD' => 'Guyana Dollar',
- 'HTG' => 'Haiti Gourde',
- 'HNL' => 'Honduras Lempira',
- 'HKD' => 'Hong Kong Dollar',
- 'HUF' => 'Hungarian Forint',
- 'ISK' => 'Iceland Krona',
- 'INR' => 'Indian Rupee',
- 'IDR' => 'Indonesian Rupiah',
- 'IQD' => 'Iraqi Dinar',
- 'ILS' => 'Israeli Shekel',
- 'JMD' => 'Jamaican Dollar',
- 'JPY' => 'Japanese Yen',
- 'JOD' => 'Jordanian Dinar',
- 'KZT' => 'Kazakhstan Tenge',
- 'KES' => 'Kenyan Shilling',
- 'KRW' => 'Korean Won',
- 'KWD' => 'Kuwaiti Dinar',
- 'LAK' => 'Lao Kip',
- 'LVL' => 'Latvian Lat',
- 'LBP' => 'Lebanese Pound',
- 'LSL' => 'Lesotho Loti',
- 'LRD' => 'Liberian Dollar',
- 'LYD' => 'Libyan Dinar',
- 'LTL' => 'Lithuanian Lita',
- 'MOP' => 'Macau Pataca',
- 'MKD' => 'Macedonian Denar',
- 'MGF' => 'Malagasy Franc',
- 'MWK' => 'Malawi Kwacha',
- 'MYR' => 'Malaysian Ringgit',
- 'MVR' => 'Maldives Rufiyaa',
- 'MTL' => 'Maltese Lira',
- 'MRO' => 'Mauritania Ougulya',
- 'MUR' => 'Mauritius Rupee',
- 'MXN' => 'Mexican Peso',
- 'MDL' => 'Moldovan Leu',
- 'MNT' => 'Mongolian Tugrik',
- 'MAD' => 'Moroccan Dirham',
- 'MZM' => 'Mozambique Metical',
- 'MMK' => 'Myanmar Kyat',
- 'NAD' => 'Namibian Dollar',
- 'NPR' => 'Nepalese Rupee',
- 'ANG' => 'Neth Antilles Guilder',
- 'NZD' => 'New Zealand Dollar',
- 'NIO' => 'Nicaragua Cordoba',
- 'NGN' => 'Nigerian Naira',
- 'KPW' => 'North Korean Won',
- 'NOK' => 'Norwegian Krone',
- 'OMR' => 'Omani Rial',
- 'XPF' => 'Pacific Franc',
- 'PKR' => 'Pakistani Rupee',
- 'XPD' => 'Palladium Ounces',
- 'PAB' => 'Panama Balboa',
- 'PGK' => 'Papua New Guinea Kina',
- 'PYG' => 'Paraguayan Guarani',
- 'PEN' => 'Peruvian Nuevo Sol',
- 'PHP' => 'Philippine Peso',
- 'XPT' => 'Platinum Ounces',
- 'PLN' => 'Polish Zloty',
- 'QAR' => 'Qatar Rial',
- 'ROL' => 'Romanian Leu',
- 'RUB' => 'Russian Rouble',
- 'WST' => 'Samoa Tala',
- 'STD' => 'Sao Tome Dobra',
- 'SAR' => 'Saudi Arabian Riyal',
- 'SCR' => 'Seychelles Rupee',
- 'SLL' => 'Sierra Leone Leone',
- 'XAG' => 'Silver Ounces',
- 'SGD' => 'Singapore Dollar',
- 'SKK' => 'Slovak Koruna',
- 'SIT' => 'Slovenian Tolar',
- 'SBD' => 'Solomon Islands Dollar',
- 'SOS' => 'Somali Shilling',
- 'ZAR' => 'South African Rand',
- 'LKR' => 'Sri Lanka Rupee',
- 'SHP' => 'St Helena Pound',
- 'SDD' => 'Sudanese Dinar',
- 'SRG' => 'Surinam Guilder',
- 'SZL' => 'Swaziland Lilageni',
- 'SEK' => 'Swedish Krona',
- 'TRY' => 'Turkey Lira',
- 'CHF' => 'Swiss Franc',
- 'SYP' => 'Syrian Pound',
- 'TWD' => 'Taiwan Dollar',
- 'TZS' => 'Tanzanian Shilling',
- 'THB' => 'Thai Baht',
- 'TOP' => 'Tonga Pa\'anga',
- 'TTD' => 'Trinidad & Tobago Dollar',
- 'TND' => 'Tunisian Dinar',
- 'TRL' => 'Turkish Lira',
- 'USD' => 'U.S. Dollar',
- 'AED' => 'UAE Dirham',
- 'UGX' => 'Ugandan Shilling',
- 'UAH' => 'Ukraine Hryvnia',
- 'UYU' => 'Uruguayan New Peso',
- 'VUV' => 'Vanuatu Vatu',
- 'VEB' => 'Venezuelan Bolivar',
- 'VND' => 'Vietnam Dong',
- 'YER' => 'Yemen Riyal',
- 'YUM' => 'Yugoslav Dinar',
- 'ZMK' => 'Zambian Kwacha',
- 'ZWD' => 'Zimbabwe Dollar',
- ];
- }
|