vendor/symfony/src/Symfony/Component/HttpKernel/HttpKernel.php
changeset 0 7f95f8617b0b
equal deleted inserted replaced
-1:000000000000 0:7f95f8617b0b
       
     1 <?php
       
     2 
       
     3 /*
       
     4  * This file is part of the Symfony package.
       
     5  *
       
     6  * (c) Fabien Potencier <fabien@symfony.com>
       
     7  *
       
     8  * For the full copyright and license information, please view the LICENSE
       
     9  * file that was distributed with this source code.
       
    10  */
       
    11 
       
    12 namespace Symfony\Component\HttpKernel;
       
    13 
       
    14 use Symfony\Component\HttpKernel\Controller\ControllerResolverInterface;
       
    15 use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
       
    16 use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
       
    17 use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
       
    18 use Symfony\Component\HttpKernel\Event\GetResponseEvent;
       
    19 use Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent;
       
    20 use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
       
    21 use Symfony\Component\HttpFoundation\Request;
       
    22 use Symfony\Component\HttpFoundation\Response;
       
    23 use Symfony\Component\EventDispatcher\EventDispatcherInterface;
       
    24 
       
    25 /**
       
    26  * HttpKernel notifies events to convert a Request object to a Response one.
       
    27  *
       
    28  * @author Fabien Potencier <fabien@symfony.com>
       
    29  *
       
    30  * @api
       
    31  */
       
    32 class HttpKernel implements HttpKernelInterface
       
    33 {
       
    34     private $dispatcher;
       
    35     private $resolver;
       
    36 
       
    37     /**
       
    38      * Constructor
       
    39      *
       
    40      * @param EventDispatcherInterface    $dispatcher An EventDispatcherInterface instance
       
    41      * @param ControllerResolverInterface $resolver   A ControllerResolverInterface instance
       
    42      *
       
    43      * @api
       
    44      */
       
    45     public function __construct(EventDispatcherInterface $dispatcher, ControllerResolverInterface $resolver)
       
    46     {
       
    47         $this->dispatcher = $dispatcher;
       
    48         $this->resolver = $resolver;
       
    49     }
       
    50 
       
    51     /**
       
    52      * Handles a Request to convert it to a Response.
       
    53      *
       
    54      * When $catch is true, the implementation must catch all exceptions
       
    55      * and do its best to convert them to a Response instance.
       
    56      *
       
    57      * @param  Request $request A Request instance
       
    58      * @param  integer $type    The type of the request
       
    59      *                          (one of HttpKernelInterface::MASTER_REQUEST or HttpKernelInterface::SUB_REQUEST)
       
    60      * @param  Boolean $catch   Whether to catch exceptions or not
       
    61      *
       
    62      * @return Response A Response instance
       
    63      *
       
    64      * @throws \Exception When an Exception occurs during processing
       
    65      *
       
    66      * @api
       
    67      */
       
    68     public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQUEST, $catch = true)
       
    69     {
       
    70         try {
       
    71             return $this->handleRaw($request, $type);
       
    72         } catch (\Exception $e) {
       
    73             if (false === $catch) {
       
    74                 throw $e;
       
    75             }
       
    76 
       
    77             return $this->handleException($e, $request, $type);
       
    78         }
       
    79     }
       
    80 
       
    81     /**
       
    82      * Handles a request to convert it to a response.
       
    83      *
       
    84      * Exceptions are not caught.
       
    85      *
       
    86      * @param Request $request A Request instance
       
    87      * @param integer $type    The type of the request (one of HttpKernelInterface::MASTER_REQUEST or HttpKernelInterface::SUB_REQUEST)
       
    88      *
       
    89      * @return Response A Response instance
       
    90      *
       
    91      * @throws \LogicException If one of the listener does not behave as expected
       
    92      * @throws NotFoundHttpException When controller cannot be found
       
    93      */
       
    94     private function handleRaw(Request $request, $type = self::MASTER_REQUEST)
       
    95     {
       
    96         // request
       
    97         $event = new GetResponseEvent($this, $request, $type);
       
    98         $this->dispatcher->dispatch(KernelEvents::REQUEST, $event);
       
    99 
       
   100         if ($event->hasResponse()) {
       
   101             return $this->filterResponse($event->getResponse(), $request, $type);
       
   102         }
       
   103 
       
   104         // load controller
       
   105         if (false === $controller = $this->resolver->getController($request)) {
       
   106             throw new NotFoundHttpException(sprintf('Unable to find the controller for path "%s". Maybe you forgot to add the matching route in your routing configuration?', $request->getPathInfo()));
       
   107         }
       
   108 
       
   109         $event = new FilterControllerEvent($this, $controller, $request, $type);
       
   110         $this->dispatcher->dispatch(KernelEvents::CONTROLLER, $event);
       
   111         $controller = $event->getController();
       
   112 
       
   113         // controller arguments
       
   114         $arguments = $this->resolver->getArguments($request, $controller);
       
   115 
       
   116         // call controller
       
   117         $response = call_user_func_array($controller, $arguments);
       
   118 
       
   119         // view
       
   120         if (!$response instanceof Response) {
       
   121             $event = new GetResponseForControllerResultEvent($this, $request, $type, $response);
       
   122             $this->dispatcher->dispatch(KernelEvents::VIEW, $event);
       
   123 
       
   124             if ($event->hasResponse()) {
       
   125                 $response = $event->getResponse();
       
   126             }
       
   127 
       
   128             if (!$response instanceof Response) {
       
   129                 $msg = sprintf('The controller must return a response (%s given).', $this->varToString($response));
       
   130 
       
   131                 // the user may have forgotten to return something
       
   132                 if (null === $response) {
       
   133                     $msg .= ' Did you forget to add a return statement somewhere in your controller?';
       
   134                 }
       
   135                 throw new \LogicException($msg);
       
   136             }
       
   137         }
       
   138 
       
   139         return $this->filterResponse($response, $request, $type);
       
   140     }
       
   141 
       
   142     /**
       
   143      * Filters a response object.
       
   144      *
       
   145      * @param Response $response A Response instance
       
   146      * @param Request  $request  A error message in case the response is not a Response object
       
   147      * @param integer  $type     The type of the request (one of HttpKernelInterface::MASTER_REQUEST or HttpKernelInterface::SUB_REQUEST)
       
   148      *
       
   149      * @return Response The filtered Response instance
       
   150      *
       
   151      * @throws \RuntimeException if the passed object is not a Response instance
       
   152      */
       
   153     private function filterResponse(Response $response, Request $request, $type)
       
   154     {
       
   155         $event = new FilterResponseEvent($this, $request, $type, $response);
       
   156 
       
   157         $this->dispatcher->dispatch(KernelEvents::RESPONSE, $event);
       
   158 
       
   159         return $event->getResponse();
       
   160     }
       
   161 
       
   162     /**
       
   163      * Handles and exception by trying to convert it to a Response.
       
   164      *
       
   165      * @param  \Exception $e       An \Exception instance
       
   166      * @param  Request    $request A Request instance
       
   167      * @param  integer    $type    The type of the request
       
   168      *
       
   169      * @return Response A Response instance
       
   170      */
       
   171     private function handleException(\Exception $e, $request, $type)
       
   172     {
       
   173         $event = new GetResponseForExceptionEvent($this, $request, $type, $e);
       
   174         $this->dispatcher->dispatch(KernelEvents::EXCEPTION, $event);
       
   175 
       
   176         if (!$event->hasResponse()) {
       
   177             throw $e;
       
   178         }
       
   179 
       
   180         try {
       
   181             return $this->filterResponse($event->getResponse(), $request, $type);
       
   182         } catch (\Exception $e) {
       
   183             return $event->getResponse();
       
   184         }
       
   185     }
       
   186 
       
   187     private function varToString($var)
       
   188     {
       
   189         if (is_object($var)) {
       
   190             return sprintf('Object(%s)', get_class($var));
       
   191         }
       
   192 
       
   193         if (is_array($var)) {
       
   194             $a = array();
       
   195             foreach ($var as $k => $v) {
       
   196                 $a[] = sprintf('%s => %s', $k, $this->varToString($v));
       
   197             }
       
   198 
       
   199             return sprintf("Array(%s)", implode(', ', $a));
       
   200         }
       
   201 
       
   202         if (is_resource($var)) {
       
   203             return sprintf('Resource(%s)', get_resource_type($var));
       
   204         }
       
   205 
       
   206         if (null === $var) {
       
   207             return 'null';
       
   208         }
       
   209 
       
   210         if (false === $var) {
       
   211             return 'false';
       
   212         }
       
   213 
       
   214         if (true === $var) {
       
   215             return 'true';
       
   216         }
       
   217 
       
   218         return (string) $var;
       
   219     }
       
   220 }