public function RouteProvider::getRouteCollectionForRequest

Finds routes that may potentially match the request.

This may return a mixed list of class instances, but all routes returned must extend the core symfony route. The classes may also implement RouteObjectInterface to link to a content document.

This method may not throw an exception based on implementation specific restrictions on the url. That case is considered a not found - returning an empty array. Exceptions are only used to abort the whole request in case something is seriously broken, like the storage backend being down.

Note that implementations may not implement an optimal matching algorithm, simply a reasonable first pass. That allows for potentially very large route sets to be filtered down to likely candidates, which may then be filtered in memory more completely.

@todo Should this method's found routes also be included in the cache?

Parameters

Request $request A request against which to match.:

Return value

\Symfony\Component\Routing\RouteCollection with all urls that could potentially match $request. Empty collection if nothing can match.

Overrides RouteProviderInterface::getRouteCollectionForRequest

File

drupal/core/lib/Drupal/Core/Routing/RouteProvider.php, line 82
Contains Drupal\Core\Routing\RouteProvider.

Class

RouteProvider
A Route Provider front-end for all Drupal-stored routes.

Namespace

Drupal\Core\Routing

Code

public function getRouteCollectionForRequest(Request $request) {

  // The 'system_path' has language prefix stripped and path alias resolved,
  // whereas getPathInfo() returns the requested path. In Drupal, the request
  // always contains a system_path attribute, but this component may get
  // adopted by non-Drupal projects. Some unit tests also skip initializing
  // 'system_path'.
  // @todo Consider abstracting this to a separate object.
  if ($request->attributes
    ->has('system_path')) {

    // system_path never has leading or trailing slashes.
    $path = '/' . $request->attributes
      ->get('system_path');
  }
  else {

    // getPathInfo() always has leading slash, and might or might not have a
    // trailing slash.
    $path = rtrim($request
      ->getPathInfo(), '/');
  }

  // Filter out each empty value, though allow '0' and 0, which would be
  // filtered out by empty().
  $parts = array_slice(array_filter(explode('/', $path), function ($value) {
    return $value !== NULL && $value !== '';
  }), 0, MatcherDumper::MAX_PARTS);
  $ancestors = $this
    ->getCandidateOutlines($parts);
  $routes = $this->connection
    ->query("SELECT name, route FROM {" . $this->connection
    ->escapeTable($this->tableName) . "} WHERE pattern_outline IN (:patterns) ORDER BY fit", array(
    ':patterns' => $ancestors,
  ))
    ->fetchAllKeyed();
  $collection = new RouteCollection();
  foreach ($routes as $name => $route) {
    $route = unserialize($route);
    if (preg_match($route
      ->compile()
      ->getRegex(), $path, $matches)) {
      $collection
        ->add($name, $route);
    }
  }
  if (!count($collection)) {
    throw new ResourceNotFoundException();
  }
  return $collection;
}