mirror of
https://github.com/twigphp/Twig.git
synced 2026-09-15 20:06:31 +00:00
made Resource::getAttribute() more generic (WIP)
This commit is contained in:
@@ -370,21 +370,28 @@ class Twig_ExpressionParser
|
||||
$token = $this->parser->getStream()->next();
|
||||
$lineno = $token->getLine();
|
||||
$arguments = new Twig_Node();
|
||||
$type = Twig_Node_Expression_GetAttr::TYPE_ANY;
|
||||
if ($token->getValue() == '.') {
|
||||
$token = $this->parser->getStream()->next();
|
||||
if ($token->getType() == Twig_Token::NAME_TYPE || $token->getType() == Twig_Token::NUMBER_TYPE) {
|
||||
$arg = new Twig_Node_Expression_Constant($token->getValue(), $lineno);
|
||||
|
||||
if ($this->parser->getStream()->test(Twig_Token::OPERATOR_TYPE, '(')) {
|
||||
$type = Twig_Node_Expression_GetAttr::TYPE_METHOD;
|
||||
}
|
||||
|
||||
$arguments = $this->parseArguments();
|
||||
} else {
|
||||
throw new Twig_SyntaxError('Expected name or number', $lineno);
|
||||
}
|
||||
} else {
|
||||
$type = Twig_Node_Expression_GetAttr::TYPE_ARRAY;
|
||||
|
||||
$arg = $this->parseExpression();
|
||||
$this->parser->getStream()->expect(Twig_Token::OPERATOR_TYPE, ']');
|
||||
}
|
||||
|
||||
return new Twig_Node_Expression_GetAttr($node, $arg, $arguments, $lineno, $token->getValue());
|
||||
return new Twig_Node_Expression_GetAttr($node, $arg, $arguments, $lineno, $type);
|
||||
}
|
||||
|
||||
public function parseFilterExpression($node)
|
||||
|
||||
@@ -11,9 +11,13 @@
|
||||
*/
|
||||
class Twig_Node_Expression_GetAttr extends Twig_Node_Expression
|
||||
{
|
||||
public function __construct(Twig_Node_Expression $node, Twig_Node_Expression $attribute, Twig_NodeInterface $arguments, $lineno, $token_value = null)
|
||||
const TYPE_ANY = 'any';
|
||||
const TYPE_ARRAY = 'array';
|
||||
const TYPE_METHOD = 'method';
|
||||
|
||||
public function __construct(Twig_Node_Expression $node, Twig_Node_Expression $attribute, Twig_NodeInterface $arguments, $lineno, $type = self::TYPE_ANY)
|
||||
{
|
||||
parent::__construct(array('node' => $node, 'attribute' => $attribute, 'arguments' => $arguments), array('token_value' => $token_value), $lineno);
|
||||
parent::__construct(array('node' => $node, 'attribute' => $attribute, 'arguments' => $arguments), array('type' => $type), $lineno);
|
||||
}
|
||||
|
||||
public function compile($compiler)
|
||||
@@ -33,13 +37,9 @@ class Twig_Node_Expression_GetAttr extends Twig_Node_Expression
|
||||
;
|
||||
}
|
||||
|
||||
$compiler->raw(')');
|
||||
|
||||
// Don't look for functions if they're using foo[bar]
|
||||
if ('[' == $this['token_value']) {
|
||||
$compiler->raw(', true');
|
||||
}
|
||||
|
||||
$compiler->raw(')');
|
||||
$compiler
|
||||
->raw('), ')
|
||||
->repr($this['type'])
|
||||
->raw(')');
|
||||
}
|
||||
}
|
||||
|
||||
+24
-11
@@ -37,30 +37,43 @@ abstract class Twig_Resource
|
||||
throw new InvalidArgumentException(sprintf('Item "%s" from context does not exist.', $item));
|
||||
}
|
||||
|
||||
protected function getAttribute($object, $item, array $arguments = array(), $arrayOnly = false)
|
||||
protected function getAttribute($object, $item, array $arguments = array(), $type = Twig_Node_Expression_GetAttr::TYPE_ANY)
|
||||
{
|
||||
$item = (string) $item;
|
||||
// array
|
||||
if (Twig_Node_Expression_GetAttr::TYPE_METHOD !== $type) {
|
||||
if ((is_array($object) || is_object($object) && $object instanceof ArrayAccess) && isset($object[$item])) {
|
||||
return $object[$item];
|
||||
}
|
||||
|
||||
if ((is_array($object) || is_object($object) && $object instanceof ArrayAccess) && isset($object[$item])) {
|
||||
return $object[$item];
|
||||
if (Twig_Node_Expression_GetAttr::TYPE_ARRAY === $type) {
|
||||
if (!$this->env->isStrictVariables()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
throw new InvalidArgumentException(sprintf('Key "%s" for array "%s" does not exist.', $item, $object));
|
||||
}
|
||||
}
|
||||
|
||||
if ($arrayOnly || !is_object($object)) {
|
||||
if (!is_object($object)) {
|
||||
if (!$this->env->isStrictVariables()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
throw new InvalidArgumentException(sprintf('Key "%s" for array "%s" does not exist.', $item, $object));
|
||||
throw new InvalidArgumentException(sprintf('Item "%s" for "%s" does not exist.', $item, $object));
|
||||
}
|
||||
|
||||
if (isset($object->$item)) {
|
||||
if ($this->env->hasExtension('sandbox')) {
|
||||
$this->env->getExtension('sandbox')->checkPropertyAllowed($object, $item);
|
||||
// object property
|
||||
if (Twig_Node_Expression_GetAttr::TYPE_METHOD !== $type) {
|
||||
if (isset($object->$item)) {
|
||||
if ($this->env->hasExtension('sandbox')) {
|
||||
$this->env->getExtension('sandbox')->checkPropertyAllowed($object, $item);
|
||||
}
|
||||
|
||||
return $object->$item;
|
||||
}
|
||||
|
||||
return $object->$item;
|
||||
}
|
||||
|
||||
// object method
|
||||
$class = get_class($object);
|
||||
|
||||
if (!isset($this->cache[$class])) {
|
||||
|
||||
@@ -24,12 +24,12 @@ class Twig_Tests_Node_Expression_GetAttrTest extends Twig_Tests_Node_TestCase
|
||||
new Twig_Node_Expression_Name('foo', 0),
|
||||
new Twig_Node_Expression_Constant('bar', 0),
|
||||
));
|
||||
$node = new Twig_Node_Expression_GetAttr($expr, $attr, $args, 0, '[');
|
||||
$node = new Twig_Node_Expression_GetAttr($expr, $attr, $args, 0, Twig_Node_Expression_GetAttr::TYPE_ARRAY);
|
||||
|
||||
$this->assertEquals($expr, $node->node);
|
||||
$this->assertEquals($attr, $node->attribute);
|
||||
$this->assertEquals($args, $node->arguments);
|
||||
$this->assertEquals('[', $node['token_value']);
|
||||
$this->assertEquals(Twig_Node_Expression_GetAttr::TYPE_ARRAY, $node['type']);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -49,17 +49,18 @@ class Twig_Tests_Node_Expression_GetAttrTest extends Twig_Tests_Node_TestCase
|
||||
$attr = new Twig_Node_Expression_Constant('bar', 0);
|
||||
$args = new Twig_Node();
|
||||
$node = new Twig_Node_Expression_GetAttr($expr, $attr, $args, 0);
|
||||
$tests[] = array($node, '$this->getAttribute($this->getContext($context, \'foo\'), "bar", array())');
|
||||
$tests[] = array($node, '$this->getAttribute($this->getContext($context, \'foo\'), "bar", array(), "any")');
|
||||
|
||||
$node = new Twig_Node_Expression_GetAttr($expr, $attr, $args, 0, Twig_Node_Expression_GetAttr::TYPE_ARRAY);
|
||||
$tests[] = array($node, '$this->getAttribute($this->getContext($context, \'foo\'), "bar", array(), "array")');
|
||||
|
||||
$node = new Twig_Node_Expression_GetAttr($expr, $attr, $args, 0, '[');
|
||||
$tests[] = array($node, '$this->getAttribute($this->getContext($context, \'foo\'), "bar", array(), true)');
|
||||
|
||||
$args = new Twig_Node(array(
|
||||
new Twig_Node_Expression_Name('foo', 0),
|
||||
new Twig_Node_Expression_Constant('bar', 0),
|
||||
));
|
||||
$node = new Twig_Node_Expression_GetAttr($expr, $attr, $args, 0);
|
||||
$tests[] = array($node, '$this->getAttribute($this->getContext($context, \'foo\'), "bar", array($this->getContext($context, \'foo\'), "bar", ))');
|
||||
$node = new Twig_Node_Expression_GetAttr($expr, $attr, $args, 0, Twig_Node_Expression_GetAttr::TYPE_METHOD);
|
||||
$tests[] = array($node, '$this->getAttribute($this->getContext($context, \'foo\'), "bar", array($this->getContext($context, \'foo\'), "bar", ), "method")');
|
||||
|
||||
return $tests;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user