Symfony вручную $form->submit(); с многомерным массивом

#symfony #symfony5

#symfony #symfony5

Вопрос:

Я уже 10 часов борюсь с Symfony 5.1.7 и $form-> submit();

Моя цель — JSON API, который преобразует данные в аналогичный массив. Я уже отладил и нашел следующую часть.

Может кто-нибудь, пожалуйста, помогите мне, что я здесь делаю не так?

Чтобы протестировать это, я вручную создал PHP-массив для его отправки.

Мой код в контроллере

         $form = $this->createForm(AddCommentFormType::class);

        $test = [
            'content' => 'Test',
            'media' => [
                [
                    'path' => '1.png',
                ],
                [
                    'path' => '2.png',
                ],
            ],
            '_token' => '3bF4qkiUPjKNuGnbY-ySdO6B2sCLzKcS4ar7auX3Dek',
        ];

        $form->submit($test);
 

AddCommentFormType

     public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('content', TextareaType::class, [
                'constraints' => [
                    new NotBlank(),
                    new Length([
                        'max' => 10000,
                    ]),
                ],
            ])
            ->add('media', CollectionType::class, [
                'entry_type' => MediaFormType::class,
                'constraints' => [
                    new Count([
                        'min' => 1,
                        'max' => 5,
                    ]),
                ],
            ])
            ->add('_token', HiddenType::class, [
                'mapped' => false,
                'constraints' => [
                    new NotBlank(),
                ],
            ])
        ;
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'csrf_protection' => false,
        ]);
    }
 

MediaFormType

     public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('path', TextType::class, [
                'constraints' => [
                    new NotBlank(),
                ],
            ])
        ;
    }

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

Результат проверки

 children[media].data
This collection should contain 1 element or more.   
[]


children[media]
This form should not contain extra fields.  
[▼
  [▼
    "path" => "1.png"
  ]
  [▼
    "path" => "2.png"
  ]
]
 

Комментарии:

1. Почему бы не отладить, как будет выглядеть «обычная» отправка формы?

2. Спасибо, я отредактирую позже с полным. Моя идея заключалась в том, чтобы сократить вопрос.

Ответ №1:

в вашей форме нет данных по умолчанию, поскольку вы создаете ее с помощью

 $form = $this->createForm(AddCommentFormType::class);
 

CreateForm может принимать дополнительный параметр для данных по умолчанию. Само по себе это не обязательно проблема, по умолчанию используется массив формы (или что-то очень похожее, возможно, пустые строки вместо null)

 [
    'content' => null, 
    'media' => [], 
    '_token' => null,
]
 

Однако CollectionType по умолчанию добавление или удаление элементов не допускается. Установка его параметров allow_add (и необязательно allow_remove , если вы когда-либо устанавливали значения по умолчанию) изменит это.

Таким образом, минимальное изменение будет:

             ->add('media', CollectionType::class, [
                'allow_add' => true,                  // <-- this is new
                'entry_type' => MediaFormType::class,
                'constraints' => [
                    new Count([
                        'min' => 1,
                        'max' => 5,
                    ]),
                ],
            ])
 

Ответ №2:

Если ваш тип AddCommentFormType, форма по умолчанию ожидает, что данные будут в ключах add_comment_form, например:

 $test = [
       ‘add_comment_form’ => [
           'content' => 'Test',
        'media' => [
            [
                'path' => '1.png',
            ],
            [
                'path' => '2.png',
            ],
        ],
        '_token' => '3bF4qkiUPjKNuGnbY-ySdO6B2sCLzKcS4ar7auX3Dek',
       ]
    ];
 

Комментарии:

1. Я уже пробовал это — все другие поля обнаружены правильно, только носитель. поле данных пустое. Но носитель без. данные найдены. Смотрите прикрепленный скриншот в первом сообщении.

2. @Aivina попробуйте добавить параметры allow_add и allow_remove к типу коллекции