Pass several parameters correctly to your controller - php

I have already inquired here and there but nothing more or less corresponds to my problem.
I have a page with information about a movie, which I access with an id parameter:
See comments
The film table having a relation with the table how, I display all the comments specific to the movie thanks to an ArrayCollection :
$filmRepo = $repo->find($id);
$comments = $filmRepo->getComments();
I created a CommentController in which I wrote this method whose goal would be to recover the id of the movie AND the id of the comment in order to be able to make CRUD operations on it:
/**
* #Route("{id}/{comment}/create", name="createComment")
* #Route("{id}/{comment}/modif", name="modifComment", defaults={"comment"=1}, methods="GET|POST")
*/
public function modification(Comment $comment = null, Film $film, Request $req, EntityManagerInterface $em)
{
if(!$comment) {
$comment = new Comment();
}
$user = $this->getUser();
$form = $this->createForm(CommentType::class, $comment);
$form->handleRequest($req);
if($form->isSubmitted() && $form->isValid()) {
$comment->setAuthor($user);
$comment->setFilm($film);
$em->persist($comment);
$em->flush();
$this->addFlash('success', 'L\'action a bien été effectuée');
return $this->redirectToRoute('home');
}
return $this->render('comment/modif.html.twig', [
"comment" => $comment,
"form" => $form->createView()
]);
}
But no matter which comment I select, it takes the default comment, that is to say the one with id 1. So something is wrong with my request. However I pass the two parameters in the twig template:
Modif

The problem comes from a syntax error in the twig template. Instead of :
Modif
Rather do :
Modif

Related

Why the URL header takes the wrong parameter?

