For now I've successful used validation groups, but now I'm stuck with validation groups and nested mapped entities.
I'll explain the problem by a simplified example.
My entities: Address, Damage, Appliance
/**
* @ORM\Entity()
*/
class Address extends ...
{
/**
* @var string
* @ORM\Column(type="string", name="postcode", nullable=true)
* @Assert\NotBlank(
* groups={
* "damage_responsible_address",
* "appliance_repairer_address",
* })
*/
private $postcode;
...
/**
* @ORM\Entity()
*/
class Damage extends ...
{
/**
* @var boolean
* @ORM\Column(type="boolean", name="responsible", nullable=true)
* @Assert\NotBlank(groups={"damage"})
*/
private $responsible;
/**
* @ORM\OneToOne(targetEntity="Address", cascade={"persist","remove"})
* @ORM\JoinColumn(name="responsible_address_id", referencedColumnName="id")
* @Assert\Valid()
*/
private $responsibleAddress;
/**
* @ORM\ManyToMany(targetEntity="Appliance", orphanRemoval=true, cascade={"persist", "remove"})
* @ORM\JoinTable(name="coronadirect_cuzo_home_damage_appliances",
* joinColumns={@ORM\JoinColumn(name="damage_id", referencedColumnName="id")},
* inverseJoinColumns={@ORM\JoinColumn(name="appliance_id", referencedColumnName="id")}
* )
*/
private $appliances;
...
/**
* @ORM\Entity()
*/
class Appliance extends ...
{
/**
* @var boolean
* @ORM\Column(type="boolean", name="to_repair", nullable=true)
* @Assert\NotBlank(groups={"appliance"})
*/
private $toRepair;
/**
* @ORM\OneToOne(targetEntity="Address", cascade={"persist","remove"})
* @ORM\JoinColumn(name="repairer_address_id", referencedColumnName="id")
* @Assert\Valid()
*/
private $repairAddress;
...
To define my forms I use a AddressType, DamageType and ApplianceType:
class DamageType extends ...
{
/**
* {@inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('appliances', 'collection', array(
'type' => 'home_damage_appliance_type',
'allow_add' => true,
'allow_delete' => true,
'prototype' => true,
'options' => array(
'cascade_validation' => true,
)
));
$builder->add('responsible', 'choice', array(
'choices' => $this->getYesNoChoiceArray(),
'expanded' => true,
'multiple' => false,
));
$builder->add('responsibleAddress', 'address_type', array(
'required' => true
));
...
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Damage',
'cascade_validation' => true,
'validation_groups' =>
function(FormInterface $form) {
$groups = array('damage');
if ($form->getData()->getResponsible() == true) {
$groups[] = 'damage_responsible_address';
}
return $groups;
}
));
}
I'm adding the damage_responsible_address group when responsible is set to true in the form. Otherwise I don't want the address to be validated.
class ApplianceType extends ...
{
/**
* {@inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('toRepair', 'choice', array(
'choices' => $this->getYesNoChoiceArray(),
'expanded' => true,
'multiple' => false,
));
$builder->add('repairAddress', 'address_type', array(
'required' => true
));
...
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Appliannce',
'cascade_validation' => true,
'validation_groups' =>
function(FormInterface $form) {
$groups = array('appliance');
if ($form->getData()->getToRepair() == true) {
$groups[] = 'appliance_repairer_address';
}
return $groups;
}
));
}
Same as previous, when toRepair is true I want to validate the address.
What's going wrong ?
I the Damage responsible is true and the appliance toRepair is false, the form does give validation errors on the responsible address BUT also on the the appliance address.
The same for the other way arround: When an appliance address is invalid (toRepar is true), then the responsibleAddress is also invalid (even when responsible is false).
The address validation groups don't look on which form they are defined, but just attatch them to every address item in the form.
Is it possible to define validation groups specific for a form only?
I am using Doctrine and Symfony 2.3.6.