Voila je rencontre un petit problème avec mon code.
J'ai un formulaire de prestataires dans lequel je souhaite intégrer une collection de prestations et pour chaque prestation y intégrer une collection de expériences.
J'ai donc un formulaire avec un ArrayColllection qui lui contient un autre ArrayCollection.
J'ai donc créé les entités Prestataire, Prestation et Expérience :
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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80 <?php namespace App\Entity; use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Collection; use Doctrine\ORM\Mapping as ORM; /** * @ORM\Entity(repositoryClass="App\Repository\PrestataireRepository") */ class Prestataire { /** * @ORM\Id() * @ORM\GeneratedValue() * @ORM\Column(type="integer") */ private $id; /** * @ORM\Column(type="string", length=255, nullable=true) */ private $name; /** * @ORM\OneToMany(targetEntity="App\Entity\Prestation", mappedBy="prestataire", cascade={"persist"}, orphanRemoval=true) */ private $prestations; public function __construct() { $this->caterings = new ArrayCollection(); } public function getId(): ?int { return $this->id; } public function getName(): ?string { return $this->name; } public function setName(?string $name): self { $this->name = $name; return $this; } /** * @return Collection|Prestation[] */ public function getPrestations(): Collection { return $this->prestations; } public function addPrestation(Prestation $prestation): self { if (!$this->prestations->contains($prestation)) { $this->prestations[] = $prestation; $prestation->setPrestataire($this); } return $this; } public function removePrestation(Prestation $prestation): self { if ($this->prestations->contains($prestation)) { $this->prestations->removeElement($prestation); // set the owning side to null (unless already changed) if ($prestation->getPrestataire() === $this) { $prestation->setPrestataire(null); } } return $this; } }
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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98 <?php namespace App\Entity; use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Collection; use Doctrine\ORM\Mapping as ORM; use Symfony\Component\Validator\Constraints as Assert; /** * @ORM\Entity(repositoryClass="App\Repository\PrestationRepository") */ class Prestation { /** * @ORM\Id() * @ORM\GeneratedValue() * @ORM\Column(type="integer") */ private $id; /** * @ORM\Column(type="text", nullable=true) */ private $descriptif; /** * @ORM\ManyToOne(targetEntity="App\Entity\Prestataire", inversedBy="prestations") */ private $prestataire; /** * @ORM\OneToMany(targetEntity="App\Entity\Experience", mappedBy="prestation", cascade={"persist"}, orphanRemoval=true) */ private $experiences; public function __construct() { $this->experiences = new ArrayCollection(); } public function getId(): ?int { return $this->id; } public function getDescriptif(): ?string { return $this->descriptif; } public function setDescriptif(?string $descriptif): self { $this->descriptif = $descriptif; return $this; } public function getPrestataire(): ?Prestataire { return $this->prestataire; } public function setPrestataireLogistique(?Prestataire $prestataire): self { $this->prestataire = $prestataire; return $this; } /** * @return Collection|Experience[] */ public function getExperiences(): Collection { return $this->experiences; } public function addExperience(Experience $experience): self { if (!$this->experiences->contains($experience)) { $this->experiences[] = $experience; $experience->setPrestation($this); } return $this; } public function removeExperience(Experience $experience): self { if ($this->experiences->contains($experience)) { $this->experiences->removeElement($experience); // set the owning side to null (unless already changed) if ($experience->getPrestation() === $this) { $experience->setPrestation(null); } } return $this; } }Voici les Forms correspondants à ces entités
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 <?php namespace App\Entity; use Doctrine\ORM\Mapping as ORM; /** * @ORM\Entity(repositoryClass="App\Repository\ExperienceRepository") */ class Experience { /** * @ORM\Id() * @ORM\GeneratedValue() * @ORM\Column(type="integer") */ private $id; /** * @ORM\Column(type="string", length=255, nullable=true) */ private $titre; /** * @ORM\ManyToOne(targetEntity="App\Entity\Prestation", inversedBy="experiences") * @ORM\JoinColumn(nullable=false) */ private $prestation; public function getId(): ?int { return $this->id; } public function getTitre(): ?string { return $this->titre; } public function setTitre(?string $titre): self { $this->titre = $titre; return $this; } public function getPrestation(): ?Prestation { return $this->prestation; } public function setPrestation(?Prestation $prestation): self { $this->prestation = $prestation; return $this; } }
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 <?php namespace App\Form; use App\Entity\Prestataire; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\Extension\Core\Type\CollectionType; use Symfony\Component\Form\Extension\Core\Type\SubmitType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; class PrestataireType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options) { $builder ->add('prestations', CollectionType::class, [ 'entry_type' => PrestationType::class, 'entry_options' => [ 'label' => false, ], 'allow_add' => true, 'allow_delete' => true, 'required' => false, 'by_reference' => false, 'prototype' => true, 'prototype_name' => 'prestation' ]) ->add('save', SubmitType::class, [ 'attr' => [ 'class' => 'btn btn-primary', ] ]) ; } public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults([ 'data_class' => Prestataire::class, ]); } }
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 <?php namespace App\Form; use App\Entity\Catering; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\Extension\Core\Type\CollectionType; use Symfony\Component\Form\Extension\Core\Type\TextareaType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; class PrestationType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options) { $builder ->add('descriptif', TextareaType::class, [ 'label' => " Descriptif de lactivité et du service proposé", ]) ->add('experiences', CollectionType::class, [ 'entry_type' => ExperienceType::class, 'entry_options' => [ 'label' => false, ], 'allow_add' => true, 'allow_delete' => true, 'required' => false, 'by_reference' => true, 'prototype' => true, ]) ; } public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults([ 'data_class' => Prestation::class, ]); } }Et voici la fonction de mon controller
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 <?php namespace App\Form; use App\Entity\Travaux; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; class TravauxType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options) { $builder ->add('titre', TextType::class, [ 'label' => false, ]) ; } public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults([ 'data_class' => Experience::class, ]); } }
Je voudrais que pour chaque prestation, l'ensemble des expériences soit enregistré.
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 /** * @Route("/prestataire/new", name="prestataire_create") * @Route("/prestataire/edit", name="prestataire_edit") */ public function editionform(PrestataireRepository $repository, Request $request, ObjectManager $manager) { $user = $this->getUser(); $prestataire = $repository->findOneByUser($user); if(!$prestataire){ $prestataire = new Prestataire(); } $form = $this->createForm(PrestataireType::class, $prestataire); $form->handleRequest($request); if($form->isSubmitted() && $form->isValid()){ //Je boucle l'ArrayCollection de Prestation foreach($prestataire->getPrestations() as $prestation){ $prestation->setPrestataire($prestation); $manager->persist($prestation); //Je flush le $manager afin d'obtenir l'id de la Prestation $manager->flush(); foreach ($prestation->getExperience() as $experience){ $experience->setPrestation($prestation); $manager->persist($experience); } //Enfin je flush de nouveau le $manager d'enregistrer les expériences $manager->flush(); } return $this->redirectToRoute('dashboard_user'); } return $this->render('recensement/prestataire.html.twig', [ 'form' => $form->createView(), ]); }
Mais hélas voilà ce que j'obtiens :
C'est comme si le controller recherchait les fonctions getExperiences , addExperience et removeExperience dans l'entité Prestataire alors que celles-ci se trouvent dans mon entité Prestation puisque les expériences sont une collection de la collection Prestation.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 Could not determine access type for property "experiences" in class "App\Entity\Prestation": Neither the property "experiences" nor one of the methods "addExperienceson()"/"removeExperienceson()", "addExperiencesum()"/"removeExperiencesum()", "setExperiences()", "experiences()", "__set()" or "__call()" exist and have public access in class "App\Entity\Prestation".
Je tente depuis plusieurs de trouver une solution mais toute mes recherches sont infructueuses donc si quelqu'un peut me donner une solution ça sera avec un immense plaisir.
Merci
Partager