Skip to content

Instantly share code, notes, and snippets.

@ArrayIterator
Created April 27, 2020 08:09
Show Gist options
  • Select an option

  • Save ArrayIterator/fe7208225f212a5bb29c41cb67874238 to your computer and use it in GitHub Desktop.

Select an option

Save ArrayIterator/fe7208225f212a5bb29c41cb67874238 to your computer and use it in GitHub Desktop.
<?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