[ Index ]

PHP Cross Reference of phpBB-3.1.12-deutsch

title

Body

[close]

/vendor/twig/twig/lib/Twig/ -> ExpressionParser.php (source)

   1  <?php
   2  
   3  /*
   4   * This file is part of Twig.
   5   *
   6   * (c) 2009 Fabien Potencier
   7   * (c) 2009 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  /**
  14   * Parses expressions.
  15   *
  16   * This parser implements a "Precedence climbing" algorithm.
  17   *
  18   * @see http://www.engr.mun.ca/~theo/Misc/exp_parsing.htm
  19   * @see http://en.wikipedia.org/wiki/Operator-precedence_parser
  20   *
  21   * @author Fabien Potencier <fabien@symfony.com>
  22   */
  23  class Twig_ExpressionParser
  24  {
  25      const OPERATOR_LEFT = 1;
  26      const OPERATOR_RIGHT = 2;
  27  
  28      protected $parser;
  29      protected $unaryOperators;
  30      protected $binaryOperators;
  31  
  32      public function __construct(Twig_Parser $parser, array $unaryOperators, array $binaryOperators)
  33      {
  34          $this->parser = $parser;
  35          $this->unaryOperators = $unaryOperators;
  36          $this->binaryOperators = $binaryOperators;
  37      }
  38  
  39      public function parseExpression($precedence = 0)
  40      {
  41          $expr = $this->getPrimary();
  42          $token = $this->parser->getCurrentToken();
  43          while ($this->isBinary($token) && $this->binaryOperators[$token->getValue()]['precedence'] >= $precedence) {
  44              $op = $this->binaryOperators[$token->getValue()];
  45              $this->parser->getStream()->next();
  46  
  47              if (isset($op['callable'])) {
  48                  $expr = call_user_func($op['callable'], $this->parser, $expr);
  49              } else {
  50                  $expr1 = $this->parseExpression(self::OPERATOR_LEFT === $op['associativity'] ? $op['precedence'] + 1 : $op['precedence']);
  51                  $class = $op['class'];
  52                  $expr = new $class($expr, $expr1, $token->getLine());
  53              }
  54  
  55              $token = $this->parser->getCurrentToken();
  56          }
  57  
  58          if (0 === $precedence) {
  59              return $this->parseConditionalExpression($expr);
  60          }
  61  
  62          return $expr;
  63      }
  64  
  65      protected function getPrimary()
  66      {
  67          $token = $this->parser->getCurrentToken();
  68  
  69          if ($this->isUnary($token)) {
  70              $operator = $this->unaryOperators[$token->getValue()];
  71              $this->parser->getStream()->next();
  72              $expr = $this->parseExpression($operator['precedence']);
  73              $class = $operator['class'];
  74  
  75              return $this->parsePostfixExpression(new $class($expr, $token->getLine()));
  76          } elseif ($token->test(Twig_Token::PUNCTUATION_TYPE, '(')) {
  77              $this->parser->getStream()->next();
  78              $expr = $this->parseExpression();
  79              $this->parser->getStream()->expect(Twig_Token::PUNCTUATION_TYPE, ')', 'An opened parenthesis is not properly closed');
  80  
  81              return $this->parsePostfixExpression($expr);
  82          }
  83  
  84          return $this->parsePrimaryExpression();
  85      }
  86  
  87      protected function parseConditionalExpression($expr)
  88      {
  89          while ($this->parser->getStream()->nextIf(Twig_Token::PUNCTUATION_TYPE, '?')) {
  90              if (!$this->parser->getStream()->nextIf(Twig_Token::PUNCTUATION_TYPE, ':')) {
  91                  $expr2 = $this->parseExpression();
  92                  if ($this->parser->getStream()->nextIf(Twig_Token::PUNCTUATION_TYPE, ':')) {
  93                      $expr3 = $this->parseExpression();
  94                  } else {
  95                      $expr3 = new Twig_Node_Expression_Constant('', $this->parser->getCurrentToken()->getLine());
  96                  }
  97              } else {
  98                  $expr2 = $expr;
  99                  $expr3 = $this->parseExpression();
 100              }
 101  
 102              $expr = new Twig_Node_Expression_Conditional($expr, $expr2, $expr3, $this->parser->getCurrentToken()->getLine());
 103          }
 104  
 105          return $expr;
 106      }
 107  
 108      protected function isUnary(Twig_Token $token)
 109      {
 110          return $token->test(Twig_Token::OPERATOR_TYPE) && isset($this->unaryOperators[$token->getValue()]);
 111      }
 112  
 113      protected function isBinary(Twig_Token $token)
 114      {
 115          return $token->test(Twig_Token::OPERATOR_TYPE) && isset($this->binaryOperators[$token->getValue()]);
 116      }
 117  
 118      public function parsePrimaryExpression()
 119      {
 120          $token = $this->parser->getCurrentToken();
 121          switch ($token->getType()) {
 122              case Twig_Token::NAME_TYPE:
 123                  $this->parser->getStream()->next();
 124                  switch ($token->getValue()) {
 125                      case 'true':
 126                      case 'TRUE':
 127                          $node = new Twig_Node_Expression_Constant(true, $token->getLine());
 128                          break;
 129  
 130                      case 'false':
 131                      case 'FALSE':
 132                          $node = new Twig_Node_Expression_Constant(false, $token->getLine());
 133                          break;
 134  
 135                      case 'none':
 136                      case 'NONE':
 137                      case 'null':
 138                      case 'NULL':
 139                          $node = new Twig_Node_Expression_Constant(null, $token->getLine());
 140                          break;
 141  
 142                      default:
 143                          if ('(' === $this->parser->getCurrentToken()->getValue()) {
 144                              $node = $this->getFunctionNode($token->getValue(), $token->getLine());
 145                          } else {
 146                              $node = new Twig_Node_Expression_Name($token->getValue(), $token->getLine());
 147                          }
 148                  }
 149                  break;
 150  
 151              case Twig_Token::NUMBER_TYPE:
 152                  $this->parser->getStream()->next();
 153                  $node = new Twig_Node_Expression_Constant($token->getValue(), $token->getLine());
 154                  break;
 155  
 156              case Twig_Token::STRING_TYPE:
 157              case Twig_Token::INTERPOLATION_START_TYPE:
 158                  $node = $this->parseStringExpression();
 159                  break;
 160  
 161              case Twig_Token::OPERATOR_TYPE:
 162                  if (preg_match(Twig_Lexer::REGEX_NAME, $token->getValue(), $matches) && $matches[0] == $token->getValue()) {
 163                      // in this context, string operators are variable names
 164                      $this->parser->getStream()->next();
 165                      $node = new Twig_Node_Expression_Name($token->getValue(), $token->getLine());
 166                      break;
 167                  } elseif (isset($this->unaryOperators[$token->getValue()])) {
 168                      $class = $this->unaryOperators[$token->getValue()]['class'];
 169  
 170                      $ref = new ReflectionClass($class);
 171                      $negClass = 'Twig_Node_Expression_Unary_Neg';
 172                      $posClass = 'Twig_Node_Expression_Unary_Pos';
 173                      if (!(in_array($ref->getName(), array($negClass, $posClass)) || $ref->isSubclassOf($negClass) || $ref->isSubclassOf($posClass))) {
 174                          throw new Twig_Error_Syntax(sprintf('Unexpected unary operator "%s".', $token->getValue()), $token->getLine(), $this->parser->getFilename());
 175                      }
 176  
 177                      $this->parser->getStream()->next();
 178                      $expr = $this->parsePrimaryExpression();
 179  
 180                      $node = new $class($expr, $token->getLine());
 181                      break;
 182                  }
 183  
 184              default:
 185                  if ($token->test(Twig_Token::PUNCTUATION_TYPE, '[')) {
 186                      $node = $this->parseArrayExpression();
 187                  } elseif ($token->test(Twig_Token::PUNCTUATION_TYPE, '{')) {
 188                      $node = $this->parseHashExpression();
 189                  } else {
 190                      throw new Twig_Error_Syntax(sprintf('Unexpected token "%s" of value "%s".', Twig_Token::typeToEnglish($token->getType()), $token->getValue()), $token->getLine(), $this->parser->getFilename());
 191                  }
 192          }
 193  
 194          return $this->parsePostfixExpression($node);
 195      }
 196  
 197      public function parseStringExpression()
 198      {
 199          $stream = $this->parser->getStream();
 200  
 201          $nodes = array();
 202          // a string cannot be followed by another string in a single expression
 203          $nextCanBeString = true;
 204          while (true) {
 205              if ($nextCanBeString && $token = $stream->nextIf(Twig_Token::STRING_TYPE)) {
 206                  $nodes[] = new Twig_Node_Expression_Constant($token->getValue(), $token->getLine());
 207                  $nextCanBeString = false;
 208              } elseif ($stream->nextIf(Twig_Token::INTERPOLATION_START_TYPE)) {
 209                  $nodes[] = $this->parseExpression();
 210                  $stream->expect(Twig_Token::INTERPOLATION_END_TYPE);
 211                  $nextCanBeString = true;
 212              } else {
 213                  break;
 214              }
 215          }
 216  
 217          $expr = array_shift($nodes);
 218          foreach ($nodes as $node) {
 219              $expr = new Twig_Node_Expression_Binary_Concat($expr, $node, $node->getLine());
 220          }
 221  
 222          return $expr;
 223      }
 224  
 225      public function parseArrayExpression()
 226      {
 227          $stream = $this->parser->getStream();
 228          $stream->expect(Twig_Token::PUNCTUATION_TYPE, '[', 'An array element was expected');
 229  
 230          $node = new Twig_Node_Expression_Array(array(), $stream->getCurrent()->getLine());
 231          $first = true;
 232          while (!$stream->test(Twig_Token::PUNCTUATION_TYPE, ']')) {
 233              if (!$first) {
 234                  $stream->expect(Twig_Token::PUNCTUATION_TYPE, ',', 'An array element must be followed by a comma');
 235  
 236                  // trailing ,?
 237                  if ($stream->test(Twig_Token::PUNCTUATION_TYPE, ']')) {
 238                      break;
 239                  }
 240              }
 241              $first = false;
 242  
 243              $node->addElement($this->parseExpression());
 244          }
 245          $stream->expect(Twig_Token::PUNCTUATION_TYPE, ']', 'An opened array is not properly closed');
 246  
 247          return $node;
 248      }
 249  
 250      public function parseHashExpression()
 251      {
 252          $stream = $this->parser->getStream();
 253          $stream->expect(Twig_Token::PUNCTUATION_TYPE, '{', 'A hash element was expected');
 254  
 255          $node = new Twig_Node_Expression_Array(array(), $stream->getCurrent()->getLine());
 256          $first = true;
 257          while (!$stream->test(Twig_Token::PUNCTUATION_TYPE, '}')) {
 258              if (!$first) {
 259                  $stream->expect(Twig_Token::PUNCTUATION_TYPE, ',', 'A hash value must be followed by a comma');
 260  
 261                  // trailing ,?
 262                  if ($stream->test(Twig_Token::PUNCTUATION_TYPE, '}')) {
 263                      break;
 264                  }
 265              }
 266              $first = false;
 267  
 268              // a hash key can be:
 269              //
 270              //  * a number -- 12
 271              //  * a string -- 'a'
 272              //  * a name, which is equivalent to a string -- a
 273              //  * an expression, which must be enclosed in parentheses -- (1 + 2)
 274              if (($token = $stream->nextIf(Twig_Token::STRING_TYPE)) || ($token = $stream->nextIf(Twig_Token::NAME_TYPE)) || $token = $stream->nextIf(Twig_Token::NUMBER_TYPE)) {
 275                  $key = new Twig_Node_Expression_Constant($token->getValue(), $token->getLine());
 276              } elseif ($stream->test(Twig_Token::PUNCTUATION_TYPE, '(')) {
 277                  $key = $this->parseExpression();
 278              } else {
 279                  $current = $stream->getCurrent();
 280  
 281                  throw new Twig_Error_Syntax(sprintf('A hash key must be a quoted string, a number, a name, or an expression enclosed in parentheses (unexpected token "%s" of value "%s".', Twig_Token::typeToEnglish($current->getType()), $current->getValue()), $current->getLine(), $this->parser->getFilename());
 282              }
 283  
 284              $stream->expect(Twig_Token::PUNCTUATION_TYPE, ':', 'A hash key must be followed by a colon (:)');
 285              $value = $this->parseExpression();
 286  
 287              $node->addElement($value, $key);
 288          }
 289          $stream->expect(Twig_Token::PUNCTUATION_TYPE, '}', 'An opened hash is not properly closed');
 290  
 291          return $node;
 292      }
 293  
 294      public function parsePostfixExpression($node)
 295      {
 296          while (true) {
 297              $token = $this->parser->getCurrentToken();
 298              if ($token->getType() == Twig_Token::PUNCTUATION_TYPE) {
 299                  if ('.' == $token->getValue() || '[' == $token->getValue()) {
 300                      $node = $this->parseSubscriptExpression($node);
 301                  } elseif ('|' == $token->getValue()) {
 302                      $node = $this->parseFilterExpression($node);
 303                  } else {
 304                      break;
 305                  }
 306              } else {
 307                  break;
 308              }
 309          }
 310  
 311          return $node;
 312      }
 313  
 314      public function getFunctionNode($name, $line)
 315      {
 316          switch ($name) {
 317              case 'parent':
 318                  $this->parseArguments();
 319                  if (!count($this->parser->getBlockStack())) {
 320                      throw new Twig_Error_Syntax('Calling "parent" outside a block is forbidden.', $line, $this->parser->getFilename());
 321                  }
 322  
 323                  if (!$this->parser->getParent() && !$this->parser->hasTraits()) {
 324                      throw new Twig_Error_Syntax('Calling "parent" on a template that does not extend nor "use" another template is forbidden.', $line, $this->parser->getFilename());
 325                  }
 326  
 327                  return new Twig_Node_Expression_Parent($this->parser->peekBlockStack(), $line);
 328              case 'block':
 329                  return new Twig_Node_Expression_BlockReference($this->parseArguments()->getNode(0), false, $line);
 330              case 'attribute':
 331                  $args = $this->parseArguments();
 332                  if (count($args) < 2) {
 333                      throw new Twig_Error_Syntax('The "attribute" function takes at least two arguments (the variable and the attributes).', $line, $this->parser->getFilename());
 334                  }
 335  
 336                  return new Twig_Node_Expression_GetAttr($args->getNode(0), $args->getNode(1), count($args) > 2 ? $args->getNode(2) : null, Twig_Template::ANY_CALL, $line);
 337              default:
 338                  if (null !== $alias = $this->parser->getImportedSymbol('function', $name)) {
 339                      $arguments = new Twig_Node_Expression_Array(array(), $line);
 340                      foreach ($this->parseArguments() as $n) {
 341                          $arguments->addElement($n);
 342                      }
 343  
 344                      $node = new Twig_Node_Expression_MethodCall($alias['node'], $alias['name'], $arguments, $line);
 345                      $node->setAttribute('safe', true);
 346  
 347                      return $node;
 348                  }
 349  
 350                  $args = $this->parseArguments(true);
 351                  $class = $this->getFunctionNodeClass($name, $line);
 352  
 353                  return new $class($name, $args, $line);
 354          }
 355      }
 356  
 357      public function parseSubscriptExpression($node)
 358      {
 359          $stream = $this->parser->getStream();
 360          $token = $stream->next();
 361          $lineno = $token->getLine();
 362          $arguments = new Twig_Node_Expression_Array(array(), $lineno);
 363          $type = Twig_Template::ANY_CALL;
 364          if ($token->getValue() == '.') {
 365              $token = $stream->next();
 366              if (
 367                  $token->getType() == Twig_Token::NAME_TYPE
 368                  ||
 369                  $token->getType() == Twig_Token::NUMBER_TYPE
 370                  ||
 371                  ($token->getType() == Twig_Token::OPERATOR_TYPE && preg_match(Twig_Lexer::REGEX_NAME, $token->getValue()))
 372              ) {
 373                  $arg = new Twig_Node_Expression_Constant($token->getValue(), $lineno);
 374  
 375                  if ($stream->test(Twig_Token::PUNCTUATION_TYPE, '(')) {
 376                      $type = Twig_Template::METHOD_CALL;
 377                      foreach ($this->parseArguments() as $n) {
 378                          $arguments->addElement($n);
 379                      }
 380                  }
 381              } else {
 382                  throw new Twig_Error_Syntax('Expected name or number', $lineno, $this->parser->getFilename());
 383              }
 384  
 385              if ($node instanceof Twig_Node_Expression_Name && null !== $this->parser->getImportedSymbol('template', $node->getAttribute('name'))) {
 386                  if (!$arg instanceof Twig_Node_Expression_Constant) {
 387                      throw new Twig_Error_Syntax(sprintf('Dynamic macro names are not supported (called on "%s").', $node->getAttribute('name')), $token->getLine(), $this->parser->getFilename());
 388                  }
 389  
 390                  $name = $arg->getAttribute('value');
 391  
 392                  if ($this->parser->isReservedMacroName($name)) {
 393                      throw new Twig_Error_Syntax(sprintf('"%s" cannot be called as macro as it is a reserved keyword.', $name), $token->getLine(), $this->parser->getFilename());
 394                  }
 395  
 396                  $node = new Twig_Node_Expression_MethodCall($node, 'get'.$name, $arguments, $lineno);
 397                  $node->setAttribute('safe', true);
 398  
 399                  return $node;
 400              }
 401          } else {
 402              $type = Twig_Template::ARRAY_CALL;
 403  
 404              // slice?
 405              $slice = false;
 406              if ($stream->test(Twig_Token::PUNCTUATION_TYPE, ':')) {
 407                  $slice = true;
 408                  $arg = new Twig_Node_Expression_Constant(0, $token->getLine());
 409              } else {
 410                  $arg = $this->parseExpression();
 411              }
 412  
 413              if ($stream->nextIf(Twig_Token::PUNCTUATION_TYPE, ':')) {
 414                  $slice = true;
 415              }
 416  
 417              if ($slice) {
 418                  if ($stream->test(Twig_Token::PUNCTUATION_TYPE, ']')) {
 419                      $length = new Twig_Node_Expression_Constant(null, $token->getLine());
 420                  } else {
 421                      $length = $this->parseExpression();
 422                  }
 423  
 424                  $class = $this->getFilterNodeClass('slice', $token->getLine());
 425                  $arguments = new Twig_Node(array($arg, $length));
 426                  $filter = new $class($node, new Twig_Node_Expression_Constant('slice', $token->getLine()), $arguments, $token->getLine());
 427  
 428                  $stream->expect(Twig_Token::PUNCTUATION_TYPE, ']');
 429  
 430                  return $filter;
 431              }
 432  
 433              $stream->expect(Twig_Token::PUNCTUATION_TYPE, ']');
 434          }
 435  
 436          return new Twig_Node_Expression_GetAttr($node, $arg, $arguments, $type, $lineno);
 437      }
 438  
 439      public function parseFilterExpression($node)
 440      {
 441          $this->parser->getStream()->next();
 442  
 443          return $this->parseFilterExpressionRaw($node);
 444      }
 445  
 446      public function parseFilterExpressionRaw($node, $tag = null)
 447      {
 448          while (true) {
 449              $token = $this->parser->getStream()->expect(Twig_Token::NAME_TYPE);
 450  
 451              $name = new Twig_Node_Expression_Constant($token->getValue(), $token->getLine());
 452              if (!$this->parser->getStream()->test(Twig_Token::PUNCTUATION_TYPE, '(')) {
 453                  $arguments = new Twig_Node();
 454              } else {
 455                  $arguments = $this->parseArguments(true);
 456              }
 457  
 458              $class = $this->getFilterNodeClass($name->getAttribute('value'), $token->getLine());
 459  
 460              $node = new $class($node, $name, $arguments, $token->getLine(), $tag);
 461  
 462              if (!$this->parser->getStream()->test(Twig_Token::PUNCTUATION_TYPE, '|')) {
 463                  break;
 464              }
 465  
 466              $this->parser->getStream()->next();
 467          }
 468  
 469          return $node;
 470      }
 471  
 472      /**
 473       * Parses arguments.
 474       *
 475       * @param bool $namedArguments Whether to allow named arguments or not
 476       * @param bool $definition     Whether we are parsing arguments for a function definition
 477       *
 478       * @return Twig_Node
 479       *
 480       * @throws Twig_Error_Syntax
 481       */
 482      public function parseArguments($namedArguments = false, $definition = false)
 483      {
 484          $args = array();
 485          $stream = $this->parser->getStream();
 486  
 487          $stream->expect(Twig_Token::PUNCTUATION_TYPE, '(', 'A list of arguments must begin with an opening parenthesis');
 488          while (!$stream->test(Twig_Token::PUNCTUATION_TYPE, ')')) {
 489              if (!empty($args)) {
 490                  $stream->expect(Twig_Token::PUNCTUATION_TYPE, ',', 'Arguments must be separated by a comma');
 491              }
 492  
 493              if ($definition) {
 494                  $token = $stream->expect(Twig_Token::NAME_TYPE, null, 'An argument must be a name');
 495                  $value = new Twig_Node_Expression_Name($token->getValue(), $this->parser->getCurrentToken()->getLine());
 496              } else {
 497                  $value = $this->parseExpression();
 498              }
 499  
 500              $name = null;
 501              if ($namedArguments && $token = $stream->nextIf(Twig_Token::OPERATOR_TYPE, '=')) {
 502                  if (!$value instanceof Twig_Node_Expression_Name) {
 503                      throw new Twig_Error_Syntax(sprintf('A parameter name must be a string, "%s" given.', get_class($value)), $token->getLine(), $this->parser->getFilename());
 504                  }
 505                  $name = $value->getAttribute('name');
 506  
 507                  if ($definition) {
 508                      $value = $this->parsePrimaryExpression();
 509  
 510                      if (!$this->checkConstantExpression($value)) {
 511                          throw new Twig_Error_Syntax(sprintf('A default value for an argument must be a constant (a boolean, a string, a number, or an array).'), $token->getLine(), $this->parser->getFilename());
 512                      }
 513                  } else {
 514                      $value = $this->parseExpression();
 515                  }
 516              }
 517  
 518              if ($definition) {
 519                  if (null === $name) {
 520                      $name = $value->getAttribute('name');
 521                      $value = new Twig_Node_Expression_Constant(null, $this->parser->getCurrentToken()->getLine());
 522                  }
 523                  $args[$name] = $value;
 524              } else {
 525                  if (null === $name) {
 526                      $args[] = $value;
 527                  } else {
 528                      $args[$name] = $value;
 529                  }
 530              }
 531          }
 532          $stream->expect(Twig_Token::PUNCTUATION_TYPE, ')', 'A list of arguments must be closed by a parenthesis');
 533  
 534          return new Twig_Node($args);
 535      }
 536  
 537      public function parseAssignmentExpression()
 538      {
 539          $targets = array();
 540          while (true) {
 541              $token = $this->parser->getStream()->expect(Twig_Token::NAME_TYPE, null, 'Only variables can be assigned to');
 542              $value = $token->getValue();
 543              if (in_array(strtolower($value), array('true', 'false', 'none', 'null'))) {
 544                  throw new Twig_Error_Syntax(sprintf('You cannot assign a value to "%s"', $value), $token->getLine(), $this->parser->getFilename());
 545              }
 546              $targets[] = new Twig_Node_Expression_AssignName($value, $token->getLine());
 547  
 548              if (!$this->parser->getStream()->nextIf(Twig_Token::PUNCTUATION_TYPE, ',')) {
 549                  break;
 550              }
 551          }
 552  
 553          return new Twig_Node($targets);
 554      }
 555  
 556      public function parseMultitargetExpression()
 557      {
 558          $targets = array();
 559          while (true) {
 560              $targets[] = $this->parseExpression();
 561              if (!$this->parser->getStream()->nextIf(Twig_Token::PUNCTUATION_TYPE, ',')) {
 562                  break;
 563              }
 564          }
 565  
 566          return new Twig_Node($targets);
 567      }
 568  
 569      protected function getFunctionNodeClass($name, $line)
 570      {
 571          $env = $this->parser->getEnvironment();
 572  
 573          if (false === $function = $env->getFunction($name)) {
 574              $e = new Twig_Error_Syntax(sprintf('Unknown "%s" function.', $name), $line, $this->parser->getFilename());
 575              $e->addSuggestions($name, array_keys($env->getFunctions()));
 576  
 577              throw $e;
 578          }
 579  
 580          if ($function instanceof Twig_SimpleFunction && $function->isDeprecated()) {
 581              $message = sprintf('Twig Function "%s" is deprecated', $function->getName());
 582              if (!is_bool($function->getDeprecatedVersion())) {
 583                  $message .= sprintf(' since version %s', $function->getDeprecatedVersion());
 584              }
 585              if ($function->getAlternative()) {
 586                  $message .= sprintf('. Use "%s" instead', $function->getAlternative());
 587              }
 588              $message .= sprintf(' in %s at line %d.', $this->parser->getFilename(), $line);
 589  
 590              @trigger_error($message, E_USER_DEPRECATED);
 591          }
 592  
 593          if ($function instanceof Twig_SimpleFunction) {
 594              return $function->getNodeClass();
 595          }
 596  
 597          return $function instanceof Twig_Function_Node ? $function->getClass() : 'Twig_Node_Expression_Function';
 598      }
 599  
 600      protected function getFilterNodeClass($name, $line)
 601      {
 602          $env = $this->parser->getEnvironment();
 603  
 604          if (false === $filter = $env->getFilter($name)) {
 605              $e = new Twig_Error_Syntax(sprintf('Unknown "%s" filter.', $name), $line, $this->parser->getFilename());
 606              $e->addSuggestions($name, array_keys($env->getFilters()));
 607  
 608              throw $e;
 609          }
 610  
 611          if ($filter instanceof Twig_SimpleFilter && $filter->isDeprecated()) {
 612              $message = sprintf('Twig Filter "%s" is deprecated', $filter->getName());
 613              if (!is_bool($filter->getDeprecatedVersion())) {
 614                  $message .= sprintf(' since version %s', $filter->getDeprecatedVersion());
 615              }
 616              if ($filter->getAlternative()) {
 617                  $message .= sprintf('. Use "%s" instead', $filter->getAlternative());
 618              }
 619              $message .= sprintf(' in %s at line %d.', $this->parser->getFilename(), $line);
 620  
 621              @trigger_error($message, E_USER_DEPRECATED);
 622          }
 623  
 624          if ($filter instanceof Twig_SimpleFilter) {
 625              return $filter->getNodeClass();
 626          }
 627  
 628          return $filter instanceof Twig_Filter_Node ? $filter->getClass() : 'Twig_Node_Expression_Filter';
 629      }
 630  
 631      // checks that the node only contains "constant" elements
 632      protected function checkConstantExpression(Twig_NodeInterface $node)
 633      {
 634          if (!($node instanceof Twig_Node_Expression_Constant || $node instanceof Twig_Node_Expression_Array
 635              || $node instanceof Twig_Node_Expression_Unary_Neg || $node instanceof Twig_Node_Expression_Unary_Pos
 636          )) {
 637              return false;
 638          }
 639  
 640          foreach ($node as $n) {
 641              if (!$this->checkConstantExpression($n)) {
 642                  return false;
 643              }
 644          }
 645  
 646          return true;
 647      }
 648  }


Generated: Thu Jan 11 00:25:41 2018 Cross-referenced by PHPXref 0.7.1