2010-02-17 13:53:18 +00:00
< ? php
2010-05-06 11:04:50 +01:00
namespace Symfony\Components\HttpKernel ;
2010-02-17 13:53:18 +00:00
use Symfony\Components\EventDispatcher\Event ;
use Symfony\Components\EventDispatcher\EventDispatcher ;
2010-05-06 11:04:50 +01:00
use Symfony\Components\HttpKernel\Exception\NotFoundHttpException ;
2010-02-17 13:53:18 +00:00
/*
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 .
*/
/**
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-04-07 01:51:29 +01:00
* @ package Symfony
2010-05-06 11:04:50 +01:00
* @ subpackage Components_HttpKernel
2010-02-17 13:53:18 +00:00
* @ author Fabien Potencier < fabien . potencier @ symfony - project . com >
*/
2010-05-06 11:04:50 +01:00
class HttpKernel implements HttpKernelInterface
2010-02-17 13:53:18 +00:00
{
2010-05-06 12:25:53 +01:00
protected $dispatcher ;
protected $request ;
/**
* Constructor
*
* @ param EventDispatcher $dispatcher An event dispatcher instance
*/
public function __construct ( EventDispatcher $dispatcher )
2010-04-25 12:18:42 +01:00
{
2010-05-06 12:25:53 +01:00
$this -> dispatcher = $dispatcher ;
2010-04-25 12:18:42 +01:00
}
2010-05-06 12:25:53 +01:00
/**
2010-05-13 16:17:33 +01:00
* Gets the Request instance associated with the master request .
2010-05-06 12:25:53 +01:00
*
* @ return Request A Request instance
*/
public function getRequest ()
2010-04-25 12:18:42 +01:00
{
2010-05-06 12:25:53 +01:00
return $this -> request ;
2010-04-25 12:18:42 +01:00
}
2010-05-06 12:25:53 +01:00
/**
2010-05-13 16:17:33 +01:00
* Handles a Request to convert it to a Response .
2010-05-06 12:25:53 +01:00
*
* All exceptions are caught , and a core . exception event is notified
* for user management .
*
2010-05-13 16:17:33 +01:00
* @ 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
2010-05-06 12:25:53 +01:00
*
2010-05-13 16:17:33 +01:00
* @ return Response A Response instance
2010-05-06 12:25:53 +01:00
*
2010-05-13 16:17:33 +01:00
* @ throws \Exception When an Exception occurs during processing
* and couldn ' t be caught by event processing or $raw is true
2010-05-06 12:25:53 +01:00
*/
2010-05-13 16:17:33 +01:00
public function handle ( Request $request = null , $type = HttpKernelInterface :: MASTER_REQUEST , $raw = false )
2010-02-17 13:53:18 +00:00
{
2010-05-13 16:17:33 +01:00
if ( HttpKernelInterface :: EMBEDDED_REQUEST === $type ) {
return $this -> handleEmbedded ( $request , $raw );
}
2010-05-06 12:25:53 +01:00
2010-05-07 15:09:11 +01:00
if ( null === $request ) {
2010-05-06 12:25:53 +01:00
$request = new Request ();
}
2010-05-13 16:17:33 +01:00
if ( HttpKernelInterface :: MASTER_REQUEST === $type ) {
2010-05-06 12:25:53 +01:00
$this -> request = $request ;
}
2010-05-07 15:09:11 +01:00
try {
2010-05-13 16:17:33 +01:00
return $this -> handleRaw ( $request , $type );
2010-05-07 15:09:11 +01:00
} catch ( \Exception $e ) {
2010-05-08 14:32:30 +01:00
if ( true === $raw ) {
2010-05-06 13:26:48 +01:00
throw $e ;
}
2010-05-06 12:25:53 +01:00
// exception
2010-05-13 16:17:33 +01:00
$event = $this -> dispatcher -> notifyUntil ( new Event ( $this , 'core.exception' , array ( 'request_type' => $type , 'request' => $request , 'exception' => $e )));
2010-05-07 15:09:11 +01:00
if ( $event -> isProcessed ()) {
2010-05-13 16:17:33 +01:00
return $this -> filterResponse ( $event -> getReturnValue (), $request , 'A "core.exception" listener returned a non response object.' , $type );
2010-05-06 12:25:53 +01:00
}
throw $e ;
}
2010-02-17 13:53:18 +00:00
}
2010-05-06 12:25:53 +01:00
/**
* Handles a request to convert it to a response .
*
* Exceptions are not caught .
*
2010-05-13 16:17:33 +01:00
* @ 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 )
2010-05-06 12:25:53 +01:00
*
2010-05-13 16:17:33 +01:00
* @ return Response A Response instance
2010-05-06 12:25:53 +01:00
*
* @ throws \LogicException If one of the listener does not behave as expected
* @ throws NotFoundHttpException When controller cannot be found
*/
2010-05-13 16:17:33 +01:00
protected function handleRaw ( Request $request , $type = self :: MASTER_REQUEST )
2010-02-17 13:53:18 +00:00
{
2010-05-06 12:25:53 +01:00
// request
2010-05-13 16:17:33 +01:00
$event = $this -> dispatcher -> notifyUntil ( new Event ( $this , 'core.request' , array ( 'request_type' => $type , 'request' => $request )));
2010-05-07 15:09:11 +01:00
if ( $event -> isProcessed ()) {
2010-05-13 16:17:33 +01:00
return $this -> filterResponse ( $event -> getReturnValue (), $request , 'A "core.request" listener returned a non response object.' , $type );
2010-05-06 12:25:53 +01:00
}
// load controller
2010-05-13 16:17:33 +01:00
$event = $this -> dispatcher -> notifyUntil ( new Event ( $this , 'core.load_controller' , array ( 'request_type' => $type , 'request' => $request )));
2010-05-07 15:09:11 +01:00
if ( ! $event -> isProcessed ()) {
2010-05-06 12:25:53 +01:00
throw new NotFoundHttpException ( 'Unable to find the controller.' );
}
list ( $controller , $arguments ) = $event -> getReturnValue ();
// controller must be a callable
2010-05-07 15:09:11 +01:00
if ( ! is_callable ( $controller )) {
2010-05-06 12:25:53 +01:00
throw new \LogicException ( sprintf ( 'The controller must be a callable (%s).' , var_export ( $controller , true )));
}
// controller
2010-05-13 16:17:33 +01:00
$event = $this -> dispatcher -> notifyUntil ( new Event ( $this , 'core.controller' , array ( 'request_type' => $type , 'request' => $request , 'controller' => & $controller , 'arguments' => & $arguments )));
2010-05-07 15:09:11 +01:00
if ( $event -> isProcessed ()) {
2010-05-08 14:32:30 +01:00
try {
2010-05-13 16:17:33 +01:00
return $this -> filterResponse ( $event -> getReturnValue (), $request , 'A "core.controller" listener returned a non response object.' , $type );
2010-05-07 15:09:11 +01:00
} catch ( \Exception $e ) {
2010-05-06 12:25:53 +01:00
$retval = $event -> getReturnValue ();
}
2010-05-07 15:09:11 +01:00
} else {
2010-05-06 12:25:53 +01:00
// call controller
$retval = call_user_func_array ( $controller , $arguments );
}
// view
2010-05-13 16:17:33 +01:00
$event = $this -> dispatcher -> filter ( new Event ( $this , 'core.view' , array ( 'request_type' => $type , 'request' => $request )), $retval );
return $this -> filterResponse ( $event -> getReturnValue (), $request , sprintf ( 'The controller must return a response (instead of %s).' , is_object ( $event -> getReturnValue ()) ? 'an object of class ' . get_class ( $event -> getReturnValue ()) : str_replace ( " \n " , '' , var_export ( $event -> getReturnValue (), true ))), $type );
}
/**
* Handles a request that need to be embedded .
*
* @ param Request $request A Request instance
2010-05-18 11:48:56 +01:00
* @ param Boolean $raw Whether to catch exceptions or not
2010-05-13 16:17:33 +01:00
*
* @ return string | false The Response content or false if there is a problem
*
* @ throws \RuntimeException When an Exception occurs during processing
* and couldn ' t be caught by event processing or $raw is true
*/
protected function handleEmbedded ( Request $request , $raw = false )
{
try {
$response = $this -> handleRaw ( $request , HttpKernelInterface :: EMBEDDED_REQUEST );
if ( 200 != $response -> getStatusCode ()) {
throw new \RuntimeException ( sprintf ( 'Error when rendering "%s" (Status code is %s).' , $request -> getUri (), $response -> getStatusCode ()));
}
2010-05-06 12:25:53 +01:00
2010-05-13 16:17:33 +01:00
return $response -> getContent ();
} catch ( \Exception $e ) {
if ( true === $raw )
{
throw $e ;
}
return false ;
}
2010-02-17 13:53:18 +00:00
}
2010-05-06 12:25:53 +01:00
/**
* Filters a response object .
*
2010-05-13 16:17:33 +01:00
* @ param Response $response A Response instance
* @ param string $message A error message in case the response is not a Response object
2010-05-18 11:48:56 +01:00
* @ param integer $type The type of the request ( one of HttpKernelInterface :: MASTER_REQUEST , HttpKernelInterface :: FORWARDED_REQUEST , or HttpKernelInterface :: EMBEDDED_REQUEST )
2010-05-06 12:25:53 +01:00
*
2010-05-13 16:17:33 +01:00
* @ return Response The filtered Response instance
2010-05-06 12:25:53 +01:00
*
2010-05-13 16:17:33 +01:00
* @ throws \RuntimeException if the passed object is not a Response instance
2010-05-06 12:25:53 +01:00
*/
2010-05-13 16:17:33 +01:00
protected function filterResponse ( $response , $request , $message , $type )
2010-02-17 13:53:18 +00:00
{
2010-05-07 15:09:11 +01:00
if ( ! $response instanceof Response ) {
2010-05-06 12:25:53 +01:00
throw new \RuntimeException ( $message );
}
2010-02-17 13:53:18 +00:00
2010-05-13 16:17:33 +01:00
$event = $this -> dispatcher -> filter ( new Event ( $this , 'core.response' , array ( 'request_type' => $type , 'request' => $request )), $response );
2010-05-06 12:25:53 +01:00
$response = $event -> getReturnValue ();
2010-02-17 13:53:18 +00:00
2010-05-07 15:09:11 +01:00
if ( ! $response instanceof Response ) {
2010-05-06 12:25:53 +01:00
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
}
}