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