8b62df7247
The three notification methods do not return the Event instance anymore. notify() does not return anything notifyUntil() returns the returned value of the event that has processed the event filter() returns the filtered value Upgrading your listeners: Listeners for notify() and filter() events: nothing to change Listeners for notifyUntil() events: Before: $event->setReturnValue('foo'); return true; After: $event->setProcessed(); return 'foo'; If you notify events, the processing also need to be changed: For filter() notifications: the filtered value is now available as the returned value of the filter() method. For notifyUntil() notifications: Before: $event = $dispatcher->notifyUntil($event); if ($event->isProcessed()) { $ret = $event->getReturnValue(); // do something with $ret } After: $ret = $dispatcher->notifyUntil($event); if ($event->isProcessed()) { // do something with $ret }
142 lines
5.3 KiB
PHP
142 lines
5.3 KiB
PHP
<?php
|
|
|
|
/*
|
|
* This file is part of the Symfony package.
|
|
*
|
|
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
|
|
*
|
|
* For the full copyright and license information, please view the LICENSE
|
|
* file that was distributed with this source code.
|
|
*/
|
|
|
|
namespace Symfony\Component\HttpKernel;
|
|
|
|
use Symfony\Component\EventDispatcher\Event;
|
|
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
|
use Symfony\Component\HttpKernel\Controller\ControllerResolverInterface;
|
|
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
|
use Symfony\Component\HttpFoundation\Request;
|
|
use Symfony\Component\HttpFoundation\Response;
|
|
|
|
/**
|
|
* HttpKernel notifies events to convert a Request object to a Response one.
|
|
*
|
|
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
|
|
*/
|
|
class HttpKernel implements HttpKernelInterface
|
|
{
|
|
protected $dispatcher;
|
|
protected $resolver;
|
|
|
|
/**
|
|
* Constructor
|
|
*
|
|
* @param EventDispatcherInterface $dispatcher An EventDispatcherInterface instance
|
|
* @param ControllerResolverInterface $resolver A ControllerResolverInterface instance
|
|
*/
|
|
public function __construct(EventDispatcherInterface $dispatcher, ControllerResolverInterface $resolver)
|
|
{
|
|
$this->dispatcher = $dispatcher;
|
|
$this->resolver = $resolver;
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*/
|
|
public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQUEST, $catch = true)
|
|
{
|
|
try {
|
|
$response = $this->handleRaw($request, $type);
|
|
} catch (\Exception $e) {
|
|
if (false === $catch) {
|
|
throw $e;
|
|
}
|
|
|
|
// exception
|
|
$event = new Event($this, 'core.exception', array('request_type' => $type, 'request' => $request, 'exception' => $e));
|
|
$response = $this->dispatcher->notifyUntil($event);
|
|
if (!$event->isProcessed()) {
|
|
throw $e;
|
|
}
|
|
|
|
$response = $this->filterResponse($response, $request, 'A "core.exception" listener returned a non response object.', $type);
|
|
}
|
|
|
|
return $response;
|
|
}
|
|
|
|
/**
|
|
* Handles a request to convert it to a response.
|
|
*
|
|
* Exceptions are not caught.
|
|
*
|
|
* @param Request $request A Request instance
|
|
* @param integer $type The type of the request (one of HttpKernelInterface::MASTER_REQUEST or HttpKernelInterface::SUB_REQUEST)
|
|
*
|
|
* @return Response A Response instance
|
|
*
|
|
* @throws \LogicException If one of the listener does not behave as expected
|
|
* @throws NotFoundHttpException When controller cannot be found
|
|
*/
|
|
protected function handleRaw(Request $request, $type = self::MASTER_REQUEST)
|
|
{
|
|
// request
|
|
$event = new Event($this, 'core.request', array('request_type' => $type, 'request' => $request));
|
|
$response = $this->dispatcher->notifyUntil($event);
|
|
if ($event->isProcessed()) {
|
|
return $this->filterResponse($response, $request, 'A "core.request" listener returned a non response object.', $type);
|
|
}
|
|
|
|
// load controller
|
|
if (false === $controller = $this->resolver->getController($request)) {
|
|
throw new NotFoundHttpException(sprintf('Unable to find the controller for "%s", check your route configuration.', $request->getPathInfo()));
|
|
}
|
|
|
|
$event = new Event($this, 'core.controller', array('request_type' => $type, 'request' => $request));
|
|
$controller = $this->dispatcher->filter($event, $controller);
|
|
|
|
// controller must be a callable
|
|
if (!is_callable($controller)) {
|
|
throw new \LogicException(sprintf('The controller must be a callable (%s).', var_export($controller, true)));
|
|
}
|
|
|
|
// controller arguments
|
|
$arguments = $this->resolver->getArguments($request, $controller);
|
|
|
|
// call controller
|
|
$retval = call_user_func_array($controller, $arguments);
|
|
|
|
// view
|
|
$event = new Event($this, 'core.view', array('request_type' => $type, 'request' => $request));
|
|
$response = $this->dispatcher->filter($event, $retval);
|
|
|
|
return $this->filterResponse($response, $request, sprintf('The controller must return a response (instead of %s).', is_object($response) ? 'an object of class '.get_class($response) : is_array($response) ? 'an array' : str_replace("\n", '', var_export($response, true))), $type);
|
|
}
|
|
|
|
/**
|
|
* Filters a response object.
|
|
*
|
|
* @param Response $response A Response instance
|
|
* @param string $message A error message in case the response is not a Response object
|
|
* @param integer $type The type of the request (one of HttpKernelInterface::MASTER_REQUEST or HttpKernelInterface::SUB_REQUEST)
|
|
*
|
|
* @return Response The filtered Response instance
|
|
*
|
|
* @throws \RuntimeException if the passed object is not a Response instance
|
|
*/
|
|
protected function filterResponse($response, $request, $message, $type)
|
|
{
|
|
if (!$response instanceof Response) {
|
|
throw new \RuntimeException($message);
|
|
}
|
|
|
|
$response = $this->dispatcher->filter(new Event($this, 'core.response', array('request_type' => $type, 'request' => $request)), $response);
|
|
|
|
if (!$response instanceof Response) {
|
|
throw new \RuntimeException('A "core.response" listener returned a non response object.');
|
|
}
|
|
|
|
return $response;
|
|
}
|
|
}
|