Permalink
Browse files

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

Support multiple bytes with thousands/decimals in CakeNumber::format < PHP5.4
  • Loading branch information...
2 parents 04c3023 + 4370bf2 commit 54bfa4cc05b81f4002f5f09d5abfad638b7ba592 @markstory markstory committed Mar 31, 2012
Showing with 86 additions and 1 deletion.
  1. +48 −0 lib/Cake/Test/Case/Utility/CakeNumberTest.php
  2. +38 −1 lib/Cake/Utility/CakeNumber.php
@@ -72,6 +72,54 @@ public function testFormat() {
$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.
*
@@ -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,14 +149,44 @@ public static function format($number, $options = false) {
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);
}
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.
*

0 comments on commit 54bfa4c

Please sign in to comment.