Security update for Core, with self-updated composer
[yaffs-website] / vendor / twig / twig / lib / Twig / Compiler.php
1 <?php
2
3 /*
4  * This file is part of Twig.
5  *
6  * (c) Fabien Potencier
7  * (c) Armin Ronacher
8  *
9  * For the full copyright and license information, please view the LICENSE
10  * file that was distributed with this source code.
11  */
12
13 /**
14  * Compiles a node to PHP code.
15  *
16  * @author Fabien Potencier <fabien@symfony.com>
17  */
18 class Twig_Compiler implements Twig_CompilerInterface
19 {
20     protected $lastLine;
21     protected $source;
22     protected $indentation;
23     protected $env;
24     protected $debugInfo = array();
25     protected $sourceOffset;
26     protected $sourceLine;
27     protected $filename;
28     private $varNameSalt = 0;
29
30     public function __construct(Twig_Environment $env)
31     {
32         $this->env = $env;
33     }
34
35     /**
36      * @deprecated since 1.25 (to be removed in 2.0)
37      */
38     public function getFilename()
39     {
40         @trigger_error(sprintf('The %s() method is deprecated since version 1.25 and will be removed in 2.0.', __FUNCTION__), E_USER_DEPRECATED);
41
42         return $this->filename;
43     }
44
45     /**
46      * Returns the environment instance related to this compiler.
47      *
48      * @return Twig_Environment
49      */
50     public function getEnvironment()
51     {
52         return $this->env;
53     }
54
55     /**
56      * Gets the current PHP code after compilation.
57      *
58      * @return string The PHP code
59      */
60     public function getSource()
61     {
62         return $this->source;
63     }
64
65     /**
66      * Compiles a node.
67      *
68      * @param Twig_NodeInterface $node        The node to compile
69      * @param int                $indentation The current indentation
70      *
71      * @return $this
72      */
73     public function compile(Twig_NodeInterface $node, $indentation = 0)
74     {
75         $this->lastLine = null;
76         $this->source = '';
77         $this->debugInfo = array();
78         $this->sourceOffset = 0;
79         // source code starts at 1 (as we then increment it when we encounter new lines)
80         $this->sourceLine = 1;
81         $this->indentation = $indentation;
82         $this->varNameSalt = 0;
83
84         if ($node instanceof Twig_Node_Module) {
85             // to be removed in 2.0
86             $this->filename = $node->getTemplateName();
87         }
88
89         $node->compile($this);
90
91         return $this;
92     }
93
94     public function subcompile(Twig_NodeInterface $node, $raw = true)
95     {
96         if (false === $raw) {
97             $this->source .= str_repeat(' ', $this->indentation * 4);
98         }
99
100         $node->compile($this);
101
102         return $this;
103     }
104
105     /**
106      * Adds a raw string to the compiled code.
107      *
108      * @param string $string The string
109      *
110      * @return $this
111      */
112     public function raw($string)
113     {
114         $this->source .= $string;
115
116         return $this;
117     }
118
119     /**
120      * Writes a string to the compiled code by adding indentation.
121      *
122      * @return $this
123      */
124     public function write()
125     {
126         $strings = func_get_args();
127         foreach ($strings as $string) {
128             $this->source .= str_repeat(' ', $this->indentation * 4).$string;
129         }
130
131         return $this;
132     }
133
134     /**
135      * Appends an indentation to the current PHP code after compilation.
136      *
137      * @return $this
138      *
139      * @deprecated since 1.27 (to be removed in 2.0).
140      */
141     public function addIndentation()
142     {
143         @trigger_error('The '.__METHOD__.' method is deprecated since version 1.27 and will be removed in 2.0. Use write(\'\') instead.', E_USER_DEPRECATED);
144
145         $this->source .= str_repeat(' ', $this->indentation * 4);
146
147         return $this;
148     }
149
150     /**
151      * Adds a quoted string to the compiled code.
152      *
153      * @param string $value The string
154      *
155      * @return $this
156      */
157     public function string($value)
158     {
159         $this->source .= sprintf('"%s"', addcslashes($value, "\0\t\"\$\\"));
160
161         return $this;
162     }
163
164     /**
165      * Returns a PHP representation of a given value.
166      *
167      * @param mixed $value The value to convert
168      *
169      * @return $this
170      */
171     public function repr($value)
172     {
173         if (is_int($value) || is_float($value)) {
174             if (false !== $locale = setlocale(LC_NUMERIC, '0')) {
175                 setlocale(LC_NUMERIC, 'C');
176             }
177
178             $this->raw($value);
179
180             if (false !== $locale) {
181                 setlocale(LC_NUMERIC, $locale);
182             }
183         } elseif (null === $value) {
184             $this->raw('null');
185         } elseif (is_bool($value)) {
186             $this->raw($value ? 'true' : 'false');
187         } elseif (is_array($value)) {
188             $this->raw('array(');
189             $first = true;
190             foreach ($value as $key => $v) {
191                 if (!$first) {
192                     $this->raw(', ');
193                 }
194                 $first = false;
195                 $this->repr($key);
196                 $this->raw(' => ');
197                 $this->repr($v);
198             }
199             $this->raw(')');
200         } else {
201             $this->string($value);
202         }
203
204         return $this;
205     }
206
207     /**
208      * Adds debugging information.
209      *
210      * @return $this
211      */
212     public function addDebugInfo(Twig_NodeInterface $node)
213     {
214         if ($node->getTemplateLine() != $this->lastLine) {
215             $this->write(sprintf("// line %d\n", $node->getTemplateLine()));
216
217             // when mbstring.func_overload is set to 2
218             // mb_substr_count() replaces substr_count()
219             // but they have different signatures!
220             if (((int) ini_get('mbstring.func_overload')) & 2) {
221                 @trigger_error('Support for having "mbstring.func_overload" different from 0 is deprecated version 1.29 and will be removed in 2.0.', E_USER_DEPRECATED);
222
223                 // this is much slower than the "right" version
224                 $this->sourceLine += mb_substr_count(mb_substr($this->source, $this->sourceOffset), "\n");
225             } else {
226                 $this->sourceLine += substr_count($this->source, "\n", $this->sourceOffset);
227             }
228             $this->sourceOffset = strlen($this->source);
229             $this->debugInfo[$this->sourceLine] = $node->getTemplateLine();
230
231             $this->lastLine = $node->getTemplateLine();
232         }
233
234         return $this;
235     }
236
237     public function getDebugInfo()
238     {
239         ksort($this->debugInfo);
240
241         return $this->debugInfo;
242     }
243
244     /**
245      * Indents the generated code.
246      *
247      * @param int $step The number of indentation to add
248      *
249      * @return $this
250      */
251     public function indent($step = 1)
252     {
253         $this->indentation += $step;
254
255         return $this;
256     }
257
258     /**
259      * Outdents the generated code.
260      *
261      * @param int $step The number of indentation to remove
262      *
263      * @return $this
264      *
265      * @throws LogicException When trying to outdent too much so the indentation would become negative
266      */
267     public function outdent($step = 1)
268     {
269         // can't outdent by more steps than the current indentation level
270         if ($this->indentation < $step) {
271             throw new LogicException('Unable to call outdent() as the indentation would become negative.');
272         }
273
274         $this->indentation -= $step;
275
276         return $this;
277     }
278
279     public function getVarName()
280     {
281         return sprintf('__internal_%s', hash('sha256', __METHOD__.$this->varNameSalt++));
282     }
283 }
284
285 class_alias('Twig_Compiler', 'Twig\Compiler', false);
286 class_exists('Twig_Node');