From 50f3012f68b19fe11816c8155f943f9944968e3c Mon Sep 17 00:00:00 2001 From: "a.kompaniets" Date: Sun, 2 Oct 2016 01:48:13 +0300 Subject: [PATCH] fixed currency format with custom decimal fraction fixes #12345 close #12648 --- framework/CHANGELOG.md | 1 + framework/i18n/Formatter.php | 18 ++++++++++-------- tests/framework/i18n/FormatterNumberTest.php | 9 +++++++++ 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/framework/CHANGELOG.md b/framework/CHANGELOG.md index 84a43da5c8..f4ec9bdf5c 100644 --- a/framework/CHANGELOG.md +++ b/framework/CHANGELOG.md @@ -101,6 +101,7 @@ Yii Framework 2 Change Log ----------------------- - Bug #7670: Added `yii\web\UrlNormalizer` for normalizing requests with and without trailing slashes (rob006, cronfy, klimov-paul) +- Bug #12345 Fixed `Formatter::asCurrency()` for proper decimal formatting (Oxyaction) - Bug #7670: Added `UrlNormalizer` for normalizing requests with and without trailing slashes (rob006, cronfy, klimov-paul) - Bug #9027: Fixed descendant class of `yii\web\UploadedFile` returns parent instances in case invoked after it (andrewnester) - Bug #9277: Fixed `yii\console\controllers\AssetController` looses custom options of 'target' bundles (petrabarus, klimov-paul) diff --git a/framework/i18n/Formatter.php b/framework/i18n/Formatter.php index 0e0dd8f97c..3254e2efbe 100644 --- a/framework/i18n/Formatter.php +++ b/framework/i18n/Formatter.php @@ -1055,17 +1055,19 @@ class Formatter extends Component $value = $this->normalizeNumericValue($value); if ($this->_intlLoaded) { + $currency = $currency ?: $this->currencyCode; + // currency code must be set before fraction digits + // http://php.net/manual/en/numberformatter.formatcurrency.php#114376 + if ($currency && !isset($textOptions[NumberFormatter::CURRENCY_CODE])) { + $textOptions[NumberFormatter::CURRENCY_CODE] = $currency; + } $formatter = $this->createNumberFormatter(NumberFormatter::CURRENCY, null, $options, $textOptions); if ($currency === null) { - if ($this->currencyCode === null) { - if (($result = $formatter->format($value)) === false) { - throw new InvalidParamException('Formatting currency value failed: ' . $formatter->getErrorCode() . ' ' . $formatter->getErrorMessage()); - } - return $result; - } - $currency = $this->currencyCode; + $result = $formatter->format($value); + } else { + $result = $formatter->formatCurrency($value, $currency); } - if (($result = $formatter->formatCurrency($value, $currency)) === false) { + if ($result === false) { throw new InvalidParamException('Formatting currency value failed: ' . $formatter->getErrorCode() . ' ' . $formatter->getErrorMessage()); } return $result; diff --git a/tests/framework/i18n/FormatterNumberTest.php b/tests/framework/i18n/FormatterNumberTest.php index 917dc782ac..e5e5d55bab 100644 --- a/tests/framework/i18n/FormatterNumberTest.php +++ b/tests/framework/i18n/FormatterNumberTest.php @@ -305,6 +305,15 @@ class FormatterNumberTest extends TestCase $this->assertSame("0,00 €", $this->formatter->asCurrency(false)); $this->assertSame("0,00 €", $this->formatter->asCurrency("")); + // decimal formatting + $this->formatter->locale = 'de-DE'; + $this->assertSame("100 $", \Yii::$app->formatter->asCurrency(100, 'USD', [ + NumberFormatter::MAX_FRACTION_DIGITS => 0, + ])); + $this->assertSame("100,00 $", $this->formatter->asCurrency(100, 'USD', [ + NumberFormatter::MAX_FRACTION_DIGITS => 2 + ])); + // null display $this->assertSame($this->formatter->nullDisplay, $this->formatter->asCurrency(null)); }