Micchaleq
Micchaleq

Reputation: 433

Symfony2: How to write a custom validator that validates a combination of 3 different properties at once?

I want to create a validator that validates a combination of 3 object properties.

I need to check package-size so I have to sum width, height and length.

I can't access height & length if I map the validator to the width field.

Is it possible using a custom validator for the whole form?

Upvotes: 1

Views: 116

Answers (2)

Nicolai Fröhlich
Nicolai Fröhlich

Reputation: 52483

You can define a class-level custom constraint somewhat like this to accomplish your aim:

use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;

class PackageSizeValidator extends ConstraintValidator
{

    public function validate($object, Constraint $constraint)
    {
        $packageSize = $object->getWidth() * $object->getHeight() * $object->getLength();

        if ( $packageSize <= 30 ) {
            return;
        }

        $this->context->addViolationAt(
           'length',
           'Package size exceeds 30.',
           array(),
           null
        );

        // ...
    }

    public function getTargets()
    {
        return self::CLASS_CONSTRAINT;
    }

    public function validatedBy()
    {
       return 'package_size';
    }
}

Now define it as a service and tag it as a validator.

# app/config/config.yml

services:
    validator.package_size:
        class: Vendor\YourBundle\Validation\Constraints\PackageSizeValidator   
        tags:
            - { name: validator.constraint_validator, alias: package_size }

Upvotes: 3

moonwave99
moonwave99

Reputation: 22817

You can create a class constraint validator, as per documentation, e.g.:

class ProtocolClassValidator extends ConstraintValidator
{
    public function validate($protocol, Constraint $constraint)
    {
        if ($protocol->getFoo() != $protocol->getBar()) {
            $this->context->addViolationAt(
                'foo',
                $constraint->message,
                array(),
                null
            );
        }
    }
}

Upvotes: 1

Related Questions