ソースを参照

Some work towards getting Number::currency fixed

Jose Lorenzo Rodriguez 11 年 前
コミット
32ed3632ea
2 ファイル変更62 行追加23 行削除
  1. 35 12
      src/Utility/Number.php
  2. 27 11
      tests/TestCase/Utility/NumberTest.php

+ 35 - 12
src/Utility/Number.php

@@ -84,18 +84,18 @@ class Number {
 	protected static $_formatters = [];
 
 /**
- * Default currency used by Number::currency()
+ * A list of currency formatters indexed by locale
  *
- * @var string
+ * @var array
  */
-	protected static $_defaultCurrency = 'USD';
+	protected static $_currencyFormatters = [];
 
 /**
- * If native number_format() should be used. If >= PHP5.4
+ * Default currency used by Number::currency()
  *
- * @var bool
+ * @var string
  */
-	protected static $_numberFormatSupport = null;
+	protected static $_defaultCurrency = 'USD';
 
 /**
  * Formats a number with a level of precision.
@@ -309,17 +309,40 @@ class Number {
  * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/number.html#NumberHelper::currency
  */
 	public static function currency($value, $currency = null, array $options = array()) {
-		$default = static::$_currencyDefaults;
+		$value = (float)$value;
+
+		if (isset($options['zero']) && !$value) {
+			return $options['zero'];
+		}
+
+		$locale = isset($options['locale']) ? $options['locale'] : ini_get('intl.default_locale');
+
+		if (!$locale) {
+			$locale = 'en_US';
+		}
+
+		if (!isset(static::$_currencyFormatters[$locale])) {
+			static::$_currencyFormatters[$locale] = new NumberFormatter(
+				$locale,
+				NumberFormatter::CURRENCY
+			);
+		}
+
 		if ($currency === null) {
 			$currency = static::defaultCurrency();
 		}
 
-		if (isset(static::$_currencies[$currency])) {
-			$default = static::$_currencies[$currency];
-		} elseif (is_string($currency)) {
-			$options['before'] = $currency;
+		$formatter = static::$_currencyFormatters[$locale];
+
+		if (!empty($options['pattern'])) {
+			$formatter->setPattern($options['pattern']);
 		}
 
+		return $formatter->formatCurrency($value, $currency);
+
+		$default = static::$_currencyDefaults;
+		
+
 		$options += $default;
 
 		if (isset($options['before']) && $options['before'] !== '') {
@@ -332,7 +355,7 @@ class Number {
 		$result = $options['before'] = $options['after'] = null;
 
 		$symbolKey = 'whole';
-		$value = (float)$value;
+		;
 		if (!$value) {
 			if ($options['zero'] !== 0) {
 				return $options['zero'];

+ 27 - 11
tests/TestCase/Utility/NumberTest.php

@@ -145,30 +145,46 @@ class NumberTest extends TestCase {
 		$expected = '$100,100,100.00';
 		$this->assertEquals($expected, $result);
 
-		$result = $this->Number->currency($value, '#');
-		$expected = '#100,100,100.00';
+		$result = $this->Number->currency($value, 'USD');
+		$expected = '$100,100,100.00';
 		$this->assertEquals($expected, $result);
 
-		$result = $this->Number->currency($value, false);
-		$expected = '100,100,100.00';
+		$result = $this->Number->currency($value, 'EUR');
+		$expected = '100,100,100.00';
 		$this->assertEquals($expected, $result);
 
-		$result = $this->Number->currency($value, 'USD');
+		$result = $this->Number->currency($value, 'EUR', ['locale' => 'de_DE']);
+		$expected = '100.100.100,00 €';
+		$this->assertEquals($expected, $result);
+
+		$result = $this->Number->currency($value, 'USD', ['locale' => 'de_DE']);
+		$expected = '100.100.100,00 $';
+		$this->assertEquals($expected, $result);
+
+		$result = $this->Number->currency($value, 'USD', ['locale' => 'en_US']);
 		$expected = '$100,100,100.00';
 		$this->assertEquals($expected, $result);
 
-		$result = $this->Number->currency($value, 'EUR');
-		$expected = '€100.100.100,00';
+		$result = $this->Number->currency($value, 'USD', ['locale' => 'en_CA']);
+		$expected = 'US$100,100,100.00';
 		$this->assertEquals($expected, $result);
 
 		$result = $this->Number->currency($value, 'GBP');
 		$expected = '£100,100,100.00';
 		$this->assertEquals($expected, $result);
 
-		$options = array('thousands' => ' ', 'wholeSymbol' => 'EUR ', 'wholePosition' => 'before',
-			'decimals' => ',', 'zero' => 'Gratuit');
-		$result = $this->Number->currency($value, '', $options);
-		$expected = 'EUR 100 100 100,00';
+		$result = $this->Number->currency($value, 'GBP', ['locale' => 'da_DK']);
+		$expected = '100.100.100,00 £';
+		$this->assertEquals($expected, $result);
+
+		$options = ['locale' => 'fr_FR', 'pattern' => 'EUR #,###.00'];
+		$result = $this->Number->currency($value, 'EUR', $options);
+		$expected = 'EUR 100 100 100,00';
+		$this->assertEquals($expected, $result);
+
+		$options = ['locale' => 'fr_FR', 'pattern' => '#,###.00 EUR'];
+		$result = $this->Number->currency($value, 'EUR', $options);
+		$expected = '100 100 100,00 EUR';
 		$this->assertEquals($expected, $result);
 
 		$options = array('after' => 'øre', 'before' => 'Kr.', 'decimals' => ',', 'thousands' => '.');