diff --git a/core/lib/Drupal/Core/Routing/UrlGenerator.php b/core/lib/Drupal/Core/Routing/UrlGenerator.php new file mode 100644 index 0000000..c33b904 --- /dev/null +++ b/core/lib/Drupal/Core/Routing/UrlGenerator.php @@ -0,0 +1,45 @@ +connection = $connection; + $this->context = $context; + } + + /** + * Generates a URL from the given parameters. + */ + public function generate($name, $parameters = array(), $absolute = false) { + $result = $this->connection->query("select route from {router} where name = :name", array(':name' => $name)); + $row = $result->fetchObject(); + + if (empty($row)) { + throw new RouteNotFoundException(sprintf('Route "%s" does not exist.', $name)); + } + + $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'); + + $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/MatcherDumperTest.php b/core/modules/system/lib/Drupal/system/Tests/Routing/MatcherDumperTest.php index 7f6f312..34bf8b0 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Routing/MatcherDumperTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Routing/MatcherDumperTest.php @@ -117,7 +117,7 @@ function testAddAdditionalRoutes() { */ public function testDump() { $connection = Database::getConnection(); - $dumper= new MatcherDumper($connection, 'test_routes'); + $dumper= new MatcherDumper($connection); $route = new Route('/test/{my}/path'); $route->setOption('compiler_class', 'Drupal\Core\Routing\RouteCompiler'); @@ -130,7 +130,7 @@ public function testDump() { $dumper->dump(array('route_set' => 'test')); - $record = $connection->query("SELECT * FROM {test_routes} WHERE name= :name", array(':name' => 'test_route'))->fetchObject(); + $record = $connection->query("SELECT * FROM {router} WHERE name= :name", array(':name' => 'test_route'))->fetchObject(); $loaded_route = unserialize($record->route); diff --git a/core/modules/system/lib/Drupal/system/Tests/Routing/PathMatcherTest.php b/core/modules/system/lib/Drupal/system/Tests/Routing/PathMatcherTest.php index 0780250..3aeab1b 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Routing/PathMatcherTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Routing/PathMatcherTest.php @@ -77,11 +77,11 @@ public function testCandidateOutlines() { */ function testExactPathMatch() { $connection = Database::getConnection(); - $matcher = new PathMatcher($connection, 'test_routes'); + $matcher = new PathMatcher($connection); $this->fixtures->createTables($connection); - $dumper = new MatcherDumper($connection, 'test_routes'); + $dumper = new MatcherDumper($connection); $dumper->addRoutes($this->fixtures->sampleRouteCollection()); $dumper->dump(); @@ -101,11 +101,11 @@ function testExactPathMatch() { */ function testOutlinePathMatch() { $connection = Database::getConnection(); - $matcher = new PathMatcher($connection, 'test_routes'); + $matcher = new PathMatcher($connection); $this->fixtures->createTables($connection); - $dumper = new MatcherDumper($connection, 'test_routes'); + $dumper = new MatcherDumper($connection); $dumper->addRoutes($this->fixtures->complexRouteCollection()); $dumper->dump(); @@ -130,11 +130,11 @@ function testOutlinePathMatch() { */ function testOutlinePathMatchTrailingSlash() { $connection = Database::getConnection(); - $matcher = new PathMatcher($connection, 'test_routes'); + $matcher = new PathMatcher($connection); $this->fixtures->createTables($connection); - $dumper = new MatcherDumper($connection, 'test_routes'); + $dumper = new MatcherDumper($connection); $dumper->addRoutes($this->fixtures->complexRouteCollection()); $dumper->dump(); @@ -159,7 +159,7 @@ function testOutlinePathMatchTrailingSlash() { */ function testOutlinePathMatchDefaults() { $connection = Database::getConnection(); - $matcher = new PathMatcher($connection, 'test_routes'); + $matcher = new PathMatcher($connection); $this->fixtures->createTables($connection); @@ -168,7 +168,7 @@ function testOutlinePathMatchDefaults() { 'value' => 'poink', ))); - $dumper = new MatcherDumper($connection, 'test_routes'); + $dumper = new MatcherDumper($connection); $dumper->addRoutes($collection); $dumper->dump(); @@ -198,7 +198,7 @@ function testOutlinePathMatchDefaults() { */ function testOutlinePathMatchDefaultsCollision() { $connection = Database::getConnection(); - $matcher = new PathMatcher($connection, 'test_routes'); + $matcher = new PathMatcher($connection); $this->fixtures->createTables($connection); @@ -208,7 +208,7 @@ function testOutlinePathMatchDefaultsCollision() { ))); $collection->add('narf', new Route('/some/path/here')); - $dumper = new MatcherDumper($connection, 'test_routes'); + $dumper = new MatcherDumper($connection); $dumper->addRoutes($collection); $dumper->dump(); @@ -238,7 +238,7 @@ function testOutlinePathMatchDefaultsCollision() { */ function testOutlinePathMatchDefaultsCollision2() { $connection = Database::getConnection(); - $matcher = new PathMatcher($connection, 'test_routes'); + $matcher = new PathMatcher($connection); $this->fixtures->createTables($connection); @@ -248,7 +248,7 @@ function testOutlinePathMatchDefaultsCollision2() { ))); $collection->add('narf', new Route('/some/path/here')); - $dumper = new MatcherDumper($connection, 'test_routes'); + $dumper = new MatcherDumper($connection); $dumper->addRoutes($collection); $dumper->dump(); @@ -277,11 +277,11 @@ function testOutlinePathMatchDefaultsCollision2() { */ function testOutlinePathNoMatch() { $connection = Database::getConnection(); - $matcher = new PathMatcher($connection, 'test_routes'); + $matcher = new PathMatcher($connection); $this->fixtures->createTables($connection); - $dumper = new MatcherDumper($connection, 'test_routes'); + $dumper = new MatcherDumper($connection); $dumper->addRoutes($this->fixtures->complexRouteCollection()); $dumper->dump(); diff --git a/core/modules/system/lib/Drupal/system/Tests/Routing/RoutingFixtures.php b/core/modules/system/lib/Drupal/system/Tests/Routing/RoutingFixtures.php index f243ff1..9eae68c 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Routing/RoutingFixtures.php +++ b/core/modules/system/lib/Drupal/system/Tests/Routing/RoutingFixtures.php @@ -111,7 +111,7 @@ public function complexRouteCollection() { */ public function routingTableDefinition() { - $tables['test_routes'] = array( + $tables['router'] = array( 'description' => 'Maps paths to various callbacks (access, page and title)', 'fields' => array( 'name' => array( 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..d6c0bfb --- /dev/null +++ b/core/modules/system/lib/Drupal/system/Tests/Routing/UrlGeneratorTest.php @@ -0,0 +1,125 @@ + '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 RoutingFixtures(); + } + + 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 UrlGenerator($connection, new RequestContext()); + + foreach ($sampleRoutes->all() as $name => $route) { + $url = $generator->generate($name); + $this->assertEqual($route->getPattern(), $url, "Correct path generated for route $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 UrlGenerator($connection, new RequestContext()); + + $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, "Correct path generated for route $name."); + } + } + + /** + * Confirms correct behavior for non existant Routes + */ + function testNonExistantRoute() { + $connection = Database::getConnection(); + $this->fixtures->createTables($connection); + + $generator = new UrlGenerator($connection, new RequestContext()); + + try { + $generator->generate('surelyNonExistantName'); + $this->fail(); + } catch (RouteNotFoundException $e) { + $this->pass("Caught exception on generating URL for non-existant route."); + } + } +}