Skip to content

Commit 551151d

Browse files
[9.x] Ability to disable route scope bindings (#44528)
* wip it * use method to determine scope bindings * test withoutScopeBindings() method * fix reference to scope_bindings * wip * drop redundant attribute * formatting * Fix test Co-authored-by: Taylor Otwell <[email protected]>
1 parent c703de3 commit 551151d

File tree

6 files changed

+46
-3
lines changed

6 files changed

+46
-3
lines changed

src/Illuminate/Routing/ImplicitRouteBinding.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,9 @@ public static function resolveForRoute($container, $route)
4646
? 'resolveSoftDeletableRouteBinding'
4747
: 'resolveRouteBinding';
4848

49-
if ($parent instanceof UrlRoutable && ($route->enforcesScopedBindings() || array_key_exists($parameterName, $route->bindingFields()))) {
49+
if ($parent instanceof UrlRoutable &&
50+
! $route->preventsScopedBindings() &&
51+
($route->enforcesScopedBindings() || array_key_exists($parameterName, $route->bindingFields()))) {
5052
$childRouteBindingMethod = $route->allowsTrashedBindings() && in_array(SoftDeletes::class, class_uses_recursive($instance))
5153
? 'resolveSoftDeletableChildRouteBinding'
5254
: 'resolveChildRouteBinding';

src/Illuminate/Routing/Route.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1155,6 +1155,18 @@ public function scopeBindings()
11551155
return $this;
11561156
}
11571157

1158+
/**
1159+
* Indicate that the route should not enforce scoping of multiple implicit Eloquent bindings.
1160+
*
1161+
* @return $this
1162+
*/
1163+
public function withoutScopedBindings()
1164+
{
1165+
$this->action['scope_bindings'] = false;
1166+
1167+
return $this;
1168+
}
1169+
11581170
/**
11591171
* Determine if the route should enforce scoping of multiple implicit Eloquent bindings.
11601172
*
@@ -1165,6 +1177,16 @@ public function enforcesScopedBindings()
11651177
return (bool) ($this->action['scope_bindings'] ?? false);
11661178
}
11671179

1180+
/**
1181+
* Determine if the route should prevent scoping of multiple implicit Eloquent bindings.
1182+
*
1183+
* @return bool
1184+
*/
1185+
public function preventsScopedBindings()
1186+
{
1187+
return isset($this->action['scope_bindings']) && $this->action['scope_bindings'] === false;
1188+
}
1189+
11681190
/**
11691191
* Specify that the route should not allow concurrent requests from the same session.
11701192
*

src/Illuminate/Routing/RouteRegistrar.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
* @method \Illuminate\Routing\RouteRegistrar scopeBindings()
2727
* @method \Illuminate\Routing\RouteRegistrar where(array $where)
2828
* @method \Illuminate\Routing\RouteRegistrar withoutMiddleware(array|string $middleware)
29+
* @method \Illuminate\Routing\RouteRegistrar withoutScopedBindings()
2930
*/
3031
class RouteRegistrar
3132
{

src/Illuminate/Support/Facades/Route.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
* @method static \Illuminate\Routing\RouteRegistrar scopeBindings()
3232
* @method static \Illuminate\Routing\RouteRegistrar where(array $where)
3333
* @method static \Illuminate\Routing\RouteRegistrar withoutMiddleware(array|string $middleware)
34+
* @method static \Illuminate\Routing\RouteRegistrar withoutScopedBindings()
3435
* @method static \Illuminate\Routing\Router|\Illuminate\Routing\RouteRegistrar group(\Closure|string|array $attributes, \Closure|string $routes)
3536
* @method static \Illuminate\Routing\ResourceRegistrar resourceVerbs(array $verbs = [])
3637
* @method static string|null currentRouteAction()

tests/Integration/Routing/ImplicitModelRouteBindingTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ public function testEnforceScopingImplicitRouteBindingsWithRouteCachingEnabled()
183183
use Illuminate\Tests\Integration\Routing\ImplicitBindingUser;
184184
use Illuminate\Tests\Integration\Routing\ImplicitBindingPost;
185185
186-
Route::group(['scoping' => true], function () {
186+
Route::group(['scope_bindings' => true], function () {
187187
Route::get('/user/{user}/post/{post}', function (ImplicitBindingUser \$user, ImplicitBindingPost \$post) {
188188
return [\$user, \$post];
189189
})->middleware(['web']);
@@ -203,7 +203,7 @@ public function testWithoutEnforceScopingImplicitRouteBindings()
203203

204204
config(['app.key' => str_repeat('a', 32)]);
205205

206-
Route::group(['scoping' => false], function () {
206+
Route::group(['scope_bindings' => false], function () {
207207
Route::get('/user/{user}/post/{post}', function (ImplicitBindingUser $user, ImplicitBindingPost $post) {
208208
return [$user, $post];
209209
})->middleware(['web']);

tests/Routing/RoutingRouteTest.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1741,6 +1741,23 @@ public function testImplicitBindings()
17411741
$this->assertSame('taylor', $router->dispatch(Request::create('foo/taylor', 'GET'))->getContent());
17421742
}
17431743

1744+
public function testImplicitBindingsWhereScopedBindingsArePrevented()
1745+
{
1746+
$router = $this->getRouter();
1747+
1748+
$router->get('foo/{test_team}/{user:id}', [
1749+
'middleware' => SubstituteBindings::class,
1750+
'uses' => function (RoutingTestTeamWithoutUserModel $testTeam, RoutingTestUserModel $user) {
1751+
$this->assertInstanceOf(RoutingTestTeamWithoutUserModel::class, $testTeam);
1752+
$this->assertInstanceOf(RoutingTestUserModel::class, $user);
1753+
1754+
return $testTeam->value.'|'.$user->value;
1755+
},
1756+
])->withoutScopedBindings();
1757+
1758+
$this->assertSame('1|4', $router->dispatch(Request::create('foo/1/4', 'GET'))->getContent());
1759+
}
1760+
17441761
public function testParentChildImplicitBindings()
17451762
{
17461763
$router = $this->getRouter();

0 commit comments

Comments
 (0)