Bonjour,
Je débute sur Symfony et je rencontre depuis quelques jours un problèmes.
Mon projet est le suivant: créer un utilitaire pour administrer des sondages.
Voci mes règles de gestion:
- Chaque sondage a plusieurs propositions de réponse.
- Chaque utilisateur répondre à un seul sondage.
- Chaque utilisateur peut choisir une ou plusieurs propositions de réponse (attention: il est possible que le sondage ait plusieurs réponses possibles).
Voici mes trois entités:

1. survey.php
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
99
100
101
102
103
104
105
106
107
108
namespace App\Entity;
 
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
 
/**
 * @ORM\Entity(repositoryClass="App\Repository\SurveyRepository")
 */
class Survey
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    protected $id;
 
    /**
     * @ORM\Column(type="string", length=500)
     */
    protected $question;
 
    /**
     * @ORM\Column(type="boolean")
     */
    protected $multiple;
 
    /**
     * @ORM\OneToMany(targetEntity="App\Entity\Proposition", mappedBy="survey", cascade={"persist"}, orphanRemoval=true)
     */
    protected $propositions;
 
    /**
     * @ORM\OneToMany(targetEntity="App\Entity\User", mappedBy="survey", cascade={"persist"}, orphanRemoval=true)
     */
    protected $users;
 
    public function __construct()
    {
        $this->propositions = new ArrayCollection();
        $this->users = new ArrayCollection();
    }
 
    public function getId(): ?int
    {
        return $this->id;
    }
 
    public function getQuestion(): ?string
    {
        return $this->question;
    }
 
    public function setQuestion(string $question): self
    {
        $this->question = $question;
 
        return $this;
    }
 
    public function getMultiple(): ?bool
    {
        return $this->multiple;
    }
 
    public function setMultiple(bool $multiple): self
    {
        $this->multiple = $multiple;
 
        return $this;
    }
 
    /**
     * @return Collection|Proposition[]
     */
    public function getPropositions(): Collection
    {
        return $this->propositions;
    }
 
    public function addProposition(Proposition $proposition): self
    {
        if (!$this->propositions->contains($proposition)) {
            $this->propositions[] = $proposition;
            $proposition->setSurvey($this);
            $this->propositions->add($proposition);
        }
				}
 
    /**
     * @return Collection|User[]
     */
    public function getUsers(): Collection
    {
        return $this->users;
    }
 
    public function addUser(User $user): self
    {
        if (!$this->users->contains($user)) {
            $this->users[] = $user;
            $user->setSurvey($this);
        }
 
        return $this;
    }
}
2. proposition.php
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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
namespace App\Entity;
 
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
 
/**
 * @ORM\Entity(repositoryClass="App\Repository\PropositionRepository")
 */
class Proposition
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;
 
    /**
     * @ORM\ManyToOne(targetEntity="App\Entity\Survey", inversedBy="propositions")
     * @ORM\JoinColumn(nullable=false)
     */
    private $survey;
 
    /**
     * @ORM\Column(type="string", length=255)
     */
    private $wording;
 
    /**
     * @ORM\ManyToMany(targetEntity="App\Entity\User", mappedBy="propositions")
     */
    private $users;
 
    public function __construct()
    {
        $this->users = new ArrayCollection();
    }
 
    public function getId(): ?int
    {
        return $this->id;
    }
 
    public function getSurvey(): ?survey
    {
        return $this->survey;
    }
 
    public function setSurvey(?survey $survey): self
    {
        $this->survey = $survey;
 
        return $this;
    }
 
    public function getWording(): ?string
    {
        return $this->wording;
    }
 
    public function setWording(string $wording): self
    {
        $this->wording = $wording;
 
        return $this;
    }
 
    /**
     * @return Collection|User[]
     */
    public function getUsers(): Collection
    {
        return $this->users;
    }
 
    public function addUser(User $user): self
    {
        if (!$this->users->contains($user)) {
            $this->users[] = $user;
            $user->addProposition($this);
        }
 
        return $this;
    }
}
 
3. user.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\UserRepository")
 */
