Skip to content

Commit

Permalink
changed HttpKernel workflow to allow more flexibility
Browse files Browse the repository at this point in the history
  • Loading branch information
fabpot committed Jul 22, 2010
1 parent 3ec9005 commit e35d345
Show file tree
Hide file tree
Showing 11 changed files with 73 additions and 144 deletions.
Expand Up @@ -3,7 +3,7 @@
namespace Symfony\Bundle\FrameworkBundle\Controller;

use Symfony\Components\HttpKernel\LoggerInterface;
use Symfony\Components\HttpKernel\Controller\ControllerManagerInterface;
use Symfony\Components\HttpKernel\Controller\ControllerResolverInterface;
use Symfony\Components\HttpKernel\HttpKernelInterface;
use Symfony\Components\HttpFoundation\Request;
use Symfony\Components\EventDispatcher\Event;
Expand All @@ -19,13 +19,13 @@
*/

/**
* ControllerManager.
* ControllerResolver.
*
* @package Symfony
* @subpackage Bundle_FrameworkBundle
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
*/
class ControllerManager implements ControllerManagerInterface
class ControllerResolver implements ControllerResolverInterface
{
protected $container;
protected $logger;
Expand Down Expand Up @@ -122,7 +122,7 @@ public function render($controller, array $options = array())
* @param \Symfony\Components\HttpFoundation\Request $request A Request instance
*
* @return mixed|Boolean A PHP callable representing the Controller,
* or false if this manager is not able to determine the controller
* or false if this resolver is not able to determine the controller
*
* @throws \InvalidArgumentException|\LogicException If the controller can't be found
*/
Expand Down Expand Up @@ -190,10 +190,9 @@ public function getController(Request $request)
*
* @throws \RuntimeException When value for argument given is not provided
*/
public function getMethodArguments(Request $request, $controller)
public function getArguments(Request $request, $controller)
{
$event = $this->container->get('event_dispatcher')->filter(new Event($this, 'controller_manager.filter_controller_arguments', array('controller' => $controller, 'request' => $request)), $request->attributes->all());
$attributes = $event->getReturnValue();
$attributes = $request->attributes->all();

list($controller, $method) = $controller;

Expand Down
Expand Up @@ -83,7 +83,7 @@

<service id="templating.helper.actions" class="%templating.helper.actions.class%">
<annotation name="templating.helper" alias="actions" />
<argument type="service" id="controller_manager" />
<argument type="service" id="controller_resolver" />
</service>

<service id="templating.loader" alias="templating.loader.filesystem" />
Expand Down
11 changes: 2 additions & 9 deletions src/Symfony/Bundle/FrameworkBundle/Resources/config/web.xml
Expand Up @@ -6,8 +6,7 @@

<parameters>
<parameter key="request_listener.class">Symfony\Bundle\FrameworkBundle\RequestListener</parameter>
<parameter key="controller_manager.class">Symfony\Bundle\FrameworkBundle\Controller\ControllerManager</parameter>
<parameter key="controller_loader_listener.class">Symfony\Components\HttpKernel\Controller\ControllerLoaderListener</parameter>
<parameter key="controller_resolver.class">Symfony\Bundle\FrameworkBundle\Controller\ControllerResolver</parameter>
<parameter key="response_listener.class">Symfony\Components\HttpKernel\ResponseListener</parameter>
<parameter key="exception_listener.class">Symfony\Bundle\FrameworkBundle\Controller\ExceptionListener</parameter>
<parameter key="exception_listener.controller">FrameworkBundle:Exception:exception</parameter>
Expand All @@ -16,17 +15,11 @@
</parameters>

<services>
<service id="controller_manager" class="%controller_manager.class%">
<service id="controller_resolver" class="%controller_resolver.class%">
<argument type="service" id="service_container" />
<argument type="service" id="logger" on-invalid="ignore" />
</service>

<service id="controller_loader_listener" class="%controller_loader_listener.class%">
<annotation name="kernel.listener" />
<argument type="service" id="controller_manager" />
<argument type="service" id="logger" on-invalid="ignore" />
</service>

<service id="request_listener" class="%request_listener.class%">
<annotation name="kernel.listener" />
<argument type="service" id="service_container" />
Expand Down
Expand Up @@ -4,7 +4,7 @@

use Symfony\Components\Templating\Helper\Helper;
use Symfony\Components\OutputEscaper\Escaper;
use Symfony\Bundle\FrameworkBundle\Controller\ControllerManager;
use Symfony\Bundle\FrameworkBundle\Controller\ControllerResolver;

/*
* This file is part of the Symfony framework.
Expand All @@ -24,16 +24,16 @@
*/
class ActionsHelper extends Helper
{
protected $manager;
protected $resolver;

/**
* Constructor.
*
* @param Constructor $container A ContainerInterface instance
*/
public function __construct(ControllerManager $manager)
public function __construct(ControllerResolver $resolver)
{
$this->manager = $manager;
$this->resolver = $resolver;
}

/**
Expand All @@ -55,7 +55,7 @@ public function output($controller, array $options = array())
* @param string $controller A controller name to execute (a string like BlogBundle:Post:index), or a relative URI
* @param array $options An array of options
*
* @see Symfony\Bundle\FrameworkBundle\Controller\ControllerManager::render()
* @see Symfony\Bundle\FrameworkBundle\Controller\ControllerResolver::render()
*/
public function render($controller, array $options = array())
{
Expand All @@ -69,7 +69,7 @@ public function render($controller, array $options = array())
$options['query'] = Escaper::unescape($options['query']);
}

return $this->manager->render($controller, $options);
return $this->resolver->render($controller, $options);
}

/**
Expand Down

This file was deleted.

Expand Up @@ -14,7 +14,7 @@
*/

/**
* A ControllerManagerInterface implementation knows how to determine the
* A ControllerResolverInterface implementation knows how to determine the
* controller to execute based on a Request object.
*
* It can also determine the arguments to pass to the Controller.
Expand All @@ -25,21 +25,21 @@
* @subpackage Bundle_FrameworkBundle
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
*/
interface ControllerManagerInterface
interface ControllerResolverInterface
{
/**
* Returns the Controller instance associated with a Request.
*
* As several managers can exist for a single application, a manager must
* As several resolvers can exist for a single application, a resolver must
* return false when it is not able to determine the controller.
*
* The manager must only throw an exception when it should be able to load
* The resolver must only throw an exception when it should be able to load
* controller but cannot because of some errors made by the developer.
*
* @param \Symfony\Components\HttpFoundation\Request $request A Request instance
*
* @return mixed|Boolean A PHP callable representing the Controller,
* or false if this manager is not able to determine the controller
* or false if this resolver is not able to determine the controller
*
* @throws \InvalidArgumentException|\LogicException If the controller can't be found
*/
Expand All @@ -53,5 +53,5 @@ public function getController(Request $request);
*
* @throws \RuntimeException When value for argument given is not provided
*/
public function getMethodArguments(Request $request, $controller);
public function getArguments(Request $request, $controller);
}
59 changes: 28 additions & 31 deletions src/Symfony/Components/HttpKernel/HttpKernel.php
Expand Up @@ -4,6 +4,7 @@

use Symfony\Components\EventDispatcher\Event;
use Symfony\Components\EventDispatcher\EventDispatcher;
use Symfony\Components\HttpKernel\Controller\ControllerResolverInterface;
use Symfony\Components\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Components\HttpFoundation\Request;
use Symfony\Components\HttpFoundation\Response;
Expand All @@ -27,16 +28,19 @@
class HttpKernel implements HttpKernelInterface
{
protected $dispatcher;
protected $resolver;
protected $request;

/**
* Constructor
*
* @param EventDispatcher $dispatcher An event dispatcher instance
* @param \Symfony\Components\EventDispatcher\EventDispatcher $dispatcher An event dispatcher instance
* @param \Symfony\Components\HttpKernel\Controller\ControllerResolverInterface $resolver A ControllerResolverInterface instance
*/
public function __construct(EventDispatcher $dispatcher)
public function __construct(EventDispatcher $dispatcher, ControllerResolverInterface $resolver)
{
$this->dispatcher = $dispatcher;
$this->resolver = $resolver;
}

/**
Expand All @@ -55,11 +59,11 @@ public function getRequest()
* All exceptions are caught, and a core.exception event is notified
* for user management.
*
* @param Request $request A Request instance
* @param integer $type The type of the request (one of HttpKernelInterface::MASTER_REQUEST, HttpKernelInterface::FORWARDED_REQUEST, or HttpKernelInterface::EMBEDDED_REQUEST)
* @param Boolean $raw Whether to catch exceptions or not
* @param \Symfony\Components\HttpFoundation\Request $request A Request instance
* @param integer $type The type of the request (one of HttpKernelInterface::MASTER_REQUEST, HttpKernelInterface::FORWARDED_REQUEST, or HttpKernelInterface::EMBEDDED_REQUEST)
* @param Boolean $raw Whether to catch exceptions or not
*
* @return Response A Response instance
* @return \Symfony\Components\HttpFoundation\Response A Response instance
*
* @throws \Exception When an Exception occurs during processing
* and couldn't be caught by event processing or $raw is true
Expand Down Expand Up @@ -100,13 +104,13 @@ public function handle(Request $request = null, $type = HttpKernelInterface::MAS
*
* Exceptions are not caught.
*
* @param Request $request A Request instance
* @param integer $type The type of the request (one of HttpKernelInterface::MASTER_REQUEST, HttpKernelInterface::FORWARDED_REQUEST, or HttpKernelInterface::EMBEDDED_REQUEST)
* @param \Symfony\Components\HttpFoundation\Request $request A Request instance
* @param integer $type The type of the request (one of HttpKernelInterface::MASTER_REQUEST, HttpKernelInterface::FORWARDED_REQUEST, or HttpKernelInterface::EMBEDDED_REQUEST)
*
* @return Response A Response instance
* @return \Symfony\Components\HttpFoundation\Response A Response instance
*
* @throws \LogicException If one of the listener does not behave as expected
* @throws NotFoundHttpException When controller cannot be found
* @throws \LogicException If one of the listener does not behave as expected
* @throws \Symfony\Components\HttpKernel\Exception\NotFoundHttpException When controller cannot be found
*/
protected function handleRaw(Request $request, $type = self::MASTER_REQUEST)
{
Expand All @@ -117,30 +121,23 @@ protected function handleRaw(Request $request, $type = self::MASTER_REQUEST)
}

// load controller
$event = $this->dispatcher->notifyUntil(new Event($this, 'core.load_controller', array('request_type' => $type, 'request' => $request)));
if (!$event->isProcessed()) {
if (false === $controller = $this->resolver->getController($request)) {
throw new NotFoundHttpException('Unable to find the controller.');
}

list($controller, $arguments) = $event->getReturnValue();
$event = $this->dispatcher->filter(new Event($this, 'core.controller', array('request' => $request)), $controller);
$controller = $event->getReturnValue();

// 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
$event = $this->dispatcher->notifyUntil(new Event($this, 'core.controller', array('request_type' => $type, 'request' => $request, 'controller' => &$controller, 'arguments' => &$arguments)));
if ($event->isProcessed()) {
try {
return $this->filterResponse($event->getReturnValue(), $request, 'A "core.controller" listener returned a non response object.', $type);
} catch (\Exception $e) {
$retval = $event->getReturnValue();
}
} else {
// call controller
$retval = call_user_func_array($controller, $arguments);
}
// controller arguments
$arguments = $this->resolver->getArguments($request, $controller);

// call controller
$retval = call_user_func_array($controller, $arguments);

// view
$event = $this->dispatcher->filter(new Event($this, 'core.view', array('request_type' => $type, 'request' => $request)), $retval);
Expand All @@ -151,7 +148,7 @@ protected function handleRaw(Request $request, $type = self::MASTER_REQUEST)
/**
* Handles a request that need to be embedded.
*
* @param Request $request A Request instance
* @param \Symfony\Components\HttpFoundation\Request $request A Request instance
* @param Boolean $raw Whether to catch exceptions or not
*
* @return string|false The Response content or false if there is a problem
Expand Down Expand Up @@ -182,11 +179,11 @@ protected function handleEmbedded(Request $request, $raw = false)
/**
* 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, HttpKernelInterface::FORWARDED_REQUEST, or HttpKernelInterface::EMBEDDED_REQUEST)
* @param \Symfony\Components\HttpFoundation\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, HttpKernelInterface::FORWARDED_REQUEST, or HttpKernelInterface::EMBEDDED_REQUEST)
*
* @return Response The filtered Response instance
* @return \Symfony\Components\HttpFoundation\Response The filtered Response instance
*
* @throws \RuntimeException if the passed object is not a Response instance
*/
Expand Down
10 changes: 5 additions & 5 deletions src/Symfony/Components/HttpKernel/HttpKernelInterface.php
Expand Up @@ -29,18 +29,18 @@ interface HttpKernelInterface
/**
* Handles a request to convert it to a response.
*
* @param Request $request A Request instance
* @param integer $type The type of the request (one of HttpKernelInterface::MASTER_REQUEST, HttpKernelInterface::FORWARDED_REQUEST, or HttpKernelInterface::EMBEDDED_REQUEST)
* @param Boolean $raw Whether to catch exceptions or not
* @param \Symfony\Components\HttpFoundation\Request $request A Request instance
* @param integer $type The type of the request (one of HttpKernelInterface::MASTER_REQUEST, HttpKernelInterface::FORWARDED_REQUEST, or HttpKernelInterface::EMBEDDED_REQUEST)
* @param Boolean $raw Whether to catch exceptions or not
*
* @return Response $response A Response instance
* @return \Symfony\Components\HttpFoundation\Response $response A Response instance
*/
public function handle(Request $request = null, $type = self::MASTER_REQUEST, $raw = false);

/**
* Gets the Request instance associated with the master request.
*
* @return Request A Request instance
* @return \Symfony\Components\HttpFoundation\Request A Request instance
*/
public function getRequest();
}

0 comments on commit e35d345

Please sign in to comment.