8000 feature #27774 [FrameworkBundle] allow turning routes to utf8 mode by… · symfony/symfony@254f4c8 · GitHub
[go: up one dir, main page]

Skip to content

Commit 254f4c8

Browse files
committed
feature #27774 [FrameworkBundle] allow turning routes to utf8 mode by default (nicolas-grekas)
This PR was merged into the 4.2-dev branch. Discussion ---------- [FrameworkBundle] allow turning routes to utf8 mode by default | Q | A | ------------- | --- | Branch? | master | Bug fix? | no | New feature? | yes | BC breaks? | no | Deprecations? | yes | Tests pass? | yes | Fixed tickets | - | License | MIT | Doc PR | - This allows building optimized routers that match in a single regexp instead of an alternate of utf8/non-utf8 set of routes. Commits ------- 8f359cc [FrameworkBundle] allow turning routes to utf8 mode by default
2 parents 10e15dc + 8f359cc commit 254f4c8

File tree

7 files changed

+63
-1
lines changed

7 files changed

+63
-1
lines changed

UPGRADE-4.2.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,14 @@ Process
7575
$process = Process::fromShellCommandline('ls -l');
7676
```
7777

78+
FrameworkBundle
79+
---------------
80+
81+
* The `framework.router.utf8` configuration option has been added. If your app's charset
82+
is UTF-8 (see kernel's `getCharset()` method), it is recommended to set it to `true`:
83+
this will generate 404s for non-UTF-8 URLs, which are incompatible with you app anyway,
84+
and will allow dumping optimized routers and using Unicode classes in requirements.
85+
7886
Security
7987
--------
8088

src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -452,6 +452,7 @@ private function addRouterSection(ArrayNodeDefinition $rootNode)
452452
)
453453
->defaultTrue()
454454
->end()
455+
->booleanNode('utf8')->defaultFalse()->end()
455456
->end()
456457
->end()
457458
->end()

src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -687,6 +687,9 @@ private function registerRouterConfiguration(array $config, ContainerBuilder $co
687687

688688
$loader->load('routing.xml');
689689

690+
if ($config['utf8']) {
691+
$container->getDefinition('routing.loader')->replaceArgument(2, array('utf8' => true));
692+
}
690693
if (!interface_exists(ContainerBagInterface::class)) {
691694
$container->getDefinition('router.default')
692695
->replaceArgument(0, new Reference('service_container'))

src/Symfony/Bundle/FrameworkBundle/Resources/config/routing.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
<service id="routing.loader" class="Symfony\Bundle\FrameworkBundle\Routing\DelegatingLoader" public="true">
4949
<argument type="service" id="controller_name_converter" />
5050
<argument type="service" id="routing.resolver" />
51+
<argument type="collection" />
5152
</service>
5253

5354
<service id="router.default" class="Symfony\Bundle\FrameworkBundle\Routing\Router">

src/Symfony/Bundle/FrameworkBundle/Routing/DelegatingLoader.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,16 @@ class DelegatingLoader extends BaseDelegatingLoader
2828
{
2929
protected $parser;
3030
private $loading = false;
31+
private $defaultOptions;
3132

3233
/**
3334
* @param ControllerNameParser $parser A ControllerNameParser instance
3435
* @param LoaderResolverInterface $resolver A LoaderResolverInterface instance
3536
*/
36-
public function __construct(ControllerNameParser $parser, LoaderResolverInterface $resolver)
37+
public function __construct(ControllerNameParser $parser, LoaderResolverInterface $resolver, array $defaultOptions = array())
3738
{
3839
$this->parser = $parser;
40+
$this->defaultOptions = $defaultOptions;
3941

4042
parent::__construct($resolver);
4143
}
@@ -73,6 +75,9 @@ public function load($resource, $type = null)
7375
}
7476

7577
foreach ($collection->all() as $route) {
78+
if ($this->defaultOptions) {
79+
$route->setOptions($route->getOptions() + $this->defaultOptions);
80+
}
7681
if (!is_string($controller = $route->getDefault('_controller'))) {
7782
continue;
7883
}

src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,7 @@ protected static function getBundleDefaultConfig()
226226
'http_port' => 80,
227227
'https_port' => 443,
228228
'strict_requirements' => true,
229+
'utf8' => false,
229230
),
230231
'session' => array(
231232
'enabled' => false,

src/Symfony/Bundle/FrameworkBundle/Tests/Routing/DelegatingLoaderTest.php

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,49 @@ public function testConstructorApi()
2222
$this->assertTrue(true, '__construct() takes a ControllerNameParser and LoaderResolverInterface respectively as its first and second argument.');
2323
}
2424

25+
public function testLoadDefaultOptions()
26+
{
27+
$controllerNameParser = $this->getMockBuilder(ControllerNameParser::class)
28+
->disableOriginalConstructor()
29+
->getMock();
30+
31+
$loaderResolver = $this->getMockBuilder(LoaderResolverInterface::class)
32+
->disableOriginalConstructor()
33+
->getMock();
34+
35+
$loader = $this->getMockBuilder(LoaderInterface::class)->getMock();
36+
37+
$loaderResolver->expects($this->once())
38+
->method('resolve')
39+
->willReturn($loader);
40+
41+
$routeCollection = new RouteCollection();
42+
$routeCollection->add('foo', new Route('/', array(), array(), array('utf8' => false)));
43+
$routeCollection->add('bar', new Route('/', array(), array(), array('foo' => 123)));
44+
45+
$loader->expects($this->once())
46+
->method('load')
47+
->willReturn($routeCollection);
48+
49+
$delegatingLoader = new DelegatingLoader($controllerNameParser, $loaderResolver, array('utf8' => true));
50+
51+
$loadedRouteCollection = $delegatingLoader->load('foo');
52+
$this->assertCount(2, $loadedRouteCollection);
53+
54+
$expected = array(
55+
'compiler_class' => 'Symfony\Component\Routing\RouteCompiler',
56+
'utf8' => false,
57+
);
58+
$this->assertSame($expected, $routeCollection->get('foo')->getOptions());
59+
60+
$expected = array(
61+
'compiler_class' => 'Symfony\Component\Routing\RouteCompiler',
62+
'foo' => 123,
63+
'utf8' => true,
64+
);
65+
$this->assertSame($expected, $routeCollection->get('bar')->getOptions());
66+
}
67+
2568
/**
2669
* @group legacy
2770
* @expectedDeprecation Referencing controllers with foo:bar:baz is deprecated since Symfony 4.1, use "some_parsed::controller" instead.

0 commit comments

Comments
 (0)
0