twigphp / Twig

Twig, the flexible, fast, and secure template language for PHP
https://twig.symfony.com/
BSD 3-Clause "New" or "Revised" License
8.14k stars 1.25k forks source link

ExpressionParser getFilterNodeClass method returns a FunctionExpression class #3064

Closed p-carrillo closed 5 years ago

p-carrillo commented 5 years ago

When launching cache:clear command i've got this twig error:

In FunctionExpression.php line 19:

  [Symfony\Component\Debug\Exception\FatalThrowableError]                                                                                                                                                           
  Type error: Argument 3 passed to Twig\Node\Expression\FunctionExpression::__construct() must be of the type integer, object given, called in /var/www/html/vendor/twig/twig/src/ExpressionParser.php on line 556  

Exception trace:
 () at /var/www/html/vendor/twig/twig/src/Node/Expression/FunctionExpression.php:19
 Twig\Node\Expression\FunctionExpression->__construct() at /var/www/html/vendor/twig/twig/src/ExpressionParser.php:556
 Twig\ExpressionParser->parseFilterExpressionRaw() at /var/www/html/vendor/twig/twig/src/ExpressionParser.php:539
 Twig\ExpressionParser->parseFilterExpression() at /var/www/html/vendor/twig/twig/src/ExpressionParser.php:397
 Twig\ExpressionParser->parsePostfixExpression() at /var/www/html/vendor/twig/twig/src/ExpressionParser.php:289
 Twig\ExpressionParser->parsePrimaryExpression() at /var/www/html/vendor/twig/twig/src/ExpressionParser.php:175
 Twig\ExpressionParser->getPrimary() at /var/www/html/vendor/twig/twig/src/ExpressionParser.php:70
 Twig\ExpressionParser->parseExpression() at /var/www/html/vendor/twig/twig/src/Parser.php:142
 Twig\Parser->subparse() at /var/www/html/vendor/twig/twig/src/TokenParser/IfTokenParser.php:39
 Twig\TokenParser\IfTokenParser->parse() at /var/www/html/vendor/twig/twig/src/Parser.php:185
 Twig\Parser->subparse() at /var/www/html/vendor/twig/twig/src/Parser.php:98
 Twig\Parser->parse() at /var/www/html/vendor/twig/twig/src/Environment.php:563
 Twig\Environment->parse() at /var/www/html/vendor/twig/twig/src/Environment.php:595
 Twig\Environment->compileSource() at /var/www/html/vendor/twig/twig/src/Environment.php:408
 Twig\Environment->loadClass() at /var/www/html/vendor/twig/twig/src/Environment.php:381
 Twig\Environment->loadTemplate() at /var/www/html/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/CacheWarmer/TemplateCacheCacheWarmer.php:77
 Symfony\Bundle\TwigBundle\CacheWarmer\TemplateCacheCacheWarmer->warmUp() at /var/www/html/vendor/symfony/symfony/src/Symfony/Component/HttpKernel/CacheWarmer/CacheWarmerAggregate.php:52
 Symfony\Component\HttpKernel\CacheWarmer\CacheWarmerAggregate->warmUp() at /var/www/html/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Command/CacheClearCommand.php:222
 Symfony\Bundle\FrameworkBundle\Command\CacheClearCommand->warmup() at /var/www/html/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Command/CacheClearCommand.php:134
 Symfony\Bundle\FrameworkBundle\Command\CacheClearCommand->execute() at /var/www/html/vendor/symfony/symfony/src/Symfony/Component/Console/Command/Command.php:255
 Symfony\Component\Console\Command\Command->run() at /var/www/html/vendor/symfony/symfony/src/Symfony/Component/Console/Application.php:987
 Symfony\Component\Console\Application->doRunCommand() at /var/www/html/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Console/Application.php:86
 Symfony\Bundle\FrameworkBundle\Console\Application->doRunCommand() at /var/www/html/vendor/symfony/symfony/src/Symfony/Component/Console/Application.php:255
 Symfony\Component\Console\Application->doRun() at /var/www/html/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Console/Application.php:74
 Symfony\Bundle\FrameworkBundle\Console\Application->doRun() at /var/www/html/vendor/symfony/symfony/src/Symfony/Component/Console/Application.php:148
 Symfony\Component\Console\Application->run() at /var/www/html/bin/console:28

I'm using Symfony 3.4 and Twig 2.10 versions.

Debuging the issue I found that as title says, method getFilterNodeClass from ExpressionParser class returns FunctionExpression as class name, so when Twig tries to generate a new node in the next line, arguments don't feet:

    public function parseFilterExpressionRaw($node, $tag = null)
    {
        while (true) {
            $token = $this->parser->getStream()->expect(/* Token::NAME_TYPE */ 5);

            $name = new ConstantExpression($token->getValue(), $token->getLine());
            if (!$this->parser->getStream()->test(/* Token::PUNCTUATION_TYPE */ 9, '(')) {
                $arguments = new Node();
            } else {
                $arguments = $this->parseArguments(true, false, true);
            }

            $class = $this->getFilterNodeClass($name->getAttribute('value'), $token->getLine());

            $node = new $class($node, $name, $arguments, $token->getLine(), $tag);

            if (!$this->parser->getStream()->test(/* Token::PUNCTUATION_TYPE */ 9, '|')) {
                break;
            }

            $this->parser->getStream()->next();
        }

        return $node;
    }

And this is the FunctionExpression contructor:

