From 096110f396365db1625bd8bf8b8222d00e8b2ff2 Mon Sep 17 00:00:00 2001 From: Seamus Lee Date: Wed, 9 Sep 2020 15:54:50 +1000 Subject: [PATCH] dev/core#2003 Use Brick/Money to ensure that we display all possible digits stored in the database for the option amount Add in noisy notice about fall back due to missing intl extension --- CRM/Price/Form/Option.php | 5 +---- CRM/Utils/Money.php | 18 +++++++++++++++++- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/CRM/Price/Form/Option.php b/CRM/Price/Form/Option.php index adf22e19a8..5aa3b3687b 100644 --- a/CRM/Price/Form/Option.php +++ b/CRM/Price/Form/Option.php @@ -75,10 +75,7 @@ class CRM_Price_Form_Option extends CRM_Core_Form { // fix the display of the monetary value, CRM-4038 foreach ($this->_moneyFields as $field) { - // @todo use formatLocaleNumericRoundedByOptionalPrecision - but note that there is an issue where php doesn't handle - // money strings beyond a certain total length - per https://github.com/civicrm/civicrm-core/pull/18409 - // & https://github.com/civicrm/civicrm-core/pull/18409 - $defaults[$field] = CRM_Utils_Money::format(CRM_Utils_Array::value($field, $defaults), NULL, '%a'); + $defaults[$field] = isset($defaults[$field]) ? CRM_Utils_Money::formatLocaleNumericRoundedByOptionalPrecision($defaults[$field], 9) : ''; } } diff --git a/CRM/Utils/Money.php b/CRM/Utils/Money.php index 45d2d3fd79..c99a792167 100644 --- a/CRM/Utils/Money.php +++ b/CRM/Utils/Money.php @@ -17,6 +17,7 @@ use Brick\Money\Money; use Brick\Money\Context\DefaultContext; +use Brick\Money\Context\CustomContext; use Brick\Math\RoundingMode; /** @@ -201,7 +202,15 @@ class CRM_Utils_Money { * @return string */ protected static function formatLocaleNumericRounded($amount, $numberOfPlaces) { - return self::formatNumericByFormat($amount, '%!.' . $numberOfPlaces . 'i'); + if (!extension_loaded('intl')) { + self::missingIntlNotice(); + return self::formatNumericByFormat($amount, '%!.' . $numberOfPlaces . 'i'); + } + $money = Money::of($amount, CRM_Core_Config::singleton()->defaultCurrency, new CustomContext($numberOfPlaces), RoundingMode::CEILING); + $formatter = new \NumberFormatter(CRM_Core_I18n::getLocale(), NumberFormatter::CURRENCY); + $formatter->setSymbol(\NumberFormatter::CURRENCY_SYMBOL, ''); + $formatter->setAttribute(\NumberFormatter::MIN_FRACTION_DIGITS, $numberOfPlaces); + return $money->formatWith($formatter); } /** @@ -306,4 +315,11 @@ class CRM_Utils_Money { return $amount; } + /** + * Emits a notice indicating we have fallen back to a less accurate way of formatting money due to missing intl extension + */ + public static function missingIntlNotice() { + CRM_Core_Session::singleton()->setStatus(ts('As this system does not include the PHP intl extension, CiviCRM has fallen back onto a slightly less accurate and deprecated method to format money'), ts('Missing PHP INTL extension')); + } + } -- 2.25.1