Reputation: 1
I was working on a symfony project last month, I could CRUD data with my entities. But now, I can't insert, update or delete a data. I can only read data, everything is fine to read it.
When I submit a form, no error is displayed.
I tried to submit a form to create an idea. No idea is created. But when I tried to return the data json when I submit my form, the date is good, but no changes in my database.
I don't know since when I have this problem, all these forms worked a few weeks ago.
Does anyone know why ?
Example of a route :
/**
* @Route("/{projet}/{id_projet}/idee/nouvelle",name="projet_idee_nouvelle")
*/
public function projet_idee_nouvelle(int $id_projet,Request $request, ObjectManager $manager){
$idee=new Idee();
$repository = $this
->getDoctrine()
->getManager()
->getRepository('App:Projet')
;
$projet=$repository->find($id_projet);
$projets=array();
array_push($projets,$projet);
$form=$this->createForm(IdeeType::class,$idee, array(
'projets'=>$projets
));
$form->handleRequest($request);
if($form->isSubmitted() && $form->isValid()){
$manager->persist($idee);
$manager->flush();
//redirection on the created project
return $this->redirectToRoute('projet_detail',array('id'=>$projet->getId()));
}
return $this->render('idee/idee_nouveau.html.twig',[
'form'=>$form->createView()
]);
}
My "Projet" entity :
/**
* @ORM\Entity(repositoryClass="App\Repository\ProjetRepository")
*/
class Projet
{
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\Column(type="string", length=50)
* @Assert\NotBlank
*/
private $nom;
//{...} Other class attributes
/**
* @ORM\OneToMany(targetEntity="App\Entity\Idee", mappedBy="projet", cascade={"all"}, orphanRemoval=true)
*/
private $projetIdee;
/**
* @ORM\OneToMany(targetEntity="App\Entity\Tache", mappedBy="projet", cascade={"all"}, orphanRemoval=true)
*/
private $projetTache;
}
My Idee entity :
/**
* @ORM\Entity(repositoryClass="App\Repository\IdeeRepository")
*/
class Idee
{
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\ManyToOne(targetEntity="App\Entity\Projet")
* @ORM\JoinColumn(nullable=false)
*/
private $projet;
/**
* @ORM\Column(type="string", length=255)
* @Assert\NotBlank
*/
private $label;
/**
* @ORM\Column(type="text")
* @Assert\NotBlank
*/
private $texte;
}
My twig to add an idea :
{% extends 'base.html.twig' %}
{% block title %}Ajouter une idée{% endblock %}
{% block main %}
<h1>Ajouter une idée au projet</h1>
{{ form_start(form) }}
{{ form_row(form.projet, {'label':'Projet associé'})}}
{{ form_row(form.label, {'label':'Label de l\'idée','attr':{'placeholder':'Label de l\'idée'}}) }}
{{ form_row(form.texte, {'label':'Description','attr':{'placeholder':'Description'}}) }}
<button class="button_form" type="submit">Ajouter l'idée</button>
{{ form_end(form) }}
{% endblock %}
My IdeeType :
<?php
namespace App\Form;
use App\Entity\Idee;
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\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
class IdeeType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('projet',ChoiceType::class,array(
'label'=>'Projet associé',
'choices'=>$options['projets'],
'choice_label' => 'nom',
'required'=>true
))
->add('label',TextType::class,array(
'required'=>true
))
->add('texte',TextareaType::class,array(
'required'=>true
))
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => Idee::class,
'projets'=>null
]);
}
}
Upvotes: 0
Views: 1474
Reputation: 2837
I will be blunt about it, but the way you code with Symfony 4 is totally wrong...
You would do best to form yourself on Symfony 4 asap.
You will only ends-up with problems if you keep it that way.
With autowiring, which is enabled by default in Symfony 4, you can pass almost anything as parameter to your fonction (controllers, repositories, etc).
Here, I changed the parameters of your function. Removed ObjectManager
as it's already part of the extended AbstractController
, added ProjetRepository
and Projet
.
It's strongly advised to always set action
for your form. 'method' is just a bonus.
I also divided isSubmitted()
and isValid()
, which will allow you to return a custom response in case of invalid submitted form.
This is how your code should looks like:
use App\Entity\Idee;
use App\Entity\Projet;
use App\Form\IdeeType;
use App\Repository\ProjetRepository;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
class IdeeController extends AbstractController {
/**
* @Route("/{nom}/{id}/idee/nouvelle",name="projet_idee_nouvelle", methods={"GET", "POST"})
* @param Request $request
* @param ProjetRepository $projetRepository
* @param Projet $projet
* @return RedirectResponse|Response
*/
public function nouvelleIdee(Request $request, ProjetRepository $projetRepository, Projet $projet) {
$idee=new Idee();
$projets=array();
array_push($projets, $projet);
$form=$this->createForm(IdeeType::class, $idee, array(
'action'=>$this->generateUrl('projet_idee_nouvelle', array('id'=>$projet->getId())),
'method'=>'POST',
'projets'=>$projets,
));
$form->handleRequest($request);
if($form->isSubmitted()) {
if($form->isValid()) {
$em=$this->getDoctrine()->getManager();
$em->persist($idee);
$em->flush();
//redirection on the created project
return $this->redirectToRoute('projet_detail', array('id'=>$projet->getId()));
} else {
//ToDo Return 404 or error message, etc...
}
}
return $this->render('idee/idee_nouveau.html.twig', array(
'idee'=>$idee,
'projet'=>$projet,
'form'=>$form->createView(),
));
}
}
In your twig, your link to your page should looks like this :
<a href="{{ path('projet_idee_nouvelle', { 'nom': projet.nom, 'id': projet.id }) }}">Ajouter une idée</a>
In case you want to keep url parameters in a way that you can understand them, you would change this :
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
/**
* @Route("/{projet_nom}/{projet_id}/idee/nouvelle",name="projet_idee_nouvelle", methods={"GET", "POST"})
* @ParamConverter("projet", options={"mapping": {"nom", "projet_nom", "id": "projet_id"}})
*/
<a href="{{ path('projet_idee_nouvelle', { 'projet_nom': projet.nom, 'projet_id': projet.id }) }}">Ajouter une idée</a>
Upvotes: 0