Skip to content

Commit

Permalink
[11.x] Support soft deleted models when using explicit route model bi…
Browse files Browse the repository at this point in the history
…nding (#51651)

* Added support for soft deleted models using explicit binding.

* Fixed use statement order.

* Update RouteBinding.php

---------

Co-authored-by: Graham Bradley <[email protected]>
Co-authored-by: Taylor Otwell <[email protected]>
  • Loading branch information
3 people authored May 31, 2024
1 parent 3672fbe commit 4ebbabe
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 2 deletions.
9 changes: 7 additions & 2 deletions src/Illuminate/Routing/RouteBinding.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use Closure;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Str;

class RouteBinding
Expand Down Expand Up @@ -57,7 +58,7 @@ protected static function createClassBinding($container, $binding)
*/
public static function forModel($container, $class, $callback = null)
{
return function ($value) use ($container, $class, $callback) {
return function ($value, $route) use ($container, $class, $callback) {
if (is_null($value)) {
return;
}
Expand All @@ -67,7 +68,11 @@ public static function forModel($container, $class, $callback = null)
// throw a not found exception otherwise we will return the instance.
$instance = $container->make($class);

if ($model = $instance->resolveRouteBinding($value)) {
$routeBindingMethod = $route->allowsTrashedBindings() && in_array(SoftDeletes::class, class_uses_recursive($instance))
? 'resolveSoftDeletableRouteBinding'
: 'resolveRouteBinding';

if ($model = $instance->{$routeBindingMethod}($value)) {
return $model;
}

Expand Down
72 changes: 72 additions & 0 deletions tests/Routing/RouteBindingTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<?php

namespace Illuminate\Tests\Routing;

use Illuminate\Container\Container;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Routing\Route;
use Illuminate\Routing\RouteBinding;
use PHPUnit\Framework\TestCase;

class RouteBindingTest extends TestCase
{
public function test_it_can_resolve_the_explicit_model_for_the_given_route()
{
$container = Container::getInstance();

$route = new Route('GET', '/users/{user}', function () {
});

$callback = RouteBinding::forModel($container, ExplicitRouteBindingUser::class);
$this->assertInstanceOf(ExplicitRouteBindingUser::class, $callback(1, $route));
}

public function test_it_cannot_resolve_the_explicit_soft_deleted_model_for_the_given_route()
{
$container = Container::getInstance();

$route = new Route('GET', '/users/{user}', function () {
});

$callback = RouteBinding::forModel($container, ExplicitRouteBindingSoftDeletableUser::class);

$this->expectException(ModelNotFoundException::class);
$callback(1, $route);
}

public function test_it_can_resolve_the_explicit_soft_deleted_model_for_the_given_route_with_trashed()
{
$container = Container::getInstance();

$route = (new Route('GET', '/users/{user}', function () {
}))->withTrashed();

$callback = RouteBinding::forModel($container, ExplicitRouteBindingSoftDeletableUser::class);
$this->assertInstanceOf(ExplicitRouteBindingSoftDeletableUser::class, $callback(1, $route));
}
}

class ExplicitRouteBindingUser extends Model
{
public function resolveRouteBinding($value, $field = null)
{
return new self();
}
}

class ExplicitRouteBindingSoftDeletableUser extends Model
{
use SoftDeletes;

public function resolveRouteBinding($value, $field = null)
{
return null;
}

public function resolveSoftDeletableRouteBinding($value, $field = null)
{
return new self();
}
}

0 comments on commit 4ebbabe

Please sign in to comment.