Support multiple bytes with thousands/decimals in CakeNumber::format < PHP5.4

Fixes #2602
This commit is contained in:
Kyle Robinson Young 2012-03-27 23:43:55 -07:00
parent 0443fe1507
commit 4370bf280a
2 changed files with 86 additions and 1 deletions

View file

@ -72,6 +72,54 @@ class CakeNumberTest extends CakeTestCase {
$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.
*

View file

@ -60,6 +60,13 @@ class CakeNumber {
'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.
*
@ -142,7 +149,7 @@ class CakeNumber {
extract($options);
}
$out = $before . number_format($number, $places, $decimals, $thousands) . $after;
$out = $before . self::_number_format($number, $places, $decimals, $thousands) . $after;
if ($escape) {
return h($out);
@ -150,6 +157,36 @@ class CakeNumber {
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.
*