Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 4.2.x will end 22 April 2024 (12 months).
  • Bug fixes for security issues in 4.2.x will end 7 October 2024 (18 months).
  • PHP version: minimum PHP 8.0.0 Note: minimum PHP version has increased since Moodle 4.1. PHP 8.1.x is supported too.
   1  <?php
   2  
   3  namespace PhpOffice\PhpSpreadsheet\Style\NumberFormat\Wizard;
   4  
   5  use NumberFormatter;
   6  use PhpOffice\PhpSpreadsheet\Exception;
   7  
   8  class Currency extends Number
   9  {
  10      public const LEADING_SYMBOL = true;
  11  
  12      public const TRAILING_SYMBOL = false;
  13  
  14      public const SYMBOL_WITH_SPACING = true;
  15  
  16      public const SYMBOL_WITHOUT_SPACING = false;
  17  
  18      protected string $currencyCode = '$';
  19  
  20      protected bool $currencySymbolPosition = self::LEADING_SYMBOL;
  21  
  22      protected bool $currencySymbolSpacing = self::SYMBOL_WITHOUT_SPACING;
  23  
  24      /**
  25       * @param string $currencyCode the currency symbol or code to display for this mask
  26       * @param int $decimals number of decimal places to display, in the range 0-30
  27       * @param bool $thousandsSeparator indicator whether the thousands separator should be used, or not
  28       * @param bool $currencySymbolPosition indicates whether the currency symbol comes before or after the value
  29       *              Possible values are Currency::LEADING_SYMBOL and Currency::TRAILING_SYMBOL
  30       * @param bool $currencySymbolSpacing indicates whether there is spacing between the currency symbol and the value
  31       *              Possible values are Currency::SYMBOL_WITH_SPACING and Currency::SYMBOL_WITHOUT_SPACING
  32       * @param ?string $locale Set the locale for the currency format; or leave as the default null.
  33       *          If provided, Locale values must be a valid formatted locale string (e.g. 'en-GB', 'fr', uz-Arab-AF).
  34       *          Note that setting a locale will override any other settings defined in this class
  35       *          other than the currency code; or decimals (unless the decimals value is set to 0).
  36       *
  37       * @throws Exception If a provided locale code is not a valid format
  38       */
  39      public function __construct(
  40          string $currencyCode = '$',
  41          int $decimals = 2,
  42          bool $thousandsSeparator = true,
  43          bool $currencySymbolPosition = self::LEADING_SYMBOL,
  44          bool $currencySymbolSpacing = self::SYMBOL_WITHOUT_SPACING,
  45          ?string $locale = null
  46      ) {
  47          $this->setCurrencyCode($currencyCode);
  48          $this->setThousandsSeparator($thousandsSeparator);
  49          $this->setDecimals($decimals);
  50          $this->setCurrencySymbolPosition($currencySymbolPosition);
  51          $this->setCurrencySymbolSpacing($currencySymbolSpacing);
  52          $this->setLocale($locale);
  53      }
  54  
  55      public function setCurrencyCode(string $currencyCode): void
  56      {
  57          $this->currencyCode = $currencyCode;
  58      }
  59  
  60      public function setCurrencySymbolPosition(bool $currencySymbolPosition = self::LEADING_SYMBOL): void
  61      {
  62          $this->currencySymbolPosition = $currencySymbolPosition;
  63      }
  64  
  65      public function setCurrencySymbolSpacing(bool $currencySymbolSpacing = self::SYMBOL_WITHOUT_SPACING): void
  66      {
  67          $this->currencySymbolSpacing = $currencySymbolSpacing;
  68      }
  69  
  70      protected function getLocaleFormat(): string
  71      {
  72          $formatter = new Locale($this->fullLocale, NumberFormatter::CURRENCY);
  73          $mask = $formatter->format();
  74          if ($this->decimals === 0) {
  75              $mask = (string) preg_replace('/\.0+/miu', '', $mask);
  76          }
  77  
  78          return str_replace('ยค', $this->formatCurrencyCode(), $mask);
  79      }
  80  
  81      private function formatCurrencyCode(): string
  82      {
  83          if ($this->locale === null) {
  84              return $this->currencyCode;
  85          }
  86  
  87          return "[\${$this->currencyCode}-{$this->locale}]";
  88      }
  89  
  90      public function format(): string
  91      {
  92          if ($this->localeFormat !== null) {
  93              return $this->localeFormat;
  94          }
  95  
  96          return sprintf(
  97              '%s%s%s0%s%s%s',
  98              $this->currencySymbolPosition === self::LEADING_SYMBOL ? $this->formatCurrencyCode() : null,
  99              (
 100                  $this->currencySymbolPosition === self::LEADING_SYMBOL &&
 101                  $this->currencySymbolSpacing === self::SYMBOL_WITH_SPACING
 102              ) ? "\u{a0}" : '',
 103              $this->thousandsSeparator ? '#,##' : null,
 104              $this->decimals > 0 ? '.' . str_repeat('0', $this->decimals) : null,
 105              (
 106                  $this->currencySymbolPosition === self::TRAILING_SYMBOL &&
 107                  $this->currencySymbolSpacing === self::SYMBOL_WITH_SPACING
 108              ) ? "\u{a0}" : '',
 109              $this->currencySymbolPosition === self::TRAILING_SYMBOL ? $this->formatCurrencyCode() : null
 110          );
 111      }
 112  }