Merge pull request #587 from shama/patch-mb-number

Support multiple bytes with thousands/decimals in CakeNumber::format < PHP5.4
This commit is contained in:
Mark Story 2012-03-31 10:22:25 -07:00
commit 54bfa4cc05
2 changed files with 86 additions and 1 deletions

View file

@ -72,6 +72,54 @@ class CakeNumberTest extends CakeTestCase {
$this->assertEquals($expected, $result); $this->assertEquals($expected, $result);
} }
/**
* testMultibyteFormat
*
* @return void
*/
public function testMultibyteFormat() {
$value = '5199100.0006';
$result = $this->Number->format($value, array(
'thousands' => '&nbsp;',
'decimals' => '&amp;',
'places' => 3,
'escape' => false,
'before' => '',
));
$expected = '5&nbsp;199&nbsp;100&amp;001';
$this->assertEqual($expected, $result);
$value = 1000.45;
$result = $this->Number->format($value, array(
'thousands' => ',,',
'decimals' => '.a',
'escape' => false,
));
$expected = '$1,,000.a45';
$this->assertEqual($expected, $result);
$value = 519919827593784.00;
$this->Number->addFormat('RUR', array(
'thousands' => 'ø€ƒ‡™',
'decimals' => '(§.§)',
'escape' => false,
'wholeSymbol' => '€',
'wholePosition' => 'after',
));
$result = $this->Number->currency($value, 'RUR');
$expected = '519ø€ƒ‡™919ø€ƒ‡™827ø€ƒ‡™593ø€ƒ‡™784(§.§)00€';
$this->assertEquals($expected, $result);
$value = '13371337.1337';
$result = CakeNumber::format($value, array(
'thousands' => '- |-| /-\ >< () |2 -',
'decimals' => '- £€€† -',
'before' => ''
));
$expected = '13- |-| /-\ &gt;&lt; () |2 -371- |-| /-\ &gt;&lt; () |2 -337- £€€† -13';
$this->assertEquals($expected, $result);
}
/** /**
* Test currency method. * Test currency method.
* *

View file

@ -60,6 +60,13 @@ class CakeNumber {
'zero' => '0', 'places' => 2, 'thousands' => ',', 'decimals' => '.','negative' => '()', 'escape' => true, 'zero' => '0', 'places' => 2, 'thousands' => ',', 'decimals' => '.','negative' => '()', 'escape' => true,
); );
/**
* If native number_format() should be used. If >= PHP5.4
*
* @var boolean
*/
protected static $_numberFormatSupport = null;
/** /**
* Formats a number with a level of precision. * Formats a number with a level of precision.
* *
@ -142,7 +149,7 @@ class CakeNumber {
extract($options); extract($options);
} }
$out = $before . number_format($number, $places, $decimals, $thousands) . $after; $out = $before . self::_number_format($number, $places, $decimals, $thousands) . $after;
if ($escape) { if ($escape) {
return h($out); return h($out);
@ -150,6 +157,36 @@ class CakeNumber {
return $out; return $out;
} }
/**
* Alternative number_format() to accommodate multibyte decimals and thousands < PHP 5.4
*
* @param float $number
* @param integer $places
* @param string $decimals
* @param string $thousands
* @return string
*/
protected static function _number_format($number, $places = 0, $decimals = '.', $thousands = ',') {
if (!isset(self::$_numberFormatSupport)) {
self::$_numberFormatSupport = version_compare(PHP_VERSION, '5.4.0', '>=');
}
if (self::$_numberFormatSupport) {
return number_format($number, $places, $decimals, $thousands);
}
$number = number_format($number, $places, '.', '');
$after = '';
$foundDecimal = strpos($number, '.');
if ($foundDecimal !== false) {
$after = substr($number, $foundDecimal);
$number = substr($number, 0, $foundDecimal);
}
while (($foundThousand = preg_replace('/(\d+)(\d\d\d)/', '\1 \2', $number)) != $number) {
$number = $foundThousand;
}
$number .= $after;
return strtr($number, array(' ' => $thousands, '.' => $decimals));
}
/** /**
* Formats a number into a currency format. * Formats a number into a currency format.
* *