Verzeichnisstruktur phpBB-3.2.0
- Veröffentlicht
- 06.01.2017
So funktioniert es
|
Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück |
Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis. |
|
(Beispiel Datei-Icons)
|
Auf das Icon klicken um den Quellcode anzuzeigen |
Module.php
001 <?php
002
003 /*
004 * This file is part of Twig.
005 *
006 * (c) 2009 Fabien Potencier
007 * (c) 2009 Armin Ronacher
008 *
009 * For the full copyright and license information, please view the LICENSE
010 * file that was distributed with this source code.
011 */
012
013 /**
014 * Represents a module node.
015 *
016 * Consider this class as being final. If you need to customize the behavior of
017 * the generated class, consider adding nodes to the following nodes: display_start,
018 * display_end, constructor_start, constructor_end, and class_end.
019 *
020 * @author Fabien Potencier <fabien@symfony.com>
021 */
022 class Twig_Node_Module extends Twig_Node
023 {
024 public function __construct(Twig_NodeInterface $body, Twig_Node_Expression $parent = null, Twig_NodeInterface $blocks, Twig_NodeInterface $macros, Twig_NodeInterface $traits, $embeddedTemplates, $filename)
025 {
026 // embedded templates are set as attributes so that they are only visited once by the visitors
027 parent::__construct(array(
028 'parent' => $parent,
029 'body' => $body,
030 'blocks' => $blocks,
031 'macros' => $macros,
032 'traits' => $traits,
033 'display_start' => new Twig_Node(),
034 'display_end' => new Twig_Node(),
035 'constructor_start' => new Twig_Node(),
036 'constructor_end' => new Twig_Node(),
037 'class_end' => new Twig_Node(),
038 ), array(
039 'filename' => $filename,
040 'index' => null,
041 'embedded_templates' => $embeddedTemplates,
042 ), 1);
043 }
044
045 public function setIndex($index)
046 {
047 $this->setAttribute('index', $index);
048 }
049
050 public function compile(Twig_Compiler $compiler)
051 {
052 $this->compileTemplate($compiler);
053
054 foreach ($this->getAttribute('embedded_templates') as $template) {
055 $compiler->subcompile($template);
056 }
057 }
058
059 protected function compileTemplate(Twig_Compiler $compiler)
060 {
061 if (!$this->getAttribute('index')) {
062 $compiler->write('<?php');
063 }
064
065 $this->compileClassHeader($compiler);
066
067 if (
068 count($this->getNode('blocks'))
069 || count($this->getNode('traits'))
070 || null === $this->getNode('parent')
071 || $this->getNode('parent') instanceof Twig_Node_Expression_Constant
072 || count($this->getNode('constructor_start'))
073 || count($this->getNode('constructor_end'))
074 ) {
075 $this->compileConstructor($compiler);
076 }
077
078 $this->compileGetParent($compiler);
079
080 $this->compileDisplay($compiler);
081
082 $compiler->subcompile($this->getNode('blocks'));
083
084 $this->compileMacros($compiler);
085
086 $this->compileGetTemplateName($compiler);
087
088 $this->compileIsTraitable($compiler);
089
090 $this->compileDebugInfo($compiler);
091
092 $this->compileClassFooter($compiler);
093 }
094
095 protected function compileGetParent(Twig_Compiler $compiler)
096 {
097 if (null === $parent = $this->getNode('parent')) {
098 return;
099 }
100
101 $compiler
102 ->write("protected function doGetParent(array \$context)\n", "{\n")
103 ->indent()
104 ->addDebugInfo($parent)
105 ->write('return ')
106 ;
107
108 if ($parent instanceof Twig_Node_Expression_Constant) {
109 $compiler->subcompile($parent);
110 } else {
111 $compiler
112 ->raw('$this->loadTemplate(')
113 ->subcompile($parent)
114 ->raw(', ')
115 ->repr($compiler->getFilename())
116 ->raw(', ')
117 ->repr($this->getNode('parent')->getLine())
118 ->raw(')')
119 ;
120 }
121
122 $compiler
123 ->raw(";\n")
124 ->outdent()
125 ->write("}\n\n")
126 ;
127 }
128
129 protected function compileClassHeader(Twig_Compiler $compiler)
130 {
131 $compiler
132 ->write("\n\n")
133 // if the filename contains */, add a blank to avoid a PHP parse error
134 ->write('/* '.str_replace('*/', '* /', $this->getAttribute('filename'))." */\n")
135 ->write('class '.$compiler->getEnvironment()->getTemplateClass($this->getAttribute('filename'), $this->getAttribute('index')))
136 ->raw(sprintf(" extends %s\n", $compiler->getEnvironment()->getBaseTemplateClass()))
137 ->write("{\n")
138 ->indent()
139 ;
140 }
141
142 protected function compileConstructor(Twig_Compiler $compiler)
143 {
144 $compiler
145 ->write("public function __construct(Twig_Environment \$env)\n", "{\n")
146 ->indent()
147 ->subcompile($this->getNode('constructor_start'))
148 ->write("parent::__construct(\$env);\n\n")
149 ;
150
151 // parent
152 if (null === $parent = $this->getNode('parent')) {
153 $compiler->write("\$this->parent = false;\n\n");
154 } elseif ($parent instanceof Twig_Node_Expression_Constant) {
155 $compiler
156 ->addDebugInfo($parent)
157 ->write('$this->parent = $this->loadTemplate(')
158 ->subcompile($parent)
159 ->raw(', ')
160 ->repr($compiler->getFilename())
161 ->raw(', ')
162 ->repr($this->getNode('parent')->getLine())
163 ->raw(");\n")
164 ;
165 }
166
167 $countTraits = count($this->getNode('traits'));
168 if ($countTraits) {
169 // traits
170 foreach ($this->getNode('traits') as $i => $trait) {
171 $this->compileLoadTemplate($compiler, $trait->getNode('template'), sprintf('$_trait_%s', $i));
172
173 $compiler
174 ->addDebugInfo($trait->getNode('template'))
175 ->write(sprintf("if (!\$_trait_%s->isTraitable()) {\n", $i))
176 ->indent()
177 ->write("throw new Twig_Error_Runtime('Template \"'.")
178 ->subcompile($trait->getNode('template'))
179 ->raw(".'\" cannot be used as a trait.');\n")
180 ->outdent()
181 ->write("}\n")
182 ->write(sprintf("\$_trait_%s_blocks = \$_trait_%s->getBlocks();\n\n", $i, $i))
183 ;
184
185 foreach ($trait->getNode('targets') as $key => $value) {
186 $compiler
187 ->write(sprintf('if (!isset($_trait_%s_blocks[', $i))
188 ->string($key)
189 ->raw("])) {\n")
190 ->indent()
191 ->write("throw new Twig_Error_Runtime(sprintf('Block ")
192 ->string($key)
193 ->raw(' is not defined in trait ')
194 ->subcompile($trait->getNode('template'))
195 ->raw(".'));\n")
196 ->outdent()
197 ->write("}\n\n")
198
199 ->write(sprintf('$_trait_%s_blocks[', $i))
200 ->subcompile($value)
201 ->raw(sprintf('] = $_trait_%s_blocks[', $i))
202 ->string($key)
203 ->raw(sprintf(']; unset($_trait_%s_blocks[', $i))
204 ->string($key)
205 ->raw("]);\n\n")
206 ;
207 }
208 }
209
210 if ($countTraits > 1) {
211 $compiler
212 ->write("\$this->traits = array_merge(\n")
213 ->indent()
214 ;
215
216 for ($i = 0; $i < $countTraits; ++$i) {
217 $compiler
218 ->write(sprintf('$_trait_%s_blocks'.($i == $countTraits - 1 ? '' : ',')."\n", $i))
219 ;
220 }
221
222 $compiler
223 ->outdent()
224 ->write(");\n\n")
225 ;
226 } else {
227 $compiler
228 ->write("\$this->traits = \$_trait_0_blocks;\n\n")
229 ;
230 }
231
232 $compiler
233 ->write("\$this->blocks = array_merge(\n")
234 ->indent()
235 ->write("\$this->traits,\n")
236 ->write("array(\n")
237 ;
238 } else {
239 $compiler
240 ->write("\$this->blocks = array(\n")
241 ;
242 }
243
244 // blocks
245 $compiler
246 ->indent()
247 ;
248
249 foreach ($this->getNode('blocks') as $name => $node) {
250 $compiler
251 ->write(sprintf("'%s' => array(\$this, 'block_%s'),\n", $name, $name))
252 ;
253 }
254
255 if ($countTraits) {
256 $compiler
257 ->outdent()
258 ->write(")\n")
259 ;
260 }
261
262 $compiler
263 ->outdent()
264 ->write(");\n")
265 ->outdent()
266 ->subcompile($this->getNode('constructor_end'))
267 ->write("}\n\n")
268 ;
269 }
270
271 protected function compileDisplay(Twig_Compiler $compiler)
272 {
273 $compiler
274 ->write("protected function doDisplay(array \$context, array \$blocks = array())\n", "{\n")
275 ->indent()
276 ->subcompile($this->getNode('display_start'))
277 ->subcompile($this->getNode('body'))
278 ;
279
280 if (null !== $parent = $this->getNode('parent')) {
281 $compiler->addDebugInfo($parent);
282 if ($parent instanceof Twig_Node_Expression_Constant) {
283 $compiler->write('$this->parent');
284 } else {
285 $compiler->write('$this->getParent($context)');
286 }
287 $compiler->raw("->display(\$context, array_merge(\$this->blocks, \$blocks));\n");
288 }
289
290 $compiler
291 ->subcompile($this->getNode('display_end'))
292 ->outdent()
293 ->write("}\n\n")
294 ;
295 }
296
297 protected function compileClassFooter(Twig_Compiler $compiler)
298 {
299 $compiler
300 ->subcompile($this->getNode('class_end'))
301 ->outdent()
302 ->write("}\n")
303 ;
304 }
305
306 protected function compileMacros(Twig_Compiler $compiler)
307 {
308 $compiler->subcompile($this->getNode('macros'));
309 }
310
311 protected function compileGetTemplateName(Twig_Compiler $compiler)
312 {
313 $compiler
314 ->write("public function getTemplateName()\n", "{\n")
315 ->indent()
316 ->write('return ')
317 ->repr($this->getAttribute('filename'))
318 ->raw(";\n")
319 ->outdent()
320 ->write("}\n\n")
321 ;
322 }
323
324 protected function compileIsTraitable(Twig_Compiler $compiler)
325 {
326 // A template can be used as a trait if:
327 // * it has no parent
328 // * it has no macros
329 // * it has no body
330 //
331 // Put another way, a template can be used as a trait if it
332 // only contains blocks and use statements.
333 $traitable = null === $this->getNode('parent') && 0 === count($this->getNode('macros'));
334 if ($traitable) {
335 if ($this->getNode('body') instanceof Twig_Node_Body) {
336 $nodes = $this->getNode('body')->getNode(0);
337 } else {
338 $nodes = $this->getNode('body');
339 }
340
341 if (!count($nodes)) {
342 $nodes = new Twig_Node(array($nodes));
343 }
344
345 foreach ($nodes as $node) {
346 if (!count($node)) {
347 continue;
348 }
349
350 if ($node instanceof Twig_Node_Text && ctype_space($node->getAttribute('data'))) {
351 continue;
352 }
353
354 if ($node instanceof Twig_Node_BlockReference) {
355 continue;
356 }
357
358 $traitable = false;
359 break;
360 }
361 }
362
363 if ($traitable) {
364 return;
365 }
366
367 $compiler
368 ->write("public function isTraitable()\n", "{\n")
369 ->indent()
370 ->write(sprintf("return %s;\n", $traitable ? 'true' : 'false'))
371 ->outdent()
372 ->write("}\n\n")
373 ;
374 }
375
376 protected function compileDebugInfo(Twig_Compiler $compiler)
377 {
378 $compiler
379 ->write("public function getDebugInfo()\n", "{\n")
380 ->indent()
381 ->write(sprintf("return %s;\n", str_replace("\n", '', var_export(array_reverse($compiler->getDebugInfo(), true), true))))
382 ->outdent()
383 ->write("}\n")
384 ;
385 }
386
387 protected function compileLoadTemplate(Twig_Compiler $compiler, $node, $var)
388 {
389 if ($node instanceof Twig_Node_Expression_Constant) {
390 $compiler
391 ->write(sprintf('%s = $this->loadTemplate(', $var))
392 ->subcompile($node)
393 ->raw(', ')
394 ->repr($compiler->getFilename())
395 ->raw(', ')
396 ->repr($node->getLine())
397 ->raw(");\n")
398 ;
399 } else {
400 throw new LogicException('Trait templates can only be constant nodes');
401 }
402 }
403 }
404