diff --git a/UPGRADE-3.4.md b/UPGRADE-3.4.md index 20114937efc26..9a3a74dd61655 100644 --- a/UPGRADE-3.4.md +++ b/UPGRADE-3.4.md @@ -234,6 +234,27 @@ Translation and will be removed in 4.0, use `Symfony\Component\Translation\Writer\TranslationWriter::write` instead. + * Passing a `Symfony\Component\Translation\MessageSelector` to `Translator` has been + deprecated. You should pass a message formatter instead + + Before: + + ```php + use Symfony\Component\Translation\Translator; + use Symfony\Component\Translation\MessageSelector; + + $translator = new Translator('fr_FR', new MessageSelector()); + ``` + + After: + + ```php + use Symfony\Component\Translation\Translator; + use Symfony\Component\Translation\Formatter\MessageFormatter; + + $translator = new Translator('fr_FR', new MessageFormatter()); + ``` + TwigBridge ---------- diff --git a/UPGRADE-4.0.md b/UPGRADE-4.0.md index 5d404598f7ec0..9dffe96789b90 100644 --- a/UPGRADE-4.0.md +++ b/UPGRADE-4.0.md @@ -643,6 +643,9 @@ Translation * Removed `Symfony\Component\Translation\Writer\TranslationWriter::writeTranslations`, use `Symfony\Component\Translation\Writer\TranslationWriter::write` instead. + * Removed support for passing `Symfony\Component\Translation\MessageSelector` as a second argument to the + `Translator::__construct()`. You should pass an instance of `Symfony\Component\Translation\Formatter\MessageFormatterInterface` instead. + TwigBundle ---------- diff --git a/src/Symfony/Bridge/Twig/Tests/Extension/TranslationExtensionTest.php b/src/Symfony/Bridge/Twig/Tests/Extension/TranslationExtensionTest.php index 36016d7f49bca..b20e0c3905a3a 100644 --- a/src/Symfony/Bridge/Twig/Tests/Extension/TranslationExtensionTest.php +++ b/src/Symfony/Bridge/Twig/Tests/Extension/TranslationExtensionTest.php @@ -14,7 +14,6 @@ use PHPUnit\Framework\TestCase; use Symfony\Bridge\Twig\Extension\TranslationExtension; use Symfony\Component\Translation\Translator; -use Symfony\Component\Translation\MessageSelector; use Symfony\Component\Translation\Loader\ArrayLoader; use Twig\Environment; use Twig\Loader\ArrayLoader as TwigArrayLoader; @@ -37,7 +36,7 @@ public function testTrans($template, $expected, array $variables = array()) echo $template."\n"; $loader = new TwigArrayLoader(array('index' => $template)); $twig = new Environment($loader, array('debug' => true, 'cache' => false)); - $twig->addExtension(new TranslationExtension(new Translator('en', new MessageSelector()))); + $twig->addExtension(new TranslationExtension(new Translator('en'))); echo $twig->compile($twig->parse($twig->tokenize($twig->getLoader()->getSourceContext('index'))))."\n\n"; $this->assertEquals($expected, $this->getTemplate($template)->render($variables)); @@ -139,7 +138,7 @@ public function testDefaultTranslationDomain() ', ); - $translator = new Translator('en', new MessageSelector()); + $translator = new Translator('en'); $translator->addLoader('array', new ArrayLoader()); $translator->addResource('array', array('foo' => 'foo (messages)'), 'en'); $translator->addResource('array', array('foo' => 'foo (custom)'), 'en', 'custom'); @@ -172,7 +171,7 @@ public function testDefaultTranslationDomainWithNamedArguments() ', ); - $translator = new Translator('en', new MessageSelector()); + $translator = new Translator('en'); $translator->addLoader('array', new ArrayLoader()); $translator->addResource('array', array('foo' => 'foo (messages)'), 'en'); $translator->addResource('array', array('foo' => 'foo (custom)'), 'en', 'custom'); @@ -187,7 +186,7 @@ public function testDefaultTranslationDomainWithNamedArguments() protected function getTemplate($template, $translator = null) { if (null === $translator) { - $translator = new Translator('en', new MessageSelector()); + $translator = new Translator('en'); } if (is_array($template)) { diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php index a9c5ec462dcd2..2fce9b2ad4aed 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php @@ -668,6 +668,7 @@ private function addTranslatorSection(ArrayNodeDefinition $rootNode) ->defaultValue(array('en')) ->end() ->booleanNode('logging')->defaultValue($this->debug)->end() + ->scalarNode('formatter')->defaultValue('translator.formatter.default')->end() ->arrayNode('paths') ->prototype('scalar')->end() ->end() diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php index 72d66442c62c9..9b3a071168a51 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php @@ -1075,6 +1075,7 @@ private function registerTranslatorConfiguration(array $config, ContainerBuilder // Use the "real" translator instead of the identity default $container->setAlias('translator', 'translator.default'); + $container->setAlias('translator.formatter', new Alias($config['formatter'], false)); $translator = $container->findDefinition('translator.default'); $translator->addMethodCall('setFallbackLocales', array($config['fallbacks'])); diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd b/src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd index 481c469e36164..f63f93723029d 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd @@ -184,6 +184,7 @@ + diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/translation.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/translation.xml index cfe05f5148fdd..d8c8f1e030111 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/translation.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/translation.xml @@ -9,7 +9,7 @@ - + %kernel.default_locale% @@ -28,6 +28,10 @@ + + + + diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php index 1835625da8611..e4e6f0f2a7bea 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php @@ -255,6 +255,7 @@ protected static function getBundleDefaultConfig() 'enabled' => !class_exists(FullStack::class), 'fallbacks' => array('en'), 'logging' => true, + 'formatter' => 'translator.formatter.default', 'paths' => array(), ), 'validation' => array( diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Translation/TranslatorTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Translation/TranslatorTest.php index 6d710a76e8819..d2d0f878f642f 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Translation/TranslatorTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Translation/TranslatorTest.php @@ -14,9 +14,9 @@ use PHPUnit\Framework\TestCase; use Psr\Container\ContainerInterface; use Symfony\Bundle\FrameworkBundle\Translation\Translator; +use Symfony\Component\Translation\Formatter\MessageFormatter; use Symfony\Component\Translation\MessageCatalogue; use Symfony\Component\Filesystem\Filesystem; -use Symfony\Component\Translation\MessageSelector; class TranslatorTest extends TestCase { @@ -149,7 +149,7 @@ public function testGetDefaultLocaleOmittingLocale() ->with('kernel.default_locale') ->will($this->returnValue('en')) ; - $translator = new Translator($container, new MessageSelector()); + $translator = new Translator($container, new MessageFormatter()); $this->assertSame('en', $translator->getLocale()); } @@ -162,7 +162,7 @@ public function testGetDefaultLocaleOmittingLocale() public function testGetDefaultLocaleOmittingLocaleWithPsrContainer() { $container = $this->getMockBuilder(ContainerInterface::class)->getMock(); - $translator = new Translator($container, new MessageSelector()); + $translator = new Translator($container, new MessageFormatter()); } /** @@ -277,7 +277,7 @@ public function testLoadResourcesWithoutCaching() public function testGetDefaultLocale() { $container = $this->getMockBuilder(ContainerInterface::class)->getMock(); - $translator = new Translator($container, new MessageSelector(), 'en'); + $translator = new Translator($container, new MessageFormatter(), 'en'); $this->assertSame('en', $translator->getLocale()); } @@ -290,7 +290,7 @@ public function testInvalidOptions() { $container = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerInterface')->getMock(); - (new Translator($container, new MessageSelector(), 'en', array(), array('foo' => 'bar'))); + (new Translator($container, new MessageFormatter(), 'en', array(), array('foo' => 'bar'))); } /** @dataProvider getDebugModeAndCacheDirCombinations */ @@ -468,7 +468,7 @@ private function createTranslator($loader, $options, $translatorClass = '\Symfon if (null === $defaultLocale) { return new $translatorClass( $this->getContainer($loader), - new MessageSelector(), + new MessageFormatter(), array($loaderFomat => array($loaderFomat)), $options ); @@ -476,7 +476,7 @@ private function createTranslator($loader, $options, $translatorClass = '\Symfon return new $translatorClass( $this->getContainer($loader), - new MessageSelector(), + new MessageFormatter(), $defaultLocale, array($loaderFomat => array($loaderFomat)), $options diff --git a/src/Symfony/Bundle/FrameworkBundle/Translation/Translator.php b/src/Symfony/Bundle/FrameworkBundle/Translation/Translator.php index d18a3b81f04ef..2b41d5af61dbd 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Translation/Translator.php +++ b/src/Symfony/Bundle/FrameworkBundle/Translation/Translator.php @@ -15,8 +15,8 @@ use Symfony\Component\DependencyInjection\ContainerInterface as SymfonyContainerInterface; use Symfony\Component\HttpKernel\CacheWarmer\WarmableInterface; use Symfony\Component\Translation\Translator as BaseTranslator; -use Symfony\Component\Translation\MessageSelector; use Symfony\Component\Translation\Exception\InvalidArgumentException; +use Symfony\Component\Translation\Formatter\MessageFormatterInterface; /** * Translator. @@ -56,15 +56,15 @@ class Translator extends BaseTranslator implements WarmableInterface * * debug: Whether to enable debugging or not (false by default) * * resource_files: List of translation resources available grouped by locale. * - * @param ContainerInterface $container A ContainerInterface instance - * @param MessageSelector $selector The message selector for pluralization - * @param string $defaultLocale - * @param array $loaderIds An array of loader Ids - * @param array $options An array of options + * @param ContainerInterface $container A ContainerInterface instance + * @param MessageFormatterInterface $formatter The message formatter + * @param string $defaultLocale + * @param array $loaderIds An array of loader Ids + * @param array $options An array of options * * @throws InvalidArgumentException */ - public function __construct(ContainerInterface $container, MessageSelector $selector, $defaultLocale = null, array $loaderIds = array(), array $options = array()) + public function __construct(ContainerInterface $container, $formatter, $defaultLocale = null, array $loaderIds = array(), array $options = array()) { // BC 3.x, to be removed in 4.0 along with the $defaultLocale default value if (is_array($defaultLocale) || 3 > func_num_args()) { @@ -90,7 +90,7 @@ public function __construct(ContainerInterface $container, MessageSelector $sele $this->resourceLocales = array_keys($this->options['resource_files']); $this->addResourceFiles($this->options['resource_files']); - parent::__construct($defaultLocale, $selector, $this->options['cache_dir'], $this->options['debug']); + parent::__construct($defaultLocale, $formatter, $this->options['cache_dir'], $this->options['debug']); } /** diff --git a/src/Symfony/Component/Translation/CHANGELOG.md b/src/Symfony/Component/Translation/CHANGELOG.md index cdd11cb91be6c..24753841cadb4 100644 --- a/src/Symfony/Component/Translation/CHANGELOG.md +++ b/src/Symfony/Component/Translation/CHANGELOG.md @@ -12,6 +12,7 @@ CHANGELOG * Improved Xliff 2.0 loader to load `` section. * Added `TranslationWriterInterface` * Deprecated `TranslationWriter::writeTranslations` in favor of `TranslationWriter::write` + * added support for adding custom message formatter and decoupling the default one. 3.2.0 ----- diff --git a/src/Symfony/Component/Translation/Formatter/ChoiceMessageFormatterInterface.php b/src/Symfony/Component/Translation/Formatter/ChoiceMessageFormatterInterface.php new file mode 100644 index 0000000000000..92acbcafe2032 --- /dev/null +++ b/src/Symfony/Component/Translation/Formatter/ChoiceMessageFormatterInterface.php @@ -0,0 +1,30 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Translation\Formatter; + +/** + * @author Abdellatif Ait boudad + */ +interface ChoiceMessageFormatterInterface +{ + /** + * Formats a localized message pattern with given arguments. + * + * @param string $message The message (may also be an object that can be cast to string) + * @param int $number The number to use to find the indice of the message + * @param string $locale The message locale + * @param array $parameters An array of parameters for the message + * + * @return string + */ + public function choiceFormat($message, $number, $locale, array $parameters = array()); +} diff --git a/src/Symfony/Component/Translation/Formatter/MessageFormatter.php b/src/Symfony/Component/Translation/Formatter/MessageFormatter.php new file mode 100644 index 0000000000000..e174be36c3a46 --- /dev/null +++ b/src/Symfony/Component/Translation/Formatter/MessageFormatter.php @@ -0,0 +1,48 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Translation\Formatter; + +use Symfony\Component\Translation\MessageSelector; + +/** + * @author Abdellatif Ait boudad + */ +class MessageFormatter implements MessageFormatterInterface, ChoiceMessageFormatterInterface +{ + private $selector; + + /** + * @param MessageSelector|null $selector The message selector for pluralization + */ + public function __construct(MessageSelector $selector = null) + { + $this->selector = $selector ?: new MessageSelector(); + } + + /** + * {@inheritdoc} + */ + public function format($message, $locale, array $parameters = array()) + { + return strtr($message, $parameters); + } + + /** + * {@inheritdoc} + */ + public function choiceFormat($message, $number, $locale, array $parameters = array()) + { + $parameters = array_merge(array('%count%' => $number), $parameters); + + return $this->format($this->selector->choose($message, (int) $number, $locale), $locale, $parameters); + } +} diff --git a/src/Symfony/Component/Translation/Formatter/MessageFormatterInterface.php b/src/Symfony/Component/Translation/Formatter/MessageFormatterInterface.php new file mode 100644 index 0000000000000..86937fb2f0853 --- /dev/null +++ b/src/Symfony/Component/Translation/Formatter/MessageFormatterInterface.php @@ -0,0 +1,30 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Translation\Formatter; + +/** + * @author Guilherme Blanco + * @author Abdellatif Ait boudad + */ +interface MessageFormatterInterface +{ + /** + * Formats a localized message pattern with given arguments. + * + * @param string $message The message (may also be an object that can be cast to string) + * @param string $locale The message locale + * @param array $parameters An array of parameters for the message + * + * @return string + */ + public function format($message, $locale, array $parameters = array()); +} diff --git a/src/Symfony/Component/Translation/Tests/Formatter/MessageFormatterTest.php b/src/Symfony/Component/Translation/Tests/Formatter/MessageFormatterTest.php new file mode 100644 index 0000000000000..1fa736e7e3df4 --- /dev/null +++ b/src/Symfony/Component/Translation/Tests/Formatter/MessageFormatterTest.php @@ -0,0 +1,82 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Translation\Tests\Formatter; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Translation\Formatter\MessageFormatter; + +class MessageFormatterTest extends TestCase +{ + /** + * @dataProvider getTransMessages + */ + public function testFormat($expected, $message, $parameters = array()) + { + $this->assertEquals($expected, $this->getMessageFormatter()->format($message, 'en', $parameters)); + } + + /** + * @dataProvider getTransChoiceMessages + */ + public function testFormatPlural($expected, $message, $number, $parameters) + { + $this->assertEquals($expected, $this->getMessageFormatter()->choiceFormat($message, $number, 'fr', $parameters)); + } + + public function getTransMessages() + { + return array( + array( + 'There is one apple', + 'There is one apple', + ), + array( + 'There are 5 apples', + 'There are %count% apples', + array('%count%' => 5), + ), + array( + 'There are 5 apples', + 'There are {{count}} apples', + array('{{count}}' => 5), + ), + ); + } + + public function getTransChoiceMessages() + { + return array( + array('Il y a 0 pomme', '[0,1] Il y a %count% pomme|]1,Inf] Il y a %count% pommes', 0, array('%count%' => 0)), + array('Il y a 1 pomme', '[0,1] Il y a %count% pomme|]1,Inf] Il y a %count% pommes', 1, array('%count%' => 1)), + array('Il y a 10 pommes', '[0,1] Il y a %count% pomme|]1,Inf] Il y a %count% pommes', 10, array('%count%' => 10)), + + array('Il y a 0 pomme', 'Il y a %count% pomme|Il y a %count% pommes', 0, array('%count%' => 0)), + array('Il y a 1 pomme', 'Il y a %count% pomme|Il y a %count% pommes', 1, array('%count%' => 1)), + array('Il y a 10 pommes', 'Il y a %count% pomme|Il y a %count% pommes', 10, array('%count%' => 10)), + + array('Il y a 0 pomme', 'one: Il y a %count% pomme|more: Il y a %count% pommes', 0, array('%count%' => 0)), + array('Il y a 1 pomme', 'one: Il y a %count% pomme|more: Il y a %count% pommes', 1, array('%count%' => 1)), + array('Il y a 10 pommes', 'one: Il y a %count% pomme|more: Il y a %count% pommes', 10, array('%count%' => 10)), + + array('Il n\'y a aucune pomme', '{0} Il n\'y a aucune pomme|one: Il y a %count% pomme|more: Il y a %count% pommes', 0, array('%count%' => 0)), + array('Il y a 1 pomme', '{0} Il n\'y a aucune pomme|one: Il y a %count% pomme|more: Il y a %count% pommes', 1, array('%count%' => 1)), + array('Il y a 10 pommes', '{0} Il n\'y a aucune pomme|one: Il y a %count% pomme|more: Il y a %count% pommes', 10, array('%count%' => 10)), + + array('Il y a 0 pomme', '[0,1] Il y a %count% pomme|]1,Inf] Il y a %count% pommes', 0, array('%count%' => 0)), + ); + } + + private function getMessageFormatter() + { + return new MessageFormatter(); + } +} diff --git a/src/Symfony/Component/Translation/Tests/TranslatorTest.php b/src/Symfony/Component/Translation/Tests/TranslatorTest.php index 2394fdb4320b1..d2c6fd51f453c 100644 --- a/src/Symfony/Component/Translation/Tests/TranslatorTest.php +++ b/src/Symfony/Component/Translation/Tests/TranslatorTest.php @@ -13,7 +13,6 @@ use PHPUnit\Framework\TestCase; use Symfony\Component\Translation\Translator; -use Symfony\Component\Translation\MessageSelector; use Symfony\Component\Translation\Loader\ArrayLoader; use Symfony\Component\Translation\MessageCatalogue; @@ -25,7 +24,7 @@ class TranslatorTest extends TestCase */ public function testConstructorInvalidLocale($locale) { - $translator = new Translator($locale, new MessageSelector()); + $translator = new Translator($locale); } /** @@ -33,14 +32,14 @@ public function testConstructorInvalidLocale($locale) */ public function testConstructorValidLocale($locale) { - $translator = new Translator($locale, new MessageSelector()); + $translator = new Translator($locale); $this->assertEquals($locale, $translator->getLocale()); } public function testConstructorWithoutLocale() { - $translator = new Translator(null, new MessageSelector()); + $translator = new Translator(null); $this->assertNull($translator->getLocale()); } @@ -61,7 +60,7 @@ public function testSetGetLocale() */ public function testSetInvalidLocale($locale) { - $translator = new Translator('fr', new MessageSelector()); + $translator = new Translator('fr'); $translator->setLocale($locale); } @@ -70,7 +69,7 @@ public function testSetInvalidLocale($locale) */ public function testSetValidLocale($locale) { - $translator = new Translator($locale, new MessageSelector()); + $translator = new Translator($locale); $translator->setLocale($locale); $this->assertEquals($locale, $translator->getLocale()); @@ -144,7 +143,7 @@ public function testSetFallbackLocalesMultiple() */ public function testSetFallbackInvalidLocales($locale) { - $translator = new Translator('fr', new MessageSelector()); + $translator = new Translator('fr'); $translator->setFallbackLocales(array('fr', $locale)); } @@ -153,7 +152,7 @@ public function testSetFallbackInvalidLocales($locale) */ public function testSetFallbackValidLocales($locale) { - $translator = new Translator($locale, new MessageSelector()); + $translator = new Translator($locale); $translator->setFallbackLocales(array('fr', $locale)); // no assertion. this method just asserts that no exception is thrown $this->addToAssertionCount(1); @@ -176,7 +175,7 @@ public function testTransWithFallbackLocale() */ public function testAddResourceInvalidLocales($locale) { - $translator = new Translator('fr', new MessageSelector()); + $translator = new Translator('fr'); $translator->addResource('array', array('foo' => 'foofoo'), $locale); } @@ -185,7 +184,7 @@ public function testAddResourceInvalidLocales($locale) */ public function testAddResourceValidLocales($locale) { - $translator = new Translator('fr', new MessageSelector()); + $translator = new Translator('fr'); $translator->addResource('array', array('foo' => 'foofoo'), $locale); // no assertion. this method just asserts that no exception is thrown $this->addToAssertionCount(1); @@ -288,7 +287,7 @@ public function testNestedFallbackCatalogueWhenUsingMultipleLocales() public function testFallbackCatalogueResources() { - $translator = new Translator('en_GB', new MessageSelector()); + $translator = new Translator('en_GB'); $translator->addLoader('yml', new \Symfony\Component\Translation\Loader\YamlFileLoader()); $translator->addResource('yml', __DIR__.'/fixtures/empty.yml', 'en_GB'); $translator->addResource('yml', __DIR__.'/fixtures/resources.yml', 'en'); @@ -324,7 +323,7 @@ public function testTrans($expected, $id, $translation, $parameters, $locale, $d */ public function testTransInvalidLocale($locale) { - $translator = new Translator('en', new MessageSelector()); + $translator = new Translator('en'); $translator->addLoader('array', new ArrayLoader()); $translator->addResource('array', array('foo' => 'foofoo'), 'en'); @@ -336,7 +335,7 @@ public function testTransInvalidLocale($locale) */ public function testTransValidLocale($locale) { - $translator = new Translator($locale, new MessageSelector()); + $translator = new Translator($locale); $translator->addLoader('array', new ArrayLoader()); $translator->addResource('array', array('test' => 'OK'), $locale); @@ -374,7 +373,7 @@ public function testTransChoice($expected, $id, $translation, $number, $paramete */ public function testTransChoiceInvalidLocale($locale) { - $translator = new Translator('en', new MessageSelector()); + $translator = new Translator('en'); $translator->addLoader('array', new ArrayLoader()); $translator->addResource('array', array('foo' => 'foofoo'), 'en'); @@ -386,7 +385,7 @@ public function testTransChoiceInvalidLocale($locale) */ public function testTransChoiceValidLocale($locale) { - $translator = new Translator('en', new MessageSelector()); + $translator = new Translator('en'); $translator->addLoader('array', new ArrayLoader()); $translator->addResource('array', array('foo' => 'foofoo'), 'en'); diff --git a/src/Symfony/Component/Translation/Translator.php b/src/Symfony/Component/Translation/Translator.php index 897aced2717b5..96553ec989986 100644 --- a/src/Symfony/Component/Translation/Translator.php +++ b/src/Symfony/Component/Translation/Translator.php @@ -14,10 +14,14 @@ use Symfony\Component\Translation\Loader\LoaderInterface; use Symfony\Component\Translation\Exception\NotFoundResourceException; use Symfony\Component\Translation\Exception\InvalidArgumentException; +use Symfony\Component\Translation\Exception\LogicException; use Symfony\Component\Translation\Exception\RuntimeException; use Symfony\Component\Config\ConfigCacheInterface; use Symfony\Component\Config\ConfigCacheFactoryInterface; use Symfony\Component\Config\ConfigCacheFactory; +use Symfony\Component\Translation\Formatter\MessageFormatterInterface; +use Symfony\Component\Translation\Formatter\ChoiceMessageFormatterInterface; +use Symfony\Component\Translation\Formatter\MessageFormatter; /** * Translator. @@ -52,9 +56,9 @@ class Translator implements TranslatorInterface, TranslatorBagInterface private $resources = array(); /** - * @var MessageSelector + * @var MessageFormatterInterface */ - private $selector; + private $formatter; /** * @var string @@ -74,17 +78,25 @@ class Translator implements TranslatorInterface, TranslatorBagInterface /** * Constructor. * - * @param string $locale The locale - * @param MessageSelector|null $selector The message selector for pluralization - * @param string|null $cacheDir The directory to use for the cache - * @param bool $debug Use cache in debug mode ? + * @param string $locale The locale + * @param MessageFormatterInterface|null $formatter The message formatter + * @param string|null $cacheDir The directory to use for the cache + * @param bool $debug Use cache in debug mode ? * * @throws InvalidArgumentException If a locale contains invalid characters */ - public function __construct($locale, MessageSelector $selector = null, $cacheDir = null, $debug = false) + public function __construct($locale, $formatter = null, $cacheDir = null, $debug = false) { $this->setLocale($locale); - $this->selector = $selector ?: new MessageSelector(); + + if ($formatter instanceof MessageSelector) { + $formatter = new MessageFormatter($formatter); + @trigger_error(sprintf('Passing a "%s" instance into the "%s" as a second argument is deprecated since version 3.4 and will be removed in 4.0. Inject a "%s" implementation instead.', MessageSelector::class, __METHOD__, MessageFormatterInterface::class), E_USER_DEPRECATED); + } elseif (null === $formatter) { + $formatter = new MessageFormatter(); + } + + $this->formatter = $formatter; $this->cacheDir = $cacheDir; $this->debug = $debug; } @@ -192,7 +204,7 @@ public function trans($id, array $parameters = array(), $domain = null, $locale $domain = 'messages'; } - return strtr($this->getCatalogue($locale)->get((string) $id, $domain), $parameters); + return $this->formatter->format($this->getCatalogue($locale)->get((string) $id, $domain), $locale, $parameters); } /** @@ -200,9 +212,9 @@ public function trans($id, array $parameters = array(), $domain = null, $locale */ public function transChoice($id, $number, array $parameters = array(), $domain = null, $locale = null) { - $parameters = array_merge(array( - '%count%' => $number, - ), $parameters); + if (!$this->formatter instanceof ChoiceMessageFormatterInterface) { + throw new LogicException(sprintf('The formatter "%s" does not support plural translations.', get_class($this->formatter))); + } if (null === $domain) { $domain = 'messages'; @@ -220,7 +232,7 @@ public function transChoice($id, $number, array $parameters = array(), $domain = } } - return strtr($this->selector->choose($catalogue->get($id, $domain), (int) $number, $locale), $parameters); + return $this->formatter->choiceFormat($catalogue->get($id, $domain), $number, $locale, $parameters); } /** pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy