Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit d870a85

Browse files
Nyholmnicolas-grekas
authored andcommitted
[Translator] Deprecated transChoice and moved it away from contracts
1 parent 3e7b029 commit d870a85

22 files changed

+494
-566
lines changed

UPGRADE-4.2.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,7 @@ Translation
219219
-----------
220220

221221
* The `TranslatorInterface` has been deprecated in favor of `Symfony\Contracts\Translation\TranslatorInterface`
222+
* The `Translator::transChoice()` has been deprecated in favor of using `Translator::trans()` with intl message format
222223
* The `MessageSelector`, `Interval` and `PluralizationRules` classes have been deprecated, use `IdentityTranslator` instead
223224
* The `Translator::getFallbackLocales()` and `TranslationDataCollector::getFallbackLocales()` method have been marked as internal
224225

src/Symfony/Bridge/Twig/Extension/TranslationExtension.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
use Symfony\Bridge\Twig\TokenParser\TransChoiceTokenParser;
1717
use Symfony\Bridge\Twig\TokenParser\TransDefaultDomainTokenParser;
1818
use Symfony\Bridge\Twig\TokenParser\TransTokenParser;
19+
use Symfony\Component\Translation\LegacyTranslatorTrait;
20+
use Symfony\Component\Translation\TranslatorInterface as LegacyTranslatorInterface;
1921
use Symfony\Contracts\Translation\TranslatorInterface;
2022
use Symfony\Contracts\Translation\TranslatorTrait;
2123
use Twig\Extension\AbstractExtension;
@@ -34,6 +36,9 @@ class TranslationExtension extends AbstractExtension
3436
getLocale as private;
3537
setLocale as private;
3638
trans as private doTrans;
39+
}
40+
41+
use LegacyTranslatorTrait {
3742
transChoice as private doTransChoice;
3843
}
3944

