-
Notifications
You must be signed in to change notification settings - Fork 11.7k
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
$keyis 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