Reset stop-propagation flag when triggering event #4147

Closed
wants to merge 3 commits into
from
@@ -201,6 +201,9 @@ public function trigger($event, $target = null, $argv = array(), $callback = nul
throw new Exception\InvalidCallbackException('Invalid callback provided');
}
+ // Initial value of stop propagation flag should be false
+ $e->stopPropagation(false);
+
return $this->triggerListeners($event, $e, $callback);
}
@@ -243,6 +246,9 @@ public function triggerUntil($event, $target, $argv = null, $callback = null)
throw new Exception\InvalidCallbackException('Invalid callback provided');
}
+ // Initial value of stop propagation flag should be false
+ $e->stopPropagation(false);
+
return $this->triggerListeners($event, $e, $callback);
}
@@ -657,4 +657,37 @@ public function testDoesNotCreateStaticInstanceIfNonePresent()
StaticEventManager::resetInstance();
$this->assertFalse($this->events->getSharedManager());
}
+
+ public function testTriggerSetsStopPropagationFlagToFalse()
+ {
+ $marker = (object) array('propagationIsStopped' => true);
+ $this->events->attach('foo', function ($e) use ($marker) {
+ $marker->propagationIsStopped = $e->propagationIsStopped();
+ });
+
+ $event = new Event();
+ $event->stopPropagation(true);
+ $this->events->trigger('foo', $event);
+
+ $this->assertFalse($marker->propagationIsStopped);
+ $this->assertFalse($event->propagationIsStopped());
+ }
+
+ public function testTriggerUntilSetsStopPropagationFlagToFalse()
+ {
+ $marker = (object) array('propagationIsStopped' => true);
+ $this->events->attach('foo', function ($e) use ($marker) {
+ $marker->propagationIsStopped = $e->propagationIsStopped();
+ });
+
+ $criteria = function ($r) {
+ return false;
+ };
+ $event = new Event();
+ $event->stopPropagation(true);
+ $this->events->triggerUntil('foo', $event, $criteria);
+
+ $this->assertFalse($marker->propagationIsStopped);
+ $this->assertFalse($event->propagationIsStopped());
+ }
}
@@ -657,4 +657,50 @@ public function testCompleteRequestShouldReturnApplicationInstance()
$result = $method->invoke($this->application, $event);
$this->assertSame($this->application, $result);
}
+
+ public function eventPropagation()
+ {
+ return array(
+ 'route' => array(array(MvcEvent::EVENT_ROUTE)),
+ 'dispatch' => array(array(MvcEvent::EVENT_DISPATCH, MvcEvent::EVENT_RENDER, MvcEvent::EVENT_FINISH)),
+ );
+ }
+
+ /**
+ * @dataProvider eventPropagation
+ */
+ public function testEventPropagationStatusIsClearedBetweenEventsDuringRun($events)
+ {
+ $event = new MvcEvent();
+ $event->setTarget($this->application);
+ $event->setApplication($this->application)
+ ->setRequest($this->application->getRequest())
+ ->setResponse($this->application->getResponse())
+ ->setRouter($this->serviceManager->get('Router'));
+ $event->stopPropagation(true);
+
+ // Intentionally not calling bootstrap; setting mvc event
+ $r = new ReflectionObject($this->application);
+ $eventProp = $r->getProperty('event');
+ $eventProp->setAccessible(true);
+ $eventProp->setValue($this->application, $event);
+
+ // Setup listeners that stop propagation, but do nothing else
+ $marker = array();
+ foreach ($events as $event) {
+ $marker[$event] = true;
+ }
+ $marker = (object) $marker;
+ $listener = function ($e) use ($marker) {
+ $marker->{$e->getName()} = $e->propagationIsStopped();
+ $e->stopPropagation(true);
+ };
+ $this->application->getEventManager()->attach($events, $listener);
+
+ $this->application->run();
+
+ foreach ($events as $event) {
+ $this->assertFalse($marker->{$event}, sprintf('Assertion failed for event "%s"', $event));
+ }
+ }
}