Fix ArrayAccess priority:
* Methods brump properties and ArrayAccess * Properties beat ArrayAccess * ArrayAccess beats nothing at all * ArrayAccess also beats private properties Add a test case to verify. See #178
This commit is contained in:
@@ -133,17 +133,13 @@ class Mustache_Context
|
|||||||
private function findVariableInStack($id, array $stack)
|
private function findVariableInStack($id, array $stack)
|
||||||
{
|
{
|
||||||
for ($i = count($stack) - 1; $i >= 0; $i--) {
|
for ($i = count($stack) - 1; $i >= 0; $i--) {
|
||||||
if (is_object($stack[$i])) {
|
if (is_object($stack[$i]) && !($stack[$i] instanceof Closure)) {
|
||||||
if ($stack[$i] instanceof ArrayAccess) {
|
|
||||||
if (isset($stack[$i][$id])) {
|
|
||||||
return $stack[$i][$id];
|
|
||||||
}
|
|
||||||
} elseif (!($stack[$i] instanceof Closure)) {
|
|
||||||
if (method_exists($stack[$i], $id)) {
|
if (method_exists($stack[$i], $id)) {
|
||||||
return $stack[$i]->$id();
|
return $stack[$i]->$id();
|
||||||
} elseif (isset($stack[$i]->$id)) {
|
} elseif (isset($stack[$i]->$id)) {
|
||||||
return $stack[$i]->$id;
|
return $stack[$i]->$id;
|
||||||
}
|
} elseif ($stack[$i] instanceof ArrayAccess && isset($stack[$i][$id])) {
|
||||||
|
return $stack[$i][$id];
|
||||||
}
|
}
|
||||||
} elseif (is_array($stack[$i]) && array_key_exists($id, $stack[$i])) {
|
} elseif (is_array($stack[$i]) && array_key_exists($id, $stack[$i])) {
|
||||||
return $stack[$i][$id];
|
return $stack[$i][$id];
|
||||||
|
|||||||
@@ -109,6 +109,16 @@ class Mustache_Test_ContextTest extends PHPUnit_Framework_TestCase
|
|||||||
$this->assertEquals('see', $context->findDot('a.b.c'));
|
$this->assertEquals('see', $context->findDot('a.b.c'));
|
||||||
$this->assertEquals(null, $context->findDot('a.b.c.d'));
|
$this->assertEquals(null, $context->findDot('a.b.c.d'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testAccessorPriority()
|
||||||
|
{
|
||||||
|
$context = new Mustache_Context(new Mustache_Test_AllTheThings);
|
||||||
|
|
||||||
|
$this->assertEquals('win', $context->find('foo'), 'method beats property');
|
||||||
|
$this->assertEquals('win', $context->find('bar'), 'property beats ArrayAccess');
|
||||||
|
$this->assertEquals('win', $context->find('baz'), 'ArrayAccess stands alone');
|
||||||
|
$this->assertEquals('win', $context->find('qux'), 'ArrayAccess beats private property');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Mustache_Test_TestDummy
|
class Mustache_Test_TestDummy
|
||||||
@@ -166,3 +176,46 @@ class Mustache_Test_TestArrayAccess implements ArrayAccess
|
|||||||
return isset($this->container[$offset]) ? $this->container[$offset] : null;
|
return isset($this->container[$offset]) ? $this->container[$offset] : null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class Mustache_Test_AllTheThings implements ArrayAccess
|
||||||
|
{
|
||||||
|
public $foo = 'fail';
|
||||||
|
public $bar = 'win';
|
||||||
|
private $qux = 'fail';
|
||||||
|
|
||||||
|
public function foo()
|
||||||
|
{
|
||||||
|
return 'win';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function offsetExists($offset)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function offsetGet($offset)
|
||||||
|
{
|
||||||
|
switch ($offset) {
|
||||||
|
case 'foo':
|
||||||
|
case 'bar':
|
||||||
|
return 'fail';
|
||||||
|
|
||||||
|
case 'baz':
|
||||||
|
case 'qux':
|
||||||
|
return 'win';
|
||||||
|
|
||||||
|
default:
|
||||||
|
return 'lolwhut';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function offsetSet($offset, $value)
|
||||||
|
{
|
||||||
|
// nada
|
||||||
|
}
|
||||||
|
|
||||||
|
public function offsetUnset($offset)
|
||||||
|
{
|
||||||
|
// nada
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user