Skip to content

[FrameworkBundle] fixed custom domain for translations in php templates #21359

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

Merged
merged 1 commit into from
Feb 3, 2017
Merged
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 @@ -31,3 +31,19 @@
10,
array('%count%' => 10)
) ?>

<?php echo $view['translator']->trans('other-domain-test-no-params-short-array', [], 'not_messages'); ?>

<?php echo $view['translator']->trans('other-domain-test-no-params-long-array', array(), 'not_messages'); ?>

<?php echo $view['translator']->trans('other-domain-test-params-short-array', ['foo' => 'bar'], 'not_messages'); ?>

<?php echo $view['translator']->trans('other-domain-test-params-long-array', array('foo' => 'bar'), 'not_messages'); ?>

<?php echo $view['translator']->transChoice('other-domain-test-trans-choice-short-array-%count%', 10, ['%count%' => 10], 'not_messages'); ?>

<?php echo $view['translator']->transChoice('other-domain-test-trans-choice-long-array-%count%', 10, array('%count%' => 10), 'not_messages'); ?>

<?php echo $view['translator']->trans('typecast', ['a' => (int) '123'], 'not_messages'); ?>
<?php echo $view['translator']->transChoice('msg1', 10 + 1, [], 'not_messages'); ?>
<?php echo $view['translator']->transChoice('msg2', intval(4.5), [], 'not_messages'); ?>
Original file line number Diff line number Diff line change
Expand Up @@ -39,18 +39,31 @@ public function testExtraction($resource)
nowdoc key with whitespace and nonescaped \$\n sequences
EOF;
// Assert
$expectedCatalogue = array('messages' => array(
'single-quoted key' => 'prefixsingle-quoted key',
'double-quoted key' => 'prefixdouble-quoted key',
'heredoc key' => 'prefixheredoc key',
'nowdoc key' => 'prefixnowdoc key',
"double-quoted key with whitespace and escaped \$\n\" sequences" => "prefixdouble-quoted key with whitespace and escaped \$\n\" sequences",
'single-quoted key with whitespace and nonescaped \$\n\' sequences' => 'prefixsingle-quoted key with whitespace and nonescaped \$\n\' sequences',
'single-quoted key with "quote mark at the end"' => 'prefixsingle-quoted key with "quote mark at the end"',
$expectedHeredoc => 'prefix'.$expectedHeredoc,
$expectedNowdoc => 'prefix'.$expectedNowdoc,
'{0} There is no apples|{1} There is one apple|]1,Inf[ There are %count% apples' => 'prefix{0} There is no apples|{1} There is one apple|]1,Inf[ There are %count% apples',
));
$expectedCatalogue = array(
'messages' => array(
'single-quoted key' => 'prefixsingle-quoted key',
'double-quoted key' => 'prefixdouble-quoted key',
'heredoc key' => 'prefixheredoc key',
'nowdoc key' => 'prefixnowdoc key',
"double-quoted key with whitespace and escaped \$\n\" sequences" => "prefixdouble-quoted key with whitespace and escaped \$\n\" sequences",
'single-quoted key with whitespace and nonescaped \$\n\' sequences' => 'prefixsingle-quoted key with whitespace and nonescaped \$\n\' sequences',
'single-quoted key with "quote mark at the end"' => 'prefixsingle-quoted key with "quote mark at the end"',
$expectedHeredoc => 'prefix'.$expectedHeredoc,
$expectedNowdoc => 'prefix'.$expectedNowdoc,
'{0} There is no apples|{1} There is one apple|]1,Inf[ There are %count% apples' => 'prefix{0} There is no apples|{1} There is one apple|]1,Inf[ There are %count% apples',
),
'not_messages' => array(
'other-domain-test-no-params-short-array' => 'prefixother-domain-test-no-params-short-array',
'other-domain-test-no-params-long-array' => 'prefixother-domain-test-no-params-long-array',
'other-domain-test-params-short-array' => 'prefixother-domain-test-params-short-array',
'other-domain-test-params-long-array' => 'prefixother-domain-test-params-long-array',
'other-domain-test-trans-choice-short-array-%count%' => 'prefixother-domain-test-trans-choice-short-array-%count%',
'other-domain-test-trans-choice-long-array-%count%' => 'prefixother-domain-test-trans-choice-long-array-%count%',
'typecast' => 'prefixtypecast',
'msg1' => 'prefixmsg1',
'msg2' => 'prefixmsg2',
),
);
$actualCatalogue = $catalogue->all();

