Complete exact-path matching.

8.0.x
Larry Garfield 2012-06-30 15:44:30 -05:00 committed by effulgentsia
parent f55ab1aff6
commit d372d6de99
2 changed files with 43 additions and 20 deletions

View File

@ -29,7 +29,6 @@ class PathMatcher implements InitialMatcherInterface {
public function __construct(Connection $connection, $table = 'router') {
$this->connection = $connection;
$this->tableName = $table;
}
@ -46,26 +45,18 @@ class PathMatcher implements InitialMatcherInterface {
$path = $request->getPathInfo();
$parts = array_slide(explode('/', $path), 0, MatcherDumper::MAX_PARTS);
$number_parts = count($parts);
$parts = array_slice(array_filter(explode('/', $path)), 0, MatcherDumper::MAX_PARTS);
$ancestors = $this->getCandidateOutlines($parts);
// @todo We want to allow matching more than one result because there could
// be more than one result with the same path. But how do we do that and
// limit by fit?
$routes = $this->connection
->select($this->tableName, 'r')
->fields('r', array('name', 'route'))
->condition('pattern_outline', $ancestors, 'IN')
->condition('number_parts', $number_parts)
->execute()
->fetchAllKeyed();
$routes = $this->connection->query("SELECT name, route FROM {{$this->tableName}} WHERE pattern_outline IN (:patterns) ORDER BY fit", array(
':patterns' => $ancestors,
))
->fetchAllKeyed();
$collection = new RouteCollection();
foreach ($routes as $name => $route) {
$collection->add($name, $route);
$collection->add($name, unserialize($route));
}
return $collection;
@ -93,7 +84,7 @@ class PathMatcher implements InitialMatcherInterface {
$masks = range($end, $start);
foreach ($masks as $i) {
$current = '';
$current = '/';
for ($j = $length; $j >= 0; $j--) {
// Check the bit on the $j offset.
if ($i & (1 << $j)) {

View File

@ -14,6 +14,7 @@ use Symfony\Component\Routing\RouteCollection;
use Drupal\simpletest\UnitTestBase;
use Drupal\Core\Routing\PathMatcher;
use Drupal\Core\Database\Database;
use Drupal\Core\Routing\MatcherDumper;
/**
* Basic tests for the UrlMatcherDumper.
@ -64,10 +65,41 @@ class PathMatcherTest extends UnitTestBase {
$candidates = array_flip($candidates);
$this->assertTrue(count($candidates) == 4, t('Correct number of candidates found'));
$this->assertTrue(array_key_exists('node/5/edit', $candidates), t('First candidate found.'));
$this->assertTrue(array_key_exists('node/5/%', $candidates), t('Second candidate found.'));
$this->assertTrue(array_key_exists('node/%/edit', $candidates), t('Third candidate found.'));
$this->assertTrue(array_key_exists('node/%/%', $candidates), t('Fourth candidate found.'));
$this->assertTrue(array_key_exists('/node/5/edit', $candidates), t('First candidate found.'));
$this->assertTrue(array_key_exists('/node/5/%', $candidates), t('Second candidate found.'));
$this->assertTrue(array_key_exists('/node/%/edit', $candidates), t('Third candidate found.'));
$this->assertTrue(array_key_exists('/node/%/%', $candidates), t('Fourth candidate found.'));
}
/**
* Confirms that we can find routes with the exact incoming path.
*/
function testExactPathMatch() {
$connection = Database::getConnection();
$matcher = new PathMatcher($connection, 'test_routes');
$this->fixtures->createTables($connection);
$dumper = new MatcherDumper($connection, 'test_routes');
$dumper->addRoutes($this->fixtures->sampleRouteCollection());
$dumper->dump();
$path = '/path/one';
$request = Request::create($path, 'GET');
$routes = $matcher->matchRequestPartial($request);
foreach ($routes as $route) {
$this->assertEqual($route->getPattern(), $path, t('Found path has correct pattern'));
}
}
/**
* Confirms that we can find routes whose pattern would match the request.
*/
function testOutlinePathMatch() {
}