[ Index ]

PHP Cross Reference of phpBB-3.2.11-deutsch

title

Body

[close]

/vendor/twig/twig/src/Node/ -> ModuleNode.php (source)

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


Generated: Wed Nov 11 20:33:01 2020 Cross-referenced by PHPXref 0.7.1