Why the URL header takes the wrong parameter? - php

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

Related

How to inject entity depencies into a controller in symfony 5.2?

I'm a beginner in symfony and I would like to inject my post entity into a method of my controller.
However, I've the following error fired :
Unable to guess how to get a Doctrine instance from the request information for parameter "post".
Here is my code :
/**
* #Route("/post/article/new", name="new.html.twig")
* #param Request $request
* #param Posts $posts
* #return Response
*/
public function newArticle(Request $request, Posts $posts): Response
{
$post = $posts;
$article = new Articles();
$post->setAuthor(1);
$form = $this->createForm(PostsType::class, $post);
$form->handleRequest($request);
if($form->isSubmitted() && $form->isValid()) {
$this->em->persist($post);
$this->em->flush();
$article->setPost($post->getId());
$themes = $form->get('themes')->getData();
$article->setThemes(implode(',', $themes));
$this->em->persist($post);
$this->em->flush();
return $this->redirectToRoute('home.html.twig');
}
return $this->render('post/article.html.twig', [
'formArticle' => $form->createView()
]);
}
You need a reference to the Post in the route, like a slug for the id or another unique field.
#Route("/post/{id}/article/new", ...
Otherwise Symfony has no idea which Post to load.

Pass several parameters correctly to your controller

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

Symfony file field empty on edit

I am reading for a while about this but found nothing that works for me.
This is entity
/**
* #ORM\Column(type="string")
*
* #Assert\NotBlank(message="Molimo unesite PDF ili Word fajl.")
* #Assert\File(mimeTypes={ "application/vnd.openxmlformats-officedocument.presentationml.presentation", "application/vnd.ms-powerpoint", "application/pdf", "application/msword", "application/vnd.openxmlformats-officedocument.wordprocessingml.document"})
*/
private $body;
This is form
// Problem with empty field on edit persist! Form expect FileType but db sends string!!!
->add('body', FileType::class, [
//'data_class' => null,// <-- If I change it nothing happened.
'label' => 'Word ili pdf dokument',
'invalid_message' =>'Id posta nije validan',
'attr' => [
'class' => 'form-group',
]])
Everything is very simple and made following docs. I have entity that contains few properties one of them for files ($body). Files are set to be saved in web/uploads/post/ . When I go to edit page I get this error:
"The form's view data is expected to be an instance of class Symfony\Component\HttpFoundation\File\File, but is a(n) string. You can avoid this by setting the "data_class" option to null or by adding a view transformer that transforms a string to an instance of Symfony\Component\HttpFoundation\File\File".
If i set data_status => null field is empty.
What I need is some link to example with this working, Data Transformer maybe?
I was having the same problem in my edit action and solved it by submitting the form manually with the clearMissing parameter set to false instead of using $form->handleRequest($request);, as explained on https://symfony.com/doc/current/form/direct_submit.html:
if ($request->isMethod('POST'))
{
$form->submit($request->request->get($form->getName()),false);
if ($form->isSubmitted() && $form->isValid())
{
This way, the original value of file will not be set to null in case you aren't submitting a new file.
You can get around this by creating a new File() in your editAction. Like this:
/**
* #Route("/edit/{yourEntity}", name="entity_edit")
*
* #return Response
*/
public function editAction(Request $request, YourEntity yourEntity)
{
$body = new File($this->getParameter('your_files_directory') . '/' . $yourEntity->getBody());
$yourEntity->setBody($body);
// rest of your editAction
}
Ok, solved. The answer from #ASOlivieri is good with one small modification. Code in his answer will remember path with file name. So if you want to edit it again it will throw not found exeption. You have to ->setBody again, to be the same as original file name. Set it before flush()
public function editAction(Request $request, Post $post) {
$fileName = $post->getBody();
$file = new File($this->getParameter('post_directory') . '/' . $post->getBody());
$post->setBody($file);
$deleteForm = $this->createDeleteForm($post);
$editForm = $this->createForm('AppBundle\Form\PostEditType', $post);
$editForm->handleRequest($request);
if ($editForm->isSubmitted() && $editForm->isValid()) {
$post->setBody($fileName);
$this->getDoctrine()->getManager()->flush();
Hope this helps!
In my case what helped was:
if ($request->isMethod('POST')) {
$form->submit($request->request->get($form->getName()));
if ($form->isValid()) {...
to
$form->handleRequest($request);
if ($form->isSubmitted()) {
if ($form->isValid()) { ...

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