浏览代码

refactored the controller manager, moved generic parts to the HttpKernel component

Fabien Potencier 15 年之前
父节点
当前提交
fb4bd3568d

+ 30 - 7
src/Symfony/Bundle/FrameworkBundle/Controller/ControllerManager.php

@@ -3,9 +3,10 @@
 namespace Symfony\Bundle\FrameworkBundle\Controller;
 
 use Symfony\Components\HttpKernel\LoggerInterface;
-use Symfony\Components\DependencyInjection\ContainerInterface;
+use Symfony\Components\HttpKernel\Controller\ControllerManagerInterface;
 use Symfony\Components\HttpKernel\HttpKernelInterface;
 use Symfony\Components\HttpFoundation\Request;
+use Symfony\Components\DependencyInjection\ContainerInterface;
 
 /*
  * This file is part of the Symfony framework.
@@ -23,7 +24,7 @@ use Symfony\Components\HttpFoundation\Request;
  * @subpackage Bundle_FrameworkBundle
  * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
  */
-class ControllerManager
+class ControllerManager implements ControllerManagerInterface
 {
     protected $container;
     protected $logger;
@@ -112,16 +113,28 @@ class ControllerManager
     }
 
     /**
-     * Creates the Controller instance associated with the controller string
+     * Returns the Controller instance associated with a Request.
+     *
+     * This method looks for a '_controller' request parameter that represents
+     * the controller name (a string like BlogBundle:Post:index).
      *
-     * @param string $controller A controller name (a string like BlogBundle:Post:index)
+     * @param \Symfony\Components\HttpFoundation\Request $request A Request instance
      *
-     * @return array An array composed of the Controller instance and the Controller method
+     * @return mixed|Boolean A PHP callable representing the Controller,
+     *                       or false if this manager is not able to determine the controller
      *
      * @throws \InvalidArgumentException|\LogicException If the controller can't be found
      */
-    public function findController($controller)
+    public function getController(Request $request)
     {
+        if (!$controller = $request->path->get('_controller')) {
+            if (null !== $this->logger) {
+                $this->logger->err('Unable to look for the controller as the "_controller" parameter is missing');
+            }
+
+            return false;
+        }
+
         list($bundle, $controller, $action) = explode(':', $controller);
         $bundle = strtr($bundle, array('/' => '\\'));
         $class = null;
@@ -154,6 +167,7 @@ class ControllerManager
         }
 
         $controller = new $class($this->container);
+        $controller->setRequest($request);
 
         $method = $action.'Action';
         if (!method_exists($controller, $method)) {
@@ -168,10 +182,19 @@ class ControllerManager
     }
 
     /**
+     * Returns the arguments to pass to the controller.
+     *
+     * @param \Symfony\Components\HttpFoundation\Request $request    A Request instance
+     * @param mixed                                      $controller A PHP callable
+     *
      * @throws \RuntimeException When value for argument given is not provided
      */
-    public function getMethodArguments(array $path, $controller, $method)
+    public function getMethodArguments(Request $request, $controller)
     {
+        $path = $request->path->all();
+
+        list($controller, $method) = $controller;
+
         $r = new \ReflectionObject($controller);
         $arguments = array();
         foreach ($r->getMethod($method)->getParameters() as $param) {

+ 1 - 1
src/Symfony/Bundle/FrameworkBundle/Resources/config/web.xml

@@ -7,7 +7,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\Bundle\FrameworkBundle\Controller\ControllerLoaderListener</parameter>
+        <parameter key="controller_loader_listener.class">Symfony\Components\HttpKernel\Controller\ControllerLoaderListener</parameter>
         <parameter key="router.class">Symfony\Components\Routing\Router</parameter>
         <parameter key="response_listener.class">Symfony\Components\HttpKernel\ResponseListener</parameter>
         <parameter key="exception_listener.class">Symfony\Bundle\FrameworkBundle\Controller\ExceptionListener</parameter>

+ 5 - 15
src/Symfony/Bundle/FrameworkBundle/Controller/ControllerLoaderListener.php

@@ -1,8 +1,7 @@
 <?php
 
-namespace Symfony\Bundle\FrameworkBundle\Controller;
+namespace Symfony\Components\HttpKernel\Controller;
 
-use Symfony\Components\HttpKernel\LoggerInterface;
 use Symfony\Components\EventDispatcher\EventDispatcher;
 use Symfony\Components\EventDispatcher\Event;
 
@@ -26,12 +25,10 @@ use Symfony\Components\EventDispatcher\Event;
 class ControllerLoaderListener
 {
     protected $manager;
-    protected $logger;
 
-    public function __construct(ControllerManager $manager, LoggerInterface $logger = null)
+    public function __construct(ControllerManagerInterface $manager)
     {
         $this->manager = $manager;
-        $this->logger = $logger;
     }
 
     /**
@@ -55,20 +52,13 @@ class ControllerLoaderListener
     {
         $request = $event->getParameter('request');
 
-        if (!$controller = $request->path->get('_controller')) {
-            if (null !== $this->logger) {
-                $this->logger->err('Unable to look for the controller as the "_controller" parameter is missing');
-            }
-
+        if (false === $controller = $this->manager->getController($request)) {
             return false;
         }
 
-        list($controller, $method) = $this->manager->findController($controller);
-        $controller->setRequest($request);
-
-        $arguments = $this->manager->getMethodArguments($request->path->all(), $controller, $method);
+        $arguments = $this->manager->getMethodArguments($request, $controller);
 
-        $event->setReturnValue(array(array($controller, $method), $arguments));
+        $event->setReturnValue(array($controller, $arguments));
 
         return true;
     }

+ 57 - 0
src/Symfony/Components/HttpKernel/Controller/ControllerManagerInterface.php

@@ -0,0 +1,57 @@
+<?php
+
+namespace Symfony\Components\HttpKernel\Controller;
+
+use Symfony\Components\HttpFoundation\Request;
+
+/*
+ * This file is part of the Symfony framework.
+ *
+ * (c) Fabien Potencier <fabien.potencier@symfony-project.com>
+ *
+ * This source file is subject to the MIT license that is bundled
+ * with this source code in the file LICENSE.
+ */
+
+/**
+ * A ControllerManagerInterface 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.
+ *
+ * A Controller can be any valid PHP callable.
+ *
+ * @package    Symfony
+ * @subpackage Bundle_FrameworkBundle
+ * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
+ */
+interface ControllerManagerInterface
+{
+    /**
+     * Returns the Controller instance associated with a Request.
+     *
+     * As several managers can exist for a single application, a manager 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
+     * 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
+     *
+     * @throws \InvalidArgumentException|\LogicException If the controller can't be found
+     */
+    public function getController(Request $request);
+
+    /**
+     * Returns the arguments to pass to the controller.
+     *
+     * @param \Symfony\Components\HttpFoundation\Request $request    A Request instance
+     * @param mixed                                      $controller A PHP callable
+     *
+     * @throws \RuntimeException When value for argument given is not provided
+     */
+    public function getMethodArguments(Request $request, $controller);
+}