diff --git a/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md b/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md index 00c86e5a03..bdba9ca429 100644 --- a/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md +++ b/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md @@ -4,6 +4,7 @@ CHANGELOG 2.3.0 ----- + * added ControllerNameParser::build() to converts a controller short notation (a:b:c) to a class::method notation * added possibility to run PHP built-in server in production environment * added possibility to load the serializer component in the service container * added route debug information when using the `router:match` command diff --git a/src/Symfony/Bundle/FrameworkBundle/Controller/ControllerNameParser.php b/src/Symfony/Bundle/FrameworkBundle/Controller/ControllerNameParser.php index 987356124e..4b1c665a94 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Controller/ControllerNameParser.php +++ b/src/Symfony/Bundle/FrameworkBundle/Controller/ControllerNameParser.php @@ -39,7 +39,7 @@ class ControllerNameParser * * @param string $controller A short notation controller (a:b:c) * - * @return string A string with class::method + * @return string A string in the class::method notation * * @throws \InvalidArgumentException when the specified bundle is not enabled * or the controller cannot be found @@ -47,7 +47,7 @@ class ControllerNameParser public function parse($controller) { if (3 != count($parts = explode(':', $controller))) { - throw new \InvalidArgumentException(sprintf('The "%s" controller is not a valid a:b:c controller string.', $controller)); + throw new \InvalidArgumentException(sprintf('The "%s" controller is not a valid "a:b:c" controller string.', $controller)); } list($bundle, $controller, $action) = $parts; @@ -72,25 +72,32 @@ class ControllerNameParser throw new \InvalidArgumentException($msg); } - public function build($controller) { - if (2 != count($parts = explode('::', $controller))) { - throw new \InvalidArgumentException(sprintf('The "%s" controller is not a valid aController::cAction controller string.', $controller)); + /** + * Converts a class::method notation to a short one (a:b:c). + * + * @param string $controller A string in the class::method notation + * + * @return string A short notation controller (a:b:c) + * + * @throws \InvalidArgumentException when the controller is not valid or cannot be found in any bundle + */ + public function build($controller) + { + if (0 === preg_match('#^(.*?\\\\Controller\\\\(.+)Controller)::(.+)Action$#', $controller, $match)) { + throw new \InvalidArgumentException(sprintf('The "%s" controller is not a valid "class::method" string.', $controller)); } - list ($className, $action) = $parts; - if (5 !== strripos($action, 'Action')) { - throw new \InvalidArgumentException(sprintf('The "%s" controller is not a valid aController::cAction controller string.', $controller)); - } - $action = substr($action, 0, strlen($action) - 6); - - foreach ($this->kernel->getBundles() as $bundles) { - foreach($bundles as $bundle) { - if (preg_match('/^'.preg_quote($bundle->getNamespace()).'\\\\Controller\\\\(.*)Controller/', $className, $m)) { - return sprintf('%s:%s:%s', $bundle->getName(), $m[1], $action); - } + $className = $match[1]; + $controllerName = $match[2]; + $actionName = $match[3]; + foreach ($this->kernel->getBundles() as $name => $bundle) { + if (0 !== strpos($className, $bundle->getNamespace())) { + continue; } + + return sprintf('%s:%s:%s', $name, $controllerName, $actionName); } - throw new \InvalidArgumentException(sprintf('The "%s" controller is not a valid aController::cAction controller string.', $controller)); + throw new \InvalidArgumentException(sprintf('Unable to find a bundle that defines controller "%s".', $controller)); } } diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/ControllerNameParserTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/ControllerNameParserTest.php index ac20e601f7..b18ade8793 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/ControllerNameParserTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/ControllerNameParserTest.php @@ -61,9 +61,6 @@ class ControllerNameParserTest extends TestCase $this->assertEquals('FooBundle:Default:index', $parser->build('TestBundle\FooBundle\Controller\DefaultController::indexAction'), '->parse() converts a class::method string to a short a:b:c notation string'); $this->assertEquals('FooBundle:Sub\Default:index', $parser->build('TestBundle\FooBundle\Controller\Sub\DefaultController::indexAction'), '->parse() converts a class::method string to a short a:b:c notation string'); - $this->assertEquals('FabpotFooBundle:Default:index', $parser->build('TestBundle\Fabpot\FooBundle\Controller\DefaultController::indexAction'), '->parse() converts a class::method string to a short a:b:c notation string'); - $this->assertEquals('SensioCmsFooBundle:Default:index', $parser->build('TestBundle\Sensio\Cms\FooBundle\Controller\DefaultController::indexAction'), '->parse() converts a class::method string to a short a:b:c notation string'); - $this->assertEquals('FooBundle:Test\\Default:index', $parser->build('TestBundle\FooBundle\Controller\Test\DefaultController::indexAction'), '->parse() converts a class::method string to a short a:b:c notation string'); try { $parser->build('TestBundle\FooBundle\Controller\DefaultController::index'); @@ -78,6 +75,13 @@ class ControllerNameParserTest extends TestCase } catch (\Exception $e) { $this->assertInstanceOf('\InvalidArgumentException', $e, '->parse() throws an \InvalidArgumentException if the controller is not an aController::cAction string'); } + + try { + $parser->build('Foo\Controller\DefaultController::indexAction'); + $this->fail('->parse() throws an \InvalidArgumentException if the controller is not an aController::cAction string'); + } catch (\Exception $e) { + $this->assertInstanceOf('\InvalidArgumentException', $e, '->parse() throws an \InvalidArgumentException if the controller is not an aController::cAction string'); + } } /** @@ -120,6 +124,13 @@ class ControllerNameParserTest extends TestCase return $bundles[$bundle]; })) ; + + $bundles = array( + 'SensioFooBundle' => $this->getBundle('TestBundle\Fabpot\FooBundle', 'FabpotFooBundle'), + 'SensioCmsFooBundle' => $this->getBundle('TestBundle\Sensio\Cms\FooBundle', 'SensioCmsFooBundle'), + 'FooBundle' => $this->getBundle('TestBundle\FooBundle', 'FooBundle'), + 'FabpotFooBundle' => $this->getBundle('TestBundle\Fabpot\FooBundle', 'FabpotFooBundle'), + ); $kernel ->expects($this->any()) ->method('getBundles')