You are here

protected function Router::applyFitOrder in Drupal 8

Same name and namespace in other branches
  1. 9 core/lib/Drupal/Core/Routing/Router.php \Drupal\Core\Routing\Router::applyFitOrder()
  2. 10 core/lib/Drupal/Core/Routing/Router.php \Drupal\Core\Routing\Router::applyFitOrder()

Reapplies the fit order to a RouteCollection object.

Route filters can reorder route collections. For example, routes with an explicit _format requirement will be preferred. This can result in a less fit route being used. For example, as a result of filtering /user/% comes before /user/login. In order to not break this fundamental property of routes, we need to reapply the fit order. We also need to ensure that order within each group of the same fit is preserved.

Parameters

\Symfony\Component\Routing\RouteCollection $collection: The route collection.

Return value

\Symfony\Component\Routing\RouteCollection The reordered route collection.

1 call to Router::applyFitOrder()
Router::matchRequest in core/lib/Drupal/Core/Routing/Router.php
Tries to match a request with a set of routes.

File

core/lib/Drupal/Core/Routing/Router.php, line 306

Class

Router
Router implementation in Drupal.

Namespace

Drupal\Core\Routing

Code

protected function applyFitOrder(RouteCollection $collection) {
  $buckets = [];

  // Sort all the routes by fit descending.
  foreach ($collection
    ->all() as $name => $route) {
    $fit = $route
      ->compile()
      ->getFit();
    $buckets += [
      $fit => [],
    ];
    $buckets[$fit][] = [
      $name,
      $route,
    ];
  }
  krsort($buckets);
  $flattened = array_reduce($buckets, 'array_merge', []);

  // Add them back onto a new route collection.
  $collection = new RouteCollection();
  foreach ($flattened as $pair) {
    $name = $pair[0];
    $route = $pair[1];
    $collection
      ->add($name, $route);
  }
  return $collection;
}