Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feature #28865 [Routing] allow using compiled matchers and generators…
… without dumping PHP code (nicolas-grekas) This PR was merged into the 4.3-dev branch. Discussion ---------- [Routing] allow using compiled matchers and generators without dumping PHP code | Q | A | ------------- | --- | Branch? | master | Bug fix? | no | New feature? | yes | BC breaks? | no | Deprecations? | yes | Tests pass? | yes | Fixed tickets | #29590 | License | MIT | Doc PR | symfony/symfony-docs#10790 This is a resurrection of #25909 to make matcher+generator dumpers output PHP arrays instead of PHP code. Don't be fooled by the diff stats, it's mostly fixtures. This PR should contribute to making the Routing component easier to use standalone. On the way back from SFLive USA. ![image](https://user-images.githubusercontent.com/243674/46920076-784e1b80-cf9d-11e8-86e7-850fffb409de.png) Commits ------- f0a519a [Routing] allow using compiled matchers and generators without dumping PHP code
- Loading branch information
Showing
51 changed files
with
5,144 additions
and
490 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
39 changes: 39 additions & 0 deletions
39
src/Symfony/Bundle/FrameworkBundle/Routing/RedirectableCompiledUrlMatcher.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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, | ||
]; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
72 changes: 72 additions & 0 deletions
72
src/Symfony/Bundle/FrameworkBundle/Tests/Routing/RedirectableCompiledUrlMatcherTest.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
58 changes: 58 additions & 0 deletions
58
src/Symfony/Component/Routing/Generator/CompiledUrlGenerator.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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); | ||
} | ||
} |
73 changes: 73 additions & 0 deletions
73
src/Symfony/Component/Routing/Generator/Dumper/CompiledUrlGeneratorDumper.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
31 changes: 31 additions & 0 deletions
31
src/Symfony/Component/Routing/Matcher/CompiledUrlMatcher.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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; | ||
} | ||
} |
Oops, something went wrong.