diff --git a/src/Extension/CoreExtension.php b/src/Extension/CoreExtension.php index 2a2281aebe9..5a0029fa909 100644 --- a/src/Extension/CoreExtension.php +++ b/src/Extension/CoreExtension.php @@ -324,6 +324,7 @@ public function getOperators(): array '+' => ['precedence' => 500, 'class' => PosUnary::class], ], [ + '? :' => ['precedence' => 5, 'class' => ElvisBinary::class, 'associativity' => ExpressionParser::OPERATOR_RIGHT], '?:' => ['precedence' => 5, 'class' => ElvisBinary::class, 'associativity' => ExpressionParser::OPERATOR_RIGHT], '??' => ['precedence' => 5, 'class' => NullCoalesceBinary::class, 'associativity' => ExpressionParser::OPERATOR_RIGHT], 'or' => ['precedence' => 10, 'class' => OrBinary::class, 'associativity' => ExpressionParser::OPERATOR_LEFT], diff --git a/src/Node/Expression/Binary/NullCoalesceBinary.php b/src/Node/Expression/Binary/NullCoalesceBinary.php index af7137388ce..1472e8e2e7a 100644 --- a/src/Node/Expression/Binary/NullCoalesceBinary.php +++ b/src/Node/Expression/Binary/NullCoalesceBinary.php @@ -29,8 +29,7 @@ public function __construct(AbstractExpression $left, AbstractExpression $right, parent::__construct($left, $right, $lineno); if (!$left instanceof ContextVariable) { - $left = clone $left; - $test = new DefinedTest($left, new TwigTest('defined'), new EmptyNode(), $left->getTemplateLine()); + $test = new DefinedTest(clone $left, new TwigTest('defined'), new EmptyNode(), $left->getTemplateLine()); // for "block()", we don't need the null test as the return value is always a string if (!$left instanceof BlockReferenceExpression) { $test = new AndBinary( diff --git a/tests/Fixtures/expressions/ternary_operator_nothen.test b/tests/Fixtures/expressions/ternary_operator_nothen.test index ecd6b754656..53f8c0b3caf 100644 --- a/tests/Fixtures/expressions/ternary_operator_nothen.test +++ b/tests/Fixtures/expressions/ternary_operator_nothen.test @@ -3,8 +3,16 @@ Twig supports the ternary operator --TEMPLATE-- {{ 'YES' ?: 'NO' }} {{ 0 ?: 'NO' }} +{{ 'YES' ? : 'NO' }} +{{ 0 ? : 'NO' }} +{{ 'YES' ? : 'NO' }} +{{ 0 ? : 'NO' }} --DATA-- return [] --EXPECT-- YES NO +YES +NO +YES +NO diff --git a/tests/Fixtures/tests/null_coalesce.test b/tests/Fixtures/tests/null_coalesce.test index 5c034e26022..ba2ad070174 100644 --- a/tests/Fixtures/tests/null_coalesce.test +++ b/tests/Fixtures/tests/null_coalesce.test @@ -14,8 +14,10 @@ Twig supports the ?? operator {{ 1 + (nope ?? (nada ?? 2)) }} {{ 1 + (nope ?? 3) + (nada ?? 2) }} {{ nope ?? nada ?? 2 }} +{{ obj.null() ?? 'OK' }} +{{ obj.empty() ?? 'KO' }} --DATA-- -return ['bar' => 'OK', 'foo' => ['bar' => 'OK']] +return ['bar' => 'OK', 'foo' => ['bar' => 'OK'], 'obj' => new Twig\Tests\TwigTestFoo()] --EXPECT-- OK OK @@ -29,4 +31,5 @@ OK OK 3 6 -2 \ No newline at end of file +2 +OK diff --git a/tests/IntegrationTest.php b/tests/IntegrationTest.php index 84e2599de94..8a5e60e0129 100644 --- a/tests/IntegrationTest.php +++ b/tests/IntegrationTest.php @@ -77,6 +77,16 @@ public function getFoo() return 'foo'; } + public function getEmpty() + { + return ''; + } + + public function getNull() + { + return null; + } + public function getSelf() { return $this;