I’m working on a Symfony project where an I have two types of User Client and EmployeSpie, both have their own entity.
When you create/edit a user you can link EmployeSpie to a CLient. That’s where is my problem, When I edit or create a user I can create a user but nothing is store inside my table which make the link between my table Client and EmployeSpie.
Here is what I’ve done:
my entity Client having this:
class Client extends User { /** * @ORMManyToMany(targetEntity=EmployeSpie::class, mappedBy="clients", cascade={"persist"}) */ private $employeSpies; /** * @return Collection|EmployeSpie[] */ public function getEmployeSpies(): Collection { return $this->employeSpies; } public function addEmployeSpy(EmployeSpie $employeSpy): self { if (!$this->employeSpies->contains($employeSpy)) { $this->employeSpies[] = $employeSpy; $employeSpy->addClientEmploye($this); } return $this; } public function removeEmployeSpy(EmployeSpie $employeSpy): self { if ($this->employeSpies->contains($employeSpy)) { $this->employeSpies->removeElement($employeSpy); $employeSpy->removeClientEmploye($this); } return $this; } }
and my table EmployeSpie:
class EmployeSpie extends User { /** * @ORMManyToMany(targetEntity=Client::class, inversedBy="employeSpies") */ private $clients; /** * @return Collection|Client[] */ public function getClients(): Collection { return $this->clients; } public function addClient(Client $client): self { if (!$this->clients->contains($client)) { $this->clients[] = $client; } return $this; } public function removeClient(Client $client): self { if ($this->clients->contains($client)) { $this->clients->removeElement($client); } return $this; } public function __toString() { return $this->getPrenom()." ".$this->getNom(); }
My forms are made with a Symfony form:
class ClientType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options) { $builder ->add('email') ->add('password') ->add('nom') ->add('prenom') ->add('telephone') ->add('fax') ->add('is_active') ->add('client_fonction') ->add('site') ->add('employeSpies', EntityType::class, array( 'class' => EmployeSpie::class , 'label' => 'Sélectionnez les emloyés rattachés à ce client', 'expanded' => false, 'multiple' => true, )) ; } public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults([ 'data_class' => Client::class, ]); } }
and in my Controller I’ve made the following thing:
/** * @Route("/admin/clients/create", name="admin.client.new") * @param Request $request * @return RedirectResponse|Response */ public function new(Request $request, UserPasswordEncoderInterface $passwordEncoder) { $client = new Client(); $form = $this->createForm(ClientType::class, $client); $form->handleRequest($request); if ($form->isSubmitted() && $form->isValid()) { $client->setRoles(array('ROLE_CUSTOMER')); $client->setPassword( $passwordEncoder->encodePassword( $client, $form->get('password')->getData() ) ); $this->em->persist($client); $this->em->flush(); $this->addFlash('success', 'Nouveau client crée avec succès'); $this->redirectToRoute('admin.clients.index'); } return $this->render("admin/clients/create.html.twig", [ 'client' => $client, 'form' => $form->createView() ]); } /** * @Route("/admin/clients/{id}", name="admin.client.edit", methods="GET|POST") * @param Client $client * @return Response */ public function edit(Client $client,Request $request, UserPasswordEncoderInterface $passwordEncoder) { $form = $this->createForm(ClientType::class, $client); $form->handleRequest($request); if ($form->isSubmitted() && $form->isValid()) { $clientEmploye = $request->request->get('client'); $clientEmploye = $clientEmploye['employeSpies']; $client->setPassword( $passwordEncoder->encodePassword( $client, $form->get('password')->getData() ) ); foreach ($form->get('employeSpies')->getData() as $employe){ $client->addEmployeSpy($employe); } $client->setRoles(array('ROLE_CUSTOMER')); $this->em->flush(); $this->addFlash('success', 'Nouveau client modifié avec succès'); $this->redirectToRoute('admin.clients.index'); } return $this->render("admin/clients/edit.html.twig", [ 'client' => $client, 'form' => $form->createView() ]); }
Si my user is created or edited normally but I did not store the link for employeSpies
in my form. Do you have any idea why?
Advertisement
Answer
I found the answer to my problem. @Jakumi was right but few other cha ges were needed.
In my client Entity I has to change :
public function addEmployeSpy(EmployeSpie $employeSpy): self { if (!$this->employeSpies->contains($employeSpy)) { $this->employeSpies[] = $employeSpy; $employeSpy->addClientEmploye($this); } return $this; }
to :
public function addEmployeSpy(EmployeSpie $employeSpy): self { if (!$this->employeSpies->contains($employeSpy)) { $this->employeSpies[] = $employeSpy; $employeSpy->addClient($this); } return $this; }
Same thing for the remove.
public function removeEmployeSpy(EmployeSpie $employeSpy): self { if ($this->employeSpies->contains($employeSpy)) { $this->employeSpies->removeElement($employeSpy); $employeSpy->removeClientEmploye($this); } return $this; }
to :
public function removeEmployeSpy(EmployeSpie $employeSpy): self { if ($this->employeSpies->contains($employeSpy)) { $this->employeSpies->removeElement($employeSpy); $employeSpy->removeClient($this); } return $this; }
But after the other change in my ClientType :
->add('employeSpies', EntityType::class, array( 'class' => EmployeSpie::class , 'by_reference' => false, 'label' => 'Sélectionnez les employés rattachés à ce client', 'expanded' => false, 'multiple' => true, ))
I need to add the 'by_reference' => false,
to make it works.
Because of this Symfony will not try to find the “setClient” method but to find addClient
method
Hope it could help later some other persons 🙂