我尝试使用一些简单的组规则来验证CollectionType内的FormType,但是它不起作用,但是如果我尝试不通过验证组来使FormType保持一致,则效果很好。 任何想法? 这是一个完整且简单的示例,可重现错误https://github.com/ychakroun/symfony-collection-type-issue
/**
* Sticker
*
* @ORM\Table(name="sticker")
* @ORM\Entity(repositoryClass="App\Repository\StickerRepository")
*/
class Sticker
{
/**
* @var \Doctrine\Common\Collections\Collection
*
* @ORM\OneToMany(targetEntity="App\Entity\Link", mappedBy="sticker", cascade={"persist", "remove"}, orphanRemoval=true)
* @ORM\OrderBy({"position"="ASC"})
* @Assert\Valid()
*/
private $links;
}
/**
* Link
*
* @ORM\Table(name="link")
* @ORM\Entity(repositoryClass="App\Repository\LinkRepository")
*/
class Link
{
/**
* @var mixed
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* @var string|null
* @Assert\NotBlank()
*
* @ORM\Column(name="title", type="string")
*/
private $title;
/**
* @var bool
*
* @ORM\Column(name="external", type="boolean")
*/
private $external;
/**
*
* @var string|null
*
* @Assert\NotBlank(groups={"isExternal"})
* @Assert\Url(groups={"isExternal"})
* @ORM\Column(name="url", type="text", nullable=true)
*/
private $url;
/**
* @var \App\Entity\PageVersion|null
*
* @Assert\NotBlank(groups={"isInternal"})
* @ORM\ManyToOne(targetEntity="App\Entity\PageVersion")
* @ORM\JoinColumns({
* @ORM\JoinColumn(name="page_version_id", referencedColumnName="id", nullable=true)
* })
*/
private $pageVersion;
/**
* @var \App\Entity\Category|null
*
* @Assert\NotBlank(groups={"isInternal"})
* @ORM\ManyToOne(targetEntity="App\Entity\Category", inversedBy="links")
* @ORM\JoinColumns({
* @ORM\JoinColumn(name="category_id", referencedColumnName="id", nullable=true)
* })
*/
private $category;
/**
* @var \App\Entity\Sticker|null
*
* @ORM\ManyToOne(targetEntity="App\Entity\Sticker", inversedBy="links")
* @ORM\JoinColumns({
* @ORM\JoinColumn(name="sticker_id", referencedColumnName="id", nullable=true)
* })
*/
private $sticker;
}
这是我使用的表格:
class StickerType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('links', CollectionType::class, [
'entry_type' => LinkType::class,
'allow_add' => true,
'allow_delete' => true,
'delete_empty' => true,
'attr' => [
'class' => 'collection',
],
'by_reference' => false,
])
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => Sticker::class,
]);
}
}
class LinkType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('title', TextType::class, [
'label' => 'Titre du menu:',
'attr' => [
'input-group' => 'true',
],
])
->add('external', ChoiceType::class, [
'label' => false,
'expanded' => true,
'choices' => [
'Lien interne' => false,
'Lien externe' => true,
],
'choice_attr' => [
'class' => 'link-type',
],
'label_attr' => [
'class' => 'btn-group btn-group-toggle',
'data-toggle' => 'buttons',
]
])
->add('url', UrlType::class, [
'label' => 'SAISISSEZ L\'URL EXTERNE',
'attr' => ['placeholder' => 'https://'],
])
->add('pageVersion', EntityType::class, [
'required' => false,
'class' => Page::class,
'choice_label' => 'name',
])
->add('category', EntityType::class, [
'required' => false,
'class' => Category::class,
'choice_label' => 'title',
'query_builder' => function (CategoryRepository $er) {
return $er->createQueryBuilder('c')->where('c.enabled = 1');
},
])
->add('position', HiddenType::class, [
'attr' => [
'class' => 'my-position',
],
])
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => Link::class,
'cascade_validation' => true,
'validation_groups' => function (FormInterface $form) {
/** @var Link $link */
$link = $form->getData();
$groups = ['Default'];
if ($link->getExternal()) {
$groups[] = 'isExternal';
} else {
$groups[] = 'isInternal';
}
return $groups;
},
]);
}
}
我们可以看到url字段已经过验证,并且为空
答案 0 :(得分:0)
我认为您也需要在Sticker实体上添加验证组:
/**
* Sticker
*
* @ORM\Table(name="sticker")
* @ORM\Entity(repositoryClass="App\Repository\StickerRepository")
*/
class Sticker
{
/**
* @var \Doctrine\Common\Collections\Collection
*
* @ORM\OneToMany(targetEntity="App\Entity\Link", mappedBy="sticker", cascade={"persist", "remove"}, orphanRemoval=true)
* @ORM\OrderBy({"position"="ASC"})
* @Assert\Valid(groups={"isInternal", "isExternal"})
*/
private $links;
}
答案 1 :(得分:0)
此选项仅在根格式上有效,用于指定验证者将使用哪些组。
答案 2 :(得分:0)
您好,我们必须添加一个addEventListener
class StickerType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('links', CollectionType::class, [
'entry_type' => LinkType::class,
'allow_add' => true,
'allow_delete' => true,
'delete_empty' => true,
'attr' => [
'class' => 'collection',
],
'by_reference' => false,
])
->addEventListener(FormEvents::PRE_SUBMIT, array($this, 'onPreSubmit'));
;
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => Sticker::class,
]);
}
public function onPreSubmit(FormEvent $event)
{
if ($event->getData()) {
$data = $event->getData();
$data['links'] = array_values($data['links']);
$event->setData($data);
}
}
}