4

I am trying to validate an attribute at a field level by the @Assert\Expression (http://symfony.com/doc/2.4/reference/constraints/Expression.html).

It works at a class level with this code:

/**
 * Foo
 * 
 * @ORM\Table(name="foo")
 * @ORM\HasLifecycleCallbacks()
 * @UniqueEntity("slug")
 * @Assert\Expression(
 *     "this.getPriceFor2PaxStandard() != null or (this.getPriceFor2PaxStandard() == null and !this.isPriceForAccLevelRequired('standard'))",
 *     message="The price for 2 pax standard is required",
 *     groups={"agency_tripEdit_finalsave"}
 * )
 * 
 */
class Foo implements ISpellcheckerLocaleProvider, ProcessStatusAware, DataTransformer
{

but if I use the same code (which should be fine) at attribute level is not working:

/**
     * @var decimal
     *
     * @ORM\Column(name="price_for_2_pax_standard", type="decimal", precision=16, scale=4, nullable=true)
     * @Assert\Expression(
     *     "this.getPriceFor2PaxStandard() != null or (this.getPriceFor2PaxStandard() == null and !this.isPriceForAccLevelRequired('standard'))",
     *     message="The price for 2 pax standard is required",
     *     groups={"agency_tripEdit_finalsave"}
     * )
     */
    private $priceFor2PaxStandard;

In addition, does not work either if I use value instead of this.getPriceFor2PaxStandard() when using the asseriont as a attribute level.

Any hint would be appreciated :-)

0

1 Answer 1

5

It is a bug in symfony. If you look at the code for the ExpressionValidator you can see it skips validating if the value is null or an empty string. This is useful for some other constraints but pointless in the ExpressionValidator. I have just submitted a pull request to fix it. The easiest way around this at the moment would be to swap to a callback validator.

<?php

namespace Symfony\Component\Validator\Constraints;

use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\Exception\UnexpectedTypeException;

class ExpressionValidator extends ConstraintValidator
{
    public function validate($value, Constraint $constraint)
    {
        if (!$constraint instanceof Expression) {
            throw new UnexpectedTypeException($constraint, __NAMESPACE__.'\Expression');
        }

        if (null === $value || '' === $value) {
            return;
        }

        //...
    }

    //...

}
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks Tom! I still validating with the expression language but a class level, what works fine. It's just that I wanted to have a clearer code.
Looks like a PR has been merged and the issue was supposed to be fixed since 2.6, right @Tom Corrigan? github.com/symfony/symfony/pull/11709 But my expression still isn't fired if the property / value is null: /** @Assert\Expression("this.getLoggiaHandrail() == '1' and value != null) */ $loggiaHandRailMaterial;

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.