From 5505370cc8d64bc4fc646c387b73464e4ae3e914 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?No=C3=ABl=20Hagestein?= <6616996+Neol3108@users.noreply.github.com> Date: Fri, 19 Apr 2024 09:16:49 +0200 Subject: [PATCH 1/2] Allow implicit binding to have optional backed enums --- .../Routing/ImplicitRouteBinding.php | 4 ++++ tests/Routing/ImplicitRouteBindingTest.php | 18 ++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/src/Illuminate/Routing/ImplicitRouteBinding.php b/src/Illuminate/Routing/ImplicitRouteBinding.php index d3590de1d707..288c7a7b6564 100644 --- a/src/Illuminate/Routing/ImplicitRouteBinding.php +++ b/src/Illuminate/Routing/ImplicitRouteBinding.php @@ -84,6 +84,10 @@ protected static function resolveBackedEnumsForRoute($route, $parameters) $parameterValue = $parameters[$parameterName]; + if ($parameterValue === null) { + continue; + } + $backedEnumClass = $parameter->getType()?->getName(); $backedEnum = $backedEnumClass::tryFrom((string) $parameterValue); diff --git a/tests/Routing/ImplicitRouteBindingTest.php b/tests/Routing/ImplicitRouteBindingTest.php index 18bb7a2ff2c1..b6db381be902 100644 --- a/tests/Routing/ImplicitRouteBindingTest.php +++ b/tests/Routing/ImplicitRouteBindingTest.php @@ -49,6 +49,24 @@ public function test_it_can_resolve_the_implicit_backed_enum_route_bindings_for_ $this->assertSame('fruits', $route->parameter('category')->value); } + public function test_it_handles_optional_implicit_backed_enum_route_bindings_for_the_given_route_with_optional_parameter() + { + $action = ['uses' => function (?CategoryBackedEnum $category = null) { + return $category->value; + }]; + + $route = new Route('GET', '/test', $action); + $route->parameters = ['category' => null]; + + $route->prepareForSerialization(); + + $container = Container::getInstance(); + + ImplicitRouteBinding::resolveForRoute($container, $route); + + $this->assertNull($route->parameter('category')); + } + public function test_it_does_not_resolve_implicit_non_backed_enum_route_bindings_for_the_given_route() { $action = ['uses' => function (CategoryEnum $category) { From 7cb1f54ae6d26565df91636aeae1cd078dab5c31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?No=C3=ABl=20Hagestein?= <6616996+Neol3108@users.noreply.github.com> Date: Mon, 22 Apr 2024 20:48:59 +0200 Subject: [PATCH 2/2] Add route-based test --- tests/Routing/RoutingRouteTest.php | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/tests/Routing/RoutingRouteTest.php b/tests/Routing/RoutingRouteTest.php index 3811b6fd350f..58871055a6b1 100644 --- a/tests/Routing/RoutingRouteTest.php +++ b/tests/Routing/RoutingRouteTest.php @@ -42,6 +42,8 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; use UnexpectedValueException; +include_once __DIR__.'/Enums.php'; + class RoutingRouteTest extends TestCase { public function testBasicDispatchingOfRoutes() @@ -1883,6 +1885,21 @@ public function testImplicitBindingsWithOptionalParameterWithExistingKeyInUri() $this->assertSame('taylor', $router->dispatch(Request::create('foo/taylor', 'GET'))->getContent()); } + public function testOptionalBackedEnumsReturnNullWhenMissing() + { + $router = $this->getRouter(); + $router->get('foo/{bar?}', [ + 'middleware' => SubstituteBindings::class, + 'uses' => function (?CategoryBackedEnum $bar = null) { + $this->assertNull($bar); + + return 'bar'; + }, + ]); + + $router->dispatch(Request::create('foo', 'GET'))->getContent(); + } + public function testImplicitBindingsWithMissingModelHandledByMissing() { $router = $this->getRouter();