Hello tous,
je travaille sur les formulaires imbriqués de symfony mais j'ai vraiment du mal même en suivant pas à pas le "cours sur symfony et les formulaires imbriqués"
J'ai toujours mon entité Opérations qui peut contenir des Ventilations :
Operation
Ventilation
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50 /** * @var ArrayCollection $ventilations * * @ORM\OneToMany(targetEntity="AppBundle\Entity\Ventilation", mappedBy="operation", cascade={"persist"}) */ protected $ventilations; /** * Constructor */ public function __construct() { $this->ventilations = new \Doctrine\Common\Collections\ArrayCollection(); } /** * Add ventilation * * @param \AppBundle\Entity\Ventilation $ventilation * * @return Operation */ public function addVentilation(\AppBundle\Entity\Ventilation $ventilation) { $ventilation->setOperation($this); this->ventilations[] = $ventilation; return $this; } /** * Remove ventilation * * @param \AppBundle\Entity\Ventilation $ventilation */ public function removeVentilation(\AppBundle\Entity\Ventilation $ventilation) { $this->ventilations->removeElement($ventilation); } /** * Get ventilations * * @return \Doctrine\Common\Collections\Collection */ public function getVentilations() { return $this->ventilations; }
Les formumaires sont définis comme ceci
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 /** * @ORM\ManyToOne(targetEntity="AppBundle\Entity\Operation", inversedBy="ventilations") * @ORM\JoinColumn(name="operation_id", referencedColumnName="id", onDelete="CASCADE") */ protected $operation; /** * Set operation * * @param \AppBundle\Entity\Operation $operation * * @return Ventilation */ public function setOperation(\AppBundle\Entity\Operation $operation = null) { $this->operation = $operation; return $this; } /** * Get operation * * @return \AppBundle\Entity\Operation */ public function getOperation() { return $this->operation; }
OperationType
VentilationType
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61 <?php namespace AppBundle\Form; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\Form\Extension\Core\Type\DateType; use Symfony\Component\Form\Extension\Core\Type\CheckboxType; use Symfony\Component\Form\Extension\Core\Type\CollectionType; use AppBundle\Form\VentilationType; class OperationType extends AbstractType { /** * {@inheritdoc} */ public function buildForm(FormBuilderInterface $builder, array $options) { $builder ->add('libelle', TextType::class) ->add('date', DateType::class, array( 'widget' => 'single_text', 'format' => 'dd/MM/yyyy')) ->add('estPointe', CheckboxType::class, array( 'required' => false, )) ->add('ventilations', CollectionType::class, array( 'entry_type' => VentilationType::class, 'allow_add' => true, 'allow_delete' => true )) ; } /** ** {@inheritdoc} **/ public function configureOptions(OptionsResolver $resolver) { $resolver->setDefined(array('compte')); } public function setDefaultOptions(OptionsResolverInterface $resolver) { $resolver->setDefaults(array( 'data_class' => 'AppBundle\Entity\Operation', 'compte' => '' )); } * /** ** {@inheritdoc} **/ public function getBlockPrefix() { return 'appbundle_operation'; } }
Tout ce passe bien, sauf qu'à l'enregistrement, l'ID Operation n'est pas enregistré en base de données comme clé étrangère dans Ventilation
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42 <?php namespace AppBundle\Form; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; use Symfony\Component\Form\Extension\Core\Type\NumberType; class VentilationType extends AbstractType { /** ** {@inheritdoc} **/ public function buildForm(FormBuilderInterface $builder, array $options) { $builder ->add('montantDebit', NumberType::class, array( 'scale' => 2 )) ->add('montantCredit', NumberType::class, array( 'scale' => 2 )) ; } public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults(array( 'data_class' => 'AppBundle\Entity\Ventilation' )); } /** ** {@inheritdoc} **/ public function getBlockPrefix() { return 'appbundle_ventilation'; } }
Le controller :
Une idée ?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 /** ** @param Request $request ** @param Compte $compte ** @return Response|RedirectResponse **/ public function ajoutAction(Request $request, Compte $compte) { if ($compte->getUser() != $this->getUser()) { throw $this->createAccessDeniedException('Accès au compte non autorisé.'); } $o = new Operation(); $o->setCompte($compte); $form = $this->createForm(OperationType::class, $o, array('compte' => $compte)); $form->handleRequest($request); if ($form->isSubmitted() && $form->isValid()) { $em = $this->getDoctrine()->getManager(); $em->persist($o); $em->flush(); return $this->redirectToRoute('compte_show', array('slug' => $compte->getSlug())); } return $this->render('operation/add.html.twig', array( 'form' => $form->createView(), 'operation' => $o, 'type' => 'add', )); }
merci,
PS : La mauvaise idée serait d'ajouter une boucle pour placer "operation" dans les différentes ventilations...
Partager