I made a search form where several entities are present. I would like to keep last values entered so that when user comes back to the form, he retrieves his last choices.
By trying to do so, I retrieve myself with the following error :
Entity of type "App\Entity\BigCity" passed to the choice field must be managed. Maybe you forget to persist it in the entity manager?
When I saw this error, I added the following line : $entityManagerInterface->persist($data); but I retrieve myself with an other error :
EntityManager#persist() expects parameter 1 to be an entity object, array given.
What should I do to avoid these errors ?
EventsController.php
<?php
namespace App\Controller;
use App\Form\SearchType;
use App\Repository\EventsRepository;
use App\Repository\CategoriesRepository;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
class EventsController extends AbstractController
{
private $requestStack;
public function __construct(RequestStack $requestStack)
{
$this->requestStack = $requestStack;
}
#[Route('/search', name: 'search')]
public function search(Request $request, EntityManagerInterface $entityManagerInterface,)
{
$data = $request->query->all();
$sessionFormData = $sessionInterface->get('data');
$form = $this->createForm(SearchType::class, $sessionFormData);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$data = $form->getData();
$session->set('data', $data);
return $this->render('front/events.html.twig', $data);
}
return $this->renderForm('front/search.html.twig', [
'form' => $form
]);
}
SearchType.php
<?php
namespace App\Form;
use App\Entity\BigCity;
use App\Entity\Categories;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
class SearchType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder
->add('bigcity', EntityType::class, [
'class' => BigCity::class,
'choice_label' => 'name',
'placeholder' => 'Sélectionne une grande ville'
])
->add('category', EntityType::class, [
'class' => Categories::class,
'choice_label' => 'image',
'expanded' => true,
'multiple' => false,
])
->add('save', SubmitType::class)
;
}
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults([
'data_class' => null
]);
}
}
CodePudding user response:
if you want to save values in session you can use SessionInterface, after that you pass the sessions values in the options of createForm method
use Symfony\Component\HttpFoundation\Session\SessionInterface;
public function someAction(Request $request, SessionInterface $session)
{
$data = $request->request->all();
$sessionSearchFormData = $session->get('searchFormData'); // null at the first time
$form = $this->createForm(SearchType::class, null, ['sessionSearchFormData'=> $sessionSearchFormData]);
$form->handleRequest($request);
if($form->isSubmitted())
{
// put values of form in session just after each time the form is submitted
$session->set('searchFormData', $data);
}
}
use Doctrine\ORM\EntityManagerInterface;
class SearchType extends AbstractType
{
private EntityManagerInterface $entityManager;
public function __construct(EntityManagerInterface $entityManager)
{
$this->entityManager = $entityManager;
}
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$bigcity = $options['sessionSearchFormData'] !== null ? $options['sessionSearchFormData']['bigcity'] : '';
$builder
->add('bigcity', EntityType::class, [
'class' => BigCity::class,
'choice_label' => 'name',
'placeholder' => 'Sélectionne une grande ville',
'data'=> $bigcity !== null ? $this->entityManager->getRepository(BigCity::class)->find($bigcity) : ''
])
->add('category', EntityType::class, [
'class' => Categories::class,
'choice_label' => 'image',
'expanded' => true,
'multiple' => false,
])
->add('save', SubmitType::class)
;
}
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults([
'data_class' => null,
'sessionSearchFormData' => null, // don't forget this
]);
}
EDIT:
This is another solution, you don't need to do anything in the formType nor passing any values as options, just remove $form->handleRequest and add $form->submit()
In twig
<form action="" method="post">
The controller
public function someAction(Request $request, SessionInterface $session)
{
// $data = $request->query->all(); // if GET method
$data = $request->request->all(); // if POST method
if($request->getMethod() === 'POST') {
$session->set('searchFormData', $data);
}
$sessionSearchFormData = $session->get('searchFormData');
$form = $this->createForm(SearchType::class);
$form->submit($sessionSearchFormData);
return $this->renderForm('front/search.html.twig', [
'form' => $form
]);
}