Symfony2 custom validators

I have an Entity with multiple custom validators as in:

use Digital\ApplicationBundle\Validator\Constraints\ConstrainsUsername;
use Digital\ApplicationBundle\Validator\Constraints\ConstrainsProduct;
use Digital\ApplicationBundle\Validator\Constraints\ConstrainsGiftValid;

/**
 * @DigitalAssert\ConstrainsGiftValid
 */
class Gift
{

/**
 * @DigitalAssert\ConstrainsUsername
 */
private $username;

/**
 * @DigitalAssert\ConstrainsProduct
 */
private $productName;
[...]

      

My question is how can I set the check order ....

I would like to check my properties first, and if the properties are valid, I would like to check if the two properties are allowed to "be" together ...

Therefore, my case requires a certain check order.

How can this be done, please?

The current problem is checking my class. "ConstrainsGiftValid" is triggered before them; S

Any help is greatly appreciated.

+3


source to share


2 answers


OK, transferring all in one constraint worked.

This includes the error of binding to a specific property and error on different messages for different failures:



public function isValid($gift, Constraint $constraint)
{

    // Validate product.
    /** @var $product Product */
    $product = $this->em->getRepository('DigitalApplicationBundle:Shop\Product')->findOneBy(array('name' => $gift->getProductName()));
    if (!$product instanceof Product) {

        $this->context->addViolationAtSubPath('username', $constraint->messageProduct, array('%string%' => $gift->getProductName()), null);
        return false;

    }

    // Validate user.
    /** @var $user User */
    $user = $this->em->getRepository('DigitalUserBundle:User')->findOneBy(array('username' => $gift->getUsername()));
    if (!$user instanceof User) {

        $this->context->addViolationAtSubPath('username', $constraint->messageUser, array('%string%' => $gift->getUsername()), null);
        return false;
    }


    // Gift correct type of the item!
    if (($product->getType() != 0) && ($user->getGender() !== $product->getType())) {

        $this->context->addViolationAtSubPath('username', $constraint->messageType, array('%string%' => $gift->getProductName()), null);
        return false;

    }

    // If already owning this product.
    foreach ($user->getWardrobe()->getProducts() as $wardrobeProduct) {
        if ($product == $wardrobeProduct) {

            $this->context->addViolationAtSubPath('username', $constraint->message, array('%string%' => $gift->getProductName(), '%user%' => $gift->getUsername()), null);
            return false;
        }
    }

    return true;
}

      

+1


source


To check if $username

and are $productName

, you need to create a custom check constraint .

If you need a specific order of authentication and want to reuse the validation of those two fields in your code, I think this should do it:

1 Create a form type for {username and productName}.



2Apply your validation rules to this type of form. You will need to apply constraints to the entire form in this particular case if you want to play with the check order. Therefore, you can just throw the errors if you want, and in the order you want.

3Finally, you can paste this formType

into yours GiftFormType

. Remember to use a valid constraint or set the parameter to a cascade_validation

value true

for inline form validation.

+1


source







All Articles