You are here

function _invoice_money_format in Invoice 7

Same name and namespace in other branches
  1. 6 invoice_helpers.inc \_invoice_money_format()

Alternative for the default PHP money_format() function

The function money_format() is only defined if the system has strfmon capabilities. For example, Windows does not, so money_format() is undefined in Windows. This function will then be used as alternative, it tries to work just the same as the original function.

This function is tested using a XAMPP installation with Apache and PHP 5.2.6 on Windows XP. The code of this function is based on http://nl.php.net/manual/en/function.money-format.php#81901

1 call to _invoice_money_format()
_invoice_format_money in ./invoice_helpers.inc
Returns a number in money format according to the locale set on the invoice settings page

File

./invoice_helpers.inc, line 74
Invoice module

Code

function _invoice_money_format($format, $number) {
  $regex = array(
    '/%((?:[\\^!\\-]|\\+|\\(|\\=.)*)([0-9]+)?(?:#([0-9]+))?',
    '(?:\\.([0-9]+))?([in%])/',
  );
  $regex = implode('', $regex);
  if (setlocale(LC_MONETARY, NULL) == '') {
    setlocale(LC_MONETARY, '');
  }
  $locale = localeconv();
  $number = floatval($number);
  if (!preg_match($regex, $format, $fmatch)) {
    trigger_error("No format specified or invalid format", E_USER_WARNING);
    return $number;
  }
  $flags = array(
    'fillchar' => preg_match('/\\=(.)/', $fmatch[1], $match) ? $match[1] : ' ',
    'nogroup' => preg_match('/\\^/', $fmatch[1]) > 0,
    'usesignal' => preg_match('/\\+|\\(/', $fmatch[1], $match) ? $match[0] : '+',
    'nosimbol' => preg_match('/\\!/', $fmatch[1]) > 0,
    'isleft' => preg_match('/\\-/', $fmatch[1]) > 0,
  );
  $width = trim($fmatch[2]) ? (int) $fmatch[2] : 0;
  $left = trim($fmatch[3]) ? (int) $fmatch[3] : 0;
  $right = trim($fmatch[4]) ? (int) $fmatch[4] : $locale['int_frac_digits'];
  $conversion = $fmatch[5];
  $positive = TRUE;
  if ($number < 0) {
    $positive = FALSE;
    $number *= -1;
  }
  $letter = $positive ? 'p' : 'n';
  $prefix = $suffix = $cprefix = $csuffix = $signal = '';
  if (!$positive) {
    $signal = $locale['negative_sign'];
    switch (TRUE) {
      case $locale['n_sign_posn'] == 0 || $flags['signal'] == '(':

        // Probably doesn't work right with negative numbers, bug fix on the line below

        //case $locale['n_sign_posn'] == 0 || $flags['usesignal'] == '(': // Fixed bug according to: http://nl.php.net/manual/en/function.money-format.php#86914
        $prefix = '(';
        $suffix = ')';
        break;
      case $locale['n_sign_posn'] == 1:
        $prefix = $signal;
        break;
      case $locale['n_sign_posn'] == 2:
        $suffix = $signal;
        break;
      case $locale['n_sign_posn'] == 3:
        $cprefix = $signal;
        break;
      case $locale['n_sign_posn'] == 4:
        $csuffix = $signal;
        break;
    }
  }
  if (!$flags['nosimbol']) {
    $currency = $cprefix;
    $currency .= $conversion == 'i' ? $locale['int_curr_symbol'] : $locale['currency_symbol'];
    $currency .= $csuffix;
  }
  else {
    $currency = '';
  }
  $space = $locale["{$letter}_sep_by_space"] ? ' ' : '';
  $number = number_format($number, $right, $locale['mon_decimal_point'], $flags['nogroup'] ? '' : $locale['mon_thousands_sep']);
  $number = explode($locale['mon_decimal_point'], $number);
  $n = strlen($prefix) + strlen($currency);
  if ($left > 0 && $left > $n) {
    if ($flags['isleft']) {
      $number[0] .= str_repeat($flags['fillchar'], $left - $n);
    }
    else {
      $number[0] = str_repeat($flags['fillchar'], $left - $n) . $number[0];
    }
  }
  $number = implode($locale['mon_decimal_point'], $number);
  if ($locale["{$letter}_cs_precedes"]) {
    $number = $prefix . $currency . $space . $number . $suffix;
  }
  else {
    $number = $prefix . $number . $space . $currency . $suffix;
  }
  if ($width > 0) {
    $number = str_pad($number, $width, $flags['fillchar'], $flags['isleft'] ? STR_PAD_RIGHT : STR_PAD_LEFT);
  }
  $format = str_replace($fmatch[0], $number, $format);
  return $format;
}