Merge pull request #19200 from eileenmcnaughton/act_contact
[civicrm-core.git] / CRM / Utils / Money.php
index 45d2d3fd79cb7c93ac4fed682320947b7f90e180..786fccd64c0bbc4e4981a5bf3b9a48c30a09217e 100644 (file)
@@ -17,6 +17,7 @@
 
 use Brick\Money\Money;
 use Brick\Money\Context\DefaultContext;
+use Brick\Money\Context\CustomContext;
 use Brick\Math\RoundingMode;
 
 /**
@@ -66,14 +67,15 @@ class CRM_Utils_Money {
     }
 
     if (!empty($valueFormat) && $valueFormat !== '%!i') {
-      CRM_Core_Error::deprecatedFunctionWarning('Having a Money Value format other than !%i is deprecated, please report this on the GitLab Issue https://lab.civicrm.org/dev/core/-/issues/1494 with the relevant moneyValueFormat you use.');
+      CRM_Core_Error::deprecatedWarning('Having a Money Value format other than %!i is deprecated, please report this on the GitLab Issue https://lab.civicrm.org/dev/core/-/issues/1494 with the relevant moneyValueFormat you use.');
+    }
+
+    if (!$currency) {
+      $currency = $config->defaultCurrency;
     }
 
     if ($onlyNumber) {
-      // money_format() exists only in certain PHP install (CRM-650)
-      if (is_numeric($amount) and function_exists('money_format')) {
-        $amount = money_format($valueFormat, $amount);
-      }
+      $amount = self::formatLocaleNumericRoundedByCurrency($amount, $currency);
       return $amount;
     }
 
@@ -84,16 +86,16 @@ class CRM_Utils_Money {
       ]);
     }
 
-    if (!$currency) {
-      $currency = $config->defaultCurrency;
-    }
-
     // ensure $currency is a valid currency code
     // for backwards-compatibility, also accept one space instead of a currency
     if ($currency != ' ' && !array_key_exists($currency, self::$_currencySymbols)) {
       throw new CRM_Core_Exception("Invalid currency \"{$currency}\"");
     }
 
+    if ($currency === ' ') {
+      CRM_Core_Error::deprecatedWarning('Passing empty currency to CRM_Utils_Money::format is deprecated if you need it for display without currency call CRM_Utils_Money::formatLocaleNumericRounded');
+    }
+
     $amount = self::formatNumericByFormat($amount, $valueFormat);
     // If it contains tags, means that HTML was passed and the
     // amount is already converted properly,
@@ -180,7 +182,7 @@ class CRM_Utils_Money {
    */
   protected static function formatLocaleNumeric($amount) {
     if (CRM_Core_Config::singleton()->moneyvalueformat !== '%!i') {
-      CRM_Core_Error::deprecatedFunctionWarning('Having a Money Value format other than !%i is deprecated, please report this on GitLab with the relevant moneyValueFormat you use.');
+      CRM_Core_Error::deprecatedWarning('Having a Money Value format other than !%i is deprecated, please report this on GitLab with the relevant moneyValueFormat you use.');
     }
     return self::formatNumericByFormat($amount, CRM_Core_Config::singleton()->moneyvalueformat);
   }
@@ -201,7 +203,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 +316,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'));
+  }
+
 }