简体   繁体   English

Symfony - 有条件地对嵌入式收集表单进行验证

[英]Symfony - Embedded Collection Form validation conditionally

I have a carousel with a collection of slides (OneToMany) and each slide contain a file that I have to validate if not exist.我有一个带有一组幻灯片 (OneToMany) 的轮播,每张幻灯片都包含一个文件,如果不存在,我必须验证该文件。

When a slide has no file, the field is required but when the file exist, it's not required.当幻灯片没有文件时,该字段是必需的,但当文件存在时,则不是必需的。

My CarouselType:我的轮播类型:

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('slides', CollectionType::class, [
            'entry_type' => SlideType::class,
            'allow_add' => true,
            'allow_delete' => true,
            'prototype' => true,
            'by_reference' => false,
            'row_attr' => [
                'class' => 'hidden'
            ]
        ]);
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => Carousel::class,
        ]);
    }

My SlideType:我的幻灯片类型:

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('title', TextType::class, [
                'row_attr' => [
                    'class' => 'form-group'
                ],
                'attr' => [
                    'class' => 'form-control'
                ],
                'required' => false
            ])
            ->add('url', UrlType::class, [
                'row_attr' => [
                    'class' => 'form-group'
                ],
                'attr' => [
                    'class' => 'form-control'
                ],
                'required' => false
            ])
            ->add('file', FileType::class, [
                'row_attr' => [
                    'class' => 'form-group'
                ],
                'attr' => [
                    'class' => 'form-control'
                ],
                'required' => false
            ]);
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => Slide::class,
            'validation_groups' => function (FormInterface $form) {
                $data = $form->getData();

                if ($data->getFile() === null && $data->getFileName() === null) {
                    return ['upload'];
                }

                return ['Default'];
            },
        ]);
    }

My Carousel Entity:我的轮播实体:

/**
 * @ORM\Entity(repositoryClass=CarouselRepository::class)
 */
class Carousel
{
    /**
     * @ORM\Id
     * @ORM\GeneratedValue
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\OneToMany(
     *     targetEntity=Slide::class,
     *     mappedBy="carousel",
     *     fetch="EXTRA_LAZY",
     *     orphanRemoval=true,
     *     cascade={"persist"}
     * )
     * @Assert\Count(min=1, minMessage="carousel.slides.count.min")
     * @Assert\Valid(groups={"upload"})
     */
    private $slides;

    ...
    ...
}

My Slide Entity:我的幻灯片实体:

/**
 * @ORM\Entity(repositoryClass=SlideRepository::class)
 */
class Slide
{
    /**
     * @ORM\Id
     * @ORM\GeneratedValue
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\Column(type="string", length=100, nullable=true)
     */
    private $title;

    /**
     * @ORM\Column(type="string", length=255, nullable=true)
     */
    private $url;

    /**
     * @ORM\Column(type="string", length=255, nullable=true)
     */
    private $fileName;

    /**
     * @var UploadedFile
     * @Assert\NotNull(message="slide.file.not_null", groups={"upload"})
     */
    protected $file;

    /**
     * @ORM\ManyToOne(targetEntity=Carousel::class, inversedBy="slides")
     * @ORM\JoinColumn(nullable=false)
     */
    private $carousel;

    ...
    ...
}

I've added validation_groups in my SlideType but it's not working.我在我的 SlideType 中添加了validation_groups但它不起作用。 What's wrong with my code?我的代码有什么问题?

You need to use "valid" to validate the subform.您需要使用“有效”来验证子表单。

https://symfony.com/doc/current/reference/constraints/Valid.html https://symfony.com/doc/current/reference/constraints/Valid.html

$builder->add('slides', CollectionType::class, [
        'entry_type' => SlideType::class,
        'allow_add' => true,
        'allow_delete' => true,
        'prototype' => true,
        'by_reference' => false,
        'row_attr' => [
            'class' => 'hidden'
        ],
        'constraints' => [new Valid()],
    ]);

Use PreSetData Event for adding file in the SlideType使用PreSetData 事件在 SlideType 中添加file

   $builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) {
        $data = $event->getData();
        $isNotRequired = ($data instanceof Slide) && $data->getUrl();
        $constraints = isNotRequired ? [] : [new NotBlank()];
       
        $event->getForm()->add('file', FileType::class, [
            'row_attr' => [
                'class'   => 'form-group'
            ],
            'attr' => [
                'class'   => 'form-control'
            ],
            'required'    => !$isNotRequired,
            'constraints' => $constraints,
        ]);
    });

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM