From 533cd7ef6c2019ae2d562e13f03f6c204d6fb9bd Mon Sep 17 00:00:00 2001 From: kylekatarnls Date: Tue, 19 Jan 2021 20:18:07 +0100 Subject: [PATCH] [Translator] fix handling plural for floating numbers --- .../Component/Translation/IdentityTranslator.php | 2 +- .../Component/Translation/PluralizationRules.php | 6 ++++-- .../Component/Translation/Tests/TranslatorTest.php | 12 ++++++++++++ .../Contracts/Translation/TranslatorTrait.php | 6 ++++-- 4 files changed, 21 insertions(+), 5 deletions(-) diff --git a/src/Symfony/Component/Translation/IdentityTranslator.php b/src/Symfony/Component/Translation/IdentityTranslator.php index 7316148e53..8643396150 100644 --- a/src/Symfony/Component/Translation/IdentityTranslator.php +++ b/src/Symfony/Component/Translation/IdentityTranslator.php @@ -70,7 +70,7 @@ class IdentityTranslator implements LegacyTranslatorInterface, TranslatorInterfa return $this->trans($id, ['%count%' => $number] + $parameters, $domain, $locale); } - private function getPluralizationRule(int $number, string $locale): int + private function getPluralizationRule(float $number, string $locale): int { return PluralizationRules::get($number, $locale, false); } diff --git a/src/Symfony/Component/Translation/PluralizationRules.php b/src/Symfony/Component/Translation/PluralizationRules.php index f5fba40394..2a46ce094f 100644 --- a/src/Symfony/Component/Translation/PluralizationRules.php +++ b/src/Symfony/Component/Translation/PluralizationRules.php @@ -25,13 +25,15 @@ class PluralizationRules /** * Returns the plural position to use for the given locale and number. * - * @param int $number The number + * @param float $number The number * @param string $locale The locale * * @return int The plural position */ public static function get($number, $locale/*, bool $triggerDeprecation = true*/) { + $number = abs($number); + if (3 > \func_num_args() || func_get_arg(2)) { @trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.2.', __CLASS__), \E_USER_DEPRECATED); } @@ -144,7 +146,7 @@ class PluralizationRules case 'xbr': case 'ti': case 'wa': - return ((0 == $number) || (1 == $number)) ? 0 : 1; + return ($number < 2) ? 0 : 1; case 'be': case 'bs': diff --git a/src/Symfony/Component/Translation/Tests/TranslatorTest.php b/src/Symfony/Component/Translation/Tests/TranslatorTest.php index a647ea5379..bfe5cd9ab8 100644 --- a/src/Symfony/Component/Translation/Tests/TranslatorTest.php +++ b/src/Symfony/Component/Translation/Tests/TranslatorTest.php @@ -612,6 +612,18 @@ class TranslatorTest extends TestCase // Override %count% with a custom value ['Il y a quelques pommes', 'one: There is one apple|more: There are %count% apples', 'one: Il y a %count% pomme|more: Il y a quelques pommes', 2, ['%count%' => 'quelques'], 'fr', ''], + + // Floating values + ['1.5 liters', 'key', '%count% liter|%count% liters', 1.5, ['%count%' => 1.5], 'en', ''], + ['1.5 litre', 'key', '%count% litre|%count% litres', 1.5, ['%count%' => 1.5], 'fr', ''], + + // Negative values + ['-1 degree', 'key', '%count% degree|%count% degrees', -1, ['%count%' => -1], 'en', ''], + ['-1 degré', 'key', '%count% degré|%count% degrés', -1, ['%count%' => -1], 'fr', ''], + ['-1.5 degrees', 'key', '%count% degree|%count% degrees', -1.5, ['%count%' => -1.5], 'en', ''], + ['-1.5 degré', 'key', '%count% degré|%count% degrés', -1.5, ['%count%' => -1.5], 'fr', ''], + ['-2 degrees', 'key', '%count% degree|%count% degrees', -2, ['%count%' => -2], 'en', ''], + ['-2 degrés', 'key', '%count% degré|%count% degrés', -2, ['%count%' => -2], 'fr', ''], ]; } diff --git a/src/Symfony/Contracts/Translation/TranslatorTrait.php b/src/Symfony/Contracts/Translation/TranslatorTrait.php index 68050ee4a1..2c09c5f14d 100644 --- a/src/Symfony/Contracts/Translation/TranslatorTrait.php +++ b/src/Symfony/Contracts/Translation/TranslatorTrait.php @@ -136,8 +136,10 @@ EOF; * which is subject to the new BSD license (http://framework.zend.com/license/new-bsd). * Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) */ - private function getPluralizationRule(int $number, string $locale): int + private function getPluralizationRule(float $number, string $locale): int { + $number = abs($number); + switch ('pt_BR' !== $locale && \strlen($locale) > 3 ? substr($locale, 0, strrpos($locale, '_')) : $locale) { case 'af': case 'bn': @@ -205,7 +207,7 @@ EOF; case 'pt_BR': case 'ti': case 'wa': - return ((0 == $number) || (1 == $number)) ? 0 : 1; + return ($number < 2) ? 0 : 1; case 'be': case 'bs':