Allow is defined test on complex variables
authorJordi Boggiano <j.boggiano@seld.be>
Fri, 26 Nov 2010 17:58:49 +0000 (18:58 +0100)
committerFabien Potencier <fabien.potencier@gmail.com>
Fri, 26 Nov 2010 18:06:50 +0000 (19:06 +0100)
lib/Twig/Node/Expression/GetAttr.php
lib/Twig/Node/Expression/Test.php
lib/Twig/Template.php

index 28f7376..64439e3 100644 (file)
@@ -39,7 +39,12 @@ class Twig_Node_Expression_GetAttr extends Twig_Node_Expression
 
         $compiler
             ->raw('), ')
-            ->repr($this->getAttribute('type'))
-            ->raw(')');
+            ->repr($this->getAttribute('type'));
+
+        if ($this->hasAttribute('is_defined_test')) {
+            $compiler->raw(', true');
+        }
+
+        $compiler->raw(')');
     }
 }
index 50cb293..2ab9aa2 100644 (file)
@@ -24,16 +24,18 @@ class Twig_Node_Expression_Test extends Twig_Node_Expression
 
         // defined is a special case
         if ('defined' === $this->getAttribute('name')) {
-            if (!$this->getNode('node') instanceof Twig_Node_Expression_Name){
+            if ($this->getNode('node') instanceof Twig_Node_Expression_Name) {
+                $compiler
+                    ->raw($testMap[$this->getAttribute('name')]->compile().'(')
+                    ->repr($this->getNode('node')->getAttribute('name'))
+                    ->raw(', $context)')
+                ;
+            } elseif ($this->getNode('node') instanceof Twig_Node_Expression_GetAttr) {
+                $this->getNode('node')->setAttribute('is_defined_test', true);
+                $compiler->subcompile($this->getNode('node'));
+            } else {
                 throw new Twig_Error_Syntax('The "defined" test only works with simple variables', $this->getLine());
             }
-
-            $compiler
-                ->raw($testMap[$this->getAttribute('name')]->compile().'(')
-                ->repr($this->getNode('node')->getAttribute('name'))
-                ->raw(', $context)')
-            ;
-
             return;
         }
 
index a1566fd..3fad2f8 100644 (file)
@@ -96,7 +96,7 @@ abstract class Twig_Template implements Twig_TemplateInterface
         return $context[$item];
     }
 
-    protected function getAttribute($object, $item, array $arguments = array(), $type = Twig_Node_Expression_GetAttr::TYPE_ANY)
+    protected function getAttribute($object, $item, array $arguments = array(), $type = Twig_Node_Expression_GetAttr::TYPE_ANY, $noStrictCheck = false)
     {
         // array
         if (Twig_Node_Expression_GetAttr::TYPE_METHOD !== $type) {
@@ -105,7 +105,7 @@ abstract class Twig_Template implements Twig_TemplateInterface
             }
 
             if (Twig_Node_Expression_GetAttr::TYPE_ARRAY === $type) {
-                if (!$this->env->isStrictVariables()) {
+                if (!$this->env->isStrictVariables() || $noStrictCheck) {
                     return null;
                 }
 
@@ -114,10 +114,9 @@ abstract class Twig_Template implements Twig_TemplateInterface
         }
 
         if (!is_object($object)) {
-            if (!$this->env->isStrictVariables()) {
+            if (!$this->env->isStrictVariables() || $noStrictCheck) {
                 return null;
             }
-
             throw new Twig_Error_Runtime(sprintf('Item "%s" for "%s" does not exist.', $item, $object));
         }
 
@@ -157,7 +156,7 @@ abstract class Twig_Template implements Twig_TemplateInterface
         } elseif (isset(self::$cache[$class]['methods']['__call'])) {
             $method = $item;
         } else {
-            if (!$this->env->isStrictVariables()) {
+            if (!$this->env->isStrictVariables() || $noStrictCheck) {
                 return null;
             }