Bonjour,
Je reviens maintenant avec un autre problème au niveau de mes formulaires et 3 entités.
J'ai une entité User :
J'ai une autre entité Question :
Et pour finir une entité Response :
J'ai crée dans mon controller Question une page pour ajouter une question :
Voici le formType :
Ma vue twig :
Et l'autre problème se situe dans mes réponses, voici la route dans le controller Question :
Le formType des Response :
L'affichage est bon tout marche bien jusqu'au moment où j'envoi le fomulaire, j'ai une erreur en récupérant mon User, que cela soit en envoyant une nouvelle question ou alors en répondant à une question existante.
Je tente plusieurs solutions mais rien n'y fait, je ne vois pas comment m'en sortir, par contre je vois bien en gros où peut se situer le problème.
Pourtant cela paraît simple mais je tourne en rond.
Si vous avez des idées, je suis preneuse.
Merci !
Je reviens maintenant avec un autre problème au niveau de mes formulaires et 3 entités.
J'ai une entité User :
<?php
namespace App\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Symfony\Component\Security\Core\User\UserInterface;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Table(name="app_user")
* @ORM\Entity(repositoryClass="App\Repository\UserRepository")
*/
class User implements UserInterface, \Serializable
{
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\Column(type="string", length=64)
*/
private $username;
/**
* @ORM\Column(type="string", length=255)
*/
private $email;
/**
* @ORM\Column(type="string", length=64)
*/
private $password;
/**
* @ORM\ManyToOne(targetEntity="App\Entity\Role", inversedBy="users")
*/
private $role;
/**
* @ORM\OneToMany(targetEntity="App\Entity\Response", mappedBy="users")
*/
private $responses;
/**
* @ORM\OneToMany(targetEntity="App\Entity\Question", mappedBy="user")
*/
private $questions;
public function __construct()
{
$this->responses = new ArrayCollection();
$this->questions = new ArrayCollection();
}
public function __toString()
{
return $this->getUsername();
}
public function getId(): ?int
{
return $this->id;
}
public function getUsername(): ?string
{
return $this->username;
}
public function getSalt()
{
// you *may* need a real salt depending on your encoder
// see section on salt below
return null;
}
public function getPassword(): ?string
{
return $this->password;
}
public function getRoles()
{
return [$this->role->getCode()];
}
public function eraseCredentials()
{
}
public function serialize()
{
return serialize(array(
$this->id,
$this->username,
$this->password,
// see section on salt below
// $this->salt,
));
}
public function unserialize($serialized)
{
list(
$this->id,
$this->username,
$this->password,
// see section on salt below
// $this->salt
) = unserialize($serialized, array('allowed_classes' => false));
}
public function setUsername(string $username): self
{
$this->username = $username;
return $this;
}
public function setPassword($password)
{
$this->password = $password;
return $this;
}
public function getEmail(): ?string
{
return $this->email;
}
public function setEmail(string $email): self
{
$this->email = $email;
return $this;
}
public function getRole(): ?Role
{
return $this->role;
}
public function setRole(?Role $role): self
{
$this->role = $role;
return $this;
}
/**
* @return Collection|Response[]
*/
public function getResponses(): Collection
{
return $this->responses;
}
public function addResponse(Response $response): self
{
if (!$this->responses->contains($response)) {
$this->responses[] = $response;
$response->setUsers($this);
}
return $this;
}
public function removeResponse(Response $response): self
{
if ($this->responses->contains($response)) {
$this->responses->removeElement($response);
// set the owning side to null (unless already changed)
if ($response->getUsers() === $this) {
$response->setUsers(null);
}
}
return $this;
}
/**
* @return Collection|Question[]
*/
public function getQuestions(): Collection
{
return $this->questions;
}
public function addQuestion(Question $question): self
{
if (!$this->questions->contains($question)) {
$this->questions[] = $question;
$question->setUser($this);
}
return $this;
}
public function removeQuestion(Question $question): self
{
if ($this->questions->contains($question)) {
$this->questions->removeElement($question);
// set the owning side to null (unless already changed)
if ($question->getUser() === $this) {
$question->setUser(null);
}
}
return $this;
}
}
J'ai une autre entité Question :
<?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\QuestionRepository")
*/
class Question
{
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\Column(type="string", length=255)
* @Assert\Length(min=10, max=255)
*/
private $titleQuestion;
/**
* @ORM\Column(type="text")
*/
private $description;
/**
* @ORM\OneToMany(targetEntity="App\Entity\Response", mappedBy="question", cascade={"persist"})
*/
private $responses;
/**
* @ORM\ManyToMany(targetEntity="App\Entity\Tag", inversedBy="questions")
*/
private $tags;
/**
* @ORM\Column(type="datetime")
*/
private $createdAt;
/**
* @ORM\ManyToOne(targetEntity="App\Entity\User", inversedBy="questions", cascade={"persist"})
*/
private $user;
public function __construct()
{
$this->responses = new ArrayCollection();
$this->tags = new ArrayCollection();
}
public function __toString()
{
return $this->getTitleQuestion();
}
public function getId(): ?int
{
return $this->id;
}
public function getTitleQuestion(): ?string
{
return $this->titleQuestion;
}
public function setTitleQuestion(string $titleQuestion): self
{
$this->titleQuestion = $titleQuestion;
return $this;
}
public function getDescription(): ?string
{
return $this->description;
}
public function setDescription(string $description): self
{
$this->description = $description;
return $this;
}
/**
* @return Collection|Response[]
*/
public function getResponses(): Collection
{
return $this->responses;
}
public function addResponse(Response $response): self
{
if (!$this->responses->contains($response)) {
$this->responses[] = $response;
$response->setQuestion($this);
}
return $this;
}
public function removeResponse(Response $response): self
{
if ($this->responses->contains($response)) {
$this->responses->removeElement($response);
// set the owning side to null (unless already changed)
if ($response->getQuestion() === $this) {
$response->setQuestion(null);
}
}
return $this;
}
/**
* @return Collection|Tag[]
*/
public function getTags(): Collection
{
return $this->tags;
}
public function addTag(Tag $tag): self
{
if (!$this->tags->contains($tag)) {
$this->tags[] = $tag;
}
return $this;
}
public function removeTag(Tag $tag): self
{
if ($this->tags->contains($tag)) {
$this->tags->removeElement($tag);
}
return $this;
}
public function getCreatedAt(): ?\DateTimeInterface
{
return $this->createdAt;
}
public function setCreatedAt(\DateTimeInterface $createdAt): self
{
$this->createdAt = $createdAt;
return $this;
}
public function getUser(): ?User
{
return $this->user;
}
public function setUser(?User $user): self
{
$this->user = $user;
return $this;
}
}
Et pour finir une entité Response :
<?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\ResponseRepository")
*/
class Response
{
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\Column(type="text", nullable=true)
*/
private $answer;
/**
* @ORM\ManyToOne(targetEntity="App\Entity\Question", inversedBy="responses")
* @ORM\JoinColumn(nullable=false)
*/
private $question;
/**
* @ORM\ManyToOne(targetEntity="App\Entity\User", inversedBy="responses", cascade={"persist"})
*/
private $users;
/**
* @ORM\Column(type="datetime")
*/
private $createdAt;
public function getId(): ?int
{
return $this->id;
}
public function getAnswer(): ?string
{
return $this->answer;
}
public function setAnswer(?string $answer): self
{
$this->answer = $answer;
return $this;
}
public function getQuestion(): ?Question
{
return $this->question;
}
public function setQuestion(?Question $question): self
{
$this->question = $question;
return $this;
}
public function getUsers(): ?User
{
return $this->users;
}
public function setUsers(?User $users): self
{
$this->users = $users;
return $this;
}
public function getCreatedAt(): ?\DateTimeInterface
{
return $this->createdAt;
}
public function setCreatedAt(\DateTimeInterface $createdAt): self
{
$this->createdAt = $createdAt;
return $this;
}
}
J'ai crée dans mon controller Question une page pour ajouter une question :
/**
* @Route("/question/new", name="question_new", methods="GET|POST")
*/
public function formQuestion(Request $request)
{
$question = new Question();
$form = $this->createForm(QuestionType::class, $question);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$manager = $this->getDoctrine()->getManager();
$manager->persist($question);
$manager->flush();
return $this->redirectToRoute('question_show', ['id'=> $question->getId()]);
}
return $this->render('question/new.html.twig', [
'formQuestion'=>$form->createView()
]);
}
Voici le formType :
namespace App\Form;
use App\Entity\Question;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
class QuestionType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('titleQuestion', TextType::class, [
'label'=>'Titre de la question',
'attr'=>['placeholder'=>'Titre de la question']
])
->add('description', TextareaType::class, [
'label'=>'Description',
'attr'=>['placeholder'=>'Ajouter un descriptif à votre question']
])
->add('tags')
->add('user', TextType::class, [
'label' => 'Votre nom',
'attr'=>['placeholder'=> 'Nom'],
'constraints'=>[new NotBlank()]
]);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => Question::class,
]);
}
}
Ma vue twig :
{% extends 'base.html.twig' %}
{% form_theme formQuestion 'bootstrap_4_layout.html.twig' %}
{% block title %}Créer une nouvelle question{% endblock %}
{% block body %}
<h2>Posez votre question</h2>
{{ form_start(formQuestion, {'attr': {'novalidate': 'novalidate'}})}}
{{ form_widget(formQuestion) }}
<button type="submit" class="btn btn-success">Ajouter la question</button>
{{ form_end(formQuestion)}}
{% endblock %}
Et l'autre problème se situe dans mes réponses, voici la route dans le controller Question :
/**
* @Route("/question/{id}", name="question_show")
*/
public function show(Question $question, Request $request)
{
$response = new Response();
$form = $this->createForm(ResponseType::class, $response);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$manager = $this->getDoctrine()->getManager();
$manager->persist($response);
$manager->flush();
return $this->redirectToRoute('question_show', ['id'=> $question->getId()]);
}
return $this->render('question/show.html.twig', [
'question' => $question,
'formResponse'=>$form->createView(),
]);
}
Le formType des Response :
<?php
namespace App\Form;
use App\Entity\Response;
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\TextareaType;
class ResponseType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('answer', TextareaType::class, [
'label'=>'Votre réponse',
'attr'=>['placeholder'=>'Veuillez saisir votre réponse']
])
->add('users', TextType::class, [
'label'=>'Votre nom',
'attr'=>['placeholder'=>'Nom']
])
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => Response::class,
]);
}
}
L'affichage est bon tout marche bien jusqu'au moment où j'envoi le fomulaire, j'ai une erreur en récupérant mon User, que cela soit en envoyant une nouvelle question ou alors en répondant à une question existante.
Je tente plusieurs solutions mais rien n'y fait, je ne vois pas comment m'en sortir, par contre je vois bien en gros où peut se situer le problème.
Pourtant cela paraît simple mais je tourne en rond.
Si vous avez des idées, je suis preneuse.
Merci !