PluginProbe
Responsive Menu – Create Mobile-Friendly Menu / 4.1.1
Responsive Menu – Create Mobile-Friendly Menu v4.1.1
4.7.3 3.1.5 3.1.6 3.1.7 3.1.8 3.1.9 4.0.0 4.0.1 4.0.2 4.0.3 4.0.4 4.1.0 4.1.1 4.1.10 4.1.11 4.1.12 4.1.2 4.1.3 4.1.4 4.1.5 4.1.6 4.1.7 4.1.8 4.1.9 4.2.0 All 90 releases
responsive-menu / vendor / twig / twig / lib / Twig / Node / Module.php

Module.php in Responsive Menu – Create Mobile-Friendly Menu 4.1.1, at vendor/twig/twig/lib/Twig/Node/Module.php

460 lines 14.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
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 * Represents a module node.
15 *
16 * Consider this class as being final. If you need to customize the behavior of
17 * the generated class, consider adding nodes to the following nodes: display_start,
18 * display_end, constructor_start, constructor_end, and class_end.
19 *
20 * @author Fabien Potencier <fabien@symfony.com>
21 */
22 class Twig_Node_Module extends Twig_Node
23 {
24 private $source;
25
26 public function __construct(Twig_NodeInterface $body, Twig_Node_Expression $parent = null, Twig_NodeInterface $blocks, Twig_NodeInterface $macros, Twig_NodeInterface $traits, $embeddedTemplates, $name, $source = '')
27 {
28 if (!$name instanceof Twig_Source) {
29 @trigger_error(sprintf('Passing a string as the $name argument of %s() is deprecated since version 1.27. Pass a Twig_Source instance instead.', __METHOD__), E_USER_DEPRECATED);
30 $this->source = new Twig_Source($source, $name);
31 } else {
32 $this->source = $name;
33 }
34
35 $nodes = array(
36 'body' => $body,
37 'blocks' => $blocks,
38 'macros' => $macros,
39 'traits' => $traits,
40 'display_start' => new Twig_Node(),
41 'display_end' => new Twig_Node(),
42 'constructor_start' => new Twig_Node(),
43 'constructor_end' => new Twig_Node(),
44 'class_end' => new Twig_Node(),
45 );
46 if (null !== $parent) {
47 $nodes['parent'] = $parent;
48 }
49
50 // embedded templates are set as attributes so that they are only visited once by the visitors
51 parent::__construct($nodes, array(
52 // source to be remove in 2.0
53 'source' => $this->source->getCode(),
54 // filename to be remove in 2.0 (use getTemplateName() instead)
55 'filename' => $this->source->getName(),
56 'index' => null,
57 'embedded_templates' => $embeddedTemplates,
58 ), 1);
59
60 // populate the template name of all node children
61 $this->setTemplateName($this->source->getName());
62 }
63
64 public function setIndex($index)
65 {
66 $this->setAttribute('index', $index);
67 }
68
69 public function compile(Twig_Compiler $compiler)
70 {
71 $this->compileTemplate($compiler);
72
73 foreach ($this->getAttribute('embedded_templates') as $template) {
74 $compiler->subcompile($template);
75 }
76 }
77
78 protected function compileTemplate(Twig_Compiler $compiler)
79 {
80 if (!$this->getAttribute('index')) {
81 $compiler->write('<?php');
82 }
83
84 $this->compileClassHeader($compiler);
85
86 if (
87 count($this->getNode('blocks'))
88 || count($this->getNode('traits'))
89 || !$this->hasNode('parent')
90 || $this->getNode('parent') instanceof Twig_Node_Expression_Constant
91 || count($this->getNode('constructor_start'))
92 || count($this->getNode('constructor_end'))
93 ) {
94 $this->compileConstructor($compiler);
95 }
96
97 $this->compileGetParent($compiler);
98
99 $this->compileDisplay($compiler);
100
101 $compiler->subcompile($this->getNode('blocks'));
102
103 $this->compileMacros($compiler);
104
105 $this->compileGetTemplateName($compiler);
106
107 $this->compileIsTraitable($compiler);
108
109 $this->compileDebugInfo($compiler);
110
111 $this->compileGetSource($compiler);
112
113 $this->compileGetSourceContext($compiler);
114
115 $this->compileClassFooter($compiler);
116 }
117
118 protected function compileGetParent(Twig_Compiler $compiler)
119 {
120 if (!$this->hasNode('parent')) {
121 return;
122 }
123 $parent = $this->getNode('parent');
124
125 $compiler
126 ->write("protected function doGetParent(array \$context)\n", "{\n")
127 ->indent()
128 ->addDebugInfo($parent)
129 ->write('return ')
130 ;
131
132 if ($parent instanceof Twig_Node_Expression_Constant) {
133 $compiler->subcompile($parent);
134 } else {
135 $compiler
136 ->raw('$this->loadTemplate(')
137 ->subcompile($parent)
138 ->raw(', ')
139 ->repr($this->source->getName())
140 ->raw(', ')
141 ->repr($parent->getTemplateLine())
142 ->raw(')')
143 ;
144 }
145
146 $compiler
147 ->raw(";\n")
148 ->outdent()
149 ->write("}\n\n")
150 ;
151 }
152
153 protected function compileClassHeader(Twig_Compiler $compiler)
154 {
155 $compiler
156 ->write("\n\n")
157 // if the template name contains */, add a blank to avoid a PHP parse error
158 ->write('/* '.str_replace('*/', '* /', $this->source->getName())." */\n")
159 ->write('class '.$compiler->getEnvironment()->getTemplateClass($this->source->getName(), $this->getAttribute('index')))
160 ->raw(sprintf(" extends %s\n", $compiler->getEnvironment()->getBaseTemplateClass()))
161 ->write("{\n")
162 ->indent()
163 ;
164 }
165
166 protected function compileConstructor(Twig_Compiler $compiler)
167 {
168 $compiler
169 ->write("public function __construct(Twig_Environment \$env)\n", "{\n")
170 ->indent()
171 ->subcompile($this->getNode('constructor_start'))
172 ->write("parent::__construct(\$env);\n\n")
173 ;
174
175 // parent
176 if (!$this->hasNode('parent')) {
177 $compiler->write("\$this->parent = false;\n\n");
178 } elseif (($parent = $this->getNode('parent')) && $parent instanceof Twig_Node_Expression_Constant) {
179 $compiler
180 ->addDebugInfo($parent)
181 ->write('$this->parent = $this->loadTemplate(')
182 ->subcompile($parent)
183 ->raw(', ')
184 ->repr($this->source->getName())
185 ->raw(', ')
186 ->repr($parent->getTemplateLine())
187 ->raw(");\n")
188 ;
189 }
190
191 $countTraits = count($this->getNode('traits'));
192 if ($countTraits) {
193 // traits
194 foreach ($this->getNode('traits') as $i => $trait) {
195 $this->compileLoadTemplate($compiler, $trait->getNode('template'), sprintf('$_trait_%s', $i));
196
197 $compiler
198 ->addDebugInfo($trait->getNode('template'))
199 ->write(sprintf("if (!\$_trait_%s->isTraitable()) {\n", $i))
200 ->indent()
201 ->write("throw new Twig_Error_Runtime('Template \"'.")
202 ->subcompile($trait->getNode('template'))
203 ->raw(".'\" cannot be used as a trait.');\n")
204 ->outdent()
205 ->write("}\n")
206 ->write(sprintf("\$_trait_%s_blocks = \$_trait_%s->getBlocks();\n\n", $i, $i))
207 ;
208
209 foreach ($trait->getNode('targets') as $key => $value) {
210 $compiler
211 ->write(sprintf('if (!isset($_trait_%s_blocks[', $i))
212 ->string($key)
213 ->raw("])) {\n")
214 ->indent()
215 ->write("throw new Twig_Error_Runtime(sprintf('Block ")
216 ->string($key)
217 ->raw(' is not defined in trait ')
218 ->subcompile($trait->getNode('template'))
219 ->raw(".'));\n")
220 ->outdent()
221 ->write("}\n\n")
222
223 ->write(sprintf('$_trait_%s_blocks[', $i))
224 ->subcompile($value)
225 ->raw(sprintf('] = $_trait_%s_blocks[', $i))
226 ->string($key)
227 ->raw(sprintf(']; unset($_trait_%s_blocks[', $i))
228 ->string($key)
229 ->raw("]);\n\n")
230 ;
231 }
232 }
233
234 if ($countTraits > 1) {
235 $compiler
236 ->write("\$this->traits = array_merge(\n")
237 ->indent()
238 ;
239
240 for ($i = 0; $i < $countTraits; ++$i) {
241 $compiler
242 ->write(sprintf('$_trait_%s_blocks'.($i == $countTraits - 1 ? '' : ',')."\n", $i))
243 ;
244 }
245
246 $compiler
247 ->outdent()
248 ->write(");\n\n")
249 ;
250 } else {
251 $compiler
252 ->write("\$this->traits = \$_trait_0_blocks;\n\n")
253 ;
254 }
255
256 $compiler
257 ->write("\$this->blocks = array_merge(\n")
258 ->indent()
259 ->write("\$this->traits,\n")
260 ->write("array(\n")
261 ;
262 } else {
263 $compiler
264 ->write("\$this->blocks = array(\n")
265 ;
266 }
267
268 // blocks
269 $compiler
270 ->indent()
271 ;
272
273 foreach ($this->getNode('blocks') as $name => $node) {
274 $compiler
275 ->write(sprintf("'%s' => array(\$this, 'block_%s'),\n", $name, $name))
276 ;
277 }
278
279 if ($countTraits) {
280 $compiler
281 ->outdent()
282 ->write(")\n")
283 ;
284 }
285
286 $compiler
287 ->outdent()
288 ->write(");\n")
289 ->outdent()
290 ->subcompile($this->getNode('constructor_end'))
291 ->write("}\n\n")
292 ;
293 }
294
295 protected function compileDisplay(Twig_Compiler $compiler)
296 {
297 $compiler
298 ->write("protected function doDisplay(array \$context, array \$blocks = array())\n", "{\n")
299 ->indent()
300 ->subcompile($this->getNode('display_start'))
301 ->subcompile($this->getNode('body'))
302 ;
303
304 if ($this->hasNode('parent')) {
305 $parent = $this->getNode('parent');
306 $compiler->addDebugInfo($parent);
307 if ($parent instanceof Twig_Node_Expression_Constant) {
308 $compiler->write('$this->parent');
309 } else {
310 $compiler->write('$this->getParent($context)');
311 }
312 $compiler->raw("->display(\$context, array_merge(\$this->blocks, \$blocks));\n");
313 }
314
315 $compiler
316 ->subcompile($this->getNode('display_end'))
317 ->outdent()
318 ->write("}\n\n")
319 ;
320 }
321
322 protected function compileClassFooter(Twig_Compiler $compiler)
323 {
324 $compiler
325 ->subcompile($this->getNode('class_end'))
326 ->outdent()
327 ->write("}\n")
328 ;
329 }
330
331 protected function compileMacros(Twig_Compiler $compiler)
332 {
333 $compiler->subcompile($this->getNode('macros'));
334 }
335
336 protected function compileGetTemplateName(Twig_Compiler $compiler)
337 {
338 $compiler
339 ->write("public function getTemplateName()\n", "{\n")
340 ->indent()
341 ->write('return ')
342 ->repr($this->source->getName())
343 ->raw(";\n")
344 ->outdent()
345 ->write("}\n\n")
346 ;
347 }
348
349 protected function compileIsTraitable(Twig_Compiler $compiler)
350 {
351 // A template can be used as a trait if:
352 // * it has no parent
353 // * it has no macros
354 // * it has no body
355 //
356 // Put another way, a template can be used as a trait if it
357 // only contains blocks and use statements.
358 $traitable = !$this->hasNode('parent') && 0 === count($this->getNode('macros'));
359 if ($traitable) {
360 if ($this->getNode('body') instanceof Twig_Node_Body) {
361 $nodes = $this->getNode('body')->getNode(0);
362 } else {
363 $nodes = $this->getNode('body');
364 }
365
366 if (!count($nodes)) {
367 $nodes = new Twig_Node(array($nodes));
368 }
369
370 foreach ($nodes as $node) {
371 if (!count($node)) {
372 continue;
373 }
374
375 if ($node instanceof Twig_Node_Text && ctype_space($node->getAttribute('data'))) {
376 continue;
377 }
378
379 if ($node instanceof Twig_Node_BlockReference) {
380 continue;
381 }
382
383 $traitable = false;
384 break;
385 }
386 }
387
388 if ($traitable) {
389 return;
390 }
391
392 $compiler
393 ->write("public function isTraitable()\n", "{\n")
394 ->indent()
395 ->write(sprintf("return %s;\n", $traitable ? 'true' : 'false'))
396 ->outdent()
397 ->write("}\n\n")
398 ;
399 }
400
401 protected function compileDebugInfo(Twig_Compiler $compiler)
402 {
403 $compiler
404 ->write("public function getDebugInfo()\n", "{\n")
405 ->indent()
406 ->write(sprintf("return %s;\n", str_replace("\n", '', var_export(array_reverse($compiler->getDebugInfo(), true), true))))
407 ->outdent()
408 ->write("}\n\n")
409 ;
410 }
411
412 protected function compileGetSource(Twig_Compiler $compiler)
413 {
414 $compiler
415 ->write("/** @deprecated since 1.27 (to be removed in 2.0). Use getSourceContext() instead */\n")
416 ->write("public function getSource()\n", "{\n")
417 ->indent()
418 ->write("@trigger_error('The '.__METHOD__.' method is deprecated since version 1.27 and will be removed in 2.0. Use getSourceContext() instead.', E_USER_DEPRECATED);\n\n")
419 ->write('return $this->getSourceContext()->getCode();')
420 ->raw("\n")
421 ->outdent()
422 ->write("}\n\n")
423 ;
424 }
425
426 protected function compileGetSourceContext(Twig_Compiler $compiler)
427 {
428 $compiler
429 ->write("public function getSourceContext()\n", "{\n")
430 ->indent()
431 ->write('return new Twig_Source(')
432 ->string($compiler->getEnvironment()->isDebug() ? $this->source->getCode() : '')
433 ->raw(', ')
434 ->string($this->source->getName())
435 ->raw(', ')
436 ->string($this->source->getPath())
437 ->raw(");\n")
438 ->outdent()
439 ->write("}\n")
440 ;
441 }
442
443 protected function compileLoadTemplate(Twig_Compiler $compiler, $node, $var)
444 {
445 if ($node instanceof Twig_Node_Expression_Constant) {
446 $compiler
447 ->write(sprintf('%s = $this->loadTemplate(', $var))
448 ->subcompile($node)
449 ->raw(', ')
450 ->repr($node->getTemplateName())
451 ->raw(', ')
452 ->repr($node->getTemplateLine())
453 ->raw(");\n")
454 ;
455 } else {
456 throw new LogicException('Trait templates can only be constant nodes.');
457 }
458 }
459 }
460