2010-02-17 13:53:18 +00:00
|
|
|
<?php
|
|
|
|
|
|
|
|
/*
|
2010-04-07 01:51:29 +01:00
|
|
|
* This file is part of the Symfony package.
|
2010-02-17 13:53:18 +00:00
|
|
|
*
|
|
|
|
* (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.
|
|
|
|
*/
|
|
|
|
|
2011-01-15 13:29:43 +00:00
|
|
|
namespace Symfony\Component\HttpKernel;
|
|
|
|
|
|
|
|
use Symfony\Component\EventDispatcher\Event;
|
2011-01-25 13:23:23 +00:00
|
|
|
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
2011-01-15 13:29:43 +00:00
|
|
|
use Symfony\Component\HttpKernel\Controller\ControllerResolverInterface;
|
|
|
|
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
|
|
|
use Symfony\Component\HttpFoundation\Request;
|
|
|
|
use Symfony\Component\HttpFoundation\Response;
|
|
|
|
|
2010-02-17 13:53:18 +00:00
|
|
|
/**
|
2010-05-06 11:04:50 +01:00
|
|
|
* HttpKernel notifies events to convert a Request object to a Response one.
|
2010-02-17 13:53:18 +00:00
|
|
|
*
|
2010-10-17 12:45:15 +01:00
|
|
|
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
|
2010-02-17 13:53:18 +00:00
|
|
|
*/
|
2010-12-08 23:58:26 +00:00
|
|
|
class HttpKernel implements HttpKernelInterface
|
2010-02-17 13:53:18 +00:00
|
|
|
{
|
2010-12-08 23:58:26 +00:00
|
|
|
protected $dispatcher;
|
|
|
|
protected $resolver;
|
2010-05-06 12:25:53 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Constructor
|
|
|
|
*
|
2011-01-25 13:23:23 +00:00
|
|
|
* @param EventDispatcherInterface $dispatcher An EventDispatcherInterface instance
|
2010-07-27 14:33:28 +01:00
|
|
|
* @param ControllerResolverInterface $resolver A ControllerResolverInterface instance
|
2010-05-06 12:25:53 +01:00
|
|
|
*/
|
2011-01-25 13:23:23 +00:00
|
|
|
public function __construct(EventDispatcherInterface $dispatcher, ControllerResolverInterface $resolver)
|
2010-04-25 12:18:42 +01:00
|
|
|
{
|
2010-12-08 23:58:26 +00:00
|
|
|
$this->dispatcher = $dispatcher;
|
|
|
|
$this->resolver = $resolver;
|
2010-04-25 12:18:42 +01:00
|
|
|
}
|
|
|
|
|
2010-05-06 12:25:53 +01:00
|
|
|
/**
|
2010-10-15 10:02:35 +01:00
|
|
|
* {@inheritdoc}
|
2010-05-06 12:25:53 +01:00
|
|
|
*/
|
2010-11-06 14:13:23 +00:00
|
|
|
public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQUEST, $catch = true)
|
2010-02-17 13:53:18 +00:00
|
|
|
{
|
2010-12-08 23:58:26 +00:00
|
|
|
try {
|
2010-12-09 17:50:49 +00:00
|
|
|
$response = $this->handleRaw($request, $type);
|
2010-12-08 23:58:26 +00:00
|
|
|
} catch (\Exception $e) {
|
|
|
|
if (false === $catch) {
|
|
|
|
throw $e;
|
|
|
|
}
|
|
|
|
|
|
|
|
// exception
|
|
|
|
$event = new Event($this, 'core.exception', array('request_type' => $type, 'request' => $request, 'exception' => $e));
|
2011-01-26 06:50:06 +00:00
|
|
|
$response = $this->dispatcher->notifyUntil($event);
|
2010-12-10 08:24:14 +00:00
|
|
|
if (!$event->isProcessed()) {
|
|
|
|
throw $e;
|
2010-12-08 23:58:26 +00:00
|
|
|
}
|
|
|
|
|
2011-01-26 06:50:06 +00:00
|
|
|
$response = $this->filterResponse($response, $request, 'A "core.exception" listener returned a non response object.', $type);
|
2010-12-08 23:58:26 +00:00
|
|
|
}
|
2010-12-09 17:50:49 +00:00
|
|
|
|
|
|
|
return $response;
|
|
|
|
}
|
|
|
|
|
2010-12-08 23:58:26 +00:00
|
|
|
/**
|
|
|
|
* 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));
|
2011-01-26 06:50:06 +00:00
|
|
|
$response = $this->dispatcher->notifyUntil($event);
|
2010-12-08 23:58:26 +00:00
|
|
|
if ($event->isProcessed()) {
|
2011-01-26 06:50:06 +00:00
|
|
|
return $this->filterResponse($response, $request, 'A "core.request" listener returned a non response object.', $type);
|
2010-12-08 23:58:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// load controller
|
|
|
|
if (false === $controller = $this->resolver->getController($request)) {
|
2011-01-23 06:37:01 +00:00
|
|
|
throw new NotFoundHttpException(sprintf('Unable to find the controller for "%s", check your route configuration.', $request->getPathInfo()));
|
2010-12-08 23:58:26 +00:00
|
|
|
}
|
2010-05-06 12:25:53 +01:00
|
|
|
|
2010-12-08 23:58:26 +00:00
|
|
|
$event = new Event($this, 'core.controller', array('request_type' => $type, 'request' => $request));
|
2011-01-26 06:50:06 +00:00
|
|
|
$controller = $this->dispatcher->filter($event, $controller);
|
2010-12-08 23:58:26 +00:00
|
|
|
|
|
|
|
// controller must be a callable
|
|
|
|
if (!is_callable($controller)) {
|
2011-01-29 14:31:42 +00:00
|
|
|
throw new \LogicException(sprintf('The controller must be a callable (%s given).', $this->varToString($controller)));
|
2010-12-08 23:58:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// controller arguments
|
|
|
|
$arguments = $this->resolver->getArguments($request, $controller);
|
|
|
|
|
|
|
|
// call controller
|
2011-02-03 18:39:28 +00:00
|
|
|
$response = call_user_func_array($controller, $arguments);
|
2010-12-08 23:58:26 +00:00
|
|
|
|
|
|
|
// view
|
2011-02-03 18:39:28 +00:00
|
|
|
if (!$response instanceof Response) {
|
|
|
|
$event = new Event($this, 'core.view', array('request_type' => $type, 'request' => $request));
|
|
|
|
$response = $this->dispatcher->filter($event, $response);
|
|
|
|
}
|
2010-12-08 23:58:26 +00:00
|
|
|
|
2011-01-29 14:31:42 +00:00
|
|
|
return $this->filterResponse($response, $request, sprintf('The controller must return a response (%s given).', $this->varToString($response)), $type);
|
2010-12-08 23:58:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 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);
|
|
|
|
}
|
2010-05-13 16:17:33 +01:00
|
|
|
|
2011-01-26 06:50:06 +00:00
|
|
|
$response = $this->dispatcher->filter(new Event($this, 'core.response', array('request_type' => $type, 'request' => $request)), $response);
|
2010-11-06 14:13:23 +00:00
|
|
|
|
2010-12-08 23:58:26 +00:00
|
|
|
if (!$response instanceof Response) {
|
|
|
|
throw new \RuntimeException('A "core.response" listener returned a non response object.');
|
|
|
|
}
|
2010-02-17 13:53:18 +00:00
|
|
|
|
2010-05-06 12:25:53 +01:00
|
|
|
return $response;
|
2010-02-17 13:53:18 +00:00
|
|
|
}
|
2011-01-29 14:31:42 +00:00
|
|
|
|
|
|
|
protected function varToString($var)
|
|
|
|
{
|
|
|
|
if (is_object($var)) {
|
|
|
|
return sprintf('[object](%s)', get_class($var));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (is_array($var)) {
|
|
|
|
$a = array();
|
|
|
|
foreach ($var as $k => $v) {
|
|
|
|
$a[] = sprintf('%s => %s', $k, $this->varToString($v));
|
|
|
|
}
|
|
|
|
|
|
|
|
return sprintf("[array](%s)", implode(', ', $a));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (is_resource($var)) {
|
|
|
|
return '[resource]';
|
|
|
|
}
|
|
|
|
|
|
|
|
return str_replace("\n", '', var_export((string) $var, true));
|
|
|
|
}
|
2010-02-17 13:53:18 +00:00
|
|
|
}
|