8000 [TwigBridge] fixed trans twig extractor by jfsimon · Pull Request #7206 · symfony/symfony · GitHub
[go: up one dir, main page]

Skip to content

[TwigBridge] fixed trans twig extractor #7206

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 8 commits into from
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,17 @@ public function enterNode(\Twig_NodeInterface $node, \Twig_Environment $env)
}

if ($node instanceof TransDefaultDomainNode) {
$var = $env->getParser()->getVarName();
$name = new \Twig_Node_Expression_AssignName($var, $node->getLine());
$this->domain = new \Twig_Node_Expression_Name($var, $node->getLine());
if ($node->getNode('expr') instanceof \Twig_Node_Expression_Constant) {
$this->domain = $node->getNode('expr');

return new \Twig_Node_Set(false, new \Twig_Node(array($name)), new \Twig_Node(array($node->getNode('expr'))), $node->getLine());
return $node;
} else {
$var = $env->getParser()->getVarName();
$name = new \Twig_Node_Expression_AssignName($var, $node->getLine());
$this->domain = new \Twig_Node_Expression_Name($var, $node->getLine());

return new \Twig_Node_Set(false, new \Twig_Node(array($name)), new \Twig_Node(array($node->getNode('expr'))), $node->getLine());
}
}

if (null === $this->domain) {
Expand Down Expand Up @@ -68,6 +74,10 @@ public function enterNode(\Twig_NodeInterface $node, \Twig_Environment $env)
*/
public function leaveNode(\Twig_NodeInterface $node, \Twig_Environment $env)
{
if ($node instanceof TransDefaultDomainNode) {
return false;
Copy link
Member

Choose a reason for hiding this comment

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

This is wrong. A visitor has to return a node, not a boolean

8000 Copy link
Member

Choose a reason for hiding this comment

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

Or false to remove the node ;)

Copy link
Member

Choose a reason for hiding this comment

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

then the phpdoc of the interface is wrong

}

return $node;
}

Expand All @@ -76,6 +86,6 @@ public function leaveNode(\Twig_NodeInterface $node, \Twig_Environment $env)
*/
public function getPriority()
{
return 0;
return -10;
}
}
47 changes: 43 additions & 4 deletions src/Symfony/Bridge/Twig/NodeVisitor/TranslationNodeVisitor.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
*/
class TranslationNodeVisitor implements \Twig_NodeVisitorInterface
{
const UNDEFINED_DOMAIN = '_undefined';

private $enabled = false;
private $messages = array();

Expand Down Expand Up @@ -57,7 +59,7 @@ public function enterNode(\Twig_NodeInterface $node, \Twig_Environment $env)
// extract constant nodes with a trans filter
$this->messages[] = array(
$node->getNode('node')->getAttribute('value'),
$node->getNode('arguments')->hasNode(1) ? $node->getNode('arguments')->getNode(1)->getAttribute('value') : null,
$this->getReadDomainFromArguments($node->getNode('arguments'), 1),
);
} elseif (
$node instanceof \Twig_Node_Expression_Filter &&
Expand All @@ -67,13 +69,13 @@ public function enterNode(\Twig_NodeInterface $node, \Twig_Environment $env)
// extract constant nodes with a trans filter
$this->messages[] = array(
$node->getNode('node')->getAttribute('value'),
$node->getNode('arguments')->hasNode(2) ? $node->getNode('arguments')->getNode(2)->getAttribute('value') : null,
$this->getReadDomainFromArguments($node->getNode('arguments'), 2),
);
8000 } elseif ($node instanceof TransNode) {
// extract trans nodes
$this->messages[] = array(
$node->getNode('body')->getAttribute('data'),
null === $node->getNode('domain') ? 'messages' : $node->getNode('domain')->getAttribute('value'),
$this->getReadDomainFromNode($node->getNode('domain')),
);
}

Expand All @@ -93,6 +95,43 @@ public function leaveNode(\Twig_NodeInterface $node, \Twig_Environment $env)
*/
public function getPriority()
{
return -10;
return 0;
}

/**
* @param \Twig_Node $arguments
* @param int $index
*
* @return string|null
*/
private function getReadDomainFromArguments(\Twig_Node $arguments, $index)
{
if ($arguments->hasNode('domain')) {
$argument = $arguments->getNode('domain');
} elseif ($arguments->hasNode($index)) {
$argument = $arguments->getNode($index);
} else {
return null;
}

return $this->getReadDomainFromNode($argument);
}

