From 6ae8a7a8f24bc0c3edcc4749b71496c7bff5c2ca Mon Sep 17 00:00:00 2001 From: simcha Date: Sun, 17 Dec 2023 07:53:26 +0200 Subject: [PATCH 1/6] Add Hebrew --- src/Concerns/ManagesCurrencyTransformers.php | 1 + src/Concerns/ManagesNumberTransformers.php | 1 + .../HebrewCurrencyTransformer.php | 80 ++++++++++ src/Language/Hebrew/HebrewDictionary.php | 138 ++++++++++++++++++ src/Language/Hebrew/HebrewExponentGetter.php | 38 +++++ .../Hebrew/HebrewExponentInflector.php | 72 +++++++++ .../Hebrew/HebrewNounGenderInflector.php | 30 ++++ .../Hebrew/HebrewTripletTransformer.php | 111 ++++++++++++++ .../HebrewNumberTransformer.php | 29 ++++ 9 files changed, 500 insertions(+) create mode 100644 src/CurrencyTransformer/HebrewCurrencyTransformer.php create mode 100644 src/Language/Hebrew/HebrewDictionary.php create mode 100644 src/Language/Hebrew/HebrewExponentGetter.php create mode 100644 src/Language/Hebrew/HebrewExponentInflector.php create mode 100644 src/Language/Hebrew/HebrewNounGenderInflector.php create mode 100644 src/Language/Hebrew/HebrewTripletTransformer.php create mode 100644 src/NumberTransformer/HebrewNumberTransformer.php diff --git a/src/Concerns/ManagesCurrencyTransformers.php b/src/Concerns/ManagesCurrencyTransformers.php index e950eede..20302387 100644 --- a/src/Concerns/ManagesCurrencyTransformers.php +++ b/src/Concerns/ManagesCurrencyTransformers.php @@ -32,6 +32,7 @@ trait ManagesCurrencyTransformers 'ua' => Transformer\UkrainianCurrencyTransformer::class, 'uz' => Transformer\UzbekCurrencyTransformer::class, 'yo' => Transformer\YorubaCurrencyTransformer::class, + 'he' => Transformer\HebrewCurrencyTransformer::class, ]; /** diff --git a/src/Concerns/ManagesNumberTransformers.php b/src/Concerns/ManagesNumberTransformers.php index d641aeed..c2bd13eb 100644 --- a/src/Concerns/ManagesNumberTransformers.php +++ b/src/Concerns/ManagesNumberTransformers.php @@ -44,6 +44,7 @@ trait ManagesNumberTransformers 'ua' => Transformer\UkrainianNumberTransformer::class, 'uz' => Transformer\UzbekNumberTransformer::class, 'yo' => Transformer\YorubaNumberTransformer::class, + 'he' => Transformer\HebrewNumberTransformer::class, ]; /** diff --git a/src/CurrencyTransformer/HebrewCurrencyTransformer.php b/src/CurrencyTransformer/HebrewCurrencyTransformer.php new file mode 100644 index 00000000..f8482981 --- /dev/null +++ b/src/CurrencyTransformer/HebrewCurrencyTransformer.php @@ -0,0 +1,80 @@ +withDictionary($dictionary) + ->withWordsSeparatedBy(' ') + ->transformNumbersBySplittingIntoPowerAwareTriplets($numberToTripletsConverter, $tripletTransformer) + ->inflectExponentByNumbers($exponentInflector) + ->build(); + + $decimal = (int) ($amount / 100); + + $fraction = abs($amount % 100); + + if ($fraction === 0) { + $fraction = null; + } + + $currency = strtoupper($currency); + + if (!array_key_exists($currency, HebrewDictionary::$currencyNames)) { + throw new NumberToWordsException( + sprintf('Currency "%s" is not available for "%s" language', $currency, get_class($this)) + ); + } + + $currencyNames = HebrewDictionary::$currencyNames[$currency]; + + $return = trim($numberTransformer->toWords($decimal)); + + $level = ($decimal === 1) ? 0 : 1; + + if ($level > 0) { + if (count($currencyNames[0]) > 1) { + $return .= ' ' . $currencyNames[0][$level]; + } else { + $return .= ' ' . $currencyNames[0][0] . 's'; + } + } else { + $return .= ' ' . $currencyNames[0][0]; + } + + if (null !== $fraction) { + $return .= ' ו' . trim($numberTransformer->toWords($fraction)); + + $level = $fraction === 1 ? 0 : 1; + + if ($level > 0) { + if (count($currencyNames[1]) > 1) { + $return .= ' ' . $currencyNames[1][$level]; + } else { + $return .= ' ' . $currencyNames[1][0] . 's'; + } + } else { + $return .= ' ' . $currencyNames[1][0]; + } + } + + return $return; + } +} diff --git a/src/Language/Hebrew/HebrewDictionary.php b/src/Language/Hebrew/HebrewDictionary.php new file mode 100644 index 00000000..a4989187 --- /dev/null +++ b/src/Language/Hebrew/HebrewDictionary.php @@ -0,0 +1,138 @@ + [['lek'], ['qindarka']], + 'AED' => [['Dirham'], ['Fils']], + 'AUD' => [['Australian dollar'], ['cent']], + 'BAM' => [['convertible marka'], ['fenig']], + 'BGN' => [['lev'], ['stotinka']], + 'BRL' => [['real'], ['centavos']], + 'BYR' => [['Belarussian rouble'], ['kopiejka']], + 'CAD' => [['Canadian dollar'], ['cent']], + 'CHF' => [['Swiss franc'], ['rapp']], + 'CYP' => [['Cypriot pound'], ['cent']], + 'CZK' => [['Czech koruna'], ['halerz']], + 'DKK' => [['Danish krone'], ['ore']], + 'DZD' => [['dinar'], ['cent']], + 'EEK' => [['kroon'], ['senti']], + 'EGP' => [['Egyptian Pound'], ['piastre']], + 'EUR' => [['euro'], ['euro-cent']], + 'GBP' => [['pound', 'pounds'], ['pence', 'pence']], + 'HKD' => [['Hong Kong dollar'], ['cent']], + 'HRK' => [['Croatian kuna'], ['lipa']], + 'HUF' => [['forint'], ['filler']], + 'ILS' => [['ש"ח', 'ש"ח'], ['אג\'', 'אג\'']], + 'ISK' => [['Icelandic króna'], ['aurar']], + 'JPY' => [['yen'], ['sen']], + 'LTL' => [['litas'], ['cent']], + 'LVL' => [['lat'], ['sentim']], + 'LYD' => [['dinar'], ['cent']], + 'MAD' => [['dirham'], ['cent']], + 'MKD' => [['Macedonian dinar'], ['deni']], + 'MRO' => [['ouguiya'], ['khoums']], + 'MTL' => [['Maltese lira'], ['centym']], + 'NGN' => [['Naira'], ['kobo']], + 'NOK' => [['Norwegian krone'], ['oere']], + 'PHP' => [['peso'], ['centavo']], + 'PLN' => [['zloty', 'zlotys'], ['grosz']], + 'ROL' => [['Romanian leu'], ['bani']], + 'RUB' => [['Russian Federation rouble'], ['kopiejka']], + 'SAR' => [['Riyal'], ['Halalah']], + 'SEK' => [['Swedish krona'], ['oere']], + 'SIT' => [['Tolar'], ['stotinia']], + 'SKK' => [['Slovak koruna'], []], + 'TMT' => [['manat'], ['tenge']], + 'TND' => [['dinar'], ['millime']], + 'TRL' => [['lira'], ['kuruş']], + 'TRY' => [['lira'], ['kuruş']], + 'UAH' => [['hryvna'], ['cent']], + 'USD' => [['דולר', 'דולר'], ['סנט', 'סנט']], + 'XAF' => [['CFA franc'], ['cent']], + 'XOF' => [['CFA franc'], ['cent']], + 'XPF' => [['CFP franc'], ['centime']], + 'YUM' => [['dinar'], ['para']], + 'ZAR' => [['rand'], ['cent']], + 'UZS' => [['sum'], ['tiyin']], + ]; + + public function getZero(): string + { + return 'אפס'; + } + + public function getMinus(): string + { + return 'מינוס'; + } + + public function getCorrespondingUnit(int $unit): string + { + return self::$units[$unit]; + } + + public function getCorrespondingTen(int $ten): string + { + return self::$tens[$ten]; + } + + public function getCorrespondingTeen(int $teen): string + { + return self::$teens[$teen]; + } + + public function getCorrespondingHundred(int $hundred): string + { + return self::$hundred[$hundred]; + } +} diff --git a/src/Language/Hebrew/HebrewExponentGetter.php b/src/Language/Hebrew/HebrewExponentGetter.php new file mode 100644 index 00000000..7381a48b --- /dev/null +++ b/src/Language/Hebrew/HebrewExponentGetter.php @@ -0,0 +1,38 @@ +inflector = $inflector; + } + + + /** + * @param int $number + * @param int $power + * + * @return string + */ + public function inflectExponent($number, $power): string + { + var_dump($number, $power); + if($power === 0) return ''; + + return $this->inflector->inflectNounByNumber( + $number, + self::$exponent[$power][0], + self::$exponent[$power][1], + $power === 1 ? self::$exponentBetweenTenToTeweny : [] + ); + } +} diff --git a/src/Language/Hebrew/HebrewNounGenderInflector.php b/src/Language/Hebrew/HebrewNounGenderInflector.php new file mode 100644 index 00000000..55477c9d --- /dev/null +++ b/src/Language/Hebrew/HebrewNounGenderInflector.php @@ -0,0 +1,30 @@ + 2 && $tens === 0) || ($units === 0 && $tens === 1)) { + return $genitivePlural; + } + + return $genitivePlural; + } +} diff --git a/src/Language/Hebrew/HebrewTripletTransformer.php b/src/Language/Hebrew/HebrewTripletTransformer.php new file mode 100644 index 00000000..64f6a13e --- /dev/null +++ b/src/Language/Hebrew/HebrewTripletTransformer.php @@ -0,0 +1,111 @@ +dictionary = $dictionary; + } + + /** + * @param int $number + * + * @return string + */ + public function transformToWords($number, $power): string + { + + $units = $number % 10; + $tens = (int) ($number / 10) % 10; + $hundreds = (int) ($number / 100) % 10; + $words = []; + + if ($hundreds > 0) { + $words[] = $this->dictionary->getCorrespondingHundred($hundreds); + } + + if ($tens !== 0 || $units !== 0) { + $words[] = $this->getSubHundred($tens, $units, $power, $number > 100); + } + return implode(' ', $words); + } + + /** + * @param int $tens + * @param int $units + * + * @return string + */ + private function getSubHundred($tens, $units, $power, $exPower) + { + $words = []; + + if ($tens === 1 && (($units > 0 || $exPower))) { + $words[] = $this->dictionary->getCorrespondingTeen($units); + } else { + if ($units > 9 || $tens || $power === 0) { + if ($tens > 0 && !($tens === 1 && $units === 0)) { + $words[] = $this->dictionary->getCorrespondingTen($tens); + } + if ($units > 0) { + $words[] = $this->dictionary->getCorrespondingUnit($units); + } + if($units === 0 && $tens === 1) { + $words[] = $this->dictionary->getCorrespondingTen($tens); + } + } elseif((!$power && !$tens) || (!$tens && $units && $exPower)) { + $words[] = $this->dictionary->getCorrespondingUnit($units); + } elseif($tens) { + $words[] = $this->dictionary->getCorrespondingTen($tens); + } + } + + if(count($words) === 1 && $exPower) { + return 'ו' . $words[0]; + } + + return implode(' ו', $words); + } + + // public function transformToWords(int $number): string + // { + // $units = $number % 10; + // $tens = (int) ($number / 10) % 10; + // $hundreds = (int) ($number / 100) % 10; + // $words = []; + + // if ($hundreds > 0) { + // $words[] = $this->dictionary->getCorrespondingHundred($hundreds); + // } + + // if ($tens !== 0 || $units !== 0) { + // $words[] = $this->getSubHundred($tens, $units); + // } + + // return implode(' ', $words); + // } + + // private function getSubHundred($tens, $units): string + // { + // $words = []; + + // if ($tens === 1) { + // $words[] = $this->dictionary->getCorrespondingTeen($units); + // } else { + // if ($tens > 0) { + // $words[] = $this->dictionary->getCorrespondingTen($tens); + // } + // if ($units > 0) { + // $words[] = $this->dictionary->getCorrespondingUnit($units); + // } + // } + + // return implode(' ו', $words); + // } +} diff --git a/src/NumberTransformer/HebrewNumberTransformer.php b/src/NumberTransformer/HebrewNumberTransformer.php new file mode 100644 index 00000000..06b24d09 --- /dev/null +++ b/src/NumberTransformer/HebrewNumberTransformer.php @@ -0,0 +1,29 @@ +withDictionary($dictionary) + ->withWordsSeparatedBy(' ') + ->transformNumbersBySplittingIntoPowerAwareTriplets($numberToTripletsConverter, $tripletTransformer) + ->inflectExponentByNumbers($exponentInflector) + ->build(); + + return $numberTransformer->toWords($number); + } +} From d54c7f0596a4bdb371d4a764e713e8c60d34265c Mon Sep 17 00:00:00 2001 From: simcha Date: Sun, 17 Dec 2023 08:12:18 +0200 Subject: [PATCH 2/6] Fix Tests results - Hebrew --- src/Language/Hebrew/HebrewDictionary.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Language/Hebrew/HebrewDictionary.php b/src/Language/Hebrew/HebrewDictionary.php index a4989187..1019acbd 100644 --- a/src/Language/Hebrew/HebrewDictionary.php +++ b/src/Language/Hebrew/HebrewDictionary.php @@ -67,12 +67,12 @@ class HebrewDictionary implements Dictionary 'DZD' => [['dinar'], ['cent']], 'EEK' => [['kroon'], ['senti']], 'EGP' => [['Egyptian Pound'], ['piastre']], - 'EUR' => [['euro'], ['euro-cent']], + 'EUR' => [['אירו'], ['אירו סנט']], 'GBP' => [['pound', 'pounds'], ['pence', 'pence']], 'HKD' => [['Hong Kong dollar'], ['cent']], 'HRK' => [['Croatian kuna'], ['lipa']], 'HUF' => [['forint'], ['filler']], - 'ILS' => [['ש"ח', 'ש"ח'], ['אג\'', 'אג\'']], + 'ILS' => [['ש"ח', 'ש"ח'], ['אגו\'', 'אגו\'']], 'ISK' => [['Icelandic króna'], ['aurar']], 'JPY' => [['yen'], ['sen']], 'LTL' => [['litas'], ['cent']], From 62597344d4088f73d31bd7d37bbf0e0dec7954df Mon Sep 17 00:00:00 2001 From: simcha Date: Sun, 17 Dec 2023 08:27:54 +0200 Subject: [PATCH 3/6] Fix Tests and add to readme --- README.md | 1 + .../HebrewCurrencyTransformer.php | 2 +- .../Hebrew/HebrewExponentInflector.php | 10 ++-- .../Hebrew/HebrewNounGenderInflector.php | 4 +- .../Hebrew/HebrewTripletTransformer.php | 46 ++----------------- 5 files changed, 16 insertions(+), 47 deletions(-) diff --git a/README.md b/README.md index 3bd90aa3..6ae78daf 100644 --- a/README.md +++ b/README.md @@ -112,6 +112,7 @@ Note: The Currency Transformer within this library processes integers; ensure yo | Ukrainian | ua | + | + | | Uzbek | uz | + | + | | Yoruba | yo | + | + | +| Hebrew | he | + | + | ## Contributors diff --git a/src/CurrencyTransformer/HebrewCurrencyTransformer.php b/src/CurrencyTransformer/HebrewCurrencyTransformer.php index f8482981..53c61cb5 100644 --- a/src/CurrencyTransformer/HebrewCurrencyTransformer.php +++ b/src/CurrencyTransformer/HebrewCurrencyTransformer.php @@ -46,7 +46,7 @@ public function toWords(int $amount, string $currency, ?CurrencyTransformerOptio $currencyNames = HebrewDictionary::$currencyNames[$currency]; $return = trim($numberTransformer->toWords($decimal)); - + $level = ($decimal === 1) ? 0 : 1; if ($level > 0) { diff --git a/src/Language/Hebrew/HebrewExponentInflector.php b/src/Language/Hebrew/HebrewExponentInflector.php index da2f89ad..56263831 100644 --- a/src/Language/Hebrew/HebrewExponentInflector.php +++ b/src/Language/Hebrew/HebrewExponentInflector.php @@ -24,9 +24,9 @@ class HebrewExponentInflector implements ExponentInflector ]; private static $exponentBetweenTenToTeweny = [ - '', - 'אלף', - 'אלפיים', + '', + 'אלף', + 'אלפיים', 'שלושת', 'ארבעת', 'חמשת', @@ -60,7 +60,9 @@ public function __construct(HebrewNounGenderInflector $inflector) public function inflectExponent($number, $power): string { var_dump($number, $power); - if($power === 0) return ''; + if ($power === 0) { + return ''; + } return $this->inflector->inflectNounByNumber( $number, diff --git a/src/Language/Hebrew/HebrewNounGenderInflector.php b/src/Language/Hebrew/HebrewNounGenderInflector.php index 55477c9d..580739a0 100644 --- a/src/Language/Hebrew/HebrewNounGenderInflector.php +++ b/src/Language/Hebrew/HebrewNounGenderInflector.php @@ -18,7 +18,9 @@ public function inflectNounByNumber($number, $plural, $genitivePlural, array $ex $tens = ((int) ($number / 10)) % 10; if ($number <= 10) { - return ($exponentBetweenTenToTeweny[$number] ?? false) ? $exponentBetweenTenToTeweny[$number] . ' ' . $plural : $plural; + return ($exponentBetweenTenToTeweny[$number] ?? false) + ? $exponentBetweenTenToTeweny[$number] . ' ' . $plural + : $plural; } if (($units > 2 && $tens === 0) || ($units === 0 && $tens === 1)) { diff --git a/src/Language/Hebrew/HebrewTripletTransformer.php b/src/Language/Hebrew/HebrewTripletTransformer.php index 64f6a13e..b0687241 100644 --- a/src/Language/Hebrew/HebrewTripletTransformer.php +++ b/src/Language/Hebrew/HebrewTripletTransformer.php @@ -19,7 +19,7 @@ public function __construct(HebrewDictionary $dictionary) * @return string */ public function transformToWords($number, $power): string - { + { $units = $number % 10; $tens = (int) ($number / 10) % 10; @@ -56,56 +56,20 @@ private function getSubHundred($tens, $units, $power, $exPower) if ($units > 0) { $words[] = $this->dictionary->getCorrespondingUnit($units); } - if($units === 0 && $tens === 1) { + if ($units === 0 && $tens === 1) { $words[] = $this->dictionary->getCorrespondingTen($tens); } - } elseif((!$power && !$tens) || (!$tens && $units && $exPower)) { + } elseif ((!$power && !$tens) || (!$tens && $units && $exPower)) { $words[] = $this->dictionary->getCorrespondingUnit($units); - } elseif($tens) { + } elseif ($tens) { $words[] = $this->dictionary->getCorrespondingTen($tens); } } - if(count($words) === 1 && $exPower) { + if (count($words) === 1 && $exPower) { return 'ו' . $words[0]; } return implode(' ו', $words); } - - // public function transformToWords(int $number): string - // { - // $units = $number % 10; - // $tens = (int) ($number / 10) % 10; - // $hundreds = (int) ($number / 100) % 10; - // $words = []; - - // if ($hundreds > 0) { - // $words[] = $this->dictionary->getCorrespondingHundred($hundreds); - // } - - // if ($tens !== 0 || $units !== 0) { - // $words[] = $this->getSubHundred($tens, $units); - // } - - // return implode(' ', $words); - // } - - // private function getSubHundred($tens, $units): string - // { - // $words = []; - - // if ($tens === 1) { - // $words[] = $this->dictionary->getCorrespondingTeen($units); - // } else { - // if ($tens > 0) { - // $words[] = $this->dictionary->getCorrespondingTen($tens); - // } - // if ($units > 0) { - // $words[] = $this->dictionary->getCorrespondingUnit($units); - // } - // } - - // return implode(' ו', $words); - // } } From 72ad2bf6208cb6e25cdc6c4af8bae6535b26041d Mon Sep 17 00:00:00 2001 From: simcha Date: Sun, 17 Dec 2023 09:35:12 +0200 Subject: [PATCH 4/6] delete var_dump --- src/Language/Hebrew/HebrewExponentInflector.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Language/Hebrew/HebrewExponentInflector.php b/src/Language/Hebrew/HebrewExponentInflector.php index 56263831..15648b1e 100644 --- a/src/Language/Hebrew/HebrewExponentInflector.php +++ b/src/Language/Hebrew/HebrewExponentInflector.php @@ -59,7 +59,6 @@ public function __construct(HebrewNounGenderInflector $inflector) */ public function inflectExponent($number, $power): string { - var_dump($number, $power); if ($power === 0) { return ''; } From 6763add3894594d4f2d62658d41d00b12fa57a91 Mon Sep 17 00:00:00 2001 From: simcha Date: Sun, 17 Dec 2023 11:39:13 +0200 Subject: [PATCH 5/6] fix --- src/Language/Hebrew/HebrewNounGenderInflector.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Language/Hebrew/HebrewNounGenderInflector.php b/src/Language/Hebrew/HebrewNounGenderInflector.php index 580739a0..8957b48b 100644 --- a/src/Language/Hebrew/HebrewNounGenderInflector.php +++ b/src/Language/Hebrew/HebrewNounGenderInflector.php @@ -17,7 +17,7 @@ public function inflectNounByNumber($number, $plural, $genitivePlural, array $ex $units = $number % 10; $tens = ((int) ($number / 10)) % 10; - if ($number <= 10) { + if ($number > 1 && $number <= 10) { return ($exponentBetweenTenToTeweny[$number] ?? false) ? $exponentBetweenTenToTeweny[$number] . ' ' . $plural : $plural; From a01f403f4e47196e2798e5d0bc6cba3476ba99d9 Mon Sep 17 00:00:00 2001 From: simcha Date: Sun, 17 Dec 2023 11:48:06 +0200 Subject: [PATCH 6/6] fix --- src/Language/Hebrew/HebrewNounGenderInflector.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Language/Hebrew/HebrewNounGenderInflector.php b/src/Language/Hebrew/HebrewNounGenderInflector.php index 8957b48b..4feb9da2 100644 --- a/src/Language/Hebrew/HebrewNounGenderInflector.php +++ b/src/Language/Hebrew/HebrewNounGenderInflector.php @@ -18,6 +18,9 @@ public function inflectNounByNumber($number, $plural, $genitivePlural, array $ex $tens = ((int) ($number / 10)) % 10; if ($number > 1 && $number <= 10) { + if($number === 2) { + return $exponentBetweenTenToTeweny[$number] ?? $plural; + } return ($exponentBetweenTenToTeweny[$number] ?? false) ? $exponentBetweenTenToTeweny[$number] . ' ' . $plural : $plural;