vendor/twig/twig/src/ExpressionParser/Infix/FilterExpressionParser.php line 47

Open in your IDE?
  1. <?php
  2. /*
  3. * This file is part of Twig.
  4. *
  5. * (c) Fabien Potencier
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Twig\ExpressionParser\Infix;
  11. use Twig\Attribute\FirstClassTwigCallableReady;
  12. use Twig\ExpressionParser\AbstractExpressionParser;
  13. use Twig\ExpressionParser\ExpressionParserDescriptionInterface;
  14. use Twig\ExpressionParser\InfixAssociativity;
  15. use Twig\ExpressionParser\InfixExpressionParserInterface;
  16. use Twig\ExpressionParser\PrecedenceChange;
  17. use Twig\Node\EmptyNode;
  18. use Twig\Node\Expression\AbstractExpression;
  19. use Twig\Node\Expression\ConstantExpression;
  20. use Twig\Parser;
  21. use Twig\Token;
  22. /**
  23. * @internal
  24. */
  25. final class FilterExpressionParser extends AbstractExpressionParser implements InfixExpressionParserInterface, ExpressionParserDescriptionInterface
  26. {
  27. use ArgumentsTrait;
  28. private $readyNodes = [];
  29. public function parse(Parser $parser, AbstractExpression $expr, Token $token): AbstractExpression
  30. {
  31. $stream = $parser->getStream();
  32. $token = $stream->expect(Token::NAME_TYPE);
  33. $line = $token->getLine();
  34. if (!$stream->test(Token::OPERATOR_TYPE, '(')) {
  35. $arguments = new EmptyNode();
  36. } else {
  37. $arguments = $this->parseNamedArguments($parser);
  38. }
  39. $filter = $parser->getFilter($token->getValue(), $line);
  40. $ready = true;
  41. if (!isset($this->readyNodes[$class = $filter->getNodeClass()])) {
  42. $this->readyNodes[$class] = (bool) (new \ReflectionClass($class))->getConstructor()->getAttributes(FirstClassTwigCallableReady::class);
  43. }
  44. if (!$ready = $this->readyNodes[$class]) {
  45. trigger_deprecation('twig/twig', '3.12', 'Twig node "%s" is not marked as ready for passing a "TwigFilter" in the constructor instead of its name; please update your code and then add #[FirstClassTwigCallableReady] attribute to the constructor.', $class);
  46. }
  47. return new $class($expr, $ready ? $filter : new ConstantExpression($filter->getName(), $line), $arguments, $line);
  48. }
  49. public function getName(): string
  50. {
  51. return '|';
  52. }
  53. public function getDescription(): string
  54. {
  55. return 'Twig filter call';
  56. }
  57. public function getPrecedence(): int
  58. {
  59. return 512;
  60. }
  61. public function getPrecedenceChange(): ?PrecedenceChange
  62. {
  63. return new PrecedenceChange('twig/twig', '3.21', 300);
  64. }
  65. public function getAssociativity(): InfixAssociativity
  66. {
  67. return InfixAssociativity::Left;
  68. }
  69. }