class FunctionExpression extends CallExpression
{
    public function __construct(string $name, Node $arguments, int $lineno)
    {
        parent::__construct(['arguments' => $arguments], ['name' => $name, 'is_defined_test' => false], $lineno);
    }

When downgrading to twig version 2.6 the error does not appear and clean cache works fine.

Here is my Composer.json:

{
    "name" : "symfony/framework-standard-edition",
    "license" : "MIT",
    "type" : "project",
    "description" : "The \"Symfony Standard Edition\" distribution",
    "autoload" : {
        "psr-0" : {
            "" : "src",
            "Payum\\Core\\" : "vendor/payum/payum/src"
        },
        "classmap": [ "app/AppKernel.php", "app/AppCache.php" ]
    },
    "repositories" : [{
        "type" : "git",
        "url" : ..."
    }, {
        "type" : "git",
        "url" : "..."
    }, {
        "type" : "git",
        "url" : "..."
    }, {
        "type" : "git",
        "url" : "..."
    }, {
        "type": "git",
        "url": "..."
    }, {
        "type": "git",
        "url": "...t"
    }
    ],
    "require" : {
        "php" : "^7.2",
        "symfony/symfony" : "v3.4.*",
        "twig/extensions" : "^1.5",
        "twig/twig": "v2.10.*",
        "sensio/framework-extra-bundle" : "v5.2.*",
        "incenteev/composer-parameter-handler" : "^2.1",
        "knplabs/knp-paginator-bundle" : "^2.8",
        "frequence-web/contact-bundle" : "dev-master",
        "jms/serializer-bundle": "^2.4",
        "sylius/sylius": "1.3.12",

        "doctrine/collections": "^1.6",
        "doctrine/data-fixtures": "^1.3",
        "doctrine/doctrine-bundle": "^1.11",
        "doctrine/doctrine-cache-bundle": "^1.3",
        "doctrine/doctrine-fixtures-bundle": "2.4.1",
        "doctrine/doctrine-migrations-bundle": "^1.3.1",
        "doctrine/inflector":"1.3.0",
        "doctrine/orm": "^2.6",
        "doctrine/dbal": "2.9.*",

        "presta/sitemap-bundle" : "v1.6.0",
        "excelwebzone/recaptcha-bundle" : "^1.5",
        "aws/aws-sdk-php" : "^3.62",
        "lexik/maintenance-bundle" : "^2.1",
        "crevillo/payum-redsys" : "^1.0",
        "php-http/guzzle6-adapter" : "^1.1",
        "predis/predis": "^1.1",
        "snc/redis-bundle": "^2.1",
        "knplabs/knp-gaufrette-bundle": "~0.5",

        "lexik/jwt-authentication-bundle": "v2.5.4",
        "aporat/store-receipt-validator": "^2.1",
        "nelmio/api-doc-bundle": "^3.2",
        "eightpoints/guzzle-bundle": "^7.3",
        "symfony/psr-http-message-bridge": "^1.0",
        "zendframework/zend-diactoros": "^1.8",
        "nelmio/cors-bundle": "^1.5",
        "maxbanton/cwh": "^1.1",
        "sonata-project/core-bundle": "3.17.*",
        "sylius/shop-api-plugin": "^1.0@beta"
    },
    "require-dev" : {
        "symfony/var-dumper" : "^4.1",
        "fzaninotto/faker" : "~1.8",
        "phpunit/phpunit" : "<=5.7",
        "phpunit/php-file-iterator": "v1.4.2",
        "sensio/generator-bundle" : "~3.1",
        "michaelmoussa/doctrine-qbmocker": "^0.12.0",
        "symfony/phpunit-bridge": "^3.3",
        "sensiolabs/security-checker": "^5.0"
    },
    "scripts" : {
        "post-install-cmd" : [
            "Incenteev\\ParameterHandler\\ScriptHandler::buildParameters",
            "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::buildBootstrap"
        ],
        "post-update-cmd" : [
            "Incenteev\\ParameterHandler\\ScriptHandler::buildParameters",
            "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::buildBootstrap"
        ]
    },
    "config" : {
        "bin-dir" : "bin",
        "github-oauth" : {
            "github.com" : "da47ef7a819204a26f4150ddd204e5e81e5192ea"
        }
    },
    "minimum-stability" : "dev",
    "extra" : {
        "symfony-app-dir" : "app",
        "symfony-bin-dir": "bin",
        "symfony-web-dir" : "web",
        "symfony-var-dir": "var",
        "symfony-assets-install": "relative",
        "incenteev-parameters" : {
            "file" : "app/config/parameters.yml"
        },
        "branch-alias" : {
            "dev-master" : "2.3-dev"
        }
    }
}

And my php version:

PHP 7.2.13 (cli) (built: Dec 29 2018 05:15:58) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies
    with Zend OPcache v7.2.13, Copyright (c) 1999-2018, by Zend Technologies
fabpot commented 5 years ago

Can you create a template or a script that helps reproduce this error? That would help debug the issue. Thank you.

p-carrillo commented 5 years ago

I couldn't isolate the problem, In a clean symfony 3.4 witth twig 2.10 instalation in PHP 7.2 the cache:clear command works perfectly, so I'll keep trying to find the source.

p-carrillo commented 5 years ago

We found the solution and it is not Twig but Sonata witch is causing the bug. The problem is that Sontata's class DateTimeExtension is returning arrays of TwigFilter instead of TwigFunction.

It is resolved in this Sonata PR

So, I close the issue.

JC5 commented 4 years ago

Thanks for the hint, @Krleza. I ran into the same problem but it was my own mistake.