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

Skip to content

Commit 23b0787

Browse files
committed
feature #28375 [Translator] Deprecated transChoice and moved it away from contracts (Nyholm, nicolas-grekas)
This PR was merged into the 4.2-dev branch. Discussion ---------- [Translator] Deprecated transChoice and moved it away from contracts | Q | A | ------------- | --- | Branch? | master | Bug fix? | no | New feature? | no | BC breaks? | no | Deprecations? | yes | Tests pass? | yes | Fixed tickets | n/a | License | MIT | Doc PR | Issue: symfony/symfony-docs#10264 This will address comment made here: #27399 (review) This PR moves the `transChoice()` method away from Contracts and back to the component. I also reverted changes in the `IdentityTranslator`. I will still use the deprecated `MessageSelector` but this is not fine since `transChoice()` is also deprecated. Commits ------- dc5f3bf Make trans + %count% parameter resolve plurals d870a85 [Translator] Deprecated transChoice and moved it away from contracts
2 parents e0cb452 + dc5f3bf commit 23b0787

39 files changed

+510
-125
lines changed

UPGRADE-4.2.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ FrameworkBundle
114114
set the "APP_ENV" environment variable instead.
115115
* The `--no-debug` console option has been deprecated,
116116
set the "APP_DEBUG" environment variable to "0" instead.
117+
* The `Templating\Helper\TranslatorHelper::transChoice()` method has been deprecated, use the `trans()` one instead with a `%count%` parameter.
117118

118119
Messenger
119120
---------
@@ -219,9 +220,15 @@ Translation
219220
-----------
220221

221222
* The `TranslatorInterface` has been deprecated in favor of `Symfony\Contracts\Translation\TranslatorInterface`
223+
* The `Translator::transChoice()` method has been deprecated in favor of using `Translator::trans()` with "%count%" as the parameter driving plurals
222224
* The `MessageSelector`, `Interval` and `PluralizationRules` classes have been deprecated, use `IdentityTranslator` instead
223225
* The `Translator::getFallbackLocales()` and `TranslationDataCollector::getFallbackLocales()` method have been marked as internal
224226

227+
TwigBundle
228+
----------
229+
230+
* The `transchoice` tag and filter have been deprecated, use the `trans` ones instead with a `%count%` parameter.
231+
225232
Validator
226233
---------
227234

UPGRADE-5.0.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ FrameworkBundle
120120
set the "APP_ENV" environment variable instead.
121121
* The `--no-debug` console option has been removed,
122122
set the "APP_DEBUG" environment variable to "0" instead.
123+
* The `Templating\Helper\TranslatorHelper::transChoice()` method has been removed, use the `trans()` one instead with a `%count%` parameter.
123124

124125
HttpFoundation
125126
--------------
@@ -196,11 +197,13 @@ Translation
196197
* The `TranslatorInterface` has been removed in favor of `Symfony\Contracts\Translation\TranslatorInterface`
197198
* The `MessageSelector`, `Interval` and `PluralizationRules` classes have been removed, use `IdentityTranslator` instead
198199
* The `Translator::getFallbackLocales()` and `TranslationDataCollector::getFallbackLocales()` method are now internal
200+
* The `Translator::transChoice()` method has been removed in favor of using `Translator::trans()` with "%count%" as the parameter driving plurals
199201

200202
TwigBundle
201203
----------
202204

203205
* The default value (`false`) of the `twig.strict_variables` configuration option has been changed to `%kernel.debug%`.
206+
* The `transchoice` tag and filter have been removed, use the `trans` ones instead with a `%count%` parameter.
204207

205208
Validator
206209
--------

src/Symfony/Bridge/Twig/CHANGELOG.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@ CHANGELOG
44
4.2.0
55
-----
66

7-
* add bundle name suggestion on wrongly overridden templates paths
8-
* added `name` argument in `debug:twig` command and changed `filter` argument as `--filter` option
7+
* add bundle name suggestion on wrongly overridden templates paths
8+
* added `name` argument in `debug:twig` command and changed `filter` argument as `--filter` option
9+
* deprecated the `transchoice` tag and filter, use the `trans` ones instead with a `%count%` parameter
910

