vendor/symfony/src/Symfony/Component/HttpKernel/Controller/ControllerResolver.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\Controller;
       
    13 
       
    14 use Symfony\Component\HttpKernel\Log\LoggerInterface;
       
    15 use Symfony\Component\HttpFoundation\Request;
       
    16 
       
    17 /**
       
    18  * ControllerResolver.
       
    19  *
       
    20  * This implementation uses the '_controller' request attribute to determine
       
    21  * the controller to execute and uses the request attributes to determine
       
    22  * the controller method arguments.
       
    23  *
       
    24  * @author Fabien Potencier <fabien@symfony.com>
       
    25  *
       
    26  * @api
       
    27  */
       
    28 class ControllerResolver implements ControllerResolverInterface
       
    29 {
       
    30     private $logger;
       
    31 
       
    32     /**
       
    33      * Constructor.
       
    34      *
       
    35      * @param LoggerInterface $logger A LoggerInterface instance
       
    36      */
       
    37     public function __construct(LoggerInterface $logger = null)
       
    38     {
       
    39         $this->logger = $logger;
       
    40     }
       
    41 
       
    42     /**
       
    43      * Returns the Controller instance associated with a Request.
       
    44      *
       
    45      * This method looks for a '_controller' request attribute that represents
       
    46      * the controller name (a string like ClassName::MethodName).
       
    47      *
       
    48      * @param Request $request A Request instance
       
    49      *
       
    50      * @return mixed|Boolean A PHP callable representing the Controller,
       
    51      *                       or false if this resolver is not able to determine the controller
       
    52      *
       
    53      * @throws \InvalidArgumentException|\LogicException If the controller can't be found
       
    54      *
       
    55      * @api
       
    56      */
       
    57     public function getController(Request $request)
       
    58     {
       
    59         if (!$controller = $request->attributes->get('_controller')) {
       
    60             if (null !== $this->logger) {
       
    61                 $this->logger->warn('Unable to look for the controller as the "_controller" parameter is missing');
       
    62             }
       
    63 
       
    64             return false;
       
    65         }
       
    66 
       
    67         if (is_array($controller) || (is_object($controller) && method_exists($controller, '__invoke'))) {
       
    68             return $controller;
       
    69         }
       
    70 
       
    71         if (false === strpos($controller, ':') && method_exists($controller, '__invoke')) {
       
    72             return new $controller;
       
    73         }
       
    74 
       
    75         list($controller, $method) = $this->createController($controller);
       
    76 
       
    77         if (!method_exists($controller, $method)) {
       
    78             throw new \InvalidArgumentException(sprintf('Method "%s::%s" does not exist.', get_class($controller), $method));
       
    79         }
       
    80 
       
    81         return array($controller, $method);
       
    82     }
       
    83 
       
    84     /**
       
    85      * Returns the arguments to pass to the controller.
       
    86      *
       
    87      * @param Request $request    A Request instance
       
    88      * @param mixed   $controller A PHP callable
       
    89      *
       
    90      * @throws \RuntimeException When value for argument given is not provided
       
    91      *
       
    92      * @api
       
    93      */
       
    94     public function getArguments(Request $request, $controller)
       
    95     {
       
    96         if (is_array($controller)) {
       
    97             $r = new \ReflectionMethod($controller[0], $controller[1]);
       
    98         } elseif (is_object($controller)) {
       
    99             $r = new \ReflectionObject($controller);
       
   100             $r = $r->getMethod('__invoke');
       
   101         } else {
       
   102             $r = new \ReflectionFunction($controller);
       
   103         }
       
   104 
       
   105         return $this->doGetArguments($request, $controller, $r->getParameters());
       
   106     }
       
   107 
       
   108     protected function doGetArguments(Request $request, $controller, array $parameters)
       
   109     {
       
   110         $attributes = $request->attributes->all();
       
   111         $arguments = array();
       
   112         foreach ($parameters as $param) {
       
   113             if (array_key_exists($param->getName(), $attributes)) {
       
   114                 $arguments[] = $attributes[$param->getName()];
       
   115             } elseif ($param->getClass() && $param->getClass()->isInstance($request)) {
       
   116                 $arguments[] = $request;
       
   117             } elseif ($param->isDefaultValueAvailable()) {
       
   118                 $arguments[] = $param->getDefaultValue();
       
   119             } else {
       
   120                 if (is_array($controller)) {
       
   121                     $repr = sprintf('%s::%s()', get_class($controller[0]), $controller[1]);
       
   122                 } elseif (is_object($controller)) {
       
   123                     $repr = get_class($controller);
       
   124                 } else {
       
   125                     $repr = $controller;
       
   126                 }
       
   127 
       
   128                 throw new \RuntimeException(sprintf('Controller "%s" requires that you provide a value for the "$%s" argument (because there is no default value or because there is a non optional argument after this one).', $repr, $param->getName()));
       
   129             }
       
   130         }
       
   131 
       
   132         return $arguments;
       
   133     }
       
   134 
       
   135     /**
       
   136      * Returns a callable for the given controller.
       
   137      *
       
   138      * @param string $controller A Controller string
       
   139      *
       
   140      * @return mixed A PHP callable
       
   141      */
       
   142     protected function createController($controller)
       
   143     {
       
   144         if (false === strpos($controller, '::')) {
       
   145             throw new \InvalidArgumentException(sprintf('Unable to find controller "%s".', $controller));
       
   146         }
       
   147 
       
   148         list($class, $method) = explode('::', $controller);
       
   149 
       
   150         if (!class_exists($class)) {
       
   151             throw new \InvalidArgumentException(sprintf('Class "%s" does not exist.', $class));
       
   152         }
       
   153 
       
   154         return array(new $class(), $method);
       
   155     }
       
   156 }