bug #30825 [Routing] Fix: annotation loader ignores method's default values (voronkovich)

This PR was merged into the 4.2 branch.

Discussion
----------

[Routing] Fix: annotation loader ignores method's default values

| Q             | A
| ------------- | ---
| Branch?       | 4.1
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? |no
| Tests pass?   | yes
| Fixed tickets | no
| License       | MIT
| Doc PR        | no

In some cases annotation loader ignores method param's default values.
For example this code won't work as expected:
```php
/**
 * @Route("/hello/{name<\w++>}", methods="GET", name="hello")
 */
public function hello(Request $request, string $name = 'World'): Response
{
    // If you try to open "/hello" path an exception (No route found for "GET /hello") will be thrown.
    return $this->json([
        'hello' => \sprintf('Hello, %s!', $name),
    ]);
}
```

Commits
-------

9b37793cbe [Routing] Fix: annotation loader ignores method's default values
This commit is contained in:
Fabien Potencier 2019-04-03 16:10:24 +02:00
commit 25db9e26c9
3 changed files with 12 additions and 2 deletions

View File

@ -196,7 +196,7 @@ abstract class AnnotationClassLoader implements LoaderInterface
continue;
}
foreach ($paths as $locale => $path) {
if (false !== strpos($path, sprintf('{%s}', $param->name))) {
if (preg_match(sprintf('/\{%s(?:<.*?>)?\}/', preg_quote($param->name)), $path)) {
$defaults[$param->name] = $param->getDefaultValue();
break;
}

View File

@ -12,4 +12,12 @@ class DefaultValueController
public function action($default = 'value')
{
}
/**
* @Route("/hello/{name<\w+>}", name="hello_without_default")
* @Route("/hello/{name<\w+>?Symfony}", name="hello_with_default")
*/
public function hello(string $name = 'World')
{
}
}

View File

@ -136,9 +136,11 @@ class AnnotationClassLoaderTest extends AbstractAnnotationLoaderTest
public function testDefaultValuesForMethods()
{
$routes = $this->loader->load(DefaultValueController::class);
$this->assertCount(1, $routes);
$this->assertCount(3, $routes);
$this->assertEquals('/{default}/path', $routes->get('action')->getPath());
$this->assertEquals('value', $routes->get('action')->getDefault('default'));
$this->assertEquals('Symfony', $routes->get('hello_with_default')->getDefault('name'));
$this->assertEquals('World', $routes->get('hello_without_default')->getDefault('name'));
}
public function testMethodActionControllers()