Esempio n. 1
0
 /**
  * Spell a number.
  *
  * @param int    $number Number to spelling.
  * @param string $type   Tye type of spelling.
  *
  * @return string
  */
 public function spell($number, $type = self::SPELLING_NUMBER)
 {
     // Split numbers in lands (eg. *100.000* should be [ 0, 100 ])
     $numberLands = static::getNumberLands($number);
     $numberLandsSpelled = [];
     // Process each number lands and get a raw spelled term.
     // Eg. *1.002* should be (reversed) [ 'two', 'one' ].
     foreach ($numberLands as $numberLandKey => $numberLand) {
         // Process the number in current land, getting it simplified spelling.
         $numberLandSpelled = $this->locale->simple($numberLands[$numberLandKey]);
         // Numbers that can't be spelled naturally should be ignored.
         // A good example is *zero*, that will be processed only on formatter.
         if ($numberLandSpelled === null) {
             continue;
         }
         // Store the spelled number in the current land.
         $numberLandsSpelled[$numberLandKey] = $numberLandSpelled;
     }
     /** @var int[] $numberLands */
     return $this->locale->format($this->locale, $numberLandsSpelled, $numberLands, $type);
 }
 /**
  * Format the number lands to spelling.
  *
  * @param Locale   $locale             The locale used to spell numbers.
  * @param string[] $numberLandsSpelled The number lands spelled.
  * @param int[]    $numberLands        The original number lands (as integer).
  * @param string   $spellingType       The spelling type.
  *
  * @return null|string
  */
 public function format($locale, $numberLandsSpelled, $numberLands, $spellingType)
 {
     if (!$numberLandsSpelled) {
         // If no lands, then spells zero.
         return $this->formatType($this->options->zeroSpell, 0, $numberLandsSpelled, Count::SIDE_INTEGER, $spellingType);
     }
     $numberLandsCount = count($numberLandsSpelled);
     if ($numberLandsCount === 1 && array_key_exists('0', $numberLandsSpelled)) {
         // Simple spell with only the first land (1 to 999).
         return $this->formatType($numberLandsSpelled[0], $numberLands[0], $numberLandsSpelled, Count::SIDE_INTEGER, $spellingType);
     }
     // Reprocess all lands, applying the suffixes.
     $numberLandsKeys = array_keys($numberLandsSpelled);
     foreach ($numberLandsKeys as $numberLandsKey) {
         if ($numberLandsKey === 1) {
             if ($this->options->includeOneThousand !== true && $numberLands[$numberLandsKey] === 1) {
                 // Exclusively for the one thousand, just use suffix (*um mil* to *mil*).
                 $numberLandsSpelled[$numberLandsKey] = $this->options->thousandSpell;
                 continue;
             }
             // Else, just append the thousand suffix (*dois* to *dois mil*).
             $numberLandsSpelled[$numberLandsKey] .= ' ' . $this->options->thousandSpell;
             continue;
         }
         if ($numberLandsKey >= 2) {
             // Numbers over one million.
             // Stores the million root (eg. *milh*) and the million suffix (eg. *ões*).
             // Together it'll be *milhões* if number is over 2 millions.
             $millionRoot = $this->options->millionRoots[$numberLandsKey - 2];
             $millionSuffix = $this->options->millionSuffixes[$numberLands[$numberLandsKey] >= 2];
             $numberLandsSpelled[$numberLandsKey] .= ' ' . $millionRoot . $millionSuffix;
             continue;
         }
         if ($numberLandsKey === -1) {
             // Consider decimals ten times less.
             $numberLandsSpelled[$numberLandsKey] = $locale->simple($numberLands[$numberLandsKey] / 10);
             continue;
         }
     }
     // Currency: if decimal was defined, so we get it first.
     $numberLandsDecimal = null;
     if (array_key_exists('-1', $numberLandsSpelled)) {
         $numberLandsCount--;
         $numberLandsDecimal = $this->formatType($numberLandsSpelled[-1], $numberLands[-1] / 10, $numberLandsSpelled, Count::SIDE_DECIMAL, $spellingType);
         unset($numberLands[-1], $numberLandsSpelled[-1]);
     }
     // If there are just one land, just return it.
     // Currency: it's always pluralized because numbers where is always greater or equal to one thousand.
     $numberResult = null;
     if ($numberLandsCount === 1) {
         $numberResult = $this->formatType(reset($numberLandsSpelled), 2, $numberLandsSpelled, Count::SIDE_INTEGER, $spellingType);
     } else {
         if ($numberLandsCount > 1) {
             // If the first land is equal or lower than 100, the result will be treated differently.
             // Or if the first land is divisible by 100 (eg. *200*, but not *201*).
             // In this case, it'll group the last land by *e* instead of comma.
             $numberLandsFirst = reset($numberLands);
             if ($numberLandsFirst <= 100 || $numberLandsFirst % 100 === 0) {
                 $numberLandsReverse = array_reverse($numberLandsSpelled);
                 $numberResult = implode($this->options->defaultSeparator ?: ' ', array_slice($numberLandsReverse, 0, -1)) . ($this->options->lastSeparator ?: ' ') . end($numberLandsReverse);
             } else {
                 // Else, just implode all by comma.
                 $numberResult = implode($this->options->defaultSeparator ?: ' ', array_reverse($numberLandsSpelled));
             }
             // Compose the integer result.
             $numberResult = $this->formatType($numberResult, 2, $numberLandsSpelled, Count::SIDE_INTEGER, $spellingType);
         }
     }
     // Currency: if decimals exists, just append it to result.
     if ($numberLandsDecimal) {
         if ($numberResult) {
             $numberResult .= $this->options->currencyDecimalSeparator;
         }
         $numberResult .= $numberLandsDecimal;
     }
     return $numberResult;
 }
 /**
  * Teste LocaleUnsupportedException exception.
  *
  * @expectedException \Rentalhost\VanillaCount\Exception\LocaleUnsupportedException
  */
 public function testLocaleUnsupportedException()
 {
     Locale::getLocale('unknowLocale');
 }
 /**
  * Format the number lands to spelling.
  *
  * @param Locale   $locale             The locale used to spell numbers.
  * @param string[] $numberLandsSpelled The number lands spelled.
  * @param int[]    $numberLands        The original number lands (as integer).
  * @param string   $spellingType       The spelling type.
  *
  * @return null|string
  */
 public function format($locale, $numberLandsSpelled, $numberLands, $spellingType)
 {
     if (!$numberLandsSpelled) {
         // If no lands, then spells zero.
         return $this->formatType($this->options->zeroSpell, 0, $numberLandsSpelled, Count::SIDE_INTEGER, $spellingType);
     }
     $numberLandsCount = count($numberLandsSpelled);
     if ($numberLandsCount === 1 && array_key_exists('0', $numberLandsSpelled)) {
         // If current number value is over 100 and starts with 1, we should apply first one identifier.
         if ($this->options->firstOneIdentifier !== 'one' && $numberLands[0] >= 100 && strpos($numberLands[0], '1') === 0) {
             $numberLandsSpelled[0] = str_replace('one ', $this->options->firstOneIdentifier ? $this->options->firstOneIdentifier . ' ' : null, $numberLandsSpelled[0]);
         }
         // Simple spell with only the first land (1 to 999).
         return $this->formatType($numberLandsSpelled[0], $numberLands[0], $numberLandsSpelled, Count::SIDE_INTEGER, $spellingType);
     }
     /** @var int $numberLandsKey */
     // Reprocess all lands, applying the suffixes.
     end($numberLandsSpelled);
     $numberLandsKeysLast = key($numberLandsSpelled);
     $numberLandsKeys = array_keys($numberLandsSpelled);
     foreach ($numberLandsKeys as $numberLandsKey) {
         // Numbers over one thousand.
         if ($numberLandsKey >= 1) {
             // If current number value is one and is the first one spelled,
             // we should apply the first one identifier option.
             if ($numberLandsKey === $numberLandsKeysLast && $numberLands[$numberLandsKey] === 1) {
                 $numberLandsSpelled[$numberLandsKey] = ($this->options->firstOneIdentifier ? $this->options->firstOneIdentifier . ' ' : null) . $this->options->highSpells[$numberLandsKey - 1];
                 continue;
             }
             $numberLandsSpelled[$numberLandsKey] .= ' ' . $this->options->highSpells[$numberLandsKey - 1];
             continue;
         }
         // Consider decimals ten times less.
         if ($numberLandsKey === -1) {
             $numberLandsSpelled[$numberLandsKey] = $locale->simple($numberLands[$numberLandsKey] / 10);
             continue;
         }
     }
     // Currency: if decimal was defined, so we get it first.
     $numberLandsDecimal = null;
     if (array_key_exists('-1', $numberLandsSpelled)) {
         $numberLandsCount--;
         $numberLandsDecimal = $this->formatType($numberLandsSpelled[-1], $numberLands[-1] / 10, $numberLandsSpelled, Count::SIDE_DECIMAL, $spellingType);
         unset($numberLands[-1], $numberLandsSpelled[-1]);
     }
     // If there are just one land, just return it.
     // Currency: it's always pluralized because numbers where is always greater or equal to one thousand.
     $numberResult = null;
     if ($numberLandsCount === 1) {
         $numberResult = $this->formatType(reset($numberLandsSpelled), 2, $numberLandsSpelled, Count::SIDE_INTEGER, $spellingType);
     } else {
         if ($numberLandsCount > 1) {
             // If the first land is equal or lower than 100, the result will be treated differently.
             // Or if the first land is divisible by 100 (eg. *200*, but not *201*).
             // In this case, it'll group the last land by *e* instead of comma.
             $numberLandsFirst = reset($numberLands);
             if ($numberLandsFirst <= 100 || $numberLandsFirst % 100 === 0) {
                 $numberLandsReverse = array_reverse($numberLandsSpelled);
                 $numberResult = implode($this->options->defaultSeparator ?: ' ', array_slice($numberLandsReverse, 0, -1)) . ($this->options->lastSeparator ?: ' ') . end($numberLandsReverse);
             } else {
                 // Else, just implode all by comma.
                 $numberResult = implode($this->options->defaultSeparator ?: ' ', array_reverse($numberLandsSpelled));
             }
             // Compose the integer result.
             $numberResult = $this->formatType($numberResult, 2, $numberLandsSpelled, Count::SIDE_INTEGER, $spellingType);
         }
     }
     // Currency: if decimals exists, just append it to result.
     if ($numberLandsDecimal) {
         if ($numberResult) {
             $numberResult .= $this->options->currencyDecimalSeparator ?: ' ';
         }
         $numberResult .= $numberLandsDecimal;
     }
     return $numberResult;
 }