+ */
+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