Skip to content

Commit

Permalink
Map integer parameter to parameter name when resolving binding field
Browse files Browse the repository at this point in the history
  • Loading branch information
ksassnowski committed May 30, 2022
1 parent acddea7 commit 9621a6a
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 24 deletions.
2 changes: 1 addition & 1 deletion src/Illuminate/Routing/ImplicitRouteBinding.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public static function resolveForRoute($container, $route)
? 'resolveSoftDeletableRouteBinding'
: 'resolveRouteBinding';

if ($parent instanceof UrlRoutable && ($route->enforcesScopedBindings() || $route->bindingFieldFor($parameterName) !== null)) {
if ($parent instanceof UrlRoutable && ($route->enforcesScopedBindings() || array_key_exists($parameterName, $route->bindingFields()))) {
$childRouteBindingMethod = $route->allowsTrashedBindings() && in_array(SoftDeletes::class, class_uses_recursive($instance))
? 'resolveSoftDeletableChildRouteBinding'
: 'resolveChildRouteBinding';
Expand Down
6 changes: 4 additions & 2 deletions src/Illuminate/Routing/Route.php
Original file line number Diff line number Diff line change
Expand Up @@ -535,9 +535,11 @@ public function signatureParameters($conditions = [])
*/
public function bindingFieldFor($parameter)
{
$fields = is_int($parameter) ? array_values($this->bindingFields) : $this->bindingFields;
if (is_int($parameter)) {
$parameter = $this->parameterNames()[$parameter];
}

return $fields[$parameter] ?? null;
return $this->bindingFields[$parameter] ?? null;
}

/**
Expand Down
16 changes: 4 additions & 12 deletions src/Illuminate/Routing/RouteUri.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,27 +44,19 @@ public static function parse($uri)
$bindingFields = [];

foreach ($matches[0] as $match) {
$parameter = trim($match, '{}?');

if (! str_contains($parameter, ':')) {
$bindingFields[$parameter] = null;

if (! str_contains($match, ':')) {
continue;
}

$segments = explode(':', $parameter);
$segments = explode(':', trim($match, '{}?'));

$bindingFields[$segments[0]] = $segments[1];

$uri = str_contains($match, '?')
? str_replace($match, '{'.$segments[0].'?}', $uri)
: str_replace($match, '{'.$segments[0].'}', $uri);
? str_replace($match, '{'.$segments[0].'?}', $uri)
: str_replace($match, '{'.$segments[0].'}', $uri);
}

$bindingFields = ! empty(array_filter($bindingFields))
? $bindingFields
: [];

return new static($uri, $bindingFields);
}
}
13 changes: 4 additions & 9 deletions tests/Routing/RouteUriTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,27 +51,22 @@ public function uriProvider()
[
'/foo/{bar}/baz/{qux:slug}',
'/foo/{bar}/baz/{qux}',
['bar' => null, 'qux' => 'slug'],
['qux' => 'slug'],
],
[
'/foo/{bar}/baz/{qux:slug}',
'/foo/{bar}/baz/{qux}',
['bar' => null, 'qux' => 'slug'],
],
[
'/foo/{bar:slug}/baz/{qux}',
'/foo/{bar}/baz/{qux}',
['bar' => 'slug', 'qux' => null],
['qux' => 'slug'],
],
[
'/foo/{bar}/baz/{qux:slug?}',
'/foo/{bar}/baz/{qux?}',
['bar' => null, 'qux' => 'slug'],
['qux' => 'slug'],
],
[
'/foo/{bar}/baz/{qux:slug?}/{test:id?}',
'/foo/{bar}/baz/{qux?}/{test?}',
['bar' => null, 'qux' => 'slug', 'test' => 'id'],
['qux' => 'slug', 'test' => 'id'],
],
];
}
Expand Down
32 changes: 32 additions & 0 deletions tests/Routing/RoutingRouteTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1706,6 +1706,23 @@ public function testParentChildImplicitBindingsWhereOnlySomeParametersAreScoped(
$this->assertSame('2|another-test-slug|3', $router->dispatch(Request::create('foo/2/another-test-slug/3', 'GET'))->getContent());
}

public function testApiResourceScopingWhenChildDoesNotBelongToParent()
{
ResourceRegistrar::singularParameters();
$router = $this->getRouter();
$router->apiResource(
'teams.users',
RouteTestNestedResourceControllerWithMissingUser::class,
['only' => ['show']],
)
->middleware(SubstituteBindings::class)
->scoped();

$this->expectException(ModelNotFoundException::class);

$router->dispatch(Request::create('teams/1/users/2', 'GET'));
}

public function testParentChildImplicitBindingsProperlyCamelCased()
{
$router = $this->getRouter();
Expand Down Expand Up @@ -2109,6 +2126,13 @@ public function show(RoutingTestUserModel $fooBar)
}
}

class RouteTestNestedResourceControllerWithMissingUser extends Controller
{
public function show(RoutingTestTeamWithoutUserModel $team, RoutingTestUserModel $user)
{
}
}

class RouteTestClosureMiddlewareController extends Controller
{
public function __construct()
Expand Down Expand Up @@ -2366,6 +2390,14 @@ public function firstOrFail()
}
}

class RoutingTestTeamWithoutUserModel extends RoutingTestTeamModel
{
public function users()
{
throw new ModelNotFoundException();
}
}

class ActionStub
{
public function __invoke()
Expand Down

0 comments on commit 9621a6a

Please sign in to comment.