You are here

protected function GeneralNumberFormatter::numberFormatGeneral in Formatter Suite 8

Formats a number using the general set of formatting features.

General number notation formats a number with two parts:

  • Whole part before the decimal.
  • Fractional part after the decimal.

The following formatting attributes are used:

  • Decimal digits (decimal & float types only).
  • Decimal separator.
  • Use thousands.
  • Thousand separator.
  • Positive style.
  • Negative style.
  • Use zero padding.
  • Padding width.

Parameters

mixed $number: The number to format.

Return value

string The formatted number, including the prefix or suffix.

1 call to GeneralNumberFormatter::numberFormatGeneral()
GeneralNumberFormatter::numberFormat in src/Plugin/Field/FieldFormatter/GeneralNumberFormatter.php
Format a number using the current settings.

File

src/Plugin/Field/FieldFormatter/GeneralNumberFormatter.php, line 1116

Class

GeneralNumberFormatter
Format a number field with a variety of notation styles and parameters.

Namespace

Drupal\formatter_suite\Plugin\Field\FieldFormatter

Code

protected function numberFormatGeneral($number) {

  // Get settings.
  $usePrefixAndSuffix = $this
    ->getSetting('usePrefixAndSuffix');
  $decimalDigits = $this
    ->getSetting('decimalDigits');
  $decimalSeparator = $this
    ->getSetting('decimalSeparator');
  $useThousands = $this
    ->getSetting('useThousands');
  $thousandsSeparator = $this
    ->getSetting('thousandsSeparator');
  $positiveStyle = $this
    ->getSetting('positiveStyle');
  $negativeStyle = $this
    ->getSetting('negativeStyle');
  $useZeroPadding = $this
    ->getSetting('useZeroPadding');
  $paddingWidth = $this
    ->getSetting('paddingWidth');
  if ($useThousands === TRUE) {

    // When a thousands separator is in use, zero padding is disabled.
    $useZeroPadding = FALSE;
  }

  // If negative, set a flag and make positive. Handle the negative later
  // based upon the chosen negative style.
  $isNegative = FALSE;
  if ($number < 0 && $negativeStyle !== 'minus') {
    $isNegative = TRUE;
    $number *= -1.0;
  }

  // Split the number into whole and fraction parts.
  $whole = (int) $number;
  $fraction = (double) $number - (double) $whole;

  // Format the whole part using the thousands separator, if any.
  if ($useThousands === FALSE) {
    $thousandsSeparator = '';
  }
  $formattedWhole = number_format($whole, 0, '', $thousandsSeparator);
  if (is_int($number) === TRUE || $decimalDigits === 0) {

    // With a zero decimalDigits, there are zero digits after the decimal.
    // So, there is no formatting of the fractional part and no use
    // of the decimal separator. The formatted whole part is the
    // formatted number.
    $formatted = $formattedWhole;
  }
  else {

    // With a positive decimalDigits, there are digits after the decimal.
    // Scale up the fraction so that the requested number of digits
    // after the decimal are now before the decimal. Then round so
    // we only have those digits as an integer.
    $fraction = (int) round($fraction * pow(10, $decimalDigits), 0);

    // Format the decimal part.
    $fmt = '%0' . $decimalDigits . 'd';
    $formattedFraction = sprintf($fmt, $fraction);

    // Concatenate, inserting the decimal point.
    $formatted = $formattedWhole . $decimalSeparator . $formattedFraction;
  }

  // Handle padding.
  if ($useZeroPadding === TRUE) {
    $len = mb_strlen($formatted);
    if ($len < $paddingWidth) {
      $fmt = '%0' . $paddingWidth . 's';
      $formatted = sprintf($fmt, $formatted);
    }
  }

  // Get prefix and suffix, if any. We need the prefix because it may go
  // before a '(' when formatting negatives below.
  if ($usePrefixAndSuffix === TRUE) {
    $prefixes = $this
      ->getFieldPrefixes();
    $suffixes = $this
      ->getFieldSuffixes();
    $prefix = $this
      ->selectPrefix($number, $prefixes);
    $suffix = $this
      ->selectSuffix($number, $suffixes);
  }
  else {
    $prefix = '';
    $suffix = '';
  }

  // Handle the sign, if needed.
  $addRed = FALSE;
  if ($isNegative === TRUE) {

    // Number is negative. Either add a '-' or surround with '(' and ')'.
    switch ($negativeStyle) {
      default:
      case 'minus':
        $formatted = $prefix . '-' . $formatted . $suffix;
        break;
      case 'red':
        $formatted = $prefix . $formatted . $suffix;
        $addRed = TRUE;
        break;
      case 'parenthesis':
        $formatted = '(' . $prefix . $formatted . ')' . $suffix;
        break;
      case 'redparenthesis':
        $formatted = '(' . $prefix . $formatted . ')' . $suffix;
        $addRed = TRUE;
        break;
    }
    if ($addRed === TRUE) {

      // Making the text red could be done in two ways:
      // - Add a class and then use CSS to give the text a red color.
      // - Include an inline style that makes the text red.
      //
      // The class approach works on pages that use this formatter
      // because we include the module's CSS. It also works while
      // the formatter's settings page is being show, because again
      // we include the module's CSS. But the class approach *does not*
      // work on a formatter setting page once the formatter's own
      // settings have been accepted because the module's CSS is then
      // omitted. This gives an inconsistent presentation to the
      // administrator using the settings page.
      //
      // The inline style approach works in all cases. The downside is
      // that it means a site theme cannot override the color. On the
      // other hand, *should they*?  Using red for negative values is
      // an accounting convention, so overriding it to be blue, for
      // instance, would be invalid.
      //
      // So, we intentionally use an inline style to insure the value
      // is always red in all contexts, and because themes really should
      // NOT override an accounting convention.
      $formatted = '<span style="color: red">' . $formatted . '</span>';
    }
  }
  elseif ($positiveStyle === 'plus') {

    // Number is positive. Add a '+'.
    $formatted = '+' . $formatted;
  }
  return $formatted;
}