Symfony preSubmit form event changes are not saved to the controller / are saved

I need to make changes to the collection (Symfony CollectionType form) to respect the ordering and deletion of objects, and I use the preSubmit event preSubmit to make changes as per this suggestion . However, the changes do not return to the controller / persistence.

The data is correct after preSubmit and is set in the event using $event->setData($data) , but the changes are not saved after sending to $form->getData()

My imagine an abstract class:

 abstract class AbstractEntityFormType extends AbstractType { /** * @param FormBuilderInterface $builder * @param array $options */ public function buildForm(FormBuilderInterface $builder, array $options) { $builder->addEventListener(FormEvents::PRE_SUBMIT, [$this, 'onPreSubmit']); } /** * @param FormEvent $event */ public function onPreSubmit(FormEvent $event) { $form = $event->getForm(); $data = $event->getData(); $document = $form->getData(); foreach ($form->all() as $field) { /** @var FormInterface $field */ $fieldName = $field->getName(); if ($field->getConfig()->getType()->getInnerType() instanceof CollectionType) { // .. DO ALL TRANSFORMATION } } $event->setData($data); } } 

When I give $data here, everything is correct.

FormType extending this AbstractEntityFormType class:

 class DocumentType extends AbstractEntityFormType { /** * @param FormBuilderInterface $builder * @param array $options * @return void */ public function buildForm(FormBuilderInterface $builder, array $options) { /** ADD THE LISTENER **/ parent::buildForm($builder, $options); $builder->add('title', TextType::class, [ 'required' => true, 'constraints' => [ new NotBlank([ 'message' => '"title" is empty', ]), ], ]); $builder->add('symptoms', CollectionType::class, [ 'entry_type' => SymptomType::class, 'allow_add' => true, 'allow_delete' => true, 'by_reference' => false, ]); $builder->add('tags', CollectionType::class, [ 'entry_type' => TagType::class, 'allow_add' => true, 'allow_delete' => true, 'by_reference' => false, ]); $builder->add('submit', SubmitType::class); } /** * @param OptionsResolver $resolver * @return void */ public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults([ 'data_class' => Document::class, ]); } } 

My controller action:

 /** * @param Request $request * @param int|null $documentId * @return Response */ public function formAction(Request $request, int $documentId = null) { if (!$documentId) { $document = new Document(); } else { try { $document = $this->documentService->getDocument($documentId); } catch (InvalidDocumentException $e) { return new NotFoundResponse('Document not found'); } } $document = $this->setAuthor($document); $form = $this->formFactory->create(DocumentType::class, $document); $form->handleRequest($request); if ($form->isSubmitted() && $form->isValid()) { $document = $this->documentService->createDocument($form->getData()); return new RedirectResponse($this->router->generate('ui.document.view', [ 'documentId' => $document->getId() ])); } return $this->templating->renderResponse( '@KBS/Document/form.html.twig', [ 'form' => $form->createView(), ] ); } 

When I delete $form->getData() before continuing with this service, the data is incorrect - it was not affected by preSubmit . What am I missing?

FYI, this uses the core components of Symfony 3.2.

Update

Thanks @LBT, I'm a little closer, but still run into some issues. Using this approach in the controller, I can get the correct data from the request at the time the form is submitted:

 public function formAction(Request $request, int $documentId = null) { if (!$documentId) { $document = new Document(); } else { try { $document = $this->documentService->getDocument($documentId); } catch (InvalidDocumentException $e) { return new NotFoundResponse('Document not found'); } } $document = $this->setAuthor($document); $form = $this->formFactory->create(DocumentType::class, $document); if ($request->isMethod('POST')) { $form->submit($request->request->get($form->getName())); if ($form->isSubmitted() && $form->isValid()) { $document = $this->documentService->createDocument($form->getData()); return new RedirectResponse($this->router->generate('ui.document.view', [ 'documentId' => $document->getId() ])); } } return $this->templating->renderResponse( '@KBS/Document/form.html.twig', [ 'form' => $form->createView(), ] ); } 

However, $form->submit($request->request->get($form->getName())); also saves incorrect (original) data before conversion. Even if the data in the request is correct:

 /var/www/html/src/Controller/DocumentController.php:94: array (size=8) 'title' => string 'Tag test' (length=8) 'symptoms' => array (size=1) 0 => array (size=3) 'position' => string '0' (length=1) 'title' => string 'The smell is terrible' (length=21) 'description' => string 'pew' (length=3) 'tags' => array (size=4) 0 => array (size=1) 'title' => string 'Volvo' (length=5) 1 => array (size=1) 'title' => string 'Engine' (length=6) 2 => array (size=1) 'title' => string 'BMW' (length=3) 3 => array (size=1) 'title' => string 'Funky' (length=5) 

It seems like I'm getting closer, but it seems like I can't use this query data as suggested in the documentation for for some reason.

+6
source share

Source: https://habr.com/ru/post/1014936/


All Articles