Verzeichnisstruktur phpBB-3.3.16


Veröffentlicht
27.04.2026

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.
Auf den Verzeichnisnamen klicken, dies zeigt nur das Verzeichnis mit Inhalt an

      (Beispiel Datei-Icons)

Auf das Icon klicken um den Quellcode anzuzeigen

ModuleNode.php

Zuletzt modifiziert: 01.05.2026, 11:27 - Dateigröße: 14.78 KiB


 001  <?php
 002   
 003  /*
 004   * This file is part of Twig.
 005   *
 006   * (c) Fabien Potencier
 007   * (c) 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  namespace Twig\Node;
 014   
 015  use Twig\Compiler;
 016  use Twig\Node\Expression\AbstractExpression;
 017  use Twig\Node\Expression\ConstantExpression;
 018  use Twig\Source;
 019   
 020  /**
 021   * Represents a module node.
 022   *
 023   * Consider this class as being final. If you need to customize the behavior of
 024   * the generated class, consider adding nodes to the following nodes: display_start,
 025   * display_end, constructor_start, constructor_end, and class_end.
 026   *
 027   * @author Fabien Potencier <fabien@symfony.com>
 028   *
 029   * @final since Twig 2.4.0
 030   */
 031  class ModuleNode extends Node
 032  {
 033      public function __construct(Node $body, ?AbstractExpression $parent, Node $blocks, Node $macros, Node $traits, $embeddedTemplates, Source $source)
 034      {
 035          if (__CLASS__ !== static::class) {
 036              @trigger_error('Overriding '.__CLASS__.' is deprecated since Twig 2.4.0 and the class will be final in 3.0.', \E_USER_DEPRECATED);
 037          }
 038   
 039          $nodes = [
 040              'body' => $body,
 041              'blocks' => $blocks,
 042              'macros' => $macros,
 043              'traits' => $traits,
 044              'display_start' => new Node(),
 045              'display_end' => new Node(),
 046              'constructor_start' => new Node(),
 047              'constructor_end' => new Node(),
 048              'class_end' => new Node(),
 049          ];
 050          if (null !== $parent) {
 051              $nodes['parent'] = $parent;
 052          }
 053   
 054          // embedded templates are set as attributes so that they are only visited once by the visitors
 055          parent::__construct($nodes, [
 056              'index' => null,
 057              'embedded_templates' => $embeddedTemplates,
 058          ], 1);
 059   
 060          // populate the template name of all node children
 061          $this->setSourceContext($source);
 062      }
 063   
 064      public function setIndex($index)
 065      {
 066          $this->setAttribute('index', $index);
 067      }
 068   
 069      public function compile(Compiler $compiler)
 070      {
 071          $this->compileTemplate($compiler);
 072   
 073          foreach ($this->getAttribute('embedded_templates') as $template) {
 074              $compiler->subcompile($template);
 075          }
 076      }
 077   
 078      protected function compileTemplate(Compiler $compiler)
 079      {
 080          if (!$this->getAttribute('index')) {
 081              $compiler->write('<?php');
 082          }
 083   
 084          $this->compileClassHeader($compiler);
 085   
 086          $this->compileConstructor($compiler);
 087   
 088          $this->compileGetParent($compiler);
 089   
 090          $this->compileDisplay($compiler);
 091   
 092          $compiler->subcompile($this->getNode('blocks'));
 093   
 094          $this->compileMacros($compiler);
 095   
 096          $this->compileGetTemplateName($compiler);
 097   
 098          $this->compileIsTraitable($compiler);
 099   
 100          $this->compileDebugInfo($compiler);
 101   
 102          $this->compileGetSourceContext($compiler);
 103   
 104          $this->compileClassFooter($compiler);
 105      }
 106   
 107      protected function compileGetParent(Compiler $compiler)
 108      {
 109          if (!$this->hasNode('parent')) {
 110              return;
 111          }
 112          $parent = $this->getNode('parent');
 113   
 114          $compiler
 115              ->write("protected function doGetParent(array \$context)\n", "{\n")
 116              ->indent()
 117              ->addDebugInfo($parent)
 118              ->write('return ')
 119          ;
 120   
 121          if ($parent instanceof ConstantExpression) {
 122              $compiler->subcompile($parent);
 123          } else {
 124              $compiler
 125                  ->raw('$this->loadTemplate(')
 126                  ->subcompile($parent)
 127                  ->raw(', ')
 128                  ->repr($this->getSourceContext()->getName())
 129                  ->raw(', ')
 130                  ->repr($parent->getTemplateLine())
 131                  ->raw(')')
 132              ;
 133          }
 134   
 135          $compiler
 136              ->raw(";\n")
 137              ->outdent()
 138              ->write("}\n\n")
 139          ;
 140      }
 141   
 142      protected function compileClassHeader(Compiler $compiler)
 143      {
 144          $compiler
 145              ->write("\n\n")
 146          ;
 147          if (!$this->getAttribute('index')) {
 148              $compiler
 149                  ->write("use Twig\Environment;\n")
 150                  ->write("use Twig\Error\LoaderError;\n")
 151                  ->write("use Twig\Error\RuntimeError;\n")
 152                  ->write("use Twig\Extension\SandboxExtension;\n")
 153                  ->write("use Twig\Markup;\n")
 154                  ->write("use Twig\Sandbox\SecurityError;\n")
 155                  ->write("use Twig\Sandbox\SecurityNotAllowedTagError;\n")
 156                  ->write("use Twig\Sandbox\SecurityNotAllowedFilterError;\n")
 157                  ->write("use Twig\Sandbox\SecurityNotAllowedFunctionError;\n")
 158                  ->write("use Twig\Source;\n")
 159                  ->write("use Twig\Template;\n\n")
 160              ;
 161          }
 162          $compiler
 163              // if the template name contains */, add a blank to avoid a PHP parse error
 164              ->write('/* '.str_replace('*/', '* /', $this->getSourceContext()->getName())." */\n")
 165              ->write('class '.$compiler->getEnvironment()->getTemplateClass($this->getSourceContext()->getName(), $this->getAttribute('index')))
 166              ->raw(sprintf(" extends %s\n", $compiler->getEnvironment()->getBaseTemplateClass(false)))
 167              ->write("{\n")
 168              ->indent()
 169              ->write("private \$source;\n")
 170              ->write("private \$macros = [];\n\n")
 171          ;
 172      }
 173   
 174      protected function compileConstructor(Compiler $compiler)
 175      {
 176          $compiler
 177              ->write("public function __construct(Environment \$env)\n", "{\n")
 178              ->indent()
 179              ->subcompile($this->getNode('constructor_start'))
 180              ->write("parent::__construct(\$env);\n\n")
 181              ->write("\$this->source = \$this->getSourceContext();\n\n")
 182          ;
 183   
 184          // parent
 185          if (!$this->hasNode('parent')) {
 186              $compiler->write("\$this->parent = false;\n\n");
 187          }
 188   
 189          $countTraits = \count($this->getNode('traits'));
 190          if ($countTraits) {
 191              // traits
 192              foreach ($this->getNode('traits') as $i => $trait) {
 193                  $node = $trait->getNode('template');
 194   
 195                  $compiler
 196                      ->addDebugInfo($node)
 197                      ->write(sprintf('$_trait_%s = $this->loadTemplate(', $i))
 198                      ->subcompile($node)
 199                      ->raw(', ')
 200                      ->repr($node->getTemplateName())
 201                      ->raw(', ')
 202                      ->repr($node->getTemplateLine())
 203                      ->raw(");\n")
 204                      ->write(sprintf("if (!\$_trait_%s->isTraitable()) {\n", $i))
 205                      ->indent()
 206                      ->write("throw new RuntimeError('Template \"'.")
 207                      ->subcompile($trait->getNode('template'))
 208                      ->raw(".'\" cannot be used as a trait.', ")
 209                      ->repr($node->getTemplateLine())
 210                      ->raw(", \$this->source);\n")
 211                      ->outdent()
 212                      ->write("}\n")
 213                      ->write(sprintf("\$_trait_%s_blocks = \$_trait_%s->getBlocks();\n\n", $i, $i))
 214                  ;
 215   
 216                  foreach ($trait->getNode('targets') as $key => $value) {
 217                      $compiler
 218                          ->write(sprintf('if (!isset($_trait_%s_blocks[', $i))
 219                          ->string($key)
 220                          ->raw("])) {\n")
 221                          ->indent()
 222                          ->write("throw new RuntimeError('Block ")
 223                          ->string($key)
 224                          ->raw(' is not defined in trait ')
 225                          ->subcompile($trait->getNode('template'))
 226                          ->raw(".', ")
 227                          ->repr($node->getTemplateLine())
 228                          ->raw(", \$this->source);\n")
 229                          ->outdent()
 230                          ->write("}\n\n")
 231   
 232                          ->write(sprintf('$_trait_%s_blocks[', $i))
 233                          ->subcompile($value)
 234                          ->raw(sprintf('] = $_trait_%s_blocks[', $i))
 235                          ->string($key)
 236                          ->raw(sprintf(']; unset($_trait_%s_blocks[', $i))
 237                          ->string($key)
 238                          ->raw("]);\n\n")
 239                      ;
 240                  }
 241              }
 242   
 243              if ($countTraits > 1) {
 244                  $compiler
 245                      ->write("\$this->traits = array_merge(\n")
 246                      ->indent()
 247                  ;
 248   
 249                  for ($i = 0; $i < $countTraits; ++$i) {
 250                      $compiler
 251                          ->write(sprintf('$_trait_%s_blocks'.($i == $countTraits - 1 ? '' : ',')."\n", $i))
 252                      ;
 253                  }
 254   
 255                  $compiler
 256                      ->outdent()
 257                      ->write(");\n\n")
 258                  ;
 259              } else {
 260                  $compiler
 261                      ->write("\$this->traits = \$_trait_0_blocks;\n\n")
 262                  ;
 263              }
 264   
 265              $compiler
 266                  ->write("\$this->blocks = array_merge(\n")
 267                  ->indent()
 268                  ->write("\$this->traits,\n")
 269                  ->write("[\n")
 270              ;
 271          } else {
 272              $compiler
 273                  ->write("\$this->blocks = [\n")
 274              ;
 275          }
 276   
 277          // blocks
 278          $compiler
 279              ->indent()
 280          ;
 281   
 282          foreach ($this->getNode('blocks') as $name => $node) {
 283              $compiler
 284                  ->write(sprintf("'%s' => [\$this, 'block_%s'],\n", $name, $name))
 285              ;
 286          }
 287   
 288          if ($countTraits) {
 289              $compiler
 290                  ->outdent()
 291                  ->write("]\n")
 292                  ->outdent()
 293                  ->write(");\n")
 294              ;
 295          } else {
 296              $compiler
 297                  ->outdent()
 298                  ->write("];\n")
 299              ;
 300          }
 301   
 302          $compiler
 303              ->subcompile($this->getNode('constructor_end'))
 304              ->outdent()
 305              ->write("}\n\n")
 306          ;
 307      }
 308   
 309      protected function compileDisplay(Compiler $compiler)
 310      {
 311          $compiler
 312              ->write("protected function doDisplay(array \$context, array \$blocks = [])\n", "{\n")
 313              ->indent()
 314              ->write("\$macros = \$this->macros;\n")
 315              ->subcompile($this->getNode('display_start'))
 316              ->subcompile($this->getNode('body'))
 317          ;
 318   
 319          if ($this->hasNode('parent')) {
 320              $parent = $this->getNode('parent');
 321   
 322              $compiler->addDebugInfo($parent);
 323              if ($parent instanceof ConstantExpression) {
 324                  $compiler
 325                      ->write('$this->parent = $this->loadTemplate(')
 326                      ->subcompile($parent)
 327                      ->raw(', ')
 328                      ->repr($this->getSourceContext()->getName())
 329                      ->raw(', ')
 330                      ->repr($parent->getTemplateLine())
 331                      ->raw(");\n")
 332                  ;
 333                  $compiler->write('$this->parent');
 334              } else {
 335                  $compiler->write('$this->getParent($context)');
 336              }
 337              $compiler->raw("->display(\$context, array_merge(\$this->blocks, \$blocks));\n");
 338          }
 339   
 340          $compiler
 341              ->subcompile($this->getNode('display_end'))
 342              ->outdent()
 343              ->write("}\n\n")
 344          ;
 345      }
 346   
 347      protected function compileClassFooter(Compiler $compiler)
 348      {
 349          $compiler
 350              ->subcompile($this->getNode('class_end'))
 351              ->outdent()
 352              ->write("}\n")
 353          ;
 354      }
 355   
 356      protected function compileMacros(Compiler $compiler)
 357      {
 358          $compiler->subcompile($this->getNode('macros'));
 359      }
 360   
 361      protected function compileGetTemplateName(Compiler $compiler)
 362      {
 363          $compiler
 364              ->write("public function getTemplateName()\n", "{\n")
 365              ->indent()
 366              ->write('return ')
 367              ->repr($this->getSourceContext()->getName())
 368              ->raw(";\n")
 369              ->outdent()
 370              ->write("}\n\n")
 371          ;
 372      }
 373   
 374      protected function compileIsTraitable(Compiler $compiler)
 375      {
 376          // A template can be used as a trait if:
 377          //   * it has no parent
 378          //   * it has no macros
 379          //   * it has no body
 380          //
 381          // Put another way, a template can be used as a trait if it
 382          // only contains blocks and use statements.
 383          $traitable = !$this->hasNode('parent') && 0 === \count($this->getNode('macros'));
 384          if ($traitable) {
 385              if ($this->getNode('body') instanceof BodyNode) {
 386                  $nodes = $this->getNode('body')->getNode(0);
 387              } else {
 388                  $nodes = $this->getNode('body');
 389              }
 390   
 391              if (!\count($nodes)) {
 392                  $nodes = new Node([$nodes]);
 393              }
 394   
 395              foreach ($nodes as $node) {
 396                  if (!\count($node)) {
 397                      continue;
 398                  }
 399   
 400                  if ($node instanceof TextNode && ctype_space($node->getAttribute('data'))) {
 401                      continue;
 402                  }
 403   
 404                  if ($node instanceof BlockReferenceNode) {
 405                      continue;
 406                  }
 407   
 408                  $traitable = false;
 409                  break;
 410              }
 411          }
 412   
 413          if ($traitable) {
 414              return;
 415          }
 416   
 417          $compiler
 418              ->write("public function isTraitable()\n", "{\n")
 419              ->indent()
 420              ->write(sprintf("return %s;\n", $traitable ? 'true' : 'false'))
 421              ->outdent()
 422              ->write("}\n\n")
 423          ;
 424      }
 425   
 426      protected function compileDebugInfo(Compiler $compiler)
 427      {
 428          $compiler
 429              ->write("public function getDebugInfo()\n", "{\n")
 430              ->indent()
 431              ->write(sprintf("return %s;\n", str_replace("\n", '', var_export(array_reverse($compiler->getDebugInfo(), true), true))))
 432              ->outdent()
 433              ->write("}\n\n")
 434          ;
 435      }
 436   
 437      protected function compileGetSourceContext(Compiler $compiler)
 438      {
 439          $compiler
 440              ->write("public function getSourceContext()\n", "{\n")
 441              ->indent()
 442              ->write('return new Source(')
 443              ->string($compiler->getEnvironment()->isDebug() ? $this->getSourceContext()->getCode() : '')
 444              ->raw(', ')
 445              ->string($this->getSourceContext()->getName())
 446              ->raw(', ')
 447              ->string($this->getSourceContext()->getPath())
 448              ->raw(");\n")
 449              ->outdent()
 450              ->write("}\n")
 451          ;
 452      }
 453   
 454      protected function compileLoadTemplate(Compiler $compiler, $node, $var)
 455      {
 456          if ($node instanceof ConstantExpression) {
 457              $compiler
 458                  ->write(sprintf('%s = $this->loadTemplate(', $var))
 459                  ->subcompile($node)
 460                  ->raw(', ')
 461                  ->repr($node->getTemplateName())
 462                  ->raw(', ')
 463                  ->repr($node->getTemplateLine())
 464                  ->raw(");\n")
 465              ;
 466          } else {
 467              throw new \LogicException('Trait templates can only be constant nodes.');
 468          }
 469      }
 470  }
 471   
 472  class_alias('Twig\Node\ModuleNode', 'Twig_Node_Module');
 473