On a CRUD comment system that I put on posts, I have no problem modifying/deleting said comment by retrieving the post of the id and that of the comment. Here is the method used (which is also used to create a comment):
/**
* #Route("{id}/create", name="createComment")
* #Route("{id}/{comment}/modif", name="modifComment", defaults={"comment"=1}, methods="GET|POST")
*/
public function modification(FilmRepository $film, Comment $comment = null, Request $req, EntityManagerInterface $em, $id)
{
if(!$comment) {
$comment = new Comment();
}
$film = $em->getRepository(Film::class)->findOneBy(array('id' => $id));
$user = $this->getUser();
$form = $this->createForm(CommentType::class, $comment);
$form->handleRequest($req);
dump($film);
dump($comment);
if($form->isSubmitted() && $form->isValid()) {
$comment->setAuthor($user);
$comment->setFilm($film);
$comment->setCreatedAt(new \DateTime());
$em->persist($comment);
$em->flush();
$this->addFlash('success', 'L\'action a bien été effectuée');
return $this->redirectToRoute('home');
}
return $this->render('comment/modif.html.twig', [
"comment" => $comment,
"form" => $form->createView()
]);
}
The problem comes when I try to create a new comment. When I am directed to the form, it considers that the post id corresponds to the comment id (for example, if I am on post 1 and want to add a comment it takes me to the comment form 1). However I specified in my twig request (contrary to modify) that I only took the film.id parameter:
{# Modif comment, with two parameters, functionnal#}
Modif
{# Add comment, with one parameter, unfunctionnal#}
Add
I used the same code as for the CRUD of my posts, and yet he when I want to create a new post returns me an empty form :
/**
* #Route("/admin/create", name="createFilm")
* #Route("/admin/{id}", name="modifFilm", methods="GET|POST")
*/
public function modification(Film $film = null, Request $req, EntityManagerInterface $em)
{
if(!$film) {
$film = new Film();
}
$form = $this->createForm(FilmType::class, $film);
$form->handleRequest($req);
if($form->isSubmitted() && $form->isValid()) {
$em->persist($film);
$em->flush();
$this->addFlash('success', 'L\'action a bien été effectuée');
return $this->redirectToRoute('admin');
}
return $this->render('admin/modif.html.twig', [
"film" => $film,
"form" => $form->createView(),
"admin" => true
]);
}
So the problem comes from the url which takes the id of the film and interprets it as the id of the comment, but I don't understand what is causing this?
In your public function, you have Comment $comment.
You are giving two argument to your Route: id and comment
The Paramconverter will try to find the correct Comment with what you gave him (an id and a comment). It will not check where the value comes from in your twig file.
Indeed, if your argument id comes from a film.id, the Paramconverter will give you the wrong comment.
What you should do is send the comment.id to the argument id.
You can change your Route this way :
#Route("{film}/{id}/modif
For your Twig :
Modif

Symfony 3 rating form on several categories displayed on one page

On some Company (entity) page I'm displaying several Categories (entity) which the Company might have. For every of the categories displayed I need to add simple form with rating value. So I've created entity Called Rating and I've generated RatingType.
Now I have the problem with display this form for each category displayed, I can display the form only once for the first category occurrence, but it in the Rating Form it can't get the name (the id) of the category which it should be connected.
The Rating entity have defined Category and Company in relation ManyToOne (#ORM).
I would appreciate for help how can I handle with that.
I suppose that the trick sits in the Controller, so below is my code:
/**
* #Route("/catalog/{id}.html", name="card_show")
*/
public function cardShowAction(Company $company, Request $request)
{
$form = null;
// #TODO: add verification if user is logged on => if ($user = $this->getUser())
$rating = new Rating();
$rating->setCompany($company);
$form = $this->createForm(RatingType::class, $rating);
$form->handleRequest($request);
if ($form->isValid() && $form->isSubmitted()) {
$em = $this->getDoctrine()->getManager();
$em->persist($rating);
$em->flush();
$this->addFlash('success', "Your vote has been saved!");
return $this->redirectToRoute('card_show', array('id' => $company->getId()));
}
return $this->render("default/catalog/show.html.twig", array(
'card' => $company,
'form' => is_null($form) ? $form : $form->createView()
));
}
Here is the RatingType code:
class RatingType extends AbstractType
{
/**
* {#inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('comment')
->add('vote')
// ->add('userName')
// ->add('ip')
// ->add('createdAt')
->add('service')
// ->add('company')
;
}
/**
* {#inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\Rating'
));
}
}
Each Symfony Form can be rendered in view only once (at least without nasty hacks).
I propose another approach. In your template render as many simple html forms (not binded with Symfony Forms at all!), as many categories you have. Then, give each of those form another action attribute (say "/catalog/{company_id}/category/{category_id}/vote"). Then, create new action, where you will parse, validate and use data from Request object.
If you really want to do all of this using Symfony forms you need to generate as many Symfony Forms instances, as many categories you will have. Each form needs to have unique name and action (or some hidden field) to distinct category user would like to vote.

Symfony - Get last id with doctrine

I have just developed a controller that consists of creating a subject with the ability to add one or more questions.
It works, but I'm not really satisfied with the quality of my code:
Indeed when I want to create a new topic, I can not retrieve the last id of my table QUESTION in phpmyadmin. (I have for the moment two tables: SUBJECT, QUESTION)
The only solution I found, and it is very ugly, is to create the subject, and create a record in my QUESTION table to finally retrieve the last id via getid () by autoincrementation and delete this same question before Display the form for adding a question.
Does any of you have a better solution? :(
Thank you in advance for your return,
My code:
/**
* #Route("/add_sujet", name="add_sujet")
* #Method({"GET", "POST"})
*/
public function add_sujetAction(Request $request)
{
$sujet = new Sujet();
$form = $this->createForm(SujetType::class, $sujet)
->add('saveAndNext', SubmitType::class);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$sujet->setSlug($this->get('slugger')->slugify($sujet->getTitle()));
$entityManager = $this->getDoctrine()->getManager();
$entityManager->persist($sujet);
$entityManager->flush();
$this->addFlash('success', 'sujet.created_successfully');
if ($form->get('saveAndNext')->isClicked()) {
// On commence à créer les questions.
$question = new question();
$question->setContent('init');
$question->setType('init');
$question->setSujet($sujet);
$entityManager = $this->getDoctrine()->getManager();
$entityManager->persist($question);
$entityManager->flush(); // Add factice question<br>
$id = $question->getId()+1; // NOT OPTIMIZED.. <br>
$entityManager->remove($question);
<br>
$entityManager->flush(); // JE SAIS C'EST TRES MOCHE.. <br>
return $this->redirectToRoute('add_question', ['sujetSlug' => $sujet->getSlug(), 'id' => $id]);
}
// On annule la création de sujet.
return $this->redirectToRoute('sujet');
}
// On présente le formulaire pour déclaration sujet.
return $this->render('default/add_sujet.html.twig', [
'sujet' => $sujet,
'form' => $form->createView(),
]);
}
You don't need to add a new record to get the last id.
You may try this:
$lastQuestion = $em->getRepository('AppBundle:Question')->findOneBy([], ['id' => 'desc']);
$lastId = $lastQuestion->getId();
To get the last id after flush:
$em->persist($question); // Id not avalaible
$em->flush();
$lastId = $question->getId(); // we can now get the Id
Just select from your table and ORDER BY the id DESC, and LIMIT to 1 record. Creating a new record just to get the last insert id is crazy!

How to reset form in Symfony

How can I reset the form after submit? It's a simple search form where I show a field on the top and a table in the bottom that shows either the results based on the search or the whole list... but it does not reset, the search key remained...
/**
* #Route("/", name="plazas_index")
*/
public function indexAction(Request $request)
{
$form = $this->createForm('AppBundle\Form\BuscarType');
$form->handleRequest($request);
$repository = $this->getDoctrine()->getRepository('AppBundle:Plaza');
if ($form->isSubmitted() && $form->isValid()) {
$clave = $form['clave']->getData();
$query = $repository->createQueryBuilder('p')
->where('p.nombre LIKE :nombre')
->orWhere('p.localidad LIKE :localidad')
->setParameter('nombre', '%'.$clave.'%')
->setParameter('localidad', '%'.$clave.'%')
->orderBy('p.nombre', 'ASC')
->getQuery();
$plazas = $query->getResult();
$cant = count($plazas);
$this->addFlash($cant ? 'success' : 'warning', 'La búsqueda de '.$clave. ' ha producido '.$cant.' resultados');
//return $this->redirectToRoute('plazas_index');
}
else {
$plazas = $repository->findAll();
}
unset ($form);
$form = $this->createForm('AppBundle\Form\BuscarType');
$form->handleRequest($request);
return $this->render('admin/plazas/index.html.twig', array(
'plazas' => $plazas,
'buscar_form' => $form->createView(),
));
}
I can't redirect because I do the render at the end of the action...
Any help is welcome, thanks!!
Remove the second $form->handleRequest($request); line and you are good to go!
handleRequest takes the submitted POST or GET data and applies it to the form, so if you want a blank form then you shouldn't call that.

How to get user ID (FOSUserBundle) in form builder in Symfony2?

I'm quite new here, be patient, please.
I'm trying to make notice board project in Symfony2 using FOSUserBundle.
I try to get logged user id to put it into form created with form builder (and then to MySQL database).
One of attempts is:
public function createNoticeAction(Request $request)
{
$notice = new Notice();
$form = $this->createFormBuilder($notice)
->add("content", "text")
->add("user_id","entity",
array("class"=>"FOS/UserBundle/FOSUserBundle:", "choice_label"=>"id"))
->add("isActive", "true")
->add("category", "entity",
array("class" => "AppBundle:Category", "choice_label" => "name"))
->add("save", "submit", array("label" => "Save"))
->getForm();
$form->handleRequest($request);
$em = $this->getDoctrine()->getManager();
$em->persist($notice);
$em->flush();
return $this->redirectToRoute('app_user_showuserpage');
}
I tried many solutions again and again and I get some error.
You already have the user object Symfony > 2.1.x
In you Controller like this:
$userId = $this->getUser()->getId();
...
$notice->setUserId($userId);
$em->persist($notice);
Don't ->add field in you FormBuilder, its not safely. Set this value in you Controller and don't ->add this field in FormBuilder
for symfony 3.2.13
have excelent solution (just because is working, but is dangerous if someone discover it in pure HTML)
1) first build YourFormType class.
add normal field in Forms/YourFormType.php (if not, formbuilder tell you that you passing smth not quite right (too many fields) ; -) )
$builder
->add(
'MyModelAddedById',
HiddenType::class,
[
'label' => 'echhh', //somehow it has to be here
'attr' => ['style' => 'display:none'], //somehow it has to be here
]
);
2) in your controller
public function addSomethingAction(Request $request){
$form = $this->createForm(MyModelFormType::class);
//set field value
$request->request->set("prodModelAddedById", $this->getUser()->getId());
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$product = $form->getData();
$em = $this->getDoctrine()->getManager();
$em->persist($product);
$em->flush();
$this->addFlash('success', 'record was added');
return $this->redirectToRoute('products');
}
return $this->render(
'default.add.form.html.twig',
[
'newprod' => $form->createView(),
]
);
}
explenation:
you are passing a field and variable to formbuilder (settig it already to default value!)
and important thing, becose of BUG in my opinion - you can't in your form type set method:
public function getBlockPrefix()
{
//return 'app_bundle_my_form_type';
}
because
$request->request->set
can't work properly if your POST data from form are in bag (parameterbag)
no entity managers, no services, no listeners...
hope it helps.

Categories