diff --git a/core/lib/Drupal/Core/Routing/DrupalUrlGenerator.php b/core/lib/Drupal/Core/Routing/DrupalUrlGenerator.php new file mode 100644 index 0000000..2d49d0a --- /dev/null +++ b/core/lib/Drupal/Core/Routing/DrupalUrlGenerator.php @@ -0,0 +1,46 @@ + $name)); + $matches = $result->fetchAll(); + + if (count($matches) == 0) { + throw new RouteNotFoundException(sprintf('Route "%s" does not exist.', $name)); + } + + $row = $matches[0]; + + $route = unserialize($row->route); + + //Test fixtures set compiler_class to Drupal\Core\Routing\RouteCompiler + //which produces compiled routes without a getVariables method + //fixing it hardcoded for now. + $route->setOption('compiler_class', '\Symfony\Component\Routing\RouteCompiler'); + + // the Route has a cache of its own and is not recompiled as long as it does not get modified + $compiledRoute = $route->compile(); + + return $this->doGenerate($compiledRoute->getVariables(), $route->getDefaults(), $route->getRequirements(), $compiledRoute->getTokens(), $parameters, $name, $absolute); + } +} diff --git a/core/modules/system/lib/Drupal/system/Tests/Routing/UrlGeneratorTest.php b/core/modules/system/lib/Drupal/system/Tests/Routing/UrlGeneratorTest.php new file mode 100644 index 0000000..acf79fc --- /dev/null +++ b/core/modules/system/lib/Drupal/system/Tests/Routing/UrlGeneratorTest.php @@ -0,0 +1,128 @@ + 'URL generator tests', + 'description' => 'Confirm that the url generation code is working correctly.', + 'group' => 'Routing', + ); + } + + function __construct($test_id = NULL) { + parent::__construct($test_id); + + $this->fixtures = new MyRoutingFixtures(); + } + + public function tearDown() { + $this->fixtures->dropTables(Database::getConnection()); + + parent::tearDown(); + } + + /** + * Confirms correct URL generation for a simple sample RouteCollection + */ + function testSampleUrlGeneration() { + $connection = Database::getConnection(); + $this->fixtures->createTables($connection); + + $dumper = new MatcherDumper($connection); + $sampleRoutes = $this->fixtures->sampleRouteCollection(); + $dumper->addRoutes($sampleRoutes); + $dumper->dump(); + + $generator = new DrupalUrlGenerator(); + + foreach ($sampleRoutes->all() as $name => $route) { + $url = $generator->generate($name); + $this->assertEqual($route->getPattern(), $url, 'Checking path generation for '. $name); + } + } + + /** + * Confirms correct URL generation for a more complex RouteCollection + */ + function testComplexUrlGeneration() { + $connection = Database::getConnection(); + $this->fixtures->createTables($connection); + + $dumper = new MatcherDumper($connection); + $sampleRoutes = $this->fixtures->complexRouteCollection(); + $dumper->addRoutes($sampleRoutes); + $dumper->dump(); + + $generator = new DrupalUrlGenerator(); + + $sampleArgs = array('foo', 'bar', 'baz'); + + foreach ($sampleRoutes->all() as $name => $route) { + $pattern = $route->getPattern(); + + //constructing the expected URL by pattern matching + $expected_url = $pattern; + $parameters = array(); + preg_match_all('/\{(.+?)\}/', $pattern, $placeholders); + foreach ($placeholders[1] as $idx => $placeholder_name) { + $expected_url = preg_replace('/\{' . $placeholder_name . '\}/', $sampleArgs[$idx], $expected_url); + $parameters[$placeholder_name] = $sampleArgs[$idx]; + } + + $url = $generator->generate($name, $parameters); + $this->assertEqual($expected_url, $url, 'Checking path generation for '. $name); + } + } +} + + +// RoutingFixtures::routingTableDefinition() hardcodes a table definition called +// 'test_routes', but I need a table called 'router', which the UrlGenerator is +// hitting while generating URLs. Quick and hacky workaround. +use Drupal\Core\Database\Connection; + +class MyRoutingFixtures extends RoutingFixtures { + + public function createTables(Connection $connection) { + $tables = $this->routingTableDefinition(); + $tables['router'] = $tables['test_routes']; + unset($tables['test_routes']); + + $schema = $connection->schema(); + + foreach ($tables as $name => $table) { + $schema->dropTable($name); + $schema->createTable($name, $table); + } + } +}