-
Notifications
You must be signed in to change notification settings - Fork 11.6k
Closed
Labels
Description
Laravel Version
12
PHP Version
any
Database Driver & Version
irrelevant
Description
Given:
- A route like
Route::get('/{foo:slug}/example/{bar}', ...)->name('example');
URL::defaults(['foo' => 'some_value']);
route('example', $bar)
will produce a "Missing required parameter" exception.
On the other hand, route('example', ['bar' => $bar])
will work fine.
The issue comes from UrlGenerator::toRoute()
:
public function toRoute($route, $parameters, $absolute)
{
// $parameters = [$bar]
$parameters = Collection::wrap($parameters)->map(function ($value, $key) use ($route) {
// $value = $bar, $key = 0
// true since it's a model && true because field '0' (foo:slug) has a binding field (slug)
return $value instanceof UrlRoutable && $route->bindingFieldFor($key)
? $value->{$route->bindingFieldFor($key)}
: $value;
})->all();
// $parameters = [null because we've incorrectly done $bar->slug]
array_walk_recursive($parameters, function (&$item) {
if ($item instanceof BackedEnum) {
$item = $item->value;
}
});
return $this->routeUrl()->to(
$route, $this->formatParameters($parameters), $absolute
);
}
The default parameter only gets used in $this->routeUrl()
(RouteUrlGenerator
), but by that point the UrlGenerator
has broken the provided parameters, passing a [null]
array.
I think the solution would be something along the lines of: Actually probably a bit more complex than this because defaults can work for latter parameters too, not just the earliest ones. I'll try to send a PR with some reasonable implementation.
- If
$key
is numeric, aka we've passedroute('example', $bar)
notroute('example', ['bar' => $bar])
- And
array_key_exists($route->parameterNames()[$key], $this->getDefaultParameters())
- Skip the
[$key]
parameter and move on to the next one - (Repeat as many times as needed — in my example there's one parameter with a default value but there can be several)
So in this case $bar
should be matched against the second parameter, not the first one.
Steps To Reproduce
See above
lukinovec