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

Skip to content

Commit b6d9263

Browse files
[Routing] allow using the compiled URL generator without dumping PHP code
1 parent 6dffd45 commit b6d9263

File tree

9 files changed

+405
-9
lines changed

9 files changed

+405
-9
lines changed

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@
7878
use Symfony\Component\PropertyInfo\PropertyInitializableExtractorInterface;
7979
use Symfony\Component\PropertyInfo\PropertyListExtractorInterface;
8080
use Symfony\Component\PropertyInfo\PropertyTypeExtractorInterface;
81+
use Symfony\Component\Routing\Generator\CompiledUrlGenerator;
82+
use Symfony\Component\Routing\Generator\Dumper\PhpGeneratorDumper;
8183
use Symfony\Component\Routing\Loader\AnnotationDirectoryLoader;
8284
use Symfony\Component\Routing\Loader\AnnotationFileLoader;
8385
use Symfony\Component\Security\Core\Security;
@@ -724,6 +726,10 @@ private function registerRouterConfiguration(array $config, ContainerBuilder $co
724726
if (isset($config['type'])) {
725727
$argument['resource_type'] = $config['type'];
726728
}
729+
if (!class_exists(CompiledUrlGenerator::class)) {
730+
$argument['generator_class'] = $argument['generator_base_class'];
731+
$argument['generator_dumper_class'] = PhpGeneratorDumper::class;
732+
}
727733
$router->replaceArgument(2, $argument);
728734

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

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,9 @@
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>
6666
<argument key="matcher_class">Symfony\Bundle\FrameworkBundle\Routing\RedirectableUrlMatcher</argument>
6767
<argument key="matcher_base_class">Symfony\Bundle\FrameworkBundle\Routing\RedirectableUrlMatcher</argument>

src/Symfony/Component/Routing/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ CHANGELOG
55
-----
66

77
* added fallback to cultureless locale for internationalized routes
8+
* added `CompiledUrlGenerator` and `CompiledUrlGeneratorDumper`
9+
* deprecated `PhpUrlGeneratorDumped`
810

911
4.0.0
1012
-----
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
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+
class CompiledUrlGenerator extends UrlGenerator
19+
{
20+
private $compiledRoutes = array();
21+
private $defaultLocale;
22+
23+
public function __construct(array $compiledRoutes, RequestContext $context, LoggerInterface $logger = null, string $defaultLocale = null)
24+
{
25+
$this->compiledRoutes = $compiledRoutes;
26+
$this->context = $context;
27+
$this->logger = $logger;
28+
$this->defaultLocale = $defaultLocale;
29+
}
30+
31+
public function generate($name, $parameters = array(), $referenceType = self::ABSOLUTE_PATH)
32+
{
33+
$locale = $parameters['_locale']
34+
?? $this->context->getParameter('_locale')
35+
?: $this->defaultLocale;
36+
37+
if (null !== $locale) {
38+
do {
39+
if (($this->compiledRoutes[$name.'.'.$locale][1]['_canonical_route'] ?? null) === $name) {
40+
unset($parameters['_locale']);
41+
$name .= '.'.$locale;
42+
break;
43+
}
44+
} while (false !== $locale = strstr($locale, '_', true));
45+
}
46+
47+
if (!isset($this->compiledRoutes[$name])) {
48+
throw new RouteNotFoundException(sprintf('Unable to generate a URL for the named route "%s" as such route does not exist.', $name));
49+
}
50+
51+
list($variables, $defaults, $requirements, $tokens, $hostTokens, $requiredSchemes) = $this->compiledRoutes[$name];
52+
53+
return $this->doGenerate($variables, $defaults, $requirements, $tokens, $parameters, $name, $referenceType, $hostTokens, $requiredSchemes);
54+
}
55+
}
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\PhpMatcherDumper;
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 = array();
28+
foreach ($this->getRoutes()->all() as $name => $route) {
29+
$compiledRoute = $route->compile();
30+
31+
$compiledRoutes[$name] = array(
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 = array())
48+
{
49+
return <<<EOF
50+
<?php
51+
52+
// This file has been auto-generated by the Symfony Routing Component.
53+
54+
return array({$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, PhpMatcherDumper::export($properties));
69+
}
70+
71+
return $routes;
72+
}
73+
}

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

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

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

14+
@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.2, use "CompiledUrlGeneratorDumper" instead.', PhpGeneratorDumper::class), E_USER_DEPRECATED);
15+
1416
use Symfony\Component\Routing\Matcher\Dumper\PhpMatcherDumper;
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.2, use CompiledUrlGeneratorDumper instead.
2125
*/
2226
class PhpGeneratorDumper extends GeneratorDumper
2327
{

src/Symfony/Component/Routing/Router.php

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
use Symfony\Component\Config\Loader\LoaderInterface;
1919
use Symfony\Component\ExpressionLanguage\ExpressionFunctionProviderInterface;
2020
use Symfony\Component\HttpFoundation\Request;
21+
use Symfony\Component\Routing\Generator\CompiledUrlGenerator;
2122
use Symfony\Component\Routing\Generator\ConfigurableRequirementsInterface;
2223
use Symfony\Component\Routing\Generator\Dumper\GeneratorDumperInterface;
2324
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
@@ -83,6 +84,8 @@ class Router implements RouterInterface, RequestMatcherInterface
8384
*/
8485
private $expressionLanguageProviders = array();
8586

87+
private static $dumpCache = array();
88+
8689
/**
8790
* @param LoaderInterface $loader A LoaderInterface instance
8891
* @param mixed $resource The main resource to load
@@ -320,8 +323,10 @@ public function getGenerator()
320323
return $this->generator;
321324
}
322325

326+
$compiled = is_a($this->options['generator_class'], CompiledUrlGenerator::class, true);
327+
323328
if (null === $this->options['cache_dir'] || null === $this->options['generator_cache_class']) {
324-
$this->generator = new $this->options['generator_class']($this->getRouteCollection(), $this->context, $this->logger);
329+
$this->generator = new $this->options[$compiled ? 'generator_base_class' : 'generator_class']($this->getRouteCollection(), $this->context, $this->logger);
325330
} else {
326331
$cache = $this->getConfigCacheFactory()->cache($this->options['cache_dir'].'/'.$this->options['generator_cache_class'].'.php',
327332
function (ConfigCacheInterface $cache) {
@@ -336,11 +341,19 @@ function (ConfigCacheInterface $cache) {
336341
}
337342
);
338343

339-
if (!class_exists($this->options['generator_cache_class'], false)) {
340-
require_once $cache->getPath();
341-
}
344+
if ($compiled) {
345+
if (!isset(self::$dumpCache[$path = $cache->getPath()])) {
346+
self::$dumpCache[$path] = require $path;
347+
}
342348

343-
$this->generator = new $this->options['generator_cache_class']($this->context, $this->logger);
349+
$this->generator = new $this->options['generator_class'](self::$dumpCache[$path], $this->context, $this->logger);
350+
} else {
351+
if (!class_exists($this->options['generator_cache_class'], false)) {
352+
require_once $cache->getPath();
353+
}
354+
355+
$this->generator = new $this->options['generator_cache_class']($this->context, $this->logger);
356+
}
344357
}
345358

346359
if ($this->generator instanceof ConfigurableRequirementsInterface) {

0 commit comments

Comments
 (0)