* 0.9.6-DEV
+ * added support for __call() in expression resolution
+ * fixed node visiting for macros (macros are now visited by visitors as any other node)
* fixed nested block definitions with a parent call (rarely useful but nonetheless supported now)
* added the cycle filter
* fixed the Lexer when mbstring.func_overload is used with an mbstring.internal_encoding different from ASCII
abstract class Twig_Resource
{
protected $env;
+ protected $cache;
public function __construct(Twig_Environment $env)
{
$this->env = $env;
+ $this->cache = array();
}
public function getEnvironment()
return $object[$item];
}
- if ($arrayOnly)
+ if ($arrayOnly || !is_object($object))
{
return null;
}
- if (is_object($object) && isset($object->$item))
+ if (isset($object->$item))
{
if ($this->env->hasExtension('sandbox'))
{
return $object->$item;
}
- if (
- !is_object($object) ||
- (
- !method_exists($object, $method = $item) &&
- !method_exists($object, $method = 'get'.$item)
- )
- )
+ $class = get_class($object);
+
+ if (!isset($this->cache[$class]))
+ {
+ $r = new ReflectionClass($class);
+ $this->cache[$class] = array();
+ foreach ($r->getMethods(ReflectionMethod::IS_STATIC | ReflectionMethod::IS_PUBLIC | ReflectionMethod::IS_FINAL) as $method)
+ {
+ $this->cache[$class][strtolower($method->getName())] = true;
+ }
+ }
+
+ $item = strtolower($item);
+ if (isset($this->cache[$class][$item]))
+ {
+ $method = $item;
+ }
+ elseif (isset($this->cache[$class]['get'.$item]))
+ {
+ $method = 'get'.$item;
+ }
+ elseif (isset($this->cache[$class]['__call']))
+ {
+ $method = $item;
+ }
+ else
{
return null;
}
--- /dev/null
+--TEST--
+Twig supports __call() for attributes
+--TEMPLATE--
+{{ foo.foo }}
+{{ foo.bar }}
+--DATA--
+class TestClassForMagicCallAttributes
+{
+ public function getBar()
+ {
+ return 'bar_from_getbar';
+ }
+
+ public function __call($method, $arguments)
+ {
+ if ('foo' === $method)
+ {
+ return 'foo_from_call';
+ }
+
+ return false;
+ }
+}
+return array('foo' => new TestClassForMagicCallAttributes())
+--EXPECT--
+foo_from_call
+bar_from_getbar