Skip to content

Commit

Permalink
Cast enums with optional parameters
Browse files Browse the repository at this point in the history
  • Loading branch information
morloderex committed Mar 16, 2023
1 parent 0b3fae2 commit a9d33e3
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 2 deletions.
2 changes: 1 addition & 1 deletion src/Illuminate/Routing/ImplicitRouteBinding.php
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ protected static function resolveBackedEnumsForRoute($route, $parameters)

$parameterValue = $parameters[$parameterName];

$backedEnumClass = (string) $parameter->getType();
$backedEnumClass = $parameter->getType()?->getName();

$backedEnum = $backedEnumClass::tryFrom((string) $parameterValue);

Expand Down
6 changes: 5 additions & 1 deletion src/Illuminate/Support/Reflector.php
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,11 @@ public static function isParameterSubclassOf($parameter, $className)
*/
public static function isParameterBackedEnumWithStringBackingType($parameter)
{
$backedEnumClass = (string) $parameter->getType();
$backedEnumClass = $parameter->getType()?->getName();

if (null === $backedEnumClass) {
return false;
}

if (enum_exists($backedEnumClass)) {
$reflectionBackedEnum = new ReflectionEnum($backedEnumClass);
Expand Down
18 changes: 18 additions & 0 deletions tests/Routing/ImplicitRouteBindingTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,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_can_resolve_the_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' => 'fruits'];

$route->prepareForSerialization();

$container = Container::getInstance();

ImplicitRouteBinding::resolveForRoute($container, $route);

$this->assertSame('fruits', $route->parameter('category')->value);
}

public function test_it_does_not_resolve_implicit_non_backed_enum_route_bindings_for_the_given_route()
{
$action = ['uses' => function (CategoryEnum $category) {
Expand Down
14 changes: 14 additions & 0 deletions tests/Routing/RoutingRouteTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1893,6 +1893,20 @@ public function testImplicitBindingsWithOptionalParameterWithNoKeyInUri()
$router->dispatch(Request::create('foo', 'GET'))->getContent();
}

public function testImplicitBindingsWithOptionalParameterUsingEnumIsAlwaysCastedToEnum()
{
include_once 'enums.php';

$router = $this->getRouter();
$router->get('foo/{bar?}', [
'middleware' => SubstituteBindings::class,
'uses' => function (?\Illuminate\Tests\Routing\CategoryBackedEnum $bar = null) {
$this->assertInstanceOf(CategoryBackedEnum::class, $bar);
},
]);
$router->dispatch(Request::create('foo/people', 'GET'))->getContent();
}

public function testImplicitBindingsWithOptionalParameterWithNonExistingKeyInUri()
{
$this->expectException(ModelNotFoundException::class);
Expand Down

0 comments on commit a9d33e3

Please sign in to comment.