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

Template.php

Zuletzt modifiziert: 01.05.2026, 11:26 - Dateigröße: 12.83 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;
 014   
 015  use Twig\Error\Error;
 016  use Twig\Error\LoaderError;
 017  use Twig\Error\RuntimeError;
 018   
 019  /**
 020   * Default base class for compiled templates.
 021   *
 022   * This class is an implementation detail of how template compilation currently
 023   * works, which might change. It should never be used directly. Use $twig->load()
 024   * instead, which returns an instance of \Twig\TemplateWrapper.
 025   *
 026   * @author Fabien Potencier <fabien@symfony.com>
 027   *
 028   * @internal
 029   */
 030  abstract class Template
 031  {
 032      public const ANY_CALL = 'any';
 033      public const ARRAY_CALL = 'array';
 034      public const METHOD_CALL = 'method';
 035   
 036      protected $parent;
 037      protected $parents = [];
 038      protected $env;
 039      protected $blocks = [];
 040      protected $traits = [];
 041      protected $extensions = [];
 042      protected $sandbox;
 043   
 044      public function __construct(Environment $env)
 045      {
 046          $this->env = $env;
 047          $this->extensions = $env->getExtensions();
 048      }
 049   
 050      /**
 051       * @internal this method will be removed in 3.0 and is only used internally to provide an upgrade path from 1.x to 2.0
 052       */
 053      public function __toString()
 054      {
 055          return $this->getTemplateName();
 056      }
 057   
 058      /**
 059       * Returns the template name.
 060       *
 061       * @return string The template name
 062       */
 063      abstract public function getTemplateName();
 064   
 065      /**
 066       * Returns debug information about the template.
 067       *
 068       * @return array Debug information
 069       */
 070      abstract public function getDebugInfo();
 071   
 072      /**
 073       * Returns information about the original template source code.
 074       *
 075       * @return Source
 076       */
 077      public function getSourceContext()
 078      {
 079          return new Source('', $this->getTemplateName());
 080      }
 081   
 082      /**
 083       * Returns the parent template.
 084       *
 085       * This method is for internal use only and should never be called
 086       * directly.
 087       *
 088       * @return Template|TemplateWrapper|false The parent template or false if there is no parent
 089       */
 090      public function getParent(array $context)
 091      {
 092          if (null !== $this->parent) {
 093              return $this->parent;
 094          }
 095   
 096          try {
 097              $parent = $this->doGetParent($context);
 098   
 099              if (false === $parent) {
 100                  return false;
 101              }
 102   
 103              if ($parent instanceof self || $parent instanceof TemplateWrapper) {
 104                  return $this->parents[$parent->getSourceContext()->getName()] = $parent;
 105              }
 106   
 107              if (!isset($this->parents[$parent])) {
 108                  $this->parents[$parent] = $this->loadTemplate($parent);
 109              }
 110          } catch (LoaderError $e) {
 111              $e->setSourceContext(null);
 112              $e->guess();
 113   
 114              throw $e;
 115          }
 116   
 117          return $this->parents[$parent];
 118      }
 119   
 120      protected function doGetParent(array $context)
 121      {
 122          return false;
 123      }
 124   
 125      public function isTraitable()
 126      {
 127          return true;
 128      }
 129   
 130      /**
 131       * Displays a parent block.
 132       *
 133       * This method is for internal use only and should never be called
 134       * directly.
 135       *
 136       * @param string $name    The block name to display from the parent
 137       * @param array  $context The context
 138       * @param array  $blocks  The current set of blocks
 139       */
 140      public function displayParentBlock($name, array $context, array $blocks = [])
 141      {
 142          if (isset($this->traits[$name])) {
 143              $this->traits[$name][0]->displayBlock($name, $context, $blocks, false);
 144          } elseif (false !== $parent = $this->getParent($context)) {
 145              $parent->displayBlock($name, $context, $blocks, false);
 146          } else {
 147              throw new RuntimeError(sprintf('The template has no parent and no traits defining the "%s" block.', $name), -1, $this->getSourceContext());
 148          }
 149      }
 150   
 151      /**
 152       * Displays a block.
 153       *
 154       * This method is for internal use only and should never be called
 155       * directly.
 156       *
 157       * @param string $name      The block name to display
 158       * @param array  $context   The context
 159       * @param array  $blocks    The current set of blocks
 160       * @param bool   $useBlocks Whether to use the current set of blocks
 161       */
 162      public function displayBlock($name, array $context, array $blocks = [], $useBlocks = true, self $templateContext = null)
 163      {
 164          if ($useBlocks && isset($blocks[$name])) {
 165              $template = $blocks[$name][0];
 166              $block = $blocks[$name][1];
 167          } elseif (isset($this->blocks[$name])) {
 168              $template = $this->blocks[$name][0];
 169              $block = $this->blocks[$name][1];
 170          } else {
 171              $template = null;
 172              $block = null;
 173          }
 174   
 175          // avoid RCEs when sandbox is enabled
 176          if (null !== $template && !$template instanceof self) {
 177              throw new \LogicException('A block must be a method on a \Twig\Template instance.');
 178          }
 179   
 180          if (null !== $template) {
 181              try {
 182                  $template->$block($context, $blocks);
 183              } catch (Error $e) {
 184                  if (!$e->getSourceContext()) {
 185                      $e->setSourceContext($template->getSourceContext());
 186                  }
 187   
 188                  // this is mostly useful for \Twig\Error\LoaderError exceptions
 189                  // see \Twig\Error\LoaderError
 190                  if (-1 === $e->getTemplateLine()) {
 191                      $e->guess();
 192                  }
 193   
 194                  throw $e;
 195              } catch (\Exception $e) {
 196                  $e = new RuntimeError(sprintf('An exception has been thrown during the rendering of a template ("%s").', $e->getMessage()), -1, $template->getSourceContext(), $e);
 197                  $e->guess();
 198   
 199                  throw $e;
 200              }
 201          } elseif (false !== $parent = $this->getParent($context)) {
 202              $parent->displayBlock($name, $context, array_merge($this->blocks, $blocks), false, $templateContext ?? $this);
 203          } elseif (isset($blocks[$name])) {
 204              throw new RuntimeError(sprintf('Block "%s" should not call parent() in "%s" as the block does not exist in the parent template "%s".', $name, $blocks[$name][0]->getTemplateName(), $this->getTemplateName()), -1, $blocks[$name][0]->getSourceContext());
 205          } else {
 206              throw new RuntimeError(sprintf('Block "%s" on template "%s" does not exist.', $name, $this->getTemplateName()), -1, ($templateContext ?? $this)->getSourceContext());
 207          }
 208      }
 209   
 210      /**
 211       * Renders a parent block.
 212       *
 213       * This method is for internal use only and should never be called
 214       * directly.
 215       *
 216       * @param string $name    The block name to render from the parent
 217       * @param array  $context The context
 218       * @param array  $blocks  The current set of blocks
 219       *
 220       * @return string The rendered block
 221       */
 222      public function renderParentBlock($name, array $context, array $blocks = [])
 223      {
 224          if ($this->env->isDebug()) {
 225              ob_start();
 226          } else {
 227              ob_start(function () { return ''; });
 228          }
 229          $this->displayParentBlock($name, $context, $blocks);
 230   
 231          return ob_get_clean();
 232      }
 233   
 234      /**
 235       * Renders a block.
 236       *
 237       * This method is for internal use only and should never be called
 238       * directly.
 239       *
 240       * @param string $name      The block name to render
 241       * @param array  $context   The context
 242       * @param array  $blocks    The current set of blocks
 243       * @param bool   $useBlocks Whether to use the current set of blocks
 244       *
 245       * @return string The rendered block
 246       */
 247      public function renderBlock($name, array $context, array $blocks = [], $useBlocks = true)
 248      {
 249          if ($this->env->isDebug()) {
 250              ob_start();
 251          } else {
 252              ob_start(function () { return ''; });
 253          }
 254          $this->displayBlock($name, $context, $blocks, $useBlocks);
 255   
 256          return ob_get_clean();
 257      }
 258   
 259      /**
 260       * Returns whether a block exists or not in the current context of the template.
 261       *
 262       * This method checks blocks defined in the current template
 263       * or defined in "used" traits or defined in parent templates.
 264       *
 265       * @param string $name    The block name
 266       * @param array  $context The context
 267       * @param array  $blocks  The current set of blocks
 268       *
 269       * @return bool true if the block exists, false otherwise
 270       */
 271      public function hasBlock($name, array $context, array $blocks = [])
 272      {
 273          if (isset($blocks[$name])) {
 274              return $blocks[$name][0] instanceof self;
 275          }
 276   
 277          if (isset($this->blocks[$name])) {
 278              return true;
 279          }
 280   
 281          if (false !== $parent = $this->getParent($context)) {
 282              return $parent->hasBlock($name, $context);
 283          }
 284   
 285          return false;
 286      }
 287   
 288      /**
 289       * Returns all block names in the current context of the template.
 290       *
 291       * This method checks blocks defined in the current template
 292       * or defined in "used" traits or defined in parent templates.
 293       *
 294       * @param array $context The context
 295       * @param array $blocks  The current set of blocks
 296       *
 297       * @return array An array of block names
 298       */
 299      public function getBlockNames(array $context, array $blocks = [])
 300      {
 301          $names = array_merge(array_keys($blocks), array_keys($this->blocks));
 302   
 303          if (false !== $parent = $this->getParent($context)) {
 304              $names = array_merge($names, $parent->getBlockNames($context));
 305          }
 306   
 307          return array_unique($names);
 308      }
 309   
 310      /**
 311       * @return Template|TemplateWrapper
 312       */
 313      protected function loadTemplate($template, $templateName = null, $line = null, $index = null)
 314      {
 315          try {
 316              if (\is_array($template)) {
 317                  return $this->env->resolveTemplate($template);
 318              }
 319   
 320              if ($template instanceof self || $template instanceof TemplateWrapper) {
 321                  return $template;
 322              }
 323   
 324              if ($template === $this->getTemplateName()) {
 325                  $class = static::class;
 326                  if (false !== $pos = strrpos($class, '___', -1)) {
 327                      $class = substr($class, 0, $pos);
 328                  }
 329   
 330                  return $this->env->loadClass($class, $template, $index);
 331              }
 332   
 333              return $this->env->loadTemplate($template, $index);
 334          } catch (Error $e) {
 335              if (!$e->getSourceContext()) {
 336                  $e->setSourceContext($templateName ? new Source('', $templateName) : $this->getSourceContext());
 337              }
 338   
 339              if ($e->getTemplateLine() > 0) {
 340                  throw $e;
 341              }
 342   
 343              if (!$line) {
 344                  $e->guess();
 345              } else {
 346                  $e->setTemplateLine($line);
 347              }
 348   
 349              throw $e;
 350          }
 351      }
 352   
 353      /**
 354       * @internal
 355       *
 356       * @return Template
 357       */
 358      public function unwrap()
 359      {
 360          return $this;
 361      }
 362   
 363      /**
 364       * Returns all blocks.
 365       *
 366       * This method is for internal use only and should never be called
 367       * directly.
 368       *
 369       * @return array An array of blocks
 370       */
 371      public function getBlocks()
 372      {
 373          return $this->blocks;
 374      }
 375   
 376      public function display(array $context, array $blocks = [])
 377      {
 378          $this->displayWithErrorHandling($this->env->mergeGlobals($context), array_merge($this->blocks, $blocks));
 379      }
 380   
 381      public function render(array $context)
 382      {
 383          $level = ob_get_level();
 384          if ($this->env->isDebug()) {
 385              ob_start();
 386          } else {
 387              ob_start(function () { return ''; });
 388          }
 389          try {
 390              $this->display($context);
 391          } catch (\Throwable $e) {
 392              while (ob_get_level() > $level) {
 393                  ob_end_clean();
 394              }
 395   
 396              throw $e;
 397          }
 398   
 399          return ob_get_clean();
 400      }
 401   
 402      protected function displayWithErrorHandling(array $context, array $blocks = [])
 403      {
 404          try {
 405              $this->doDisplay($context, $blocks);
 406          } catch (Error $e) {
 407              if (!$e->getSourceContext()) {
 408                  $e->setSourceContext($this->getSourceContext());
 409              }
 410   
 411              // this is mostly useful for \Twig\Error\LoaderError exceptions
 412              // see \Twig\Error\LoaderError
 413              if (-1 === $e->getTemplateLine()) {
 414                  $e->guess();
 415              }
 416   
 417              throw $e;
 418          } catch (\Exception $e) {
 419              $e = new RuntimeError(sprintf('An exception has been thrown during the rendering of a template ("%s").', $e->getMessage()), -1, $this->getSourceContext(), $e);
 420              $e->guess();
 421   
 422              throw $e;
 423          }
 424      }
 425   
 426      /**
 427       * Auto-generated method to display the template with the given context.
 428       *
 429       * @param array $context An array of parameters to pass to the template
 430       * @param array $blocks  An array of blocks to pass to the template
 431       */
 432      abstract protected function doDisplay(array $context, array $blocks = []);
 433  }
 434   
 435  class_alias('Twig\Template', 'Twig_Template');
 436