From 983e0303a51614f5f79a7c4411a8fccfdb2ce021 Mon Sep 17 00:00:00 2001 From: Hugo Sales Date: Wed, 1 Sep 2021 15:54:13 +0100 Subject: [PATCH] [ROUTER] Sort routes so that the one with a smaller list of Accept types matches first This requires a copy, but gets cached, so it's the ideal place to do it. Note that only routes that match the incoming Accept match anyway, so the order between those with different accept types is not relevant --- src/Core/Router/RouteLoader.php | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/Core/Router/RouteLoader.php b/src/Core/Router/RouteLoader.php index 05125add28..3538fe6429 100644 --- a/src/Core/Router/RouteLoader.php +++ b/src/Core/Router/RouteLoader.php @@ -64,6 +64,16 @@ class RouteLoader extends Loader Event::handle('AddRoute', [&$this]); + // Sort routes so that whichever route has the smallest accept option matches first, as it's more specific + // This requires a copy, sadly, as it doesn't seem to be possible to modify the collection in-place + // However, this is fine since this gets cached + $it = $this->rc->getIterator(); + $it->uasort(fn (Route $left, Route $right) => count($left->getDefaults()['accept']) <=> count($right->getDefaults()['accept'])); + $this->rc = new RouteCollection(); + foreach ($it as $id => $route) { + $this->rc->add($id, $route); + } + return $this->rc; } @@ -93,6 +103,7 @@ class RouteLoader extends Loader '_fragment' => $options['fragment'] ?? '', '_locale' => $options['locale'] ?? 'en', 'template' => $options['template'] ?? '', + 'accept' => $options['accept'] ?? [], ], $options['defaults'] ?? [] ),