2

It looks like symfony tries to help you out a lot with Validation but I am a bit confused. I have an Address object that looks like this

/**
 * @ORM\Entity
 * @ORM\Table(name="address")
 */
class Address {
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue
     * @var int $id
     */
    private $id;

    /**
     * @ORM\Column(name="street1", type="string", nullable=true)
     * @var string $street1
     */
    private $street1;

    /**
     * @ORM\Column(name="street2", type="string", nullable=true)
     * @var string $street2
     */
    private $street2;

    /**
     * @ORM\Column(name="street3", type="string", nullable=true)
     * @var string $street3
     */
    private $street3;

    /**
     * @ORM\Column(name="city", type="string", nullable=true)
     * @var string $city
     */
    private $city;

    /**
     * @ORM\Column(name="state", type="string", nullable=true)
     * @var string $state
     */
    private $state;

    /**
     * @ORM\Column(name="zip", type="integer", nullable=true)
     * @var integer $zip
     */
    private $zip;

    /**
     * @var AddressType
     * This is only used for previous addresses
     * @DoctrineAssert\Enum(entity="RLD\AppBundle\DBAL\AddressType")
     * @ORM\Column(name="address_type", type="AddressType", nullable=true)
     */
    private $addressType;
}

I am using this object twice. Once for Current address and another time for previous address. The problem is I only need the info for previous address if the user hasn't been in the current address for more than 5 years. I suspect I am going to need to extend the class in order to get what I want working. However even after extending I am not sure how to make conditional validation.

The Question

How do you make conditional validation?

if(currentAddress < 5)
    validate previous address;

Anyone have ideas for this? This form seems to carry a common theme across it that needs this functionality. Any help/suggestions would be appreciated.

2
  • 2
    How you can do the year control? Where is the field with the date? Usually i implements this kind of conditional validation with a Callback validator in conjunction with Validation Groups. Let me know if you need an example about it Commented Mar 23, 2015 at 8:13
  • @Matteo So can I use the Validation Group inside the Callback validator. I have been looking at the callback and I think its what I need the only thing I don't know is how to tell it to use a specific set of validation parameters and Groups does seem to do that job. I just cant figure out how to use them together. Commented Mar 23, 2015 at 15:21

2 Answers 2

1

You can use the validation group for activate selectively the validation callback. As Example:

Address Entity

/**
 *
 * @Assert\Callback(methods={"validateCurrentAddress"}, groups={"currentAddress"})
 * @Assert\Callback(methods={"validatePreviousAddress"}, groups={"previousAddress"})
 */
class Address
{

    ....

        public function validatePreviousAddress(ExecutionContextInterface $context)
    {
        if (/* is not valid */)
        {
            $context->addViolationAt('/*your field*/','error.previous_address_invalid');
        }

    }

}

CurrentAddressFormType

class CurrentAddressFormType extends AbstractType
{

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class'=> 'Acme\DemoBundle\Entity\Address',
            'validation_groups' => array('currentAddress')
        ));
    }
}

PreviousAddressFormType

class PreviousAddressFormType extends AbstractType
{

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class'=> 'Acme\DemoBundle\Entity\Address',
            'validation_groups' => array('previousAddress')
        ));
    }

Hope this help

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

Comments

1

What about using Traits?

http://php.net/manual/de/language.oop5.traits.php

Define a trait for your default attributes and then create 2 classes:

  • Class Address

  • Class PreviousAddress

The class PreviousAddress has the addiotional attribute.

You can then validate via instanceof:

if ($object instanceof PreviousAddress) {
    // has type
}

3 Comments

I am not very familiar with Traits however I would rather use the framework if possible. It seems like there would be a lot of overhead to get what you are talking about working in all the instances needed in this project. However this seems like a reasonable option to fall back on. Thank you!
You can also extend the class using Inheritance Strategies. But also you have to use instanceof
I am looking at Callbacks to accomplish this and then maybe using yml so I don't need to extend a class just for validation.

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.