The currency list hasn't been properly maintained for the last 4-5 years. While most currencies haven't changed since then, a handful currencies have become obsolete and countries have started using new ones (mostly due to inflation or migration to the euro). The list should be checked for outdated information, and we should add the currency information as listed at ISO 4217 - Wikipedia.

Comments

xano’s picture

I would like to parse all current and historical currencies from http://en.wikipedia.org/wiki/ISO4217 into the format we have for 7.x-1.x. For 7.x-2.x (later, in another issue) we can then add extra information such as the period of time the currencies were used in, the currencies they were replaced by, etc.

xano’s picture

I wrote the following script to crawl Wikipedia (or any other page that has HTML tables with currency information in the same format), so we can reuse it in the future. Example usage:

$currencies = currency_update_list('../testing/7/sites/all/modules/currency/currency_api/currency_api.module', CURRENCY_WIKIPEDIA_URL, array(CURRENCY_WIKIPEDIA_XPATH_QUERY_CURRENT));
echo currency_format_list($currencies);

Crawler script:


define('CURRENCY_WIKIPEDIA_URL', 'http://en.wikipedia.org/wiki/ISO4217');

define('CURRENCY_WIKIPEDIA_XPATH_QUERY_CURRENT', '/html/body/div[3]/div[3]/div[4]/table[2]');

define('CURRENCY_WIKIPEDIA_XPATH_QUERY_HISTORICAL', '/html/body/div[3]/div[3]/div[4]/table[5]');

/**
 * Currency requires t(), so mock it here.
 */
function t($t) {
  return $t;
}

/**
 * Convert a Wikipedia HTML table containing currency information to an array.
 *
 * @param string $html
 *
 * @return array
 */
function currency_parse_html_table($html) {
  $currencies = array();
  $dom = new DOMDocument();
  @$dom->loadHTML($html);
  $xpath = new DOMXpath($dom);
  $trs = $xpath->query('//tr');
  foreach ($trs as $tr) {
    $tds = $xpath->query('td', $tr);

    if ($tds->length) {
      // ISO 4217 Currency code.
      $code = $tds->item(0)->nodeValue;

      // ISO 4217 currency number.
      $number = $tds->item(1)->nodeValue;
      $number = is_numeric($number) ? $number : NULL;

      // The number of decimals.
      $decimals = $xpath->query('text()', $tds->item(2))->item(0);
      $decimals = $decimals ? (int) round($decimals->nodeValue) : NULL;

      // The English currency name.
      $name = $tds->item(3)->nodeValue;
      $name = trim(str_replace('(funds code)', '', $name));
      $name = trim(preg_replace('#\([^(]*?\)$#', '', $name));
      $name .= " ($code)";

      // Add the currency to the list.
      if (!is_null($decimals)) {
        $currencies[$code]['decimals'] = $decimals;
      }
      $currencies[$code]['name'] = $name;
      if (!is_null($number)) {
        $currencies[$code]['number'] = $number;
      }
    }
  }

  return $currencies;
}

/**
 * Get HTML tables that contain currency information.
 *
 * @param string $url
 *   The cURL-compatible URL to the location that contains the HTML tables.
 * @param array $xpath_queries
 *   The XPath queries of the tables on $url.
 *
 * @return array
 */
function currency_get_html_tables($url, array $xpath_queries) {
  $curl = curl_init($url);
  curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);
  curl_setopt($curl, CURLOPT_USERAGENT, 'ISO 4217 information collection script for http://drupal.org/project/currency.');
  $html = curl_exec($curl);
  curl_close($curl);

  $dom = new DOMDocument();
  $dom->loadHTML($html);
  $xpath = new DOMXpath($dom);
  $tables = array();
  foreach ($xpath_queries as $query) {
    $tables[] = $xpath->query($query)->item(0)->C14N();
  }

  return $tables;
}

/**
 * Update an existing currency list with new information.
 *
 * @param string $path
 *   The path to the file that contains currency_api_get_currencies().
 * @param string $url
 *   The cURL-compatible URL to the location that contains the HTML tables.
 * @param string $xpath_queries
 *   The XPath queries of the tables on $url.
 *
 * @return array
 *   The updated currency list in the format of currency_api_get_currencies().
 */
function currency_update_list($path, $url, array $xpath_queries) {
  require_once $path;

  $currencies = currency_api_get_currencies();
  foreach (currency_get_html_tables($url, $xpath_queries) as $table) {
    foreach (currency_parse_html_table($table) as $code => $info) {
      if (isset($currencies[$code])) {
        $currencies[$code] += $info;
      }
      else {
        $currencies[$code] = $info;
      }
    }
  }

  return $currencies;
}

/**
 * Format an array with currency information as raw PHP code.
 *
 * @param array $currencies
 *
 * @return string
 */
function currency_format_list(array $currencies) {
  ksort($currencies);
  $export = str_replace("=> \n  array", '=> array', var_export($currencies, TRUE)); 
  // Wrap currency names in t().
  $export = preg_replace("#'name' => '(.+?)',#", "'name' => t('\\1'),", $export);

  return $export;
}
xano’s picture

Assigned: Unassigned » xano
Status: Active » Needs review
StatusFileSize
new52.18 KB
xano’s picture

Bump. Also, if this is committed, we can probably release 7.x-1.1.

xano’s picture

StatusFileSize
new42.54 KB

As agreed upon with amateescu, here's another patch without the historical codes, which we're going to keep for version 2.

xano’s picture

StatusFileSize
new42.99 KB
xano’s picture

xano’s picture

Bump.

amateescu’s picture

Status: Needs review » Fixed

Committed to 7.x-1.x after cleaning up array ( to array( :)

http://drupalcode.org/project/currency.git/commit/1cc58a0

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.

xano’s picture

Assigned: xano » Unassigned