mirror of
https://github.com/slawkens/myaac.git
synced 2025-10-14 09:44:55 +02:00
Update Twig to v2.15.4
This commit is contained in:
@@ -26,7 +26,7 @@ use Twig\Compiler;
|
||||
*/
|
||||
class AutoEscapeNode extends Node
|
||||
{
|
||||
public function __construct($value, \Twig_NodeInterface $body, $lineno, $tag = 'autoescape')
|
||||
public function __construct($value, Node $body, int $lineno, string $tag = 'autoescape')
|
||||
{
|
||||
parent::__construct(['body' => $body], ['value' => $value], $lineno, $tag);
|
||||
}
|
||||
|
@@ -21,7 +21,7 @@ use Twig\Compiler;
|
||||
*/
|
||||
class BlockNode extends Node
|
||||
{
|
||||
public function __construct($name, \Twig_NodeInterface $body, $lineno, $tag = null)
|
||||
public function __construct(string $name, Node $body, int $lineno, string $tag = null)
|
||||
{
|
||||
parent::__construct(['body' => $body], ['name' => $name], $lineno, $tag);
|
||||
}
|
||||
@@ -32,6 +32,7 @@ class BlockNode extends Node
|
||||
->addDebugInfo($this)
|
||||
->write(sprintf("public function block_%s(\$context, array \$blocks = [])\n", $this->getAttribute('name')), "{\n")
|
||||
->indent()
|
||||
->write("\$macros = \$this->macros;\n")
|
||||
;
|
||||
|
||||
$compiler
|
||||
|
@@ -21,7 +21,7 @@ use Twig\Compiler;
|
||||
*/
|
||||
class BlockReferenceNode extends Node implements NodeOutputInterface
|
||||
{
|
||||
public function __construct($name, $lineno, $tag = null)
|
||||
public function __construct(string $name, int $lineno, string $tag = null)
|
||||
{
|
||||
parent::__construct([], ['name' => $name], $lineno, $tag);
|
||||
}
|
||||
|
28
system/libs/Twig/Node/CheckSecurityCallNode.php
Normal file
28
system/libs/Twig/Node/CheckSecurityCallNode.php
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Twig\Node;
|
||||
|
||||
use Twig\Compiler;
|
||||
|
||||
/**
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class CheckSecurityCallNode extends Node
|
||||
{
|
||||
public function compile(Compiler $compiler)
|
||||
{
|
||||
$compiler
|
||||
->write("\$this->sandbox = \$this->env->getExtension('\Twig\Extension\SandboxExtension');\n")
|
||||
->write("\$this->checkSecurity();\n")
|
||||
;
|
||||
}
|
||||
}
|
@@ -18,9 +18,9 @@ use Twig\Compiler;
|
||||
*/
|
||||
class CheckSecurityNode extends Node
|
||||
{
|
||||
protected $usedFilters;
|
||||
protected $usedTags;
|
||||
protected $usedFunctions;
|
||||
private $usedFilters;
|
||||
private $usedTags;
|
||||
private $usedFunctions;
|
||||
|
||||
public function __construct(array $usedFilters, array $usedTags, array $usedFunctions)
|
||||
{
|
||||
@@ -45,10 +45,13 @@ class CheckSecurityNode extends Node
|
||||
}
|
||||
|
||||
$compiler
|
||||
->write("\$this->sandbox = \$this->env->getExtension('\Twig\Extension\SandboxExtension');\n")
|
||||
->write('$tags = ')->repr(array_filter($tags))->raw(";\n")
|
||||
->write('$filters = ')->repr(array_filter($filters))->raw(";\n")
|
||||
->write('$functions = ')->repr(array_filter($functions))->raw(";\n\n")
|
||||
->write("\n")
|
||||
->write("public function checkSecurity()\n")
|
||||
->write("{\n")
|
||||
->indent()
|
||||
->write('static $tags = ')->repr(array_filter($tags))->raw(";\n")
|
||||
->write('static $filters = ')->repr(array_filter($filters))->raw(";\n")
|
||||
->write('static $functions = ')->repr(array_filter($functions))->raw(";\n\n")
|
||||
->write("try {\n")
|
||||
->indent()
|
||||
->write("\$this->sandbox->checkSecurity(\n")
|
||||
@@ -61,7 +64,7 @@ class CheckSecurityNode extends Node
|
||||
->outdent()
|
||||
->write("} catch (SecurityError \$e) {\n")
|
||||
->indent()
|
||||
->write("\$e->setSourceContext(\$this->getSourceContext());\n\n")
|
||||
->write("\$e->setSourceContext(\$this->source);\n\n")
|
||||
->write("if (\$e instanceof SecurityNotAllowedTagError && isset(\$tags[\$e->getTagName()])) {\n")
|
||||
->indent()
|
||||
->write("\$e->setTemplateLine(\$tags[\$e->getTagName()]);\n")
|
||||
@@ -78,6 +81,8 @@ class CheckSecurityNode extends Node
|
||||
->write("throw \$e;\n")
|
||||
->outdent()
|
||||
->write("}\n\n")
|
||||
->outdent()
|
||||
->write("}\n")
|
||||
;
|
||||
}
|
||||
}
|
||||
|
@@ -33,10 +33,13 @@ class CheckToStringNode extends AbstractExpression
|
||||
|
||||
public function compile(Compiler $compiler)
|
||||
{
|
||||
$expr = $this->getNode('expr');
|
||||
$compiler
|
||||
->raw('$this->sandbox->ensureToStringAllowed(')
|
||||
->subcompile($this->getNode('expr'))
|
||||
->raw(')')
|
||||
->subcompile($expr)
|
||||
->raw(', ')
|
||||
->repr($expr->getTemplateLine())
|
||||
->raw(', $this->source)')
|
||||
;
|
||||
}
|
||||
}
|
||||
|
@@ -22,7 +22,7 @@ use Twig\Node\Expression\ConstantExpression;
|
||||
*/
|
||||
class DeprecatedNode extends Node
|
||||
{
|
||||
public function __construct(AbstractExpression $expr, $lineno, $tag = null)
|
||||
public function __construct(AbstractExpression $expr, int $lineno, string $tag = null)
|
||||
{
|
||||
parent::__construct(['expr' => $expr], [], $lineno, $tag);
|
||||
}
|
||||
|
@@ -21,7 +21,7 @@ use Twig\Node\Expression\AbstractExpression;
|
||||
*/
|
||||
class DoNode extends Node
|
||||
{
|
||||
public function __construct(AbstractExpression $expr, $lineno, $tag = null)
|
||||
public function __construct(AbstractExpression $expr, int $lineno, string $tag = null)
|
||||
{
|
||||
parent::__construct(['expr' => $expr], [], $lineno, $tag);
|
||||
}
|
||||
|
@@ -23,13 +23,11 @@ use Twig\Node\Expression\ConstantExpression;
|
||||
class EmbedNode extends IncludeNode
|
||||
{
|
||||
// we don't inject the module to avoid node visitors to traverse it twice (as it will be already visited in the main module)
|
||||
public function __construct($name, $index, AbstractExpression $variables = null, $only = false, $ignoreMissing = false, $lineno, $tag = null)
|
||||
public function __construct(string $name, int $index, ?AbstractExpression $variables, bool $only, bool $ignoreMissing, int $lineno, string $tag = null)
|
||||
{
|
||||
parent::__construct(new ConstantExpression('not_used', $lineno), $variables, $only, $ignoreMissing, $lineno, $tag);
|
||||
|
||||
$this->setAttribute('name', $name);
|
||||
// to be removed in 2.0, used name instead
|
||||
$this->setAttribute('filename', $name);
|
||||
$this->setAttribute('index', $index);
|
||||
}
|
||||
|
||||
|
@@ -15,9 +15,9 @@ use Twig\Compiler;
|
||||
|
||||
class ArrayExpression extends AbstractExpression
|
||||
{
|
||||
protected $index;
|
||||
private $index;
|
||||
|
||||
public function __construct(array $elements, $lineno)
|
||||
public function __construct(array $elements, int $lineno)
|
||||
{
|
||||
parent::__construct($elements, [], $lineno);
|
||||
|
||||
|
@@ -44,7 +44,7 @@ class ArrowFunctionExpression extends AbstractExpression
|
||||
;
|
||||
}
|
||||
$compiler
|
||||
->raw(') use ($context) { ')
|
||||
->raw(') use ($context, $macros) { ')
|
||||
;
|
||||
foreach ($this->getNode('names') as $name) {
|
||||
$compiler
|
||||
|
@@ -14,10 +14,11 @@ namespace Twig\Node\Expression\Binary;
|
||||
|
||||
use Twig\Compiler;
|
||||
use Twig\Node\Expression\AbstractExpression;
|
||||
use Twig\Node\Node;
|
||||
|
||||
abstract class AbstractBinary extends AbstractExpression
|
||||
{
|
||||
public function __construct(\Twig_NodeInterface $left, \Twig_NodeInterface $right, $lineno)
|
||||
public function __construct(Node $left, Node $right, int $lineno)
|
||||
{
|
||||
parent::__construct(['left' => $left, 'right' => $right], [], $lineno);
|
||||
}
|
||||
|
@@ -15,21 +15,6 @@ use Twig\Compiler;
|
||||
|
||||
class PowerBinary extends AbstractBinary
|
||||
{
|
||||
public function compile(Compiler $compiler)
|
||||
{
|
||||
if (\PHP_VERSION_ID >= 50600) {
|
||||
return parent::compile($compiler);
|
||||
}
|
||||
|
||||
$compiler
|
||||
->raw('pow(')
|
||||
->subcompile($this->getNode('left'))
|
||||
->raw(', ')
|
||||
->subcompile($this->getNode('right'))
|
||||
->raw(')')
|
||||
;
|
||||
}
|
||||
|
||||
public function operator(Compiler $compiler)
|
||||
{
|
||||
return $compiler->raw('**');
|
||||
|
22
system/libs/Twig/Node/Expression/Binary/SpaceshipBinary.php
Normal file
22
system/libs/Twig/Node/Expression/Binary/SpaceshipBinary.php
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Twig\Node\Expression\Binary;
|
||||
|
||||
use Twig\Compiler;
|
||||
|
||||
class SpaceshipBinary extends AbstractBinary
|
||||
{
|
||||
public function operator(Compiler $compiler)
|
||||
{
|
||||
return $compiler->raw('<=>');
|
||||
}
|
||||
}
|
@@ -22,17 +22,8 @@ use Twig\Node\Node;
|
||||
*/
|
||||
class BlockReferenceExpression extends AbstractExpression
|
||||
{
|
||||
/**
|
||||
* @param Node|null $template
|
||||
*/
|
||||
public function __construct(\Twig_NodeInterface $name, $template = null, $lineno, $tag = null)
|
||||
public function __construct(Node $name, ?Node $template, int $lineno, string $tag = null)
|
||||
{
|
||||
if (\is_bool($template)) {
|
||||
@trigger_error(sprintf('The %s method "$asString" argument is deprecated since version 1.28 and will be removed in 2.0.', __METHOD__), E_USER_DEPRECATED);
|
||||
|
||||
$template = null;
|
||||
}
|
||||
|
||||
$nodes = ['name' => $name];
|
||||
if (null !== $template) {
|
||||
$nodes['template'] = $template;
|
||||
@@ -58,7 +49,7 @@ class BlockReferenceExpression extends AbstractExpression
|
||||
}
|
||||
}
|
||||
|
||||
private function compileTemplateCall(Compiler $compiler, $method)
|
||||
private function compileTemplateCall(Compiler $compiler, string $method): Compiler
|
||||
{
|
||||
if (!$this->hasNode('template')) {
|
||||
$compiler->write('$this');
|
||||
@@ -75,12 +66,11 @@ class BlockReferenceExpression extends AbstractExpression
|
||||
}
|
||||
|
||||
$compiler->raw(sprintf('->%s', $method));
|
||||
$this->compileBlockArguments($compiler);
|
||||
|
||||
return $compiler;
|
||||
return $this->compileBlockArguments($compiler);
|
||||
}
|
||||
|
||||
private function compileBlockArguments(Compiler $compiler)
|
||||
private function compileBlockArguments(Compiler $compiler): Compiler
|
||||
{
|
||||
$compiler
|
||||
->raw('(')
|
||||
|
@@ -22,37 +22,37 @@ abstract class CallExpression extends AbstractExpression
|
||||
|
||||
protected function compileCallable(Compiler $compiler)
|
||||
{
|
||||
$closingParenthesis = false;
|
||||
$isArray = false;
|
||||
if ($this->hasAttribute('callable') && $callable = $this->getAttribute('callable')) {
|
||||
if (\is_string($callable) && false === strpos($callable, '::')) {
|
||||
$compiler->raw($callable);
|
||||
} else {
|
||||
list($r, $callable) = $this->reflectCallable($callable);
|
||||
if ($r instanceof \ReflectionMethod && \is_string($callable[0])) {
|
||||
if ($r->isStatic()) {
|
||||
$compiler->raw(sprintf('%s::%s', $callable[0], $callable[1]));
|
||||
} else {
|
||||
$compiler->raw(sprintf('$this->env->getRuntime(\'%s\')->%s', $callable[0], $callable[1]));
|
||||
}
|
||||
} elseif ($r instanceof \ReflectionMethod && $callable[0] instanceof ExtensionInterface) {
|
||||
$compiler->raw(sprintf('$this->env->getExtension(\'%s\')->%s', \get_class($callable[0]), $callable[1]));
|
||||
} else {
|
||||
$type = ucfirst($this->getAttribute('type'));
|
||||
$compiler->raw(sprintf('call_user_func_array($this->env->get%s(\'%s\')->getCallable(), ', $type, $this->getAttribute('name')));
|
||||
$closingParenthesis = true;
|
||||
$isArray = true;
|
||||
}
|
||||
}
|
||||
$callable = $this->getAttribute('callable');
|
||||
|
||||
if (\is_string($callable) && false === strpos($callable, '::')) {
|
||||
$compiler->raw($callable);
|
||||
} else {
|
||||
$compiler->raw($this->getAttribute('thing')->compile());
|
||||
[$r, $callable] = $this->reflectCallable($callable);
|
||||
|
||||
if (\is_string($callable)) {
|
||||
$compiler->raw($callable);
|
||||
} elseif (\is_array($callable) && \is_string($callable[0])) {
|
||||
if (!$r instanceof \ReflectionMethod || $r->isStatic()) {
|
||||
$compiler->raw(sprintf('%s::%s', $callable[0], $callable[1]));
|
||||
} else {
|
||||
$compiler->raw(sprintf('$this->env->getRuntime(\'%s\')->%s', $callable[0], $callable[1]));
|
||||
}
|
||||
} elseif (\is_array($callable) && $callable[0] instanceof ExtensionInterface) {
|
||||
$class = \get_class($callable[0]);
|
||||
if (!$compiler->getEnvironment()->hasExtension($class)) {
|
||||
// Compile a non-optimized call to trigger a \Twig\Error\RuntimeError, which cannot be a compile-time error
|
||||
$compiler->raw(sprintf('$this->env->getExtension(\'%s\')', $class));
|
||||
} else {
|
||||
$compiler->raw(sprintf('$this->extensions[\'%s\']', ltrim($class, '\\')));
|
||||
}
|
||||
|
||||
$compiler->raw(sprintf('->%s', $callable[1]));
|
||||
} else {
|
||||
$compiler->raw(sprintf('$this->env->get%s(\'%s\')->getCallable()', ucfirst($this->getAttribute('type')), $this->getAttribute('name')));
|
||||
}
|
||||
}
|
||||
|
||||
$this->compileArguments($compiler, $isArray);
|
||||
|
||||
if ($closingParenthesis) {
|
||||
$compiler->raw(')');
|
||||
}
|
||||
$this->compileArguments($compiler);
|
||||
}
|
||||
|
||||
protected function compileArguments(Compiler $compiler, $isArray = false)
|
||||
@@ -93,10 +93,8 @@ abstract class CallExpression extends AbstractExpression
|
||||
}
|
||||
|
||||
if ($this->hasNode('arguments')) {
|
||||
$callable = $this->hasAttribute('callable') ? $this->getAttribute('callable') : null;
|
||||
|
||||
$callable = $this->getAttribute('callable');
|
||||
$arguments = $this->getArguments($callable, $this->getNode('arguments'));
|
||||
|
||||
foreach ($arguments as $node) {
|
||||
if (!$first) {
|
||||
$compiler->raw(', ');
|
||||
@@ -142,14 +140,23 @@ abstract class CallExpression extends AbstractExpression
|
||||
throw new \LogicException($message);
|
||||
}
|
||||
|
||||
$callableParameters = $this->getCallableParameters($callable, $isVariadic);
|
||||
list($callableParameters, $isPhpVariadic) = $this->getCallableParameters($callable, $isVariadic);
|
||||
$arguments = [];
|
||||
$names = [];
|
||||
$missingArguments = [];
|
||||
$optionalArguments = [];
|
||||
$pos = 0;
|
||||
foreach ($callableParameters as $callableParameter) {
|
||||
$names[] = $name = $this->normalizeName($callableParameter->name);
|
||||
$name = $this->normalizeName($callableParameter->name);
|
||||
if (\PHP_VERSION_ID >= 80000 && 'range' === $callable) {
|
||||
if ('start' === $name) {
|
||||
$name = 'low';
|
||||
} elseif ('end' === $name) {
|
||||
$name = 'high';
|
||||
}
|
||||
}
|
||||
|
||||
$names[] = $name;
|
||||
|
||||
if (\array_key_exists($name, $parameters)) {
|
||||
if (\array_key_exists($pos, $parameters)) {
|
||||
@@ -187,7 +194,7 @@ abstract class CallExpression extends AbstractExpression
|
||||
}
|
||||
|
||||
if ($isVariadic) {
|
||||
$arbitraryArguments = new ArrayExpression([], -1);
|
||||
$arbitraryArguments = $isPhpVariadic ? new VariadicExpression([], -1) : new ArrayExpression([], -1);
|
||||
foreach ($parameters as $key => $value) {
|
||||
if (\is_int($key)) {
|
||||
$arbitraryArguments->addElement($value);
|
||||
@@ -230,12 +237,9 @@ abstract class CallExpression extends AbstractExpression
|
||||
return strtolower(preg_replace(['/([A-Z]+)([A-Z][a-z])/', '/([a-z\d])([A-Z])/'], ['\\1_\\2', '\\1_\\2'], $name));
|
||||
}
|
||||
|
||||
private function getCallableParameters($callable, $isVariadic)
|
||||
private function getCallableParameters($callable, bool $isVariadic): array
|
||||
{
|
||||
list($r) = $this->reflectCallable($callable);
|
||||
if (null === $r) {
|
||||
return [];
|
||||
}
|
||||
[$r, , $callableName] = $this->reflectCallable($callable);
|
||||
|
||||
$parameters = $r->getParameters();
|
||||
if ($this->hasNode('node')) {
|
||||
@@ -252,21 +256,21 @@ abstract class CallExpression extends AbstractExpression
|
||||
array_shift($parameters);
|
||||
}
|
||||
}
|
||||
$isPhpVariadic = false;
|
||||
if ($isVariadic) {
|
||||
$argument = end($parameters);
|
||||
if ($argument && $argument->isArray() && $argument->isDefaultValueAvailable() && [] === $argument->getDefaultValue()) {
|
||||
$isArray = $argument && $argument->hasType() && 'array' === $argument->getType()->getName();
|
||||
if ($isArray && $argument->isDefaultValueAvailable() && [] === $argument->getDefaultValue()) {
|
||||
array_pop($parameters);
|
||||
} elseif ($argument && $argument->isVariadic()) {
|
||||
array_pop($parameters);
|
||||
$isPhpVariadic = true;
|
||||
} else {
|
||||
$callableName = $r->name;
|
||||
if ($r instanceof \ReflectionMethod) {
|
||||
$callableName = $r->getDeclaringClass()->name.'::'.$callableName;
|
||||
}
|
||||
|
||||
throw new \LogicException(sprintf('The last parameter of "%s" for %s "%s" must be an array with default value, eg. "array $arg = []".', $callableName, $this->getAttribute('type'), $this->getAttribute('name')));
|
||||
}
|
||||
}
|
||||
|
||||
return $parameters;
|
||||
return [$parameters, $isPhpVariadic];
|
||||
}
|
||||
|
||||
private function reflectCallable($callable)
|
||||
@@ -275,30 +279,44 @@ abstract class CallExpression extends AbstractExpression
|
||||
return $this->reflector;
|
||||
}
|
||||
|
||||
if (\is_array($callable)) {
|
||||
if (!method_exists($callable[0], $callable[1])) {
|
||||
// __call()
|
||||
return [null, []];
|
||||
}
|
||||
$r = new \ReflectionMethod($callable[0], $callable[1]);
|
||||
} elseif (\is_object($callable) && !$callable instanceof \Closure) {
|
||||
$r = new \ReflectionObject($callable);
|
||||
$r = $r->getMethod('__invoke');
|
||||
$callable = [$callable, '__invoke'];
|
||||
} elseif (\is_string($callable) && false !== $pos = strpos($callable, '::')) {
|
||||
$class = substr($callable, 0, $pos);
|
||||
$method = substr($callable, $pos + 2);
|
||||
if (!method_exists($class, $method)) {
|
||||
// __staticCall()
|
||||
return [null, []];
|
||||
}
|
||||
$r = new \ReflectionMethod($callable);
|
||||
$callable = [$class, $method];
|
||||
} else {
|
||||
$r = new \ReflectionFunction($callable);
|
||||
if (\is_string($callable) && false !== $pos = strpos($callable, '::')) {
|
||||
$callable = [substr($callable, 0, $pos), substr($callable, 2 + $pos)];
|
||||
}
|
||||
|
||||
return $this->reflector = [$r, $callable];
|
||||
if (\is_array($callable) && method_exists($callable[0], $callable[1])) {
|
||||
$r = new \ReflectionMethod($callable[0], $callable[1]);
|
||||
|
||||
return $this->reflector = [$r, $callable, $r->class.'::'.$r->name];
|
||||
}
|
||||
|
||||
$checkVisibility = $callable instanceof \Closure;
|
||||
try {
|
||||
$closure = \Closure::fromCallable($callable);
|
||||
} catch (\TypeError $e) {
|
||||
throw new \LogicException(sprintf('Callback for %s "%s" is not callable in the current scope.', $this->getAttribute('type'), $this->getAttribute('name')), 0, $e);
|
||||
}
|
||||
$r = new \ReflectionFunction($closure);
|
||||
|
||||
if (false !== strpos($r->name, '{closure}')) {
|
||||
return $this->reflector = [$r, $callable, 'Closure'];
|
||||
}
|
||||
|
||||
if ($object = $r->getClosureThis()) {
|
||||
$callable = [$object, $r->name];
|
||||
$callableName = (\function_exists('get_debug_type') ? get_debug_type($object) : \get_class($object)).'::'.$r->name;
|
||||
} elseif (\PHP_VERSION_ID >= 80111 && $class = $r->getClosureCalledClass()) {
|
||||
$callableName = $class->name.'::'.$r->name;
|
||||
} elseif (\PHP_VERSION_ID < 80111 && $class = $r->getClosureScopeClass()) {
|
||||
$callableName = (\is_array($callable) ? $callable[0] : $class->name).'::'.$r->name;
|
||||
} else {
|
||||
$callable = $callableName = $r->name;
|
||||
}
|
||||
|
||||
if ($checkVisibility && \is_array($callable) && method_exists(...$callable) && !(new \ReflectionMethod(...$callable))->isPublic()) {
|
||||
$callable = $r->getClosure();
|
||||
}
|
||||
|
||||
return $this->reflector = [$r, $callable, $callableName];
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -16,7 +16,7 @@ use Twig\Compiler;
|
||||
|
||||
class ConditionalExpression extends AbstractExpression
|
||||
{
|
||||
public function __construct(AbstractExpression $expr1, AbstractExpression $expr2, AbstractExpression $expr3, $lineno)
|
||||
public function __construct(AbstractExpression $expr1, AbstractExpression $expr2, AbstractExpression $expr3, int $lineno)
|
||||
{
|
||||
parent::__construct(['expr1' => $expr1, 'expr2' => $expr2, 'expr3' => $expr3], [], $lineno);
|
||||
}
|
||||
|
@@ -16,7 +16,7 @@ use Twig\Compiler;
|
||||
|
||||
class ConstantExpression extends AbstractExpression
|
||||
{
|
||||
public function __construct($value, $lineno)
|
||||
public function __construct($value, int $lineno)
|
||||
{
|
||||
parent::__construct([], ['value' => $value], $lineno);
|
||||
}
|
||||
|
@@ -29,7 +29,7 @@ use Twig\Node\Node;
|
||||
*/
|
||||
class DefaultFilter extends FilterExpression
|
||||
{
|
||||
public function __construct(\Twig_NodeInterface $node, ConstantExpression $filterName, \Twig_NodeInterface $arguments, $lineno, $tag = null)
|
||||
public function __construct(Node $node, ConstantExpression $filterName, Node $arguments, int $lineno, string $tag = null)
|
||||
{
|
||||
$default = new FilterExpression($node, new ConstantExpression('default', $node->getTemplateLine()), $arguments, $node->getTemplateLine());
|
||||
|
||||
|
@@ -13,11 +13,11 @@
|
||||
namespace Twig\Node\Expression;
|
||||
|
||||
use Twig\Compiler;
|
||||
use Twig\TwigFilter;
|
||||
use Twig\Node\Node;
|
||||
|
||||
class FilterExpression extends CallExpression
|
||||
{
|
||||
public function __construct(\Twig_NodeInterface $node, ConstantExpression $filterName, \Twig_NodeInterface $arguments, $lineno, $tag = null)
|
||||
public function __construct(Node $node, ConstantExpression $filterName, Node $arguments, int $lineno, string $tag = null)
|
||||
{
|
||||
parent::__construct(['node' => $node, 'filter' => $filterName, 'arguments' => $arguments], [], $lineno, $tag);
|
||||
}
|
||||
@@ -29,16 +29,11 @@ class FilterExpression extends CallExpression
|
||||
|
||||
$this->setAttribute('name', $name);
|
||||
$this->setAttribute('type', 'filter');
|
||||
$this->setAttribute('thing', $filter);
|
||||
$this->setAttribute('needs_environment', $filter->needsEnvironment());
|
||||
$this->setAttribute('needs_context', $filter->needsContext());
|
||||
$this->setAttribute('arguments', $filter->getArguments());
|
||||
if ($filter instanceof \Twig_FilterCallableInterface || $filter instanceof TwigFilter) {
|
||||
$this->setAttribute('callable', $filter->getCallable());
|
||||
}
|
||||
if ($filter instanceof TwigFilter) {
|
||||
$this->setAttribute('is_variadic', $filter->isVariadic());
|
||||
}
|
||||
$this->setAttribute('callable', $filter->getCallable());
|
||||
$this->setAttribute('is_variadic', $filter->isVariadic());
|
||||
|
||||
$this->compileCallable($compiler);
|
||||
}
|
||||
|
@@ -12,11 +12,11 @@
|
||||
namespace Twig\Node\Expression;
|
||||
|
||||
use Twig\Compiler;
|
||||
use Twig\TwigFunction;
|
||||
use Twig\Node\Node;
|
||||
|
||||
class FunctionExpression extends CallExpression
|
||||
{
|
||||
public function __construct($name, \Twig_NodeInterface $arguments, $lineno)
|
||||
public function __construct(string $name, Node $arguments, int $lineno)
|
||||
{
|
||||
parent::__construct(['arguments' => $arguments], ['name' => $name, 'is_defined_test' => false], $lineno);
|
||||
}
|
||||
@@ -28,21 +28,15 @@ class FunctionExpression extends CallExpression
|
||||
|
||||
$this->setAttribute('name', $name);
|
||||
$this->setAttribute('type', 'function');
|
||||
$this->setAttribute('thing', $function);
|
||||
$this->setAttribute('needs_environment', $function->needsEnvironment());
|
||||
$this->setAttribute('needs_context', $function->needsContext());
|
||||
$this->setAttribute('arguments', $function->getArguments());
|
||||
if ($function instanceof \Twig_FunctionCallableInterface || $function instanceof TwigFunction) {
|
||||
$callable = $function->getCallable();
|
||||
if ('constant' === $name && $this->getAttribute('is_defined_test')) {
|
||||
$callable = 'twig_constant_is_defined';
|
||||
}
|
||||
|
||||
$this->setAttribute('callable', $callable);
|
||||
}
|
||||
if ($function instanceof TwigFunction) {
|
||||
$this->setAttribute('is_variadic', $function->isVariadic());
|
||||
$callable = $function->getCallable();
|
||||
if ('constant' === $name && $this->getAttribute('is_defined_test')) {
|
||||
$callable = 'twig_constant_is_defined';
|
||||
}
|
||||
$this->setAttribute('callable', $callable);
|
||||
$this->setAttribute('is_variadic', $function->isVariadic());
|
||||
|
||||
$this->compileCallable($compiler);
|
||||
}
|
||||
|
@@ -13,67 +13,76 @@
|
||||
namespace Twig\Node\Expression;
|
||||
|
||||
use Twig\Compiler;
|
||||
use Twig\Extension\SandboxExtension;
|
||||
use Twig\Template;
|
||||
|
||||
class GetAttrExpression extends AbstractExpression
|
||||
{
|
||||
public function __construct(AbstractExpression $node, AbstractExpression $attribute, AbstractExpression $arguments = null, $type, $lineno)
|
||||
public function __construct(AbstractExpression $node, AbstractExpression $attribute, ?AbstractExpression $arguments, string $type, int $lineno)
|
||||
{
|
||||
$nodes = ['node' => $node, 'attribute' => $attribute];
|
||||
if (null !== $arguments) {
|
||||
$nodes['arguments'] = $arguments;
|
||||
}
|
||||
|
||||
parent::__construct($nodes, ['type' => $type, 'is_defined_test' => false, 'ignore_strict_check' => false, 'disable_c_ext' => false], $lineno);
|
||||
parent::__construct($nodes, ['type' => $type, 'is_defined_test' => false, 'ignore_strict_check' => false, 'optimizable' => true], $lineno);
|
||||
}
|
||||
|
||||
public function compile(Compiler $compiler)
|
||||
{
|
||||
if ($this->getAttribute('disable_c_ext')) {
|
||||
@trigger_error(sprintf('Using the "disable_c_ext" attribute on %s is deprecated since version 1.30 and will be removed in 2.0.', __CLASS__), E_USER_DEPRECATED);
|
||||
$env = $compiler->getEnvironment();
|
||||
|
||||
// optimize array calls
|
||||
if (
|
||||
$this->getAttribute('optimizable')
|
||||
&& (!$env->isStrictVariables() || $this->getAttribute('ignore_strict_check'))
|
||||
&& !$this->getAttribute('is_defined_test')
|
||||
&& Template::ARRAY_CALL === $this->getAttribute('type')
|
||||
) {
|
||||
$var = '$'.$compiler->getVarName();
|
||||
$compiler
|
||||
->raw('(('.$var.' = ')
|
||||
->subcompile($this->getNode('node'))
|
||||
->raw(') && is_array(')
|
||||
->raw($var)
|
||||
->raw(') || ')
|
||||
->raw($var)
|
||||
->raw(' instanceof ArrayAccess ? (')
|
||||
->raw($var)
|
||||
->raw('[')
|
||||
->subcompile($this->getNode('attribute'))
|
||||
->raw('] ?? null) : null)')
|
||||
;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (\function_exists('twig_template_get_attributes') && !$this->getAttribute('disable_c_ext')) {
|
||||
$compiler->raw('twig_template_get_attributes($this, ');
|
||||
} else {
|
||||
$compiler->raw('$this->getAttribute(');
|
||||
}
|
||||
$compiler->raw('twig_get_attribute($this->env, $this->source, ');
|
||||
|
||||
if ($this->getAttribute('ignore_strict_check')) {
|
||||
$this->getNode('node')->setAttribute('ignore_strict_check', true);
|
||||
}
|
||||
|
||||
$compiler->subcompile($this->getNode('node'));
|
||||
$compiler
|
||||
->subcompile($this->getNode('node'))
|
||||
->raw(', ')
|
||||
->subcompile($this->getNode('attribute'))
|
||||
;
|
||||
|
||||
$compiler->raw(', ')->subcompile($this->getNode('attribute'));
|
||||
|
||||
// only generate optional arguments when needed (to make generated code more readable)
|
||||
$needFourth = $this->getAttribute('ignore_strict_check');
|
||||
$needThird = $needFourth || $this->getAttribute('is_defined_test');
|
||||
$needSecond = $needThird || Template::ANY_CALL !== $this->getAttribute('type');
|
||||
$needFirst = $needSecond || $this->hasNode('arguments');
|
||||
|
||||
if ($needFirst) {
|
||||
if ($this->hasNode('arguments')) {
|
||||
$compiler->raw(', ')->subcompile($this->getNode('arguments'));
|
||||
} else {
|
||||
$compiler->raw(', []');
|
||||
}
|
||||
if ($this->hasNode('arguments')) {
|
||||
$compiler->raw(', ')->subcompile($this->getNode('arguments'));
|
||||
} else {
|
||||
$compiler->raw(', []');
|
||||
}
|
||||
|
||||
if ($needSecond) {
|
||||
$compiler->raw(', ')->repr($this->getAttribute('type'));
|
||||
}
|
||||
|
||||
if ($needThird) {
|
||||
$compiler->raw(', ')->repr($this->getAttribute('is_defined_test'));
|
||||
}
|
||||
|
||||
if ($needFourth) {
|
||||
$compiler->raw(', ')->repr($this->getAttribute('ignore_strict_check'));
|
||||
}
|
||||
|
||||
$compiler->raw(')');
|
||||
$compiler->raw(', ')
|
||||
->repr($this->getAttribute('type'))
|
||||
->raw(', ')->repr($this->getAttribute('is_defined_test'))
|
||||
->raw(', ')->repr($this->getAttribute('ignore_strict_check'))
|
||||
->raw(', ')->repr($env->hasExtension(SandboxExtension::class))
|
||||
->raw(', ')->repr($this->getNode('node')->getTemplateLine())
|
||||
->raw(')')
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -15,9 +15,9 @@ use Twig\Compiler;
|
||||
|
||||
class MethodCallExpression extends AbstractExpression
|
||||
{
|
||||
public function __construct(AbstractExpression $node, $method, ArrayExpression $arguments, $lineno)
|
||||
public function __construct(AbstractExpression $node, string $method, ArrayExpression $arguments, int $lineno)
|
||||
{
|
||||
parent::__construct(['node' => $node, 'arguments' => $arguments], ['method' => $method, 'safe' => false], $lineno);
|
||||
parent::__construct(['node' => $node, 'arguments' => $arguments], ['method' => $method, 'safe' => false, 'is_defined_test' => false], $lineno);
|
||||
|
||||
if ($node instanceof NameExpression) {
|
||||
$node->setAttribute('always_defined', true);
|
||||
@@ -26,11 +26,24 @@ class MethodCallExpression extends AbstractExpression
|
||||
|
||||
public function compile(Compiler $compiler)
|
||||
{
|
||||
if ($this->getAttribute('is_defined_test')) {
|
||||
$compiler
|
||||
->raw('method_exists($macros[')
|
||||
->repr($this->getNode('node')->getAttribute('name'))
|
||||
->raw('], ')
|
||||
->repr($this->getAttribute('method'))
|
||||
->raw(')')
|
||||
;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$compiler
|
||||
->subcompile($this->getNode('node'))
|
||||
->raw('->')
|
||||
->raw($this->getAttribute('method'))
|
||||
->raw('(')
|
||||
->raw('twig_call_macro($macros[')
|
||||
->repr($this->getNode('node')->getAttribute('name'))
|
||||
->raw('], ')
|
||||
->repr($this->getAttribute('method'))
|
||||
->raw(', [')
|
||||
;
|
||||
$first = true;
|
||||
foreach ($this->getNode('arguments')->getKeyValuePairs() as $pair) {
|
||||
@@ -41,7 +54,10 @@ class MethodCallExpression extends AbstractExpression
|
||||
|
||||
$compiler->subcompile($pair['value']);
|
||||
}
|
||||
$compiler->raw(')');
|
||||
$compiler
|
||||
->raw('], ')
|
||||
->repr($this->getTemplateLine())
|
||||
->raw(', $context, $this->getSourceContext())');
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -16,13 +16,13 @@ use Twig\Compiler;
|
||||
|
||||
class NameExpression extends AbstractExpression
|
||||
{
|
||||
protected $specialVars = [
|
||||
'_self' => '$this',
|
||||
private $specialVars = [
|
||||
'_self' => '$this->getTemplateName()',
|
||||
'_context' => '$context',
|
||||
'_charset' => '$this->env->getCharset()',
|
||||
];
|
||||
|
||||
public function __construct($name, $lineno)
|
||||
public function __construct(string $name, int $lineno)
|
||||
{
|
||||
parent::__construct([], ['name' => $name, 'is_defined_test' => false, 'ignore_strict_check' => false, 'always_defined' => false], $lineno);
|
||||
}
|
||||
@@ -36,7 +36,7 @@ class NameExpression extends AbstractExpression
|
||||
if ($this->getAttribute('is_defined_test')) {
|
||||
if ($this->isSpecial()) {
|
||||
$compiler->repr(true);
|
||||
} elseif (\PHP_VERSION_ID >= 700400) {
|
||||
} elseif (\PHP_VERSION_ID >= 70400) {
|
||||
$compiler
|
||||
->raw('array_key_exists(')
|
||||
->string($name)
|
||||
@@ -60,45 +60,25 @@ class NameExpression extends AbstractExpression
|
||||
->raw(']')
|
||||
;
|
||||
} else {
|
||||
if (\PHP_VERSION_ID >= 70000) {
|
||||
// use PHP 7 null coalescing operator
|
||||
if ($this->getAttribute('ignore_strict_check') || !$compiler->getEnvironment()->isStrictVariables()) {
|
||||
$compiler
|
||||
->raw('($context[')
|
||||
->string($name)
|
||||
->raw('] ?? ')
|
||||
->raw('] ?? null)')
|
||||
;
|
||||
|
||||
if ($this->getAttribute('ignore_strict_check') || !$compiler->getEnvironment()->isStrictVariables()) {
|
||||
$compiler->raw('null)');
|
||||
} else {
|
||||
$compiler->raw('$this->getContext($context, ')->string($name)->raw('))');
|
||||
}
|
||||
} elseif (\PHP_VERSION_ID >= 50400) {
|
||||
// PHP 5.4 ternary operator performance was optimized
|
||||
} else {
|
||||
$compiler
|
||||
->raw('(isset($context[')
|
||||
->string($name)
|
||||
->raw(']) ? $context[')
|
||||
->raw(']) || array_key_exists(')
|
||||
->string($name)
|
||||
->raw('] : ')
|
||||
;
|
||||
|
||||
if ($this->getAttribute('ignore_strict_check') || !$compiler->getEnvironment()->isStrictVariables()) {
|
||||
$compiler->raw('null)');
|
||||
} else {
|
||||
$compiler->raw('$this->getContext($context, ')->string($name)->raw('))');
|
||||
}
|
||||
} else {
|
||||
$compiler
|
||||
->raw('$this->getContext($context, ')
|
||||
->raw(', $context) ? $context[')
|
||||
->string($name)
|
||||
;
|
||||
|
||||
if ($this->getAttribute('ignore_strict_check')) {
|
||||
$compiler->raw(', true');
|
||||
}
|
||||
|
||||
$compiler
|
||||
->raw('] : (function () { throw new RuntimeError(\'Variable ')
|
||||
->string($name)
|
||||
->raw(' does not exist.\', ')
|
||||
->repr($this->lineno)
|
||||
->raw(', $this->source); })()')
|
||||
->raw(')')
|
||||
;
|
||||
}
|
||||
|
@@ -20,7 +20,7 @@ use Twig\Node\Node;
|
||||
|
||||
class NullCoalesceExpression extends ConditionalExpression
|
||||
{
|
||||
public function __construct(\Twig_NodeInterface $left, \Twig_NodeInterface $right, $lineno)
|
||||
public function __construct(Node $left, Node $right, int $lineno)
|
||||
{
|
||||
$test = new DefinedTest(clone $left, 'defined', new Node(), $left->getTemplateLine());
|
||||
// for "block()", we don't need the null test as the return value is always a string
|
||||
@@ -44,7 +44,7 @@ class NullCoalesceExpression extends ConditionalExpression
|
||||
* cases might be implemented as an optimizer node visitor, but has not been done
|
||||
* as benefits are probably not worth the added complexity.
|
||||
*/
|
||||
if (\PHP_VERSION_ID >= 70000 && $this->getNode('expr2') instanceof NameExpression) {
|
||||
if ($this->getNode('expr2') instanceof NameExpression) {
|
||||
$this->getNode('expr2')->setAttribute('always_defined', true);
|
||||
$compiler
|
||||
->raw('((')
|
||||
|
@@ -21,7 +21,7 @@ use Twig\Compiler;
|
||||
*/
|
||||
class ParentExpression extends AbstractExpression
|
||||
{
|
||||
public function __construct($name, $lineno, $tag = null)
|
||||
public function __construct(string $name, int $lineno, string $tag = null)
|
||||
{
|
||||
parent::__construct([], ['output' => false, 'name' => $name], $lineno, $tag);
|
||||
}
|
||||
|
@@ -15,7 +15,7 @@ use Twig\Compiler;
|
||||
|
||||
class TempNameExpression extends AbstractExpression
|
||||
{
|
||||
public function __construct($name, $lineno)
|
||||
public function __construct(string $name, int $lineno)
|
||||
{
|
||||
parent::__construct([], ['name' => $name], $lineno);
|
||||
}
|
||||
|
@@ -18,8 +18,10 @@ use Twig\Node\Expression\BlockReferenceExpression;
|
||||
use Twig\Node\Expression\ConstantExpression;
|
||||
use Twig\Node\Expression\FunctionExpression;
|
||||
use Twig\Node\Expression\GetAttrExpression;
|
||||
use Twig\Node\Expression\MethodCallExpression;
|
||||
use Twig\Node\Expression\NameExpression;
|
||||
use Twig\Node\Expression\TestExpression;
|
||||
use Twig\Node\Node;
|
||||
|
||||
/**
|
||||
* Checks if a variable is defined in the current context.
|
||||
@@ -33,7 +35,7 @@ use Twig\Node\Expression\TestExpression;
|
||||
*/
|
||||
class DefinedTest extends TestExpression
|
||||
{
|
||||
public function __construct(\Twig_NodeInterface $node, $name, \Twig_NodeInterface $arguments = null, $lineno)
|
||||
public function __construct(Node $node, string $name, ?Node $arguments, int $lineno)
|
||||
{
|
||||
if ($node instanceof NameExpression) {
|
||||
$node->setAttribute('is_defined_test', true);
|
||||
@@ -46,6 +48,8 @@ class DefinedTest extends TestExpression
|
||||
$node->setAttribute('is_defined_test', true);
|
||||
} elseif ($node instanceof ConstantExpression || $node instanceof ArrayExpression) {
|
||||
$node = new ConstantExpression(true, $node->getTemplateLine());
|
||||
} elseif ($node instanceof MethodCallExpression) {
|
||||
$node->setAttribute('is_defined_test', true);
|
||||
} else {
|
||||
throw new SyntaxError('The "defined" test only works with simple variables.', $lineno);
|
||||
}
|
||||
@@ -53,8 +57,9 @@ class DefinedTest extends TestExpression
|
||||
parent::__construct($node, $name, $arguments, $lineno);
|
||||
}
|
||||
|
||||
protected function changeIgnoreStrictCheck(GetAttrExpression $node)
|
||||
private function changeIgnoreStrictCheck(GetAttrExpression $node)
|
||||
{
|
||||
$node->setAttribute('optimizable', false);
|
||||
$node->setAttribute('ignore_strict_check', true);
|
||||
|
||||
if ($node->getNode('node') instanceof GetAttrExpression) {
|
||||
|
@@ -28,7 +28,7 @@ class OddTest extends TestExpression
|
||||
$compiler
|
||||
->raw('(')
|
||||
->subcompile($this->getNode('node'))
|
||||
->raw(' % 2 == 1')
|
||||
->raw(' % 2 != 0')
|
||||
->raw(')')
|
||||
;
|
||||
}
|
||||
|
@@ -12,11 +12,11 @@
|
||||
namespace Twig\Node\Expression;
|
||||
|
||||
use Twig\Compiler;
|
||||
use Twig\TwigTest;
|
||||
use Twig\Node\Node;
|
||||
|
||||
class TestExpression extends CallExpression
|
||||
{
|
||||
public function __construct(\Twig_NodeInterface $node, $name, \Twig_NodeInterface $arguments = null, $lineno)
|
||||
public function __construct(Node $node, string $name, ?Node $arguments, int $lineno)
|
||||
{
|
||||
$nodes = ['node' => $node];
|
||||
if (null !== $arguments) {
|
||||
@@ -33,16 +33,9 @@ class TestExpression extends CallExpression
|
||||
|
||||
$this->setAttribute('name', $name);
|
||||
$this->setAttribute('type', 'test');
|
||||
$this->setAttribute('thing', $test);
|
||||
if ($test instanceof TwigTest) {
|
||||
$this->setAttribute('arguments', $test->getArguments());
|
||||
}
|
||||
if ($test instanceof \Twig_TestCallableInterface || $test instanceof TwigTest) {
|
||||
$this->setAttribute('callable', $test->getCallable());
|
||||
}
|
||||
if ($test instanceof TwigTest) {
|
||||
$this->setAttribute('is_variadic', $test->isVariadic());
|
||||
}
|
||||
$this->setAttribute('arguments', $test->getArguments());
|
||||
$this->setAttribute('callable', $test->getCallable());
|
||||
$this->setAttribute('is_variadic', $test->isVariadic());
|
||||
|
||||
$this->compileCallable($compiler);
|
||||
}
|
||||
|
@@ -14,10 +14,11 @@ namespace Twig\Node\Expression\Unary;
|
||||
|
||||
use Twig\Compiler;
|
||||
use Twig\Node\Expression\AbstractExpression;
|
||||
use Twig\Node\Node;
|
||||
|
||||
abstract class AbstractUnary extends AbstractExpression
|
||||
{
|
||||
public function __construct(\Twig_NodeInterface $node, $lineno)
|
||||
public function __construct(Node $node, int $lineno)
|
||||
{
|
||||
parent::__construct(['node' => $node], [], $lineno);
|
||||
}
|
||||
|
24
system/libs/Twig/Node/Expression/VariadicExpression.php
Normal file
24
system/libs/Twig/Node/Expression/VariadicExpression.php
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Twig\Node\Expression;
|
||||
|
||||
use Twig\Compiler;
|
||||
|
||||
class VariadicExpression extends ArrayExpression
|
||||
{
|
||||
public function compile(Compiler $compiler)
|
||||
{
|
||||
$compiler->raw('...');
|
||||
|
||||
parent::compile($compiler);
|
||||
}
|
||||
}
|
@@ -20,7 +20,7 @@ use Twig\Compiler;
|
||||
*/
|
||||
class FlushNode extends Node
|
||||
{
|
||||
public function __construct($lineno, $tag)
|
||||
public function __construct(int $lineno, string $tag)
|
||||
{
|
||||
parent::__construct([], [], $lineno, $tag);
|
||||
}
|
||||
|
@@ -20,7 +20,7 @@ use Twig\Compiler;
|
||||
*/
|
||||
class ForLoopNode extends Node
|
||||
{
|
||||
public function __construct($lineno, $tag = null)
|
||||
public function __construct(int $lineno, string $tag = null)
|
||||
{
|
||||
parent::__construct([], ['with_loop' => false, 'ifexpr' => false, 'else' => false], $lineno, $tag);
|
||||
}
|
||||
|
@@ -23,9 +23,9 @@ use Twig\Node\Expression\AssignNameExpression;
|
||||
*/
|
||||
class ForNode extends Node
|
||||
{
|
||||
protected $loop;
|
||||
private $loop;
|
||||
|
||||
public function __construct(AssignNameExpression $keyTarget, AssignNameExpression $valueTarget, AbstractExpression $seq, AbstractExpression $ifexpr = null, \Twig_NodeInterface $body, \Twig_NodeInterface $else = null, $lineno, $tag = null)
|
||||
public function __construct(AssignNameExpression $keyTarget, AssignNameExpression $valueTarget, AbstractExpression $seq, ?AbstractExpression $ifexpr, Node $body, ?Node $else, int $lineno, string $tag = null)
|
||||
{
|
||||
$body = new Node([$body, $this->loop = new ForLoopNode($lineno, $tag)]);
|
||||
|
||||
|
@@ -21,7 +21,7 @@ use Twig\Compiler;
|
||||
*/
|
||||
class IfNode extends Node
|
||||
{
|
||||
public function __construct(\Twig_NodeInterface $tests, \Twig_NodeInterface $else = null, $lineno, $tag = null)
|
||||
public function __construct(Node $tests, ?Node $else, int $lineno, string $tag = null)
|
||||
{
|
||||
$nodes = ['tests' => $tests];
|
||||
if (null !== $else) {
|
||||
@@ -50,8 +50,11 @@ class IfNode extends Node
|
||||
->subcompile($this->getNode('tests')->getNode($i))
|
||||
->raw(") {\n")
|
||||
->indent()
|
||||
->subcompile($this->getNode('tests')->getNode($i + 1))
|
||||
;
|
||||
// The node might not exists if the content is empty
|
||||
if ($this->getNode('tests')->hasNode($i + 1)) {
|
||||
$compiler->subcompile($this->getNode('tests')->getNode($i + 1));
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->hasNode('else')) {
|
||||
|
@@ -22,20 +22,28 @@ use Twig\Node\Expression\NameExpression;
|
||||
*/
|
||||
class ImportNode extends Node
|
||||
{
|
||||
public function __construct(AbstractExpression $expr, AbstractExpression $var, $lineno, $tag = null)
|
||||
public function __construct(AbstractExpression $expr, AbstractExpression $var, int $lineno, string $tag = null, bool $global = true)
|
||||
{
|
||||
parent::__construct(['expr' => $expr, 'var' => $var], [], $lineno, $tag);
|
||||
parent::__construct(['expr' => $expr, 'var' => $var], ['global' => $global], $lineno, $tag);
|
||||
}
|
||||
|
||||
public function compile(Compiler $compiler)
|
||||
{
|
||||
$compiler
|
||||
->addDebugInfo($this)
|
||||
->write('')
|
||||
->subcompile($this->getNode('var'))
|
||||
->raw(' = ')
|
||||
->write('$macros[')
|
||||
->repr($this->getNode('var')->getAttribute('name'))
|
||||
->raw('] = ')
|
||||
;
|
||||
|
||||
if ($this->getAttribute('global')) {
|
||||
$compiler
|
||||
->raw('$this->macros[')
|
||||
->repr($this->getNode('var')->getAttribute('name'))
|
||||
->raw('] = ')
|
||||
;
|
||||
}
|
||||
|
||||
if ($this->getNode('expr') instanceof NameExpression && '_self' === $this->getNode('expr')->getAttribute('name')) {
|
||||
$compiler->raw('$this');
|
||||
} else {
|
||||
|
@@ -22,7 +22,7 @@ use Twig\Node\Expression\AbstractExpression;
|
||||
*/
|
||||
class IncludeNode extends Node implements NodeOutputInterface
|
||||
{
|
||||
public function __construct(AbstractExpression $expr, AbstractExpression $variables = null, $only = false, $ignoreMissing = false, $lineno, $tag = null)
|
||||
public function __construct(AbstractExpression $expr, ?AbstractExpression $variables, bool $only, bool $ignoreMissing, int $lineno, string $tag = null)
|
||||
{
|
||||
$nodes = ['expr' => $expr];
|
||||
if (null !== $variables) {
|
||||
|
@@ -21,9 +21,9 @@ use Twig\Error\SyntaxError;
|
||||
*/
|
||||
class MacroNode extends Node
|
||||
{
|
||||
const VARARGS_NAME = 'varargs';
|
||||
public const VARARGS_NAME = 'varargs';
|
||||
|
||||
public function __construct($name, \Twig_NodeInterface $body, \Twig_NodeInterface $arguments, $lineno, $tag = null)
|
||||
public function __construct(string $name, Node $body, Node $arguments, int $lineno, string $tag = null)
|
||||
{
|
||||
foreach ($arguments as $argumentName => $argument) {
|
||||
if (self::VARARGS_NAME === $argumentName) {
|
||||
@@ -38,7 +38,7 @@ class MacroNode extends Node
|
||||
{
|
||||
$compiler
|
||||
->addDebugInfo($this)
|
||||
->write(sprintf('public function get%s(', $this->getAttribute('name')))
|
||||
->write(sprintf('public function macro_%s(', $this->getAttribute('name')))
|
||||
;
|
||||
|
||||
$count = \count($this->getNode('arguments'));
|
||||
@@ -54,21 +54,16 @@ class MacroNode extends Node
|
||||
}
|
||||
}
|
||||
|
||||
if (\PHP_VERSION_ID >= 50600) {
|
||||
if ($count) {
|
||||
$compiler->raw(', ');
|
||||
}
|
||||
|
||||
$compiler->raw('...$__varargs__');
|
||||
if ($count) {
|
||||
$compiler->raw(', ');
|
||||
}
|
||||
|
||||
$compiler
|
||||
->raw('...$__varargs__')
|
||||
->raw(")\n")
|
||||
->write("{\n")
|
||||
->indent()
|
||||
;
|
||||
|
||||
$compiler
|
||||
->write("\$macros = \$this->macros;\n")
|
||||
->write("\$context = \$this->env->mergeGlobals([\n")
|
||||
->indent()
|
||||
;
|
||||
@@ -88,19 +83,8 @@ class MacroNode extends Node
|
||||
->raw(' => ')
|
||||
;
|
||||
|
||||
if (\PHP_VERSION_ID >= 50600) {
|
||||
$compiler->raw("\$__varargs__,\n");
|
||||
} else {
|
||||
$compiler
|
||||
->raw('func_num_args() > ')
|
||||
->repr($count)
|
||||
->raw(' ? array_slice(func_get_args(), ')
|
||||
->repr($count)
|
||||
->raw(") : [],\n")
|
||||
;
|
||||
}
|
||||
|
||||
$compiler
|
||||
->raw("\$__varargs__,\n")
|
||||
->outdent()
|
||||
->write("]);\n\n")
|
||||
->write("\$blocks = [];\n\n")
|
||||
@@ -114,19 +98,14 @@ class MacroNode extends Node
|
||||
->write("try {\n")
|
||||
->indent()
|
||||
->subcompile($this->getNode('body'))
|
||||
->raw("\n")
|
||||
->write("return ('' === \$tmp = ob_get_contents()) ? '' : new Markup(\$tmp, \$this->env->getCharset());\n")
|
||||
->outdent()
|
||||
->write("} catch (\Exception \$e) {\n")
|
||||
->write("} finally {\n")
|
||||
->indent()
|
||||
->write("ob_end_clean();\n\n")
|
||||
->write("throw \$e;\n")
|
||||
->write("ob_end_clean();\n")
|
||||
->outdent()
|
||||
->write("} catch (\Throwable \$e) {\n")
|
||||
->indent()
|
||||
->write("ob_end_clean();\n\n")
|
||||
->write("throw \$e;\n")
|
||||
->outdent()
|
||||
->write("}\n\n")
|
||||
->write("return ('' === \$tmp = ob_get_clean()) ? '' : new Markup(\$tmp, \$this->env->getCharset());\n")
|
||||
->write("}\n")
|
||||
->outdent()
|
||||
->write("}\n\n")
|
||||
;
|
||||
|
@@ -25,16 +25,15 @@ use Twig\Source;
|
||||
* display_end, constructor_start, constructor_end, and class_end.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* @final since Twig 2.4.0
|
||||
*/
|
||||
class ModuleNode extends Node
|
||||
{
|
||||
public function __construct(\Twig_NodeInterface $body, AbstractExpression $parent = null, \Twig_NodeInterface $blocks, \Twig_NodeInterface $macros, \Twig_NodeInterface $traits, $embeddedTemplates, $name, $source = '')
|
||||
public function __construct(Node $body, ?AbstractExpression $parent, Node $blocks, Node $macros, Node $traits, $embeddedTemplates, Source $source)
|
||||
{
|
||||
if (!$name instanceof Source) {
|
||||
@trigger_error(sprintf('Passing a string as the $name argument of %s() is deprecated since version 1.27. Pass a \Twig\Source instance instead.', __METHOD__), E_USER_DEPRECATED);
|
||||
$source = new Source($source, $name);
|
||||
} else {
|
||||
$source = $name;
|
||||
if (__CLASS__ !== static::class) {
|
||||
@trigger_error('Overriding '.__CLASS__.' is deprecated since Twig 2.4.0 and the class will be final in 3.0.', \E_USER_DEPRECATED);
|
||||
}
|
||||
|
||||
$nodes = [
|
||||
@@ -54,16 +53,11 @@ class ModuleNode extends Node
|
||||
|
||||
// embedded templates are set as attributes so that they are only visited once by the visitors
|
||||
parent::__construct($nodes, [
|
||||
// source to be remove in 2.0
|
||||
'source' => $source->getCode(),
|
||||
// filename to be remove in 2.0 (use getTemplateName() instead)
|
||||
'filename' => $source->getName(),
|
||||
'index' => null,
|
||||
'embedded_templates' => $embeddedTemplates,
|
||||
], 1);
|
||||
|
||||
// populate the template name of all node children
|
||||
$this->setTemplateName($source->getName());
|
||||
$this->setSourceContext($source);
|
||||
}
|
||||
|
||||
@@ -89,16 +83,7 @@ class ModuleNode extends Node
|
||||
|
||||
$this->compileClassHeader($compiler);
|
||||
|
||||
if (
|
||||
\count($this->getNode('blocks'))
|
||||
|| \count($this->getNode('traits'))
|
||||
|| !$this->hasNode('parent')
|
||||
|| $this->getNode('parent') instanceof ConstantExpression
|
||||
|| \count($this->getNode('constructor_start'))
|
||||
|| \count($this->getNode('constructor_end'))
|
||||
) {
|
||||
$this->compileConstructor($compiler);
|
||||
}
|
||||
$this->compileConstructor($compiler);
|
||||
|
||||
$this->compileGetParent($compiler);
|
||||
|
||||
@@ -114,8 +99,6 @@ class ModuleNode extends Node
|
||||
|
||||
$this->compileDebugInfo($compiler);
|
||||
|
||||
$this->compileGetSource($compiler);
|
||||
|
||||
$this->compileGetSourceContext($compiler);
|
||||
|
||||
$this->compileClassFooter($compiler);
|
||||
@@ -166,6 +149,7 @@ class ModuleNode extends Node
|
||||
->write("use Twig\Environment;\n")
|
||||
->write("use Twig\Error\LoaderError;\n")
|
||||
->write("use Twig\Error\RuntimeError;\n")
|
||||
->write("use Twig\Extension\SandboxExtension;\n")
|
||||
->write("use Twig\Markup;\n")
|
||||
->write("use Twig\Sandbox\SecurityError;\n")
|
||||
->write("use Twig\Sandbox\SecurityNotAllowedTagError;\n")
|
||||
@@ -179,9 +163,11 @@ class ModuleNode extends Node
|
||||
// if the template name contains */, add a blank to avoid a PHP parse error
|
||||
->write('/* '.str_replace('*/', '* /', $this->getSourceContext()->getName())." */\n")
|
||||
->write('class '.$compiler->getEnvironment()->getTemplateClass($this->getSourceContext()->getName(), $this->getAttribute('index')))
|
||||
->raw(sprintf(" extends %s\n", $compiler->getEnvironment()->getBaseTemplateClass()))
|
||||
->raw(sprintf(" extends %s\n", $compiler->getEnvironment()->getBaseTemplateClass(false)))
|
||||
->write("{\n")
|
||||
->indent()
|
||||
->write("private \$source;\n")
|
||||
->write("private \$macros = [];\n\n")
|
||||
;
|
||||
}
|
||||
|
||||
@@ -192,6 +178,7 @@ class ModuleNode extends Node
|
||||
->indent()
|
||||
->subcompile($this->getNode('constructor_start'))
|
||||
->write("parent::__construct(\$env);\n\n")
|
||||
->write("\$this->source = \$this->getSourceContext();\n\n")
|
||||
;
|
||||
|
||||
// parent
|
||||
@@ -203,18 +190,24 @@ class ModuleNode extends Node
|
||||
if ($countTraits) {
|
||||
// traits
|
||||
foreach ($this->getNode('traits') as $i => $trait) {
|
||||
$this->compileLoadTemplate($compiler, $trait->getNode('template'), sprintf('$_trait_%s', $i));
|
||||
|
||||
$node = $trait->getNode('template');
|
||||
|
||||
$compiler
|
||||
->addDebugInfo($node)
|
||||
->write(sprintf('$_trait_%s = $this->loadTemplate(', $i))
|
||||
->subcompile($node)
|
||||
->raw(', ')
|
||||
->repr($node->getTemplateName())
|
||||
->raw(', ')
|
||||
->repr($node->getTemplateLine())
|
||||
->raw(");\n")
|
||||
->write(sprintf("if (!\$_trait_%s->isTraitable()) {\n", $i))
|
||||
->indent()
|
||||
->write("throw new RuntimeError('Template \"'.")
|
||||
->subcompile($trait->getNode('template'))
|
||||
->raw(".'\" cannot be used as a trait.', ")
|
||||
->repr($node->getTemplateLine())
|
||||
->raw(", \$this->getSourceContext());\n")
|
||||
->raw(", \$this->source);\n")
|
||||
->outdent()
|
||||
->write("}\n")
|
||||
->write(sprintf("\$_trait_%s_blocks = \$_trait_%s->getBlocks();\n\n", $i, $i))
|
||||
@@ -226,13 +219,13 @@ class ModuleNode extends Node
|
||||
->string($key)
|
||||
->raw("])) {\n")
|
||||
->indent()
|
||||
->write("throw new RuntimeError(sprintf('Block ")
|
||||
->write("throw new RuntimeError('Block ")
|
||||
->string($key)
|
||||
->raw(' is not defined in trait ')
|
||||
->subcompile($trait->getNode('template'))
|
||||
->raw(".'), ")
|
||||
->raw(".', ")
|
||||
->repr($node->getTemplateLine())
|
||||
->raw(", \$this->getSourceContext());\n")
|
||||
->raw(", \$this->source);\n")
|
||||
->outdent()
|
||||
->write("}\n\n")
|
||||
|
||||
@@ -318,6 +311,7 @@ class ModuleNode extends Node
|
||||
$compiler
|
||||
->write("protected function doDisplay(array \$context, array \$blocks = [])\n", "{\n")
|
||||
->indent()
|
||||
->write("\$macros = \$this->macros;\n")
|
||||
->subcompile($this->getNode('display_start'))
|
||||
->subcompile($this->getNode('body'))
|
||||
;
|
||||
@@ -440,20 +434,6 @@ class ModuleNode extends Node
|
||||
;
|
||||
}
|
||||
|
||||
protected function compileGetSource(Compiler $compiler)
|
||||
{
|
||||
$compiler
|
||||
->write("/** @deprecated since 1.27 (to be removed in 2.0). Use getSourceContext() instead */\n")
|
||||
->write("public function getSource()\n", "{\n")
|
||||
->indent()
|
||||
->write("@trigger_error('The '.__METHOD__.' method is deprecated since version 1.27 and will be removed in 2.0. Use getSourceContext() instead.', E_USER_DEPRECATED);\n\n")
|
||||
->write('return $this->getSourceContext()->getCode();')
|
||||
->raw("\n")
|
||||
->outdent()
|
||||
->write("}\n\n")
|
||||
;
|
||||
}
|
||||
|
||||
protected function compileGetSourceContext(Compiler $compiler)
|
||||
{
|
||||
$compiler
|
||||
|
@@ -20,7 +20,7 @@ use Twig\Source;
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class Node implements \Twig_NodeInterface
|
||||
class Node implements \Countable, \IteratorAggregate
|
||||
{
|
||||
protected $nodes;
|
||||
protected $attributes;
|
||||
@@ -36,11 +36,11 @@ class Node implements \Twig_NodeInterface
|
||||
* @param int $lineno The line number
|
||||
* @param string $tag The tag name associated with the Node
|
||||
*/
|
||||
public function __construct(array $nodes = [], array $attributes = [], $lineno = 0, $tag = null)
|
||||
public function __construct(array $nodes = [], array $attributes = [], int $lineno = 0, string $tag = null)
|
||||
{
|
||||
foreach ($nodes as $name => $node) {
|
||||
if (!$node instanceof \Twig_NodeInterface) {
|
||||
@trigger_error(sprintf('Using "%s" for the value of node "%s" of "%s" is deprecated since version 1.25 and will be removed in 2.0.', \is_object($node) ? \get_class($node) : (null === $node ? 'null' : \gettype($node)), $name, \get_class($this)), E_USER_DEPRECATED);
|
||||
if (!$node instanceof self) {
|
||||
throw new \InvalidArgumentException(sprintf('Using "%s" for the value of node "%s" of "%s" is not supported. You must pass a \Twig\Node\Node instance.', \is_object($node) ? \get_class($node) : (null === $node ? 'null' : \gettype($node)), $name, static::class));
|
||||
}
|
||||
}
|
||||
$this->nodes = $nodes;
|
||||
@@ -56,7 +56,7 @@ class Node implements \Twig_NodeInterface
|
||||
$attributes[] = sprintf('%s: %s', $name, str_replace("\n", '', var_export($value, true)));
|
||||
}
|
||||
|
||||
$repr = [\get_class($this).'('.implode(', ', $attributes)];
|
||||
$repr = [static::class.'('.implode(', ', $attributes)];
|
||||
|
||||
if (\count($this->nodes)) {
|
||||
foreach ($this->nodes as $name => $node) {
|
||||
@@ -77,41 +77,6 @@ class Node implements \Twig_NodeInterface
|
||||
return implode("\n", $repr);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated since 1.16.1 (to be removed in 2.0)
|
||||
*/
|
||||
public function toXml($asDom = false)
|
||||
{
|
||||
@trigger_error(sprintf('%s is deprecated since version 1.16.1 and will be removed in 2.0.', __METHOD__), E_USER_DEPRECATED);
|
||||
|
||||
$dom = new \DOMDocument('1.0', 'UTF-8');
|
||||
$dom->formatOutput = true;
|
||||
$dom->appendChild($xml = $dom->createElement('twig'));
|
||||
|
||||
$xml->appendChild($node = $dom->createElement('node'));
|
||||
$node->setAttribute('class', \get_class($this));
|
||||
|
||||
foreach ($this->attributes as $name => $value) {
|
||||
$node->appendChild($attribute = $dom->createElement('attribute'));
|
||||
$attribute->setAttribute('name', $name);
|
||||
$attribute->appendChild($dom->createTextNode($value));
|
||||
}
|
||||
|
||||
foreach ($this->nodes as $name => $n) {
|
||||
if (null === $n) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$child = $n->toXml(true)->getElementsByTagName('node')->item(0);
|
||||
$child = $dom->importNode($child, true);
|
||||
$child->setAttribute('name', $name);
|
||||
|
||||
$node->appendChild($child);
|
||||
}
|
||||
|
||||
return $asDom ? $dom : $dom->saveXML();
|
||||
}
|
||||
|
||||
public function compile(Compiler $compiler)
|
||||
{
|
||||
foreach ($this->nodes as $node) {
|
||||
@@ -124,16 +89,6 @@ class Node implements \Twig_NodeInterface
|
||||
return $this->lineno;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated since 1.27 (to be removed in 2.0)
|
||||
*/
|
||||
public function getLine()
|
||||
{
|
||||
@trigger_error('The '.__METHOD__.' method is deprecated since version 1.27 and will be removed in 2.0. Use getTemplateLine() instead.', E_USER_DEPRECATED);
|
||||
|
||||
return $this->lineno;
|
||||
}
|
||||
|
||||
public function getNodeTag()
|
||||
{
|
||||
return $this->tag;
|
||||
@@ -153,7 +108,7 @@ class Node implements \Twig_NodeInterface
|
||||
public function getAttribute($name)
|
||||
{
|
||||
if (!\array_key_exists($name, $this->attributes)) {
|
||||
throw new \LogicException(sprintf('Attribute "%s" does not exist for Node "%s".', $name, \get_class($this)));
|
||||
throw new \LogicException(sprintf('Attribute "%s" does not exist for Node "%s".', $name, static::class));
|
||||
}
|
||||
|
||||
return $this->attributes[$name];
|
||||
@@ -178,7 +133,7 @@ class Node implements \Twig_NodeInterface
|
||||
*/
|
||||
public function hasNode($name)
|
||||
{
|
||||
return \array_key_exists($name, $this->nodes);
|
||||
return isset($this->nodes[$name]);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -186,19 +141,15 @@ class Node implements \Twig_NodeInterface
|
||||
*/
|
||||
public function getNode($name)
|
||||
{
|
||||
if (!\array_key_exists($name, $this->nodes)) {
|
||||
throw new \LogicException(sprintf('Node "%s" does not exist for Node "%s".', $name, \get_class($this)));
|
||||
if (!isset($this->nodes[$name])) {
|
||||
throw new \LogicException(sprintf('Node "%s" does not exist for Node "%s".', $name, static::class));
|
||||
}
|
||||
|
||||
return $this->nodes[$name];
|
||||
}
|
||||
|
||||
public function setNode($name, $node = null)
|
||||
public function setNode($name, self $node)
|
||||
{
|
||||
if (!$node instanceof \Twig_NodeInterface) {
|
||||
@trigger_error(sprintf('Using "%s" for the value of node "%s" of "%s" is deprecated since version 1.25 and will be removed in 2.0.', \is_object($node) ? \get_class($node) : (null === $node ? 'null' : \gettype($node)), $name, \get_class($this)), E_USER_DEPRECATED);
|
||||
}
|
||||
|
||||
$this->nodes[$name] = $node;
|
||||
}
|
||||
|
||||
@@ -207,65 +158,59 @@ class Node implements \Twig_NodeInterface
|
||||
unset($this->nodes[$name]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function count()
|
||||
{
|
||||
return \count($this->nodes);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Traversable
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function getIterator()
|
||||
{
|
||||
return new \ArrayIterator($this->nodes);
|
||||
}
|
||||
|
||||
public function setTemplateName($name)
|
||||
/**
|
||||
* @deprecated since 2.8 (to be removed in 3.0)
|
||||
*/
|
||||
public function setTemplateName($name/*, $triggerDeprecation = true */)
|
||||
{
|
||||
$triggerDeprecation = 2 > \func_num_args() || \func_get_arg(1);
|
||||
if ($triggerDeprecation) {
|
||||
@trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0. Use setSourceContext() instead.', \E_USER_DEPRECATED);
|
||||
}
|
||||
|
||||
$this->name = $name;
|
||||
foreach ($this->nodes as $node) {
|
||||
if (null !== $node) {
|
||||
$node->setTemplateName($name);
|
||||
}
|
||||
$node->setTemplateName($name, $triggerDeprecation);
|
||||
}
|
||||
}
|
||||
|
||||
public function getTemplateName()
|
||||
{
|
||||
return $this->name;
|
||||
return $this->sourceContext ? $this->sourceContext->getName() : null;
|
||||
}
|
||||
|
||||
public function setSourceContext(Source $source)
|
||||
{
|
||||
$this->sourceContext = $source;
|
||||
foreach ($this->nodes as $node) {
|
||||
if ($node instanceof Node) {
|
||||
$node->setSourceContext($source);
|
||||
}
|
||||
$node->setSourceContext($source);
|
||||
}
|
||||
|
||||
$this->setTemplateName($source->getName(), false);
|
||||
}
|
||||
|
||||
public function getSourceContext()
|
||||
{
|
||||
return $this->sourceContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated since 1.27 (to be removed in 2.0)
|
||||
*/
|
||||
public function setFilename($name)
|
||||
{
|
||||
@trigger_error('The '.__METHOD__.' method is deprecated since version 1.27 and will be removed in 2.0. Use setTemplateName() instead.', E_USER_DEPRECATED);
|
||||
|
||||
$this->setTemplateName($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated since 1.27 (to be removed in 2.0)
|
||||
*/
|
||||
public function getFilename()
|
||||
{
|
||||
@trigger_error('The '.__METHOD__.' method is deprecated since version 1.27 and will be removed in 2.0. Use getTemplateName() instead.', E_USER_DEPRECATED);
|
||||
|
||||
return $this->name;
|
||||
}
|
||||
}
|
||||
|
||||
class_alias('Twig\Node\Node', 'Twig_Node');
|
||||
|
@@ -22,7 +22,7 @@ use Twig\Node\Expression\AbstractExpression;
|
||||
*/
|
||||
class PrintNode extends Node implements NodeOutputInterface
|
||||
{
|
||||
public function __construct(AbstractExpression $expr, $lineno, $tag = null)
|
||||
public function __construct(AbstractExpression $expr, int $lineno, string $tag = null)
|
||||
{
|
||||
parent::__construct(['expr' => $expr], [], $lineno, $tag);
|
||||
}
|
||||
|
@@ -20,7 +20,7 @@ use Twig\Compiler;
|
||||
*/
|
||||
class SandboxNode extends Node
|
||||
{
|
||||
public function __construct(\Twig_NodeInterface $body, $lineno, $tag = null)
|
||||
public function __construct(Node $body, int $lineno, string $tag = null)
|
||||
{
|
||||
parent::__construct(['body' => $body], [], $lineno, $tag);
|
||||
}
|
||||
@@ -34,12 +34,19 @@ class SandboxNode extends Node
|
||||
->write("\$this->sandbox->enableSandbox();\n")
|
||||
->outdent()
|
||||
->write("}\n")
|
||||
->write("try {\n")
|
||||
->indent()
|
||||
->subcompile($this->getNode('body'))
|
||||
->outdent()
|
||||
->write("} finally {\n")
|
||||
->indent()
|
||||
->write("if (!\$alreadySandboxed) {\n")
|
||||
->indent()
|
||||
->write("\$this->sandbox->disableSandbox();\n")
|
||||
->outdent()
|
||||
->write("}\n")
|
||||
->outdent()
|
||||
->write("}\n")
|
||||
;
|
||||
}
|
||||
}
|
||||
|
@@ -13,7 +13,6 @@ namespace Twig\Node;
|
||||
|
||||
use Twig\Compiler;
|
||||
use Twig\Node\Expression\ConstantExpression;
|
||||
use Twig\Node\Expression\FilterExpression;
|
||||
|
||||
/**
|
||||
* Adds a check for the __toString() method when the variable is an object and the sandbox is activated.
|
||||
@@ -42,28 +41,14 @@ class SandboxedPrintNode extends PrintNode
|
||||
;
|
||||
} else {
|
||||
$compiler
|
||||
->write('$this->env->getExtension(\'\Twig\Extension\SandboxExtension\')->ensureToStringAllowed(')
|
||||
->write('$this->extensions[SandboxExtension::class]->ensureToStringAllowed(')
|
||||
->subcompile($expr)
|
||||
->raw(");\n")
|
||||
->raw(', ')
|
||||
->repr($expr->getTemplateLine())
|
||||
->raw(", \$this->source);\n")
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes node filters.
|
||||
*
|
||||
* This is mostly needed when another visitor adds filters (like the escaper one).
|
||||
*
|
||||
* @return Node
|
||||
*/
|
||||
protected function removeNodeFilter(Node $node)
|
||||
{
|
||||
if ($node instanceof FilterExpression) {
|
||||
return $this->removeNodeFilter($node->getNode('node'));
|
||||
}
|
||||
|
||||
return $node;
|
||||
}
|
||||
}
|
||||
|
||||
class_alias('Twig\Node\SandboxedPrintNode', 'Twig_Node_SandboxedPrint');
|
||||
|
@@ -21,7 +21,7 @@ use Twig\Node\Expression\ConstantExpression;
|
||||
*/
|
||||
class SetNode extends Node implements NodeCaptureInterface
|
||||
{
|
||||
public function __construct($capture, \Twig_NodeInterface $names, \Twig_NodeInterface $values, $lineno, $tag = null)
|
||||
public function __construct(bool $capture, Node $names, Node $values, int $lineno, string $tag = null)
|
||||
{
|
||||
parent::__construct(['names' => $names, 'values' => $values], ['capture' => $capture, 'safe' => false], $lineno, $tag);
|
||||
|
||||
|
@@ -18,11 +18,13 @@ use Twig\Compiler;
|
||||
*
|
||||
* It removes spaces between HTML tags.
|
||||
*
|
||||
* @deprecated since Twig 2.7, to be removed in 3.0
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class SpacelessNode extends Node
|
||||
class SpacelessNode extends Node implements NodeOutputInterface
|
||||
{
|
||||
public function __construct(\Twig_NodeInterface $body, $lineno, $tag = 'spaceless')
|
||||
public function __construct(Node $body, int $lineno, string $tag = 'spaceless')
|
||||
{
|
||||
parent::__construct(['body' => $body], [], $lineno, $tag);
|
||||
}
|
||||
|
@@ -21,7 +21,7 @@ use Twig\Compiler;
|
||||
*/
|
||||
class TextNode extends Node implements NodeOutputInterface
|
||||
{
|
||||
public function __construct($data, $lineno)
|
||||
public function __construct(string $data, int $lineno)
|
||||
{
|
||||
parent::__construct([], ['data' => $data], $lineno);
|
||||
}
|
||||
|
@@ -20,14 +20,14 @@ use Twig\Compiler;
|
||||
*/
|
||||
class WithNode extends Node
|
||||
{
|
||||
public function __construct(Node $body, Node $variables = null, $only = false, $lineno, $tag = null)
|
||||
public function __construct(Node $body, ?Node $variables, bool $only, int $lineno, string $tag = null)
|
||||
{
|
||||
$nodes = ['body' => $body];
|
||||
if (null !== $variables) {
|
||||
$nodes['variables'] = $variables;
|
||||
}
|
||||
|
||||
parent::__construct($nodes, ['only' => (bool) $only], $lineno, $tag);
|
||||
parent::__construct($nodes, ['only' => $only], $lineno, $tag);
|
||||
}
|
||||
|
||||
public function compile(Compiler $compiler)
|
||||
|
Reference in New Issue
Block a user