class User
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;
 
    /**
     * @ORM\ManyToOne(targetEntity="App\Entity\Survey", inversedBy="users")
     * @ORM\JoinColumn(nullable=false)
     */
    private $survey;
 
 
    /**
     * @ORM\ManyToMany(targetEntity="App\Entity\Proposition", inversedBy="users")
     */
    protected $propositions;
 
 
    public function __construct()
    {
        $this->propositions = new ArrayCollection();
    }
 
    public function getId(): ?int
    {
        return $this->id;
    }
 
    public function getSurvey(): ?survey
    {
        return $this->survey;
    }
 
    public function setSurvey(?survey $survey): self
    {
        $this->survey = $survey;
 
        return $this;
    }
 
    /**
     * @return Collection|proposition[]
     */
    public function getPropositions(): Collection
    {
        return $this->propositions;
    }
 
    public function addProposition(proposition $proposition): self
    {
        if (!$this->propositions->contains($proposition)) {
            $this->propositions[] = $proposition;
        }
 
        return $this;
    }
}
Ma relation ManyToMany a créé une table user_proposition dans ma BDD.
Quand je crée un sondage:
1. S'il y a plusieurs réponses possibles: des checkbox sont présentées à l'utilisateur.
2. S'il y a une seule réponse possible: des boutons radios sont présentés à l'utilisateur.
Voici le formulaire UserType:
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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
namespace App\Form;
 
use App\Entity\User;
use App\Entity\Proposition;
use Doctrine\ORM\EntityRepository;
use Symfony\Component\Form\AbstractType;
use App\Repository\PropositionRepository;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\FormInterface;
 
class UserType extends AbstractType
{
 
 
 
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $survey = $options['survey'];
        $multiple = $options['multiple'];
 
        if ($multiple == 1)
            $param = "true";
        else
            $param = "false";
 
        $choices = array();
        foreach ($options['propositions'] as $proposition) {
            $wording = $proposition->getWording();
            $choices[$wording] = $wording;
        }
 
			//...
 
        if ($param == "false") {
            $builder->add('propositions', ChoiceType::class, array(
                'choices' => $choices,
                'expanded' => true,
                'multiple' => false,
            ));
        } else {
            $builder->add('propositions', EntityType::class, [
                'class' => Proposition::class,
                'expanded' => true,
                'multiple' => true,
                'query_builder' => function (EntityRepository $proposition) use ($survey) {
                    return $proposition->createQueryBuilder('u')
                        ->where('u.survey = :survey')
                        ->setParameter('survey', $survey);
                },
                'choice_label' => 'wording',
            ]);
        }    
 
    }
 
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => User::class,
            'survey' => null,
            'multiple' => null,
            'propositions' => null,
        ]);
    }
}
 
Voici le SurveyController:
 
namespace App\Controller;
 
use App\Entity\User;
use App\Entity\Survey;
use App\Form\UserType;
use App\Form\SurveyType;
use App\Entity\Proposition;
use App\Repository\PropositionRepository;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
class SurveyController extends AbstractController
{    
    /**
     * @Route("/answer/{id}", name="survey_answer")
     */
    public function survey_answer($id, Request $request, EntityManagerInterface $manager)
    {
        $survey = $this->getDoctrine()->getRepository(Survey::class)->find($id);
        $user = new User();
        $form = $this->createForm(UserType::class, $user, array(
            'survey' => $survey->getId(),
            'multiple' => $survey->getMultiple(),
            'propositions' => $survey->getPropositions(),
        ));
        $form->handleRequest($request);
        if ($form->isSubmitted() && $form->isValid()) {
            $user->setSurvey($survey);
            foreach($form["propositions"]->getData() as $proposition) {
                $user->addProposition($proposition);
            }
            $manager->persist($user);
            $manager->flush();
            return $this->redirectToRoute('survey_list');
        }
            return $this->render('survey/answer.html.twig', [
            'controller_name' => 'SurveyController',
            'form' => $form->createView(),
            'survey' => $survey,
        ]);
    }
}
Mon problème :
Quand j'ai plusieurs réponses possibles et que je valide mon formulaire, je n'ai aucun problème.
en revanche, quand j'ai qu'une seule réponse possible, j'ai une erreur :
Could not determine access type for property "propositions" in class "App\Entity\User": The property "propositions" in class "App\Entity\User" can be defined with the methods "addProposition()"" but the new value must be an array or an instance of \Traversable, "string"
J'ai cherché sur internet. Malheureusement, JE ne n'ai rien trouvé de probant.
Auriez-vous une idée s'il-vous-plaît?
Espérant avoir été assez clair,
Vous en remerciant par avance,