I'm trying to validate enum type inside a custom DTO class. I'm trying to use the Symfony #[Assert\Choice] attribute but it seems that it doesn't work if I pass wrong value.
Custom DTO:
#[Assert\Choice(callback: 'getConditionTypes')]
public string $conditionType;
public static function getConditionTypes(): array
{
return array_column(ConditionType::cases(), 'name');
}
Enum class:
enum ConditionType: string
{
case NEW = "NEW";
case USED = "USED";
case CRASHED = "CRASHED";
case BROKEN = "BROKEN";
case FOR_PARTS = "FOR_PARTS";
}
When I try to pass a conditionType via Postman with a wrong value, for example "conditionType": "rand" it passes through the DTO without any issue and I'm trying to catch if there is wrong value. What am I missing?
Instead of providing a callback and using Assert\Choice, I used #[Assert\Type(type: ConditionType::class)] which automatically validates if the passed value is part of this enum.
UPDATE JULY 2025
I see that my previous answer is getting some upvotes, today I had to deal with the same problem and this time I used a different approach which also worked:
#[Assert\NotBlank]
#[Assert\Choice(callback: [ConditionType::class, 'getValues'])]
public string $conditionType;
public static function getValues(): array
{
return array_column(self::cases(), 'value');
}
If I pass the wrong value:
{
"errors": "Object(App\\DTO\\DealCreateDTO).conditionType:\n The value you selected is not a valid choice. (code 8e179f1b-97aa-4560-a02f-2a8b42e49df7)\n"
}
I hope this updated answer helps more people.
interface EnumValidate
{
public static function validate(string $item): bool;
}
trait ValidateEnumTrait
{
public static function validate(string $item): bool
{
if (!self::tryFrom($item) instanceof self) {
throw new ValidatorException($item . ' is not a valid backing value for enum ' . self::class);
}
return true;
}
}
enum MyEnum: string implements EnumValidate
{
use ValidateEnumTrait;
# …
In DTO
#[Assert\Callback([MyEnum::class, 'validate'])]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With