diff options
Diffstat (limited to 'vendor/symfony/twig-bridge/Symfony/Bridge/Twig/NodeVisitor')
3 files changed, 378 insertions, 0 deletions
diff --git a/vendor/symfony/twig-bridge/Symfony/Bridge/Twig/NodeVisitor/Scope.php b/vendor/symfony/twig-bridge/Symfony/Bridge/Twig/NodeVisitor/Scope.php new file mode 100644 index 00000000..ce27b6a6 --- /dev/null +++ b/vendor/symfony/twig-bridge/Symfony/Bridge/Twig/NodeVisitor/Scope.php | |||
@@ -0,0 +1,135 @@ | |||
1 | <?php | ||
2 | |||
3 | /* | ||
4 | * This file is part of the Symfony package. | ||
5 | * | ||
6 | * (c) Fabien Potencier <fabien@symfony.com> | ||
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\Bridge\Twig\NodeVisitor; | ||
13 | |||
14 | /** | ||
15 | * @author Jean-François Simon <jeanfrancois.simon@sensiolabs.com> | ||
16 | */ | ||
17 | class Scope | ||
18 | { | ||
19 | /** | ||
20 | * @var Scope|null | ||
21 | */ | ||
22 | private $parent; | ||
23 | |||
24 | /** | ||
25 | * @var Scope[] | ||
26 | */ | ||
27 | private $children; | ||
28 | |||
29 | /** | ||
30 | * @var array | ||
31 | */ | ||
32 | private $data; | ||
33 | |||
34 | /** | ||
35 | * @var boolean | ||
36 | */ | ||
37 | private $left; | ||
38 | |||
39 | /** | ||
40 | * @param Scope $parent | ||
41 | */ | ||
42 | public function __construct(Scope $parent = null) | ||
43 | { | ||
44 | $this->parent = $parent; | ||
45 | $this->left = false; | ||
46 | $this->data = array(); | ||
47 | } | ||
48 | |||
49 | /** | ||
50 | * Opens a new child scope. | ||
51 | * | ||
52 | * @return Scope | ||
53 | */ | ||
54 | public function enter() | ||
55 | { | ||
56 | $child = new self($this); | ||
57 | $this->children[] = $child; | ||
58 | |||
59 | return $child; | ||
60 | } | ||
61 | |||
62 | /** | ||
63 | * Closes current scope and returns parent one. | ||
64 | * | ||
65 | * @return Scope|null | ||
66 | */ | ||
67 | public function leave() | ||
68 | { | ||
69 | $this->left = true; | ||
70 | |||
71 | return $this->parent; | ||
72 | } | ||
73 | |||
74 | /** | ||
75 | * Stores data into current scope. | ||
76 | * | ||
77 | * @param string $key | ||
78 | * @param mixed $value | ||
79 | * | ||
80 | * @throws \LogicException | ||
81 | * | ||
82 | * @return Scope Current scope | ||
83 | */ | ||
84 | public function set($key, $value) | ||
85 | { | ||
86 | if ($this->left) { | ||
87 | throw new \LogicException('Left scope is not mutable.'); | ||
88 | } | ||
89 | |||
90 | $this->data[$key] = $value; | ||
91 | |||
92 | return $this; | ||
93 | } | ||
94 | |||
95 | /** | ||
96 | * Tests if a data is visible from current scope. | ||
97 | * | ||
98 | * @param string $key | ||
99 | * | ||
100 | * @return boolean | ||
101 | */ | ||
102 | public function has($key) | ||
103 | { | ||
104 | if (array_key_exists($key, $this->data)) { | ||
105 | return true; | ||
106 | } | ||
107 | |||
108 | if (null === $this->parent) { | ||
109 | return false; | ||
110 | } | ||
111 | |||
112 | return $this->parent->has($key); | ||
113 | } | ||
114 | |||
115 | /** | ||
116 | * Returns data visible from current scope. | ||
117 | * | ||
118 | * @param string $key | ||
119 | * @param mixed $default | ||
120 | * | ||
121 | * @return mixed | ||
122 | */ | ||
123 | public function get($key, $default = null) | ||
124 | { | ||
125 | if (array_key_exists($key, $this->data)) { | ||
126 | return $this->data[$key]; | ||
127 | } | ||
128 | |||
129 | if (null === $this->parent) { | ||
130 | return $default; | ||
131 | } | ||
132 | |||
133 | return $this->parent->get($key, $default); | ||
134 | } | ||
135 | } | ||
diff --git a/vendor/symfony/twig-bridge/Symfony/Bridge/Twig/NodeVisitor/TranslationDefaultDomainNodeVisitor.php b/vendor/symfony/twig-bridge/Symfony/Bridge/Twig/NodeVisitor/TranslationDefaultDomainNodeVisitor.php new file mode 100644 index 00000000..8e7e7f48 --- /dev/null +++ b/vendor/symfony/twig-bridge/Symfony/Bridge/Twig/NodeVisitor/TranslationDefaultDomainNodeVisitor.php | |||
@@ -0,0 +1,106 @@ | |||
1 | <?php | ||
2 | |||
3 | /* | ||
4 | * This file is part of the Symfony package. | ||
5 | * | ||
6 | * (c) Fabien Potencier <fabien@symfony.com> | ||
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\Bridge\Twig\NodeVisitor; | ||
13 | |||
14 | use Symfony\Bridge\Twig\Node\TransNode; | ||
15 | use Symfony\Bridge\Twig\Node\TransDefaultDomainNode; | ||
16 | |||
17 | /** | ||
18 | * TranslationDefaultDomainNodeVisitor. | ||
19 | * | ||
20 | * @author Fabien Potencier <fabien@symfony.com> | ||
21 | */ | ||
22 | class TranslationDefaultDomainNodeVisitor implements \Twig_NodeVisitorInterface | ||
23 | { | ||
24 | /** | ||
25 | * @var Scope | ||
26 | */ | ||
27 | private $scope; | ||
28 | |||
29 | /** | ||
30 | * Constructor. | ||
31 | */ | ||
32 | public function __construct() | ||
33 | { | ||
34 | $this->scope = new Scope(); | ||
35 | } | ||
36 | |||
37 | /** | ||
38 | * {@inheritdoc} | ||
39 | */ | ||
40 | public function enterNode(\Twig_NodeInterface $node, \Twig_Environment $env) | ||
41 | { | ||
42 | if ($node instanceof \Twig_Node_Block || $node instanceof \Twig_Node_Module) { | ||
43 | $this->scope = $this->scope->enter(); | ||
44 | } | ||
45 | |||
46 | if ($node instanceof TransDefaultDomainNode) { | ||
47 | if ($node->getNode('expr') instanceof \Twig_Node_Expression_Constant) { | ||
48 | $this->scope->set('domain', $node->getNode('expr')); | ||
49 | |||
50 | return $node; | ||
51 | } else { | ||
52 | $var = $env->getParser()->getVarName(); | ||
53 | $name = new \Twig_Node_Expression_AssignName($var, $node->getLine()); | ||
54 | $this->scope->set('domain', new \Twig_Node_Expression_Name($var, $node->getLine())); | ||
55 | |||
56 | return new \Twig_Node_Set(false, new \Twig_Node(array($name)), new \Twig_Node(array($node->getNode('expr'))), $node->getLine()); | ||
57 | } | ||
58 | } | ||
59 | |||
60 | if (!$this->scope->has('domain')) { | ||
61 | return $node; | ||
62 | } | ||
63 | |||
64 | if ($node instanceof \Twig_Node_Expression_Filter && in_array($node->getNode('filter')->getAttribute('value'), array('trans', 'transchoice'))) { | ||
65 | $ind = 'trans' === $node->getNode('filter')->getAttribute('value') ? 1 : 2; | ||
66 | $arguments = $node->getNode('arguments'); | ||
67 | if (!$arguments->hasNode($ind)) { | ||
68 | if (!$arguments->hasNode($ind - 1)) { | ||
69 | $arguments->setNode($ind - 1, new \Twig_Node_Expression_Array(array(), $node->getLine())); | ||
70 | } | ||
71 | |||
72 | $arguments->setNode($ind, $this->scope->get('domain')); | ||
73 | } | ||
74 | } elseif ($node instanceof TransNode) { | ||
75 | if (null === $node->getNode('domain')) { | ||
76 | $node->setNode('domain', $this->scope->get('domain')); | ||
77 | } | ||
78 | } | ||
79 | |||
80 | return $node; | ||
81 | } | ||
82 | |||
83 | /** | ||
84 | * {@inheritdoc} | ||
85 | */ | ||
86 | public function leaveNode(\Twig_NodeInterface $node, \Twig_Environment $env) | ||
87 | { | ||
88 | if ($node instanceof TransDefaultDomainNode) { | ||
89 | return false; | ||
90 | } | ||
91 | |||
92 | if ($node instanceof \Twig_Node_Block || $node instanceof \Twig_Node_Module) { | ||
93 | $this->scope = $this->scope->leave(); | ||
94 | } | ||
95 | |||
96 | return $node; | ||
97 | } | ||
98 | |||
99 | /** | ||
100 | * {@inheritdoc} | ||
101 | */ | ||
102 | public function getPriority() | ||
103 | { | ||
104 | return -10; | ||
105 | } | ||
106 | } | ||
diff --git a/vendor/symfony/twig-bridge/Symfony/Bridge/Twig/NodeVisitor/TranslationNodeVisitor.php b/vendor/symfony/twig-bridge/Symfony/Bridge/Twig/NodeVisitor/TranslationNodeVisitor.php new file mode 100644 index 00000000..592c2506 --- /dev/null +++ b/vendor/symfony/twig-bridge/Symfony/Bridge/Twig/NodeVisitor/TranslationNodeVisitor.php | |||
@@ -0,0 +1,137 @@ | |||
1 | <?php | ||
2 | |||
3 | /* | ||
4 | * This file is part of the Symfony package. | ||
5 | * | ||
6 | * (c) Fabien Potencier <fabien@symfony.com> | ||
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\Bridge\Twig\NodeVisitor; | ||
13 | |||
14 | use Symfony\Bridge\Twig\Node\TransNode; | ||
15 | |||
16 | /** | ||
17 | * TranslationNodeVisitor extracts translation messages. | ||
18 | * | ||
19 | * @author Fabien Potencier <fabien@symfony.com> | ||
20 | */ | ||
21 | class TranslationNodeVisitor implements \Twig_NodeVisitorInterface | ||
22 | { | ||
23 | const UNDEFINED_DOMAIN = '_undefined'; | ||
24 | |||
25 | private $enabled = false; | ||
26 | private $messages = array(); | ||
27 | |||
28 | public function enable() | ||
29 | { | ||
30 | $this->enabled = true; | ||
31 | $this->messages = array(); | ||
32 | } | ||
33 | |||
34 | public function disable() | ||
35 | { | ||
36 | $this->enabled = false; | ||
37 | $this->messages = array(); | ||
38 | } | ||
39 | |||
40 | public function getMessages() | ||
41 | { | ||
42 | return $this->messages; | ||
43 | } | ||
44 | |||
45 | /** | ||
46 | * {@inheritdoc} | ||
47 | */ | ||
48 | public function enterNode(\Twig_NodeInterface $node, \Twig_Environment $env) | ||
49 | { | ||
50 | if (!$this->enabled) { | ||
51 | return $node; | ||
52 | } | ||
53 | |||
54 | if ( | ||
55 | $node instanceof \Twig_Node_Expression_Filter && | ||
56 | 'trans' === $node->getNode('filter')->getAttribute('value') && | ||
57 | $node->getNode('node') instanceof \Twig_Node_Expression_Constant | ||
58 | ) { | ||
59 | // extract constant nodes with a trans filter | ||
60 | $this->messages[] = array( | ||
61 | $node->getNode('node')->getAttribute('value'), | ||
62 | $this->getReadDomainFromArguments($node->getNode('arguments'), 1), | ||
63 | ); | ||
64 | } elseif ( | ||
65 | $node instanceof \Twig_Node_Expression_Filter && | ||
66 | 'transchoice' === $node->getNode('filter')->getAttribute('value') && | ||
67 | $node->getNode('node') instanceof \Twig_Node_Expression_Constant | ||
68 | ) { | ||
69 | // extract constant nodes with a trans filter | ||
70 | $this->messages[] = array( | ||
71 | $node->getNode('node')->getAttribute('value'), | ||
72 | $this->getReadDomainFromArguments($node->getNode('arguments'), 2), | ||
73 | ); | ||
74 | } elseif ($node instanceof TransNode) { | ||
75 | // extract trans nodes | ||
76 | $this->messages[] = array( | ||
77 | $node->getNode('body')->getAttribute('data'), | ||
78 | $this->getReadDomainFromNode($node->getNode('domain')), | ||
79 | ); | ||
80 | } | ||
81 | |||
82 | return $node; | ||
83 | } | ||
84 | |||
85 | /** | ||
86 | * {@inheritdoc} | ||
87 | */ | ||
88 | public function leaveNode(\Twig_NodeInterface $node, \Twig_Environment $env) | ||
89 | { | ||
90 | return $node; | ||
91 | } | ||
92 | |||
93 | /** | ||
94 | * {@inheritdoc} | ||
95 | */ | ||
96 | public function getPriority() | ||
97 | { | ||
98 | return 0; | ||
99 | } | ||
100 | |||
101 | /** | ||
102 | * @param \Twig_Node $arguments | ||
103 | * @param int $index | ||
104 | * | ||
105 | * @return string|null | ||
106 | */ | ||
107 | private function getReadDomainFromArguments(\Twig_Node $arguments, $index) | ||
108 | { | ||
109 | if ($arguments->hasNode('domain')) { | ||
110 | $argument = $arguments->getNode('domain'); | ||
111 | } elseif ($arguments->hasNode($index)) { | ||
112 | $argument = $arguments->getNode($index); | ||
113 | } else { | ||
114 | return null; | ||
115 | } | ||
116 | |||
117 | return $this->getReadDomainFromNode($argument); | ||
118 | } | ||
119 | |||
120 | /** | ||
121 | * @param \Twig_Node $node | ||
122 | * | ||
123 | * @return string|null | ||
124 | */ | ||
125 | private function getReadDomainFromNode(\Twig_Node $node = null) | ||
126 | { | ||
127 | if (null === $node) { | ||
128 | return null; | ||
129 | } | ||
130 | |||
131 | if ($node instanceof \Twig_Node_Expression_Constant) { | ||
132 | return $node->getAttribute('value'); | ||
133 | } | ||
134 | |||
135 | return self::UNDEFINED_DOMAIN; | ||
136 | } | ||
137 | } | ||