merged branch Tobion/generator-dumper (PR #3894)
Commits -------382b083
[Routing] improved generated class by PhpGeneratorDumper27a05f4
[Routing] small optimization of PhpGeneratorDumper Discussion ---------- [Routing] improved PhpGeneratorDumper Test pass: yes BC break: no The first commit only replaces arrays with strings and makes some cosmetic changes, so that it's more readable. This makes the `PhpGeneratorDumper` consistent in style with `PhpMatcherDumper` that I fixed recently and should slightly improve performance of the generation of the class. The second commit changes the output of the `PhpGeneratorDumper->dump` and tries to optimize the resulting class that is used to generate URLs. It's best explained with an example. Before my changes: ```php class ProjectUrlGenerator extends Symfony\Component\Routing\Generator\UrlGenerator { static private $declaredRouteNames = array( 'Test' => true, 'Test2' => true, ); /** * Constructor. */ public function __construct(RequestContext $context) { $this->context = $context; } public function generate($name, $parameters = array(), $absolute = false) { if (!isset(self::$declaredRouteNames[$name])) { throw new RouteNotFoundException(sprintf('Route "%s" does not exist.', $name)); } $escapedName = str_replace('.', '__', $name); list($variables, $defaults, $requirements, $tokens) = $this->{'get'.$escapedName.'RouteInfo'}(); return $this->doGenerate($variables, $defaults, $requirements, $tokens, $parameters, $name, $absolute); } private function getTestRouteInfo() { return array(array ( 0 => 'foo',), array (), array (), array ( 0 => array ( 0 => 'variable', 1 => '/', 2 => '[^/]+?', 3 => 'foo', ), 1 => array ( 0 => 'text', 1 => '/testing', ),)); } private function getTest2RouteInfo() { return array(array (), array (), array (), array ( 0 => array ( 0 => 'text', 1 => '/testing2', ),)); } } ``` After my changes in second commit: ```php class ProjectUrlGenerator extends Symfony\Component\Routing\Generator\UrlGenerator { static private $declaredRoutes = array( 'Test' => array ( 0 => array ( 0 => 'foo', ), 1 => array ( ), 2 => array ( ), 3 => array ( 0 => array ( 0 => 'variable', 1 => '/', 2 => '[^/]+?', 3 => 'foo', ), 1 => array ( 0 => 'text', 1 => '/testing', ), ),), 'Test2' => array ( 0 => array ( ), 1 => array ( ), 2 => array ( ), 3 => array ( 0 => array ( 0 => 'text', 1 => '/testing2', ), ),), ); /** * Constructor. */ public function __construct(RequestContext $context) { $this->context = $context; } public function generate($name, $parameters = array(), $absolute = false) { if (!isset(self::$declaredRoutes[$name])) { throw new RouteNotFoundException(sprintf('Route "%s" does not exist.', $name)); } list($variables, $defaults, $requirements, $tokens) = self::$declaredRoutes[$name]; return $this->doGenerate($variables, $defaults, $requirements, $tokens, $parameters, $name, $absolute); } } ``` As you can see, there is no need to escape the route name and invoke a special method anymore. Instead the route properties are included in the static route array directly, that existed anyway. Is also easier to read as defined routes and their properties are in the same place.
This commit is contained in:
commit
5ab006aca2
@ -17,6 +17,7 @@ use Symfony\Component\Routing\Route;
|
||||
* PhpGeneratorDumper creates a PHP class able to generate URLs for a given set of routes.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
* @author Tobias Schultze <http://tobion.de>
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
@ -43,92 +44,22 @@ class PhpGeneratorDumper extends GeneratorDumper
|
||||
'base_class' => 'Symfony\\Component\\Routing\\Generator\\UrlGenerator',
|
||||
), $options);
|
||||
|
||||
return
|
||||
$this->startClass($options['class'], $options['base_class']).
|
||||
$this->addConstructor().
|
||||
$this->addGenerator().
|
||||
$this->endClass()
|
||||
;
|
||||
}
|
||||
|
||||
private function addGenerator()
|
||||
{
|
||||
$methods = array();
|
||||
foreach ($this->getRoutes()->all() as $name => $route) {
|
||||
$compiledRoute = $route->compile();
|
||||
|
||||
$variables = str_replace("\n", '', var_export($compiledRoute->getVariables(), true));
|
||||
$defaults = str_replace("\n", '', var_export($compiledRoute->getDefaults(), true));
|
||||
$requirements = str_replace("\n", '', var_export($compiledRoute->getRequirements(), true));
|
||||
$tokens = str_replace("\n", '', var_export($compiledRoute->getTokens(), true));
|
||||
|
||||
$escapedName = str_replace('.', '__', $name);
|
||||
|
||||
$methods[] = <<<EOF
|
||||
private function get{$escapedName}RouteInfo()
|
||||
{
|
||||
return array($variables, $defaults, $requirements, $tokens);
|
||||
}
|
||||
|
||||
EOF
|
||||
;
|
||||
}
|
||||
|
||||
$methods = implode("\n", $methods);
|
||||
|
||||
return <<<EOF
|
||||
|
||||
public function generate(\$name, \$parameters = array(), \$absolute = false)
|
||||
{
|
||||
if (!isset(self::\$declaredRouteNames[\$name])) {
|
||||
throw new RouteNotFoundException(sprintf('Route "%s" does not exist.', \$name));
|
||||
}
|
||||
|
||||
\$escapedName = str_replace('.', '__', \$name);
|
||||
|
||||
list(\$variables, \$defaults, \$requirements, \$tokens) = \$this->{'get'.\$escapedName.'RouteInfo'}();
|
||||
|
||||
return \$this->doGenerate(\$variables, \$defaults, \$requirements, \$tokens, \$parameters, \$name, \$absolute);
|
||||
}
|
||||
|
||||
$methods
|
||||
EOF;
|
||||
}
|
||||
|
||||
private function startClass($class, $baseClass)
|
||||
{
|
||||
$routes = array();
|
||||
foreach ($this->getRoutes()->all() as $name => $route) {
|
||||
$routes[] = " '$name' => true,";
|
||||
}
|
||||
$routes = implode("\n", $routes);
|
||||
|
||||
return <<<EOF
|
||||
<?php
|
||||
|
||||
use Symfony\Component\Routing\RequestContext;
|
||||
use Symfony\Component\Routing\Exception\RouteNotFoundException;
|
||||
|
||||
|
||||
/**
|
||||
* $class
|
||||
* {$options['class']}
|
||||
*
|
||||
* This class has been auto-generated
|
||||
* by the Symfony Routing Component.
|
||||
*/
|
||||
class $class extends $baseClass
|
||||
class {$options['class']} extends {$options['base_class']}
|
||||
{
|
||||
static private \$declaredRouteNames = array(
|
||||
$routes
|
||||
);
|
||||
static private \$declaredRoutes = {$this->generateDeclaredRoutes()};
|
||||
|
||||
|
||||
EOF;
|
||||
}
|
||||
|
||||
private function addConstructor()
|
||||
{
|
||||
return <<<EOF
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
@ -137,14 +68,55 @@ EOF;
|
||||
\$this->context = \$context;
|
||||
}
|
||||
|
||||
{$this->generateGenerateMethod()}
|
||||
}
|
||||
|
||||
EOF;
|
||||
}
|
||||
|
||||
private function endClass()
|
||||
/**
|
||||
* Generates PHP code representing an array of defined routes
|
||||
* together with the routes properties (e.g. requirements).
|
||||
*
|
||||
* @return string PHP code
|
||||
*/
|
||||
private function generateDeclaredRoutes()
|
||||
{
|
||||
$routes = "array(\n";
|
||||
foreach ($this->getRoutes()->all() as $name => $route) {
|
||||
$compiledRoute = $route->compile();
|
||||
|
||||
$properties = array();
|
||||
$properties[] = $compiledRoute->getVariables();
|
||||
$properties[] = $compiledRoute->getDefaults();
|
||||
$properties[] = $compiledRoute->getRequirements();
|
||||
$properties[] = $compiledRoute->getTokens();
|
||||
|
||||
$routes .= sprintf(" '%s' => %s,\n", $name, str_replace("\n", '', var_export($properties, true)));
|
||||
}
|
||||
$routes .= ' )';
|
||||
|
||||
return $routes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates PHP code representing the `generate` method that implements the UrlGeneratorInterface.
|
||||
*
|
||||
* @return string PHP code
|
||||
*/
|
||||
private function generateGenerateMethod()
|
||||
{
|
||||
return <<<EOF
|
||||
}
|
||||
public function generate(\$name, \$parameters = array(), \$absolute = false)
|
||||
{
|
||||
if (!isset(self::\$declaredRoutes[\$name])) {
|
||||
throw new RouteNotFoundException(sprintf('Route "%s" does not exist.', \$name));
|
||||
}
|
||||
|
||||
list(\$variables, \$defaults, \$requirements, \$tokens) = self::\$declaredRoutes[\$name];
|
||||
|
||||
return \$this->doGenerate(\$variables, \$defaults, \$requirements, \$tokens, \$parameters, \$name, \$absolute);
|
||||
}
|
||||
EOF;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user