1<?php
2
3/*
4 * This file is part of Twig.
5 *
6 * (c) 2010 Fabien Potencier
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/**
13 * Represents a trans node.
14 *
15 * @author Fabien Potencier <fabien.potencier@symfony-project.com>
16 */
17class Twig_Extensions_Node_Trans extends Twig_Node
18{
19    public function __construct(Twig_Node $body, Twig_Node $plural = null, Twig_Node_Expression $count = null, Twig_Node $notes = null, $lineno, $tag = null)
20    {
21        $nodes = array('body' => $body);
22        if (null !== $count) {
23            $nodes['count'] = $count;
24        }
25        if (null !== $plural) {
26            $nodes['plural'] = $plural;
27        }
28        if (null !== $notes) {
29            $nodes['notes'] = $notes;
30        }
31
32        parent::__construct($nodes, array(), $lineno, $tag);
33    }
34
35    /**
36     * {@inheritdoc}
37     */
38    public function compile(Twig_Compiler $compiler)
39    {
40        $compiler->addDebugInfo($this);
41
42        list($msg, $vars) = $this->compileString($this->getNode('body'));
43
44        if ($this->hasNode('plural')) {
45            list($msg1, $vars1) = $this->compileString($this->getNode('plural'));
46
47            $vars = array_merge($vars, $vars1);
48        }
49
50        $function = $this->getTransFunction($this->hasNode('plural'));
51
52        if ($this->hasNode('notes')) {
53            $message = trim($this->getNode('notes')->getAttribute('data'));
54
55            // line breaks are not allowed cause we want a single line comment
56            $message = str_replace(array("\n", "\r"), ' ', $message);
57            $compiler->write("// notes: {$message}\n");
58        }
59
60        if ($vars) {
61            $compiler
62                ->write('echo strtr('.$function.'(')
63                ->subcompile($msg)
64            ;
65
66            if ($this->hasNode('plural')) {
67                $compiler
68                    ->raw(', ')
69                    ->subcompile($msg1)
70                    ->raw(', abs(')
71                    ->subcompile($this->hasNode('count') ? $this->getNode('count') : null)
72                    ->raw(')')
73                ;
74            }
75
76            $compiler->raw('), array(');
77
78            foreach ($vars as $var) {
79                if ('count' === $var->getAttribute('name')) {
80                    $compiler
81                        ->string('%count%')
82                        ->raw(' => abs(')
83                        ->subcompile($this->hasNode('count') ? $this->getNode('count') : null)
84                        ->raw('), ')
85                    ;
86                } else {
87                    $compiler
88                        ->string('%'.$var->getAttribute('name').'%')
89                        ->raw(' => ')
90                        ->subcompile($var)
91                        ->raw(', ')
92                    ;
93                }
94            }
95
96            $compiler->raw("));\n");
97        } else {
98            $compiler
99                ->write('echo '.$function.'(')
100                ->subcompile($msg)
101            ;
102
103            if ($this->hasNode('plural')) {
104                $compiler
105                    ->raw(', ')
106                    ->subcompile($msg1)
107                    ->raw(', abs(')
108                    ->subcompile($this->hasNode('count') ? $this->getNode('count') : null)
109                    ->raw(')')
110                ;
111            }
112
113            $compiler->raw(");\n");
114        }
115    }
116
117    /**
118     * @param Twig_Node $body A Twig_Node instance
119     *
120     * @return array
121     */
122    protected function compileString(Twig_Node $body)
123    {
124        if ($body instanceof Twig_Node_Expression_Name || $body instanceof Twig_Node_Expression_Constant || $body instanceof Twig_Node_Expression_TempName) {
125            return array($body, array());
126        }
127
128        $vars = array();
129        if (count($body)) {
130            $msg = '';
131
132            foreach ($body as $node) {
133                if (get_class($node) === 'Twig_Node' && $node->getNode(0) instanceof Twig_Node_SetTemp) {
134                    $node = $node->getNode(1);
135                }
136
137                if ($node instanceof Twig_Node_Print) {
138                    $n = $node->getNode('expr');
139                    while ($n instanceof Twig_Node_Expression_Filter) {
140                        $n = $n->getNode('node');
141                    }
142                    $msg .= sprintf('%%%s%%', $n->getAttribute('name'));
143                    $vars[] = new Twig_Node_Expression_Name($n->getAttribute('name'), $n->getTemplateLine());
144                } else {
145                    $msg .= $node->getAttribute('data');
146                }
147            }
148        } else {
149            $msg = $body->getAttribute('data');
150        }
151
152        return array(new Twig_Node(array(new Twig_Node_Expression_Constant(trim($msg), $body->getTemplateLine()))), $vars);
153    }
154
155    /**
156     * @param bool $plural Return plural or singular function to use
157     *
158     * @return string
159     */
160    protected function getTransFunction($plural)
161    {
162        return $plural ? 'ngettext' : 'gettext';
163    }
164}
165
166class_alias('Twig_Extensions_Node_Trans', 'Twig\Extensions\Node\TransNode', false);
167