/** * @param \Brick\Http\Request $request The request to handle. * * @return \Brick\Http\Response The generated response. * * @throws \Brick\Http\Exception\HttpException If a route throws such an exception, or no route matches the request. * @throws \UnexpectedValueException If a route or controller returned an invalid value. */ private function handleRequest(Request $request) { $event = new IncomingRequestEvent($request); $this->eventDispatcher->dispatch(IncomingRequestEvent::class, $event); $match = $this->route($request); $event = new RouteMatchedEvent($request, $match); $this->eventDispatcher->dispatch(RouteMatchedEvent::class, $event); $controllerReflection = $match->getControllerReflection(); $instance = null; $this->valueResolver->setRequest($request); $this->valueResolver->setParameters($match->getClassParameters()); if ($controllerReflection instanceof \ReflectionMethod) { $className = $controllerReflection->getDeclaringClass()->getName(); $instance = $this->injector->instantiate($className); $callable = $controllerReflection->getClosure($instance); } elseif ($controllerReflection instanceof \ReflectionFunction) { $callable = $controllerReflection->getClosure(); } else { throw new \UnexpectedValueException('Unknown controller reflection type.'); } $event = new ControllerReadyEvent($request, $match, $instance); $event->addParameters($match->getFunctionParameters()); $this->eventDispatcher->dispatch(ControllerReadyEvent::class, $event); $response = $event->getResponse(); if ($response === null) { $this->valueResolver->setParameters($event->getParameters()); try { $result = $this->injector->invoke($callable); if ($result instanceof Response) { $response = $result; } else { $event = new NonResponseResultEvent($request, $match, $instance, $result); $this->eventDispatcher->dispatch(NonResponseResultEvent::class, $event); $response = $event->getResponse(); if ($response === null) { throw $this->invalidReturnValue('controller', Response::class, $result); } } } catch (HttpException $e) { $response = $this->handleHttpException($e, $request); } finally { $event = new ControllerInvocatedEvent($request, $match, $instance); $this->eventDispatcher->dispatch(ControllerInvocatedEvent::class, $event); } } $event = new ResponseReceivedEvent($request, $response, $match, $instance); $this->eventDispatcher->dispatch(ResponseReceivedEvent::class, $event); return $response; }
public function testDispatchAndStopPropagation() { $dispatcher = new EventDispatcher(); $listener1 = new LoggerListener(); $listener2 = new LoggerListener(); $dispatcher->addListener('x', $listener1); $dispatcher->addListener('x', $listener2); $dispatcher->addListener('y', $listener2); $dispatcher->dispatch('x', '1'); $this->assertReceivedParameters($listener1, '1'); $this->assertReceivedParameters($listener2, '1'); $dispatcher->dispatch('y', '2'); $this->assertReceivedParameters($listener1, '1'); $this->assertReceivedParameters($listener2, '1', '2'); $listener1->setStopPropagation(true); $dispatcher->dispatch('x', '3'); $this->assertReceivedParameters($listener1, '1', '3'); $this->assertReceivedParameters($listener2, '1', '2'); $listener1->setStopPropagation(false); $listener2->setStopPropagation(true); $dispatcher->dispatch('x', '4', '5'); $this->assertReceivedParameters($listener1, '1', '3', '4', '5'); $this->assertReceivedParameters($listener2, '1', '2', '4', '5'); $dispatcher->dispatch('z', '6'); $this->assertReceivedParameters($listener1, '1', '3', '4', '5'); $this->assertReceivedParameters($listener2, '1', '2', '4', '5'); }