Vous avez rencontré l'un des problèmes les plus difficiles avec les formulaires Symfony. Heureusement, il existe une bonne documentation. Permettez-moi de résumer les étapes importantes.
Vous avez raison :l'entité Person doit connaître sa relation avec PersonJob si vous souhaitez manipuler cette relation du point de vue d'une personne. Vous devez donc ajouter une propriété :
// src/AppBundle/Entity/Person.php
/**
* @ORM\OneToMany(targetEntity="PersonJob", mappedBy="person")
*/
private $personJobs;
public function __construct()
{
$this->personJobs = new \Doctrine\Common\Collections\ArrayCollection();
}
et ensuite vous aurez dans le type de formulaire
// src/AppBundle/Form/PersonType.php
$builder
->add('name')
->add('firstname')
->add('personJobs', CollectionType::class, array(
'entry_type' => PersonJobType::class,
'allow_add' => true,
)
;
Notez le type de personJobs
champ. Puisqu'une personne peut avoir plusieurs PersonJobs, vous avez besoin d'un type de formulaire qui peut gérer les collections. C'est le but du CollectionType
intégré (consultez sa documentation !
). Vous avez également besoin du type de formulaire PersonJobType
, de sorte que CollectionType
sait construire les sous-formulaires :
class PersonJobType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('comment')
->add('datestart', DateTimeType::class)
->add('dateend', DateTimeType::class)
->add('job') // requires Job::__toString() to be defined!
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\PersonJob'
));
}
}
À des fins de débogage, remplacez votre contrôleur par
public function testAction()
{
$person = new Person();
$form = $this->createForm(PersonType::class, $person);
$form->add('submit', SubmitType::class);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
print '<pre>';
var_dump($form->getData());
die();
}
return $this->render('default/index.html.twig', [
'form' => $form->createView(),
]);
}
Maintenant, allez-y et copiez et collez le code Twig et Javascript de Ajout et suppression d'éléments
(vous devez apporter des modifications mineures telles que le remplacement de form.emails
avec form.personJobs
).
Le formulaire
Le formulaire ressemblera à
Juste le formulaire Personne avec un "Ajouter un autre PersonJob" lien :
Ajouter un PersonJob :
Ajouter un PersonJob :
Les données reçues
Soumettez le formulaire et voyez la sortie de var_dump
:
object(AppBundle\Entity\Person)#247 (5) {
["id":"AppBundle\Entity\Person":private]=>
NULL
["name":"AppBundle\Entity\Person":private]=>
string(12) "Charles Dude"
["firstName":"AppBundle\Entity\Person":private]=>
string(7) "Charles"
["active":"AppBundle\Entity\Person":private]=>
bool(true)
["personJobs":"AppBundle\Entity\Person":private]=>
object(Doctrine\Common\Collections\ArrayCollection)#248 (1) {
["elements":"Doctrine\Common\Collections\ArrayCollection":private]=>
array(2) {
[0]=>
object(AppBundle\Entity\PersonJob)#962 (6) {
["id":"AppBundle\Entity\PersonJob":private]=>
NULL
["comment":"AppBundle\Entity\PersonJob":private]=>
string(19) "Something important"
["datestart":"AppBundle\Entity\PersonJob":private]=>
object(DateTime)#1088 (3) { … }
["dateend": …] => …
["person":"AppBundle\Entity\PersonJob":private]=>
NULL
["job":"AppBundle\Entity\PersonJob":private]=>
object(AppBundle\Entity\Job)#1171 (2) {
["id":"AppBundle\Entity\Job":private]=>
int(2)
["name":"AppBundle\Entity\Job":private]=>
string(5) "Job 2"
}
}
[1]=> …
}
}
Il reste deux choses à faire :
-
Définissez la
person
propriété duPersonJob
imbriqué entités correctement à la nouvelle personne (mais pas encore persistante). -
Parlez à Doctrine du nouveau
PersonJob
entités en appelant$em->persist(…)
sur eux.