0
votes

I have a default currency as USD.

The part of the class below allow to convert different currencies but my problem is the conversion is always based in EUR as default.

How to update the function to use USD as default if it selected ?

Thank you

EUR = 1 (default) USD = 1.10 This approach works very well for any currencies

EUR = 0.9 USD = 1 (default) This approach do not work because USD is in default and the result is always like above.

Note : $currenciesAdmin->getAll() take all the currencies with the code (EUR) and the title (Euro) for example.

The value of EUR is always null because the convertion is based on EUR as default (see link ecb.europa.eu for the values)

public function getConvertCurrency()
{

  $currenciesAdmin = new CurrenciesAdmin();

  $XML = HTTP::getResponse([
    'url' => 'https://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml'
  ]);

  if (empty($XML)) {
    throw new \Exception('Can not load currency rates from the European Central Bank website');
  }

  $currencies = [];

  foreach ($currenciesAdmin->getAll() as $c) {
    $currencies[$c['id']] = null;
  }

  $XML = new \SimpleXMLElement($XML);

  foreach ($XML->Cube->Cube->Cube as $rate) {
    if (array_key_exists((string)$rate['currency'], $currencies)) {
      $currencies[(string)$rate['currency']] = (float)$rate['rate'];
    }
  }

  foreach ($currencies as $code => $value) {
    if (!is_null($value)) {
      try {
        $this->db->save('currencies', [
          'value' => $value,
          'last_updated' => 'now()'
        ], [
          'code' => $code
        ]);
      } catch (\PDOException $e) {
        trigger_error($e->getMessage());
      }
    }
  }
}
1

1 Answers

0
votes

Normally you'd use an API that allows you to select a base currency and do the conversion that way. That said, if you need to work with this dataset I believe the following approach may work for you:

$sourceCurrency = 'EUR'; // Your data source uses this as the base value
$defaultCurrency = 'USD'; // Read this from desired location

$currencies = [];
foreach ($currenciesAdmin->getAll() as $c) {
  $currencies[$c['id']] = null;
}

// This is a constant
$currencies[$sourceCurrency] = 1;

$XML = new \SimpleXMLElement($XML);

foreach ($XML->Cube->Cube->Cube as $rate) {
  $code = (string)$rate['currency'];
  if (array_key_exists($code, $currencies)) {
    $currencies[$code] = (float)$rate['rate'];
  }
}

if ($defaultCurrency !== $sourceCurrency) {
  // Conversion is required
  $convertedCurrencies = [];
  foreach (array_keys($currencies) as $code) {
    $convertedCurrencies[$code] = $currencies[$code] / $currencies[$defaultCurrency];
  }
  $currencies = $convertedCurrencies;
}

// Use $currencies as normal with the adjusted values

Below is an interactive demo that contains the JavaScript equivalent code that you can test in your browser:

(() => {

  const currencyDropdown = document.querySelector('select');
  const selForm = document.querySelector('form');
  const sourceCurrency = 'EUR';
  let cachedData = null;
  const generateTable = async(first) => {
    const defaultCurrency = first ? sourceCurrency : currencyDropdown.options[currencyDropdown.selectedIndex].value;

    if (cachedData === null)
      cachedData = await fetch('https://cors-anywhere.herokuapp.com/https://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml').then(r => r.text()).then(str => (new window.DOMParser()).parseFromString(str, "text/xml"));

    let currencies = Array.from(cachedData.querySelectorAll('Cube > Cube > Cube'))
      .reduce((a, c) => ({ ...a,
        [c.attributes.currency.value]: parseFloat(c.attributes.rate.value)
      }), {});
    currencies.EUR = 1;
    const currencyKeys = Object.keys(currencies).sort();
    currencyDropdown.innerHTML = currencyKeys.map(code => `<option${code === defaultCurrency ? ' selected' : ''}>${code}</option>`)
    if (sourceCurrency !== defaultCurrency) {
      const convertedCurrencies = currencyKeys.reduce((a, code) => ({
        ...a,
        [code]: currencies[code] / currencies[defaultCurrency],
      }), {});
      currencies = convertedCurrencies;
    }

    let tbl = document.querySelector('table');
    if (tbl !== null)
      tbl.remove();
    tbl = document.createElement('table');
    tbl.innerHTML = '<tr><th>code</th><th>value</th></tr>' +
      (currencyKeys.map(
        code => `<tr><td>${code}</td><td>${currencies[code]} ${defaultCurrency}</td></tr>`).join(''));
    document.body.appendChild(tbl);
    selForm.hidden = false;
  };
  selForm.addEventListener('submit', (e) => {
    e.preventDefault();

    generateTable(false);
  });
  generateTable(true);

})();
<form hidden>
  <label>
Default currency:
<select></select>
<input type="submit">
</label>
</form>
<table>
  <tr>
    <td>Loading&hellip;</td>
  </tr>
</table>