Verzeichnisstruktur phpBB-3.1.0


Veröffentlicht
27.10.2014

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

Parser.php

Zuletzt modifiziert: 09.10.2024, 12:57 - Dateigröße: 11.62 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 parser implementation.
 015   *
 016   * @author Fabien Potencier <fabien@symfony.com>
 017   */
 018  class Twig_Parser implements Twig_ParserInterface
 019  {
 020      protected $stack = array();
 021      protected $stream;
 022      protected $parent;
 023      protected $handlers;
 024      protected $visitors;
 025      protected $expressionParser;
 026      protected $blocks;
 027      protected $blockStack;
 028      protected $macros;
 029      protected $env;
 030      protected $reservedMacroNames;
 031      protected $importedSymbols;
 032      protected $traits;
 033      protected $embeddedTemplates = array();
 034   
 035      /**
 036       * Constructor.
 037       *
 038       * @param Twig_Environment $env A Twig_Environment instance
 039       */
 040      public function __construct(Twig_Environment $env)
 041      {
 042          $this->env = $env;
 043      }
 044   
 045      public function getEnvironment()
 046      {
 047          return $this->env;
 048      }
 049   
 050      public function getVarName()
 051      {
 052          return sprintf('__internal_%s', hash('sha1', uniqid(mt_rand(), true), false));
 053      }
 054   
 055      public function getFilename()
 056      {
 057          return $this->stream->getFilename();
 058      }
 059   
 060      /**
 061       * Converts a token stream to a node tree.
 062       *
 063       * @param Twig_TokenStream $stream A token stream instance
 064       *
 065       * @return Twig_Node_Module A node tree
 066       */
 067      public function parse(Twig_TokenStream $stream, $test = null, $dropNeedle = false)
 068      {
 069          // push all variables into the stack to keep the current state of the parser
 070          $vars = get_object_vars($this);
 071          unset($vars['stack'], $vars['env'], $vars['handlers'], $vars['visitors'], $vars['expressionParser']);
 072          $this->stack[] = $vars;
 073   
 074          // tag handlers
 075          if (null === $this->handlers) {
 076              $this->handlers = $this->env->getTokenParsers();
 077              $this->handlers->setParser($this);
 078          }
 079   
 080          // node visitors
 081          if (null === $this->visitors) {
 082              $this->visitors = $this->env->getNodeVisitors();
 083          }
 084   
 085          if (null === $this->expressionParser) {
 086              $this->expressionParser = new Twig_ExpressionParser($this, $this->env->getUnaryOperators(), $this->env->getBinaryOperators());
 087          }
 088   
 089          $this->stream = $stream;
 090          $this->parent = null;
 091          $this->blocks = array();
 092          $this->macros = array();
 093          $this->traits = array();
 094          $this->blockStack = array();
 095          $this->importedSymbols = array(array());
 096          $this->embeddedTemplates = array();
 097   
 098          try {
 099              $body = $this->subparse($test, $dropNeedle);
 100   
 101              if (null !== $this->parent) {
 102                  if (null === $body = $this->filterBodyNodes($body)) {
 103                      $body = new Twig_Node();
 104                  }
 105              }
 106          } catch (Twig_Error_Syntax $e) {
 107              if (!$e->getTemplateFile()) {
 108                  $e->setTemplateFile($this->getFilename());
 109              }
 110   
 111              if (!$e->getTemplateLine()) {
 112                  $e->setTemplateLine($this->stream->getCurrent()->getLine());
 113              }
 114   
 115              throw $e;
 116          }
 117   
 118          $node = new Twig_Node_Module(new Twig_Node_Body(array($body)), $this->parent, new Twig_Node($this->blocks), new Twig_Node($this->macros), new Twig_Node($this->traits), $this->embeddedTemplates, $this->getFilename());
 119   
 120          $traverser = new Twig_NodeTraverser($this->env, $this->visitors);
 121   
 122          $node = $traverser->traverse($node);
 123   
 124          // restore previous stack so previous parse() call can resume working
 125          foreach (array_pop($this->stack) as $key => $val) {
 126              $this->$key = $val;
 127          }
 128   
 129          return $node;
 130      }
 131   
 132      public function subparse($test, $dropNeedle = false)
 133      {
 134          $lineno = $this->getCurrentToken()->getLine();
 135          $rv = array();
 136          while (!$this->stream->isEOF()) {
 137              switch ($this->getCurrentToken()->getType()) {
 138                  case Twig_Token::TEXT_TYPE:
 139                      $token = $this->stream->next();
 140                      $rv[] = new Twig_Node_Text($token->getValue(), $token->getLine());
 141                      break;
 142   
 143                  case Twig_Token::VAR_START_TYPE:
 144                      $token = $this->stream->next();
 145                      $expr = $this->expressionParser->parseExpression();
 146                      $this->stream->expect(Twig_Token::VAR_END_TYPE);
 147                      $rv[] = new Twig_Node_Print($expr, $token->getLine());
 148                      break;
 149   
 150                  case Twig_Token::BLOCK_START_TYPE:
 151                      $this->stream->next();
 152                      $token = $this->getCurrentToken();
 153   
 154                      if ($token->getType() !== Twig_Token::NAME_TYPE) {
 155                          throw new Twig_Error_Syntax('A block must start with a tag name', $token->getLine(), $this->getFilename());
 156                      }
 157   
 158                      if (null !== $test && call_user_func($test, $token)) {
 159                          if ($dropNeedle) {
 160                              $this->stream->next();
 161                          }
 162   
 163                          if (1 === count($rv)) {
 164                              return $rv[0];
 165                          }
 166   
 167                          return new Twig_Node($rv, array(), $lineno);
 168                      }
 169   
 170                      $subparser = $this->handlers->getTokenParser($token->getValue());
 171                      if (null === $subparser) {
 172                          if (null !== $test) {
 173                              $error = sprintf('Unexpected tag name "%s"', $token->getValue());
 174                              if (is_array($test) && isset($test[0]) && $test[0] instanceof Twig_TokenParserInterface) {
 175                                  $error .= sprintf(' (expecting closing tag for the "%s" tag defined near line %s)', $test[0]->getTag(), $lineno);
 176                              }
 177   
 178                              throw new Twig_Error_Syntax($error, $token->getLine(), $this->getFilename());
 179                          }
 180   
 181                          $message = sprintf('Unknown tag name "%s"', $token->getValue());
 182                          if ($alternatives = $this->env->computeAlternatives($token->getValue(), array_keys($this->env->getTags()))) {
 183                              $message = sprintf('%s. Did you mean "%s"', $message, implode('", "', $alternatives));
 184                          }
 185   
 186                          throw new Twig_Error_Syntax($message, $token->getLine(), $this->getFilename());
 187                      }
 188   
 189                      $this->stream->next();
 190   
 191                      $node = $subparser->parse($token);
 192                      if (null !== $node) {
 193                          $rv[] = $node;
 194                      }
 195                      break;
 196   
 197                  default:
 198                      throw new Twig_Error_Syntax('Lexer or parser ended up in unsupported state.', 0, $this->getFilename());
 199              }
 200          }
 201   
 202          if (1 === count($rv)) {
 203              return $rv[0];
 204          }
 205   
 206          return new Twig_Node($rv, array(), $lineno);
 207      }
 208   
 209      public function addHandler($name, $class)
 210      {
 211          $this->handlers[$name] = $class;
 212      }
 213   
 214      public function addNodeVisitor(Twig_NodeVisitorInterface $visitor)
 215      {
 216          $this->visitors[] = $visitor;
 217      }
 218   
 219      public function getBlockStack()
 220      {
 221          return $this->blockStack;
 222      }
 223   
 224      public function peekBlockStack()
 225      {
 226          return $this->blockStack[count($this->blockStack) - 1];
 227      }
 228   
 229      public function popBlockStack()
 230      {
 231          array_pop($this->blockStack);
 232      }
 233   
 234      public function pushBlockStack($name)
 235      {
 236          $this->blockStack[] = $name;
 237      }
 238   
 239      public function hasBlock($name)
 240      {
 241          return isset($this->blocks[$name]);
 242      }
 243   
 244      public function getBlock($name)
 245      {
 246          return $this->blocks[$name];
 247      }
 248   
 249      public function setBlock($name, $value)
 250      {
 251          $this->blocks[$name] = new Twig_Node_Body(array($value), array(), $value->getLine());
 252      }
 253   
 254      public function hasMacro($name)
 255      {
 256          return isset($this->macros[$name]);
 257      }
 258   
 259      public function setMacro($name, Twig_Node_Macro $node)
 260      {
 261          if (null === $this->reservedMacroNames) {
 262              $this->reservedMacroNames = array();
 263              $r = new ReflectionClass($this->env->getBaseTemplateClass());
 264              foreach ($r->getMethods() as $method) {
 265                  $this->reservedMacroNames[] = $method->getName();
 266              }
 267          }
 268   
 269          if (in_array($name, $this->reservedMacroNames)) {
 270              throw new Twig_Error_Syntax(sprintf('"%s" cannot be used as a macro name as it is a reserved keyword', $name), $node->getLine(), $this->getFilename());
 271          }
 272   
 273          $this->macros[$name] = $node;
 274      }
 275   
 276      public function addTrait($trait)
 277      {
 278          $this->traits[] = $trait;
 279      }
 280   
 281      public function hasTraits()
 282      {
 283          return count($this->traits) > 0;
 284      }
 285   
 286      public function embedTemplate(Twig_Node_Module $template)
 287      {
 288          $template->setIndex(mt_rand());
 289   
 290          $this->embeddedTemplates[] = $template;
 291      }
 292   
 293      public function addImportedSymbol($type, $alias, $name = null, Twig_Node_Expression $node = null)
 294      {
 295          $this->importedSymbols[0][$type][$alias] = array('name' => $name, 'node' => $node);
 296      }
 297   
 298      public function getImportedSymbol($type, $alias)
 299      {
 300          foreach ($this->importedSymbols as $functions) {
 301              if (isset($functions[$type][$alias])) {
 302                  return $functions[$type][$alias];
 303              }
 304          }
 305      }
 306   
 307      public function isMainScope()
 308      {
 309          return 1 === count($this->importedSymbols);
 310      }
 311   
 312      public function pushLocalScope()
 313      {
 314          array_unshift($this->importedSymbols, array());
 315      }
 316   
 317      public function popLocalScope()
 318      {
 319          array_shift($this->importedSymbols);
 320      }
 321   
 322      /**
 323       * Gets the expression parser.
 324       *
 325       * @return Twig_ExpressionParser The expression parser
 326       */
 327      public function getExpressionParser()
 328      {
 329          return $this->expressionParser;
 330      }
 331   
 332      public function getParent()
 333      {
 334          return $this->parent;
 335      }
 336   
 337      public function setParent($parent)
 338      {
 339          $this->parent = $parent;
 340      }
 341   
 342      /**
 343       * Gets the token stream.
 344       *
 345       * @return Twig_TokenStream The token stream
 346       */
 347      public function getStream()
 348      {
 349          return $this->stream;
 350      }
 351   
 352      /**
 353       * Gets the current token.
 354       *
 355       * @return Twig_Token The current token
 356       */
 357      public function getCurrentToken()
 358      {
 359          return $this->stream->getCurrent();
 360      }
 361   
 362      protected function filterBodyNodes(Twig_NodeInterface $node)
 363      {
 364          // check that the body does not contain non-empty output nodes
 365          if (
 366              ($node instanceof Twig_Node_Text && !ctype_space($node->getAttribute('data')))
 367              ||
 368              (!$node instanceof Twig_Node_Text && !$node instanceof Twig_Node_BlockReference && $node instanceof Twig_NodeOutputInterface)
 369          ) {
 370              if (false !== strpos((string) $node, chr(0xEF).chr(0xBB).chr(0xBF))) {
 371                  throw new Twig_Error_Syntax('A template that extends another one cannot have a body but a byte order mark (BOM) has been detected; it must be removed.', $node->getLine(), $this->getFilename());
 372              }
 373   
 374              throw new Twig_Error_Syntax('A template that extends another one cannot have a body.', $node->getLine(), $this->getFilename());
 375          }
 376   
 377          // bypass "set" nodes as they "capture" the output
 378          if ($node instanceof Twig_Node_Set) {
 379              return $node;
 380          }
 381   
 382          if ($node instanceof Twig_NodeOutputInterface) {
 383              return;
 384          }
 385   
 386          foreach ($node as $k => $n) {
 387              if (null !== $n && null === $n = $this->filterBodyNodes($n)) {
 388                  $node->removeNode($k);
 389              }
 390          }
 391   
 392          return $node;
 393      }
 394  }
 395