diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
index c6e99dea0b..d02fc13c6f 100644
--- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
+++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
@@ -100,9 +100,7 @@ class FrameworkExtension extends Extension
$this->registerUserConfiguration($config, $container);
}
- if (array_key_exists('translator', $config)) {
- $this->registerTranslatorConfiguration($config, $container);
- }
+ $this->registerTranslatorConfiguration($config, $container);
$this->addCompiledClasses($container, array(
'Symfony\\Component\\HttpFoundation\\ParameterBag',
@@ -234,40 +232,49 @@ class FrameworkExtension extends Extension
*/
protected function registerTranslatorConfiguration($config, ContainerBuilder $container)
{
- $config = $config['translator'];
+ $first = false;
+ if (!$container->hasDefinition('translator')) {
+ $first = true;
+ $loader = new XmlFileLoader($container, array(__DIR__.'/../Resources/config', __DIR__.'/Resources/config'));
+ $loader->load('translation.xml');
+ }
+
+ $config = array_key_exists('translator', $config) ? $config['translator'] : array();
if (!is_array($config)) {
$config = array();
}
- if (!$container->hasDefinition('translator')) {
- $loader = new XmlFileLoader($container, array(__DIR__.'/../Resources/config', __DIR__.'/Resources/config'));
- $loader->load('translation.xml');
+ if (!isset($config['translator']['enabled']) || $config['translator']['enabled']) {
+ // use the "real" translator
+ $container->setDefinition('translator', $container->findDefinition('translator.real'));
- // translation directories
- $dirs = array();
- foreach (array_reverse($container->getParameter('kernel.bundles')) as $bundle) {
- $reflection = new \ReflectionClass($bundle);
- if (is_dir($dir = dirname($reflection->getFilename()).'/Resources/translations')) {
+ if ($first) {
+ // translation directories
+ $dirs = array();
+ foreach (array_reverse($container->getParameter('kernel.bundles')) as $bundle) {
+ $reflection = new \ReflectionClass($bundle);
+ if (is_dir($dir = dirname($reflection->getFilename()).'/Resources/translations')) {
+ $dirs[] = $dir;
+ }
+ }
+ if (is_dir($dir = $container->getParameter('kernel.root_dir').'/translations')) {
$dirs[] = $dir;
}
- }
- if (is_dir($dir = $container->getParameter('kernel.root_dir').'/translations')) {
- $dirs[] = $dir;
- }
- // translation resources
- $resources = array();
- if ($dirs) {
- $finder = new Finder();
- $finder->files()->filter(function (\SplFileInfo $file) { return 2 === substr_count($file->getBasename(), '.'); })->in($dirs);
- foreach ($finder as $file) {
- // filename is domain.locale.format
- list($domain, $locale, $format) = explode('.', $file->getBasename());
+ // translation resources
+ $resources = array();
+ if ($dirs) {
+ $finder = new Finder();
+ $finder->files()->filter(function (\SplFileInfo $file) { return 2 === substr_count($file->getBasename(), '.'); })->in($dirs);
+ foreach ($finder as $file) {
+ // filename is domain.locale.format
+ list($domain, $locale, $format) = explode('.', $file->getBasename());
- $resources[] = array($format, (string) $file, $locale, $domain);
+ $resources[] = array($format, (string) $file, $locale, $domain);
+ }
}
+ $container->setParameter('translation.resources', $resources);
}
- $container->setParameter('translation.resources', $resources);
}
if (array_key_exists('fallback', $config)) {
diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/translation.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/translation.xml
index 2a914004c1..ed9021fc45 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/translation.xml
+++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/translation.xml
@@ -6,14 +6,17 @@
Symfony\Bundle\FrameworkBundle\Translation\Translator
+ Symfony\Component\Translation\IdentityTranslator
+ Symfony\Component\Translation\MessageSelector
Symfony\Component\Translation\Loader\PhpFileLoader
Symfony\Component\Translation\Loader\XliffFileLoader
en
-
+
+
%kernel.cache_dir%/translations
%kernel.debug%
@@ -22,6 +25,12 @@
%translator.fallback_locale%
+
+
+
+
+
+
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php
index b97a7f8074..e07ee431e2 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php
@@ -53,8 +53,9 @@ class FrameworkExtensionTest extends TestCase
'Symfony\\Framework' => __DIR__ . '/../../../Framework',
),
'kernel.bundles' => array(
- 'FrameworkBundle',
+ 'Symfony\\Bundle\\FrameworkBundle\\FrameworkBundle',
),
+ 'kernel.root_dir' => __DIR__,
'kernel.debug' => false,
'kernel.compiled_classes' => array(),
)));
diff --git a/src/Symfony/Bundle/FrameworkBundle/Translation/Translator.php b/src/Symfony/Bundle/FrameworkBundle/Translation/Translator.php
index acdbc33485..454ad26576 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Translation/Translator.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Translation/Translator.php
@@ -4,6 +4,7 @@ namespace Symfony\Bundle\FrameworkBundle\Translation;
use Symfony\Component\Translation\Translator as BaseTranslator;
use Symfony\Component\Translation\Loader\LoaderInterface;
+use Symfony\Component\Translation\MessageSelector;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\Session;
@@ -35,13 +36,14 @@ class Translator extends BaseTranslator
* * debug: Whether to enable debugging or not (false by default)
*
* @param ContainerInterface $container A ContainerInterface instance
+ * @param MessageSelector $selector The message selector for pluralization
* @param array $options An array of options
* @param Session $session A Session instance
*/
- public function __construct(ContainerInterface $container, array $options = array(), Session $session = null)
+ public function __construct(ContainerInterface $container, MessageSelector $selector, array $options = array(), Session $session = null)
{
if (null !== $session) {
- parent::__construct($session->getLocale());
+ parent::__construct($session->getLocale(), $selector);
}
$this->container = $container;
diff --git a/src/Symfony/Component/Translation/IdentityTranslator.php b/src/Symfony/Component/Translation/IdentityTranslator.php
new file mode 100644
index 0000000000..6dc41afc2c
--- /dev/null
+++ b/src/Symfony/Component/Translation/IdentityTranslator.php
@@ -0,0 +1,55 @@
+
+ *
+ * This source file is subject to the MIT license that is bundled
+ * with this source code in the file LICENSE.
+ */
+
+/**
+ * IdentityTranslator does not translate anything.
+ *
+ * @author Fabien Potencier
+ */
+class IdentityTranslator implements TranslatorInterface
+{
+ protected $selector;
+
+ /**
+ * Constructor.
+ *
+ * @param MessageSelector $selector The message selector for pluralization
+ */
+ public function __construct(MessageSelector $selector)
+ {
+ $this->selector = $selector;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setLocale($locale)
+ {
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function trans($id, array $parameters = array(), $domain = 'messages', $locale = null)
+ {
+ return strtr($id, $parameters);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function transChoice($id, $number, array $parameters = array(), $domain = 'messages', $locale = null)
+ {
+ return strtr($this->selector->choose($id, (int) $number, $locale), $parameters);
+ }
+}
diff --git a/src/Symfony/Component/Translation/MessageSelector.php b/src/Symfony/Component/Translation/MessageSelector.php
new file mode 100644
index 0000000000..f5cc34ae26
--- /dev/null
+++ b/src/Symfony/Component/Translation/MessageSelector.php
@@ -0,0 +1,52 @@
+
+ *
+ * This source file is subject to the MIT license that is bundled
+ * with this source code in the file LICENSE.
+ */
+
+/**
+ * MessageSelector.
+ *
+ * @author Fabien Potencier
+ */
+class MessageSelector
+{
+ public function choose($message, $number, $locale)
+ {
+ $parts = explode('|', $message);
+ $explicitRules = array();
+ $standardRules = array();
+ foreach ($parts as $part) {
+ $part = trim($part);
+
+ if (preg_match('/^(?'.Range::getRangeRegexp().')\s+(?.+?)$/x', $part, $matches)) {
+ $explicitRules[$matches['range']] = $matches['message'];
+ } elseif (preg_match('/^\w+\: +(.+)$/', $part, $matches)) {
+ $standardRules[] = $matches[1];
+ } else {
+ $standardRules[] = $part;
+ }
+ }
+
+ // try to match an explicit rule, then fallback to the standard ones
+ foreach ($explicitRules as $range => $m) {
+ if (Range::test($number, $range)) {
+ return $m;
+ }
+ }
+
+ $position = PluralizationRules::get($number, $locale);
+ if (!isset($standardRules[$position])) {
+ throw new \InvalidArgumentException('Unable to choose a translation.');
+ }
+
+ return $standardRules[$position];
+ }
+}
diff --git a/src/Symfony/Component/Translation/Translator.php b/src/Symfony/Component/Translation/Translator.php
index 583a949d67..b85a332ef8 100644
--- a/src/Symfony/Component/Translation/Translator.php
+++ b/src/Symfony/Component/Translation/Translator.php
@@ -25,15 +25,18 @@ class Translator implements TranslatorInterface
protected $fallbackLocale;
protected $loaders;
protected $resources;
+ protected $selector;
/**
* Constructor.
*
- * @param string $locale The locale
+ * @param string $locale The locale
+ * @param MessageSelector $selector The message selector for pluralization
*/
- public function __construct($locale = null)
+ public function __construct($locale = null, MessageSelector $selector)
{
$this->locale = $locale;
+ $this->selector = $selector;
$this->loaders = array();
$this->resources = array();
$this->catalogues = array();
@@ -119,39 +122,7 @@ class Translator implements TranslatorInterface
$this->loadCatalogue($locale);
}
- return strtr($this->chooseMessage($this->catalogues[$locale]->getMessage($id, $domain), (int) $number, $locale), $parameters);
- }
-
- protected function chooseMessage($message, $number, $locale)
- {
- $parts = explode('|', $message);
- $explicitRules = array();
- $standardRules = array();
- foreach ($parts as $part) {
- $part = trim($part);
-
- if (preg_match('/^(?'.Range::getRangeRegexp().')\s+(?.+?)$/x', $part, $matches)) {
- $explicitRules[$matches['range']] = $matches['message'];
- } elseif (preg_match('/^\w+\: +(.+)$/', $part, $matches)) {
- $standardRules[] = $matches[1];
- } else {
- $standardRules[] = $part;
- }
- }
-
- // try to match an explicit rule, then fallback to the standard ones
- foreach ($explicitRules as $range => $m) {
- if (Range::test($number, $range)) {
- return $m;
- }
- }
-
- $position = PluralizationRules::get($number, $locale);
- if (!isset($standardRules[$position])) {
- throw new \InvalidArgumentException('Unable to choose a translation.');
- }
-
- return $standardRules[$position];
+ return strtr($this->selector->choose($this->catalogues[$locale]->getMessage($id, $domain), (int) $number, $locale), $parameters);
}
protected function loadCatalogue($locale)
diff --git a/tests/Symfony/Tests/Component/Translation/TranslatorTest.php b/tests/Symfony/Tests/Component/Translation/TranslatorTest.php
index 185626085e..950da78647 100644
--- a/tests/Symfony/Tests/Component/Translation/TranslatorTest.php
+++ b/tests/Symfony/Tests/Component/Translation/TranslatorTest.php
@@ -12,6 +12,7 @@
namespace Symfony\Tests\Component\Translation;
use Symfony\Component\Translation\Translator;
+use Symfony\Component\Translation\MessageSelector;
use Symfony\Component\Translation\Loader\ArrayLoader;
class TranslatorTest extends \PHPUnit_Framework_TestCase
@@ -21,7 +22,7 @@ class TranslatorTest extends \PHPUnit_Framework_TestCase
*/
public function testTrans($expected, $id, $translation, $parameters, $locale, $domain)
{
- $translator = new Translator();
+ $translator = new Translator('en', new MessageSelector());
$translator->addLoader('array', new ArrayLoader());
$translator->addResource('array', array($id => $translation), $locale, $domain);
@@ -33,7 +34,7 @@ class TranslatorTest extends \PHPUnit_Framework_TestCase
*/
public function testTransChoice($expected, $id, $translation, $number, $parameters, $locale, $domain)
{
- $translator = new Translator();
+ $translator = new Translator('en', new MessageSelector());
$translator->addLoader('array', new ArrayLoader());
$translator->addResource('array', array($id => $translation), $locale, $domain);