diff --git a/core/Object.php b/core/Object.php index d2cf878dc..56ee9cac4 100755 --- a/core/Object.php +++ b/core/Object.php @@ -970,7 +970,7 @@ abstract class Object { if(!empty($this->beforeExtendCallbacks[$method])) { foreach(array_reverse($this->beforeExtendCallbacks[$method]) as $callback) { - $value = call_user_func($callback, $a1, $a2, $a3, $a4, $a5, $a6, $a7); + $value = call_user_func_array($callback, array(&$a1, &$a2, &$a3, &$a4, &$a5, &$a6, &$a7)); if($value !== null) $values[] = $value; } $this->beforeExtendCallbacks[$method] = array(); @@ -987,7 +987,7 @@ abstract class Object { if(!empty($this->afterExtendCallbacks[$method])) { foreach(array_reverse($this->afterExtendCallbacks[$method]) as $callback) { - $value = call_user_func($callback, $a1, $a2, $a3, $a4, $a5, $a6, $a7); + $value = call_user_func_array($callback, array(&$a1, &$a2, &$a3, &$a4, &$a5, &$a6, &$a7)); if($value !== null) $values[] = $value; } $this->afterExtendCallbacks[$method] = array(); diff --git a/tests/core/ObjectTest.php b/tests/core/ObjectTest.php index d4ee89969..487affb97 100644 --- a/tests/core/ObjectTest.php +++ b/tests/core/ObjectTest.php @@ -383,6 +383,19 @@ class ObjectTest extends SapphireTest { $object->invokeWithExtensions('extendableMethod', 'test'), array('ExtendTest(test)', 'ExtendTest2(modified)') ); + + $object2 = new ObjectTest_Extending(); + $first = 1; + $second = 2; + $third = 3; + $result = $object2->getResults($first, $second, $third); + $this->assertEquals( + array(array('before', 'extension', 'after')), + $result + ); + $this->assertEquals(31, $first); + $this->assertEquals(32, $second); + $this->assertEquals(33, $third); } public function testParseClassSpec() { @@ -600,4 +613,52 @@ class ObjectTest_ExtendTest4 extends ObjectTest_ExtendTest3 { public function extendableMethod($argument = null) { return "ExtendTest4($argument)"; } } +class ObjectTest_Extending extends Object implements TestOnly { + + private static $extensions = array( + 'ObjectTest_Extending_Extension' + ); + + public function getResults(&$first, &$second, &$third) { + // Before extending should be invoked second + $this->beforeExtending('updateResult', function(&$first, &$second, &$third) { + if($first === 1 && $second === 2 && $third === 3) { + $first = 11; + $second = 12; + $third = 13; + return 'before'; + } + return 'before-error'; + }); + + // After extending should be invoked fourth + $this->afterExtending('updateResult', function(&$first, &$second, &$third) { + if($first === 21 && $second === 22 && $third = 23) { + $first = 31; + $second = 32; + $third = 33; + return 'after'; + } + return 'after-error'; + }); + + // Function body invoked first + $result = $this->extend('updateResult', $first, $second, $third); + return array($result); + } +} + +class ObjectTest_Extending_Extension extends Extension implements TestOnly { + public function updateResult(&$first, &$second, &$third) { + // Extension should be invoked third + if($first === 11 && $second === 12 && $third == 13) { + $first = 21; + $second = 22; + $third = 23; + return 'extension'; + } + return 'extension-error'; + } +} + /**#@-*/