今のところ、検証グループの使用に成功しましたが、検証グループとネストされたマップされたエンティティに行き詰まっています。
簡単な例で問題を説明します。
マイ エンティティ: アドレス、ダメージ、アプライアンス
/**
* @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;
...
フォームを定義するには、AddressType、DamageType、および 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;
}
));
}
フォームで責任者が true に設定されている場合、damage_responsible_address グループを追加しています。そうでなければ、アドレスを検証したくありません。
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;
}
));
}
前と同じように、toRepair が true の場合、アドレスを検証します。
何が問題なのですか?
損害の責任が true で、アプライアンス toRepair が false の場合、フォームは責任のあるアドレスで検証エラーを返しますが、アプライアンスのアドレスでも検証エラーを返します。
逆の場合も同様です。アプライアンス アドレスが無効な場合 (toRepar が true)、responsibleAddress も無効です (responsible が false であっても)。
住所検証グループは、定義されているフォームを調べませんが、フォーム内のすべての住所項目に添付するだけです。
フォーム専用の検証グループを定義することはできますか?
Doctrine と Symfony 2.3.6 を使用しています。