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.
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: 09.10.2024, 12:57 - Dateigröße: 20.13 KiB


 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   * Default base class for compiled templates.
 015   *
 016   * @author Fabien Potencier <fabien@symfony.com>
 017   */
 018  abstract class Twig_Template implements Twig_TemplateInterface
 019  {
 020      protected static $cache = array();
 021   
 022      protected $parent;
 023      protected $parents = array();
 024      protected $env;
 025      protected $blocks = array();
 026      protected $traits = array();
 027   
 028      /**
 029       * Constructor.
 030       *
 031       * @param Twig_Environment $env A Twig_Environment instance
 032       */
 033      public function __construct(Twig_Environment $env)
 034      {
 035          $this->env = $env;
 036      }
 037   
 038      /**
 039       * Returns the template name.
 040       *
 041       * @return string The template name
 042       */
 043      abstract public function getTemplateName();
 044   
 045      /**
 046       * @deprecated since 1.20 (to be removed in 2.0)
 047       */
 048      public function getEnvironment()
 049      {
 050          @trigger_error('The '.__METHOD__.' method is deprecated since version 1.20 and will be removed in 2.0.', E_USER_DEPRECATED);
 051   
 052          return $this->env;
 053      }
 054   
 055      /**
 056       * Returns the parent template.
 057       *
 058       * This method is for internal use only and should never be called
 059       * directly.
 060       *
 061       * @param array $context
 062       *
 063       * @return Twig_TemplateInterface|false The parent template or false if there is no parent
 064       *
 065       * @internal
 066       */
 067      public function getParent(array $context)
 068      {
 069          if (null !== $this->parent) {
 070              return $this->parent;
 071          }
 072   
 073          try {
 074              $parent = $this->doGetParent($context);
 075   
 076              if (false === $parent) {
 077                  return false;
 078              }
 079   
 080              if ($parent instanceof self) {
 081                  return $this->parents[$parent->getTemplateName()] = $parent;
 082              }
 083   
 084              if (!isset($this->parents[$parent])) {
 085                  $this->parents[$parent] = $this->loadTemplate($parent);
 086              }
 087          } catch (Twig_Error_Loader $e) {
 088              $e->setTemplateFile(null);
 089              $e->guess();
 090   
 091              throw $e;
 092          }
 093   
 094          return $this->parents[$parent];
 095      }
 096   
 097      protected function doGetParent(array $context)
 098      {
 099          return false;
 100      }
 101   
 102      public function isTraitable()
 103      {
 104          return true;
 105      }
 106   
 107      /**
 108       * Displays a parent block.
 109       *
 110       * This method is for internal use only and should never be called
 111       * directly.
 112       *
 113       * @param string $name    The block name to display from the parent
 114       * @param array  $context The context
 115       * @param array  $blocks  The current set of blocks
 116       *
 117       * @internal
 118       */
 119      public function displayParentBlock($name, array $context, array $blocks = array())
 120      {
 121          $name = (string) $name;
 122   
 123          if (isset($this->traits[$name])) {
 124              $this->traits[$name][0]->displayBlock($name, $context, $blocks, false);
 125          } elseif (false !== $parent = $this->getParent($context)) {
 126              $parent->displayBlock($name, $context, $blocks, false);
 127          } else {
 128              throw new Twig_Error_Runtime(sprintf('The template has no parent and no traits defining the "%s" block', $name), -1, $this->getTemplateName());
 129          }
 130      }
 131   
 132      /**
 133       * Displays a block.
 134       *
 135       * This method is for internal use only and should never be called
 136       * directly.
 137       *
 138       * @param string $name      The block name to display
 139       * @param array  $context   The context
 140       * @param array  $blocks    The current set of blocks
 141       * @param bool   $useBlocks Whether to use the current set of blocks
 142       *
 143       * @internal
 144       */
 145      public function displayBlock($name, array $context, array $blocks = array(), $useBlocks = true)
 146      {
 147          $name = (string) $name;
 148   
 149          if ($useBlocks && isset($blocks[$name])) {
 150              $template = $blocks[$name][0];
 151              $block = $blocks[$name][1];
 152          } elseif (isset($this->blocks[$name])) {
 153              $template = $this->blocks[$name][0];
 154              $block = $this->blocks[$name][1];
 155          } else {
 156              $template = null;
 157              $block = null;
 158          }
 159   
 160          if (null !== $template) {
 161              // avoid RCEs when sandbox is enabled
 162              if (!$template instanceof self) {
 163                  throw new LogicException('A block must be a method on a Twig_Template instance.');
 164              }
 165   
 166              try {
 167                  $template->$block($context, $blocks);
 168              } catch (Twig_Error $e) {
 169                  if (!$e->getTemplateFile()) {
 170                      $e->setTemplateFile($template->getTemplateName());
 171                  }
 172   
 173                  // this is mostly useful for Twig_Error_Loader exceptions
 174                  // see Twig_Error_Loader
 175                  if (false === $e->getTemplateLine()) {
 176                      $e->setTemplateLine(-1);
 177                      $e->guess();
 178                  }
 179   
 180                  throw $e;
 181              } catch (Exception $e) {
 182                  throw new Twig_Error_Runtime(sprintf('An exception has been thrown during the rendering of a template ("%s").', $e->getMessage()), -1, $template->getTemplateName(), $e);
 183              }
 184          } elseif (false !== $parent = $this->getParent($context)) {
 185              $parent->displayBlock($name, $context, array_merge($this->blocks, $blocks), false);
 186          }
 187      }
 188   
 189      /**
 190       * Renders a parent block.
 191       *
 192       * This method is for internal use only and should never be called
 193       * directly.
 194       *
 195       * @param string $name    The block name to render from the parent
 196       * @param array  $context The context
 197       * @param array  $blocks  The current set of blocks
 198       *
 199       * @return string The rendered block
 200       *
 201       * @internal
 202       */
 203      public function renderParentBlock($name, array $context, array $blocks = array())
 204      {
 205          ob_start();
 206          $this->displayParentBlock($name, $context, $blocks);
 207   
 208          return ob_get_clean();
 209      }
 210   
 211      /**
 212       * Renders a block.
 213       *
 214       * This method is for internal use only and should never be called
 215       * directly.
 216       *
 217       * @param string $name      The block name to render
 218       * @param array  $context   The context
 219       * @param array  $blocks    The current set of blocks
 220       * @param bool   $useBlocks Whether to use the current set of blocks
 221       *
 222       * @return string The rendered block
 223       *
 224       * @internal
 225       */
 226      public function renderBlock($name, array $context, array $blocks = array(), $useBlocks = true)
 227      {
 228          ob_start();
 229          $this->displayBlock($name, $context, $blocks, $useBlocks);
 230   
 231          return ob_get_clean();
 232      }
 233   
 234      /**
 235       * Returns whether a block exists or not.
 236       *
 237       * This method is for internal use only and should never be called
 238       * directly.
 239       *
 240       * This method does only return blocks defined in the current template
 241       * or defined in "used" traits.
 242       *
 243       * It does not return blocks from parent templates as the parent
 244       * template name can be dynamic, which is only known based on the
 245       * current context.
 246       *
 247       * @param string $name The block name
 248       *
 249       * @return bool true if the block exists, false otherwise
 250       *
 251       * @internal
 252       */
 253      public function hasBlock($name)
 254      {
 255          return isset($this->blocks[(string) $name]);
 256      }
 257   
 258      /**
 259       * Returns all block names.
 260       *
 261       * This method is for internal use only and should never be called
 262       * directly.
 263       *
 264       * @return array An array of block names
 265       *
 266       * @see hasBlock
 267       *
 268       * @internal
 269       */
 270      public function getBlockNames()
 271      {
 272          return array_keys($this->blocks);
 273      }
 274   
 275      protected function loadTemplate($template, $templateName = null, $line = null, $index = null)
 276      {
 277          try {
 278              if (is_array($template)) {
 279                  return $this->env->resolveTemplate($template);
 280              }
 281   
 282              if ($template instanceof self) {
 283                  return $template;
 284              }
 285   
 286              return $this->env->loadTemplate($template, $index);
 287          } catch (Twig_Error $e) {
 288              if (!$e->getTemplateFile()) {
 289                  $e->setTemplateFile($templateName ? $templateName : $this->getTemplateName());
 290              }
 291   
 292              if ($e->getTemplateLine()) {
 293                  throw $e;
 294              }
 295   
 296              if (!$line) {
 297                  $e->guess();
 298              } else {
 299                  $e->setTemplateLine($line);
 300              }
 301   
 302              throw $e;
 303          }
 304      }
 305   
 306      /**
 307       * Returns all blocks.
 308       *
 309       * This method is for internal use only and should never be called
 310       * directly.
 311       *
 312       * @return array An array of blocks
 313       *
 314       * @see hasBlock
 315       *
 316       * @internal
 317       */
 318      public function getBlocks()
 319      {
 320          return $this->blocks;
 321      }
 322   
 323      /**
 324       * Returns the template source code.
 325       *
 326       * @return string|null The template source code or null if it is not available
 327       */
 328      public function getSource()
 329      {
 330          $reflector = new ReflectionClass($this);
 331          $file = $reflector->getFileName();
 332   
 333          if (!file_exists($file)) {
 334              return;
 335          }
 336   
 337          $source = file($file, FILE_IGNORE_NEW_LINES);
 338          array_splice($source, 0, $reflector->getEndLine());
 339   
 340          $i = 0;
 341          while (isset($source[$i]) && '/* */' === substr_replace($source[$i], '', 3, -2)) {
 342              $source[$i] = str_replace('*//* ', '*/', substr($source[$i], 3, -2));
 343              ++$i;
 344          }
 345          array_splice($source, $i);
 346   
 347          return implode("\n", $source);
 348      }
 349   
 350      /**
 351       * {@inheritdoc}
 352       */
 353      public function display(array $context, array $blocks = array())
 354      {
 355          $this->displayWithErrorHandling($this->env->mergeGlobals($context), array_merge($this->blocks, $blocks));
 356      }
 357   
 358      /**
 359       * {@inheritdoc}
 360       */
 361      public function render(array $context)
 362      {
 363          $level = ob_get_level();
 364          ob_start();
 365          try {
 366              $this->display($context);
 367          } catch (Exception $e) {
 368              while (ob_get_level() > $level) {
 369                  ob_end_clean();
 370              }
 371   
 372              throw $e;
 373          } catch (Throwable $e) {
 374              while (ob_get_level() > $level) {
 375                  ob_end_clean();
 376              }
 377   
 378              throw $e;
 379          }
 380   
 381          return ob_get_clean();
 382      }
 383   
 384      protected function displayWithErrorHandling(array $context, array $blocks = array())
 385      {
 386          try {
 387              $this->doDisplay($context, $blocks);
 388          } catch (Twig_Error $e) {
 389              if (!$e->getTemplateFile()) {
 390                  $e->setTemplateFile($this->getTemplateName());
 391              }
 392   
 393              // this is mostly useful for Twig_Error_Loader exceptions
 394              // see Twig_Error_Loader
 395              if (false === $e->getTemplateLine()) {
 396                  $e->setTemplateLine(-1);
 397                  $e->guess();
 398              }
 399   
 400              throw $e;
 401          } catch (Exception $e) {
 402              throw new Twig_Error_Runtime(sprintf('An exception has been thrown during the rendering of a template ("%s").', $e->getMessage()), -1, $this->getTemplateName(), $e);
 403          }
 404      }
 405   
 406      /**
 407       * Auto-generated method to display the template with the given context.
 408       *
 409       * @param array $context An array of parameters to pass to the template
 410       * @param array $blocks  An array of blocks to pass to the template
 411       */
 412      abstract protected function doDisplay(array $context, array $blocks = array());
 413   
 414      /**
 415       * Returns a variable from the context.
 416       *
 417       * This method is for internal use only and should never be called
 418       * directly.
 419       *
 420       * This method should not be overridden in a sub-class as this is an
 421       * implementation detail that has been introduced to optimize variable
 422       * access for versions of PHP before 5.4. This is not a way to override
 423       * the way to get a variable value.
 424       *
 425       * @param array  $context           The context
 426       * @param string $item              The variable to return from the context
 427       * @param bool   $ignoreStrictCheck Whether to ignore the strict variable check or not
 428       *
 429       * @return mixed The content of the context variable
 430       *
 431       * @throws Twig_Error_Runtime if the variable does not exist and Twig is running in strict mode
 432       *
 433       * @internal
 434       */
 435      final protected function getContext($context, $item, $ignoreStrictCheck = false)
 436      {
 437          if (!array_key_exists($item, $context)) {
 438              if ($ignoreStrictCheck || !$this->env->isStrictVariables()) {
 439                  return;
 440              }
 441   
 442              throw new Twig_Error_Runtime(sprintf('Variable "%s" does not exist', $item), -1, $this->getTemplateName());
 443          }
 444   
 445          return $context[$item];
 446      }
 447   
 448      /**
 449       * Returns the attribute value for a given array/object.
 450       *
 451       * @param mixed  $object            The object or array from where to get the item
 452       * @param mixed  $item              The item to get from the array or object
 453       * @param array  $arguments         An array of arguments to pass if the item is an object method
 454       * @param string $type              The type of attribute (@see Twig_Template constants)
 455       * @param bool   $isDefinedTest     Whether this is only a defined check
 456       * @param bool   $ignoreStrictCheck Whether to ignore the strict attribute check or not
 457       *
 458       * @return mixed The attribute value, or a Boolean when $isDefinedTest is true, or null when the attribute is not set and $ignoreStrictCheck is true
 459       *
 460       * @throws Twig_Error_Runtime if the attribute does not exist and Twig is running in strict mode and $isDefinedTest is false
 461       */
 462      protected function getAttribute($object, $item, array $arguments = array(), $type = self::ANY_CALL, $isDefinedTest = false, $ignoreStrictCheck = false)
 463      {
 464          // array
 465          if (self::METHOD_CALL !== $type) {
 466              $arrayItem = is_bool($item) || is_float($item) ? (int) $item : $item;
 467   
 468              if ((is_array($object) && array_key_exists($arrayItem, $object))
 469                  || ($object instanceof ArrayAccess && isset($object[$arrayItem]))
 470              ) {
 471                  if ($isDefinedTest) {
 472                      return true;
 473                  }
 474   
 475                  return $object[$arrayItem];
 476              }
 477   
 478              if (self::ARRAY_CALL === $type || !is_object($object)) {
 479                  if ($isDefinedTest) {
 480                      return false;
 481                  }
 482   
 483                  if ($ignoreStrictCheck || !$this->env->isStrictVariables()) {
 484                      return;
 485                  }
 486   
 487                  if ($object instanceof ArrayAccess) {
 488                      $message = sprintf('Key "%s" in object with ArrayAccess of class "%s" does not exist', $arrayItem, get_class($object));
 489                  } elseif (is_object($object)) {
 490                      $message = sprintf('Impossible to access a key "%s" on an object of class "%s" that does not implement ArrayAccess interface', $item, get_class($object));
 491                  } elseif (is_array($object)) {
 492                      if (empty($object)) {
 493                          $message = sprintf('Key "%s" does not exist as the array is empty', $arrayItem);
 494                      } else {
 495                          $message = sprintf('Key "%s" for array with keys "%s" does not exist', $arrayItem, implode(', ', array_keys($object)));
 496                      }
 497                  } elseif (self::ARRAY_CALL === $type) {
 498                      if (null === $object) {
 499                          $message = sprintf('Impossible to access a key ("%s") on a null variable', $item);
 500                      } else {
 501                          $message = sprintf('Impossible to access a key ("%s") on a %s variable ("%s")', $item, gettype($object), $object);
 502                      }
 503                  } elseif (null === $object) {
 504                      $message = sprintf('Impossible to access an attribute ("%s") on a null variable', $item);
 505                  } else {
 506                      $message = sprintf('Impossible to access an attribute ("%s") on a %s variable ("%s")', $item, gettype($object), $object);
 507                  }
 508   
 509                  throw new Twig_Error_Runtime($message, -1, $this->getTemplateName());
 510              }
 511          }
 512   
 513          if (!is_object($object)) {
 514              if ($isDefinedTest) {
 515                  return false;
 516              }
 517   
 518              if ($ignoreStrictCheck || !$this->env->isStrictVariables()) {
 519                  return;
 520              }
 521   
 522              if (null === $object) {
 523                  $message = sprintf('Impossible to invoke a method ("%s") on a null variable', $item);
 524              } else {
 525                  $message = sprintf('Impossible to invoke a method ("%s") on a %s variable ("%s")', $item, gettype($object), $object);
 526              }
 527   
 528              throw new Twig_Error_Runtime($message, -1, $this->getTemplateName());
 529          }
 530   
 531          // object property
 532          if (self::METHOD_CALL !== $type && !$object instanceof self) { // Twig_Template does not have public properties, and we don't want to allow access to internal ones
 533              if (isset($object->$item) || array_key_exists((string) $item, $object)) {
 534                  if ($isDefinedTest) {
 535                      return true;
 536                  }
 537   
 538                  if ($this->env->hasExtension('sandbox')) {
 539                      $this->env->getExtension('sandbox')->checkPropertyAllowed($object, $item);
 540                  }
 541   
 542                  return $object->$item;
 543              }
 544          }
 545   
 546          $class = get_class($object);
 547   
 548          // object method
 549          if (!isset(self::$cache[$class]['methods'])) {
 550              // get_class_methods returns all methods accessible in the scope, but we only want public ones to be accessible in templates
 551              if ($object instanceof self) {
 552                  $ref = new ReflectionClass($class);
 553                  $methods = array();
 554   
 555                  foreach ($ref->getMethods(ReflectionMethod::IS_PUBLIC) as $refMethod) {
 556                      $methodName = strtolower($refMethod->name);
 557   
 558                      // Accessing the environment from templates is forbidden to prevent untrusted changes to the environment
 559                      if ('getenvironment' !== $methodName) {
 560                          $methods[$methodName] = true;
 561                      }
 562                  }
 563   
 564                  self::$cache[$class]['methods'] = $methods;
 565              } else {
 566                  self::$cache[$class]['methods'] = array_change_key_case(array_flip(get_class_methods($object)));
 567              }
 568          }
 569   
 570          $call = false;
 571          $lcItem = strtolower($item);
 572          if (isset(self::$cache[$class]['methods'][$lcItem])) {
 573              $method = (string) $item;
 574          } elseif (isset(self::$cache[$class]['methods']['get'.$lcItem])) {
 575              $method = 'get'.$item;
 576          } elseif (isset(self::$cache[$class]['methods']['is'.$lcItem])) {
 577              $method = 'is'.$item;
 578          } elseif (isset(self::$cache[$class]['methods']['__call'])) {
 579              $method = (string) $item;
 580              $call = true;
 581          } else {
 582              if ($isDefinedTest) {
 583                  return false;
 584              }
 585   
 586              if ($ignoreStrictCheck || !$this->env->isStrictVariables()) {
 587                  return;
 588              }
 589   
 590              throw new Twig_Error_Runtime(sprintf('Neither the property "%1$s" nor one of the methods "%1$s()", "get%1$s()"/"is%1$s()" or "__call()" exist and have public access in class "%2$s"', $item, get_class($object)), -1, $this->getTemplateName());
 591          }
 592   
 593          if ($isDefinedTest) {
 594              return true;
 595          }
 596   
 597          if ($this->env->hasExtension('sandbox')) {
 598              $this->env->getExtension('sandbox')->checkMethodAllowed($object, $method);
 599          }
 600   
 601          // Some objects throw exceptions when they have __call, and the method we try
 602          // to call is not supported. If ignoreStrictCheck is true, we should return null.
 603          try {
 604              $ret = call_user_func_array(array($object, $method), $arguments);
 605          } catch (BadMethodCallException $e) {
 606              if ($call && ($ignoreStrictCheck || !$this->env->isStrictVariables())) {
 607                  return;
 608              }
 609              throw $e;
 610          }
 611   
 612          // useful when calling a template method from a template
 613          // this is not supported but unfortunately heavily used in the Symfony profiler
 614          if ($object instanceof Twig_TemplateInterface) {
 615              return $ret === '' ? '' : new Twig_Markup($ret, $this->env->getCharset());
 616          }
 617   
 618          return $ret;
 619      }
 620  }
 621