Skip to content

Commit 2adabe9

Browse files
feature #28865 [Routing] allow using compiled matchers and generators without dumping PHP code (nicolas-grekas)
This PR was merged into the 4.3-dev branch. Discussion ---------- [Routing] allow using compiled matchers and generators without dumping PHP code | Q | A | ------------- | --- | Branch? | master | Bug fix? | no | New feature? | yes | BC breaks? | no | Deprecations? | yes | Tests pass? | yes | Fixed tickets | #29590 | License | MIT | Doc PR | symfony/symfony-docs#10790 This is a resurrection of #25909 to make matcher+generator dumpers output PHP arrays instead of PHP code. Don't be fooled by the diff stats, it's mostly fixtures. This PR should contribute to making the Routing component easier to use standalone. On the way back from SFLive USA. ![image](https://user-images.githubusercontent.com/243674/46920076-784e1b80-cf9d-11e8-86e7-850fffb409de.png) Commits ------- f0a519ac7d [Routing] allow using compiled matchers and generators without dumping PHP code
2 parents 5f4b604 + a788950 commit 2adabe9

File tree

6 files changed

+131
-4
lines changed

6 files changed

+131
-4
lines changed

DependencyInjection/FrameworkExtension.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,11 @@
8282
use Symfony\Component\PropertyInfo\PropertyInitializableExtractorInterface;
8383
use Symfony\Component\PropertyInfo\PropertyListExtractorInterface;
8484
use Symfony\Component\PropertyInfo\PropertyTypeExtractorInterface;
85+
use Symfony\Component\Routing\Generator\Dumper\PhpGeneratorDumper;
8586
use Symfony\Component\Routing\Loader\AnnotationDirectoryLoader;
8687
use Symfony\Component\Routing\Loader\AnnotationFileLoader;
88+
use Symfony\Component\Routing\Matcher\CompiledUrlMatcher;
89+
use Symfony\Component\Routing\Matcher\Dumper\PhpMatcherDumper;
8790
use Symfony\Component\Security\Core\Security;
8891
use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
8992
use Symfony\Component\Serializer\Encoder\DecoderInterface;
@@ -754,6 +757,12 @@ private function registerRouterConfiguration(array $config, ContainerBuilder $co
754757
if (isset($config['type'])) {
755758
$argument['resource_type'] = $config['type'];
756759
}
760+
if (!class_exists(CompiledUrlMatcher::class)) {
761+
$argument['matcher_class'] = $argument['matcher_base_class'];
762+
$argument['matcher_dumper_class'] = PhpMatcherDumper::class;
763+
$argument['generator_class'] = $argument['generator_base_class'];
764+
$argument['generator_dumper_class'] = PhpGeneratorDumper::class;
765+
}
757766
$router->replaceArgument(2, $argument);
758767

759768
$container->setParameter('request_listener.http_port', $config['http_port']);

Resources/config/routing.xml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,13 +59,13 @@
5959
<argument type="collection">
6060
<argument key="cache_dir">%kernel.cache_dir%</argument>
6161
<argument key="debug">%kernel.debug%</argument>
62-
<argument key="generator_class">Symfony\Component\Routing\Generator\UrlGenerator</argument>
62+
<argument key="generator_class">Symfony\Component\Routing\Generator\CompiledUrlGenerator</argument>
6363
<argument key="generator_base_class">Symfony\Component\Routing\Generator\UrlGenerator</argument>
64-
<argument key="generator_dumper_class">Symfony\Component\Routing\Generator\Dumper\PhpGeneratorDumper</argument>
64+
<argument key="generator_dumper_class">Symfony\Component\Routing\Generator\Dumper\CompiledUrlGeneratorDumper</argument>
6565
<argument key="generator_cache_class">%router.cache_class_prefix%UrlGenerator</argument>
66-
<argument key="matcher_class">Symfony\Bundle\FrameworkBundle\Routing\RedirectableUrlMatcher</argument>
66+
<argument key="matcher_class">Symfony\Bundle\FrameworkBundle\Routing\RedirectableCompiledUrlMatcher</argument>
6767
<argument key="matcher_base_class">Symfony\Bundle\FrameworkBundle\Routing\RedirectableUrlMatcher</argument>
68-
<argument key="matcher_dumper_class">Symfony\Component\Routing\Matcher\Dumper\PhpMatcherDumper</argument>
68+
<argument key="matcher_dumper_class">Symfony\Component\Routing\Matcher\Dumper\CompiledUrlMatcherDumper</argument>
6969
<argument key="matcher_cache_class">%router.cache_class_prefix%UrlMatcher</argument>
7070
</argument>
7171
<argument type="service" id="router.request_context" on-invalid="ignore" />
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bundle\FrameworkBundle\Routing;
13+
14+
use Symfony\Component\Routing\Matcher\CompiledUrlMatcher;
15+
use Symfony\Component\Routing\Matcher\RedirectableUrlMatcherInterface;
16+
17+
/**
18+
* @author Fabien Potencier <[email protected]>
19+
*
20+
* @internal
21+
*/
22+
class RedirectableCompiledUrlMatcher extends CompiledUrlMatcher implements RedirectableUrlMatcherInterface
23+
{
24+
/**
25+
* {@inheritdoc}
26+
*/
27+
public function redirect($path, $route, $scheme = null)
28+
{
29+
return [
30+
'_controller' => 'Symfony\\Bundle\\FrameworkBundle\\Controller\\RedirectController::urlRedirectAction',
31+
'path' => $path,
32+
'permanent' => true,
33+
'scheme' => $scheme,
34+
'httpPort' => $this->context->getHttpPort(),
35+
'httpsPort' => $this->context->getHttpsPort(),
36+
'_route' => $route,
37+
];
38+
}
39+
}

Routing/RedirectableUrlMatcher.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,14 @@
1111

1212
namespace Symfony\Bundle\FrameworkBundle\Routing;
1313

14+
@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.3.', RedirectableUrlMatcher::class), E_USER_DEPRECATED);
15+
1416
use Symfony\Component\Routing\Matcher\RedirectableUrlMatcher as BaseMatcher;
1517

1618
/**
1719
* @author Fabien Potencier <[email protected]>
20+
*
21+
* @deprecated since Symfony 4.3
1822
*/
1923
class RedirectableUrlMatcher extends BaseMatcher
2024
{
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bundle\FrameworkBundle\Tests\Routing;
13+
14+
use PHPUnit\Framework\TestCase;
15+
use Symfony\Bundle\FrameworkBundle\Routing\RedirectableCompiledUrlMatcher;
16+
use Symfony\Component\Routing\Matcher\Dumper\CompiledUrlMatcherDumper;
17+
use Symfony\Component\Routing\RequestContext;
18+
use Symfony\Component\Routing\Route;
19+
use Symfony\Component\Routing\RouteCollection;
20+
21+
/**
22+
* @requires function \Symfony\Component\Routing\Matcher\CompiledUrlMatcher::match
23+
*/
24+
class RedirectableCompiledUrlMatcherTest extends TestCase
25+
{
26+
public function testRedirectWhenNoSlash()
27+
{
28+
$routes = new RouteCollection();
29+
$routes->add('foo', new Route('/foo/'));
30+
31+
$matcher = $this->getMatcher($routes, $context = new RequestContext());
32+
33+
$this->assertEquals([
34+
'_controller' => 'Symfony\Bundle\FrameworkBundle\Controller\RedirectController::urlRedirectAction',
35+
'path' => '/foo/',
36+
'permanent' => true,
37+
'scheme' => null,
38+
'httpPort' => $context->getHttpPort(),
39+
'httpsPort' => $context->getHttpsPort(),
40+
'_route' => 'foo',
41+
],
42+
$matcher->match('/foo')
43+
);
44+
}
45+
46+
public function testSchemeRedirect()
47+
{
48+
$routes = new RouteCollection();
49+
$routes->add('foo', new Route('/foo', [], [], [], '', ['https']));
50+
51+
$matcher = $this->getMatcher($routes, $context = new RequestContext());
52+
53+
$this->assertEquals([
54+
'_controller' => 'Symfony\Bundle\FrameworkBundle\Controller\RedirectController::urlRedirectAction',
55+
'path' => '/foo',
56+
'permanent' => true,
57+
'scheme' => 'https',
58+
'httpPort' => $context->getHttpPort(),
59+
'httpsPort' => $context->getHttpsPort(),
60+
'_route' => 'foo',
61+
],
62+
$matcher->match('/foo')
63+
);
64+
}
65+
66+
private function getMatcher(RouteCollection $routes, RequestContext $context)
67+
{
68+
$dumper = new CompiledUrlMatcherDumper($routes);
69+
70+
return new RedirectableCompiledUrlMatcher($dumper->getCompiledRoutes(), $context);
71+
}
72+
}

Tests/Routing/RedirectableUrlMatcherTest.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@
1717
use Symfony\Component\Routing\Route;
1818
use Symfony\Component\Routing\RouteCollection;
1919

20+
/**
21+
* @group legacy
22+
*/
2023
class RedirectableUrlMatcherTest extends TestCase
2124
{
2225
public function testRedirectWhenNoSlash()

0 commit comments

Comments
 (0)