From a0c44d238a6d09a6025fd38b42efff2343e9fc48 Mon Sep 17 00:00:00 2001 From: Frédéric Guillot Date: Fri, 1 Jun 2018 16:35:45 -0700 Subject: Make sure automatic actions are applied to all tasks when using bulk operations --- app/Action/Base.php | 17 ++++++++++------- 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')); + } } -- cgit v1.2.3