1011
4.1.0
1112
-----

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

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
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\TranslatorInterface as LegacyTranslatorInterface;
1920
use Symfony\Contracts\Translation\TranslatorInterface;
2021
use Symfony\Contracts\Translation\TranslatorTrait;
2122
use Twig\Extension\AbstractExtension;
@@ -27,27 +28,39 @@
2728
* Provides integration of the Translation component with Twig.
2829
*
2930
* @author Fabien Potencier <[email protected]>
31+
*
32+
* @final since Symfony 4.2
3033
*/
3134
class TranslationExtension extends AbstractExtension
3235
{
3336
use TranslatorTrait {
3437
getLocale as private;
3538
setLocale as private;
3639
trans as private doTrans;
37-
transChoice as private doTransChoice;
3840
}
3941

4042
private $translator;
4143
private $translationNodeVisitor;
4244

43-
public function __construct(TranslatorInterface $translator = null, NodeVisitorInterface $translationNodeVisitor = null)
45+
/**
46+
* @param TranslatorInterface|null $translator
47+
*/
48+
public function __construct($translator = null, NodeVisitorInterface $translationNodeVisitor = null)
4449
{
50+
if (null !== $translator && !$translator instanceof LegacyTranslatorInterface && !$translator instanceof TranslatorInterface) {
51+
throw new \TypeError(sprintf('Argument 1 passed to %s() must be an instance of %s, %s given.', __METHOD__, TranslatorInterface::class, \is_object($translator) ? \get_class($translator) : \gettype($translator)));
52+
}
4553
$this->translator = $translator;
4654
$this->translationNodeVisitor = $translationNodeVisitor;
4755
}
4856

57+
/**
58+
* @deprecated since Symfony 4.2
59+
*/
4960
public function getTranslator()
5061
{
62+
@trigger_error(sprintf('The "%s()" method is deprecated since Symfony 4.2.', __METHOD__), E_USER_DEPRECATED);
63+
5164
return $this->translator;
5265
}
5366

@@ -58,7 +71,7 @@ public function getFilters()
5871
{
5972
return array(
6073
new TwigFilter('trans', array($this, 'trans')),
61-
new TwigFilter('transchoice', array($this, 'transchoice')),
74+
new TwigFilter('transchoice', array($this, 'transchoice'), array('deprecated' => '4.2', 'alternative' => 'trans" with parameter "%count%')),
6275
);
6376
}
6477

@@ -96,19 +109,28 @@ public function getTranslationNodeVisitor()
96109
return $this->translationNodeVisitor ?: $this->translationNodeVisitor = new TranslationNodeVisitor();
97110
}
98111

99-
public function trans($message, array $arguments = array(), $domain = null, $locale = null)
112+
public function trans($message, array $arguments = array(), $domain = null, $locale = null, $count = null)
100113
{
114+
if (null !== $count) {
115+
$arguments['%count%'] = $count;
116+
}
101117
if (null === $this->translator) {
102118
return $this->doTrans($message, $arguments, $domain, $locale);
103119
}
104120

105121
return $this->translator->trans($message, $arguments, $domain, $locale);
106122
}
107123

