From 1d298f0417652ce5dac2e0e4756d5c244be57046 Mon Sep 17 00:00:00 2001 From: Robin Chalas Date: Mon, 23 Jan 2017 17:37:56 +0100 Subject: [PATCH] [Routing] Fix BC break in AnnotationClassLoader defaults attributes handling --- composer.json | 3 +- .../Functional/AnnotatedControllerTest.php | 39 ++++++++++++++ .../Controller/AnnotatedController.php | 51 +++++++++++++++++++ .../app/AnnotatedController/bundles.php | 20 ++++++++ .../app/AnnotatedController/config.yml | 2 + .../app/AnnotatedController/routing.yml | 4 ++ .../Bundle/FrameworkBundle/composer.json | 5 +- .../Routing/Loader/AnnotationClassLoader.php | 5 ++ 8 files changed, 126 insertions(+), 3 deletions(-) create mode 100644 src/Symfony/Bundle/FrameworkBundle/Tests/Functional/AnnotatedControllerTest.php create mode 100644 src/Symfony/Bundle/FrameworkBundle/Tests/Functional/Bundle/TestBundle/Controller/AnnotatedController.php create mode 100644 src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/AnnotatedController/bundles.php create mode 100644 src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/AnnotatedController/config.yml create mode 100644 src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/AnnotatedController/routing.yml diff --git a/composer.json b/composer.json index 34dfa896e3b4..2d7b45115975 100644 --- a/composer.json +++ b/composer.json @@ -79,7 +79,8 @@ "ircmaxell/password-compat": "~1.0", "ocramius/proxy-manager": "~0.4|~1.0|~2.0", "symfony/phpunit-bridge": "~3.2", - "egulias/email-validator": "~1.2,>=1.2.1" + "egulias/email-validator": "~1.2,>=1.2.1", + "sensio/framework-extra-bundle": "^3.0.2" }, "autoload": { "psr-4": { diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/AnnotatedControllerTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/AnnotatedControllerTest.php new file mode 100644 index 000000000000..2fdbef883949 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/AnnotatedControllerTest.php @@ -0,0 +1,39 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\FrameworkBundle\Tests\Functional; + +class AnnotatedControllerTest extends WebTestCase +{ + /** + * @dataProvider getRoutes + */ + public function testAnnotatedController($path, $expectedValue) + { + $client = $this->createClient(array('test_case' => 'AnnotatedController', 'root_config' => 'config.yml')); + $client->request('GET', '/annotated'.$path); + + $this->assertSame(200, $client->getResponse()->getStatusCode()); + $this->assertSame($expectedValue, $client->getResponse()->getContent()); + } + + public function getRoutes() + { + return array( + array('/null_request', 'Symfony\Component\HttpFoundation\Request'), + array('/null_argument', ''), + array('/null_argument_with_route_param', ''), + array('/null_argument_with_route_param/value', 'value'), + array('/argument_with_route_param_and_default', 'value'), + array('/argument_with_route_param_and_default/custom', 'custom'), + ); + } +} diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/Bundle/TestBundle/Controller/AnnotatedController.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/Bundle/TestBundle/Controller/AnnotatedController.php new file mode 100644 index 000000000000..98a3ace982e3 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/Bundle/TestBundle/Controller/AnnotatedController.php @@ -0,0 +1,51 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\FrameworkBundle\Tests\Functional\Bundle\TestBundle\Controller; + +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\Routing\Annotation\Route; + +class AnnotatedController +{ + /** + * @Route("/null_request", name="null_request") + */ + public function requestDefaultNullAction(Request $request = null) + { + return new Response($request ? get_class($request) : null); + } + + /** + * @Route("/null_argument", name="null_argument") + */ + public function argumentDefaultNullWithoutRouteParamAction($value = null) + { + return new Response($value); + } + + /** + * @Route("/null_argument_with_route_param/{value}", name="null_argument_with_route_param") + */ + public function argumentDefaultNullWithRouteParamAction($value = null) + { + return new Response($value); + } + + /** + * @Route("/argument_with_route_param_and_default/{value}", defaults={"value": "value"}, name="argument_with_route_param_and_default") + */ + public function argumentWithoutDefaultWithRouteParamAndDefaultAction($value) + { + return new Response($value); + } +} diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/AnnotatedController/bundles.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/AnnotatedController/bundles.php new file mode 100644 index 000000000000..f3290d772854 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/AnnotatedController/bundles.php @@ -0,0 +1,20 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +use Symfony\Bundle\FrameworkBundle\Tests\Functional\Bundle\TestBundle\TestBundle; +use Symfony\Bundle\FrameworkBundle\FrameworkBundle; +use Sensio\Bundle\FrameworkExtraBundle\SensioFrameworkExtraBundle; + +return array( + new FrameworkBundle(), + new TestBundle(), + new SensioFrameworkExtraBundle(), +); diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/AnnotatedController/config.yml b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/AnnotatedController/config.yml new file mode 100644 index 000000000000..377d3e785206 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/AnnotatedController/config.yml @@ -0,0 +1,2 @@ +imports: + - { resource: ../config/default.yml } diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/AnnotatedController/routing.yml b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/AnnotatedController/routing.yml new file mode 100644 index 000000000000..ebd18a0a4c28 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/AnnotatedController/routing.yml @@ -0,0 +1,4 @@ +annotated_controller: + prefix: /annotated + resource: "@TestBundle/Controller/AnnotatedController.php" + type: annotation diff --git a/src/Symfony/Bundle/FrameworkBundle/composer.json b/src/Symfony/Bundle/FrameworkBundle/composer.json index 63c43e003506..5f0c6ce2e146 100644 --- a/src/Symfony/Bundle/FrameworkBundle/composer.json +++ b/src/Symfony/Bundle/FrameworkBundle/composer.json @@ -25,7 +25,7 @@ "symfony/http-foundation": "~2.7", "symfony/http-kernel": "~2.7.23|~2.8.16", "symfony/filesystem": "~2.3", - "symfony/routing": "~2.6,>2.6.4", + "symfony/routing": "~2.7.24|~2.8.17", "symfony/security-core": "~2.6.13|~2.7.9|~2.8", "symfony/security-csrf": "~2.6", "symfony/stopwatch": "~2.3", @@ -45,7 +45,8 @@ "symfony/expression-language": "~2.6", "symfony/process": "~2.0,>=2.0.5", "symfony/validator": "~2.5", - "symfony/yaml": "~2.0,>=2.0.5" + "symfony/yaml": "~2.0,>=2.0.5", + "sensio/framework-extra-bundle": "^3.0.2" }, "suggest": { "symfony/console": "For using the console commands", diff --git a/src/Symfony/Component/Routing/Loader/AnnotationClassLoader.php b/src/Symfony/Component/Routing/Loader/AnnotationClassLoader.php index 339529e5190e..62ad9c3f9fae 100644 --- a/src/Symfony/Component/Routing/Loader/AnnotationClassLoader.php +++ b/src/Symfony/Component/Routing/Loader/AnnotationClassLoader.php @@ -138,6 +138,11 @@ protected function addRoute(RouteCollection $collection, $annot, $globals, \Refl } $defaults = array_replace($globals['defaults'], $annot->getDefaults()); + foreach ($method->getParameters() as $param) { + if (false !== strpos($globals['path'].$annot->getPath(), sprintf('{%s}', $param->getName())) && !isset($defaults[$param->getName()]) && $param->isDefaultValueAvailable()) { + $defaults[$param->getName()] = $param->getDefaultValue(); + } + } $requirements = array_replace($globals['requirements'], $annot->getRequirements()); $options = array_replace($globals['options'], $annot->getOptions()); $schemes = array_merge($globals['schemes'], $annot->getSchemes());