[Routing] allow using compiled matchers and generators without dumping PHP code
This commit is contained in:
parent
a9f8ca57af
commit
f0a519ac7d
@ -82,8 +82,11 @@ use Symfony\Component\PropertyInfo\PropertyInfoExtractorInterface;
|
|||||||
use Symfony\Component\PropertyInfo\PropertyInitializableExtractorInterface;
|
use Symfony\Component\PropertyInfo\PropertyInitializableExtractorInterface;
|
||||||
use Symfony\Component\PropertyInfo\PropertyListExtractorInterface;
|
use Symfony\Component\PropertyInfo\PropertyListExtractorInterface;
|
||||||
use Symfony\Component\PropertyInfo\PropertyTypeExtractorInterface;
|
use Symfony\Component\PropertyInfo\PropertyTypeExtractorInterface;
|
||||||
|
use Symfony\Component\Routing\Generator\Dumper\PhpGeneratorDumper;
|
||||||
use Symfony\Component\Routing\Loader\AnnotationDirectoryLoader;
|
use Symfony\Component\Routing\Loader\AnnotationDirectoryLoader;
|
||||||
use Symfony\Component\Routing\Loader\AnnotationFileLoader;
|
use Symfony\Component\Routing\Loader\AnnotationFileLoader;
|
||||||
|
use Symfony\Component\Routing\Matcher\CompiledUrlMatcher;
|
||||||
|
use Symfony\Component\Routing\Matcher\Dumper\PhpMatcherDumper;
|
||||||
use Symfony\Component\Security\Core\Security;
|
use Symfony\Component\Security\Core\Security;
|
||||||
use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
|
use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
|
||||||
use Symfony\Component\Serializer\Encoder\DecoderInterface;
|
use Symfony\Component\Serializer\Encoder\DecoderInterface;
|
||||||
@ -754,6 +757,12 @@ class FrameworkExtension extends Extension
|
|||||||
if (isset($config['type'])) {
|
if (isset($config['type'])) {
|
||||||
$argument['resource_type'] = $config['type'];
|
$argument['resource_type'] = $config['type'];
|
||||||
}
|
}
|
||||||
|
if (!class_exists(CompiledUrlMatcher::class)) {
|
||||||
|
$argument['matcher_class'] = $argument['matcher_base_class'];
|
||||||
|
$argument['matcher_dumper_class'] = PhpMatcherDumper::class;
|
||||||
|
$argument['generator_class'] = $argument['generator_base_class'];
|
||||||
|
$argument['generator_dumper_class'] = PhpGeneratorDumper::class;
|
||||||
|
}
|
||||||
$router->replaceArgument(2, $argument);
|
$router->replaceArgument(2, $argument);
|
||||||
|
|
||||||
$container->setParameter('request_listener.http_port', $config['http_port']);
|
$container->setParameter('request_listener.http_port', $config['http_port']);
|
||||||
|
@ -59,13 +59,13 @@
|
|||||||
<argument type="collection">
|
<argument type="collection">
|
||||||
<argument key="cache_dir">%kernel.cache_dir%</argument>
|
<argument key="cache_dir">%kernel.cache_dir%</argument>
|
||||||
<argument key="debug">%kernel.debug%</argument>
|
<argument key="debug">%kernel.debug%</argument>
|
||||||
<argument key="generator_class">Symfony\Component\Routing\Generator\UrlGenerator</argument>
|
<argument key="generator_class">Symfony\Component\Routing\Generator\CompiledUrlGenerator</argument>
|
||||||
<argument key="generator_base_class">Symfony\Component\Routing\Generator\UrlGenerator</argument>
|
<argument key="generator_base_class">Symfony\Component\Routing\Generator\UrlGenerator</argument>
|
||||||
<argument key="generator_dumper_class">Symfony\Component\Routing\Generator\Dumper\PhpGeneratorDumper</argument>
|
<argument key="generator_dumper_class">Symfony\Component\Routing\Generator\Dumper\CompiledUrlGeneratorDumper</argument>
|
||||||
<argument key="generator_cache_class">%router.cache_class_prefix%UrlGenerator</argument>
|
<argument key="generator_cache_class">%router.cache_class_prefix%UrlGenerator</argument>
|
||||||
<argument key="matcher_class">Symfony\Bundle\FrameworkBundle\Routing\RedirectableUrlMatcher</argument>
|
<argument key="matcher_class">Symfony\Bundle\FrameworkBundle\Routing\RedirectableCompiledUrlMatcher</argument>
|
||||||
<argument key="matcher_base_class">Symfony\Bundle\FrameworkBundle\Routing\RedirectableUrlMatcher</argument>
|
<argument key="matcher_base_class">Symfony\Bundle\FrameworkBundle\Routing\RedirectableUrlMatcher</argument>
|
||||||
<argument key="matcher_dumper_class">Symfony\Component\Routing\Matcher\Dumper\PhpMatcherDumper</argument>
|
<argument key="matcher_dumper_class">Symfony\Component\Routing\Matcher\Dumper\CompiledUrlMatcherDumper</argument>
|
||||||
<argument key="matcher_cache_class">%router.cache_class_prefix%UrlMatcher</argument>
|
<argument key="matcher_cache_class">%router.cache_class_prefix%UrlMatcher</argument>
|
||||||
</argument>
|
</argument>
|
||||||
<argument type="service" id="router.request_context" on-invalid="ignore" />
|
<argument type="service" id="router.request_context" on-invalid="ignore" />
|
||||||
|
@ -0,0 +1,39 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Bundle\FrameworkBundle\Routing;
|
||||||
|
|
||||||
|
use Symfony\Component\Routing\Matcher\CompiledUrlMatcher;
|
||||||
|
use Symfony\Component\Routing\Matcher\RedirectableUrlMatcherInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
class RedirectableCompiledUrlMatcher extends CompiledUrlMatcher implements RedirectableUrlMatcherInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function redirect($path, $route, $scheme = null)
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'_controller' => 'Symfony\\Bundle\\FrameworkBundle\\Controller\\RedirectController::urlRedirectAction',
|
||||||
|
'path' => $path,
|
||||||
|
'permanent' => true,
|
||||||
|
'scheme' => $scheme,
|
||||||
|
'httpPort' => $this->context->getHttpPort(),
|
||||||
|
'httpsPort' => $this->context->getHttpsPort(),
|
||||||
|
'_route' => $route,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
@ -11,10 +11,14 @@
|
|||||||
|
|
||||||
namespace Symfony\Bundle\FrameworkBundle\Routing;
|
namespace Symfony\Bundle\FrameworkBundle\Routing;
|
||||||
|
|
||||||
|
@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.3.', RedirectableUrlMatcher::class), E_USER_DEPRECATED);
|
||||||
|
|
||||||
use Symfony\Component\Routing\Matcher\RedirectableUrlMatcher as BaseMatcher;
|
use Symfony\Component\Routing\Matcher\RedirectableUrlMatcher as BaseMatcher;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Fabien Potencier <fabien@symfony.com>
|
* @author Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* @deprecated since Symfony 4.3
|
||||||
*/
|
*/
|
||||||
class RedirectableUrlMatcher extends BaseMatcher
|
class RedirectableUrlMatcher extends BaseMatcher
|
||||||
{
|
{
|
||||||
|
@ -0,0 +1,72 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Bundle\FrameworkBundle\Tests\Routing;
|
||||||
|
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use Symfony\Bundle\FrameworkBundle\Routing\RedirectableCompiledUrlMatcher;
|
||||||
|
use Symfony\Component\Routing\Matcher\Dumper\CompiledUrlMatcherDumper;
|
||||||
|
use Symfony\Component\Routing\RequestContext;
|
||||||
|
use Symfony\Component\Routing\Route;
|
||||||
|
use Symfony\Component\Routing\RouteCollection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @requires function \Symfony\Component\Routing\Matcher\CompiledUrlMatcher::match
|
||||||
|
*/
|
||||||
|
class RedirectableCompiledUrlMatcherTest extends TestCase
|
||||||
|
{
|
||||||
|
public function testRedirectWhenNoSlash()
|
||||||
|
{
|
||||||
|
$routes = new RouteCollection();
|
||||||
|
$routes->add('foo', new Route('/foo/'));
|
||||||
|
|
||||||
|
$matcher = $this->getMatcher($routes, $context = new RequestContext());
|
||||||
|
|
||||||
|
$this->assertEquals([
|
||||||
|
'_controller' => 'Symfony\Bundle\FrameworkBundle\Controller\RedirectController::urlRedirectAction',
|
||||||
|
'path' => '/foo/',
|
||||||
|
'permanent' => true,
|
||||||
|
'scheme' => null,
|
||||||
|
'httpPort' => $context->getHttpPort(),
|
||||||
|
'httpsPort' => $context->getHttpsPort(),
|
||||||
|
'_route' => 'foo',
|
||||||
|
],
|
||||||
|
$matcher->match('/foo')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testSchemeRedirect()
|
||||||
|
{
|
||||||
|
$routes = new RouteCollection();
|
||||||
|
$routes->add('foo', new Route('/foo', [], [], [], '', ['https']));
|
||||||
|
|
||||||
|
$matcher = $this->getMatcher($routes, $context = new RequestContext());
|
||||||
|
|
||||||
|
$this->assertEquals([
|
||||||
|
'_controller' => 'Symfony\Bundle\FrameworkBundle\Controller\RedirectController::urlRedirectAction',
|
||||||
|
'path' => '/foo',
|
||||||
|
'permanent' => true,
|
||||||
|
'scheme' => 'https',
|
||||||
|
'httpPort' => $context->getHttpPort(),
|
||||||
|
'httpsPort' => $context->getHttpsPort(),
|
||||||
|
'_route' => 'foo',
|
||||||
|
],
|
||||||
|
$matcher->match('/foo')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getMatcher(RouteCollection $routes, RequestContext $context)
|
||||||
|
{
|
||||||
|
$dumper = new CompiledUrlMatcherDumper($routes);
|
||||||
|
|
||||||
|
return new RedirectableCompiledUrlMatcher($dumper->getCompiledRoutes(), $context);
|
||||||
|
}
|
||||||
|
}
|
@ -17,6 +17,9 @@ use Symfony\Component\Routing\RequestContext;
|
|||||||
use Symfony\Component\Routing\Route;
|
use Symfony\Component\Routing\Route;
|
||||||
use Symfony\Component\Routing\RouteCollection;
|
use Symfony\Component\Routing\RouteCollection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @group legacy
|
||||||
|
*/
|
||||||
class RedirectableUrlMatcherTest extends TestCase
|
class RedirectableUrlMatcherTest extends TestCase
|
||||||
{
|
{
|
||||||
public function testRedirectWhenNoSlash()
|
public function testRedirectWhenNoSlash()
|
||||||
|
@ -1,6 +1,13 @@
|
|||||||
CHANGELOG
|
CHANGELOG
|
||||||
=========
|
=========
|
||||||
|
|
||||||
|
4.3.0
|
||||||
|
-----
|
||||||
|
|
||||||
|
* added `CompiledUrlMatcher` and `CompiledUrlMatcherDumper`
|
||||||
|
* added `CompiledUrlGenerator` and `CompiledUrlGeneratorDumper`
|
||||||
|
* deprecated `PhpUrlGeneratorDumped` and `PhpMatcherDumper`
|
||||||
|
|
||||||
4.2.0
|
4.2.0
|
||||||
-----
|
-----
|
||||||
|
|
||||||
|
@ -0,0 +1,58 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Component\Routing\Generator;
|
||||||
|
|
||||||
|
use Psr\Log\LoggerInterface;
|
||||||
|
use Symfony\Component\Routing\Exception\RouteNotFoundException;
|
||||||
|
use Symfony\Component\Routing\RequestContext;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates URLs based on rules dumped by CompiledUrlGeneratorDumper.
|
||||||
|
*/
|
||||||
|
class CompiledUrlGenerator extends UrlGenerator
|
||||||
|
{
|
||||||
|
private $compiledRoutes = [];
|
||||||
|
private $defaultLocale;
|
||||||
|
|
||||||
|
public function __construct(array $compiledRoutes, RequestContext $context, LoggerInterface $logger = null, string $defaultLocale = null)
|
||||||
|
{
|
||||||
|
$this->compiledRoutes = $compiledRoutes;
|
||||||
|
$this->context = $context;
|
||||||
|
$this->logger = $logger;
|
||||||
|
$this->defaultLocale = $defaultLocale;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function generate($name, $parameters = [], $referenceType = self::ABSOLUTE_PATH)
|
||||||
|
{
|
||||||
|
$locale = $parameters['_locale']
|
||||||
|
?? $this->context->getParameter('_locale')
|
||||||
|
?: $this->defaultLocale;
|
||||||
|
|
||||||
|
if (null !== $locale) {
|
||||||
|
do {
|
||||||
|
if (($this->compiledRoutes[$name.'.'.$locale][1]['_canonical_route'] ?? null) === $name) {
|
||||||
|
unset($parameters['_locale']);
|
||||||
|
$name .= '.'.$locale;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} while (false !== $locale = strstr($locale, '_', true));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isset($this->compiledRoutes[$name])) {
|
||||||
|
throw new RouteNotFoundException(sprintf('Unable to generate a URL for the named route "%s" as such route does not exist.', $name));
|
||||||
|
}
|
||||||
|
|
||||||
|
list($variables, $defaults, $requirements, $tokens, $hostTokens, $requiredSchemes) = $this->compiledRoutes[$name];
|
||||||
|
|
||||||
|
return $this->doGenerate($variables, $defaults, $requirements, $tokens, $parameters, $name, $referenceType, $hostTokens, $requiredSchemes);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,73 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Component\Routing\Generator\Dumper;
|
||||||
|
|
||||||
|
use Symfony\Component\Routing\Matcher\Dumper\CompiledUrlMatcherDumper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CompiledUrlGeneratorDumper creates a PHP array to be used with CompiledUrlGenerator.
|
||||||
|
*
|
||||||
|
* @author Fabien Potencier <fabien@symfony.com>
|
||||||
|
* @author Tobias Schultze <http://tobion.de>
|
||||||
|
* @author Nicolas Grekas <p@tchwork.com>
|
||||||
|
*/
|
||||||
|
class CompiledUrlGeneratorDumper extends GeneratorDumper
|
||||||
|
{
|
||||||
|
public function getCompiledRoutes(): array
|
||||||
|
{
|
||||||
|
$compiledRoutes = [];
|
||||||
|
foreach ($this->getRoutes()->all() as $name => $route) {
|
||||||
|
$compiledRoute = $route->compile();
|
||||||
|
|
||||||
|
$compiledRoutes[$name] = [
|
||||||
|
$compiledRoute->getVariables(),
|
||||||
|
$route->getDefaults(),
|
||||||
|
$route->getRequirements(),
|
||||||
|
$compiledRoute->getTokens(),
|
||||||
|
$compiledRoute->getHostTokens(),
|
||||||
|
$route->getSchemes(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $compiledRoutes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function dump(array $options = [])
|
||||||
|
{
|
||||||
|
return <<<EOF
|
||||||
|
<?php
|
||||||
|
|
||||||
|
// This file has been auto-generated by the Symfony Routing Component.
|
||||||
|
|
||||||
|
return [{$this->generateDeclaredRoutes()}
|
||||||
|
];
|
||||||
|
|
||||||
|
EOF;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates PHP code representing an array of defined routes
|
||||||
|
* together with the routes properties (e.g. requirements).
|
||||||
|
*/
|
||||||
|
private function generateDeclaredRoutes(): string
|
||||||
|
{
|
||||||
|
$routes = '';
|
||||||
|
foreach ($this->getCompiledRoutes() as $name => $properties) {
|
||||||
|
$routes .= sprintf("\n '%s' => %s,", $name, CompiledUrlMatcherDumper::export($properties));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $routes;
|
||||||
|
}
|
||||||
|
}
|
@ -11,13 +11,17 @@
|
|||||||
|
|
||||||
namespace Symfony\Component\Routing\Generator\Dumper;
|
namespace Symfony\Component\Routing\Generator\Dumper;
|
||||||
|
|
||||||
use Symfony\Component\Routing\Matcher\Dumper\PhpMatcherDumper;
|
@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.3, use "CompiledUrlGeneratorDumper" instead.', PhpGeneratorDumper::class), E_USER_DEPRECATED);
|
||||||
|
|
||||||
|
use Symfony\Component\Routing\Matcher\Dumper\CompiledUrlMatcherDumper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* PhpGeneratorDumper creates a PHP class able to generate URLs for a given set of routes.
|
* PhpGeneratorDumper creates a PHP class able to generate URLs for a given set of routes.
|
||||||
*
|
*
|
||||||
* @author Fabien Potencier <fabien@symfony.com>
|
* @author Fabien Potencier <fabien@symfony.com>
|
||||||
* @author Tobias Schultze <http://tobion.de>
|
* @author Tobias Schultze <http://tobion.de>
|
||||||
|
*
|
||||||
|
* @deprecated since Symfony 4.3, use CompiledUrlGeneratorDumper instead.
|
||||||
*/
|
*/
|
||||||
class PhpGeneratorDumper extends GeneratorDumper
|
class PhpGeneratorDumper extends GeneratorDumper
|
||||||
{
|
{
|
||||||
@ -92,7 +96,7 @@ EOF;
|
|||||||
$properties[] = $compiledRoute->getHostTokens();
|
$properties[] = $compiledRoute->getHostTokens();
|
||||||
$properties[] = $route->getSchemes();
|
$properties[] = $route->getSchemes();
|
||||||
|
|
||||||
$routes .= sprintf(" '%s' => %s,\n", $name, PhpMatcherDumper::export($properties));
|
$routes .= sprintf(" '%s' => %s,\n", $name, CompiledUrlMatcherDumper::export($properties));
|
||||||
}
|
}
|
||||||
$routes .= ' ]';
|
$routes .= ' ]';
|
||||||
|
|
||||||
|
31
src/Symfony/Component/Routing/Matcher/CompiledUrlMatcher.php
Normal file
31
src/Symfony/Component/Routing/Matcher/CompiledUrlMatcher.php
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Component\Routing\Matcher;
|
||||||
|
|
||||||
|
use Symfony\Component\Routing\Matcher\Dumper\CompiledUrlMatcherTrait;
|
||||||
|
use Symfony\Component\Routing\RequestContext;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Matches URLs based on rules dumped by CompiledUrlMatcherDumper.
|
||||||
|
*
|
||||||
|
* @author Nicolas Grekas <p@tchwork.com>
|
||||||
|
*/
|
||||||
|
class CompiledUrlMatcher extends UrlMatcher
|
||||||
|
{
|
||||||
|
use CompiledUrlMatcherTrait;
|
||||||
|
|
||||||
|
public function __construct(array $compiledRoutes, RequestContext $context)
|
||||||
|
{
|
||||||
|
$this->context = $context;
|
||||||
|
list($this->matchHost, $this->staticRoutes, $this->regexpList, $this->dynamicRoutes, $this->checkCondition) = $compiledRoutes;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,500 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Component\Routing\Matcher\Dumper;
|
||||||
|
|
||||||
|
use Symfony\Component\ExpressionLanguage\ExpressionFunctionProviderInterface;
|
||||||
|
use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
|
||||||
|
use Symfony\Component\Routing\Route;
|
||||||
|
use Symfony\Component\Routing\RouteCollection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CompiledUrlMatcherDumper creates PHP arrays to be used with CompiledUrlMatcher.
|
||||||
|
*
|
||||||
|
* @author Fabien Potencier <fabien@symfony.com>
|
||||||
|
* @author Tobias Schultze <http://tobion.de>
|
||||||
|
* @author Arnaud Le Blanc <arnaud.lb@gmail.com>
|
||||||
|
* @author Nicolas Grekas <p@tchwork.com>
|
||||||
|
*/
|
||||||
|
class CompiledUrlMatcherDumper extends MatcherDumper
|
||||||
|
{
|
||||||
|
private $expressionLanguage;
|
||||||
|
private $signalingException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var ExpressionFunctionProviderInterface[]
|
||||||
|
*/
|
||||||
|
private $expressionLanguageProviders = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function dump(array $options = [])
|
||||||
|
{
|
||||||
|
return <<<EOF
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This file has been auto-generated
|
||||||
|
* by the Symfony Routing Component.
|
||||||
|
*/
|
||||||
|
|
||||||
|
return [
|
||||||
|
{$this->generateCompiledRoutes()}];
|
||||||
|
|
||||||
|
EOF;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addExpressionLanguageProvider(ExpressionFunctionProviderInterface $provider)
|
||||||
|
{
|
||||||
|
$this->expressionLanguageProviders[] = $provider;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates the arrays for CompiledUrlMatcher's constructor.
|
||||||
|
*/
|
||||||
|
public function getCompiledRoutes(bool $forDump = false): array
|
||||||
|
{
|
||||||
|
// Group hosts by same-suffix, re-order when possible
|
||||||
|
$matchHost = false;
|
||||||
|
$routes = new StaticPrefixCollection();
|
||||||
|
foreach ($this->getRoutes()->all() as $name => $route) {
|
||||||
|
if ($host = $route->getHost()) {
|
||||||
|
$matchHost = true;
|
||||||
|
$host = '/'.strtr(strrev($host), '}.{', '(/)');
|
||||||
|
}
|
||||||
|
|
||||||
|
$routes->addRoute($host ?: '/(.*)', [$name, $route]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($matchHost) {
|
||||||
|
$compiledRoutes = [true];
|
||||||
|
$routes = $routes->populateCollection(new RouteCollection());
|
||||||
|
} else {
|
||||||
|
$compiledRoutes = [false];
|
||||||
|
$routes = $this->getRoutes();
|
||||||
|
}
|
||||||
|
|
||||||
|
list($staticRoutes, $dynamicRoutes) = $this->groupStaticRoutes($routes);
|
||||||
|
|
||||||
|
$conditions = [null];
|
||||||
|
$compiledRoutes[] = $this->compileStaticRoutes($staticRoutes, $conditions);
|
||||||
|
$chunkLimit = \count($dynamicRoutes);
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
try {
|
||||||
|
$this->signalingException = new \RuntimeException('preg_match(): Compilation failed: regular expression is too large');
|
||||||
|
$compiledRoutes = array_merge($compiledRoutes, $this->compileDynamicRoutes($dynamicRoutes, $matchHost, $chunkLimit, $conditions));
|
||||||
|
|
||||||
|
break;
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
if (1 < $chunkLimit && $this->signalingException === $e) {
|
||||||
|
$chunkLimit = 1 + ($chunkLimit >> 1);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($forDump) {
|
||||||
|
$compiledRoutes[2] = $compiledRoutes[4];
|
||||||
|
}
|
||||||
|
unset($conditions[0]);
|
||||||
|
|
||||||
|
if ($conditions) {
|
||||||
|
foreach ($conditions as $expression => $condition) {
|
||||||
|
$conditions[$expression] = "case {$condition}: return {$expression};";
|
||||||
|
}
|
||||||
|
|
||||||
|
$checkConditionCode = <<<EOF
|
||||||
|
static function (\$condition, \$context, \$request) { // \$checkCondition
|
||||||
|
switch (\$condition) {
|
||||||
|
{$this->indent(implode("\n", $conditions), 3)}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EOF;
|
||||||
|
$compiledRoutes[4] = $forDump ? $checkConditionCode .= ",\n" : eval('return '.$checkConditionCode.';');
|
||||||
|
} else {
|
||||||
|
$compiledRoutes[4] = $forDump ? " null, // \$checkCondition\n" : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $compiledRoutes;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function generateCompiledRoutes(): string
|
||||||
|
{
|
||||||
|
list($matchHost, $staticRoutes, $regexpCode, $dynamicRoutes, $checkConditionCode) = $this->getCompiledRoutes(true);
|
||||||
|
|
||||||
|
$code = self::export($matchHost).', // $matchHost'."\n";
|
||||||
|
|
||||||
|
$code .= '[ // $staticRoutes'."\n";
|
||||||
|
foreach ($staticRoutes as $path => $routes) {
|
||||||
|
$code .= sprintf(" %s => [\n", self::export($path));
|
||||||
|
foreach ($routes as $route) {
|
||||||
|
$code .= sprintf(" [%s, %s, %s, %s, %s, %s, %s],\n", ...array_map([__CLASS__, 'export'], $route));
|
||||||
|
}
|
||||||
|
$code .= " ],\n";
|
||||||
|
}
|
||||||
|
$code .= "],\n";
|
||||||
|
|
||||||
|
$code .= sprintf("[ // \$regexpList%s\n],\n", $regexpCode);
|
||||||
|
|
||||||
|
$code .= '[ // $dynamicRoutes'."\n";
|
||||||
|
foreach ($dynamicRoutes as $path => $routes) {
|
||||||
|
$code .= sprintf(" %s => [\n", self::export($path));
|
||||||
|
foreach ($routes as $route) {
|
||||||
|
$code .= sprintf(" [%s, %s, %s, %s, %s, %s, %s],\n", ...array_map([__CLASS__, 'export'], $route));
|
||||||
|
}
|
||||||
|
$code .= " ],\n";
|
||||||
|
}
|
||||||
|
$code .= "],\n";
|
||||||
|
$code = preg_replace('/ => \[\n (\[.+?),\n \],/', ' => [$1],', $code);
|
||||||
|
|
||||||
|
return $this->indent($code, 1).$checkConditionCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Splits static routes from dynamic routes, so that they can be matched first, using a simple switch.
|
||||||
|
*/
|
||||||
|
private function groupStaticRoutes(RouteCollection $collection): array
|
||||||
|
{
|
||||||
|
$staticRoutes = $dynamicRegex = [];
|
||||||
|
$dynamicRoutes = new RouteCollection();
|
||||||
|
|
||||||
|
foreach ($collection->all() as $name => $route) {
|
||||||
|
$compiledRoute = $route->compile();
|
||||||
|
$hostRegex = $compiledRoute->getHostRegex();
|
||||||
|
$regex = $compiledRoute->getRegex();
|
||||||
|
if ($hasTrailingSlash = '/' !== $route->getPath()) {
|
||||||
|
$pos = strrpos($regex, '$');
|
||||||
|
$hasTrailingSlash = '/' === $regex[$pos - 1];
|
||||||
|
$regex = substr_replace($regex, '/?$', $pos - $hasTrailingSlash, 1 + $hasTrailingSlash);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$compiledRoute->getPathVariables()) {
|
||||||
|
$host = !$compiledRoute->getHostVariables() ? $route->getHost() : '';
|
||||||
|
$url = $route->getPath();
|
||||||
|
if ($hasTrailingSlash) {
|
||||||
|
$url = substr($url, 0, -1);
|
||||||
|
}
|
||||||
|
foreach ($dynamicRegex as list($hostRx, $rx)) {
|
||||||
|
if (preg_match($rx, $url) && (!$host || !$hostRx || preg_match($hostRx, $host))) {
|
||||||
|
$dynamicRegex[] = [$hostRegex, $regex];
|
||||||
|
$dynamicRoutes->add($name, $route);
|
||||||
|
continue 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$staticRoutes[$url][$name] = [$route, $hasTrailingSlash];
|
||||||
|
} else {
|
||||||
|
$dynamicRegex[] = [$hostRegex, $regex];
|
||||||
|
$dynamicRoutes->add($name, $route);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return [$staticRoutes, $dynamicRoutes];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compiles static routes in a switch statement.
|
||||||
|
*
|
||||||
|
* Condition-less paths are put in a static array in the switch's default, with generic matching logic.
|
||||||
|
* Paths that can match two or more routes, or have user-specified conditions are put in separate switch's cases.
|
||||||
|
*
|
||||||
|
* @throws \LogicException
|
||||||
|
*/
|
||||||
|
private function compileStaticRoutes(array $staticRoutes, array &$conditions): array
|
||||||
|
{
|
||||||
|
if (!$staticRoutes) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
$compiledRoutes = [];
|
||||||
|
|
||||||
|
foreach ($staticRoutes as $url => $routes) {
|
||||||
|
$compiledRoutes[$url] = [];
|
||||||
|
foreach ($routes as $name => list($route, $hasTrailingSlash)) {
|
||||||
|
$compiledRoutes[$url][] = $this->compileRoute($route, $name, !$route->compile()->getHostVariables() ? $route->getHost() : $route->compile()->getHostRegex() ?: null, $hasTrailingSlash, false, $conditions);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $compiledRoutes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compiles a regular expression followed by a switch statement to match dynamic routes.
|
||||||
|
*
|
||||||
|
* The regular expression matches both the host and the pathinfo at the same time. For stellar performance,
|
||||||
|
* it is built as a tree of patterns, with re-ordering logic to group same-prefix routes together when possible.
|
||||||
|
*
|
||||||
|
* Patterns are named so that we know which one matched (https://pcre.org/current/doc/html/pcre2syntax.html#SEC23).
|
||||||
|
* This name is used to "switch" to the additional logic required to match the final route.
|
||||||
|
*
|
||||||
|
* Condition-less paths are put in a static array in the switch's default, with generic matching logic.
|
||||||
|
* Paths that can match two or more routes, or have user-specified conditions are put in separate switch's cases.
|
||||||
|
*
|
||||||
|
* Last but not least:
|
||||||
|
* - Because it is not possibe to mix unicode/non-unicode patterns in a single regexp, several of them can be generated.
|
||||||
|
* - The same regexp can be used several times when the logic in the switch rejects the match. When this happens, the
|
||||||
|
* matching-but-failing subpattern is blacklisted by replacing its name by "(*F)", which forces a failure-to-match.
|
||||||
|
* To ease this backlisting operation, the name of subpatterns is also the string offset where the replacement should occur.
|
||||||
|
*/
|
||||||
|
private function compileDynamicRoutes(RouteCollection $collection, bool $matchHost, int $chunkLimit, array &$conditions): array
|
||||||
|
{
|
||||||
|
if (!$collection->all()) {
|
||||||
|
return [[], [], ''];
|
||||||
|
}
|
||||||
|
$regexpList = [];
|
||||||
|
$code = '';
|
||||||
|
$state = (object) [
|
||||||
|
'regexMark' => 0,
|
||||||
|
'regex' => [],
|
||||||
|
'routes' => [],
|
||||||
|
'mark' => 0,
|
||||||
|
'markTail' => 0,
|
||||||
|
'hostVars' => [],
|
||||||
|
'vars' => [],
|
||||||
|
];
|
||||||
|
$state->getVars = static function ($m) use ($state) {
|
||||||
|
if ('_route' === $m[1]) {
|
||||||
|
return '?:';
|
||||||
|
}
|
||||||
|
|
||||||
|
$state->vars[] = $m[1];
|
||||||
|
|
||||||
|
return '';
|
||||||
|
};
|
||||||
|
|
||||||
|
$chunkSize = 0;
|
||||||
|
$prev = null;
|
||||||
|
$perModifiers = [];
|
||||||
|
foreach ($collection->all() as $name => $route) {
|
||||||
|
preg_match('#[a-zA-Z]*$#', $route->compile()->getRegex(), $rx);
|
||||||
|
if ($chunkLimit < ++$chunkSize || $prev !== $rx[0] && $route->compile()->getPathVariables()) {
|
||||||
|
$chunkSize = 1;
|
||||||
|
$routes = new RouteCollection();
|
||||||
|
$perModifiers[] = [$rx[0], $routes];
|
||||||
|
$prev = $rx[0];
|
||||||
|
}
|
||||||
|
$routes->add($name, $route);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($perModifiers as list($modifiers, $routes)) {
|
||||||
|
$prev = false;
|
||||||
|
$perHost = [];
|
||||||
|
foreach ($routes->all() as $name => $route) {
|
||||||
|
$regex = $route->compile()->getHostRegex();
|
||||||
|
if ($prev !== $regex) {
|
||||||
|
$routes = new RouteCollection();
|
||||||
|
$perHost[] = [$regex, $routes];
|
||||||
|
$prev = $regex;
|
||||||
|
}
|
||||||
|
$routes->add($name, $route);
|
||||||
|
}
|
||||||
|
$prev = false;
|
||||||
|
$rx = '{^(?';
|
||||||
|
$code .= "\n {$state->mark} => ".self::export($rx);
|
||||||
|
$startingMark = $state->mark;
|
||||||
|
$state->mark += \strlen($rx);
|
||||||
|
$state->regex = $rx;
|
||||||
|
|
||||||
|
foreach ($perHost as list($hostRegex, $routes)) {
|
||||||
|
if ($matchHost) {
|
||||||
|
if ($hostRegex) {
|
||||||
|
preg_match('#^.\^(.*)\$.[a-zA-Z]*$#', $hostRegex, $rx);
|
||||||
|
$state->vars = [];
|
||||||
|
$hostRegex = '(?i:'.preg_replace_callback('#\?P<([^>]++)>#', $state->getVars, $rx[1]).')\.';
|
||||||
|
$state->hostVars = $state->vars;
|
||||||
|
} else {
|
||||||
|
$hostRegex = '(?:(?:[^./]*+\.)++)';
|
||||||
|
$state->hostVars = [];
|
||||||
|
}
|
||||||
|
$state->mark += \strlen($rx = ($prev ? ')' : '')."|{$hostRegex}(?");
|
||||||
|
$code .= "\n .".self::export($rx);
|
||||||
|
$state->regex .= $rx;
|
||||||
|
$prev = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
$tree = new StaticPrefixCollection();
|
||||||
|
foreach ($routes->all() as $name => $route) {
|
||||||
|
preg_match('#^.\^(.*)\$.[a-zA-Z]*$#', $route->compile()->getRegex(), $rx);
|
||||||
|
|
||||||
|
$state->vars = [];
|
||||||
|
$regex = preg_replace_callback('#\?P<([^>]++)>#', $state->getVars, $rx[1]);
|
||||||
|
if ($hasTrailingSlash = '/' !== $regex && '/' === $regex[-1]) {
|
||||||
|
$regex = substr($regex, 0, -1);
|
||||||
|
}
|
||||||
|
$hasTrailingVar = (bool) preg_match('#\{\w+\}/?$#', $route->getPath());
|
||||||
|
|
||||||
|
$tree->addRoute($regex, [$name, $regex, $state->vars, $route, $hasTrailingSlash, $hasTrailingVar]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$code .= $this->compileStaticPrefixCollection($tree, $state, 0, $conditions);
|
||||||
|
}
|
||||||
|
if ($matchHost) {
|
||||||
|
$code .= "\n .')'";
|
||||||
|
$state->regex .= ')';
|
||||||
|
}
|
||||||
|
$rx = ")/?$}{$modifiers}";
|
||||||
|
$code .= "\n .'{$rx}',";
|
||||||
|
$state->regex .= $rx;
|
||||||
|
$state->markTail = 0;
|
||||||
|
|
||||||
|
// if the regex is too large, throw a signaling exception to recompute with smaller chunk size
|
||||||
|
set_error_handler(function ($type, $message) { throw 0 === strpos($message, $this->signalingException->getMessage()) ? $this->signalingException : new \ErrorException($message); });
|
||||||
|
try {
|
||||||
|
preg_match($state->regex, '');
|
||||||
|
} finally {
|
||||||
|
restore_error_handler();
|
||||||
|
}
|
||||||
|
|
||||||
|
$regexpList[$startingMark] = $state->regex;
|
||||||
|
}
|
||||||
|
|
||||||
|
$state->routes[$state->mark][] = [null, null, null, null, false, false, 0];
|
||||||
|
unset($state->getVars);
|
||||||
|
|
||||||
|
return [$regexpList, $state->routes, $code];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compiles a regexp tree of subpatterns that matches nested same-prefix routes.
|
||||||
|
*
|
||||||
|
* @param \stdClass $state A simple state object that keeps track of the progress of the compilation,
|
||||||
|
* and gathers the generated switch's "case" and "default" statements
|
||||||
|
*/
|
||||||
|
private function compileStaticPrefixCollection(StaticPrefixCollection $tree, \stdClass $state, int $prefixLen, array &$conditions): string
|
||||||
|
{
|
||||||
|
$code = '';
|
||||||
|
$prevRegex = null;
|
||||||
|
$routes = $tree->getRoutes();
|
||||||
|
|
||||||
|
foreach ($routes as $i => $route) {
|
||||||
|
if ($route instanceof StaticPrefixCollection) {
|
||||||
|
$prevRegex = null;
|
||||||
|
$prefix = substr($route->getPrefix(), $prefixLen);
|
||||||
|
$state->mark += \strlen($rx = "|{$prefix}(?");
|
||||||
|
$code .= "\n .".self::export($rx);
|
||||||
|
$state->regex .= $rx;
|
||||||
|
$code .= $this->indent($this->compileStaticPrefixCollection($route, $state, $prefixLen + \strlen($prefix), $conditions));
|
||||||
|
$code .= "\n .')'";
|
||||||
|
$state->regex .= ')';
|
||||||
|
++$state->markTail;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
list($name, $regex, $vars, $route, $hasTrailingSlash, $hasTrailingVar) = $route;
|
||||||
|
$compiledRoute = $route->compile();
|
||||||
|
$vars = array_merge($state->hostVars, $vars);
|
||||||
|
|
||||||
|
if ($compiledRoute->getRegex() === $prevRegex) {
|
||||||
|
$state->routes[$state->mark][] = $this->compileRoute($route, $name, $vars, $hasTrailingSlash, $hasTrailingVar, $conditions);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$state->mark += 3 + $state->markTail + \strlen($regex) - $prefixLen;
|
||||||
|
$state->markTail = 2 + \strlen($state->mark);
|
||||||
|
$rx = sprintf('|%s(*:%s)', substr($regex, $prefixLen), $state->mark);
|
||||||
|
$code .= "\n .".self::export($rx);
|
||||||
|
$state->regex .= $rx;
|
||||||
|
|
||||||
|
$prevRegex = $compiledRoute->getRegex();
|
||||||
|
$state->routes[$state->mark] = [$this->compileRoute($route, $name, $vars, $hasTrailingSlash, $hasTrailingVar, $conditions)];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $code;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compiles a single Route to PHP code used to match it against the path info.
|
||||||
|
*/
|
||||||
|
private function compileRoute(Route $route, string $name, $vars, bool $hasTrailingSlash, bool $hasTrailingVar, array &$conditions): array
|
||||||
|
{
|
||||||
|
$defaults = $route->getDefaults();
|
||||||
|
|
||||||
|
if (isset($defaults['_canonical_route'])) {
|
||||||
|
$name = $defaults['_canonical_route'];
|
||||||
|
unset($defaults['_canonical_route']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($condition = $route->getCondition()) {
|
||||||
|
$condition = $this->getExpressionLanguage()->compile($condition, ['context', 'request']);
|
||||||
|
$condition = $conditions[$condition] ?? $conditions[$condition] = (false !== strpos($condition, '$request') ? 1 : -1) * \count($conditions);
|
||||||
|
} else {
|
||||||
|
$condition = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
['_route' => $name] + $defaults,
|
||||||
|
$vars,
|
||||||
|
array_flip($route->getMethods()) ?: null,
|
||||||
|
array_flip($route->getSchemes()) ?: null,
|
||||||
|
$hasTrailingSlash,
|
||||||
|
$hasTrailingVar,
|
||||||
|
$condition,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getExpressionLanguage()
|
||||||
|
{
|
||||||
|
if (null === $this->expressionLanguage) {
|
||||||
|
if (!class_exists('Symfony\Component\ExpressionLanguage\ExpressionLanguage')) {
|
||||||
|
throw new \LogicException('Unable to use expressions as the Symfony ExpressionLanguage component is not installed.');
|
||||||
|
}
|
||||||
|
$this->expressionLanguage = new ExpressionLanguage(null, $this->expressionLanguageProviders);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->expressionLanguage;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function indent($code, $level = 1)
|
||||||
|
{
|
||||||
|
return preg_replace('/^./m', str_repeat(' ', $level).'$0', $code);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
public static function export($value): string
|
||||||
|
{
|
||||||
|
if (null === $value) {
|
||||||
|
return 'null';
|
||||||
|
}
|
||||||
|
if (!\is_array($value)) {
|
||||||
|
if (\is_object($value)) {
|
||||||
|
throw new \InvalidArgumentException('Symfony\Component\Routing\Route cannot contain objects.');
|
||||||
|
}
|
||||||
|
|
||||||
|
return str_replace("\n", '\'."\n".\'', var_export($value, true));
|
||||||
|
}
|
||||||
|
if (!$value) {
|
||||||
|
return '[]';
|
||||||
|
}
|
||||||
|
|
||||||
|
$i = 0;
|
||||||
|
$export = '[';
|
||||||
|
|
||||||
|
foreach ($value as $k => $v) {
|
||||||
|
if ($i === $k) {
|
||||||
|
++$i;
|
||||||
|
} else {
|
||||||
|
$export .= self::export($k).' => ';
|
||||||
|
|
||||||
|
if (\is_int($k) && $i < $k) {
|
||||||
|
$i = 1 + $k;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$export .= self::export($v).', ';
|
||||||
|
}
|
||||||
|
|
||||||
|
return substr_replace($export, ']', -2);
|
||||||
|
}
|
||||||
|
}
|
@ -21,7 +21,7 @@ use Symfony\Component\Routing\Matcher\RedirectableUrlMatcherInterface;
|
|||||||
*
|
*
|
||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
trait PhpMatcherTrait
|
trait CompiledUrlMatcherTrait
|
||||||
{
|
{
|
||||||
private $matchHost = false;
|
private $matchHost = false;
|
||||||
private $staticRoutes = [];
|
private $staticRoutes = [];
|
||||||
@ -126,9 +126,14 @@ trait PhpMatcherTrait
|
|||||||
foreach ($this->regexpList as $offset => $regex) {
|
foreach ($this->regexpList as $offset => $regex) {
|
||||||
while (preg_match($regex, $matchedPathinfo, $matches)) {
|
while (preg_match($regex, $matchedPathinfo, $matches)) {
|
||||||
foreach ($this->dynamicRoutes[$m = (int) $matches['MARK']] as list($ret, $vars, $requiredMethods, $requiredSchemes, $hasTrailingSlash, $hasTrailingVar, $condition)) {
|
foreach ($this->dynamicRoutes[$m = (int) $matches['MARK']] as list($ret, $vars, $requiredMethods, $requiredSchemes, $hasTrailingSlash, $hasTrailingVar, $condition)) {
|
||||||
if ($condition && !($this->checkCondition)($condition, $context, 0 < $condition ? $request ?? $request = $this->request ?: $this->createRequest($pathinfo) : null)) {
|
if (null !== $condition) {
|
||||||
|
if (0 === $condition) { // marks the last route in the regexp
|
||||||
|
continue 3;
|
||||||
|
}
|
||||||
|
if (!($this->checkCondition)($condition, $context, 0 < $condition ? $request ?? $request = $this->request ?: $this->createRequest($pathinfo) : null)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ($trimmedPathinfo === $pathinfo || !$hasTrailingVar) {
|
if ($trimmedPathinfo === $pathinfo || !$hasTrailingVar) {
|
||||||
// no-op
|
// no-op
|
@ -11,10 +11,7 @@
|
|||||||
|
|
||||||
namespace Symfony\Component\Routing\Matcher\Dumper;
|
namespace Symfony\Component\Routing\Matcher\Dumper;
|
||||||
|
|
||||||
use Symfony\Component\ExpressionLanguage\ExpressionFunctionProviderInterface;
|
@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.2, use "CompiledUrlMatcherDumper" instead.', PhpMatcherDumper::class), E_USER_DEPRECATED);
|
||||||
use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
|
|
||||||
use Symfony\Component\Routing\Route;
|
|
||||||
use Symfony\Component\Routing\RouteCollection;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* PhpMatcherDumper creates a PHP class able to match URLs for a given set of routes.
|
* PhpMatcherDumper creates a PHP class able to match URLs for a given set of routes.
|
||||||
@ -23,17 +20,11 @@ use Symfony\Component\Routing\RouteCollection;
|
|||||||
* @author Tobias Schultze <http://tobion.de>
|
* @author Tobias Schultze <http://tobion.de>
|
||||||
* @author Arnaud Le Blanc <arnaud.lb@gmail.com>
|
* @author Arnaud Le Blanc <arnaud.lb@gmail.com>
|
||||||
* @author Nicolas Grekas <p@tchwork.com>
|
* @author Nicolas Grekas <p@tchwork.com>
|
||||||
|
*
|
||||||
|
* @deprecated since Symfony 4.2, use CompiledUrlMatcherDumper instead.
|
||||||
*/
|
*/
|
||||||
class PhpMatcherDumper extends MatcherDumper
|
class PhpMatcherDumper extends CompiledUrlMatcherDumper
|
||||||
{
|
{
|
||||||
private $expressionLanguage;
|
|
||||||
private $signalingException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var ExpressionFunctionProviderInterface[]
|
|
||||||
*/
|
|
||||||
private $expressionLanguageProviders = [];
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dumps a set of routes to a PHP class.
|
* Dumps a set of routes to a PHP class.
|
||||||
*
|
*
|
||||||
@ -53,13 +44,17 @@ class PhpMatcherDumper extends MatcherDumper
|
|||||||
'base_class' => 'Symfony\\Component\\Routing\\Matcher\\UrlMatcher',
|
'base_class' => 'Symfony\\Component\\Routing\\Matcher\\UrlMatcher',
|
||||||
], $options);
|
], $options);
|
||||||
|
|
||||||
// trailing slash support is only enabled if we know how to redirect the user
|
$code = parent::dump();
|
||||||
$interfaces = class_implements($options['base_class']);
|
$code = preg_replace('#\n ([^ ].*?) // \$(\w++)$#m', "\n \$this->$2 = $1", $code);
|
||||||
|
$code = str_replace(",\n $", ";\n $", $code);
|
||||||
|
$code = substr($code, strpos($code, '$this') - 4, -5).";\n";
|
||||||
|
$code = preg_replace('/^ \$this->\w++ = (?:null|false|\[\n \]);\n/m', '', $code);
|
||||||
|
$code = str_replace("\n ", "\n ", "\n".$code);
|
||||||
|
|
||||||
return <<<EOF
|
return <<<EOF
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
use Symfony\Component\Routing\Matcher\Dumper\PhpMatcherTrait;
|
use Symfony\Component\Routing\Matcher\Dumper\CompiledUrlMatcherTrait;
|
||||||
use Symfony\Component\Routing\RequestContext;
|
use Symfony\Component\Routing\RequestContext;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -68,424 +63,13 @@ use Symfony\Component\Routing\RequestContext;
|
|||||||
*/
|
*/
|
||||||
class {$options['class']} extends {$options['base_class']}
|
class {$options['class']} extends {$options['base_class']}
|
||||||
{
|
{
|
||||||
use PhpMatcherTrait;
|
use CompiledUrlMatcherTrait;
|
||||||
|
|
||||||
public function __construct(RequestContext \$context)
|
public function __construct(RequestContext \$context)
|
||||||
{
|
{
|
||||||
\$this->context = \$context;
|
\$this->context = \$context;{$code} }
|
||||||
{$this->generateProperties()} }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EOF;
|
EOF;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function addExpressionLanguageProvider(ExpressionFunctionProviderInterface $provider)
|
|
||||||
{
|
|
||||||
$this->expressionLanguageProviders[] = $provider;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generates the code for the match method implementing UrlMatcherInterface.
|
|
||||||
*/
|
|
||||||
private function generateProperties(): string
|
|
||||||
{
|
|
||||||
// Group hosts by same-suffix, re-order when possible
|
|
||||||
$matchHost = false;
|
|
||||||
$routes = new StaticPrefixCollection();
|
|
||||||
foreach ($this->getRoutes()->all() as $name => $route) {
|
|
||||||
if ($host = $route->getHost()) {
|
|
||||||
$matchHost = true;
|
|
||||||
$host = '/'.strtr(strrev($host), '}.{', '(/)');
|
|
||||||
}
|
|
||||||
|
|
||||||
$routes->addRoute($host ?: '/(.*)', [$name, $route]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($matchHost) {
|
|
||||||
$code = '$this->matchHost = true;'."\n";
|
|
||||||
$routes = $routes->populateCollection(new RouteCollection());
|
|
||||||
} else {
|
|
||||||
$code = '';
|
|
||||||
$routes = $this->getRoutes();
|
|
||||||
}
|
|
||||||
|
|
||||||
list($staticRoutes, $dynamicRoutes) = $this->groupStaticRoutes($routes);
|
|
||||||
|
|
||||||
$conditions = [null];
|
|
||||||
$code .= $this->compileStaticRoutes($staticRoutes, $conditions);
|
|
||||||
$chunkLimit = \count($dynamicRoutes);
|
|
||||||
|
|
||||||
while (true) {
|
|
||||||
try {
|
|
||||||
$this->signalingException = new \RuntimeException('preg_match(): Compilation failed: regular expression is too large');
|
|
||||||
$code .= $this->compileDynamicRoutes($dynamicRoutes, $matchHost, $chunkLimit, $conditions);
|
|
||||||
break;
|
|
||||||
} catch (\Exception $e) {
|
|
||||||
if (1 < $chunkLimit && $this->signalingException === $e) {
|
|
||||||
$chunkLimit = 1 + ($chunkLimit >> 1);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
throw $e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unset($conditions[0]);
|
|
||||||
|
|
||||||
if (!$conditions) {
|
|
||||||
return $this->indent($code, 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($conditions as $expression => $condition) {
|
|
||||||
$conditions[$expression] = "case {$condition}: return {$expression};";
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->indent($code, 2).<<<EOF
|
|
||||||
\$this->checkCondition = static function (\$condition, \$context, \$request) {
|
|
||||||
switch (\$condition) {
|
|
||||||
{$this->indent(implode("\n", $conditions), 4)}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
EOF;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Splits static routes from dynamic routes, so that they can be matched first, using a simple switch.
|
|
||||||
*/
|
|
||||||
private function groupStaticRoutes(RouteCollection $collection): array
|
|
||||||
{
|
|
||||||
$staticRoutes = $dynamicRegex = [];
|
|
||||||
$dynamicRoutes = new RouteCollection();
|
|
||||||
|
|
||||||
foreach ($collection->all() as $name => $route) {
|
|
||||||
$compiledRoute = $route->compile();
|
|
||||||
$hostRegex = $compiledRoute->getHostRegex();
|
|
||||||
$regex = $compiledRoute->getRegex();
|
|
||||||
if ($hasTrailingSlash = '/' !== $route->getPath()) {
|
|
||||||
$pos = strrpos($regex, '$');
|
|
||||||
$hasTrailingSlash = '/' === $regex[$pos - 1];
|
|
||||||
$regex = substr_replace($regex, '/?$', $pos - $hasTrailingSlash, 1 + $hasTrailingSlash);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!$compiledRoute->getPathVariables()) {
|
|
||||||
$host = !$compiledRoute->getHostVariables() ? $route->getHost() : '';
|
|
||||||
$url = $route->getPath();
|
|
||||||
if ($hasTrailingSlash) {
|
|
||||||
$url = substr($url, 0, -1);
|
|
||||||
}
|
|
||||||
foreach ($dynamicRegex as list($hostRx, $rx)) {
|
|
||||||
if (preg_match($rx, $url) && (!$host || !$hostRx || preg_match($hostRx, $host))) {
|
|
||||||
$dynamicRegex[] = [$hostRegex, $regex];
|
|
||||||
$dynamicRoutes->add($name, $route);
|
|
||||||
continue 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$staticRoutes[$url][$name] = [$route, $hasTrailingSlash];
|
|
||||||
} else {
|
|
||||||
$dynamicRegex[] = [$hostRegex, $regex];
|
|
||||||
$dynamicRoutes->add($name, $route);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return [$staticRoutes, $dynamicRoutes];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Compiles static routes in a switch statement.
|
|
||||||
*
|
|
||||||
* Condition-less paths are put in a static array in the switch's default, with generic matching logic.
|
|
||||||
* Paths that can match two or more routes, or have user-specified conditions are put in separate switch's cases.
|
|
||||||
*
|
|
||||||
* @throws \LogicException
|
|
||||||
*/
|
|
||||||
private function compileStaticRoutes(array $staticRoutes, array &$conditions): string
|
|
||||||
{
|
|
||||||
if (!$staticRoutes) {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
$code = '';
|
|
||||||
|
|
||||||
foreach ($staticRoutes as $url => $routes) {
|
|
||||||
$code .= self::export($url)." => [\n";
|
|
||||||
foreach ($routes as $name => list($route, $hasTrailingSlash)) {
|
|
||||||
$code .= $this->compileRoute($route, $name, !$route->compile()->getHostVariables() ? $route->getHost() : $route->compile()->getHostRegex() ?: null, $hasTrailingSlash, false, $conditions);
|
|
||||||
}
|
|
||||||
$code .= "],\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($code) {
|
|
||||||
return "\$this->staticRoutes = [\n{$this->indent($code, 1)}];\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
return $code;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Compiles a regular expression followed by a switch statement to match dynamic routes.
|
|
||||||
*
|
|
||||||
* The regular expression matches both the host and the pathinfo at the same time. For stellar performance,
|
|
||||||
* it is built as a tree of patterns, with re-ordering logic to group same-prefix routes together when possible.
|
|
||||||
*
|
|
||||||
* Patterns are named so that we know which one matched (https://pcre.org/current/doc/html/pcre2syntax.html#SEC23).
|
|
||||||
* This name is used to "switch" to the additional logic required to match the final route.
|
|
||||||
*
|
|
||||||
* Condition-less paths are put in a static array in the switch's default, with generic matching logic.
|
|
||||||
* Paths that can match two or more routes, or have user-specified conditions are put in separate switch's cases.
|
|
||||||
*
|
|
||||||
* Last but not least:
|
|
||||||
* - Because it is not possibe to mix unicode/non-unicode patterns in a single regexp, several of them can be generated.
|
|
||||||
* - The same regexp can be used several times when the logic in the switch rejects the match. When this happens, the
|
|
||||||
* matching-but-failing subpattern is blacklisted by replacing its name by "(*F)", which forces a failure-to-match.
|
|
||||||
* To ease this backlisting operation, the name of subpatterns is also the string offset where the replacement should occur.
|
|
||||||
*/
|
|
||||||
private function compileDynamicRoutes(RouteCollection $collection, bool $matchHost, int $chunkLimit, array &$conditions): string
|
|
||||||
{
|
|
||||||
if (!$collection->all()) {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
$code = '';
|
|
||||||
$state = (object) [
|
|
||||||
'regex' => '',
|
|
||||||
'routes' => '',
|
|
||||||
'mark' => 0,
|
|
||||||
'markTail' => 0,
|
|
||||||
'hostVars' => [],
|
|
||||||
'vars' => [],
|
|
||||||
];
|
|
||||||
$state->getVars = static function ($m) use ($state) {
|
|
||||||
if ('_route' === $m[1]) {
|
|
||||||
return '?:';
|
|
||||||
}
|
|
||||||
|
|
||||||
$state->vars[] = $m[1];
|
|
||||||
|
|
||||||
return '';
|
|
||||||
};
|
|
||||||
|
|
||||||
$chunkSize = 0;
|
|
||||||
$prev = null;
|
|
||||||
$perModifiers = [];
|
|
||||||
foreach ($collection->all() as $name => $route) {
|
|
||||||
preg_match('#[a-zA-Z]*$#', $route->compile()->getRegex(), $rx);
|
|
||||||
if ($chunkLimit < ++$chunkSize || $prev !== $rx[0] && $route->compile()->getPathVariables()) {
|
|
||||||
$chunkSize = 1;
|
|
||||||
$routes = new RouteCollection();
|
|
||||||
$perModifiers[] = [$rx[0], $routes];
|
|
||||||
$prev = $rx[0];
|
|
||||||
}
|
|
||||||
$routes->add($name, $route);
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($perModifiers as list($modifiers, $routes)) {
|
|
||||||
$prev = false;
|
|
||||||
$perHost = [];
|
|
||||||
foreach ($routes->all() as $name => $route) {
|
|
||||||
$regex = $route->compile()->getHostRegex();
|
|
||||||
if ($prev !== $regex) {
|
|
||||||
$routes = new RouteCollection();
|
|
||||||
$perHost[] = [$regex, $routes];
|
|
||||||
$prev = $regex;
|
|
||||||
}
|
|
||||||
$routes->add($name, $route);
|
|
||||||
}
|
|
||||||
$prev = false;
|
|
||||||
$rx = '{^(?';
|
|
||||||
$code .= "\n {$state->mark} => ".self::export($rx);
|
|
||||||
$state->mark += \strlen($rx);
|
|
||||||
$state->regex = $rx;
|
|
||||||
|
|
||||||
foreach ($perHost as list($hostRegex, $routes)) {
|
|
||||||
if ($matchHost) {
|
|
||||||
if ($hostRegex) {
|
|
||||||
preg_match('#^.\^(.*)\$.[a-zA-Z]*$#', $hostRegex, $rx);
|
|
||||||
$state->vars = [];
|
|
||||||
$hostRegex = '(?i:'.preg_replace_callback('#\?P<([^>]++)>#', $state->getVars, $rx[1]).')\.';
|
|
||||||
$state->hostVars = $state->vars;
|
|
||||||
} else {
|
|
||||||
$hostRegex = '(?:(?:[^./]*+\.)++)';
|
|
||||||
$state->hostVars = [];
|
|
||||||
}
|
|
||||||
$state->mark += \strlen($rx = ($prev ? ')' : '')."|{$hostRegex}(?");
|
|
||||||
$code .= "\n .".self::export($rx);
|
|
||||||
$state->regex .= $rx;
|
|
||||||
$prev = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
$tree = new StaticPrefixCollection();
|
|
||||||
foreach ($routes->all() as $name => $route) {
|
|
||||||
preg_match('#^.\^(.*)\$.[a-zA-Z]*$#', $route->compile()->getRegex(), $rx);
|
|
||||||
|
|
||||||
$state->vars = [];
|
|
||||||
$regex = preg_replace_callback('#\?P<([^>]++)>#', $state->getVars, $rx[1]);
|
|
||||||
if ($hasTrailingSlash = '/' !== $regex && '/' === $regex[-1]) {
|
|
||||||
$regex = substr($regex, 0, -1);
|
|
||||||
}
|
|
||||||
$hasTrailingVar = (bool) preg_match('#\{\w+\}/?$#', $route->getPath());
|
|
||||||
|
|
||||||
$tree->addRoute($regex, [$name, $regex, $state->vars, $route, $hasTrailingSlash, $hasTrailingVar]);
|
|
||||||
}
|
|
||||||
|
|
||||||
$code .= $this->compileStaticPrefixCollection($tree, $state, 0, $conditions);
|
|
||||||
}
|
|
||||||
if ($matchHost) {
|
|
||||||
$code .= "\n .')'";
|
|
||||||
$state->regex .= ')';
|
|
||||||
}
|
|
||||||
$rx = ")/?$}{$modifiers}";
|
|
||||||
$code .= "\n .'{$rx}',";
|
|
||||||
$state->regex .= $rx;
|
|
||||||
$state->markTail = 0;
|
|
||||||
|
|
||||||
// if the regex is too large, throw a signaling exception to recompute with smaller chunk size
|
|
||||||
set_error_handler(function ($type, $message) { throw 0 === strpos($message, $this->signalingException->getMessage()) ? $this->signalingException : new \ErrorException($message); });
|
|
||||||
try {
|
|
||||||
preg_match($state->regex, '');
|
|
||||||
} finally {
|
|
||||||
restore_error_handler();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unset($state->getVars);
|
|
||||||
|
|
||||||
return "\$this->regexpList = [{$code}\n];\n"
|
|
||||||
."\$this->dynamicRoutes = [\n{$this->indent($state->routes, 1)}];\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Compiles a regexp tree of subpatterns that matches nested same-prefix routes.
|
|
||||||
*
|
|
||||||
* @param \stdClass $state A simple state object that keeps track of the progress of the compilation,
|
|
||||||
* and gathers the generated switch's "case" and "default" statements
|
|
||||||
*/
|
|
||||||
private function compileStaticPrefixCollection(StaticPrefixCollection $tree, \stdClass $state, int $prefixLen, array &$conditions): string
|
|
||||||
{
|
|
||||||
$code = '';
|
|
||||||
$prevRegex = null;
|
|
||||||
$routes = $tree->getRoutes();
|
|
||||||
|
|
||||||
foreach ($routes as $i => $route) {
|
|
||||||
if ($route instanceof StaticPrefixCollection) {
|
|
||||||
$prevRegex = null;
|
|
||||||
$prefix = substr($route->getPrefix(), $prefixLen);
|
|
||||||
$state->mark += \strlen($rx = "|{$prefix}(?");
|
|
||||||
$code .= "\n .".self::export($rx);
|
|
||||||
$state->regex .= $rx;
|
|
||||||
$code .= $this->indent($this->compileStaticPrefixCollection($route, $state, $prefixLen + \strlen($prefix), $conditions));
|
|
||||||
$code .= "\n .')'";
|
|
||||||
$state->regex .= ')';
|
|
||||||
++$state->markTail;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
list($name, $regex, $vars, $route, $hasTrailingSlash, $hasTrailingVar) = $route;
|
|
||||||
$compiledRoute = $route->compile();
|
|
||||||
$vars = array_merge($state->hostVars, $vars);
|
|
||||||
|
|
||||||
if ($compiledRoute->getRegex() === $prevRegex) {
|
|
||||||
$state->routes = substr_replace($state->routes, $this->compileRoute($route, $name, $vars, $hasTrailingSlash, $hasTrailingVar, $conditions), -3, 0);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
$state->mark += 3 + $state->markTail + \strlen($regex) - $prefixLen;
|
|
||||||
$state->markTail = 2 + \strlen($state->mark);
|
|
||||||
$rx = sprintf('|%s(*:%s)', substr($regex, $prefixLen), $state->mark);
|
|
||||||
$code .= "\n .".self::export($rx);
|
|
||||||
$state->regex .= $rx;
|
|
||||||
|
|
||||||
$prevRegex = $compiledRoute->getRegex();
|
|
||||||
$state->routes .= sprintf("%s => [\n%s],\n", $state->mark, $this->compileRoute($route, $name, $vars, $hasTrailingSlash, $hasTrailingVar, $conditions));
|
|
||||||
}
|
|
||||||
|
|
||||||
return $code;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Compiles a single Route to PHP code used to match it against the path info.
|
|
||||||
*/
|
|
||||||
private function compileRoute(Route $route, string $name, $vars, bool $hasTrailingSlash, bool $hasTrailingVar, array &$conditions): string
|
|
||||||
{
|
|
||||||
$defaults = $route->getDefaults();
|
|
||||||
|
|
||||||
if (isset($defaults['_canonical_route'])) {
|
|
||||||
$name = $defaults['_canonical_route'];
|
|
||||||
unset($defaults['_canonical_route']);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($condition = $route->getCondition()) {
|
|
||||||
$condition = $this->getExpressionLanguage()->compile($condition, ['context', 'request']);
|
|
||||||
$condition = $conditions[$condition] ?? $conditions[$condition] = (false !== strpos($condition, '$request') ? 1 : -1) * \count($conditions);
|
|
||||||
} else {
|
|
||||||
$condition = 'null';
|
|
||||||
}
|
|
||||||
|
|
||||||
return sprintf(
|
|
||||||
" [%s, %s, %s, %s, %s, %s, %s],\n",
|
|
||||||
self::export(['_route' => $name] + $defaults),
|
|
||||||
self::export($vars),
|
|
||||||
self::export(array_flip($route->getMethods()) ?: null),
|
|
||||||
self::export(array_flip($route->getSchemes()) ?: null),
|
|
||||||
self::export($hasTrailingSlash),
|
|
||||||
self::export($hasTrailingVar),
|
|
||||||
$condition
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private function getExpressionLanguage()
|
|
||||||
{
|
|
||||||
if (null === $this->expressionLanguage) {
|
|
||||||
if (!class_exists('Symfony\Component\ExpressionLanguage\ExpressionLanguage')) {
|
|
||||||
throw new \LogicException('Unable to use expressions as the Symfony ExpressionLanguage component is not installed.');
|
|
||||||
}
|
|
||||||
$this->expressionLanguage = new ExpressionLanguage(null, $this->expressionLanguageProviders);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->expressionLanguage;
|
|
||||||
}
|
|
||||||
|
|
||||||
private function indent($code, $level = 1)
|
|
||||||
{
|
|
||||||
$code = preg_replace('/ => \[\n (\[.+),\n\],/', ' => [$1],', $code);
|
|
||||||
|
|
||||||
return preg_replace('/^./m', str_repeat(' ', $level).'$0', $code);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
public static function export($value): string
|
|
||||||
{
|
|
||||||
if (null === $value) {
|
|
||||||
return 'null';
|
|
||||||
}
|
|
||||||
if (!\is_array($value)) {
|
|
||||||
if (\is_object($value)) {
|
|
||||||
throw new \InvalidArgumentException('Symfony\Component\Routing\Route cannot contain objects.');
|
|
||||||
}
|
|
||||||
|
|
||||||
return str_replace("\n", '\'."\n".\'', var_export($value, true));
|
|
||||||
}
|
|
||||||
if (!$value) {
|
|
||||||
return '[]';
|
|
||||||
}
|
|
||||||
|
|
||||||
$i = 0;
|
|
||||||
$export = '[';
|
|
||||||
|
|
||||||
foreach ($value as $k => $v) {
|
|
||||||
if ($i === $k) {
|
|
||||||
++$i;
|
|
||||||
} else {
|
|
||||||
$export .= self::export($k).' => ';
|
|
||||||
|
|
||||||
if (\is_int($k) && $i < $k) {
|
|
||||||
$i = 1 + $k;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$export .= self::export($v).', ';
|
|
||||||
}
|
|
||||||
|
|
||||||
return substr_replace($export, ']', -2);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -18,11 +18,17 @@ use Symfony\Component\Config\ConfigCacheInterface;
|
|||||||
use Symfony\Component\Config\Loader\LoaderInterface;
|
use Symfony\Component\Config\Loader\LoaderInterface;
|
||||||
use Symfony\Component\ExpressionLanguage\ExpressionFunctionProviderInterface;
|
use Symfony\Component\ExpressionLanguage\ExpressionFunctionProviderInterface;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
|
use Symfony\Component\Routing\Generator\CompiledUrlGenerator;
|
||||||
use Symfony\Component\Routing\Generator\ConfigurableRequirementsInterface;
|
use Symfony\Component\Routing\Generator\ConfigurableRequirementsInterface;
|
||||||
|
use Symfony\Component\Routing\Generator\Dumper\CompiledUrlGeneratorDumper;
|
||||||
use Symfony\Component\Routing\Generator\Dumper\GeneratorDumperInterface;
|
use Symfony\Component\Routing\Generator\Dumper\GeneratorDumperInterface;
|
||||||
|
use Symfony\Component\Routing\Generator\UrlGenerator;
|
||||||
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
|
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
|
||||||
|
use Symfony\Component\Routing\Matcher\CompiledUrlMatcher;
|
||||||
|
use Symfony\Component\Routing\Matcher\Dumper\CompiledUrlMatcherDumper;
|
||||||
use Symfony\Component\Routing\Matcher\Dumper\MatcherDumperInterface;
|
use Symfony\Component\Routing\Matcher\Dumper\MatcherDumperInterface;
|
||||||
use Symfony\Component\Routing\Matcher\RequestMatcherInterface;
|
use Symfony\Component\Routing\Matcher\RequestMatcherInterface;
|
||||||
|
use Symfony\Component\Routing\Matcher\UrlMatcher;
|
||||||
use Symfony\Component\Routing\Matcher\UrlMatcherInterface;
|
use Symfony\Component\Routing\Matcher\UrlMatcherInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -127,14 +133,14 @@ class Router implements RouterInterface, RequestMatcherInterface
|
|||||||
$this->options = [
|
$this->options = [
|
||||||
'cache_dir' => null,
|
'cache_dir' => null,
|
||||||
'debug' => false,
|
'debug' => false,
|
||||||
'generator_class' => 'Symfony\\Component\\Routing\\Generator\\UrlGenerator',
|
'generator_class' => CompiledUrlGenerator::class,
|
||||||
'generator_base_class' => 'Symfony\\Component\\Routing\\Generator\\UrlGenerator',
|
'generator_base_class' => UrlGenerator::class,
|
||||||
'generator_dumper_class' => 'Symfony\\Component\\Routing\\Generator\\Dumper\\PhpGeneratorDumper',
|
'generator_dumper_class' => CompiledUrlGeneratorDumper::class,
|
||||||
'generator_cache_class' => 'ProjectUrlGenerator',
|
'generator_cache_class' => 'UrlGenerator',
|
||||||
'matcher_class' => 'Symfony\\Component\\Routing\\Matcher\\UrlMatcher',
|
'matcher_class' => CompiledUrlMatcher::class,
|
||||||
'matcher_base_class' => 'Symfony\\Component\\Routing\\Matcher\\UrlMatcher',
|
'matcher_base_class' => UrlMatcher::class,
|
||||||
'matcher_dumper_class' => 'Symfony\\Component\\Routing\\Matcher\\Dumper\\PhpMatcherDumper',
|
'matcher_dumper_class' => CompiledUrlMatcherDumper::class,
|
||||||
'matcher_cache_class' => 'ProjectUrlMatcher',
|
'matcher_cache_class' => 'UrlMatcher',
|
||||||
'resource_type' => null,
|
'resource_type' => null,
|
||||||
'strict_requirements' => true,
|
'strict_requirements' => true,
|
||||||
];
|
];
|
||||||
@ -273,8 +279,14 @@ class Router implements RouterInterface, RequestMatcherInterface
|
|||||||
return $this->matcher;
|
return $this->matcher;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$compiled = is_a($this->options['matcher_class'], CompiledUrlMatcher::class, true);
|
||||||
|
|
||||||
if (null === $this->options['cache_dir'] || null === $this->options['matcher_cache_class']) {
|
if (null === $this->options['cache_dir'] || null === $this->options['matcher_cache_class']) {
|
||||||
$this->matcher = new $this->options['matcher_class']($this->getRouteCollection(), $this->context);
|
$routes = $this->getRouteCollection();
|
||||||
|
if ($compiled) {
|
||||||
|
$routes = (new CompiledUrlMatcherDumper($routes))->getCompiledRoutes();
|
||||||
|
}
|
||||||
|
$this->matcher = new $this->options['matcher_class']($routes, $this->context);
|
||||||
if (method_exists($this->matcher, 'addExpressionLanguageProvider')) {
|
if (method_exists($this->matcher, 'addExpressionLanguageProvider')) {
|
||||||
foreach ($this->expressionLanguageProviders as $provider) {
|
foreach ($this->expressionLanguageProviders as $provider) {
|
||||||
$this->matcher->addExpressionLanguageProvider($provider);
|
$this->matcher->addExpressionLanguageProvider($provider);
|
||||||
@ -302,6 +314,10 @@ class Router implements RouterInterface, RequestMatcherInterface
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if ($compiled) {
|
||||||
|
return $this->matcher = new $this->options['matcher_class'](require $cache->getPath(), $this->context);
|
||||||
|
}
|
||||||
|
|
||||||
if (!class_exists($this->options['matcher_cache_class'], false)) {
|
if (!class_exists($this->options['matcher_cache_class'], false)) {
|
||||||
require_once $cache->getPath();
|
require_once $cache->getPath();
|
||||||
}
|
}
|
||||||
@ -320,8 +336,14 @@ class Router implements RouterInterface, RequestMatcherInterface
|
|||||||
return $this->generator;
|
return $this->generator;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$compiled = is_a($this->options['generator_class'], CompiledUrlGenerator::class, true);
|
||||||
|
|
||||||
if (null === $this->options['cache_dir'] || null === $this->options['generator_cache_class']) {
|
if (null === $this->options['cache_dir'] || null === $this->options['generator_cache_class']) {
|
||||||
$this->generator = new $this->options['generator_class']($this->getRouteCollection(), $this->context, $this->logger);
|
$routes = $this->getRouteCollection();
|
||||||
|
if ($compiled) {
|
||||||
|
$routes = (new CompiledUrlGeneratorDumper($routes))->getCompiledRoutes();
|
||||||
|
}
|
||||||
|
$this->generator = new $this->options['generator_class']($routes, $this->context, $this->logger);
|
||||||
} else {
|
} else {
|
||||||
$cache = $this->getConfigCacheFactory()->cache($this->options['cache_dir'].'/'.$this->options['generator_cache_class'].'.php',
|
$cache = $this->getConfigCacheFactory()->cache($this->options['cache_dir'].'/'.$this->options['generator_cache_class'].'.php',
|
||||||
function (ConfigCacheInterface $cache) {
|
function (ConfigCacheInterface $cache) {
|
||||||
@ -336,12 +358,16 @@ class Router implements RouterInterface, RequestMatcherInterface
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if ($compiled) {
|
||||||
|
$this->generator = new $this->options['generator_class'](require $cache->getPath(), $this->context, $this->logger);
|
||||||
|
} else {
|
||||||
if (!class_exists($this->options['generator_cache_class'], false)) {
|
if (!class_exists($this->options['generator_cache_class'], false)) {
|
||||||
require_once $cache->getPath();
|
require_once $cache->getPath();
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->generator = new $this->options['generator_cache_class']($this->context, $this->logger);
|
$this->generator = new $this->options['generator_cache_class']($this->context, $this->logger);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ($this->generator instanceof ConfigurableRequirementsInterface) {
|
if ($this->generator instanceof ConfigurableRequirementsInterface) {
|
||||||
$this->generator->setStrictRequirements($this->options['strict_requirements']);
|
$this->generator->setStrictRequirements($this->options['strict_requirements']);
|
||||||
|
@ -0,0 +1,17 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This file has been auto-generated
|
||||||
|
* by the Symfony Routing Component.
|
||||||
|
*/
|
||||||
|
|
||||||
|
return [
|
||||||
|
false, // $matchHost
|
||||||
|
[ // $staticRoutes
|
||||||
|
],
|
||||||
|
[ // $regexpList
|
||||||
|
],
|
||||||
|
[ // $dynamicRoutes
|
||||||
|
],
|
||||||
|
null, // $checkCondition
|
||||||
|
];
|
@ -0,0 +1,108 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This file has been auto-generated
|
||||||
|
* by the Symfony Routing Component.
|
||||||
|
*/
|
||||||
|
|
||||||
|
return [
|
||||||
|
true, // $matchHost
|
||||||
|
[ // $staticRoutes
|
||||||
|
'/test/baz' => [[['_route' => 'baz'], null, null, null, false, false, null]],
|
||||||
|
'/test/baz.html' => [[['_route' => 'baz2'], null, null, null, false, false, null]],
|
||||||
|
'/test/baz3' => [[['_route' => 'baz3'], null, null, null, true, false, null]],
|
||||||
|
'/foofoo' => [[['_route' => 'foofoo', 'def' => 'test'], null, null, null, false, false, null]],
|
||||||
|
'/spa ce' => [[['_route' => 'space'], null, null, null, false, false, null]],
|
||||||
|
'/multi/new' => [[['_route' => 'overridden2'], null, null, null, false, false, null]],
|
||||||
|
'/multi/hey' => [[['_route' => 'hey'], null, null, null, true, false, null]],
|
||||||
|
'/ababa' => [[['_route' => 'ababa'], null, null, null, false, false, null]],
|
||||||
|
'/route1' => [[['_route' => 'route1'], 'a.example.com', null, null, false, false, null]],
|
||||||
|
'/c2/route2' => [[['_route' => 'route2'], 'a.example.com', null, null, false, false, null]],
|
||||||
|
'/route4' => [[['_route' => 'route4'], 'a.example.com', null, null, false, false, null]],
|
||||||
|
'/c2/route3' => [[['_route' => 'route3'], 'b.example.com', null, null, false, false, null]],
|
||||||
|
'/route5' => [[['_route' => 'route5'], 'c.example.com', null, null, false, false, null]],
|
||||||
|
'/route6' => [[['_route' => 'route6'], null, null, null, false, false, null]],
|
||||||
|
'/route11' => [[['_route' => 'route11'], '#^(?P<var1>[^\\.]++)\\.example\\.com$#sDi', null, null, false, false, null]],
|
||||||
|
'/route12' => [[['_route' => 'route12', 'var1' => 'val'], '#^(?P<var1>[^\\.]++)\\.example\\.com$#sDi', null, null, false, false, null]],
|
||||||
|
'/route17' => [[['_route' => 'route17'], null, null, null, false, false, null]],
|
||||||
|
],
|
||||||
|
[ // $regexpList
|
||||||
|
0 => '{^(?'
|
||||||
|
.'|(?:(?:[^./]*+\\.)++)(?'
|
||||||
|
.'|/foo/(baz|symfony)(*:47)'
|
||||||
|
.'|/bar(?'
|
||||||
|
.'|/([^/]++)(*:70)'
|
||||||
|
.'|head/([^/]++)(*:90)'
|
||||||
|
.')'
|
||||||
|
.'|/test/([^/]++)(?'
|
||||||
|
.'|(*:115)'
|
||||||
|
.')'
|
||||||
|
.'|/([\']+)(*:131)'
|
||||||
|
.'|/a/(?'
|
||||||
|
.'|b\'b/([^/]++)(?'
|
||||||
|
.'|(*:160)'
|
||||||
|
.'|(*:168)'
|
||||||
|
.')'
|
||||||
|
.'|(.*)(*:181)'
|
||||||
|
.'|b\'b/([^/]++)(?'
|
||||||
|
.'|(*:204)'
|
||||||
|
.'|(*:212)'
|
||||||
|
.')'
|
||||||
|
.')'
|
||||||
|
.'|/multi/hello(?:/([^/]++))?(*:248)'
|
||||||
|
.'|/([^/]++)/b/([^/]++)(?'
|
||||||
|
.'|(*:279)'
|
||||||
|
.'|(*:287)'
|
||||||
|
.')'
|
||||||
|
.'|/aba/([^/]++)(*:309)'
|
||||||
|
.')|(?i:([^\\.]++)\\.example\\.com)\\.(?'
|
||||||
|
.'|/route1(?'
|
||||||
|
.'|3/([^/]++)(*:371)'
|
||||||
|
.'|4/([^/]++)(*:389)'
|
||||||
|
.')'
|
||||||
|
.')|(?i:c\\.example\\.com)\\.(?'
|
||||||
|
.'|/route15/([^/]++)(*:441)'
|
||||||
|
.')|(?:(?:[^./]*+\\.)++)(?'
|
||||||
|
.'|/route16/([^/]++)(*:489)'
|
||||||
|
.'|/a/(?'
|
||||||
|
.'|a\\.\\.\\.(*:510)'
|
||||||
|
.'|b/(?'
|
||||||
|
.'|([^/]++)(*:531)'
|
||||||
|
.'|c/([^/]++)(*:549)'
|
||||||
|
.')'
|
||||||
|
.')'
|
||||||
|
.')'
|
||||||
|
.')/?$}sD',
|
||||||
|
],
|
||||||
|
[ // $dynamicRoutes
|
||||||
|
47 => [[['_route' => 'foo', 'def' => 'test'], ['bar'], null, null, false, true, null]],
|
||||||
|
70 => [[['_route' => 'bar'], ['foo'], ['GET' => 0, 'HEAD' => 1], null, false, true, null]],
|
||||||
|
90 => [[['_route' => 'barhead'], ['foo'], ['GET' => 0], null, false, true, null]],
|
||||||
|
115 => [
|
||||||
|
[['_route' => 'baz4'], ['foo'], null, null, true, true, null],
|
||||||
|
[['_route' => 'baz5'], ['foo'], ['POST' => 0], null, true, true, null],
|
||||||
|
[['_route' => 'baz.baz6'], ['foo'], ['PUT' => 0], null, true, true, null],
|
||||||
|
],
|
||||||
|
131 => [[['_route' => 'quoter'], ['quoter'], null, null, false, true, null]],
|
||||||
|
160 => [[['_route' => 'foo1'], ['foo'], ['PUT' => 0], null, false, true, null]],
|
||||||
|
168 => [[['_route' => 'bar1'], ['bar'], null, null, false, true, null]],
|
||||||
|
181 => [[['_route' => 'overridden'], ['var'], null, null, false, true, null]],
|
||||||
|
204 => [[['_route' => 'foo2'], ['foo1'], null, null, false, true, null]],
|
||||||
|
212 => [[['_route' => 'bar2'], ['bar1'], null, null, false, true, null]],
|
||||||
|
248 => [[['_route' => 'helloWorld', 'who' => 'World!'], ['who'], null, null, false, true, null]],
|
||||||
|
279 => [[['_route' => 'foo3'], ['_locale', 'foo'], null, null, false, true, null]],
|
||||||
|
287 => [[['_route' => 'bar3'], ['_locale', 'bar'], null, null, false, true, null]],
|
||||||
|
309 => [[['_route' => 'foo4'], ['foo'], null, null, false, true, null]],
|
||||||
|
371 => [[['_route' => 'route13'], ['var1', 'name'], null, null, false, true, null]],
|
||||||
|
389 => [[['_route' => 'route14', 'var1' => 'val'], ['var1', 'name'], null, null, false, true, null]],
|
||||||
|
441 => [[['_route' => 'route15'], ['name'], null, null, false, true, null]],
|
||||||
|
489 => [[['_route' => 'route16', 'var1' => 'val'], ['name'], null, null, false, true, null]],
|
||||||
|
510 => [[['_route' => 'a'], [], null, null, false, false, null]],
|
||||||
|
531 => [[['_route' => 'b'], ['var'], null, null, false, true, null]],
|
||||||
|
549 => [
|
||||||
|
[['_route' => 'c'], ['var'], null, null, false, true, null],
|
||||||
|
[null, null, null, null, false, false, 0],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
null, // $checkCondition
|
||||||
|
];
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,64 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This file has been auto-generated
|
||||||
|
* by the Symfony Routing Component.
|
||||||
|
*/
|
||||||
|
|
||||||
|
return [
|
||||||
|
false, // $matchHost
|
||||||
|
[ // $staticRoutes
|
||||||
|
],
|
||||||
|
[ // $regexpList
|
||||||
|
0 => '{^(?'
|
||||||
|
.'|/(en|fr)/(?'
|
||||||
|
.'|admin/post(?'
|
||||||
|
.'|(*:32)'
|
||||||
|
.'|/(?'
|
||||||
|
.'|new(*:46)'
|
||||||
|
.'|(\\d+)(*:58)'
|
||||||
|
.'|(\\d+)/edit(*:75)'
|
||||||
|
.'|(\\d+)/delete(*:94)'
|
||||||
|
.')'
|
||||||
|
.')'
|
||||||
|
.'|blog(?'
|
||||||
|
.'|(*:110)'
|
||||||
|
.'|/(?'
|
||||||
|
.'|rss\\.xml(*:130)'
|
||||||
|
.'|p(?'
|
||||||
|
.'|age/([^/]++)(*:154)'
|
||||||
|
.'|osts/([^/]++)(*:175)'
|
||||||
|
.')'
|
||||||
|
.'|comments/(\\d+)/new(*:202)'
|
||||||
|
.'|search(*:216)'
|
||||||
|
.')'
|
||||||
|
.')'
|
||||||
|
.'|log(?'
|
||||||
|
.'|in(*:234)'
|
||||||
|
.'|out(*:245)'
|
||||||
|
.')'
|
||||||
|
.')'
|
||||||
|
.'|/(en|fr)?(*:264)'
|
||||||
|
.')/?$}sD',
|
||||||
|
],
|
||||||
|
[ // $dynamicRoutes
|
||||||
|
32 => [[['_route' => 'a', '_locale' => 'en'], ['_locale'], null, null, true, false, null]],
|
||||||
|
46 => [[['_route' => 'b', '_locale' => 'en'], ['_locale'], null, null, false, false, null]],
|
||||||
|
58 => [[['_route' => 'c', '_locale' => 'en'], ['_locale', 'id'], null, null, false, true, null]],
|
||||||
|
75 => [[['_route' => 'd', '_locale' => 'en'], ['_locale', 'id'], null, null, false, false, null]],
|
||||||
|
94 => [[['_route' => 'e', '_locale' => 'en'], ['_locale', 'id'], null, null, false, false, null]],
|
||||||
|
110 => [[['_route' => 'f', '_locale' => 'en'], ['_locale'], null, null, true, false, null]],
|
||||||
|
130 => [[['_route' => 'g', '_locale' => 'en'], ['_locale'], null, null, false, false, null]],
|
||||||
|
154 => [[['_route' => 'h', '_locale' => 'en'], ['_locale', 'page'], null, null, false, true, null]],
|
||||||
|
175 => [[['_route' => 'i', '_locale' => 'en'], ['_locale', 'page'], null, null, false, true, null]],
|
||||||
|
202 => [[['_route' => 'j', '_locale' => 'en'], ['_locale', 'id'], null, null, false, false, null]],
|
||||||
|
216 => [[['_route' => 'k', '_locale' => 'en'], ['_locale'], null, null, false, false, null]],
|
||||||
|
234 => [[['_route' => 'l', '_locale' => 'en'], ['_locale'], null, null, false, false, null]],
|
||||||
|
245 => [[['_route' => 'm', '_locale' => 'en'], ['_locale'], null, null, false, false, null]],
|
||||||
|
264 => [
|
||||||
|
[['_route' => 'n', '_locale' => 'en'], ['_locale'], null, null, false, true, null],
|
||||||
|
[null, null, null, null, false, false, 0],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
null, // $checkCondition
|
||||||
|
];
|
@ -0,0 +1,44 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This file has been auto-generated
|
||||||
|
* by the Symfony Routing Component.
|
||||||
|
*/
|
||||||
|
|
||||||
|
return [
|
||||||
|
false, // $matchHost
|
||||||
|
[ // $staticRoutes
|
||||||
|
],
|
||||||
|
[ // $regexpList
|
||||||
|
0 => '{^(?'
|
||||||
|
.'|/abc([^/]++)/(?'
|
||||||
|
.'|1(?'
|
||||||
|
.'|(*:27)'
|
||||||
|
.'|0(?'
|
||||||
|
.'|(*:38)'
|
||||||
|
.'|0(*:46)'
|
||||||
|
.')'
|
||||||
|
.')'
|
||||||
|
.'|2(?'
|
||||||
|
.'|(*:59)'
|
||||||
|
.'|0(?'
|
||||||
|
.'|(*:70)'
|
||||||
|
.'|0(*:78)'
|
||||||
|
.')'
|
||||||
|
.')'
|
||||||
|
.')'
|
||||||
|
.')/?$}sD',
|
||||||
|
],
|
||||||
|
[ // $dynamicRoutes
|
||||||
|
27 => [[['_route' => 'r1'], ['foo'], null, null, false, false, null]],
|
||||||
|
38 => [[['_route' => 'r10'], ['foo'], null, null, false, false, null]],
|
||||||
|
46 => [[['_route' => 'r100'], ['foo'], null, null, false, false, null]],
|
||||||
|
59 => [[['_route' => 'r2'], ['foo'], null, null, false, false, null]],
|
||||||
|
70 => [[['_route' => 'r20'], ['foo'], null, null, false, false, null]],
|
||||||
|
78 => [
|
||||||
|
[['_route' => 'r200'], ['foo'], null, null, false, false, null],
|
||||||
|
[null, null, null, null, false, false, 0],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
null, // $checkCondition
|
||||||
|
];
|
@ -0,0 +1,29 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This file has been auto-generated
|
||||||
|
* by the Symfony Routing Component.
|
||||||
|
*/
|
||||||
|
|
||||||
|
return [
|
||||||
|
true, // $matchHost
|
||||||
|
[ // $staticRoutes
|
||||||
|
],
|
||||||
|
[ // $regexpList
|
||||||
|
0 => '{^(?'
|
||||||
|
.'|(?i:([^\\.]++)\\.exampple\\.com)\\.(?'
|
||||||
|
.'|/abc([^/]++)(?'
|
||||||
|
.'|(*:56)'
|
||||||
|
.')'
|
||||||
|
.')'
|
||||||
|
.')/?$}sD',
|
||||||
|
],
|
||||||
|
[ // $dynamicRoutes
|
||||||
|
56 => [
|
||||||
|
[['_route' => 'r1'], ['foo', 'foo'], null, null, false, true, null],
|
||||||
|
[['_route' => 'r2'], ['foo', 'foo'], null, null, false, true, null],
|
||||||
|
[null, null, null, null, false, false, 0],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
null, // $checkCondition
|
||||||
|
];
|
@ -0,0 +1,110 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This file has been auto-generated
|
||||||
|
* by the Symfony Routing Component.
|
||||||
|
*/
|
||||||
|
|
||||||
|
return [
|
||||||
|
true, // $matchHost
|
||||||
|
[ // $staticRoutes
|
||||||
|
'/test/baz' => [[['_route' => 'baz'], null, null, null, false, false, null]],
|
||||||
|
'/test/baz.html' => [[['_route' => 'baz2'], null, null, null, false, false, null]],
|
||||||
|
'/test/baz3' => [[['_route' => 'baz3'], null, null, null, true, false, null]],
|
||||||
|
'/foofoo' => [[['_route' => 'foofoo', 'def' => 'test'], null, null, null, false, false, null]],
|
||||||
|
'/spa ce' => [[['_route' => 'space'], null, null, null, false, false, null]],
|
||||||
|
'/multi/new' => [[['_route' => 'overridden2'], null, null, null, false, false, null]],
|
||||||
|
'/multi/hey' => [[['_route' => 'hey'], null, null, null, true, false, null]],
|
||||||
|
'/ababa' => [[['_route' => 'ababa'], null, null, null, false, false, null]],
|
||||||
|
'/route1' => [[['_route' => 'route1'], 'a.example.com', null, null, false, false, null]],
|
||||||
|
'/c2/route2' => [[['_route' => 'route2'], 'a.example.com', null, null, false, false, null]],
|
||||||
|
'/route4' => [[['_route' => 'route4'], 'a.example.com', null, null, false, false, null]],
|
||||||
|
'/c2/route3' => [[['_route' => 'route3'], 'b.example.com', null, null, false, false, null]],
|
||||||
|
'/route5' => [[['_route' => 'route5'], 'c.example.com', null, null, false, false, null]],
|
||||||
|
'/route6' => [[['_route' => 'route6'], null, null, null, false, false, null]],
|
||||||
|
'/route11' => [[['_route' => 'route11'], '#^(?P<var1>[^\\.]++)\\.example\\.com$#sDi', null, null, false, false, null]],
|
||||||
|
'/route12' => [[['_route' => 'route12', 'var1' => 'val'], '#^(?P<var1>[^\\.]++)\\.example\\.com$#sDi', null, null, false, false, null]],
|
||||||
|
'/route17' => [[['_route' => 'route17'], null, null, null, false, false, null]],
|
||||||
|
'/secure' => [[['_route' => 'secure'], null, null, ['https' => 0], false, false, null]],
|
||||||
|
'/nonsecure' => [[['_route' => 'nonsecure'], null, null, ['http' => 0], false, false, null]],
|
||||||
|
],
|
||||||
|
[ // $regexpList
|
||||||
|
0 => '{^(?'
|
||||||
|
.'|(?:(?:[^./]*+\\.)++)(?'
|
||||||
|
.'|/foo/(baz|symfony)(*:47)'
|
||||||
|
.'|/bar(?'
|
||||||
|
.'|/([^/]++)(*:70)'
|
||||||
|
.'|head/([^/]++)(*:90)'
|
||||||
|
.')'
|
||||||
|
.'|/test/([^/]++)(?'
|
||||||
|
.'|(*:115)'
|
||||||
|
.')'
|
||||||
|
.'|/([\']+)(*:131)'
|
||||||
|
.'|/a/(?'
|
||||||
|
.'|b\'b/([^/]++)(?'
|
||||||
|
.'|(*:160)'
|
||||||
|
.'|(*:168)'
|
||||||
|
.')'
|
||||||
|
.'|(.*)(*:181)'
|
||||||
|
.'|b\'b/([^/]++)(?'
|
||||||
|
.'|(*:204)'
|
||||||
|
.'|(*:212)'
|
||||||
|
.')'
|
||||||
|
.')'
|
||||||
|
.'|/multi/hello(?:/([^/]++))?(*:248)'
|
||||||
|
.'|/([^/]++)/b/([^/]++)(?'
|
||||||
|
.'|(*:279)'
|
||||||
|
.'|(*:287)'
|
||||||
|
.')'
|
||||||
|
.'|/aba/([^/]++)(*:309)'
|
||||||
|
.')|(?i:([^\\.]++)\\.example\\.com)\\.(?'
|
||||||
|
.'|/route1(?'
|
||||||
|
.'|3/([^/]++)(*:371)'
|
||||||
|
.'|4/([^/]++)(*:389)'
|
||||||
|
.')'
|
||||||
|
.')|(?i:c\\.example\\.com)\\.(?'
|
||||||
|
.'|/route15/([^/]++)(*:441)'
|
||||||
|
.')|(?:(?:[^./]*+\\.)++)(?'
|
||||||
|
.'|/route16/([^/]++)(*:489)'
|
||||||
|
.'|/a/(?'
|
||||||
|
.'|a\\.\\.\\.(*:510)'
|
||||||
|
.'|b/(?'
|
||||||
|
.'|([^/]++)(*:531)'
|
||||||
|
.'|c/([^/]++)(*:549)'
|
||||||
|
.')'
|
||||||
|
.')'
|
||||||
|
.')'
|
||||||
|
.')/?$}sD',
|
||||||
|
],
|
||||||
|
[ // $dynamicRoutes
|
||||||
|
47 => [[['_route' => 'foo', 'def' => 'test'], ['bar'], null, null, false, true, null]],
|
||||||
|
70 => [[['_route' => 'bar'], ['foo'], ['GET' => 0, 'HEAD' => 1], null, false, true, null]],
|
||||||
|
90 => [[['_route' => 'barhead'], ['foo'], ['GET' => 0], null, false, true, null]],
|
||||||
|
115 => [
|
||||||
|
[['_route' => 'baz4'], ['foo'], null, null, true, true, null],
|
||||||
|
[['_route' => 'baz5'], ['foo'], ['POST' => 0], null, true, true, null],
|
||||||
|
[['_route' => 'baz.baz6'], ['foo'], ['PUT' => 0], null, true, true, null],
|
||||||
|
],
|
||||||
|
131 => [[['_route' => 'quoter'], ['quoter'], null, null, false, true, null]],
|
||||||
|
160 => [[['_route' => 'foo1'], ['foo'], ['PUT' => 0], null, false, true, null]],
|
||||||
|
168 => [[['_route' => 'bar1'], ['bar'], null, null, false, true, null]],
|
||||||
|
181 => [[['_route' => 'overridden'], ['var'], null, null, false, true, null]],
|
||||||
|
204 => [[['_route' => 'foo2'], ['foo1'], null, null, false, true, null]],
|
||||||
|
212 => [[['_route' => 'bar2'], ['bar1'], null, null, false, true, null]],
|
||||||
|
248 => [[['_route' => 'helloWorld', 'who' => 'World!'], ['who'], null, null, false, true, null]],
|
||||||
|
279 => [[['_route' => 'foo3'], ['_locale', 'foo'], null, null, false, true, null]],
|
||||||
|
287 => [[['_route' => 'bar3'], ['_locale', 'bar'], null, null, false, true, null]],
|
||||||
|
309 => [[['_route' => 'foo4'], ['foo'], null, null, false, true, null]],
|
||||||
|
371 => [[['_route' => 'route13'], ['var1', 'name'], null, null, false, true, null]],
|
||||||
|
389 => [[['_route' => 'route14', 'var1' => 'val'], ['var1', 'name'], null, null, false, true, null]],
|
||||||
|
441 => [[['_route' => 'route15'], ['name'], null, null, false, true, null]],
|
||||||
|
489 => [[['_route' => 'route16', 'var1' => 'val'], ['name'], null, null, false, true, null]],
|
||||||
|
510 => [[['_route' => 'a'], [], null, null, false, false, null]],
|
||||||
|
531 => [[['_route' => 'b'], ['var'], null, null, false, true, null]],
|
||||||
|
549 => [
|
||||||
|
[['_route' => 'c'], ['var'], null, null, false, true, null],
|
||||||
|
[null, null, null, null, false, false, 0],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
null, // $checkCondition
|
||||||
|
];
|
@ -0,0 +1,30 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This file has been auto-generated
|
||||||
|
* by the Symfony Routing Component.
|
||||||
|
*/
|
||||||
|
|
||||||
|
return [
|
||||||
|
false, // $matchHost
|
||||||
|
[ // $staticRoutes
|
||||||
|
'/rootprefix/test' => [[['_route' => 'static'], null, null, null, false, false, null]],
|
||||||
|
'/with-condition' => [[['_route' => 'with-condition'], null, null, null, false, false, -1]],
|
||||||
|
],
|
||||||
|
[ // $regexpList
|
||||||
|
0 => '{^(?'
|
||||||
|
.'|/rootprefix/([^/]++)(*:27)'
|
||||||
|
.')/?$}sD',
|
||||||
|
],
|
||||||
|
[ // $dynamicRoutes
|
||||||
|
27 => [
|
||||||
|
[['_route' => 'dynamic'], ['var'], null, null, false, true, null],
|
||||||
|
[null, null, null, null, false, false, 0],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
static function ($condition, $context, $request) { // $checkCondition
|
||||||
|
switch ($condition) {
|
||||||
|
case -1: return ($context->getMethod() == "GET");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
];
|
@ -0,0 +1,25 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This file has been auto-generated
|
||||||
|
* by the Symfony Routing Component.
|
||||||
|
*/
|
||||||
|
|
||||||
|
return [
|
||||||
|
false, // $matchHost
|
||||||
|
[ // $staticRoutes
|
||||||
|
'/just_head' => [[['_route' => 'just_head'], null, ['HEAD' => 0], null, false, false, null]],
|
||||||
|
'/head_and_get' => [[['_route' => 'head_and_get'], null, ['HEAD' => 0, 'GET' => 1], null, false, false, null]],
|
||||||
|
'/get_and_head' => [[['_route' => 'get_and_head'], null, ['GET' => 0, 'HEAD' => 1], null, false, false, null]],
|
||||||
|
'/post_and_head' => [[['_route' => 'post_and_head'], null, ['POST' => 0, 'HEAD' => 1], null, false, false, null]],
|
||||||
|
'/put_and_post' => [
|
||||||
|
[['_route' => 'put_and_post'], null, ['PUT' => 0, 'POST' => 1], null, false, false, null],
|
||||||
|
[['_route' => 'put_and_get_and_head'], null, ['PUT' => 0, 'GET' => 1, 'HEAD' => 2], null, false, false, null],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
[ // $regexpList
|
||||||
|
],
|
||||||
|
[ // $dynamicRoutes
|
||||||
|
],
|
||||||
|
null, // $checkCondition
|
||||||
|
];
|
@ -0,0 +1,38 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This file has been auto-generated
|
||||||
|
* by the Symfony Routing Component.
|
||||||
|
*/
|
||||||
|
|
||||||
|
return [
|
||||||
|
false, // $matchHost
|
||||||
|
[ // $staticRoutes
|
||||||
|
'/a/11' => [[['_route' => 'a_first'], null, null, null, false, false, null]],
|
||||||
|
'/a/22' => [[['_route' => 'a_second'], null, null, null, false, false, null]],
|
||||||
|
'/a/333' => [[['_route' => 'a_third'], null, null, null, false, false, null]],
|
||||||
|
'/a/44' => [[['_route' => 'a_fourth'], null, null, null, true, false, null]],
|
||||||
|
'/a/55' => [[['_route' => 'a_fifth'], null, null, null, true, false, null]],
|
||||||
|
'/a/66' => [[['_route' => 'a_sixth'], null, null, null, true, false, null]],
|
||||||
|
'/nested/group/a' => [[['_route' => 'nested_a'], null, null, null, true, false, null]],
|
||||||
|
'/nested/group/b' => [[['_route' => 'nested_b'], null, null, null, true, false, null]],
|
||||||
|
'/nested/group/c' => [[['_route' => 'nested_c'], null, null, null, true, false, null]],
|
||||||
|
'/slashed/group' => [[['_route' => 'slashed_a'], null, null, null, true, false, null]],
|
||||||
|
'/slashed/group/b' => [[['_route' => 'slashed_b'], null, null, null, true, false, null]],
|
||||||
|
'/slashed/group/c' => [[['_route' => 'slashed_c'], null, null, null, true, false, null]],
|
||||||
|
],
|
||||||
|
[ // $regexpList
|
||||||
|
0 => '{^(?'
|
||||||
|
.'|/([^/]++)(*:16)'
|
||||||
|
.'|/nested/([^/]++)(*:39)'
|
||||||
|
.')/?$}sD',
|
||||||
|
],
|
||||||
|
[ // $dynamicRoutes
|
||||||
|
16 => [[['_route' => 'a_wildcard'], ['param'], null, null, false, true, null]],
|
||||||
|
39 => [
|
||||||
|
[['_route' => 'nested_wildcard'], ['param'], null, null, false, true, null],
|
||||||
|
[null, null, null, null, false, false, 0],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
null, // $checkCondition
|
||||||
|
];
|
@ -0,0 +1,50 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This file has been auto-generated
|
||||||
|
* by the Symfony Routing Component.
|
||||||
|
*/
|
||||||
|
|
||||||
|
return [
|
||||||
|
false, // $matchHost
|
||||||
|
[ // $staticRoutes
|
||||||
|
'/trailing/simple/no-methods' => [[['_route' => 'simple_trailing_slash_no_methods'], null, null, null, true, false, null]],
|
||||||
|
'/trailing/simple/get-method' => [[['_route' => 'simple_trailing_slash_GET_method'], null, ['GET' => 0], null, true, false, null]],
|
||||||
|
'/trailing/simple/head-method' => [[['_route' => 'simple_trailing_slash_HEAD_method'], null, ['HEAD' => 0], null, true, false, null]],
|
||||||
|
'/trailing/simple/post-method' => [[['_route' => 'simple_trailing_slash_POST_method'], null, ['POST' => 0], null, true, false, null]],
|
||||||
|
'/not-trailing/simple/no-methods' => [[['_route' => 'simple_not_trailing_slash_no_methods'], null, null, null, false, false, null]],
|
||||||
|
'/not-trailing/simple/get-method' => [[['_route' => 'simple_not_trailing_slash_GET_method'], null, ['GET' => 0], null, false, false, null]],
|
||||||
|
'/not-trailing/simple/head-method' => [[['_route' => 'simple_not_trailing_slash_HEAD_method'], null, ['HEAD' => 0], null, false, false, null]],
|
||||||
|
'/not-trailing/simple/post-method' => [[['_route' => 'simple_not_trailing_slash_POST_method'], null, ['POST' => 0], null, false, false, null]],
|
||||||
|
],
|
||||||
|
[ // $regexpList
|
||||||
|
0 => '{^(?'
|
||||||
|
.'|/trailing/regex/(?'
|
||||||
|
.'|no\\-methods/([^/]++)(*:46)'
|
||||||
|
.'|get\\-method/([^/]++)(*:73)'
|
||||||
|
.'|head\\-method/([^/]++)(*:101)'
|
||||||
|
.'|post\\-method/([^/]++)(*:130)'
|
||||||
|
.')'
|
||||||
|
.'|/not\\-trailing/regex/(?'
|
||||||
|
.'|no\\-methods/([^/]++)(*:183)'
|
||||||
|
.'|get\\-method/([^/]++)(*:211)'
|
||||||
|
.'|head\\-method/([^/]++)(*:240)'
|
||||||
|
.'|post\\-method/([^/]++)(*:269)'
|
||||||
|
.')'
|
||||||
|
.')/?$}sD',
|
||||||
|
],
|
||||||
|
[ // $dynamicRoutes
|
||||||
|
46 => [[['_route' => 'regex_trailing_slash_no_methods'], ['param'], null, null, true, true, null]],
|
||||||
|
73 => [[['_route' => 'regex_trailing_slash_GET_method'], ['param'], ['GET' => 0], null, true, true, null]],
|
||||||
|
101 => [[['_route' => 'regex_trailing_slash_HEAD_method'], ['param'], ['HEAD' => 0], null, true, true, null]],
|
||||||
|
130 => [[['_route' => 'regex_trailing_slash_POST_method'], ['param'], ['POST' => 0], null, true, true, null]],
|
||||||
|
183 => [[['_route' => 'regex_not_trailing_slash_no_methods'], ['param'], null, null, false, true, null]],
|
||||||
|
211 => [[['_route' => 'regex_not_trailing_slash_GET_method'], ['param'], ['GET' => 0], null, false, true, null]],
|
||||||
|
240 => [[['_route' => 'regex_not_trailing_slash_HEAD_method'], ['param'], ['HEAD' => 0], null, false, true, null]],
|
||||||
|
269 => [
|
||||||
|
[['_route' => 'regex_not_trailing_slash_POST_method'], ['param'], ['POST' => 0], null, false, true, null],
|
||||||
|
[null, null, null, null, false, false, 0],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
null, // $checkCondition
|
||||||
|
];
|
@ -0,0 +1,50 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This file has been auto-generated
|
||||||
|
* by the Symfony Routing Component.
|
||||||
|
*/
|
||||||
|
|
||||||
|
return [
|
||||||
|
false, // $matchHost
|
||||||
|
[ // $staticRoutes
|
||||||
|
'/trailing/simple/no-methods' => [[['_route' => 'simple_trailing_slash_no_methods'], null, null, null, true, false, null]],
|
||||||
|
'/trailing/simple/get-method' => [[['_route' => 'simple_trailing_slash_GET_method'], null, ['GET' => 0], null, true, false, null]],
|
||||||
|
'/trailing/simple/head-method' => [[['_route' => 'simple_trailing_slash_HEAD_method'], null, ['HEAD' => 0], null, true, false, null]],
|
||||||
|
'/trailing/simple/post-method' => [[['_route' => 'simple_trailing_slash_POST_method'], null, ['POST' => 0], null, true, false, null]],
|
||||||
|
'/not-trailing/simple/no-methods' => [[['_route' => 'simple_not_trailing_slash_no_methods'], null, null, null, false, false, null]],
|
||||||
|
'/not-trailing/simple/get-method' => [[['_route' => 'simple_not_trailing_slash_GET_method'], null, ['GET' => 0], null, false, false, null]],
|
||||||
|
'/not-trailing/simple/head-method' => [[['_route' => 'simple_not_trailing_slash_HEAD_method'], null, ['HEAD' => 0], null, false, false, null]],
|
||||||
|
'/not-trailing/simple/post-method' => [[['_route' => 'simple_not_trailing_slash_POST_method'], null, ['POST' => 0], null, false, false, null]],
|
||||||
|
],
|
||||||
|
[ // $regexpList
|
||||||
|
0 => '{^(?'
|
||||||
|
.'|/trailing/regex/(?'
|
||||||
|
.'|no\\-methods/([^/]++)(*:46)'
|
||||||
|
.'|get\\-method/([^/]++)(*:73)'
|
||||||
|
.'|head\\-method/([^/]++)(*:101)'
|
||||||
|
.'|post\\-method/([^/]++)(*:130)'
|
||||||
|
.')'
|
||||||
|
.'|/not\\-trailing/regex/(?'
|
||||||
|
.'|no\\-methods/([^/]++)(*:183)'
|
||||||
|
.'|get\\-method/([^/]++)(*:211)'
|
||||||
|
.'|head\\-method/([^/]++)(*:240)'
|
||||||
|
.'|post\\-method/([^/]++)(*:269)'
|
||||||
|
.')'
|
||||||
|
.')/?$}sD',
|
||||||
|
],
|
||||||
|
[ // $dynamicRoutes
|
||||||
|
46 => [[['_route' => 'regex_trailing_slash_no_methods'], ['param'], null, null, true, true, null]],
|
||||||
|
73 => [[['_route' => 'regex_trailing_slash_GET_method'], ['param'], ['GET' => 0], null, true, true, null]],
|
||||||
|
101 => [[['_route' => 'regex_trailing_slash_HEAD_method'], ['param'], ['HEAD' => 0], null, true, true, null]],
|
||||||
|
130 => [[['_route' => 'regex_trailing_slash_POST_method'], ['param'], ['POST' => 0], null, true, true, null]],
|
||||||
|
183 => [[['_route' => 'regex_not_trailing_slash_no_methods'], ['param'], null, null, false, true, null]],
|
||||||
|
211 => [[['_route' => 'regex_not_trailing_slash_GET_method'], ['param'], ['GET' => 0], null, false, true, null]],
|
||||||
|
240 => [[['_route' => 'regex_not_trailing_slash_HEAD_method'], ['param'], ['HEAD' => 0], null, false, true, null]],
|
||||||
|
269 => [
|
||||||
|
[['_route' => 'regex_not_trailing_slash_POST_method'], ['param'], ['POST' => 0], null, false, true, null],
|
||||||
|
[null, null, null, null, false, false, 0],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
null, // $checkCondition
|
||||||
|
];
|
@ -0,0 +1,32 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This file has been auto-generated
|
||||||
|
* by the Symfony Routing Component.
|
||||||
|
*/
|
||||||
|
|
||||||
|
return [
|
||||||
|
false, // $matchHost
|
||||||
|
[ // $staticRoutes
|
||||||
|
],
|
||||||
|
[ // $regexpList
|
||||||
|
0 => '{^(?'
|
||||||
|
.'|/(a)(*:11)'
|
||||||
|
.')/?$}sD',
|
||||||
|
11 => '{^(?'
|
||||||
|
.'|/(.)(*:22)'
|
||||||
|
.')/?$}sDu',
|
||||||
|
22 => '{^(?'
|
||||||
|
.'|/(.)(*:33)'
|
||||||
|
.')/?$}sD',
|
||||||
|
],
|
||||||
|
[ // $dynamicRoutes
|
||||||
|
11 => [[['_route' => 'a'], ['a'], null, null, false, true, null]],
|
||||||
|
22 => [[['_route' => 'b'], ['a'], null, null, false, true, null]],
|
||||||
|
33 => [
|
||||||
|
[['_route' => 'c'], ['a'], null, null, false, true, null],
|
||||||
|
[null, null, null, null, false, false, 0],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
null, // $checkCondition
|
||||||
|
];
|
@ -0,0 +1,22 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This file has been auto-generated
|
||||||
|
* by the Symfony Routing Component.
|
||||||
|
*/
|
||||||
|
|
||||||
|
return [
|
||||||
|
true, // $matchHost
|
||||||
|
[ // $staticRoutes
|
||||||
|
'/' => [
|
||||||
|
[['_route' => 'a'], '#^(?P<d>[^\\.]++)\\.e\\.c\\.b\\.a$#sDi', null, null, false, false, null],
|
||||||
|
[['_route' => 'c'], '#^(?P<e>[^\\.]++)\\.e\\.c\\.b\\.a$#sDi', null, null, false, false, null],
|
||||||
|
[['_route' => 'b'], 'd.c.b.a', null, null, false, false, null],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
[ // $regexpList
|
||||||
|
],
|
||||||
|
[ // $dynamicRoutes
|
||||||
|
],
|
||||||
|
null, // $checkCondition
|
||||||
|
];
|
@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
use Symfony\Component\Routing\Matcher\Dumper\PhpMatcherTrait;
|
use Symfony\Component\Routing\Matcher\Dumper\CompiledUrlMatcherTrait;
|
||||||
use Symfony\Component\Routing\RequestContext;
|
use Symfony\Component\Routing\RequestContext;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -9,7 +9,7 @@ use Symfony\Component\Routing\RequestContext;
|
|||||||
*/
|
*/
|
||||||
class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
|
class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
|
||||||
{
|
{
|
||||||
use PhpMatcherTrait;
|
use CompiledUrlMatcherTrait;
|
||||||
|
|
||||||
public function __construct(RequestContext $context)
|
public function __construct(RequestContext $context)
|
||||||
{
|
{
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
use Symfony\Component\Routing\Matcher\Dumper\PhpMatcherTrait;
|
use Symfony\Component\Routing\Matcher\Dumper\CompiledUrlMatcherTrait;
|
||||||
use Symfony\Component\Routing\RequestContext;
|
use Symfony\Component\Routing\RequestContext;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -9,7 +9,7 @@ use Symfony\Component\Routing\RequestContext;
|
|||||||
*/
|
*/
|
||||||
class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
|
class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
|
||||||
{
|
{
|
||||||
use PhpMatcherTrait;
|
use CompiledUrlMatcherTrait;
|
||||||
|
|
||||||
public function __construct(RequestContext $context)
|
public function __construct(RequestContext $context)
|
||||||
{
|
{
|
||||||
@ -107,7 +107,10 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
|
|||||||
489 => [[['_route' => 'route16', 'var1' => 'val'], ['name'], null, null, false, true, null]],
|
489 => [[['_route' => 'route16', 'var1' => 'val'], ['name'], null, null, false, true, null]],
|
||||||
510 => [[['_route' => 'a'], [], null, null, false, false, null]],
|
510 => [[['_route' => 'a'], [], null, null, false, false, null]],
|
||||||
531 => [[['_route' => 'b'], ['var'], null, null, false, true, null]],
|
531 => [[['_route' => 'b'], ['var'], null, null, false, true, null]],
|
||||||
549 => [[['_route' => 'c'], ['var'], null, null, false, true, null]],
|
549 => [
|
||||||
|
[['_route' => 'c'], ['var'], null, null, false, true, null],
|
||||||
|
[null, null, null, null, false, false, 0],
|
||||||
|
],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
use Symfony\Component\Routing\Matcher\Dumper\PhpMatcherTrait;
|
use Symfony\Component\Routing\Matcher\Dumper\CompiledUrlMatcherTrait;
|
||||||
use Symfony\Component\Routing\RequestContext;
|
use Symfony\Component\Routing\RequestContext;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -9,7 +9,7 @@ use Symfony\Component\Routing\RequestContext;
|
|||||||
*/
|
*/
|
||||||
class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
|
class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
|
||||||
{
|
{
|
||||||
use PhpMatcherTrait;
|
use CompiledUrlMatcherTrait;
|
||||||
|
|
||||||
public function __construct(RequestContext $context)
|
public function __construct(RequestContext $context)
|
||||||
{
|
{
|
||||||
@ -2770,7 +2770,10 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
|
|||||||
49567 => [[['_route' => '_974'], ['a', 'b', 'c'], null, null, false, false, null]],
|
49567 => [[['_route' => '_974'], ['a', 'b', 'c'], null, null, false, false, null]],
|
||||||
49620 => [[['_route' => '_835'], ['a', 'b', 'c'], null, null, false, false, null]],
|
49620 => [[['_route' => '_835'], ['a', 'b', 'c'], null, null, false, false, null]],
|
||||||
49668 => [[['_route' => '_934'], ['a', 'b', 'c'], null, null, false, false, null]],
|
49668 => [[['_route' => '_934'], ['a', 'b', 'c'], null, null, false, false, null]],
|
||||||
49718 => [[['_route' => '_869'], ['a', 'b', 'c'], null, null, false, false, null]],
|
49718 => [
|
||||||
|
[['_route' => '_869'], ['a', 'b', 'c'], null, null, false, false, null],
|
||||||
|
[null, null, null, null, false, false, 0],
|
||||||
|
],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
use Symfony\Component\Routing\Matcher\Dumper\PhpMatcherTrait;
|
use Symfony\Component\Routing\Matcher\Dumper\CompiledUrlMatcherTrait;
|
||||||
use Symfony\Component\Routing\RequestContext;
|
use Symfony\Component\Routing\RequestContext;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -9,7 +9,7 @@ use Symfony\Component\Routing\RequestContext;
|
|||||||
*/
|
*/
|
||||||
class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\RedirectableUrlMatcher
|
class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\RedirectableUrlMatcher
|
||||||
{
|
{
|
||||||
use PhpMatcherTrait;
|
use CompiledUrlMatcherTrait;
|
||||||
|
|
||||||
public function __construct(RequestContext $context)
|
public function __construct(RequestContext $context)
|
||||||
{
|
{
|
||||||
@ -60,7 +60,10 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec
|
|||||||
216 => [[['_route' => 'k', '_locale' => 'en'], ['_locale'], null, null, false, false, null]],
|
216 => [[['_route' => 'k', '_locale' => 'en'], ['_locale'], null, null, false, false, null]],
|
||||||
234 => [[['_route' => 'l', '_locale' => 'en'], ['_locale'], null, null, false, false, null]],
|
234 => [[['_route' => 'l', '_locale' => 'en'], ['_locale'], null, null, false, false, null]],
|
||||||
245 => [[['_route' => 'm', '_locale' => 'en'], ['_locale'], null, null, false, false, null]],
|
245 => [[['_route' => 'm', '_locale' => 'en'], ['_locale'], null, null, false, false, null]],
|
||||||
264 => [[['_route' => 'n', '_locale' => 'en'], ['_locale'], null, null, false, true, null]],
|
264 => [
|
||||||
|
[['_route' => 'n', '_locale' => 'en'], ['_locale'], null, null, false, true, null],
|
||||||
|
[null, null, null, null, false, false, 0],
|
||||||
|
],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
use Symfony\Component\Routing\Matcher\Dumper\PhpMatcherTrait;
|
use Symfony\Component\Routing\Matcher\Dumper\CompiledUrlMatcherTrait;
|
||||||
use Symfony\Component\Routing\RequestContext;
|
use Symfony\Component\Routing\RequestContext;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -9,7 +9,7 @@ use Symfony\Component\Routing\RequestContext;
|
|||||||
*/
|
*/
|
||||||
class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
|
class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
|
||||||
{
|
{
|
||||||
use PhpMatcherTrait;
|
use CompiledUrlMatcherTrait;
|
||||||
|
|
||||||
public function __construct(RequestContext $context)
|
public function __construct(RequestContext $context)
|
||||||
{
|
{
|
||||||
@ -40,7 +40,10 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
|
|||||||
46 => [[['_route' => 'r100'], ['foo'], null, null, false, false, null]],
|
46 => [[['_route' => 'r100'], ['foo'], null, null, false, false, null]],
|
||||||
59 => [[['_route' => 'r2'], ['foo'], null, null, false, false, null]],
|
59 => [[['_route' => 'r2'], ['foo'], null, null, false, false, null]],
|
||||||
70 => [[['_route' => 'r20'], ['foo'], null, null, false, false, null]],
|
70 => [[['_route' => 'r20'], ['foo'], null, null, false, false, null]],
|
||||||
78 => [[['_route' => 'r200'], ['foo'], null, null, false, false, null]],
|
78 => [
|
||||||
|
[['_route' => 'r200'], ['foo'], null, null, false, false, null],
|
||||||
|
[null, null, null, null, false, false, 0],
|
||||||
|
],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
use Symfony\Component\Routing\Matcher\Dumper\PhpMatcherTrait;
|
use Symfony\Component\Routing\Matcher\Dumper\CompiledUrlMatcherTrait;
|
||||||
use Symfony\Component\Routing\RequestContext;
|
use Symfony\Component\Routing\RequestContext;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -9,7 +9,7 @@ use Symfony\Component\Routing\RequestContext;
|
|||||||
*/
|
*/
|
||||||
class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
|
class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
|
||||||
{
|
{
|
||||||
use PhpMatcherTrait;
|
use CompiledUrlMatcherTrait;
|
||||||
|
|
||||||
public function __construct(RequestContext $context)
|
public function __construct(RequestContext $context)
|
||||||
{
|
{
|
||||||
@ -28,6 +28,7 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
|
|||||||
56 => [
|
56 => [
|
||||||
[['_route' => 'r1'], ['foo', 'foo'], null, null, false, true, null],
|
[['_route' => 'r1'], ['foo', 'foo'], null, null, false, true, null],
|
||||||
[['_route' => 'r2'], ['foo', 'foo'], null, null, false, true, null],
|
[['_route' => 'r2'], ['foo', 'foo'], null, null, false, true, null],
|
||||||
|
[null, null, null, null, false, false, 0],
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
use Symfony\Component\Routing\Matcher\Dumper\PhpMatcherTrait;
|
use Symfony\Component\Routing\Matcher\Dumper\CompiledUrlMatcherTrait;
|
||||||
use Symfony\Component\Routing\RequestContext;
|
use Symfony\Component\Routing\RequestContext;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -9,7 +9,7 @@ use Symfony\Component\Routing\RequestContext;
|
|||||||
*/
|
*/
|
||||||
class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\RedirectableUrlMatcher
|
class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\RedirectableUrlMatcher
|
||||||
{
|
{
|
||||||
use PhpMatcherTrait;
|
use CompiledUrlMatcherTrait;
|
||||||
|
|
||||||
public function __construct(RequestContext $context)
|
public function __construct(RequestContext $context)
|
||||||
{
|
{
|
||||||
@ -109,7 +109,10 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec
|
|||||||
489 => [[['_route' => 'route16', 'var1' => 'val'], ['name'], null, null, false, true, null]],
|
489 => [[['_route' => 'route16', 'var1' => 'val'], ['name'], null, null, false, true, null]],
|
||||||
510 => [[['_route' => 'a'], [], null, null, false, false, null]],
|
510 => [[['_route' => 'a'], [], null, null, false, false, null]],
|
||||||
531 => [[['_route' => 'b'], ['var'], null, null, false, true, null]],
|
531 => [[['_route' => 'b'], ['var'], null, null, false, true, null]],
|
||||||
549 => [[['_route' => 'c'], ['var'], null, null, false, true, null]],
|
549 => [
|
||||||
|
[['_route' => 'c'], ['var'], null, null, false, true, null],
|
||||||
|
[null, null, null, null, false, false, 0],
|
||||||
|
],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
use Symfony\Component\Routing\Matcher\Dumper\PhpMatcherTrait;
|
use Symfony\Component\Routing\Matcher\Dumper\CompiledUrlMatcherTrait;
|
||||||
use Symfony\Component\Routing\RequestContext;
|
use Symfony\Component\Routing\RequestContext;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -9,7 +9,7 @@ use Symfony\Component\Routing\RequestContext;
|
|||||||
*/
|
*/
|
||||||
class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
|
class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
|
||||||
{
|
{
|
||||||
use PhpMatcherTrait;
|
use CompiledUrlMatcherTrait;
|
||||||
|
|
||||||
public function __construct(RequestContext $context)
|
public function __construct(RequestContext $context)
|
||||||
{
|
{
|
||||||
@ -24,7 +24,10 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
|
|||||||
.')/?$}sD',
|
.')/?$}sD',
|
||||||
];
|
];
|
||||||
$this->dynamicRoutes = [
|
$this->dynamicRoutes = [
|
||||||
27 => [[['_route' => 'dynamic'], ['var'], null, null, false, true, null]],
|
27 => [
|
||||||
|
[['_route' => 'dynamic'], ['var'], null, null, false, true, null],
|
||||||
|
[null, null, null, null, false, false, 0],
|
||||||
|
],
|
||||||
];
|
];
|
||||||
$this->checkCondition = static function ($condition, $context, $request) {
|
$this->checkCondition = static function ($condition, $context, $request) {
|
||||||
switch ($condition) {
|
switch ($condition) {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
use Symfony\Component\Routing\Matcher\Dumper\PhpMatcherTrait;
|
use Symfony\Component\Routing\Matcher\Dumper\CompiledUrlMatcherTrait;
|
||||||
use Symfony\Component\Routing\RequestContext;
|
use Symfony\Component\Routing\RequestContext;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -9,7 +9,7 @@ use Symfony\Component\Routing\RequestContext;
|
|||||||
*/
|
*/
|
||||||
class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
|
class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
|
||||||
{
|
{
|
||||||
use PhpMatcherTrait;
|
use CompiledUrlMatcherTrait;
|
||||||
|
|
||||||
public function __construct(RequestContext $context)
|
public function __construct(RequestContext $context)
|
||||||
{
|
{
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
use Symfony\Component\Routing\Matcher\Dumper\PhpMatcherTrait;
|
use Symfony\Component\Routing\Matcher\Dumper\CompiledUrlMatcherTrait;
|
||||||
use Symfony\Component\Routing\RequestContext;
|
use Symfony\Component\Routing\RequestContext;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -9,7 +9,7 @@ use Symfony\Component\Routing\RequestContext;
|
|||||||
*/
|
*/
|
||||||
class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\RedirectableUrlMatcher
|
class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\RedirectableUrlMatcher
|
||||||
{
|
{
|
||||||
use PhpMatcherTrait;
|
use CompiledUrlMatcherTrait;
|
||||||
|
|
||||||
public function __construct(RequestContext $context)
|
public function __construct(RequestContext $context)
|
||||||
{
|
{
|
||||||
@ -36,7 +36,10 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec
|
|||||||
];
|
];
|
||||||
$this->dynamicRoutes = [
|
$this->dynamicRoutes = [
|
||||||
16 => [[['_route' => 'a_wildcard'], ['param'], null, null, false, true, null]],
|
16 => [[['_route' => 'a_wildcard'], ['param'], null, null, false, true, null]],
|
||||||
39 => [[['_route' => 'nested_wildcard'], ['param'], null, null, false, true, null]],
|
39 => [
|
||||||
|
[['_route' => 'nested_wildcard'], ['param'], null, null, false, true, null],
|
||||||
|
[null, null, null, null, false, false, 0],
|
||||||
|
],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
use Symfony\Component\Routing\Matcher\Dumper\PhpMatcherTrait;
|
use Symfony\Component\Routing\Matcher\Dumper\CompiledUrlMatcherTrait;
|
||||||
use Symfony\Component\Routing\RequestContext;
|
use Symfony\Component\Routing\RequestContext;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -9,7 +9,7 @@ use Symfony\Component\Routing\RequestContext;
|
|||||||
*/
|
*/
|
||||||
class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
|
class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
|
||||||
{
|
{
|
||||||
use PhpMatcherTrait;
|
use CompiledUrlMatcherTrait;
|
||||||
|
|
||||||
public function __construct(RequestContext $context)
|
public function __construct(RequestContext $context)
|
||||||
{
|
{
|
||||||
@ -48,7 +48,10 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
|
|||||||
183 => [[['_route' => 'regex_not_trailing_slash_no_methods'], ['param'], null, null, false, true, null]],
|
183 => [[['_route' => 'regex_not_trailing_slash_no_methods'], ['param'], null, null, false, true, null]],
|
||||||
211 => [[['_route' => 'regex_not_trailing_slash_GET_method'], ['param'], ['GET' => 0], null, false, true, null]],
|
211 => [[['_route' => 'regex_not_trailing_slash_GET_method'], ['param'], ['GET' => 0], null, false, true, null]],
|
||||||
240 => [[['_route' => 'regex_not_trailing_slash_HEAD_method'], ['param'], ['HEAD' => 0], null, false, true, null]],
|
240 => [[['_route' => 'regex_not_trailing_slash_HEAD_method'], ['param'], ['HEAD' => 0], null, false, true, null]],
|
||||||
269 => [[['_route' => 'regex_not_trailing_slash_POST_method'], ['param'], ['POST' => 0], null, false, true, null]],
|
269 => [
|
||||||
|
[['_route' => 'regex_not_trailing_slash_POST_method'], ['param'], ['POST' => 0], null, false, true, null],
|
||||||
|
[null, null, null, null, false, false, 0],
|
||||||
|
],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
use Symfony\Component\Routing\Matcher\Dumper\PhpMatcherTrait;
|
use Symfony\Component\Routing\Matcher\Dumper\CompiledUrlMatcherTrait;
|
||||||
use Symfony\Component\Routing\RequestContext;
|
use Symfony\Component\Routing\RequestContext;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -9,7 +9,7 @@ use Symfony\Component\Routing\RequestContext;
|
|||||||
*/
|
*/
|
||||||
class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\RedirectableUrlMatcher
|
class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\RedirectableUrlMatcher
|
||||||
{
|
{
|
||||||
use PhpMatcherTrait;
|
use CompiledUrlMatcherTrait;
|
||||||
|
|
||||||
public function __construct(RequestContext $context)
|
public function __construct(RequestContext $context)
|
||||||
{
|
{
|
||||||
@ -48,7 +48,10 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec
|
|||||||
183 => [[['_route' => 'regex_not_trailing_slash_no_methods'], ['param'], null, null, false, true, null]],
|
183 => [[['_route' => 'regex_not_trailing_slash_no_methods'], ['param'], null, null, false, true, null]],
|
||||||
211 => [[['_route' => 'regex_not_trailing_slash_GET_method'], ['param'], ['GET' => 0], null, false, true, null]],
|
211 => [[['_route' => 'regex_not_trailing_slash_GET_method'], ['param'], ['GET' => 0], null, false, true, null]],
|
||||||
240 => [[['_route' => 'regex_not_trailing_slash_HEAD_method'], ['param'], ['HEAD' => 0], null, false, true, null]],
|
240 => [[['_route' => 'regex_not_trailing_slash_HEAD_method'], ['param'], ['HEAD' => 0], null, false, true, null]],
|
||||||
269 => [[['_route' => 'regex_not_trailing_slash_POST_method'], ['param'], ['POST' => 0], null, false, true, null]],
|
269 => [
|
||||||
|
[['_route' => 'regex_not_trailing_slash_POST_method'], ['param'], ['POST' => 0], null, false, true, null],
|
||||||
|
[null, null, null, null, false, false, 0],
|
||||||
|
],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
use Symfony\Component\Routing\Matcher\Dumper\PhpMatcherTrait;
|
use Symfony\Component\Routing\Matcher\Dumper\CompiledUrlMatcherTrait;
|
||||||
use Symfony\Component\Routing\RequestContext;
|
use Symfony\Component\Routing\RequestContext;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -9,7 +9,7 @@ use Symfony\Component\Routing\RequestContext;
|
|||||||
*/
|
*/
|
||||||
class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
|
class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
|
||||||
{
|
{
|
||||||
use PhpMatcherTrait;
|
use CompiledUrlMatcherTrait;
|
||||||
|
|
||||||
public function __construct(RequestContext $context)
|
public function __construct(RequestContext $context)
|
||||||
{
|
{
|
||||||
@ -28,7 +28,10 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
|
|||||||
$this->dynamicRoutes = [
|
$this->dynamicRoutes = [
|
||||||
11 => [[['_route' => 'a'], ['a'], null, null, false, true, null]],
|
11 => [[['_route' => 'a'], ['a'], null, null, false, true, null]],
|
||||||
22 => [[['_route' => 'b'], ['a'], null, null, false, true, null]],
|
22 => [[['_route' => 'b'], ['a'], null, null, false, true, null]],
|
||||||
33 => [[['_route' => 'c'], ['a'], null, null, false, true, null]],
|
33 => [
|
||||||
|
[['_route' => 'c'], ['a'], null, null, false, true, null],
|
||||||
|
[null, null, null, null, false, false, 0],
|
||||||
|
],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
use Symfony\Component\Routing\Matcher\Dumper\PhpMatcherTrait;
|
use Symfony\Component\Routing\Matcher\Dumper\CompiledUrlMatcherTrait;
|
||||||
use Symfony\Component\Routing\RequestContext;
|
use Symfony\Component\Routing\RequestContext;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -9,7 +9,7 @@ use Symfony\Component\Routing\RequestContext;
|
|||||||
*/
|
*/
|
||||||
class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
|
class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
|
||||||
{
|
{
|
||||||
use PhpMatcherTrait;
|
use CompiledUrlMatcherTrait;
|
||||||
|
|
||||||
public function __construct(RequestContext $context)
|
public function __construct(RequestContext $context)
|
||||||
{
|
{
|
||||||
|
@ -0,0 +1,240 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Component\Routing\Tests\Generator\Dumper;
|
||||||
|
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use Symfony\Component\Routing\Generator\CompiledUrlGenerator;
|
||||||
|
use Symfony\Component\Routing\Generator\Dumper\CompiledUrlGeneratorDumper;
|
||||||
|
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
|
||||||
|
use Symfony\Component\Routing\RequestContext;
|
||||||
|
use Symfony\Component\Routing\Route;
|
||||||
|
use Symfony\Component\Routing\RouteCollection;
|
||||||
|
|
||||||
|
class CompiledUrlGeneratorDumperTest extends TestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var RouteCollection
|
||||||
|
*/
|
||||||
|
private $routeCollection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var CompiledUrlGeneratorDumper
|
||||||
|
*/
|
||||||
|
private $generatorDumper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $testTmpFilepath;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $largeTestTmpFilepath;
|
||||||
|
|
||||||
|
protected function setUp()
|
||||||
|
{
|
||||||
|
parent::setUp();
|
||||||
|
|
||||||
|
$this->routeCollection = new RouteCollection();
|
||||||
|
$this->generatorDumper = new CompiledUrlGeneratorDumper($this->routeCollection);
|
||||||
|
$this->testTmpFilepath = sys_get_temp_dir().'/php_generator.'.$this->getName().'.php';
|
||||||
|
$this->largeTestTmpFilepath = sys_get_temp_dir().'/php_generator.'.$this->getName().'.large.php';
|
||||||
|
@unlink($this->testTmpFilepath);
|
||||||
|
@unlink($this->largeTestTmpFilepath);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function tearDown()
|
||||||
|
{
|
||||||
|
parent::tearDown();
|
||||||
|
|
||||||
|
@unlink($this->testTmpFilepath);
|
||||||
|
|
||||||
|
$this->routeCollection = null;
|
||||||
|
$this->generatorDumper = null;
|
||||||
|
$this->testTmpFilepath = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testDumpWithRoutes()
|
||||||
|
{
|
||||||
|
$this->routeCollection->add('Test', new Route('/testing/{foo}'));
|
||||||
|
$this->routeCollection->add('Test2', new Route('/testing2'));
|
||||||
|
|
||||||
|
file_put_contents($this->testTmpFilepath, $this->generatorDumper->dump());
|
||||||
|
|
||||||
|
$projectUrlGenerator = new CompiledUrlGenerator(require $this->testTmpFilepath, new RequestContext('/app.php'));
|
||||||
|
|
||||||
|
$absoluteUrlWithParameter = $projectUrlGenerator->generate('Test', ['foo' => 'bar'], UrlGeneratorInterface::ABSOLUTE_URL);
|
||||||
|
$absoluteUrlWithoutParameter = $projectUrlGenerator->generate('Test2', [], UrlGeneratorInterface::ABSOLUTE_URL);
|
||||||
|
$relativeUrlWithParameter = $projectUrlGenerator->generate('Test', ['foo' => 'bar'], UrlGeneratorInterface::ABSOLUTE_PATH);
|
||||||
|
$relativeUrlWithoutParameter = $projectUrlGenerator->generate('Test2', [], UrlGeneratorInterface::ABSOLUTE_PATH);
|
||||||
|
|
||||||
|
$this->assertEquals('http://localhost/app.php/testing/bar', $absoluteUrlWithParameter);
|
||||||
|
$this->assertEquals('http://localhost/app.php/testing2', $absoluteUrlWithoutParameter);
|
||||||
|
$this->assertEquals('/app.php/testing/bar', $relativeUrlWithParameter);
|
||||||
|
$this->assertEquals('/app.php/testing2', $relativeUrlWithoutParameter);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testDumpWithSimpleLocalizedRoutes()
|
||||||
|
{
|
||||||
|
$this->routeCollection->add('test', (new Route('/foo')));
|
||||||
|
$this->routeCollection->add('test.en', (new Route('/testing/is/fun'))->setDefault('_locale', 'en')->setDefault('_canonical_route', 'test'));
|
||||||
|
$this->routeCollection->add('test.nl', (new Route('/testen/is/leuk'))->setDefault('_locale', 'nl')->setDefault('_canonical_route', 'test'));
|
||||||
|
|
||||||
|
$code = $this->generatorDumper->dump();
|
||||||
|
file_put_contents($this->testTmpFilepath, $code);
|
||||||
|
|
||||||
|
$context = new RequestContext('/app.php');
|
||||||
|
$projectUrlGenerator = new CompiledUrlGenerator(require $this->testTmpFilepath, $context, null, 'en');
|
||||||
|
|
||||||
|
$urlWithDefaultLocale = $projectUrlGenerator->generate('test');
|
||||||
|
$urlWithSpecifiedLocale = $projectUrlGenerator->generate('test', ['_locale' => 'nl']);
|
||||||
|
$context->setParameter('_locale', 'en');
|
||||||
|
$urlWithEnglishContext = $projectUrlGenerator->generate('test');
|
||||||
|
$context->setParameter('_locale', 'nl');
|
||||||
|
$urlWithDutchContext = $projectUrlGenerator->generate('test');
|
||||||
|
|
||||||
|
$this->assertEquals('/app.php/testing/is/fun', $urlWithDefaultLocale);
|
||||||
|
$this->assertEquals('/app.php/testen/is/leuk', $urlWithSpecifiedLocale);
|
||||||
|
$this->assertEquals('/app.php/testing/is/fun', $urlWithEnglishContext);
|
||||||
|
$this->assertEquals('/app.php/testen/is/leuk', $urlWithDutchContext);
|
||||||
|
|
||||||
|
// test with full route name
|
||||||
|
$this->assertEquals('/app.php/testing/is/fun', $projectUrlGenerator->generate('test.en'));
|
||||||
|
|
||||||
|
$context->setParameter('_locale', 'de_DE');
|
||||||
|
// test that it fall backs to another route when there is no matching localized route
|
||||||
|
$this->assertEquals('/app.php/foo', $projectUrlGenerator->generate('test'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @expectedException \Symfony\Component\Routing\Exception\RouteNotFoundException
|
||||||
|
* @expectedExceptionMessage Unable to generate a URL for the named route "test" as such route does not exist.
|
||||||
|
*/
|
||||||
|
public function testDumpWithRouteNotFoundLocalizedRoutes()
|
||||||
|
{
|
||||||
|
$this->routeCollection->add('test.en', (new Route('/testing/is/fun'))->setDefault('_locale', 'en')->setDefault('_canonical_route', 'test'));
|
||||||
|
|
||||||
|
$code = $this->generatorDumper->dump();
|
||||||
|
file_put_contents($this->testTmpFilepath, $code);
|
||||||
|
|
||||||
|
$projectUrlGenerator = new CompiledUrlGenerator(require $this->testTmpFilepath, new RequestContext('/app.php'), null, 'pl_PL');
|
||||||
|
$projectUrlGenerator->generate('test');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testDumpWithFallbackLocaleLocalizedRoutes()
|
||||||
|
{
|
||||||
|
$this->routeCollection->add('test.en', (new Route('/testing/is/fun'))->setDefault('_canonical_route', 'test'));
|
||||||
|
$this->routeCollection->add('test.nl', (new Route('/testen/is/leuk'))->setDefault('_canonical_route', 'test'));
|
||||||
|
$this->routeCollection->add('test.fr', (new Route('/tester/est/amusant'))->setDefault('_canonical_route', 'test'));
|
||||||
|
|
||||||
|
$code = $this->generatorDumper->dump();
|
||||||
|
file_put_contents($this->testTmpFilepath, $code);
|
||||||
|
|
||||||
|
$context = new RequestContext('/app.php');
|
||||||
|
$context->setParameter('_locale', 'en_GB');
|
||||||
|
$projectUrlGenerator = new CompiledUrlGenerator(require $this->testTmpFilepath, $context, null, null);
|
||||||
|
|
||||||
|
// test with context _locale
|
||||||
|
$this->assertEquals('/app.php/testing/is/fun', $projectUrlGenerator->generate('test'));
|
||||||
|
// test with parameters _locale
|
||||||
|
$this->assertEquals('/app.php/testen/is/leuk', $projectUrlGenerator->generate('test', ['_locale' => 'nl_BE']));
|
||||||
|
|
||||||
|
$projectUrlGenerator = new CompiledUrlGenerator(require $this->testTmpFilepath, new RequestContext('/app.php'), null, 'fr_CA');
|
||||||
|
// test with default locale
|
||||||
|
$this->assertEquals('/app.php/tester/est/amusant', $projectUrlGenerator->generate('test'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testDumpWithTooManyRoutes()
|
||||||
|
{
|
||||||
|
$this->routeCollection->add('Test', new Route('/testing/{foo}'));
|
||||||
|
for ($i = 0; $i < 32769; ++$i) {
|
||||||
|
$this->routeCollection->add('route_'.$i, new Route('/route_'.$i));
|
||||||
|
}
|
||||||
|
$this->routeCollection->add('Test2', new Route('/testing2'));
|
||||||
|
|
||||||
|
file_put_contents($this->largeTestTmpFilepath, $this->generatorDumper->dump());
|
||||||
|
$this->routeCollection = $this->generatorDumper = null;
|
||||||
|
|
||||||
|
$projectUrlGenerator = new CompiledUrlGenerator(require $this->largeTestTmpFilepath, new RequestContext('/app.php'));
|
||||||
|
|
||||||
|
$absoluteUrlWithParameter = $projectUrlGenerator->generate('Test', ['foo' => 'bar'], UrlGeneratorInterface::ABSOLUTE_URL);
|
||||||
|
$absoluteUrlWithoutParameter = $projectUrlGenerator->generate('Test2', [], UrlGeneratorInterface::ABSOLUTE_URL);
|
||||||
|
$relativeUrlWithParameter = $projectUrlGenerator->generate('Test', ['foo' => 'bar'], UrlGeneratorInterface::ABSOLUTE_PATH);
|
||||||
|
$relativeUrlWithoutParameter = $projectUrlGenerator->generate('Test2', [], UrlGeneratorInterface::ABSOLUTE_PATH);
|
||||||
|
|
||||||
|
$this->assertEquals('http://localhost/app.php/testing/bar', $absoluteUrlWithParameter);
|
||||||
|
$this->assertEquals('http://localhost/app.php/testing2', $absoluteUrlWithoutParameter);
|
||||||
|
$this->assertEquals('/app.php/testing/bar', $relativeUrlWithParameter);
|
||||||
|
$this->assertEquals('/app.php/testing2', $relativeUrlWithoutParameter);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @expectedException \InvalidArgumentException
|
||||||
|
*/
|
||||||
|
public function testDumpWithoutRoutes()
|
||||||
|
{
|
||||||
|
file_put_contents($this->testTmpFilepath, $this->generatorDumper->dump());
|
||||||
|
|
||||||
|
$projectUrlGenerator = new CompiledUrlGenerator(require $this->testTmpFilepath, new RequestContext('/app.php'));
|
||||||
|
|
||||||
|
$projectUrlGenerator->generate('Test', []);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @expectedException \Symfony\Component\Routing\Exception\RouteNotFoundException
|
||||||
|
*/
|
||||||
|
public function testGenerateNonExistingRoute()
|
||||||
|
{
|
||||||
|
$this->routeCollection->add('Test', new Route('/test'));
|
||||||
|
|
||||||
|
file_put_contents($this->testTmpFilepath, $this->generatorDumper->dump());
|
||||||
|
|
||||||
|
$projectUrlGenerator = new CompiledUrlGenerator(require $this->testTmpFilepath, new RequestContext());
|
||||||
|
$url = $projectUrlGenerator->generate('NonExisting', []);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testDumpForRouteWithDefaults()
|
||||||
|
{
|
||||||
|
$this->routeCollection->add('Test', new Route('/testing/{foo}', ['foo' => 'bar']));
|
||||||
|
|
||||||
|
file_put_contents($this->testTmpFilepath, $this->generatorDumper->dump());
|
||||||
|
|
||||||
|
$projectUrlGenerator = new CompiledUrlGenerator(require $this->testTmpFilepath, new RequestContext());
|
||||||
|
$url = $projectUrlGenerator->generate('Test', []);
|
||||||
|
|
||||||
|
$this->assertEquals('/testing', $url);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testDumpWithSchemeRequirement()
|
||||||
|
{
|
||||||
|
$this->routeCollection->add('Test1', new Route('/testing', [], [], [], '', ['ftp', 'https']));
|
||||||
|
|
||||||
|
file_put_contents($this->testTmpFilepath, $this->generatorDumper->dump());
|
||||||
|
|
||||||
|
$projectUrlGenerator = new CompiledUrlGenerator(require $this->testTmpFilepath, new RequestContext('/app.php'));
|
||||||
|
|
||||||
|
$absoluteUrl = $projectUrlGenerator->generate('Test1', [], UrlGeneratorInterface::ABSOLUTE_URL);
|
||||||
|
$relativeUrl = $projectUrlGenerator->generate('Test1', [], UrlGeneratorInterface::ABSOLUTE_PATH);
|
||||||
|
|
||||||
|
$this->assertEquals('ftp://localhost/app.php/testing', $absoluteUrl);
|
||||||
|
$this->assertEquals('ftp://localhost/app.php/testing', $relativeUrl);
|
||||||
|
|
||||||
|
$projectUrlGenerator = new CompiledUrlGenerator(require $this->testTmpFilepath, new RequestContext('/app.php', 'GET', 'localhost', 'https'));
|
||||||
|
|
||||||
|
$absoluteUrl = $projectUrlGenerator->generate('Test1', [], UrlGeneratorInterface::ABSOLUTE_URL);
|
||||||
|
$relativeUrl = $projectUrlGenerator->generate('Test1', [], UrlGeneratorInterface::ABSOLUTE_PATH);
|
||||||
|
|
||||||
|
$this->assertEquals('https://localhost/app.php/testing', $absoluteUrl);
|
||||||
|
$this->assertEquals('/app.php/testing', $relativeUrl);
|
||||||
|
}
|
||||||
|
}
|
@ -18,6 +18,9 @@ use Symfony\Component\Routing\RequestContext;
|
|||||||
use Symfony\Component\Routing\Route;
|
use Symfony\Component\Routing\Route;
|
||||||
use Symfony\Component\Routing\RouteCollection;
|
use Symfony\Component\Routing\RouteCollection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @group legacy
|
||||||
|
*/
|
||||||
class PhpGeneratorDumperTest extends TestCase
|
class PhpGeneratorDumperTest extends TestCase
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
|
@ -0,0 +1,40 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Component\Routing\Tests\Matcher;
|
||||||
|
|
||||||
|
use Symfony\Component\Routing\Matcher\CompiledUrlMatcher;
|
||||||
|
use Symfony\Component\Routing\Matcher\Dumper\CompiledUrlMatcherDumper;
|
||||||
|
use Symfony\Component\Routing\Matcher\RedirectableUrlMatcherInterface;
|
||||||
|
use Symfony\Component\Routing\RequestContext;
|
||||||
|
use Symfony\Component\Routing\RouteCollection;
|
||||||
|
|
||||||
|
class CompiledRedirectableUrlMatcherTest extends RedirectableUrlMatcherTest
|
||||||
|
{
|
||||||
|
protected function getUrlMatcher(RouteCollection $routes, RequestContext $context = null)
|
||||||
|
{
|
||||||
|
$dumper = new CompiledUrlMatcherDumper($routes);
|
||||||
|
$compiledRoutes = $dumper->getCompiledRoutes();
|
||||||
|
|
||||||
|
return $this->getMockBuilder(TestCompiledRedirectableUrlMatcher::class)
|
||||||
|
->setConstructorArgs([$compiledRoutes, $context ?: new RequestContext()])
|
||||||
|
->setMethods(['redirect'])
|
||||||
|
->getMock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class TestCompiledRedirectableUrlMatcher extends CompiledUrlMatcher implements RedirectableUrlMatcherInterface
|
||||||
|
{
|
||||||
|
public function redirect($path, $route, $scheme = null)
|
||||||
|
{
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,27 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Component\Routing\Tests\Matcher;
|
||||||
|
|
||||||
|
use Symfony\Component\Routing\Matcher\CompiledUrlMatcher;
|
||||||
|
use Symfony\Component\Routing\Matcher\Dumper\CompiledUrlMatcherDumper;
|
||||||
|
use Symfony\Component\Routing\RequestContext;
|
||||||
|
use Symfony\Component\Routing\RouteCollection;
|
||||||
|
|
||||||
|
class CompiledUrlMatcherTest extends UrlMatcherTest
|
||||||
|
{
|
||||||
|
protected function getUrlMatcher(RouteCollection $routes, RequestContext $context = null)
|
||||||
|
{
|
||||||
|
$dumper = new CompiledUrlMatcherDumper($routes);
|
||||||
|
|
||||||
|
return new CompiledUrlMatcher($dumper->getCompiledRoutes(), $context ?: new RequestContext());
|
||||||
|
}
|
||||||
|
}
|
@ -17,6 +17,9 @@ use Symfony\Component\Routing\Matcher\UrlMatcher;
|
|||||||
use Symfony\Component\Routing\RequestContext;
|
use Symfony\Component\Routing\RequestContext;
|
||||||
use Symfony\Component\Routing\RouteCollection;
|
use Symfony\Component\Routing\RouteCollection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @group legacy
|
||||||
|
*/
|
||||||
class DumpedRedirectableUrlMatcherTest extends RedirectableUrlMatcherTest
|
class DumpedRedirectableUrlMatcherTest extends RedirectableUrlMatcherTest
|
||||||
{
|
{
|
||||||
protected function getUrlMatcher(RouteCollection $routes, RequestContext $context = null)
|
protected function getUrlMatcher(RouteCollection $routes, RequestContext $context = null)
|
||||||
|
@ -15,6 +15,9 @@ use Symfony\Component\Routing\Matcher\Dumper\PhpMatcherDumper;
|
|||||||
use Symfony\Component\Routing\RequestContext;
|
use Symfony\Component\Routing\RequestContext;
|
||||||
use Symfony\Component\Routing\RouteCollection;
|
use Symfony\Component\Routing\RouteCollection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @group legacy
|
||||||
|
*/
|
||||||
class DumpedUrlMatcherTest extends UrlMatcherTest
|
class DumpedUrlMatcherTest extends UrlMatcherTest
|
||||||
{
|
{
|
||||||
protected function getUrlMatcher(RouteCollection $routes, RequestContext $context = null)
|
protected function getUrlMatcher(RouteCollection $routes, RequestContext $context = null)
|
||||||
|
@ -0,0 +1,496 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Component\Routing\Tests\Matcher\Dumper;
|
||||||
|
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use Symfony\Component\Routing\Matcher\CompiledUrlMatcher;
|
||||||
|
use Symfony\Component\Routing\Matcher\Dumper\CompiledUrlMatcherDumper;
|
||||||
|
use Symfony\Component\Routing\Matcher\RedirectableUrlMatcherInterface;
|
||||||
|
use Symfony\Component\Routing\RequestContext;
|
||||||
|
use Symfony\Component\Routing\Route;
|
||||||
|
use Symfony\Component\Routing\RouteCollection;
|
||||||
|
|
||||||
|
class CompiledUrlMatcherDumperTest extends TestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $dumpPath;
|
||||||
|
|
||||||
|
protected function setUp()
|
||||||
|
{
|
||||||
|
parent::setUp();
|
||||||
|
|
||||||
|
$this->dumpPath = sys_get_temp_dir().\DIRECTORY_SEPARATOR.'php_matcher.'.uniqid('CompiledUrlMatcher').'.php';
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function tearDown()
|
||||||
|
{
|
||||||
|
parent::tearDown();
|
||||||
|
|
||||||
|
@unlink($this->dumpPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testRedirectPreservesUrlEncoding()
|
||||||
|
{
|
||||||
|
$collection = new RouteCollection();
|
||||||
|
$collection->add('foo', new Route('/foo:bar/'));
|
||||||
|
|
||||||
|
$matcher = $this->generateDumpedMatcher($collection);
|
||||||
|
$matcher->expects($this->once())->method('redirect')->with('/foo%3Abar/', 'foo')->willReturn([]);
|
||||||
|
|
||||||
|
$matcher->match('/foo%3Abar');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider getRouteCollections
|
||||||
|
*/
|
||||||
|
public function testDump(RouteCollection $collection, $fixture)
|
||||||
|
{
|
||||||
|
$basePath = __DIR__.'/../../Fixtures/dumper/';
|
||||||
|
|
||||||
|
$dumper = new CompiledUrlMatcherDumper($collection);
|
||||||
|
$this->assertStringEqualsFile($basePath.$fixture, $dumper->dump());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getRouteCollections()
|
||||||
|
{
|
||||||
|
/* test case 1 */
|
||||||
|
|
||||||
|
$collection = new RouteCollection();
|
||||||
|
|
||||||
|
$collection->add('overridden', new Route('/overridden'));
|
||||||
|
|
||||||
|
// defaults and requirements
|
||||||
|
$collection->add('foo', new Route(
|
||||||
|
'/foo/{bar}',
|
||||||
|
['def' => 'test'],
|
||||||
|
['bar' => 'baz|symfony']
|
||||||
|
));
|
||||||
|
// method requirement
|
||||||
|
$collection->add('bar', new Route(
|
||||||
|
'/bar/{foo}',
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
'',
|
||||||
|
[],
|
||||||
|
['GET', 'head']
|
||||||
|
));
|
||||||
|
// GET method requirement automatically adds HEAD as valid
|
||||||
|
$collection->add('barhead', new Route(
|
||||||
|
'/barhead/{foo}',
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
'',
|
||||||
|
[],
|
||||||
|
['GET']
|
||||||
|
));
|
||||||
|
// simple
|
||||||
|
$collection->add('baz', new Route(
|
||||||
|
'/test/baz'
|
||||||
|
));
|
||||||
|
// simple with extension
|
||||||
|
$collection->add('baz2', new Route(
|
||||||
|
'/test/baz.html'
|
||||||
|
));
|
||||||
|
// trailing slash
|
||||||
|
$collection->add('baz3', new Route(
|
||||||
|
'/test/baz3/'
|
||||||
|
));
|
||||||
|
// trailing slash with variable
|
||||||
|
$collection->add('baz4', new Route(
|
||||||
|
'/test/{foo}/'
|
||||||
|
));
|
||||||
|
// trailing slash and method
|
||||||
|
$collection->add('baz5', new Route(
|
||||||
|
'/test/{foo}/',
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
'',
|
||||||
|
[],
|
||||||
|
['post']
|
||||||
|
));
|
||||||
|
// complex name
|
||||||
|
$collection->add('baz.baz6', new Route(
|
||||||
|
'/test/{foo}/',
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
'',
|
||||||
|
[],
|
||||||
|
['put']
|
||||||
|
));
|
||||||
|
// defaults without variable
|
||||||
|
$collection->add('foofoo', new Route(
|
||||||
|
'/foofoo',
|
||||||
|
['def' => 'test']
|
||||||
|
));
|
||||||
|
// pattern with quotes
|
||||||
|
$collection->add('quoter', new Route(
|
||||||
|
'/{quoter}',
|
||||||
|
[],
|
||||||
|
['quoter' => '[\']+']
|
||||||
|
));
|
||||||
|
// space in pattern
|
||||||
|
$collection->add('space', new Route(
|
||||||
|
'/spa ce'
|
||||||
|
));
|
||||||
|
|
||||||
|
// prefixes
|
||||||
|
$collection1 = new RouteCollection();
|
||||||
|
$collection1->add('overridden', new Route('/overridden1'));
|
||||||
|
$collection1->add('foo1', (new Route('/{foo}'))->setMethods('PUT'));
|
||||||
|
$collection1->add('bar1', new Route('/{bar}'));
|
||||||
|
$collection1->addPrefix('/b\'b');
|
||||||
|
$collection2 = new RouteCollection();
|
||||||
|
$collection2->addCollection($collection1);
|
||||||
|
$collection2->add('overridden', new Route('/{var}', [], ['var' => '.*']));
|
||||||
|
$collection1 = new RouteCollection();
|
||||||
|
$collection1->add('foo2', new Route('/{foo1}'));
|
||||||
|
$collection1->add('bar2', new Route('/{bar1}'));
|
||||||
|
$collection1->addPrefix('/b\'b');
|
||||||
|
$collection2->addCollection($collection1);
|
||||||
|
$collection2->addPrefix('/a');
|
||||||
|
$collection->addCollection($collection2);
|
||||||
|
|
||||||
|
// overridden through addCollection() and multiple sub-collections with no own prefix
|
||||||
|
$collection1 = new RouteCollection();
|
||||||
|
$collection1->add('overridden2', new Route('/old'));
|
||||||
|
$collection1->add('helloWorld', new Route('/hello/{who}', ['who' => 'World!']));
|
||||||
|
$collection2 = new RouteCollection();
|
||||||
|
$collection3 = new RouteCollection();
|
||||||
|
$collection3->add('overridden2', new Route('/new'));
|
||||||
|
$collection3->add('hey', new Route('/hey/'));
|
||||||
|
$collection2->addCollection($collection3);
|
||||||
|
$collection1->addCollection($collection2);
|
||||||
|
$collection1->addPrefix('/multi');
|
||||||
|
$collection->addCollection($collection1);
|
||||||
|
|
||||||
|
// "dynamic" prefix
|
||||||
|
$collection1 = new RouteCollection();
|
||||||
|
$collection1->add('foo3', new Route('/{foo}'));
|
||||||
|
$collection1->add('bar3', new Route('/{bar}'));
|
||||||
|
$collection1->addPrefix('/b');
|
||||||
|
$collection1->addPrefix('{_locale}');
|
||||||
|
$collection->addCollection($collection1);
|
||||||
|
|
||||||
|
// route between collections
|
||||||
|
$collection->add('ababa', new Route('/ababa'));
|
||||||
|
|
||||||
|
// collection with static prefix but only one route
|
||||||
|
$collection1 = new RouteCollection();
|
||||||
|
$collection1->add('foo4', new Route('/{foo}'));
|
||||||
|
$collection1->addPrefix('/aba');
|
||||||
|
$collection->addCollection($collection1);
|
||||||
|
|
||||||
|
// prefix and host
|
||||||
|
|
||||||
|
$collection1 = new RouteCollection();
|
||||||
|
|
||||||
|
$route1 = new Route('/route1', [], [], [], 'a.example.com');
|
||||||
|
$collection1->add('route1', $route1);
|
||||||
|
|
||||||
|
$route2 = new Route('/c2/route2', [], [], [], 'a.example.com');
|
||||||
|
$collection1->add('route2', $route2);
|
||||||
|
|
||||||
|
$route3 = new Route('/c2/route3', [], [], [], 'b.example.com');
|
||||||
|
$collection1->add('route3', $route3);
|
||||||
|
|
||||||
|
$route4 = new Route('/route4', [], [], [], 'a.example.com');
|
||||||
|
$collection1->add('route4', $route4);
|
||||||
|
|
||||||
|
$route5 = new Route('/route5', [], [], [], 'c.example.com');
|
||||||
|
$collection1->add('route5', $route5);
|
||||||
|
|
||||||
|
$route6 = new Route('/route6', [], [], [], null);
|
||||||
|
$collection1->add('route6', $route6);
|
||||||
|
|
||||||
|
$collection->addCollection($collection1);
|
||||||
|
|
||||||
|
// host and variables
|
||||||
|
|
||||||
|
$collection1 = new RouteCollection();
|
||||||
|
|
||||||
|
$route11 = new Route('/route11', [], [], [], '{var1}.example.com');
|
||||||
|
$collection1->add('route11', $route11);
|
||||||
|
|
||||||
|
$route12 = new Route('/route12', ['var1' => 'val'], [], [], '{var1}.example.com');
|
||||||
|
$collection1->add('route12', $route12);
|
||||||
|
|
||||||
|
$route13 = new Route('/route13/{name}', [], [], [], '{var1}.example.com');
|
||||||
|
$collection1->add('route13', $route13);
|
||||||
|
|
||||||
|
$route14 = new Route('/route14/{name}', ['var1' => 'val'], [], [], '{var1}.example.com');
|
||||||
|
$collection1->add('route14', $route14);
|
||||||
|
|
||||||
|
$route15 = new Route('/route15/{name}', [], [], [], 'c.example.com');
|
||||||
|
$collection1->add('route15', $route15);
|
||||||
|
|
||||||
|
$route16 = new Route('/route16/{name}', ['var1' => 'val'], [], [], null);
|
||||||
|
$collection1->add('route16', $route16);
|
||||||
|
|
||||||
|
$route17 = new Route('/route17', [], [], [], null);
|
||||||
|
$collection1->add('route17', $route17);
|
||||||
|
|
||||||
|
$collection->addCollection($collection1);
|
||||||
|
|
||||||
|
// multiple sub-collections with a single route and a prefix each
|
||||||
|
$collection1 = new RouteCollection();
|
||||||
|
$collection1->add('a', new Route('/a...'));
|
||||||
|
$collection2 = new RouteCollection();
|
||||||
|
$collection2->add('b', new Route('/{var}'));
|
||||||
|
$collection3 = new RouteCollection();
|
||||||
|
$collection3->add('c', new Route('/{var}'));
|
||||||
|
$collection3->addPrefix('/c');
|
||||||
|
$collection2->addCollection($collection3);
|
||||||
|
$collection2->addPrefix('/b');
|
||||||
|
$collection1->addCollection($collection2);
|
||||||
|
$collection1->addPrefix('/a');
|
||||||
|
$collection->addCollection($collection1);
|
||||||
|
|
||||||
|
/* test case 2 */
|
||||||
|
|
||||||
|
$redirectCollection = clone $collection;
|
||||||
|
|
||||||
|
// force HTTPS redirection
|
||||||
|
$redirectCollection->add('secure', new Route(
|
||||||
|
'/secure',
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
'',
|
||||||
|
['https']
|
||||||
|
));
|
||||||
|
|
||||||
|
// force HTTP redirection
|
||||||
|
$redirectCollection->add('nonsecure', new Route(
|
||||||
|
'/nonsecure',
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
'',
|
||||||
|
['http']
|
||||||
|
));
|
||||||
|
|
||||||
|
/* test case 3 */
|
||||||
|
|
||||||
|
$rootprefixCollection = new RouteCollection();
|
||||||
|
$rootprefixCollection->add('static', new Route('/test'));
|
||||||
|
$rootprefixCollection->add('dynamic', new Route('/{var}'));
|
||||||
|
$rootprefixCollection->addPrefix('rootprefix');
|
||||||
|
$route = new Route('/with-condition');
|
||||||
|
$route->setCondition('context.getMethod() == "GET"');
|
||||||
|
$rootprefixCollection->add('with-condition', $route);
|
||||||
|
|
||||||
|
/* test case 4 */
|
||||||
|
$headMatchCasesCollection = new RouteCollection();
|
||||||
|
$headMatchCasesCollection->add('just_head', new Route(
|
||||||
|
'/just_head',
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
'',
|
||||||
|
[],
|
||||||
|
['HEAD']
|
||||||
|
));
|
||||||
|
$headMatchCasesCollection->add('head_and_get', new Route(
|
||||||
|
'/head_and_get',
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
'',
|
||||||
|
[],
|
||||||
|
['HEAD', 'GET']
|
||||||
|
));
|
||||||
|
$headMatchCasesCollection->add('get_and_head', new Route(
|
||||||
|
'/get_and_head',
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
'',
|
||||||
|
[],
|
||||||
|
['GET', 'HEAD']
|
||||||
|
));
|
||||||
|
$headMatchCasesCollection->add('post_and_head', new Route(
|
||||||
|
'/post_and_head',
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
'',
|
||||||
|
[],
|
||||||
|
['POST', 'HEAD']
|
||||||
|
));
|
||||||
|
$headMatchCasesCollection->add('put_and_post', new Route(
|
||||||
|
'/put_and_post',
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
'',
|
||||||
|
[],
|
||||||
|
['PUT', 'POST']
|
||||||
|
));
|
||||||
|
$headMatchCasesCollection->add('put_and_get_and_head', new Route(
|
||||||
|
'/put_and_post',
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
'',
|
||||||
|
[],
|
||||||
|
['PUT', 'GET', 'HEAD']
|
||||||
|
));
|
||||||
|
|
||||||
|
/* test case 5 */
|
||||||
|
$groupOptimisedCollection = new RouteCollection();
|
||||||
|
$groupOptimisedCollection->add('a_first', new Route('/a/11'));
|
||||||
|
$groupOptimisedCollection->add('a_second', new Route('/a/22'));
|
||||||
|
$groupOptimisedCollection->add('a_third', new Route('/a/333'));
|
||||||
|
$groupOptimisedCollection->add('a_wildcard', new Route('/{param}'));
|
||||||
|
$groupOptimisedCollection->add('a_fourth', new Route('/a/44/'));
|
||||||
|
$groupOptimisedCollection->add('a_fifth', new Route('/a/55/'));
|
||||||
|
$groupOptimisedCollection->add('a_sixth', new Route('/a/66/'));
|
||||||
|
$groupOptimisedCollection->add('nested_wildcard', new Route('/nested/{param}'));
|
||||||
|
$groupOptimisedCollection->add('nested_a', new Route('/nested/group/a/'));
|
||||||
|
$groupOptimisedCollection->add('nested_b', new Route('/nested/group/b/'));
|
||||||
|
$groupOptimisedCollection->add('nested_c', new Route('/nested/group/c/'));
|
||||||
|
|
||||||
|
$groupOptimisedCollection->add('slashed_a', new Route('/slashed/group/'));
|
||||||
|
$groupOptimisedCollection->add('slashed_b', new Route('/slashed/group/b/'));
|
||||||
|
$groupOptimisedCollection->add('slashed_c', new Route('/slashed/group/c/'));
|
||||||
|
|
||||||
|
/* test case 6 & 7 */
|
||||||
|
$trailingSlashCollection = new RouteCollection();
|
||||||
|
$trailingSlashCollection->add('simple_trailing_slash_no_methods', new Route('/trailing/simple/no-methods/', [], [], [], '', [], []));
|
||||||
|
$trailingSlashCollection->add('simple_trailing_slash_GET_method', new Route('/trailing/simple/get-method/', [], [], [], '', [], ['GET']));
|
||||||
|
$trailingSlashCollection->add('simple_trailing_slash_HEAD_method', new Route('/trailing/simple/head-method/', [], [], [], '', [], ['HEAD']));
|
||||||
|
$trailingSlashCollection->add('simple_trailing_slash_POST_method', new Route('/trailing/simple/post-method/', [], [], [], '', [], ['POST']));
|
||||||
|
$trailingSlashCollection->add('regex_trailing_slash_no_methods', new Route('/trailing/regex/no-methods/{param}/', [], [], [], '', [], []));
|
||||||
|
$trailingSlashCollection->add('regex_trailing_slash_GET_method', new Route('/trailing/regex/get-method/{param}/', [], [], [], '', [], ['GET']));
|
||||||
|
$trailingSlashCollection->add('regex_trailing_slash_HEAD_method', new Route('/trailing/regex/head-method/{param}/', [], [], [], '', [], ['HEAD']));
|
||||||
|
$trailingSlashCollection->add('regex_trailing_slash_POST_method', new Route('/trailing/regex/post-method/{param}/', [], [], [], '', [], ['POST']));
|
||||||
|
|
||||||
|
$trailingSlashCollection->add('simple_not_trailing_slash_no_methods', new Route('/not-trailing/simple/no-methods', [], [], [], '', [], []));
|
||||||
|
$trailingSlashCollection->add('simple_not_trailing_slash_GET_method', new Route('/not-trailing/simple/get-method', [], [], [], '', [], ['GET']));
|
||||||
|
$trailingSlashCollection->add('simple_not_trailing_slash_HEAD_method', new Route('/not-trailing/simple/head-method', [], [], [], '', [], ['HEAD']));
|
||||||
|
$trailingSlashCollection->add('simple_not_trailing_slash_POST_method', new Route('/not-trailing/simple/post-method', [], [], [], '', [], ['POST']));
|
||||||
|
$trailingSlashCollection->add('regex_not_trailing_slash_no_methods', new Route('/not-trailing/regex/no-methods/{param}', [], [], [], '', [], []));
|
||||||
|
$trailingSlashCollection->add('regex_not_trailing_slash_GET_method', new Route('/not-trailing/regex/get-method/{param}', [], [], [], '', [], ['GET']));
|
||||||
|
$trailingSlashCollection->add('regex_not_trailing_slash_HEAD_method', new Route('/not-trailing/regex/head-method/{param}', [], [], [], '', [], ['HEAD']));
|
||||||
|
$trailingSlashCollection->add('regex_not_trailing_slash_POST_method', new Route('/not-trailing/regex/post-method/{param}', [], [], [], '', [], ['POST']));
|
||||||
|
|
||||||
|
/* test case 8 */
|
||||||
|
$unicodeCollection = new RouteCollection();
|
||||||
|
$unicodeCollection->add('a', new Route('/{a}', [], ['a' => 'a'], ['utf8' => false]));
|
||||||
|
$unicodeCollection->add('b', new Route('/{a}', [], ['a' => '.'], ['utf8' => true]));
|
||||||
|
$unicodeCollection->add('c', new Route('/{a}', [], ['a' => '.'], ['utf8' => false]));
|
||||||
|
|
||||||
|
/* test case 9 */
|
||||||
|
$hostTreeCollection = new RouteCollection();
|
||||||
|
$hostTreeCollection->add('a', (new Route('/'))->setHost('{d}.e.c.b.a'));
|
||||||
|
$hostTreeCollection->add('b', (new Route('/'))->setHost('d.c.b.a'));
|
||||||
|
$hostTreeCollection->add('c', (new Route('/'))->setHost('{e}.e.c.b.a'));
|
||||||
|
|
||||||
|
/* test case 10 */
|
||||||
|
$chunkedCollection = new RouteCollection();
|
||||||
|
for ($i = 0; $i < 1000; ++$i) {
|
||||||
|
$h = substr(md5($i), 0, 6);
|
||||||
|
$chunkedCollection->add('_'.$i, new Route('/'.$h.'/{a}/{b}/{c}/'.$h));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* test case 11 */
|
||||||
|
$demoCollection = new RouteCollection();
|
||||||
|
$demoCollection->add('a', new Route('/admin/post/'));
|
||||||
|
$demoCollection->add('b', new Route('/admin/post/new'));
|
||||||
|
$demoCollection->add('c', (new Route('/admin/post/{id}'))->setRequirements(['id' => '\d+']));
|
||||||
|
$demoCollection->add('d', (new Route('/admin/post/{id}/edit'))->setRequirements(['id' => '\d+']));
|
||||||
|
$demoCollection->add('e', (new Route('/admin/post/{id}/delete'))->setRequirements(['id' => '\d+']));
|
||||||
|
$demoCollection->add('f', new Route('/blog/'));
|
||||||
|
$demoCollection->add('g', new Route('/blog/rss.xml'));
|
||||||
|
$demoCollection->add('h', (new Route('/blog/page/{page}'))->setRequirements(['id' => '\d+']));
|
||||||
|
$demoCollection->add('i', (new Route('/blog/posts/{page}'))->setRequirements(['id' => '\d+']));
|
||||||
|
$demoCollection->add('j', (new Route('/blog/comments/{id}/new'))->setRequirements(['id' => '\d+']));
|
||||||
|
$demoCollection->add('k', new Route('/blog/search'));
|
||||||
|
$demoCollection->add('l', new Route('/login'));
|
||||||
|
$demoCollection->add('m', new Route('/logout'));
|
||||||
|
$demoCollection->addPrefix('/{_locale}');
|
||||||
|
$demoCollection->add('n', new Route('/{_locale}'));
|
||||||
|
$demoCollection->addRequirements(['_locale' => 'en|fr']);
|
||||||
|
$demoCollection->addDefaults(['_locale' => 'en']);
|
||||||
|
|
||||||
|
/* test case 12 */
|
||||||
|
$suffixCollection = new RouteCollection();
|
||||||
|
$suffixCollection->add('r1', new Route('abc{foo}/1'));
|
||||||
|
$suffixCollection->add('r2', new Route('abc{foo}/2'));
|
||||||
|
$suffixCollection->add('r10', new Route('abc{foo}/10'));
|
||||||
|
$suffixCollection->add('r20', new Route('abc{foo}/20'));
|
||||||
|
$suffixCollection->add('r100', new Route('abc{foo}/100'));
|
||||||
|
$suffixCollection->add('r200', new Route('abc{foo}/200'));
|
||||||
|
|
||||||
|
/* test case 13 */
|
||||||
|
$hostCollection = new RouteCollection();
|
||||||
|
$hostCollection->add('r1', (new Route('abc{foo}'))->setHost('{foo}.exampple.com'));
|
||||||
|
$hostCollection->add('r2', (new Route('abc{foo}'))->setHost('{foo}.exampple.com'));
|
||||||
|
|
||||||
|
return [
|
||||||
|
[new RouteCollection(), 'compiled_url_matcher0.php'],
|
||||||
|
[$collection, 'compiled_url_matcher1.php'],
|
||||||
|
[$redirectCollection, 'compiled_url_matcher2.php'],
|
||||||
|
[$rootprefixCollection, 'compiled_url_matcher3.php'],
|
||||||
|
[$headMatchCasesCollection, 'compiled_url_matcher4.php'],
|
||||||
|
[$groupOptimisedCollection, 'compiled_url_matcher5.php'],
|
||||||
|
[$trailingSlashCollection, 'compiled_url_matcher6.php'],
|
||||||
|
[$trailingSlashCollection, 'compiled_url_matcher7.php'],
|
||||||
|
[$unicodeCollection, 'compiled_url_matcher8.php'],
|
||||||
|
[$hostTreeCollection, 'compiled_url_matcher9.php'],
|
||||||
|
[$chunkedCollection, 'compiled_url_matcher10.php'],
|
||||||
|
[$demoCollection, 'compiled_url_matcher11.php'],
|
||||||
|
[$suffixCollection, 'compiled_url_matcher12.php'],
|
||||||
|
[$hostCollection, 'compiled_url_matcher13.php'],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
private function generateDumpedMatcher(RouteCollection $collection)
|
||||||
|
{
|
||||||
|
$dumper = new CompiledUrlMatcherDumper($collection);
|
||||||
|
$code = $dumper->dump();
|
||||||
|
|
||||||
|
file_put_contents($this->dumpPath, $code);
|
||||||
|
$compiledRoutes = require $this->dumpPath;
|
||||||
|
|
||||||
|
return $this->getMockBuilder(TestCompiledUrlMatcher::class)
|
||||||
|
->setConstructorArgs([$compiledRoutes, new RequestContext()])
|
||||||
|
->setMethods(['redirect'])
|
||||||
|
->getMock();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @expectedException \InvalidArgumentException
|
||||||
|
* @expectedExceptionMessage Symfony\Component\Routing\Route cannot contain objects
|
||||||
|
*/
|
||||||
|
public function testGenerateDumperMatcherWithObject()
|
||||||
|
{
|
||||||
|
$routeCollection = new RouteCollection();
|
||||||
|
$routeCollection->add('_', new Route('/', [new \stdClass()]));
|
||||||
|
$dumper = new CompiledUrlMatcherDumper($routeCollection);
|
||||||
|
$dumper->dump();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class TestCompiledUrlMatcher extends CompiledUrlMatcher implements RedirectableUrlMatcherInterface
|
||||||
|
{
|
||||||
|
public function redirect($path, $route, $scheme = null)
|
||||||
|
{
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
@ -19,6 +19,9 @@ use Symfony\Component\Routing\RequestContext;
|
|||||||
use Symfony\Component\Routing\Route;
|
use Symfony\Component\Routing\Route;
|
||||||
use Symfony\Component\Routing\RouteCollection;
|
use Symfony\Component\Routing\RouteCollection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @group legacy
|
||||||
|
*/
|
||||||
class PhpMatcherDumperTest extends TestCase
|
class PhpMatcherDumperTest extends TestCase
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
|
Reference in New Issue
Block a user