124+
/**
125+
* @deprecated since Symfony 4.2, use the trans() method instead with a %count% parameter
126+
*/
108127
public function transchoice($message, $count, array $arguments = array(), $domain = null, $locale = null)
109128
{
110129
if (null === $this->translator) {
111-
return $this->doTransChoice($message, $count, array_merge(array('%count%' => $count), $arguments), $domain, $locale);
130+
return $this->doTrans($message, array_merge(array('%count%' => $count), $arguments), $domain, $locale);
131+
}
132+
if ($this->translator instanceof TranslatorInterface) {
133+
return $this->translator->trans($message, array_merge(array('%count%' => $count), $arguments), $domain, $locale);
112134
}
113135

114136
return $this->translator->transChoice($message, $count, array_merge(array('%count%' => $count), $arguments), $domain, $locale);

src/Symfony/Bridge/Twig/Node/TransNode.php

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -60,19 +60,12 @@ public function compile(Compiler $compiler)
6060
$method = !$this->hasNode('count') ? 'trans' : 'transChoice';
6161

6262
$compiler
63-
->write('echo $this->env->getExtension(\'Symfony\Bridge\Twig\Extension\TranslationExtension\')->getTranslator()->'.$method.'(')
63+
->write('echo $this->env->getExtension(\'Symfony\Bridge\Twig\Extension\TranslationExtension\')->trans(')
6464
->subcompile($msg)
6565
;
6666

6767
$compiler->raw(', ');
6868

69-
if ($this->hasNode('count')) {
70-
$compiler
71-
->subcompile($this->getNode('count'))
72-
->raw(', ')
73-
;
74-
}
75-
7669
if (null !== $vars) {
7770
$compiler
7871
->raw('array_merge(')
@@ -98,7 +91,17 @@ public function compile(Compiler $compiler)
9891
->raw(', ')
9992
->subcompile($this->getNode('locale'))
10093
;
94+
} elseif ($this->hasNode('count')) {
95+
$compiler->raw(', null');
10196
}
97+
98+
if ($this->hasNode('count')) {
99+
$compiler
100+
->raw(', ')
101+
->subcompile($this->getNode('count'))
102+
;
103+
}
104+
102105
$compiler->raw(");\n");
103106
}
104107

src/Symfony/Bridge/Twig/Tests/Extension/TranslationExtensionTest.php

Lines changed: 79 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,15 @@ public function testTrans($template, $expected, array $variables = array())
4545
$this->assertEquals($expected, $this->getTemplate($template)->render($variables));
4646
}
4747

48+
/**
49+
* @group legacy
50+
* @dataProvider getTransChoiceTests
51+
*/
52+
public function testTransChoice($template, $expected, array $variables = array())
53+
{
54+
$this->testTrans($template, $expected, $variables);
55+
}
56+
4857
/**
4958
* @expectedException \Twig\Error\SyntaxError
5059
* @expectedExceptionMessage Unexpected token. Twig was looking for the "with", "from", or "into" keyword in "index" at line 3.
@@ -64,6 +73,7 @@ public function testTransComplexBody()
6473
}
6574

6675
/**
76+
* @group legacy
6777
* @expectedException \Twig\Error\SyntaxError
6878
* @expectedExceptionMessage A message inside a transchoice tag must be a simple text in "index" at line 2.
6979
*/
@@ -87,6 +97,69 @@ public function getTransTests()
8797

8898
array('{% trans into "fr"%}Hello{% endtrans %}', 'Hello'),
8999

