diff --git a/core/lib/Drupal/Core/Routing/RouteProvider.php b/core/lib/Drupal/Core/Routing/RouteProvider.php index 73be1c7..9835848 100644 --- a/core/lib/Drupal/Core/Routing/RouteProvider.php +++ b/core/lib/Drupal/Core/Routing/RouteProvider.php @@ -296,16 +296,10 @@ protected function getRoutesByPath($path) { )) ->fetchAll(\PDO::FETCH_ASSOC); + // We sort but fit and name in PHP to avoid a SQL filesort. usort($routes, array($this, 'routeProviderRouteCompare')); - if ($first = reset($routes)) { - $max = $first['fit']; - } foreach ($routes as $row) { - // We only want to consider routes with the maximum fit value. - if ($row['fit'] < $max) { - break; - } $route = unserialize($row['route']); if (preg_match($route->compile()->getRegex(), $path, $matches)) { $collection->add($row['name'], $route); diff --git a/core/modules/system/lib/Drupal/system/Tests/Routing/RouteProviderTest.php b/core/modules/system/lib/Drupal/system/Tests/Routing/RouteProviderTest.php index 05d1131..31d2639 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Routing/RouteProviderTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Routing/RouteProviderTest.php @@ -283,7 +283,46 @@ function testOutlinePathMatchDefaultsCollision2() { $this->assertEqual(array('narf', 'poink'), array_keys($routes_array), 'Ensure the fitness was taken into account.'); $this->assertNotNull($routes->get('narf'), 'The first matching route was found.'); $this->assertNotNull($routes->get('poink'), 'The second matching route was found.'); - $this->assertNull($routes->get('eep'), 'Noin-matching route was not found.'); + $this->assertNull($routes->get('eep'), 'Non-matching route was not found.'); + } + catch (ResourceNotFoundException $e) { + $this->fail('No matching route found with default argument value.'); + } + } + + /** + * Confirms that we can find multiple routes that match the request equally. + */ + function testOutlinePathMatchDefaultsCollision3() { + $connection = Database::getConnection(); + $provider = new RouteProvider($connection, $this->routeBuilder, $this->state, 'test_routes'); + + $this->fixtures->createTables($connection); + + $collection = new RouteCollection(); + $collection->add('poink', new Route('/some/{value}/path')); + // Add a second route matching the same path pattern. + $collection->add('poink2', new Route('/some/{object}/path')); + $collection->add('narf', new Route('/some/here/path')); + $collection->add('eep', new Route('/something/completely/different')); + + $dumper = new MatcherDumper($connection, $this->state, 'test_routes'); + $dumper->addRoutes($collection); + $dumper->dump(); + + $path = '/some/over-there/path'; + + $request = Request::create($path, 'GET'); + + try { + $routes = $provider->getRouteCollectionForRequest($request); + $routes_array = $routes->all(); + + $this->assertEqual(count($routes), 2, 'The correct number of routes was found.'); + $this->assertEqual(array('poink', 'poink2'), array_keys($routes_array), 'Ensure the fitness and name were taken into account in the sort.'); + $this->assertNotNull($routes->get('poink'), 'The first matching route was found.'); + $this->assertNotNull($routes->get('poink2'), 'The second matching route was found.'); + $this->assertNull($routes->get('eep'), 'Non-matching route was not found.'); } catch (ResourceNotFoundException $e) { $this->fail('No matching route found with default argument value.');