Ошибка формы Symfony2.4 'Эта форма не должна содержать лишних полей'

Я пытаюсь создать приложение на основе REST api angularJS. Я следил за этим руководством http://npmasters.com/2012/11/25/Symfony2-Rest-FOSRestBundle.html, но мне нужно изменить некоторые детали (устаревшие методы), и прямо сейчас, когда я публикую для создания нового объекта, я получаю ошибку «Эта форма не должна содержать дополнительных полей».

class MainController extends Controller
{
    public function indexAction(Request $request)
    {
        $form = $this->createForm(new TaskType(),null,array('action' => $this->generateUrl('post_tasks').'.json'))
                ->add('submit','submit');


        $note_form = $this->createForm(new NoteType())
                ->add('submit','submit');

        return $this->render('MyBundle:Main:index.html.twig',
                array(
                    'form'=>$form->createView(),
                    'note_form'=>$note_form->createView(),
                )
        );
    }
}

моя форма TaskType:

 public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder

            ->add('timeStart','datetime',array(
                'date_widget' => 'single_text',
                'time_widget' => 'single_text',
                'date_format' => 'yyyy-MM-dd',
                'data' => new \DateTime('now')
            ))

            ->add('timeStop','datetime',array(
                'date_widget' => 'single_text',
                'time_widget' => 'single_text',
                'date_format' => 'yyyy-MM-dd',
                'data' => new \DateTime('now')
            ))

            ->add('project')  
            ->add('descriptionTask')
            ->add('isCompleted',null,array('required' => false))  
            ->add('isVisible',null,array('required' => false))
        ;
    }

прямо сейчас, на мой взгляд, я визуализирую только одну форму, НО Я НАХОДЯСЬ НА ТЕСТИРОВАНИИ:

{%extends 'MyBundle::layout.html.twig' %}

{%block content %}

<div ng-view></div>

{{ form(form) }}

{% endblock %}

И это контроллер REST, который должен сбрасывать данную сущность:

public function cpostAction(Request $request)
{
 $entity = new Task();
 $form = $this->createForm(new TaskType(), $entity);
 $form->handleRequest($request);

 if ($form->isValid()) {

     $em = $this->getDoctrine()->getManager();
     $em->persist($entity);
     $em->flush();

     return $this->redirectView(
             $this->generateUrl(
                 'get_organisation',
                 array('id' => $entity->getId())
                 ),
             Codes::HTTP_CREATED
             );
 }

 return array(
     'form' => $form,
 );
}

СТРАННАЯ ВЕЩЬ: когда я помещаю тот же код из контроллера REST в MainController, форма проверяется и новый объект сбрасывается, но каким-то образом контроллер REST выдает ошибку ...


person mmmm    schedule 11.04.2014    source источник


Ответы (5)


Это потому, что когда вы создаете форму, вы добавляете кнопки отправки, но когда вы их проверяете, это не так. пытаться:

public function cpostAction(Request $request)
{
    $entity = new Task();
    $form = $this->createForm(new TaskType(), $entity)->add('submit','submit');
    ...

Кнопка отправки технически является полем, хотя по умолчанию symfony не отображает ее в свойство сущности. Поэтому, когда вы создаете форму с помощью кнопки отправки, а затем отправляете эту форму, форма, которую вы создаете в действии контроллера проверки, также должна иметь кнопку отправки.

person Chase    schedule 11.04.2014
comment
Большое спасибо за решение. Знаете ли вы, есть ли решение, которое не требует, чтобы я делал это с каждым из моих обработчиков форм? - person Jonathan; 20.04.2014
comment
Да, вместо того, чтобы добавлять отправку после факта, добавьте ее в свои Типы - person Chase; 21.04.2014

Если вы хотите, чтобы валидатор игнорировал дополнительные поля, попробуйте передать 'allow_extra_fields' => true в качестве параметра FormBuilder.

person Rudiger    schedule 29.07.2015
comment
Примечание: опция allow_extra_fields была добавлена ​​в Symfony v2.6 - person biphobe; 12.11.2015

Если вы хотите отключить проверку полей, вы должны добавить

public function setDefaultOptions(\Symfony\Component\OptionsResolver\OptionsResolverInterface $resolver)
{
    $resolver->setDefaults(array(
        'csrf_protection' => false,
        'validation_groups' => false,
    ));
}

И в методе buildForm:

    public function buildForm(FormBuilderInterface $builder, array $options) {
        $builder->addEventListener(FormEvents::POST_SUBMIT, function ($event) {
            $event->stopPropagation();
        }, 900);
        $builder->add('field1','text')
                ->add('field2','text')
                .
                .
                .
    } 

Для получения дополнительных сведений: http://symfony.com/doc/current/cookbook/form/dynamic_form_modification.html#cookbook-dynamic-form-modification-suppressing-form-validation

person Dapter20    schedule 30.07.2014
comment
Имейте в виду, что отключение csrf - это ужасная практика безопасности. Скорее всего, всегда есть лучший способ решения проблемы. - person csvan; 18.06.2015
comment
@csvan Но и не для спокойного API - person Arash Mousavi; 14.02.2017

Работа в Symfony 4/5 в CustomFormType

public function configureOptions(OptionsResolver $resolver)
{
    $resolver->setDefaults([
        'data_class' => CustomFormType::class,
        'allow_extra_fields' => true // <<<<<<<<<<<<<<<<<<<<<
    ]);
}
person DevWL    schedule 06.07.2020

Если вы добавляете одну кнопку SubmitType или аналогичную, вы используете решение, указанное Chausser

$entity = new Task();
$form = $this->createForm(new TaskType(), $entity)->add('submit','SubmitType::class');

Однако, если вы используете CollectionType и встраиваете набор вспомогательных форм, вам необходимо включить 'allow_add' => true в свои параметры для этого типа. Например, в вашем конструкторе форм EntityType:

$builder->add('subEntities', CollectionType::class, array(
                'entry_type' => SubEntityType::class,
                'entry_options' => array('label' => false),
                'allow_add' => true,
            ))

Убедитесь, что вы сделали это для всех уровней встраивания, если у вас несколько уровней.

person tlarson    schedule 18.10.2018