100+
// trans with count
101+
array(
102+
'{% trans from "messages" %}{0} There is no apples|{1} There is one apple|]1,Inf] There is %count% apples{% endtrans %}',
103+
'There is no apples',
104+
array('count' => 0),
105+
),
106+
array(
107+
'{% trans %}{0} There is no apples|{1} There is one apple|]1,Inf] There is %count% apples{% endtrans %}',
108+
'There is 5 apples',
109+
array('count' => 5),
110+
),
111+
array(
112+
'{% trans %}{0} There is no apples|{1} There is one apple|]1,Inf] There is %count% apples (%name%){% endtrans %}',
113+
'There is 5 apples (Symfony)',
114+
array('count' => 5, 'name' => 'Symfony'),
115+
),
116+
array(
117+
'{% trans with { \'%name%\': \'Symfony\' } %}{0} There is no apples|{1} There is one apple|]1,Inf] There is %count% apples (%name%){% endtrans %}',
118+
'There is 5 apples (Symfony)',
119+
array('count' => 5),
120+
),
121+
array(
122+
'{% trans into "fr"%}{0} There is no apples|{1} There is one apple|]1,Inf] There is %count% apples{% endtrans %}',
123+
'There is no apples',
124+
array('count' => 0),
125+
),
126+
array(
127+
'{% trans count 5 into "fr"%}{0} There is no apples|{1} There is one apple|]1,Inf] There is %count% apples{% endtrans %}',
128+
'There is 5 apples',
129+
),
130+
131+
// trans filter
132+
array('{{ "Hello"|trans }}', 'Hello'),
133+
array('{{ name|trans }}', 'Symfony', array('name' => 'Symfony')),
134+
array('{{ hello|trans({ \'%name%\': \'Symfony\' }) }}', 'Hello Symfony', array('hello' => 'Hello %name%')),
135+
array('{% set vars = { \'%name%\': \'Symfony\' } %}{{ hello|trans(vars) }}', 'Hello Symfony', array('hello' => 'Hello %name%')),
136+
array('{{ "Hello"|trans({}, "messages", "fr") }}', 'Hello'),
137+
138+
// trans filter with count
139+
array('{{ "{0} There is no apples|{1} There is one apple|]1,Inf] There is %count% apples"|trans(count=count) }}', 'There is 5 apples', array('count' => 5)),
140+
array('{{ text|trans(count=5, arguments={\'%name%\': \'Symfony\'}) }}', 'There is 5 apples (Symfony)', array('text' => '{0} There is no apples|{1} There is one apple|]1,Inf] There is %count% apples (%name%)')),
141+
array('{{ "{0} There is no apples|{1} There is one apple|]1,Inf] There is %count% apples"|trans({}, "messages", "fr", count) }}', 'There is 5 apples', array('count' => 5)),
142+
);
143+
}
144+
145+
/**
146+
* @group legacy
147+
*/
148+
public function getTransChoiceTests()
149+
{
150+
return array(
151+
// trans tag
152+
array('{% trans %}Hello{% endtrans %}', 'Hello'),
153+
array('{% trans %}%name%{% endtrans %}', 'Symfony', array('name' => 'Symfony')),
154+
155+
array('{% trans from elsewhere %}Hello{% endtrans %}', 'Hello'),
156+
157+
array('{% trans %}Hello %name%{% endtrans %}', 'Hello Symfony', array('name' => 'Symfony')),
158+
array('{% trans with { \'%name%\': \'Symfony\' } %}Hello %name%{% endtrans %}', 'Hello Symfony'),
159+
array('{% set vars = { \'%name%\': \'Symfony\' } %}{% trans with vars %}Hello %name%{% endtrans %}', 'Hello Symfony'),
160+
161+
array('{% trans into "fr"%}Hello{% endtrans %}', 'Hello'),
162+
90163
// transchoice
91164
array(
92165
'{% transchoice count from "messages" %}{0} There is no apples|{1} There is one apple|]1,Inf] There is %count% apples{% endtranschoice %}',
@@ -145,8 +218,8 @@ public function testDefaultTranslationDomain()
145218
{%- trans from "custom" %}foo{% endtrans %}
146219
{{- "foo"|trans }}
147220
{{- "foo"|trans({}, "custom") }}
148-
{{- "foo"|transchoice(1) }}
149-
{{- "foo"|transchoice(1, {}, "custom") }}
221+
{{- "foo"|trans(count=1) }}
222+
{{- "foo"|trans({"%count%":1}, "custom") }}
150223
{% endblock %}
151224
',
152225

@@ -174,12 +247,12 @@ public function testDefaultTranslationDomainWithNamedArguments()
174247
175248
{%- block content %}
176249
{{- "foo"|trans(arguments = {}, domain = "custom") }}
177-
{{- "foo"|transchoice(count = 1) }}
178-
{{- "foo"|transchoice(count = 1, arguments = {}, domain = "custom") }}
250+
{{- "foo"|trans(count = 1) }}
251+
{{- "foo"|trans(count = 1, arguments = {}, domain = "custom") }}
179252
{{- "foo"|trans({}, domain = "custom") }}
180253
{{- "foo"|trans({}, "custom", locale = "fr") }}
181-
{{- "foo"|transchoice(1, arguments = {}, domain = "custom") }}
182-
{{- "foo"|transchoice(1, {}, "custom", locale = "fr") }}
254+
{{- "foo"|trans(arguments = {"%count%":1}, domain = "custom") }}
255+
{{- "foo"|trans({"%count%":1}, "custom", locale = "fr") }}
183256
{% endblock %}
184257
',
185258

src/Symfony/Bridge/Twig/Tests/Node/TransNodeTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ public function testCompileStrict()
3434

3535
$this->assertEquals(
3636
sprintf(
37-
'echo $this->env->getExtension(\'Symfony\Bridge\Twig\Extension\TranslationExtension\')->getTranslator()->trans("trans %%var%%", array_merge(array("%%var%%" => %s), %s), "messages");',
37+
'echo $this->env->getExtension(\'Symfony\Bridge\Twig\Extension\TranslationExtension\')->trans("trans %%var%%", array_merge(array("%%var%%" => %s), %s), "messages");',
3838
$this->getVariableGetterWithoutStrictCheck('var'),
3939
$this->getVariableGetterWithStrictCheck('foo')
4040
),

src/Symfony/Bridge/Twig/Tests/Translation/TwigExtractorTest.php

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,15 +50,21 @@ public function testExtract($template, $messages)
5050
}
5151
}
5252

53+
/**
54+
* @group legacy
55+
* @dataProvider getLegacyExtractData
56+
*/
57+
public function testLegacyExtract($template, $messages)
58+
{
59+
$this->testExtract($template, $messages);
60+
}
61+
5362
public function getExtractData()
5463
{
5564
return array(
5665
array('{{ "new key" | trans() }}', array('new key' => 'messages')),
5766
array('{{ "new key" | trans() | upper }}', array('new key' => 'messages')),
5867
array('{{ "new key" | trans({}, "domain") }}', array('new key' => 'domain')),
59-
array('{{ "new key" | transchoice(1) }}', array('new key' => 'messages')),
60-
array('{{ "new key" | transchoice(1) | upper }}', array('new key' => 'messages')),
61-
array('{{ "new key" | transchoice(1, {}, "domain") }}', array('new key' => 'domain')),
6268
array('{% trans %}new key{% endtrans %}', array('new key' => 'messages')),
6369
array('{% trans %} new key {% endtrans %}', array('new key' => 'messages')),
6470
array('{% trans from "domain" %}new key{% endtrans %}', array('new key' => 'domain')),
@@ -67,11 +73,27 @@ public function getExtractData()
6773

6874
// make sure 'trans_default_domain' tag is supported
6975
array('{% trans_default_domain "domain" %}{{ "new key"|trans }}', array('new key' => 'domain')),
70-
array('{% trans_default_domain "domain" %}{{ "new key"|transchoice }}', array('new key' => 'domain')),
7176
array('{% trans_default_domain "domain" %}{% trans %}new key{% endtrans %}', array('new key' => 'domain')),
7277

7378
// make sure this works with twig's named arguments
7479
array('{{ "new key" | trans(domain="domain") }}', array('new key' => 'domain')),
80+
);
81+
}
82+
83+
/**
84+
* @group legacy
85+
*/
86+
public function getLegacyExtractData()
87+
{
88+
return array(
89+
array('{{ "new key" | transchoice(1) }}', array('new key' => 'messages')),
90+
array('{{ "new key" | transchoice(1) | upper }}', array('new key' => 'messages')),
91+
array('{{ "new key" | transchoice(1, {}, "domain") }}', array('new key' => 'domain')),
92+
93+
// make sure 'trans_default_domain' tag is supported
94+
array('{% trans_default_domain "domain" %}{{ "new key"|transchoice }}', array('new key' => 'domain')),
95+
96+
// make sure this works with twig's named arguments
7597
array('{{ "new key" | transchoice(domain="domain", count=1) }}', array('new key' => 'domain')),
7698
);
7799
}

src/Symfony/Bridge/Twig/TokenParser/TransChoiceTokenParser.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
* Token Parser for the 'transchoice' tag.
2424
*
2525
* @author Fabien Potencier <[email protected]>
26+
*
27+
* @deprecated since Symfony 4.2, use the "trans" tag with a "%count%" parameter instead
2628
*/
2729
class TransChoiceTokenParser extends TransTokenParser
2830
{
@@ -38,6 +40,8 @@ public function parse(Token $token)
3840
$lineno = $token->getLine();
3941
$stream = $this->parser->getStream();
4042

43+
@trigger_error(sprintf('The "transchoice" tag is deprecated since Symfony 4.2, use the "trans" one instead with a "%count%" parameter in %s line %d.', $stream->getSourceContext()->getName(), $lineno), E_USER_DEPRECATED);
44+
4145
$vars = new ArrayExpression(array(), $lineno);
4246

4347
$count = $this->parser->getExpressionParser()->parseExpression();

0 commit comments

Comments
 (0)