/**
* @param \Twig_Node $node
*
* @return string|null
*/
private function getReadDomainFromNode(\Twig_Node $node = null)
{
if (null === $node) {
return null;
}

if ($node instanceof \Twig_Node_Expression_Constant) {
return $node->getAttribute('value');
}

return self::UNDEFINED_DOMAIN;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<?php

namespace Symfony\Bridge\Twig\Tests\NodeVisitor;

use Symfony\Bridge\Twig\NodeVisitor\TranslationDefaultDomainNodeVisitor;
use Symfony\Bridge\Twig\NodeVisitor\TranslationNodeVisitor;
use Symfony\Bridge\Twig\Tests\TestCase;

class TranslationDefaultDomainNodeVisitorTest extends TestCase
{
private static $message = 'message';
private static $domain = 'domain';

/** @dataProvider getDefaultDomainAssignmentTestData */
public function testDefaultDomainAssignment(\Twig_Node $node)
{
$env = new \Twig_Environment(new \Twig_Loader_String(), array('cache' => false, 'autoescape' => false, 'optimizations' => 0));

$visitor = new TranslationDefaultDomainNodeVisitor();

// visit trans_default_domain tag
$defaultDomain = TwigNodeProvider::getTransDefaultDomainTag('domain');
$visitor->enterNode($defaultDomain, $env);
$visitor->leaveNode($defaultDomain, $env);

// visit tested node
$enteredNode = $visitor->enterNode($node, $env);
$leavedNode = $visitor->leaveNode($node, $env);
$this->assertSame($node, $enteredNode);
$this->assertSame($node, $leavedNode);

// extracting tested node messages
$visitor = new TranslationNodeVisitor();
$visitor->enable();
$visitor->enterNode($node, $env);
$visitor->leaveNode($node, $env);

$this->assertEquals(array(array(self::$message, self::$domain)), $visitor->getMessages());
}

public function getDefaultDomainAssignmentTestData()
{
return array(
array(TwigNodeProvider::getTransFilter(self::$message, self::$domain)),
array(TwigNodeProvider::getTransChoiceFilter(self::$message, self::$domain)),
array(TwigNodeProvider::getTransTag(self::$message, self::$domain)),
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<?php

namespace Symfony\Bridge\Twig\Tests\NodeVisitor;

use Symfony\Bridge\Twig\NodeVisitor\TranslationNodeVisitor;
use Symfony\Bridge\Twig\Tests\TestCase;

class TranslationNodeVisitorTest extends TestCase
{
/** @dataProvider getMessagesExtractionTestData */
public function testMessagesExtraction(\Twig_Node $node, array $expectedMessages)
{
$env = new \Twig_Environment(new \Twig_Loader_String(), array('cache' => false, 'autoescape' => false, 'optimizations' => 0));
$visitor = new TranslationNodeVisitor();
$visitor->enable();
$visitor->enterNode($node, $env);
$visitor->leaveNode($node, $env);
$this->assertEquals($expectedMessages, $visitor->getMessages());
}

public function testMessageExtractionWithInvalidDomainNode()
{
$message = 'new key';

$node = new \Twig_Node_Expression_Filter(
new \Twig_Node_Expression_Constant($message, 0),
new \Twig_Node_Expression_Constant('trans', 0),
new \Twig_Node(array(
new \Twig_Node_Expression_Array(array(), 0),
new \Twig_Node_Expression_Name('variable', 0),
)),
0
);

$this->testMessagesExtraction($node, array(array($message, TranslationNodeVisitor::UNDEFINED_DOMAIN)));
}

public function getMessagesExtractionTestData()
{
$message = 'new key';
$domain = 'domain';

return array(
array(TwigNodeProvider::getTransFilter($message), array(array($message, null))),
array(TwigNodeProvider::getTransChoiceFilter($message), array(array($message, null))),
array(TwigNodeProvider::getTransTag($message), array(array($message, null))),
array(TwigNodeProvider::getTransFilter($message, $domain), array(array($message, $domain))),
array(TwigNodeProvider::getTransChoiceFilter($message, $domain), array(array($message, $domain))),
array(TwigNodeProvider::getTransTag($message, $domain), array(array($message, $domain))),
);
}
}
55 changes: 55 additions & 0 deletions src/Symfony/Bridge/Twig/Tests/NodeVisitor/TwigNodeProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?php

namespace Symfony\Bridge\Twig\Tests\NodeVisitor;

use Symfony\Bridge\Twig\Node\TransDefaultDomainNode;
use Symfony\Bridge\Twig\Node\TransNode;

class TwigNodeProvider
{
public static function getTransFilter($message, $domain = null)
{
$arguments = $domain ? array(
new \Twig_Node_Expression_Array(array(), 0),
new \Twig_Node_Expression_Constant($domain, 0),
) : array();

return new \Twig_Node_Expression_Filter(
new \Twig_Node_Expression_Constant($message, 0),
new \Twig_Node_Expression_Constant('trans', 0),
new \Twig_Node($arguments),
0
);
}

public static function getTransChoiceFilter($message, $domain = null)
{
$arguments = $domain ? array(
new \Twig_Node_Expression_Constant(0, 0),
new \Twig_Node_Expression_Array(array(), 0),
new \Twig_Node_Expression_Constant($domain, 0),
) : array();

return new \Twig_Node_Expression_Filter(
new \Twig_Node_Expression_Constant($message, 0),
new \Twig_Node_Expression_Constant('transchoice', 0),
new \Twig_Node($arguments),
0
);
}

public static function getTransTag($message, $domain = null)
{
return new TransNode(
new \Twig_Node_Body(array(), array('data' => $message)),
$domain ? new \Twig_Node_Expression_Constant($domain, 0) : null
);
}

public static function getTransDefaultDomainTag($domain)
{
return new TransDefaultDomainNode(
new \Twig_Node_Expression_Constant($domain, 0)
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,15 @@ public function getExtractData()
array('{% trans from "domain" %}new key{% endtrans %}', array('new key' => 'domain')),
array('{% set foo = "new key" | trans %}', array('new key' => 'messages')),
array('{{ 1 ? "new key" | trans : "another key" | trans }}', array('new key' => 'messages', 'another key' => 'messages')),

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

// make sure this works with twig's named arguments
array('{{ "new key" | trans(domain="domain") }}', array('new key' => 'domain')),
array('{{ "new key" | transchoice(domain="domain", count=1) }}', array('new key' => 'domain')),
);
}
}
0