Skip to content

[DX][Translation][3.0] Adding support for intl message formatter and decoupling default formatter #12060

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

use Symfony\Bridge\Twig\Extension\TranslationExtension;
use Symfony\Component\Translation\Translator;
use Symfony\Component\Translation\MessageSelector;
use Symfony\Component\Translation\Formatter\DefaultMessageFormatter;
use Symfony\Component\Translation\Loader\ArrayLoader;

class TranslationExtensionTest extends \PHPUnit_Framework_TestCase
Expand All @@ -34,7 +34,7 @@ public function testTrans($template, $expected, array $variables = array())
print $template."\n";
$loader = new \Twig_Loader_Array(array('index' => $template));
$twig = new \Twig_Environment($loader, array('debug' => true, 'cache' => false));
$twig->addExtension(new TranslationExtension(new Translator('en', new MessageSelector())));
$twig->addExtension(new TranslationExtension(new Translator('en', new DefaultMessageFormatter())));

echo $twig->compile($twig->parse($twig->tokenize($twig->getLoader()->getSource('index'), 'index')))."\n\n";
$this->assertEquals($expected, $this->getTemplate($template)->render($variables));
Expand Down Expand Up @@ -136,7 +136,7 @@ public function testDefaultTranslationDomain()
',
);

$translator = new Translator('en', new MessageSelector());
$translator = new Translator('en', new DefaultMessageFormatter());
$translator->addLoader('array', new ArrayLoader());
$translator->addResource('array', array('foo' => 'foo (messages)'), 'en');
$translator->addResource('array', array('foo' => 'foo (custom)'), 'en', 'custom');
Expand All @@ -150,7 +150,7 @@ public function testDefaultTranslationDomain()
protected function getTemplate($template, $translator = null)
{
if (null === $translator) {
$translator = new Translator('en', new MessageSelector());
$translator = new Translator('en', new DefaultMessageFormatter());
}

if (is_array($template)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -450,6 +450,7 @@ private function addTranslatorSection(ArrayNodeDefinition $rootNode)
->info('translator configuration')
->canBeEnabled()
->children()
->scalarNode('formatter')->defaultValue('default')->end()
->scalarNode('fallback')->defaultValue('en')->end()
->booleanNode('logging')->defaultValue($this->debug)->end()
->end()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -637,6 +637,9 @@ private function registerTranslatorConfiguration(array $config, ContainerBuilder

$container->setParameter('translator.logging', $config['logging']);

// Modify translator formatter
$container->setAlias('translator.formatter', 'translator.formatter.' . $config['formatter']);

// Discover translation directories
$dirs = array();
if (class_exists('Symfony\Component\Validator\Validator')) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@

<xsd:complexType name="translator">
<xsd:attribute name="enabled" type="xsd:boolean" />
<xsd:attribute name="formatter" type="xsd:string" />
<xsd:attribute name="fallback" type="xsd:string" />
</xsd:complexType>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@
<parameter key="translator.class">Symfony\Bundle\FrameworkBundle\Translation\Translator</parameter>
<parameter key="translator.logging.class">Symfony\Component\Translation\LoggingTranslator</parameter>
<parameter key="translator.identity.class">Symfony\Component\Translation\IdentityTranslator</parameter>
<parameter key="translator.selector.class">Symfony\Component\Translation\MessageSelector</parameter>
<parameter key="translator.formatter.intl.class">Symfony\Component\Translation\Formatter\IntlMessageFormatter</parameter>
<parameter key="translator.formatter.default.class">Symfony\Component\Translation\Formatter\DefaultMessageFormatter</parameter>
<parameter key="translator.selector.class">Symfony\Component\Translation\Formatter\MessageSelector</parameter>
<parameter key="translation.loader.php.class">Symfony\Component\Translation\Loader\PhpFileLoader</parameter>
<parameter key="translation.loader.yml.class">Symfony\Component\Translation\Loader\YamlFileLoader</parameter>
<parameter key="translation.loader.xliff.class">Symfony\Component\Translation\Loader\XliffFileLoader</parameter>
Expand Down Expand Up @@ -39,7 +41,7 @@
<services>
<service id="translator.default" class="%translator.class%">
<argument type="service" id="service_container" />
<argument type="service" id="translator.selector" />
<argument type="service" id="translator.formatter" />
<argument type="collection" /> <!-- translation loaders -->
<argument type="collection">
<argument key="cache_dir">%kernel.cache_dir%/translations</argument>
Expand All @@ -54,6 +56,14 @@
</service>

<service id="translator" class="%translator.identity.class%">
<argument type="service" id="translator.formatter" />
</service>

<service id="translator.formatter" alias="translator.formatter.default" />

<service id="translator.formatter.intl" class="%translator.formatter.intl.class%" public="false" />

<service id="translator.formatter.default" class="%translator.formatter.default.class%" public="false">
<argument type="service" id="translator.selector" />
</service>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,9 +121,10 @@ protected static function getBundleDefaultConfig()
'collect' => true,
),
'translator' => array(
'enabled' => false,
'fallback' => 'en',
'logging' => true,
'enabled' => false,
'formatter' => 'default',
'fallback' => 'en',
'logging' => true,
),
'validation' => array(
'enabled' => false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\Translation\MessageCatalogue;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\Translation\MessageSelector;
use Symfony\Component\Translation\Formatter\DefaultMessageFormatter;

class TranslatorTest extends \PHPUnit_Framework_TestCase
{
Expand Down Expand Up @@ -128,7 +128,7 @@ public function testGetLocale($inRequestScope)
->will($this->returnValue($requestStack))
;

$translator = new Translator($container, new MessageSelector());
$translator = new Translator($container, new DefaultMessageFormatter());

if ($inRequestScope) {
$this->assertSame('en', $translator->getLocale());
Expand Down Expand Up @@ -171,7 +171,7 @@ public function testGetLocaleWithInvalidLocale()
->will($this->returnValue($requestStack))
;

$translator = new Translator($container, new MessageSelector());
$translator = new Translator($container, new DefaultMessageFormatter());
$this->assertSame('en-US', $translator->getLocale());
}

Expand Down Expand Up @@ -259,7 +259,7 @@ public function getTranslator($loader, $options = array(), $translatorClass = '\
{
$translator = new $translatorClass(
$this->getContainer($loader),
new MessageSelector(),
new DefaultMessageFormatter(),
array('loader' => array('loader')),
$options
);
Expand Down
14 changes: 7 additions & 7 deletions src/Symfony/Bundle/FrameworkBundle/Translation/Translator.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
namespace Symfony\Bundle\FrameworkBundle\Translation;

use Symfony\Component\Translation\Translator as BaseTranslator;
use Symfony\Component\Translation\MessageSelector;
use Symfony\Component\Translation\Formatter\MessageFormatterInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
Expand All @@ -38,14 +38,14 @@ class Translator extends BaseTranslator
* * cache_dir: The cache directory (or null to disable caching)
* * 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 $loaderIds An array of loader Ids
* @param array $options An array of options
* @param ContainerInterface $container A ContainerInterface instance
* @param MessageFormatterInterface $selector The message formatter
* @param array $loaderIds An array of loader Ids
* @param array $options An array of options
*
* @throws \InvalidArgumentException
*/
public function __construct(ContainerInterface $container, MessageSelector $selector, $loaderIds = array(), array $options = array())
public function __construct(ContainerInterface $container, MessageFormatterInterface $formatter, $loaderIds = array(), array $options = array())
{
$this->container = $container;
$this->loaderIds = $loaderIds;
Expand All @@ -57,7 +57,7 @@ public function __construct(ContainerInterface $container, MessageSelector $sele

$this->options = array_merge($this->options, $options);

parent::__construct(null, $selector, $this->options['cache_dir'], $this->options['debug']);
parent::__construct(null, $formatter, $this->options['cache_dir'], $this->options['debug']);
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Symfony\Component\Translation\Formatter;

/**
* DefaultMessageFormatter.
*
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
*
* @api
*/
class DefaultMessageFormatter implements MessageFormatterInterface
{
/**
* @var MessageSelector
*/
protected $selector;

/**
* Constructor.
*
* @param MessageSelector $selector Message selector to choose pluralization messages.
*/
public function __construct(MessageSelector $selector = null)
{
$this->selector = $selector ?: new MessageSelector();
}

/**
* {@inheritdoc}
*
* @api
*/
public function format($locale, $id, $number = null, array $arguments = array())
{
$pattern = ($number !== null)
? $this->selector->choose($id, (int) $number, $locale)
: $id;

return strtr($pattern, $arguments);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/

namespace Symfony\Component\Translation;
namespace Symfony\Component\Translation\Formatter;

/**
* Tests if a given number belongs to a given math interval.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Symfony\Component\Translation\Formatter;

/**
* IntlMessageFormatter.
*
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
*
* @api
*/
class IntlMessageFormatter implements MessageFormatterInterface
{
/**
* {@inheritdoc}
*
* @api
*/
public function format($locale, $id, $number = null, array $arguments = array())
{
if ($number !== null) {
array_unshift($arguments, $number);
}

$formatter = new \MessageFormatter($locale, $id);

if ( ! $formatter) {
throw new \InvalidArgumentException(
sprintf(
'Invalid message format. Reason: %s (error #%d)',
$formatter->getErrorMessage(),
$formatter->getErrorCode()
)
);
}

$message = $formatter->format($arguments);

if ($formatter->getErrorCode() !== U_ZERO_ERROR) {
throw new \InvalidArgumentException(
sprintf(
'Unable to format message. Reason: %s (error #%s)',
$formatter->getErrorMessage(),
$formatter->getErrorCode()
)
);
}

return $message;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Symfony\Component\Translation\Formatter;

/**
* MessageFormatterInterface.
*
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
*
* @api
*/
interface MessageFormatterInterface
{
/**
* Formats a lozalized message pattern with given arguments.
*
* @param string $locale The message locale
* @param string $id The message id (may also be an object that can be cast to string)
* @param integer|null $number The number to use to find the indice of the message (if exists)
* @param array $arguments An array of parameters for the message
*
* @return string
*
* @throws \InvalidArgumentException
*
* @api
*/
public function format($locale, $id, $number = null, array $arguments = array());
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/

namespace Symfony\Component\Translation;
namespace Symfony\Component\Translation\Formatter;

/**
* MessageSelector.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/

namespace Symfony\Component\Translation;
namespace Symfony\Component\Translation\Formatter;

/**
* Returns the plural rules for a given locale.
Expand Down
Loading