Skip to content

Commit

Permalink
[HttpFoundation] ParameterBag::getEnum()
Browse files Browse the repository at this point in the history
  • Loading branch information
nikophil committed Jan 4, 2023
1 parent f43cd26 commit 6b6c7df
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 1 deletion.
3 changes: 2 additions & 1 deletion src/Symfony/Component/HttpFoundation/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ CHANGELOG
6.3
---

* Create migration for session table when pdo handler is used
* Add `ParameterBag::getEnum()`
* Create migration for session table when pdo handler is used

6.2
---
Expand Down
19 changes: 19 additions & 0 deletions src/Symfony/Component/HttpFoundation/InputBag.php
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,25 @@ public function set(string $key, mixed $value)
$this->parameters[$key] = $value;
}

/**
* Returns the parameter value converted to an enum.
*
* @template T of \BackedEnum
*
* @param class-string<T> $class
* @param ?T $default
*
* @return ?T
*/
public function getEnum(string $key, string $class, \BackedEnum $default = null): ?\BackedEnum
{
try {
return parent::getEnum($key, $class, $default);
} catch (\UnexpectedValueException $e) {
throw new BadRequestException($e->getMessage(), $e->getCode(), $e);
}
}

public function filter(string $key, mixed $default = null, int $filter = \FILTER_DEFAULT, mixed $options = []): mixed
{
$value = $this->has($key) ? $this->all()[$key] : $default;
Expand Down
25 changes: 25 additions & 0 deletions src/Symfony/Component/HttpFoundation/ParameterBag.php
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,31 @@ public function getBoolean(string $key, bool $default = false): bool
return $this->filter($key, $default, \FILTER_VALIDATE_BOOL);
}

/**
* Returns the parameter value converted to an enum.
*
* @template T of \BackedEnum
*
* @param class-string<T> $class
* @param ?T $default
*
* @return ?T
*/
public function getEnum(string $key, string $class, \BackedEnum $default = null): ?\BackedEnum
{
$value = $this->get($key);

if (null === $value) {
return $default;
}

try {
return $class::from($value);
} catch (\ValueError|\TypeError $e) {
throw new \UnexpectedValueException(sprintf('Parameter "%s" cannot be converted to enum: %s.', $key, $e->getMessage()), $e->getCode(), $e);
}
}

/**
* Filter key.
*
Expand Down
17 changes: 17 additions & 0 deletions src/Symfony/Component/HttpFoundation/Tests/InputBagTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -106,4 +106,21 @@ public function testFilterArrayWithoutArrayFlag()
$bag = new InputBag(['foo' => ['bar', 'baz']]);
$bag->filter('foo', \FILTER_VALIDATE_INT);
}

public function testGetEnum()
{
$bag = new InputBag(['valid-value' => 1]);

$this->assertSame(Foo::Bar, $bag->getEnum('valid-value', Foo::class));
}

public function testGetEnumThrowsExceptionWithInvalidValue()
{
$bag = new InputBag(['invalid-value' => 2]);

$this->expectException(BadRequestException::class);
$this->expectExceptionMessage('Parameter "invalid-value" cannot be converted to enum: 2 is not a valid backing value for enum "Symfony\Component\HttpFoundation\Tests\Foo".');

$this->assertNull($bag->getEnum('invalid-value', Foo::class));
}
}
35 changes: 35 additions & 0 deletions src/Symfony/Component/HttpFoundation/Tests/ParameterBagTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -226,4 +226,39 @@ public function testGetBoolean()
$this->assertFalse($bag->getBoolean('string_false'), '->getBoolean() gets the string false as boolean false');
$this->assertFalse($bag->getBoolean('unknown'), '->getBoolean() returns false if a parameter is not defined');
}

public function testGetEnum()
{
$bag = new ParameterBag(['valid-value' => 1]);

$this->assertSame(Foo::Bar, $bag->getEnum('valid-value', Foo::class));

$this->assertNull($bag->getEnum('invalid-key', Foo::class));
$this->assertSame(Foo::Bar, $bag->getEnum('invalid-key', Foo::class, Foo::Bar));
}

public function testGetEnumThrowsExceptionWithNotBackingValue()
{
$bag = new ParameterBag(['invalid-value' => 2]);

$this->expectException(\UnexpectedValueException::class);
$this->expectExceptionMessage('Parameter "invalid-value" cannot be converted to enum: 2 is not a valid backing value for enum "Symfony\Component\HttpFoundation\Tests\Foo".');

$this->assertNull($bag->getEnum('invalid-value', Foo::class));
}

public function testGetEnumThrowsExceptionWithInvalidValueType()
{
$bag = new ParameterBag(['invalid-value' => ['foo']]);

$this->expectException(\UnexpectedValueException::class);
$this->expectExceptionMessage('Parameter "invalid-value" cannot be converted to enum: Symfony\Component\HttpFoundation\Tests\Foo::from(): Argument #1 ($value) must be of type int, array given.');

$this->assertNull($bag->getEnum('invalid-value', Foo::class));
}
}

enum Foo: int
{
case Bar = 1;
}

0 comments on commit 6b6c7df

Please sign in to comment.