diff options
-rw-r--r-- | app/Action/Base.php | 17 | ||||
-rw-r--r-- | tests/units/Action/BaseActionTest.php | 14 |
2 files changed, 24 insertions, 7 deletions
diff --git a/app/Action/Base.php b/app/Action/Base.php index 9a502a08..a9939388 100644 --- a/app/Action/Base.php +++ b/app/Action/Base.php @@ -21,12 +21,12 @@ abstract class Base extends \Kanboard\Core\Base private $compatibleEvents = array(); /** - * Flag for called listener + * Keep history of executed events * * @access private - * @var boolean + * @var array */ - private $called = false; + private $callStack = []; /** * Project id @@ -252,17 +252,20 @@ abstract class Base extends \Kanboard\Core\Base */ public function execute(GenericEvent $event, $eventName) { - // Avoid infinite loop, a listener instance can be called only one time - if ($this->called) { + $data = $event->getAll(); + $hash = md5(serialize($data).$eventName); + + // Do not call twice the same action with the same arguments. + if (isset($this->callStack[$hash])) { return false; + } else { + $this->callStack[$hash] = true; } - $data = $event->getAll(); $executable = $this->isExecutable($data, $eventName); $executed = false; if ($executable) { - $this->called = true; $executed = $this->doAction($data); } diff --git a/tests/units/Action/BaseActionTest.php b/tests/units/Action/BaseActionTest.php index feeba3f9..50c68fb5 100644 --- a/tests/units/Action/BaseActionTest.php +++ b/tests/units/Action/BaseActionTest.php @@ -141,4 +141,18 @@ class BaseActionTest extends Base $this->assertTrue($dummyAction->execute($event, 'foobar')); $this->assertFalse($dummyAction->execute($event, 'foobar')); } + + public function testExecuteSameActionSeveralTimesWithDifferentEvents() + { + $dummyAction = new DummyAction($this->container); + $dummyAction->setProjectId(1234); + $dummyAction->setParam('p1', 'something'); + $dummyAction->addEvent('foobar', 'FooBar'); + + $event1 = new GenericEvent(array('project_id' => 1234, 'p1' => 'something', 'p2' => 'abc', 'p3' => array('p4' => 'a'))); + $event2 = new GenericEvent(array('project_id' => 1234, 'p1' => 'something', 'p2' => 'abc', 'p3' => array('p4' => 'b'))); + + $this->assertTrue($dummyAction->execute($event1, 'foobar')); + $this->assertTrue($dummyAction->execute($event2, 'foobar')); + } } |