From 9c837ddc1a74aecb9d5c1ca80c3ac47740ab4e4c Mon Sep 17 00:00:00 2001 From: Javier Spagnoletti Date: Thu, 4 Jun 2020 00:30:59 -0300 Subject: [PATCH 1/3] Require "twig/intl-extra" --- composer.json | 2 + src/Resources/config/intl.xml | 1 + src/Templating/Helper/LocaleHelper.php | 68 +++++++++++++++++--------- src/Twig/Extension/LocaleExtension.php | 2 + tests/Helper/LocaleHelperTest.php | 9 ++-- 5 files changed, 56 insertions(+), 26 deletions(-) diff --git a/composer.json b/composer.json index 5981ce41..1634dacb 100644 --- a/composer.json +++ b/composer.json @@ -29,6 +29,8 @@ "symfony/http-kernel": "^4.4", "symfony/intl": "^4.4", "symfony/templating": "^4.4", + "twig/extra-bundle": "^3.0", + "twig/intl-extra": "^3.0", "twig/twig": "^2.9" }, "conflict": { diff --git a/src/Resources/config/intl.xml b/src/Resources/config/intl.xml index 3c1e0441..bbaadabb 100644 --- a/src/Resources/config/intl.xml +++ b/src/Resources/config/intl.xml @@ -26,6 +26,7 @@ %kernel.charset% + diff --git a/src/Templating/Helper/LocaleHelper.php b/src/Templating/Helper/LocaleHelper.php index e86d55c8..dcf442e6 100644 --- a/src/Templating/Helper/LocaleHelper.php +++ b/src/Templating/Helper/LocaleHelper.php @@ -13,18 +13,36 @@ namespace Sonata\IntlBundle\Templating\Helper; +use Sonata\IntlBundle\Locale\LocaleDetectorInterface; use Symfony\Component\Intl\Countries; -use Symfony\Component\Intl\Intl; use Symfony\Component\Intl\Languages; use Symfony\Component\Intl\Locales; +use Twig\Extra\Intl\IntlExtension; /** * LocaleHelper displays culture information. * + * @final since sonata-project/intl-bundle 2.x + * * @author Thomas Rabaix */ class LocaleHelper extends BaseHelper { + /** + * @var IntlExtension|null + */ + private $intlExtension; + + /** + * @param string $charset The output charset of the helper + */ + public function __construct(string $charset, LocaleDetectorInterface $localeDetector, ?IntlExtension $intlExtension = null) + { + parent::__construct($charset, $localeDetector); + + $this->intlExtension = $intlExtension; + } + /** * @param string $code * @param string|null $locale @@ -33,13 +51,17 @@ class LocaleHelper extends BaseHelper */ public function country($code, $locale = null) { - // NEXT_MAJOR: Remove this when dropping < 4.3 Symfony support - if (!class_exists(Countries::class)) { - $name = Intl::getRegionBundle()->getCountryName($code, $locale ?: $this->localeDetector->getLocale()); - - return $name ? $this->fixCharset($name) : ''; + if ($this->intlExtension) { + return $this->fixCharset($this->intlExtension->getCountryName($code, $locale ?: $this->localeDetector->getLocale())); } + @trigger_error(sprintf( + 'Not passing an instance of "%s" as argument 3 for %s::__construct() is deprecated since sonata-project/intl-bundle 2.x.' + .' and will throw an exception since version 3.x.', + IntlExtension::class, + __CLASS__ + )); + return $this->fixCharset(Countries::getName($code, $locale ?: $this->localeDetector->getLocale())); } @@ -51,19 +73,17 @@ public function country($code, $locale = null) */ public function language($code, $locale = null) { - // NEXT_MAJOR: Remove this when dropping < 4.3 Symfony support - if (!class_exists(Languages::class)) { - $codes = explode('_', $code); - - $name = Intl::getLanguageBundle()->getLanguageName( - $codes[0], - $codes[1] ?? null, - $locale ?: $this->localeDetector->getLocale() - ); - - return $name ? $this->fixCharset($name) : ''; + if ($this->intlExtension) { + $this->fixCharset($this->intlExtension->getLanguageName($code, $locale)); } + @trigger_error(sprintf( + 'Not passing an instance of "%s" as argument 3 for %s::__construct() is deprecated since sonata-project/intl-bundle 2.x.' + .' and will throw an exception since version 3.x.', + IntlExtension::class, + __CLASS__ + )); + return $this->fixCharset(Languages::getName($code, $locale ?: $this->localeDetector->getLocale())); } @@ -75,13 +95,17 @@ public function language($code, $locale = null) */ public function locale($code, $locale = null) { - // NEXT_MAJOR: Remove this when dropping < 4.3 Symfony support - if (!class_exists(Locales::class)) { - $name = Intl::getLocaleBundle()->getLocaleName($code, $locale ?: $this->localeDetector->getLocale()); - - return $name ? $this->fixCharset($name) : ''; + if ($this->intlExtension) { + $this->fixCharset($this->intlExtension->getLocaleName($code, $locale)); } + @trigger_error(sprintf( + 'Not passing an instance of "%s" as argument 3 for %s::__construct() is deprecated since sonata-project/intl-bundle 2.x.' + .' and will throw an exception since version 3.x.', + IntlExtension::class, + __CLASS__ + )); + return $this->fixCharset(Locales::getName($code, $locale ?: $this->localeDetector->getLocale())); } diff --git a/src/Twig/Extension/LocaleExtension.php b/src/Twig/Extension/LocaleExtension.php index 96df770a..50aa1a9d 100644 --- a/src/Twig/Extension/LocaleExtension.php +++ b/src/Twig/Extension/LocaleExtension.php @@ -20,6 +20,8 @@ /** * LocaleExtension extends Twig with local capabilities. * + * @final since sonata-project/intl-bundle 2.x + * * @author Thomas Rabaix */ class LocaleExtension extends AbstractExtension diff --git a/tests/Helper/LocaleHelperTest.php b/tests/Helper/LocaleHelperTest.php index 18c5017f..89312436 100644 --- a/tests/Helper/LocaleHelperTest.php +++ b/tests/Helper/LocaleHelperTest.php @@ -16,10 +16,11 @@ use PHPUnit\Framework\TestCase; use Sonata\IntlBundle\Locale\LocaleDetectorInterface; use Sonata\IntlBundle\Templating\Helper\LocaleHelper; +use Symfony\Component\Templating\Helper\HelperInterface; class LocaleHelperTest extends TestCase { - public function getHelper() + public function getHelper(): HelperInterface { $localeDetector = $this->createMock(LocaleDetectorInterface::class); $localeDetector @@ -31,7 +32,7 @@ public function getHelper() /** * @group legacy */ - public function testLanguage() + public function testLanguage(): void { $helper = $this->getHelper(); $this->assertSame('français', $helper->language('fr')); @@ -40,7 +41,7 @@ public function testLanguage() $this->assertSame('French', $helper->language('fr', 'en')); } - public function testCountry() + public function testCountry(): void { $helper = $this->getHelper(); $this->assertSame('France', $helper->country('FR')); @@ -48,7 +49,7 @@ public function testCountry() // $this->assertEquals('', $helper->country('FR', 'fake')); } - public function testLocale() + public function testLocale(): void { $helper = $this->getHelper(); From 721434e7e020c21be12f584028b73eb8b1e885fa Mon Sep 17 00:00:00 2001 From: Javier Spagnoletti Date: Sat, 6 Jun 2020 10:36:39 -0300 Subject: [PATCH 2/3] Update tests --- src/Templating/Helper/NumberHelper.php | 33 +++++++++- tests/Helper/LocaleHelperTest.php | 86 ++++++++++++++++++++------ tests/Helper/NumberHelperTest.php | 7 ++- 3 files changed, 103 insertions(+), 23 deletions(-) diff --git a/src/Templating/Helper/NumberHelper.php b/src/Templating/Helper/NumberHelper.php index de63f019..8c68544c 100644 --- a/src/Templating/Helper/NumberHelper.php +++ b/src/Templating/Helper/NumberHelper.php @@ -14,10 +14,13 @@ namespace Sonata\IntlBundle\Templating\Helper; use Sonata\IntlBundle\Locale\LocaleDetectorInterface; +use Twig\Extra\Intl\IntlExtension; /** * NumberHelper displays culture information. * + * @final since sonata-project/intl-bundle 2.x + * * @author Thomas Rabaix * @author Stefano Arlandini */ @@ -38,6 +41,11 @@ class NumberHelper extends BaseHelper */ protected $symbols = []; + /** + * @var IntlExtension|null + */ + private $intlExtension; + /** * @param string $charset The output charset of the helper * @param LocaleDetectorInterface $localeDetector A locale detector instance @@ -45,13 +53,14 @@ class NumberHelper extends BaseHelper * @param array $textAttributes The default text attributes to apply to the \NumberFormatter instance * @param array $symbols The default symbols to apply to the \NumberFormatter instance */ - public function __construct($charset, LocaleDetectorInterface $localeDetector, array $attributes = [], array $textAttributes = [], array $symbols = []) + public function __construct($charset, LocaleDetectorInterface $localeDetector, array $attributes = [], array $textAttributes = [], array $symbols = [], ?IntlExtension $intlExtension = null) { parent::__construct($charset, $localeDetector); $this->attributes = $attributes; $this->textAttributes = $textAttributes; $this->symbols = $symbols; + $this->intlExtension = $intlExtension; } /** @@ -67,6 +76,17 @@ public function __construct($charset, LocaleDetectorInterface $localeDetector, a */ public function formatPercent($number, array $attributes = [], array $textAttributes = [], $locale = null) { + if ($this->intlExtension) { + return $this->fixCharset($this->intlExtension->formatNumberStyle($locale, $number, $attributes, 'default', $locale ?: $this->localeDetector->getLocale())); + } + + @trigger_error(sprintf( + 'Not passing an instance of "%s" as argument 6 for %s::__construct() is deprecated since sonata-project/intl-bundle 2.x.' + .' and will throw an exception since version 3.x.', + IntlExtension::class, + __CLASS__ + )); + $methodArgs = array_pad(\func_get_args(), 5, null); [$locale, $symbols] = $this->normalizeMethodSignature($methodArgs[3], $methodArgs[4]); @@ -148,6 +168,17 @@ public function formatSpellout($number, array $attributes = [], array $textAttri */ public function formatCurrency($number, $currency, array $attributes = [], array $textAttributes = [], $locale = null) { + if ($this->intlExtension) { + return $this->fixCharset($this->intlExtension->formatCurrency($number, $currency, $attributes, $locale ?: $this->localeDetector->getLocale())); + } + + @trigger_error(sprintf( + 'Not passing an instance of "%s" as argument 6 for %s::__construct() is deprecated since sonata-project/intl-bundle 2.x.' + .' and will throw an exception since version 3.x.', + IntlExtension::class, + __CLASS__ + )); + // convert Doctrine's decimal type (fixed-point number represented as string) to float for backward compatibility if (\is_string($number) && is_numeric($number)) { $number = (float) $number; diff --git a/tests/Helper/LocaleHelperTest.php b/tests/Helper/LocaleHelperTest.php index 89312436..c3501c54 100644 --- a/tests/Helper/LocaleHelperTest.php +++ b/tests/Helper/LocaleHelperTest.php @@ -17,16 +17,30 @@ use Sonata\IntlBundle\Locale\LocaleDetectorInterface; use Sonata\IntlBundle\Templating\Helper\LocaleHelper; use Symfony\Component\Templating\Helper\HelperInterface; +use Twig\Extra\Intl\IntlExtension; -class LocaleHelperTest extends TestCase +final class LocaleHelperTest extends TestCase { - public function getHelper(): HelperInterface + /** + * NEXT_MAJOR: Remove this property. + * + * @var HelperInterface + */ + private $legacyLocaleHelper; + + /** + * @var HelperInterface + */ + private $localeHelper; + + protected function setUp(): void { $localeDetector = $this->createMock(LocaleDetectorInterface::class); $localeDetector ->method('getLocale')->willReturn('fr'); - return new LocaleHelper('UTF-8', $localeDetector); + $this->localeHelper = new LocaleHelper('UTF-8', $localeDetector, new IntlExtension()); + $this->legacyLocaleHelper = new LocaleHelper('UTF-8', $localeDetector); } /** @@ -34,31 +48,65 @@ public function getHelper(): HelperInterface */ public function testLanguage(): void { - $helper = $this->getHelper(); - $this->assertSame('français', $helper->language('fr')); - $this->assertSame('français', $helper->language('fr_FR')); - $this->assertSame('anglais américain', $helper->language('en_US')); - $this->assertSame('French', $helper->language('fr', 'en')); + $this->assertSame('français', $this->localeHelper->language('fr')); + $this->assertSame('français', $this->localeHelper->language('fr_FR')); + $this->assertSame('anglais américain', $this->localeHelper->language('en_US')); + $this->assertSame('French', $this->localeHelper->language('fr', 'en')); } public function testCountry(): void { - $helper = $this->getHelper(); - $this->assertSame('France', $helper->country('FR')); - $this->assertSame('France', $helper->country('FR', 'en')); - // $this->assertEquals('', $helper->country('FR', 'fake')); + $this->assertSame('France', $this->localeHelper->country('FR')); + $this->assertSame('France', $this->localeHelper->country('FR', 'en')); + // $this->assertEquals('', $this->localeHelper->country('FR', 'fake')); } public function testLocale(): void { - $helper = $this->getHelper(); + $this->assertSame('français', $this->localeHelper->locale('fr')); + $this->assertSame('français (Canada)', $this->localeHelper->locale('fr_CA')); + + $this->assertSame('French', $this->localeHelper->locale('fr', 'en')); + $this->assertSame('French (Canada)', $this->localeHelper->locale('fr_CA', 'en')); + // $this->assertEquals('', $this->localeHelper->locale('fr', 'fake')); + // $this->assertEquals('', $this->localeHelper->locale('fr_CA', 'fake')); + } + + /** + * NEXT_MAJOR: Remove this method. + * + * @group legacy + */ + public function testLegacyLanguage(): void + { + $this->assertSame('français', $this->legacyLocaleHelper->language('fr')); + $this->assertSame('français', $this->legacyLocaleHelper->language('fr_FR')); + $this->assertSame('anglais américain', $this->legacyLocaleHelper->language('en_US')); + $this->assertSame('French', $this->legacyLocaleHelper->language('fr', 'en')); + } + + /** + * NEXT_MAJOR: Remove this method. + * + * @group legacy + */ + public function testLegacyCountry(): void + { + $this->assertSame('France', $this->legacyLocaleHelper->country('FR')); + $this->assertSame('France', $this->legacyLocaleHelper->country('FR', 'en')); + } - $this->assertSame('français', $helper->locale('fr')); - $this->assertSame('français (Canada)', $helper->locale('fr_CA')); + /** + * NEXT_MAJOR: Remove this method. + * + * @group legacy + */ + public function testLegacyLocale(): void + { + $this->assertSame('français', $this->legacyLocaleHelper->locale('fr')); + $this->assertSame('français (Canada)', $this->legacyLocaleHelper->locale('fr_CA')); - $this->assertSame('French', $helper->locale('fr', 'en')); - $this->assertSame('French (Canada)', $helper->locale('fr_CA', 'en')); - // $this->assertEquals('', $helper->locale('fr', 'fake')); - // $this->assertEquals('', $helper->locale('fr_CA', 'fake')); + $this->assertSame('French', $this->legacyLocaleHelper->locale('fr', 'en')); + $this->assertSame('French (Canada)', $this->legacyLocaleHelper->locale('fr_CA', 'en')); } } diff --git a/tests/Helper/NumberHelperTest.php b/tests/Helper/NumberHelperTest.php index 582c377d..ceafe94c 100644 --- a/tests/Helper/NumberHelperTest.php +++ b/tests/Helper/NumberHelperTest.php @@ -16,16 +16,17 @@ use PHPUnit\Framework\TestCase; use Sonata\IntlBundle\Locale\LocaleDetectorInterface; use Sonata\IntlBundle\Templating\Helper\NumberHelper; +use Twig\Extra\Intl\IntlExtension; /** * @author Stefano Arlandini */ -class NumberHelperTest extends TestCase +final class NumberHelperTest extends TestCase { - public function testLocale() + public function testLocale(): void { $localeDetector = $this->createLocaleDetectorMock(); - $helper = new NumberHelper('UTF-8', $localeDetector); + $helper = new NumberHelper('UTF-8', $localeDetector, [], [], [], new IntlExtension()); // currency $this->assertSame('€10.49', $helper->formatCurrency(10.49, 'EUR')); From f1fa92e943c02e6939bdea529b874fd69ba10b4a Mon Sep 17 00:00:00 2001 From: Javier Spagnoletti Date: Sat, 6 Jun 2020 14:22:48 -0300 Subject: [PATCH 3/3] Update `NumberHelper` --- src/Templating/Helper/NumberHelper.php | 159 ++++++++++++++++++++++++- tests/Helper/NumberHelperTest.php | 44 +++---- 2 files changed, 171 insertions(+), 32 deletions(-) diff --git a/src/Templating/Helper/NumberHelper.php b/src/Templating/Helper/NumberHelper.php index 8c68544c..c3dc683c 100644 --- a/src/Templating/Helper/NumberHelper.php +++ b/src/Templating/Helper/NumberHelper.php @@ -77,12 +77,16 @@ public function __construct($charset, LocaleDetectorInterface $localeDetector, a public function formatPercent($number, array $attributes = [], array $textAttributes = [], $locale = null) { if ($this->intlExtension) { - return $this->fixCharset($this->intlExtension->formatNumberStyle($locale, $number, $attributes, 'default', $locale ?: $this->localeDetector->getLocale())); + $attributes = self::processLegacyAttributes($attributes); + + return $this->fixCharset($this->intlExtension->formatNumberStyle('percent', $number, $attributes, 'default', $locale ?: $this->localeDetector->getLocale())); } + // NEXT_MAJOR: Execute the previous block unconditionally and remove following lines in this method. + @trigger_error(sprintf( 'Not passing an instance of "%s" as argument 6 for %s::__construct() is deprecated since sonata-project/intl-bundle 2.x.' - .' and will throw an exception since version 3.x.', + .' and will throw an exception in version 3.x.', IntlExtension::class, __CLASS__ )); @@ -107,6 +111,21 @@ public function formatPercent($number, array $attributes = [], array $textAttrib */ public function formatDuration($number, array $attributes = [], array $textAttributes = [], $locale = null) { + if ($this->intlExtension) { + $attributes = self::processLegacyAttributes($attributes); + + return $this->fixCharset($this->intlExtension->formatNumberStyle('duration', $number, $attributes, 'default', $locale ?: $this->localeDetector->getLocale())); + } + + // NEXT_MAJOR: Execute the previous block unconditionally and remove following lines in this method. + + @trigger_error(sprintf( + 'Not passing an instance of "%s" as argument 6 for %s::__construct() is deprecated since sonata-project/intl-bundle 2.x.' + .' and will throw an exception in version 3.x.', + IntlExtension::class, + __CLASS__ + )); + $methodArgs = array_pad(\func_get_args(), 5, null); [$locale, $symbols] = $this->normalizeMethodSignature($methodArgs[3], $methodArgs[4]); @@ -127,6 +146,21 @@ public function formatDuration($number, array $attributes = [], array $textAttri */ public function formatDecimal($number, array $attributes = [], array $textAttributes = [], $locale = null) { + if ($this->intlExtension) { + $attributes = self::processLegacyAttributes($attributes); + + return $this->fixCharset($this->intlExtension->formatNumberStyle('decimal', $number, $attributes, 'default', $locale ?: $this->localeDetector->getLocale())); + } + + // NEXT_MAJOR: Execute the previous block unconditionally and remove following lines in this method. + + @trigger_error(sprintf( + 'Not passing an instance of "%s" as argument 6 for %s::__construct() is deprecated since sonata-project/intl-bundle 2.x.' + .' and will throw an exception in version 3.x.', + IntlExtension::class, + __CLASS__ + )); + $methodArgs = array_pad(\func_get_args(), 5, null); [$locale, $symbols] = $this->normalizeMethodSignature($methodArgs[3], $methodArgs[4]); @@ -147,6 +181,21 @@ public function formatDecimal($number, array $attributes = [], array $textAttrib */ public function formatSpellout($number, array $attributes = [], array $textAttributes = [], $locale = null) { + if ($this->intlExtension) { + $attributes = self::processLegacyAttributes($attributes); + + return $this->fixCharset($this->intlExtension->formatNumberStyle('spellout', $number, $attributes, 'default', $locale ?: $this->localeDetector->getLocale())); + } + + // NEXT_MAJOR: Execute the previous block unconditionally and remove following lines in this method. + + @trigger_error(sprintf( + 'Not passing an instance of "%s" as argument 6 for %s::__construct() is deprecated since sonata-project/intl-bundle 2.x.' + .' and will throw an exception in version 3.x.', + IntlExtension::class, + __CLASS__ + )); + $methodArgs = array_pad(\func_get_args(), 5, null); [$locale, $symbols] = $this->normalizeMethodSignature($methodArgs[3], $methodArgs[4]); @@ -169,12 +218,16 @@ public function formatSpellout($number, array $attributes = [], array $textAttri public function formatCurrency($number, $currency, array $attributes = [], array $textAttributes = [], $locale = null) { if ($this->intlExtension) { + $attributes = self::processLegacyAttributes($attributes); + return $this->fixCharset($this->intlExtension->formatCurrency($number, $currency, $attributes, $locale ?: $this->localeDetector->getLocale())); } + // NEXT_MAJOR: Execute the previous block unconditionally and remove following lines in this method. + @trigger_error(sprintf( 'Not passing an instance of "%s" as argument 6 for %s::__construct() is deprecated since sonata-project/intl-bundle 2.x.' - .' and will throw an exception since version 3.x.', + .' and will throw an exception in version 3.x.', IntlExtension::class, __CLASS__ )); @@ -206,6 +259,21 @@ public function formatCurrency($number, $currency, array $attributes = [], array */ public function formatScientific($number, array $attributes = [], array $textAttributes = [], $locale = null) { + if ($this->intlExtension) { + $attributes = self::processLegacyAttributes($attributes); + + return $this->fixCharset($this->intlExtension->formatNumberStyle('scientific', $number, $attributes, 'default', $locale ?: $this->localeDetector->getLocale())); + } + + // NEXT_MAJOR: Execute the previous block unconditionally and remove following lines in this method. + + @trigger_error(sprintf( + 'Not passing an instance of "%s" as argument 6 for %s::__construct() is deprecated since sonata-project/intl-bundle 2.x.' + .' and will throw an exception in version 3.x.', + IntlExtension::class, + __CLASS__ + )); + $methodArgs = array_pad(\func_get_args(), 5, null); [$locale, $symbols] = $this->normalizeMethodSignature($methodArgs[3], $methodArgs[4]); @@ -226,6 +294,21 @@ public function formatScientific($number, array $attributes = [], array $textAtt */ public function formatOrdinal($number, array $attributes = [], array $textAttributes = [], $locale = null) { + if ($this->intlExtension) { + $attributes = self::processLegacyAttributes($attributes); + + return $this->fixCharset($this->intlExtension->formatNumberStyle('ordinal', $number, $attributes, 'default', $locale ?: $this->localeDetector->getLocale())); + } + + // NEXT_MAJOR: Execute the previous block unconditionally and remove following lines in this method. + + @trigger_error(sprintf( + 'Not passing an instance of "%s" as argument 6 for %s::__construct() is deprecated since sonata-project/intl-bundle 2.x.' + .' and will throw an exception in version 3.x.', + IntlExtension::class, + __CLASS__ + )); + $methodArgs = array_pad(\func_get_args(), 5, null); [$locale, $symbols] = $this->normalizeMethodSignature($methodArgs[3], $methodArgs[4]); @@ -247,6 +330,21 @@ public function formatOrdinal($number, array $attributes = [], array $textAttrib */ public function format($number, $style, array $attributes = [], array $textAttributes = [], $locale = null) { + if ($this->intlExtension) { + $attributes = self::processLegacyAttributes($attributes); + + return $this->fixCharset($this->intlExtension->formatNumber($number, $attributes, $style, 'default', $locale ?: $this->localeDetector->getLocale())); + } + + // NEXT_MAJOR: Execute the previous block unconditionally and remove following lines in this method. + + @trigger_error(sprintf( + 'Not passing an instance of "%s" as argument 6 for %s::__construct() is deprecated since sonata-project/intl-bundle 2.x.' + .' and will throw an exception in version 3.x.', + IntlExtension::class, + __CLASS__ + )); + $methodArgs = array_pad(\func_get_args(), 6, null); [$locale, $symbols] = $this->normalizeMethodSignature($methodArgs[4], $methodArgs[5]); @@ -257,10 +355,14 @@ public function format($number, $style, array $attributes = [], array $textAttri } /** + * NEXT_MAJOR: Remove this method. + * * Normalizes the given arguments according to the new function signature. * It asserts if neither the new nor old signature matches. This function * is public just to prevent code duplication inside the Twig Extension. * + * @deprecated since sonata-project/intl-bundle 2.x + * * @param mixed $symbols The symbols used by the formatter * @param mixed $locale The locale * @@ -272,6 +374,12 @@ public function format($number, $style, array $attributes = [], array $textAttri */ public function normalizeMethodSignature($symbols, $locale) { + @trigger_error(sprintf( + 'Method "%s()" is deprecated since sonata-project/intl-bundle 2.x.' + .' and will be removed in version 3.x.', + __METHOD__ + )); + $oldSignature = (null === $symbols || \is_string($symbols)) && null === $locale; $newSignature = \is_array($symbols) && (\is_string($locale) || null === $locale); @@ -298,9 +406,13 @@ public function getName() } /** + * NEXT_MAJOR: Remove this method. + * * Gets an instance of \NumberFormatter set with the given attributes and * style. * + * @deprecated since sonata-project/intl-bundle 2.x + * * @param string $culture The culture used by \NumberFormatter * @param string $style The style used by \NumberFormatter * @param array $attributes The attributes used by \NumberFormatter @@ -311,6 +423,12 @@ public function getName() */ protected function getFormatter($culture, $style, $attributes = [], $textAttributes = [], $symbols = []) { + @trigger_error(sprintf( + 'Method "%s()" is deprecated since sonata-project/intl-bundle 2.x.' + .' and will be removed in version 3.x.', + __METHOD__ + )); + $attributes = $this->parseAttributes(array_merge($this->attributes, $attributes)); $textAttributes = $this->parseAttributes(array_merge($this->textAttributes, $textAttributes)); $symbols = $this->parseAttributes(array_merge($this->symbols, $symbols)); @@ -337,8 +455,12 @@ protected function getFormatter($culture, $style, $attributes = [], $textAttribu } /** + * NEXT_MAJOR: Remove this method. + * * Converts keys of attributes array to values of \NumberFormatter constants. * + * @deprecated since sonata-project/intl-bundle 2.x + * * @param array $attributes The list of attributes * * @throws \InvalidArgumentException If any attribute does not match any constant @@ -347,6 +469,12 @@ protected function getFormatter($culture, $style, $attributes = [], $textAttribu */ protected function parseAttributes(array $attributes) { + @trigger_error(sprintf( + 'Method "%s()" is deprecated since sonata-project/intl-bundle 2.x.' + .' and will be removed in version 3.x.', + __METHOD__ + )); + $result = []; foreach ($attributes as $attribute => $value) { @@ -357,8 +485,12 @@ protected function parseAttributes(array $attributes) } /** + * NEXT_MAJOR: Remove this method. + * * Parse the given value trying to get a match with a \NumberFormatter constant. * + * @deprecated since sonata-project/intl-bundle 2.x + * * @param string $attribute The constant's name * * @throws \InvalidArgumentException If the value does not match any constant @@ -367,6 +499,12 @@ protected function parseAttributes(array $attributes) */ protected function parseConstantValue($attribute) { + @trigger_error(sprintf( + 'Method "%s()" is deprecated since sonata-project/intl-bundle 2.x.' + .' and will be removed in version 3.x.', + __METHOD__ + )); + $attribute = strtoupper($attribute); $constantName = 'NumberFormatter::'.$attribute; @@ -376,4 +514,19 @@ protected function parseConstantValue($attribute) return \constant($constantName); } + + /** + * NEXT_MAJOR: Remove this method. + * + * Replaces legacy attribute names with its new variants. + */ + private static function processLegacyAttributes(array $attributes): array + { + if (isset($attributes['fraction_digits'])) { + $curatedAttributes['fraction_digit'] = $attributes['fraction_digits']; + unset($attributes['fraction_digits']); + } + + return $attributes; + } } diff --git a/tests/Helper/NumberHelperTest.php b/tests/Helper/NumberHelperTest.php index ceafe94c..4f4a51be 100644 --- a/tests/Helper/NumberHelperTest.php +++ b/tests/Helper/NumberHelperTest.php @@ -73,7 +73,7 @@ public function testLocale(): void $this->assertSame('10,000th', $helper->formatOrdinal(10000), 'ICU Version: '.NumberHelper::getICUDataVersion()); } - public function testArguments() + public function testArguments(): void { $localeDetector = $this->createLocaleDetectorMock(); $helper = new NumberHelper('UTF-8', $localeDetector, ['fraction_digits' => 2], ['negative_prefix' => 'MINUS']); @@ -87,32 +87,18 @@ public function testArguments() $this->assertSame('MIN1.34', $helper->formatDecimal(-1.337, [], ['negative_prefix' => 'MIN'])); } - public function testExceptionOnInvalidParams() + public function testExceptionOnInvalidParams(): void { - $this->expectException(\RuntimeException::class); + $this->expectException(\IntlException::class); // https://wiki.php.net/rfc/internal_constructor_behaviour - try { - $formatter = new \NumberFormatter('EN', -1); - } catch (\IntlException $e) { - throw new \RuntimeException($e->getMessage()); - } - - $this->assertNull($formatter); - - $localeDetector = $this->createMock(LocaleDetectorInterface::class); - $localeDetector - ->method('getLocale')->willReturn('en'); - - $helper = new NumberHelper('UTF-8', $localeDetector, ['fraction_digits' => 2], ['negative_prefix' => 'MINUS']); - - $helper->format(10.49, -1); + $formatter = new \NumberFormatter('EN', -1); } /** * @dataProvider provideConstantValues */ - public function testParseConstantValue($constantName, $expectedConstant, $exceptionExpected) + public function testParseConstantValue(string $constantName, int $expectedConstant, bool $exceptionExpected): void { $localeDetector = $this->createLocaleDetectorMock(); $helper = new NumberHelper('UTF-8', $localeDetector); @@ -126,7 +112,7 @@ public function testParseConstantValue($constantName, $expectedConstant, $except $this->assertSame($expectedConstant, $method->invoke($helper, $constantName)); } - public function provideConstantValues() + public function provideConstantValues(): iterable { return [ ['positive_prefix', \NumberFormatter::POSITIVE_PREFIX, false], @@ -137,7 +123,7 @@ public function provideConstantValues() /** * @dataProvider provideAttributeValues */ - public function testParseAttributes($attributes, $expectedAttributes, $exceptionExpected) + public function testParseAttributes(array $attributes, array $expectedAttributes, bool $exceptionExpected): void { $localeDetector = $this->createLocaleDetectorMock(); $helper = new NumberHelper('UTF-8', $localeDetector); @@ -151,7 +137,7 @@ public function testParseAttributes($attributes, $expectedAttributes, $exception $this->assertSame($expectedAttributes, $method->invoke($helper, $attributes)); } - public function provideAttributeValues() + public function provideAttributeValues(): iterable { return [ [ @@ -178,7 +164,7 @@ public function provideAttributeValues() /** * @dataProvider provideFormatMethodArguments */ - public function testFormatMethodSignatures($arguments, $expectedArguments, $exceptionExpected) + public function testFormatMethodSignatures(array $arguments, array $expectedArguments, bool $exceptionExpected): void { $localeDetector = $this->createLocaleDetectorMock(); $helper = new NumberHelper('UTF-8', $localeDetector); @@ -190,7 +176,7 @@ public function testFormatMethodSignatures($arguments, $expectedArguments, $exce $this->assertSame($expectedArguments, \call_user_func_array([$helper, 'normalizeMethodSignature'], $arguments)); } - public function provideFormatMethodArguments() + public function provideFormatMethodArguments(): iterable { return [ [ @@ -221,7 +207,7 @@ public function provideFormatMethodArguments() ]; } - public function testFormatMethodWithDefaultArguments() + public function testFormatMethodWithDefaultArguments(): void { $localeDetector = $this->createLocaleDetectorMock(); $helper = new NumberHelper('UTF-8', $localeDetector); @@ -233,12 +219,12 @@ public function testFormatMethodWithDefaultArguments() $this->assertSame('10', $method->invoke($helper, 10, \NumberFormatter::DECIMAL, [], [], [])); } - private function createLocaleDetectorMock() + private function createLocaleDetectorMock(): LocaleDetectorInterface { - $localeDetector = $this->createMock(LocaleDetectorInterface::class); + $localeDetector = $this->createStub(LocaleDetectorInterface::class); $localeDetector - ->method('getLocale')->willReturn('en') - ; + ->method('getLocale') + ->willReturn('en'); return $localeDetector; }