Reputation: 149
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
{
/**
* @ORM\ManyToMany(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
{
/**
* @ORM\ManyToMany(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?
Upvotes: 1
Views: 71
Reputation: 149
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 :)
Upvotes: 1