Created
April 27, 2020 08:09
-
-
Save ArrayIterator/fe7208225f212a5bb29c41cb67874238 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| namespace ArrayIterator\Currency\Daily; | |
| class Eu | |
| { | |
| const API_URI = 'http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml'; | |
| /** | |
| * @var string | |
| */ | |
| protected static $needTheDate; | |
| /** | |
| * @var int | |
| */ | |
| protected static $currentDate; | |
| /** | |
| * @var array | |
| */ | |
| protected static $rates; | |
| /** | |
| * {@inheritdoc} | |
| */ | |
| public function __construct() | |
| { | |
| self::$currentDate = strtotime(gmdate('Y-m-d H:i:s \G\M\T', time())); | |
| self::$needTheDate = strtotime(date('Y-m-d', self::$currentDate) .' 14:15 CET'); // for cache date identifier 2:15PM | |
| } | |
| /** | |
| * Set Error Handler | |
| */ | |
| protected static function createSetErrorHandler() | |
| { | |
| set_error_handler(function () { | |
| error_clear_last(); | |
| }); | |
| } | |
| /** | |
| * Restore Handler | |
| */ | |
| protected static function restoreErrorHandler() | |
| { | |
| restore_error_handler(); | |
| } | |
| /** | |
| * @return array | |
| */ | |
| public static function getRates() : array | |
| { | |
| if (! empty(self::$rates) && is_array(self::$rates)) { | |
| return self::$rates; | |
| } | |
| /* // add cache logic / database worker here | |
| $cacheKey = Cache::createUniqueKey(__CLASS__, 'rates'); | |
| if ((self::$needTheDate - self::$currentDate) < 3600) { | |
| Cache::delete($cacheKey); | |
| } | |
| $rates = Cache::get($cacheKey); | |
| if (is_array($rates) && !empty($rates)) { | |
| ksort($rates, SORT_ASC); | |
| return self::$rates = $rates; | |
| }*/ | |
| $xml = simplexml_load_file(self::API_URI); | |
| self::createSetErrorHandler(); | |
| $data = []; | |
| foreach ($xml->Cube->Cube->Cube as $item) { | |
| if (! isset($item['currency']) || ! isset($item['rate'])) { | |
| self::restoreErrorHandler(); | |
| return []; | |
| } | |
| $currency = strtoupper((string)$item['currency']); | |
| $rate = (string)$item['rate']; | |
| $data[$currency] = $rate; | |
| } | |
| self::restoreErrorHandler(); | |
| $data['EUR'] = 1 / $data['USD']; | |
| $data['USD'] = 1.0; | |
| foreach ($data as $key => $v) { | |
| if ($key === 'USD' || $key === 'EUR') { | |
| continue; | |
| } | |
| $data[$key] = (float) $data['EUR'] * $v; | |
| } | |
| ksort($data, SORT_ASC); | |
| // Cache::set($cacheKey, $data, 3600*24); | |
| return self::$rates = $data; | |
| } | |
| /** | |
| * @param string $code | |
| * | |
| * @return string|null string numeric | |
| */ | |
| public static function getRateFor(string $code) | |
| { | |
| $rates = self::getRates(); | |
| $code = self::normalizeCode($code); | |
| return isset($rates[$code]) | |
| ? $rates[$code] | |
| : null; | |
| } | |
| /** | |
| * @param string $code | |
| * | |
| * @return string | |
| */ | |
| public static function normalizeCode(string $code) : string | |
| { | |
| return strtoupper(trim($code)); | |
| } | |
| /** | |
| * @param string $from | |
| * @param string $to | |
| * | |
| * @return null | |
| */ | |
| public static function convert(string $from, string $to) | |
| { | |
| $from = self::normalizeCode($from); | |
| $to = self::normalizeCode($to); | |
| if ($from === '' || $to === '') { | |
| return null; | |
| } | |
| if ($from === $to) { | |
| return $from; | |
| } | |
| if ($from === 'USD') { | |
| return self::getRateFor($to); | |
| } | |
| $rates['USD'] = 1; | |
| $rates = self::getRates(); | |
| if (!isset($rates[$from]) || !isset($rates[$to])) { | |
| return null; | |
| } | |
| return ($rates[$to] / $rates[$from]); | |
| } | |
| /** | |
| * @param $value | |
| * @param string $from | |
| * @param string $to | |
| * | |
| * @return float|int|null | |
| */ | |
| public static function convertRate($value, string $from, string $to) | |
| { | |
| $rate = self::convert($from, $to); | |
| if ($rate === null) { | |
| return null; | |
| } | |
| return $value*$rate; | |
| } | |
| /** | |
| * @param $rate | |
| * @param int $roundAdd | |
| * | |
| * @return string | |
| */ | |
| public static function sanityNumber($rate, int $roundAdd = 1) | |
| { | |
| $roundAdd = $roundAdd < 0 ? 0 : $roundAdd; | |
| preg_match('/[\-\+]([0-9]+)$/', (string) $rate, $match); | |
| if (!empty($match[1])) { | |
| $rate = number_format((float) $rate, (int) $match[1]+$roundAdd, '.', ''); | |
| } elseif (strpos((string) $rate, '.')) { | |
| $ex = explode('.', (string) $rate); | |
| $ex = array_pop($ex); | |
| if (strlen($ex) > 5) { | |
| $rate = number_format((float) $rate, 5, '.', ''); | |
| } | |
| } | |
| return rtrim((string) $rate, '.0'); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment