Skip to content

Make ConstraintValidator->formatValue aware of enums #50000

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
PhoneixS opened this issue Apr 12, 2023 · 1 comment · Fixed by #50017
Closed

Make ConstraintValidator->formatValue aware of enums #50000

PhoneixS opened this issue Apr 12, 2023 · 1 comment · Fixed by #50017

Comments

@PhoneixS
Copy link
Contributor

Description

The Symfony\Component\Validator\ConstraintValidator->formatValue() method transforms values of a form into strings so they can be used in the error message. Now, if it is an object it checks if it's Stringable to convert it correctly, and if it isn't, it will use the value "Object".

When the value is an enum, it will consider it as an object and check if it implements Stringable, the problem is that enums can't implement the magic method __toString() so it will be always "Object" which isn't too useful.

I propose to make it enum aware by adding a check to see if it's an enum and in that case use the name as value (or a concatenation of Enum-{name} to represent it.

Example

For example, with the next code for validation of a form model:

// EnumNiceClass.php
enum EnumNiceClass: int {
    case DoSomething = 2;
    case NothingToDo = 3;
}

// FormModel.php
class FormModel {

Assert\NotIdenticalTo(
        value: EnumNiceClass::DoSomething,
)]
public EnumNiceClass $whatWillDo;

}

You will get the next message if it is invalid (with the default message This value should not be identical to {{ compared_value_type }} {{ compared_value }}.:

This value should not be identical to EnumNiceClass Object.

But changing the code to something like this:

    protected function formatValue(mixed $value, int $format = 0): string
    {

// ...

        if (\is_object($value)) {
            if (($format & self::OBJECT_TO_STRING) && $value instanceof \Stringable) {
                return $value->__toString();
            }
            
            if ($value instanceof \UnitEnum) {
                return $value->name;
            }

            return 'object';
        }
// ...

It would be:

This value should not be identical to EnumNiceClass NothingToDo.

That I think is more useful for debugging (and users in general).

@stof
Copy link
Member

stof commented Apr 12, 2023

Please submit a pull request. This change makes sense to me.

nicolas-grekas added a commit that referenced this issue Apr 19, 2023
…ormatValue` (PhoneixS)

This PR was submitted for the 6.2 branch but it was squashed and merged into the 5.4 branch instead.

Discussion
----------

[Validator] Fix support of Enum to `ConstraintValidator::formatValue`

| Q             | A
| ------------- | ---
| Branch?       | 5.4
| Bug fix?      | yes
| New feature?  | no
| Deprecations? | no
| Tickets       | Fix #50000
| License       | MIT

I have added a simple check in the `formatValue` to see if the object is an enum and in that case, return the name of the enum instead of the "object" string.

Commits
-------

128b3da [Validator] Fix support of Enum to `ConstraintValidator::formatValue`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants