zerkms
zerkms

Reputation: 255155

Validating decimals in symfony 2

I have symfony2 entity mapped to a table using Doctrine. One of the properties is:

/**
 * @var decimal $price
 *
 * @ORM\Column(name="price", type="decimal", nullable=false)
 */
private $price;

What Assert would satisfy my requirement that $price should be a valid decimal?

If I stay things as-is then passing string foo as a decimal value will lead to validation error, while passing string NaN passes validation, because the string NaN is mapped as float(NaN) thus treated as a valid decimal value.

Any workarounds?

Symfony dev team assures it is not an issue: https://github.com/symfony/symfony/issues/3161

Well, if it is not - then there is probably a solution to validate it. Any ideas?

Upvotes: 5

Views: 9628

Answers (4)

Azhar Khattak
Azhar Khattak

Reputation: 875

You can simply use @Assert\Type(type="Numeric"). Tested in symfony 3.4 but I think it will works with previous versions as well. E.g.

 /**
 * @var float
 *
 * @ORM\Column(name="cost", type="decimal", precision=10, scale=4)
 * @Assert\Type(type="Numeric")
 */
private $cost;

Thanks!

Upvotes: 1

valdas.mistolis
valdas.mistolis

Reputation: 1341

If you are using form type for record

        ->add(
            'amount',
            'text', change text to number and it will be validated 
            [
                'required' => true
            ]
        )

Or you can use range assert

  • @Assert\Range(min=0)

it will validate that it should be number

Upvotes: 2

JamesHalsall
JamesHalsall

Reputation: 13505

From looking at the Symfony documentation, there isn't a built in validator for decimals. You could use a callback validator, or better still you could create your own custom validator like this article describes here.

As for the actual validation, I'd use a combination of is_numeric and is_float to check. There are methods using regex, but in my opinion if the value satisfies either the is_numeric or is_float check then you can safely assume it is a valid decimal (or a whole number).

EDIT:

Maybe the best solution would be to validate the decimal as a string. Something like...

$stringDecimal = strval($decimalValue);
return (preg_match(/[0-9]+(\.[0-9][0-9]?)?/, $stringDecimal) !== 0);

Whilst this isn't perfect (you could easily pass '1.15adowadjaow' and it would validate), it serves the basis of what you're after. Combining the above regex with something that searches for anything other than 0-9, fullstop or comma (depending if you want to cater for European decimal formatting).

Upvotes: 6

maiwald
maiwald

Reputation: 932

you could try a custom validator that checks just for that string.

Upvotes: 2

Related Questions