Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit f0a519a

Browse files
[Routing] allow using compiled matchers and generators without dumping PHP code
1 parent a9f8ca5 commit f0a519a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+5144
-490
lines changed

src/Symfony/Bundle/FrameworkBundle/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']);

src/Symfony/Bundle/FrameworkBundle/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+
}

src/Symfony/Bundle/FrameworkBundle/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+
}

src/Symfony/Bundle/FrameworkBundle/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()

src/Symfony/Component/Routing/CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
CHANGELOG
22
=========
33

4+
4.3.0
5+
-----
6+
7+
* added `CompiledUrlMatcher` and `CompiledUrlMatcherDumper`
8+
* added `CompiledUrlGenerator` and `CompiledUrlGeneratorDumper`
9+
* deprecated `PhpUrlGeneratorDumped` and `PhpMatcherDumper`
10+
411
4.2.0
512
-----
613

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
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\Component\Routing\Generator;
13+
14+
use Psr\Log\LoggerInterface;
15+
use Symfony\Component\Routing\Exception\RouteNotFoundException;
16+
use Symfony\Component\Routing\RequestContext;
17+
18+
/**
19+
* Generates URLs based on rules dumped by CompiledUrlGeneratorDumper.
20+
*/
21+
class CompiledUrlGenerator extends UrlGenerator
22+
{
23+
private $compiledRoutes = [];
24+
private $defaultLocale;
25+
26+
public function __construct(array $compiledRoutes, RequestContext $context, LoggerInterface $logger = null, string $defaultLocale = null)
27+
{
28+
$this->compiledRoutes = $compiledRoutes;
29+
$this->context = $context;
30+
$this->logger = $logger;
31+
$this->defaultLocale = $defaultLocale;
32+
}
33+
34+
public function generate($name, $parameters = [], $referenceType = self::ABSOLUTE_PATH)
35+
{
36+
$locale = $parameters['_locale']
37+
?? $this->context->getParameter('_locale')
38+
?: $this->defaultLocale;
39+
40+
if (null !== $locale) {
41+
do {
42+
if (($this->compiledRoutes[$name.'.'.$locale][1]['_canonical_route'] ?? null) === $name) {
43+
unset($parameters['_locale']);
44+
$name .= '.'.$locale;
45+
break;
46+
}
47+
} while (false !== $locale = strstr($locale, '_', true));
48+
}
49+
50+
if (!isset($this->compiledRoutes[$name])) {
51+
throw new RouteNotFoundException(sprintf('Unable to generate a URL for the named route "%s" as such route does not exist.', $name));
52+
}
53+
54+
list($variables, $defaults, $requirements, $tokens, $hostTokens, $requiredSchemes) = $this->compiledRoutes[$name];
55+
56+
return $this->doGenerate($variables, $defaults, $requirements, $tokens, $parameters, $name, $referenceType, $hostTokens, $requiredSchemes);
57+
}
58+
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
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\Component\Routing\Generator\Dumper;
13+
14+
use Symfony\Component\Routing\Matcher\Dumper\CompiledUrlMatcherDumper;
15+
16+
/**
17+
* CompiledUrlGeneratorDumper creates a PHP array to be used with CompiledUrlGenerator.
18+
*
19+
* @author Fabien Potencier <[email protected]>
20+
* @author Tobias Schultze <http://tobion.de>
21+
* @author Nicolas Grekas <[email protected]>
22+
*/
23+
class CompiledUrlGeneratorDumper extends GeneratorDumper
24+
{
25+
public function getCompiledRoutes(): array
26+
{
27+
$compiledRoutes = [];
28+
foreach ($this->getRoutes()->all() as $name => $route) {
29+
$compiledRoute = $route->compile();
30+
31+
$compiledRoutes[$name] = [
32+
$compiledRoute->getVariables(),
33+
$route->getDefaults(),
34+
$route->getRequirements(),
35+
$compiledRoute->getTokens(),
36+
$compiledRoute->getHostTokens(),
37+
$route->getSchemes(),
38+
];
39+
}
40+
41+
return $compiledRoutes;
42+
}
43+
44+
/**
45+
* {@inheritdoc}
46+
*/
47+
public function dump(array $options = [])
48+
{
49+
return <<<EOF
50+
<?php
51+
52+
// This file has been auto-generated by the Symfony Routing Component.
53+
54+
return [{$this->generateDeclaredRoutes()}
55+
];
56+
57+
EOF;
58+
}
59+
60+
/**
61+
* Generates PHP code representing an array of defined routes
62+
* together with the routes properties (e.g. requirements).
63+
*/
64+
private function generateDeclaredRoutes(): string
65+
{
66+
$routes = '';
67+
foreach ($this->getCompiledRoutes() as $name => $properties) {
68+
$routes .= sprintf("\n '%s' => %s,", $name, CompiledUrlMatcherDumper::export($properties));
69+
}
70+
71+
return $routes;
72+
}
73+
}

src/Symfony/Component/Routing/Generator/Dumper/PhpGeneratorDumper.php

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,17 @@
1111

1212
namespace Symfony\Component\Routing\Generator\Dumper;
1313

14-
use Symfony\Component\Routing\Matcher\Dumper\PhpMatcherDumper;
14+
@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.3, use "CompiledUrlGeneratorDumper" instead.', PhpGeneratorDumper::class), E_USER_DEPRECATED);
15+
16+
use Symfony\Component\Routing\Matcher\Dumper\CompiledUrlMatcherDumper;
1517

1618
/**
1719
* PhpGeneratorDumper creates a PHP class able to generate URLs for a given set of routes.
1820
*
1921
* @author Fabien Potencier <[email protected]>
2022
* @author Tobias Schultze <http://tobion.de>
23+
*
24+
* @deprecated since Symfony 4.3, use CompiledUrlGeneratorDumper instead.
2125
*/
2226
class PhpGeneratorDumper extends GeneratorDumper
2327
{
@@ -92,7 +96,7 @@ private function generateDeclaredRoutes()
9296
$properties[] = $compiledRoute->getHostTokens();
9397
$properties[] = $route->getSchemes();
9498

95-
$routes .= sprintf(" '%s' => %s,\n", $name, PhpMatcherDumper::export($properties));
99+
$routes .= sprintf(" '%s' => %s,\n", $name, CompiledUrlMatcherDumper::export($properties));
96100
}
97101
$routes .= ' ]';
98102

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
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\Component\Routing\Matcher;
13+
14+
use Symfony\Component\Routing\Matcher\Dumper\CompiledUrlMatcherTrait;
15+
use Symfony\Component\Routing\RequestContext;
16+
17+
/**
18+
* Matches URLs based on rules dumped by CompiledUrlMatcherDumper.
19+
*
20+
* @author Nicolas Grekas <[email protected]>
21+
*/
22+
class CompiledUrlMatcher extends UrlMatcher
23+
{
24+
use CompiledUrlMatcherTrait;
25+
26+
public function __construct(array $compiledRoutes, RequestContext $context)
27+
{
28+
$this->context = $context;
29+
list($this->matchHost, $this->staticRoutes, $this->regexpList, $this->dynamicRoutes, $this->checkCondition) = $compiledRoutes;
30+
}
31+
}

0 commit comments

Comments
 (0)