$this->assertEquals($expectedCatalogue, $actualCatalogue);
Expand Down
67 changes: 61 additions & 6 deletions src/Symfony/Bundle/FrameworkBundle/Translation/PhpExtractor.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
class PhpExtractor extends AbstractFileExtractor implements ExtractorInterface
{
const MESSAGE_TOKEN = 300;
const METHOD_ARGUMENTS_TOKEN = 1000;
const DOMAIN_TOKEN = 1001;

/**
* Prefix for new found message.
Expand All @@ -38,6 +40,28 @@ class PhpExtractor extends AbstractFileExtractor implements ExtractorInterface
* @var array
*/
protected $sequences = array(
array(
'->',
'trans',
'(',
self::MESSAGE_TOKEN,
',',
self::METHOD_ARGUMENTS_TOKEN,
',',
self::DOMAIN_TOKEN,
),
array(
'->',
'transChoice',
'(',
self::MESSAGE_TOKEN,
',',
self::METHOD_ARGUMENTS_TOKEN,
',',
self::METHOD_ARGUMENTS_TOKEN,
',',
self::DOMAIN_TOKEN,
),
array(
'->',
'trans',
Expand Down Expand Up @@ -105,11 +129,32 @@ private function seekToNextRelevantToken(\Iterator $tokenIterator)
}
}

private function skipMethodArgument(\Iterator $tokenIterator)
{
$openBraces = 0;

for (; $tokenIterator->valid(); $tokenIterator->next()) {
$t = $tokenIterator->current();

if ('[' === $t[0] || '(' === $t[0]) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you should not take account of braces inside a string

->trans('msg', [ 'p' => '[ \'' ], 'not_messages')

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added this line to my tests too and it passes.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@aitboudad In your example, $t will be an array consisting of three elements where the value at index 0 is T_CONSTANT_ENCAPSED_STRING if I am not mistaken.

++$openBraces;
}

if (']' === $t[0] || ')' === $t[0]) {
--$openBraces;
}

if ((0 === $openBraces && ',' === $t[0]) || (-1 === $openBraces && ')' === $t[0])) {
break;
}
}
}

/**
* Extracts the message from the iterator while the tokens
* match allowed message tokens.
*/
private function getMessage(\Iterator $tokenIterator)
private function getValue(\Iterator $tokenIterator)
{
$message = '';
$docToken = '';
Expand Down Expand Up @@ -155,24 +200,34 @@ protected function parseTokens($tokens, MessageCatalogue $catalog)
for ($key = 0; $key < $tokenIterator->count(); ++$key) {
foreach ($this->sequences as $sequence) {
$message = '';
$domain = 'messages';
$tokenIterator->seek($key);

foreach ($sequence as $item) {
foreach ($sequence as $sequenceKey => $item) {
$this->seekToNextRelevantToken($tokenIterator);

if ($this->normalizeToken($tokenIterator->current()) == $item) {
if ($this->normalizeToken($tokenIterator->current()) === $item) {
$tokenIterator->next();
continue;
} elseif (self::MESSAGE_TOKEN == $item) {
$message = $this->getMessage($tokenIterator);
} elseif (self::MESSAGE_TOKEN === $item) {
$message = $this->getValue($tokenIterator);

if (count($sequence) === ($sequenceKey + 1)) {
break;
}
} elseif (self::METHOD_ARGUMENTS_TOKEN === $item) {
$this->skipMethodArgument($tokenIterator);
} elseif (self::DOMAIN_TOKEN === $item) {
$domain = $this->getValue($tokenIterator);

break;
} else {
break;
}
}

if ($message) {
$catalog->set($message, $this->prefix.$message);
$catalog->set($message, $this->prefix.$message, $domain);
break;
}
}
Expand Down