@@ -107,7 +112,7 @@ public function trans($message, array $arguments = array(), $domain = null, $loc
107112

108113
public function transchoice($message, $count, array $arguments = array(), $domain = null, $locale = null)
109114
{
110-
if (null === $this->translator) {
115+
if (null === $this->translator || !$this->translator instanceof LegacyTranslatorInterface) {
111116
return $this->doTransChoice($message, $count, array_merge(array('%count%' => $count), $arguments), $domain, $locale);
112117
}
113118

src/Symfony/Bundle/FrameworkBundle/Templating/Helper/TranslatorHelper.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
namespace Symfony\Bundle\FrameworkBundle\Templating\Helper;
1313

1414
use Symfony\Component\Templating\Helper\Helper;
15+
use Symfony\Component\Translation\LegacyTranslatorTrait;
16+
use Symfony\Component\Translation\TranslatorInterface as LegacyTranslatorInterface;
1517
use Symfony\Contracts\Translation\TranslatorInterface;
1618
use Symfony\Contracts\Translation\TranslatorTrait;
1719

@@ -24,6 +26,9 @@ class TranslatorHelper extends Helper
2426
getLocale as private;
2527
setLocale as private;
2628
trans as private doTrans;
29+
}
30+
31+
use LegacyTranslatorTrait {
2732
transChoice as private doTransChoice;
2833
}
2934

@@ -51,7 +56,7 @@ public function trans($id, array $parameters = array(), $domain = 'messages', $l
5156
*/
5257
public function transChoice($id, $number, array $parameters = array(), $domain = 'messages', $locale = null)
5358
{
54-
if (null === $this->translator) {
59+
if (null === $this->translator || !$this->translator instanceof LegacyTranslatorInterface) {
5560
return $this->doTransChoice($id, $number, $parameters, $domain, $locale);
5661
}
5762

src/Symfony/Bundle/FrameworkBundle/Tests/Translation/TranslatorTest.php

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -52,14 +52,25 @@ public function testTransWithoutCaching()
5252
$this->assertEquals('foo (FR)', $translator->trans('foo'));
5353
$this->assertEquals('bar (EN)', $translator->trans('bar'));
5454
$this->assertEquals('foobar (ES)', $translator->trans('foobar'));
55-
$this->assertEquals('choice 0 (EN)', $translator->transChoice('choice', 0));
5655
$this->assertEquals('no translation', $translator->trans('no translation'));
5756
$this->assertEquals('foobarfoo (PT-PT)', $translator->trans('foobarfoo'));
58-
$this->assertEquals('other choice 1 (PT-BR)', $translator->transChoice('other choice', 1));
5957
$this->assertEquals('foobarbaz (fr.UTF-8)', $translator->trans('foobarbaz'));
6058
$this->assertEquals('foobarbax (sr@latin)', $translator->trans('foobarbax'));
6159
}
6260

61+
/**
62+
* @group legacy
63+
*/
64+
public function testTransChoiceWithoutCaching()
65+
{
66+
$translator = $this->getTranslator($this->getLoader());
67+
$translator->setLocale('fr');
68+
$translator->setFallbackLocales(array('en', 'es', 'pt-PT', 'pt_BR', 'fr.UTF-8', 'sr@latin'));
69+
70+
$this->assertEquals('choice 0 (EN)', $translator->transChoice('choice', 0));
71+
$this->assertEquals('other choice 1 (PT-BR)', $translator->transChoice('other choice', 1));
72+
}
73+
6374
public function testTransWithCaching()
6475
{
6576
// prime the cache
@@ -70,10 +81,8 @@ public function testTransWithCaching()
7081
$this->assertEquals('foo (FR)', $translator->trans('foo'));
7182
$this->assertEquals('bar (EN)', $translator->trans('bar'));
7283
$this->assertEquals('foobar (ES)', $translator->trans('foobar'));
73-
$this->assertEquals('choice 0 (EN)', $translator->transChoice('choice', 0));
7484
$this->assertEquals('no translation', $translator->trans('no translation'));
7585
$this->assertEquals('foobarfoo (PT-PT)', $translator->trans('foobarfoo'));
76-
$this->assertEquals('other choice 1 (PT-BR)', $translator->transChoice('other choice', 1));
7786
$this->assertEquals('foobarbaz (fr.UTF-8)', $translator->trans('foobarbaz'));
7887
$this->assertEquals('foobarbax (sr@latin)', $translator->trans('foobarbax'));
7988

@@ -88,14 +97,37 @@ public function testTransWithCaching()
8897
$this->assertEquals('foo (FR)', $translator->trans('foo'));
8998
$this->assertEquals('bar (EN)', $translator->trans('bar'));
9099
$this->assertEquals('foobar (ES)', $translator->trans('foobar'));
91-
$this->assertEquals('choice 0 (EN)', $translator->transChoice('choice', 0));
92100
$this->assertEquals('no translation', $translator->trans('no translation'));
93101
$this->assertEquals('foobarfoo (PT-PT)', $translator->trans('foobarfoo'));
94-
$this->assertEquals('other choice 1 (PT-BR)', $translator->transChoice('other choice', 1));
95102
$this->assertEquals('foobarbaz (fr.UTF-8)', $translator->trans('foobarbaz'));
96103
$this->assertEquals('foobarbax (sr@latin)', $translator->trans('foobarbax'));
97104
}
98105

106+
/**
107+
* @group legacy
108+
*/
109+
public function testTransChoiceWithCaching()
110+
{
111+
// prime the cache
112+
$translator = $this->getTranslator($this->getLoader(), array('cache_dir' => $this->tmpDir));
113+
$translator->setLocale('fr');
114+
$translator->setFallbackLocales(array('en', 'es', 'pt-PT', 'pt_BR', 'fr.UTF-8', 'sr@latin'));
115+
116+
$this->assertEquals('choice 0 (EN)', $translator->transChoice('choice', 0));
117+
$this->assertEquals('other choice 1 (PT-BR)', $translator->transChoice('other choice', 1));
118+
119+
// do it another time as the cache is primed now
120+
$loader = $this->getMockBuilder('Symfony\Component\Translation\Loader\LoaderInterface')->getMock();
121+
$loader->expects($this->never())->method('load');
122+
123+
$translator = $this->getTranslator($loader, array('cache_dir' => $this->tmpDir));
124+
$translator->setLocale('fr');
125+
$translator->setFallbackLocales(array('en', 'es', 'pt-PT', 'pt_BR', 'fr.UTF-8', 'sr@latin'));
126+
127+
$this->assertEquals('choice 0 (EN)', $translator->transChoice('choice', 0));
128+
$this->assertEquals('other choice 1 (PT-BR)', $translator->transChoice('other choice', 1));
129+
}
130+
99131
/**
100132
* @expectedException \InvalidArgumentException
101133
* @expectedExceptionMessage Invalid "invalid locale" locale.

src/Symfony/Component/Translation/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ CHANGELOG
55
-----
66

77
* Started using ICU parent locales as fallback locales.
8+
* deprecated `Translator::transChoice()` in favor of using `Translator::trans()` with intl message format
89
* deprecated `TranslatorInterface` in favor of `Symfony\Contracts\Translation\TranslatorInterface`
910
* deprecated `MessageSelector`, `Interval` and `PluralizationRules`; use `IdentityTranslator` instead
1011
* Added `IntlMessageFormatter` and `FallbackMessageFormatter`

src/Symfony/Component/Translation/DataCollectorTranslator.php

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@
2020
*/
2121
class DataCollectorTranslator implements LegacyTranslatorInterface, TranslatorBagInterface
2222
{
23+
use LegacyTranslatorTrait {
24+
transChoice as private doTransChoice;
25+
}
26+
2327
const MESSAGE_DEFINED = 0;
2428
const MESSAGE_MISSING = 1;
2529
const MESSAGE_EQUALS_FALLBACK = 2;
@@ -59,7 +63,12 @@ public function trans($id, array $parameters = array(), $domain = null, $locale
5963
*/
6064
public function transChoice($id, $number, array $parameters = array(), $domain = null, $locale = null)
6165
{
62-
$trans = $this->translator->transChoice($id, $number, $parameters, $domain, $locale);
66+
if ($this->translator instanceof LegacyTranslatorInterface) {
67+
$trans = $this->translator->transChoice($id, $number, $parameters, $domain, $locale);
68+
} else {
69+
$trans = $this->doTransChoice($id, $number, $parameters, $domain, $locale);
70+
}
71+
6372
$this->collectMessage($locale, $domain, $id, $trans, $parameters, $number);
6473

6574
return $trans;

src/Symfony/Component/Translation/IdentityTranslator.php

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@
2020
*/
2121
class IdentityTranslator implements TranslatorInterface
2222
{
23-
use TranslatorTrait {
23+
use TranslatorTrait;
24+
use LegacyTranslatorTrait {
2425
transChoice as private doTransChoice;
2526
}
2627

@@ -43,15 +44,11 @@ public function __construct(MessageSelector $selector = null)
4344
*/
4445
public function transChoice($id, $number, array $parameters = array(), $domain = null, $locale = null)
4546
{
47+
@trigger_error(sprintf('The "%s()" method is deprecated since Symfony 4.2, use the "trans()" method with intl formatted messages instead.', __METHOD__), E_USER_DEPRECATED);
4648
if ($this->selector) {
47-
return strtr($this->selector->choose((string) $id, (int) $number, $locale ?: $this->getLocale()), $parameters);
49+
return strtr($this->selector->choose((string) $id, $number, $locale ?: $this->getLocale()), $parameters);
4850
}
4951

5052
return $this->doTransChoice($id, $number, $parameters, $domain, $locale);
5153
}
52-
53-
private function getPluralizationRule(int $number, string $locale): int
54-
{
55-
return PluralizationRules::get($number, $locale, false);
56-
}
5754
}
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Translation;
13+
14+
use Symfony\Component\Translation\Exception\InvalidArgumentException;
15+
16+
/**
17+
* @author Tobias Nyholm <[email protected]>
18+
* @author Fabien Potencier <[email protected]>
19+
*
20+
* @deprecated since Symfony 4.2, use IdentityTranslator instead
21+
*/
22+
trait LegacyTranslatorTrait
23+
{
24+
/**
25+
* Implementation of Symfony\Component\Translation\TranslationInterface::transChoice
26+
* {@inheritdoc}
27+
*/
28+
public function transChoice($id, $number, array $parameters = array(), $domain = null, $locale = null)
29+
{
30+
@trigger_error(sprintf('The "%s()" method is deprecated since Symfony 4.2, use the "trans()" method with intl formatted messages instead.', __METHOD__), E_USER_DEPRECATED);
31+
32+
$id = (string) $id;
33+
$number = (float) $number;
34+
$locale = (string) $locale ?: $this->getLocale();
35+
36+
$parts = array();
37+
if (preg_match('/^\|++$/', $id)) {
38+
$parts = explode('|', $id);
39+
} elseif (preg_match_all('/(?:\|\||[^\|])++/', $id, $matches)) {
40+
$parts = $matches[0];
41+
}
42+
43+
$intervalRegexp = <<<'EOF'
44+
/^(?P<interval>
45+
({\s*
46+
(\-?\d+(\.\d+)?[\s*,\s*\-?\d+(\.\d+)?]*)
47+
\s*})
48+
49+
|
50+
51+
(?P<left_delimiter>[\[\]])
52+
\s*
53+
(?P<left>-Inf|\-?\d+(\.\d+)?)
54+
\s*,\s*
55+
(?P<right>\+?Inf|\-?\d+(\.\d+)?)
56+
\s*
57+
(?P<right_delimiter>[\[\]])
58+
)\s*(?P<message>.*?)$/xs
59+
EOF;
60+
61+
$standardRules = array();
62+
foreach ($parts as $part) {
63+
$part = trim(str_replace('||', '|', $part));
64+
65+
// try to match an explicit rule, then fallback to the standard ones
66+
if (preg_match($intervalRegexp, $part, $matches)) {
67+
if ($matches[2]) {
68+
foreach (explode(',', $matches[3]) as $n) {
69+
if ($number == $n) {
70+
return strtr($matches['message'], $parameters);
71+
}
72+
}
73+
} else {
74+
$leftNumber = '-Inf' === $matches['left'] ? -INF : (float) $matches['left'];
75+
$rightNumber = \is_numeric($matches['right']) ? (float) $matches['right'] : INF;
76+
77+
if (('[' === $matches['left_delimiter'] ? $number >= $leftNumber : $number > $leftNumber)
78+
&& (']' === $matches['right_delimiter'] ? $number <= $rightNumber : $number < $rightNumber)
79+
) {
80+
return strtr($matches['message'], $parameters);
81+
}
82+
}
83+
} elseif (preg_match('/^\w+\:\s*(.*?)$/', $part, $matches)) {
84+
$standardRules[] = $matches[1];
85+
} else {
86+
$standardRules[] = $part;
87+
}
88+
}
89+
90+
$position = PluralizationRules::get($number, $locale, false);
91+
92+
if (!isset($standardRules[$position])) {
93+
// when there's exactly one rule given, and that rule is a standard
94+
// rule, use this rule
95+
if (1 === \count($parts) && isset($standardRules[0])) {
96+
return strtr($standardRules[0], $parameters);
97+
}
98+
99+
$message = sprintf('Unable to choose a translation for "%s" with locale "%s" for value "%d". Double check that this translation has the correct plural options (e.g. "There is one apple|There are %%count%% apples").', $id, $locale, $number);
100+
101+
if (\class_exists(InvalidArgumentException::class)) {
102+
throw new InvalidArgumentException($message);
103+
}
104+
105+
throw new \InvalidArgumentException($message);
106+
}
107+
108+
return strtr($standardRules[$position], $parameters);
109+
}
110+
}

src/Symfony/Component/Translation/LoggingTranslator.php

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@
2121
*/
2222
class LoggingTranslator implements LegacyTranslatorInterface, TranslatorBagInterface
2323
{
24+
use LegacyTranslatorTrait {
25+
transChoice as private doTransChoice;
26+
}
27+
2428
/**
2529
* @var TranslatorInterface|TranslatorBagInterface
2630
*/
@@ -58,7 +62,12 @@ public function trans($id, array $parameters = array(), $domain = null, $locale
5862
*/
5963
public function transChoice($id, $number, array $parameters = array(), $domain = null, $locale = null)
6064
{
61-
$trans = $this->translator->transChoice($id, $number, $parameters, $domain, $locale);
65+
if ($this->translator instanceof LegacyTranslatorInterface) {
66+
$trans = $this->translator->transChoice($id, $number, $parameters, $domain, $locale);
67+
} else {
68+
$trans = $this->doTransChoice($id, $number, $parameters, $domain, $locale);
69+
}
70+
6271
$this->log($id, $domain, $locale);
6372

6473
return $trans;

src/Symfony/Component/Translation/MessageSelector.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,9 @@ class MessageSelector
4343
* The two methods can also be mixed:
4444
* {0} There are no apples|one: There is one apple|more: There are %count% apples
4545
*
46-
* @param string $message The message being translated
47-
* @param int $number The number of items represented for the message
48-
* @param string $locale The locale to use for choosing
46+
* @param string $message The message being translated
47+
* @param int|float $number The number of items represented for the message
48+
* @param string $locale The locale to use for choosing
4949
*
5050
* @return string
5151
*

0 commit comments

Comments
 (0)