From 96968f7194708519980f2ac9e1411aca2ce5e793 Mon Sep 17 00:00:00 2001 From: mark_story Date: Sun, 12 Dec 2010 14:10:22 -0500 Subject: [PATCH] Moving the modParams option into ObjectCollection, so it can replace the specific trigger method in BehaviorCollection. Changed how break behaves, so it is works better with modParams and collectReturn options. Tests updated and expanded. --- cake/libs/object_collection.php | 37 +++++++-- .../cases/libs/object_collection.test.php | 80 ++++++++++++++++--- 2 files changed, 101 insertions(+), 16 deletions(-) diff --git a/cake/libs/object_collection.php b/cake/libs/object_collection.php index e9dd53abe..ea0ee8455 100644 --- a/cake/libs/object_collection.php +++ b/cake/libs/object_collection.php @@ -60,12 +60,20 @@ abstract class ObjectCollection { * ### Options * * - `breakOn` Set to the value or values you want the callback propagation to stop on. - * Defaults to `false` - * - `break` Set to true to enabled breaking. Defaults to `false`. + * Can either be a scalar value, or an array of values to break on. Defaults to `false`. + * + * - `break` Set to true to enabled breaking. When a trigger is broken, the last returned value + * will be returned. If used in combination with `collectReturn` the collected results will be returned. + * Defaults to `false`. + * * - `collectReturn` Set to true to collect the return of each object into an array. * This array of return values will be returned from the trigger() call. Defaults to `false`. + * * - `triggerDisabled` Will trigger the callback on all objects in the collection even the non-enabled - * objects. Defaults to false. + * objects. Defaults to false. + * + * - `modParams` Allows each object the callback gets called on to modify the parameters to the next object. + * Setting modParams to an integer value will allow you to modify the parameter with that index. Defaults to false. * * @param string $callback Method to fire on all the objects. Its assumed all the objects implement * the method you are calling. @@ -78,7 +86,13 @@ abstract class ObjectCollection { return true; } $options = array_merge( - array('break' => false, 'breakOn' => false, 'collectReturn' => false, 'triggerDisabled' => false), + array( + 'break' => false, + 'breakOn' => false, + 'collectReturn' => false, + 'triggerDisabled' => false, + 'modParams' => false + ), $options ); $collected = array(); @@ -86,8 +100,12 @@ abstract class ObjectCollection { if ($options['triggerDisabled'] === true) { $list = array_keys($this->_loaded); } + if ($options['modParams'] !== false && !isset($params[$options['modParams']])) { + throw new CakeException(__('Cannot use modParams with indexes that do not exist.')); + } + foreach ($list as $name) { - $result = call_user_func_array(array(&$this->_loaded[$name], $callback), $params); + $result = call_user_func_array(array($this->_loaded[$name], $callback), $params); if ($options['collectReturn'] === true) { $collected[] = $result; } @@ -95,10 +113,15 @@ abstract class ObjectCollection { $options['break'] && ($result === $options['breakOn'] || (is_array($options['breakOn']) && in_array($result, $options['breakOn'], true))) ) { - return ($options['collectReturn'] === true) ? $collected : $result; + break; + } elseif ($options['modParams'] !== false) { + $params[$options['modParams']] = $result; } } - return $options['collectReturn'] ? $collected : true; + if ($options['modParams'] !== false) { + return $params[$options['modParams']]; + } + return $options['collectReturn'] ? $collected : $result; } /** diff --git a/cake/tests/cases/libs/object_collection.test.php b/cake/tests/cases/libs/object_collection.test.php index 9d0861861..c2105558c 100644 --- a/cake/tests/cases/libs/object_collection.test.php +++ b/cake/tests/cases/libs/object_collection.test.php @@ -158,9 +158,11 @@ class ObjectCollectionTest extends CakeTestCase { $this->Objects->load('TriggerMockSecond'); $this->Objects->TriggerMockFirst->expects($this->once()) - ->method('callback'); + ->method('callback') + ->will($this->returnValue(true)); $this->Objects->TriggerMockSecond->expects($this->once()) - ->method('callback'); + ->method('callback') + ->will($this->returnValue(true)); $this->assertTrue($this->Objects->trigger('callback')); } @@ -170,15 +172,17 @@ class ObjectCollectionTest extends CakeTestCase { * * @return void */ - function testTriggerWithTriggerDisabledObjects() { + function testTriggerWithTriggerDisabledObjects() { $this->_makeMockClasses(); $this->Objects->load('TriggerMockFirst', array(), false); $this->Objects->load('TriggerMockSecond'); $this->Objects->TriggerMockFirst->expects($this->once()) - ->method('callback'); + ->method('callback') + ->will($this->returnValue(true)); $this->Objects->TriggerMockSecond->expects($this->once()) - ->method('callback'); + ->method('callback') + ->will($this->returnValue(true)); $result = $this->Objects->trigger('callback', array(), array('triggerDisabled' => true)); $this->assertTrue($result); @@ -195,9 +199,11 @@ class ObjectCollectionTest extends CakeTestCase { $this->Objects->load('TriggerMockSecond'); $this->Objects->TriggerMockFirst->expects($this->once()) - ->method('callback'); + ->method('callback') + ->will($this->returnValue(true)); $this->Objects->TriggerMockSecond->expects($this->never()) - ->method('callback'); + ->method('callback') + ->will($this->returnValue(true)); $this->Objects->disable('TriggerMockSecond'); @@ -247,12 +253,68 @@ class ObjectCollectionTest extends CakeTestCase { $result = $this->Objects->trigger( 'callback', - array(&$controller), + array(), array('break' => true, 'breakOn' => false) ); $this->assertFalse($result); } +/** + * test that trigger with modParams works. + * + * @return void + */ + function testTriggerWithModParams() { + $this->_makeMockClasses(); + $this->Objects->load('TriggerMockFirst'); + $this->Objects->load('TriggerMockSecond'); + + $this->Objects->TriggerMockFirst->expects($this->once()) + ->method('callback') + ->with(array('value')) + ->will($this->returnValue(array('new value'))); + + $this->Objects->TriggerMockSecond->expects($this->once()) + ->method('callback') + ->with(array('new value')) + ->will($this->returnValue(array('newer value'))); + + $result = $this->Objects->trigger( + 'callback', + array(array('value')), + array('modParams' => 0) + ); + $this->assertEquals(array('newer value'), $result); + } + +/** + * test that setting modParams to an index that doesn't exist doesn't cause errors. + * + * @expectedException CakeException + * @return void + */ + function testTriggerModParamsInvalidIndex() { + $this->_makeMockClasses(); + $this->Objects->load('TriggerMockFirst'); + $this->Objects->load('TriggerMockSecond'); + + $this->Objects->TriggerMockFirst->expects($this->once()) + ->method('callback') + ->with(array('value')) + ->will($this->returnValue(array('new value'))); + + $this->Objects->TriggerMockSecond->expects($this->once()) + ->method('callback') + ->with(array('value')) + ->will($this->returnValue(array('newer value'))); + + $result = $this->Objects->trigger( + 'callback', + array(array('value')), + array('modParams' => 2) + ); + } + /** * test normalizeObjectArray * @@ -265,7 +327,7 @@ class ObjectCollectionTest extends CakeTestCase { 'Something', 'Banana.Apple' => array('foo' => 'bar') ); - $result = ComponentCollection::normalizeObjectArray($components); + $result = ObjectCollection::normalizeObjectArray($components); $expected = array( 'Html' => array('class' => 'Html', 'settings' => array()), 'Bar' => array('class' => 'Foo.Bar', 'settings' => array('one', 'two')),