src/NumberTransformer/GenericNumberTransformer.php
<?php
namespace NumberToWords\NumberTransformer;
use NumberToWords\Language\Dictionary;
use NumberToWords\Language\ExponentGetter;
use NumberToWords\Language\ExponentInflector;
use NumberToWords\Language\PowerAwareTripletTransformer;
use NumberToWords\Language\TripletTransformer;
use NumberToWords\Service\NumberToTripletsConverter;
class GenericNumberTransformer implements NumberTransformer
{
private Dictionary $dictionary;
private ?TripletTransformer $tripletTransformer;
private ?PowerAwareTripletTransformer $powerAwareTripletTransformer;
private NumberToTripletsConverter $numberToTripletsConverter;
private ?ExponentInflector $exponentInflector;
private ?ExponentGetter $exponentGetter;
private ?string $wordsSeparator = null;
private ?string $exponentSeparator = null;
public function toWords(int $number): string
{
if ($number === 0) {
return $this->dictionary->getZero();
}
$words = [];
$minus = '';
if ($number < 0) {
$minus = $this->dictionary->getMinus();
$number *= -1;
}
if (null !== $this->tripletTransformer || null !== $this->powerAwareTripletTransformer) {
$words = array_merge($words, $this->getWordsBySplittingIntoTriplets($number));
}
return trim(sprintf('%s %s', $minus, implode($this->wordsSeparator, $words)));
}
private function getWordsBySplittingIntoTriplets(int $number): array
{
$words = [];
$triplets = $this->numberToTripletsConverter->convertToTriplets($number);
foreach ($triplets as $i => $triplet) {
if ($triplet > 0) {
if (null !== $this->tripletTransformer) {
$words[] = $this->tripletTransformer->transformToWords($triplet);
}
if (null !== $this->powerAwareTripletTransformer) {
$words[] = $this->powerAwareTripletTransformer->transformToWords(
$triplet,
count($triplets) - $i - 1
);
}
if (null !== $this->exponentInflector) {
$words[] = $this->exponentInflector->inflectExponent($triplet, count($triplets) - $i - 1);
}
if (null !== $this->exponentGetter) {
$words[] = $this->exponentGetter->getExponent(count($triplets) - $i - 1);
}
}
}
if (null !== $this->exponentSeparator && count($words) > 2) {
for ($i = 2; $i <= count($words) - 2; $i += 2) {
array_splice($words, $i++, 0, $this->exponentSeparator);
}
}
return $words;
}
public function setDictionary(Dictionary $dictionary): void
{
$this->dictionary = $dictionary;
}
public function setTripletTransformer(TripletTransformer $tripletTransformer): void
{
$this->tripletTransformer = $tripletTransformer;
$this->powerAwareTripletTransformer = null;
}
public function setPowerAwareTripletTransformer(PowerAwareTripletTransformer $powerAwareTripletTransformer): void
{
$this->powerAwareTripletTransformer = $powerAwareTripletTransformer;
$this->tripletTransformer = null;
}
public function setWordsSeparator(string $wordsSeparator): void
{
$this->wordsSeparator = $wordsSeparator;
}
public function setNumberToTripletsConverter(NumberToTripletsConverter $numberToTripletsConverter): void
{
$this->numberToTripletsConverter = $numberToTripletsConverter;
}
public function setExponentInflector(ExponentInflector $exponentInflector): void
{
$this->exponentInflector = $exponentInflector;
$this->exponentGetter = null;
}
public function setExponentGetter(ExponentGetter $exponentGetter): void
{
$this->exponentGetter = $exponentGetter;
$this->exponentInflector = null;
}
public function setExponentsSeparator(string $exponentSeparator): void
{
$this->exponentSeparator = $exponentSeparator;
}
}