Wrong form is validated in symfony - php

I have a controller action with a couple of forms. One form is for adding a question entity and the other form is for editing an existing question. This is a part of the action
/**
* #Route("/edit/{form}")
* #Template()
* #ParamConverter("form", class="AppBundle:Form")
*/
public function editAction(Request $request, $form)
{
$questionForm = new Question();
$addQuestionForm = $this->createForm(new AddQuestionType(), $questionForm);
$addQuestionForm->handleRequest($request);
if ($addQuestionForm->isValid()) {
dump('Wrong form');
die();
$em->persist($questionForm);
$em->flush();
return $this->redirectToRoute('app_form_edit', array('form' => $form_id));
}
$editQuestion = new Question();
$editAjaxQuestionForm = $this->createForm(new AddQuestionType(), $editQuestion);
$editAjaxQuestionForm->handleRequest($request);
if ($editAjaxQuestionForm->isValid()) {
dump('Correct form');
die();
$em->persist($editQuestion);
$em->flush();
return $this->redirectToRoute('app_form_edit', array('form' => $form_id));
}
I added the dump() and die() for debugging because the editAjaxQuestionForm was not working properly. Then I noticed that when I submit the editAjaxQuestionForm, the dump('Wrong form') is shown. So the form goes through the wrong validation.
The forms are created after an Ajax call. This is the code
/**
* #Route("/AjaxAddQuestionForm/{section}")
* #Template
* #ParamConverter("section", class="AppBundle:Section")
*/
public function ajaxAddQuestionFormAction(Request $request, $section)
{
$question = new Question();
$question->setSection($section);
$addQuestionForm = $this->createForm(new AddQuestionType(), $question);
return array(
'section' => $section,
'addAjaxQuestionForm' => $addQuestionForm->createView(),
);
}
/**
* #Route("/AjaxEditQuestionForm/{question}")
* #Template
* #ParamConverter("question", class="AppBundle:Question")
*/
public function ajaxEditQuestionFormAction(Request $request, $question)
{
$editQuestionForm = $this->createForm(new AddQuestionType(), $question);
return array(
'question' => $question,
'editAjaxQuestionForm' => $editQuestionForm->createView(),
);
}
I think I've tried everything but I can't figure out what is wrong.

Related

How Can I specified the object of my precedent form?

In my project I want to use the object created by my precedent form:
Here is the schema of my database:
My QuizController
public function creation(Request $request){
$quiz = new Quiz();
$user = $this->getUser();
$formQuiz = $this->createForm(QuizType::class, $quiz);
$formQuiz->handleRequest($request);
if ($formQuiz->isSubmitted() && $formQuiz->isValid() ) {
$quiz->setCreatedAt(new DateTimeImmutable());
$quiz->setCreatedBy($user);
$entityManager = $this->getDoctrine()->getManager();
$entityManager->persist($quiz);
$entityManager->flush();
return $this->redirectToRoute('creation_questions');
}
return $this->render('quiz/creation.html.twig', [
'formQuiz' => $formQuiz->createView(),
]);
}
And my QuestionController that must be connected with the quiz form
public function creation_questions(Request $request){
$quiz = ?
$question = new Questions();
$formQuestions = $this->createForm(QuestionType::class, $question);
$formQuestions->handleRequest($request);
if ($formQuestions->isSubmitted() && $formQuestions->isValid() ) {
$question->setCreatedAt(new DateTimeImmutable());
$question->setQuiz($quiz);
$entityManager = $this->getDoctrine()->getManager();
$entityManager->persist($question);
$entityManager->flush();
return $this->redirectToRoute('home');
}
return $this->render('questions/questions.html.twig', [
'formQuestion' => $formQuestions->createView()
]);
}
What do I have to write in place of the '?'?
You don't show your routing but you could use paramConverte "magic" from SensioFrameworkExtraBundle and do something like this.
/**
* #Route("/some-route/{id}", name="some_route_name")
*/
public function creation_questions(Request $request, Quiz $quiz)
{
$question = new Questions();
$formQuestions = $this->createForm(QuestionType::class, $question);
$formQuestions->handleRequest($request);
if ($formQuestions->isSubmitted() && $formQuestions->isValid()) {
$question->setCreatedAt(new DateTimeImmutable());
$question->setQuiz($quiz);
$entityManager = $this->getDoctrine()->getManager();
$entityManager->persist($question);
$entityManager->flush();
return $this->redirectToRoute('home');
}
return $this->render('questions/questions.html.twig', [
'formQuestion' => $formQuestions->createView()
]);
}
Where the {id} part of /someRoute/{id} is the Quiz Id. Symfony should automagically fetch the Quiz matching that id. Or you can be more explicit about how the param converter should interpret such a value. More info here https://symfony.com/bundles/SensioFrameworkExtraBundle/current/annotations/converters.html
Alternatively, you could pass the quiz id and fetch the quiz manually (less magic but totally legit).
/**
* #Route("/some-route/{id}", name="some_route_name")
*/
public function creation_questions(Request $request, int $id)
{
$entityManager = $this->getDoctrine()->getManager();
$quiz = $entityManager->getRepository(Quiz::class)->find($id);
$question = new Questions();
$formQuestions = $this->createForm(QuestionType::class, $question);
$formQuestions->handleRequest($request);
if ($formQuestions->isSubmitted() && $formQuestions->isValid()) {
$question->setCreatedAt(new DateTimeImmutable());
$question->setQuiz($quiz);
$entityManager->persist($question);
$entityManager->flush();
return $this->redirectToRoute('home');
}
return $this->render('questions/questions.html.twig', [
'formQuestion' => $formQuestions->createView()
]);
}

Return post values of form after submit

How to retrive values of posted form, for example in controller i check if is any username already if it redirect back to route which render the form, but how to retrive the last post values to not fill data of this form again.
example of controle:
/**
* #Route("/dystrybutor/pracownicy/add", name="dystrybutor_pracownicy_add")
*/
public function new(UserManagerInterface $userManager, EntityManagerInterface $entityManager, Request $request)
{
$pracownik = new Pracownik();
$form = $this->createForm(PracownikType::class, $pracownik);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$id = $this->getUser()->getDystrybutorId();
$username = $form["username"]->getData();
$password = $form["password"]->getData();
$email = $form["email"]->getData();
$userManager = $this->get('fos_user.user_manager');
$checkUser = $userManager->findUserByUsername($username);
if($checkUser) {
$this->addFlash(
'danger',
'Login jest już zajęty!'
);
return $this->redirectToRoute('dystrybutor_pracownicy_add');
}
else {
Generally you should just pass the $pracownik object to the action where you redirect to and then just pass it as argument when creating your form. This can be done with a lot of ways but I would suggest to use the forward method in your controller:
public function new(UserManagerInterface $userManager, EntityManagerInterface $entityManager, Request $request, Pracownik $pracownik = null){
$pracownik = $pracownik ?? new Pracownik();
$form = $this->createForm(PracownikType::class, $pracownik);
...
if($checkUser) {
$this->addFlash('danger','Login jest już zajęty!');
return $this->forward('App\Controller\DystrybutorController::new', array(
'pracownik' => $pracownik
));
}

Search filter with method get doesn't found results [symfony2]

I have a search form that works with the method POST, but the method POST doesn't display the requested data in the url.
With method POST the url look like this:
/search_flight
with the method GET no results found, the url look like this:
/search_flight?from=Cape+Town%2C+International+CPT&to=Johannesburg%2C+O.R.+Tambo+International+JNB&departuredate=2016%2F01%2F08&arrivaldate=2016%2F10%2F04&price=57.5%2C1000
I also noticed that with the method GET the data is reset in each input of the form.
routing.yml
searchFlight:
path: /search_flight
defaults: { _controller: FLYBookingsBundle:Post:searchtabflightResult }
requirements:
_method: GET|POST
controller
This method send the requested data to the method searchtabflightResultAction that will handle the query.
public function searchtabflightAction()
{
//$form = $this->createForm(new SearchflightType(),null, array('action' => $this->generateUrl('searchFlight'),'method' => 'GET',));
$form = $this->get('form.factory')->createNamed(null, new SearchflightType());
return $this->render('FLYBookingsBundle:Post:searchtabflight.html.twig', array(
'form' => $form->createView(),
));
}
.
<form action="{{ path ('searchFlight') }}" method="GET">
{# here I have my forms #}
</form>
.
public function searchtabflightResultAction(Request $request)
{
//$form = $this->createForm(new SearchflightType());
$form = $this->get('form.factory')->createNamed(null, new SearchflightType());
$form->handleRequest($request);
$em = $this->getDoctrine()->getManager();
$airport1 = $form["to"]->getData();
$airport = $form["from"]->getData();
$departureDateObj = $form["departuredate"]->getData();
$arrivalDateObj = $form["arrivaldate"]->getData();
$price = $form["price"]->getData();
$entities = $em->getRepository('FLYBookingsBundle:Post')->searchflight($airport1,$airport,$departureDateObj,$arrivalDateObj,$price);
return $this->render('FLYBookingsBundle:Post:searchtabflightResult.html.twig', array(
'entities' => $entities,
'form' => $form->createView(),
));
}
How can I make my search filter works with method get ?
Everything should be done within two actions, the basic concept is:
SearchFlightType has with/wo price option:
class SearchFlightType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('from', FormType\TextType::class)
->add('to', FormType\TextType::class)
->add('departuredate', FormType\TextType::class)
->add('arrivaldate', FormType\TextType::class);
if ($options['price']) {
$builder->add( 'price', FormType\TextType::class );
}
$builder
->add('submit', FormType\SubmitType::class);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'price' => false,
));
}
}
Controller.php
class PostController extends Controller
{
/**
* #Route("/index", name="index")
*/
public function indexAction(Request $request)
{
$defaultData = array();
$form = $this->createForm(SearchFlightType::class, $defaultData, array(
// action is set to the specific route, so the form will
// redirect it's submission there
'action' => $this->generateUrl('search_flight_result'),
// method is set to desired GET, so the data will be send
//via URL params
'method' => 'GET',
));
return $this->render('Post/searchtabflight.html.twig', array(
'form' => $form->createView(),
));
}
/**
* #Route("/search_flight_result", name="search_flight_result")
*/
public function searchTabFlightResultAction(Request $request)
{
$defaultData = array();
$entities = null;
$form = $this->createForm(SearchFlightType::class, $defaultData, array(
// again GET method for data via URL params
'method' => 'GET',
// option for price form field present
'price' => true,
));
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
// get data from form
$data = $form->getData();
// process the data and get result
$em = $this->getDoctrine()->getManager();
$entities = $em->getRepository('FLYBookingsBundle:Post')->searchflight($data['from'], $data['to'], ...);
}
return $this->render('Post/searchtabflight.html.twig', array(
'form' => $form->createView(),
// present the result
'entities' => $entites,
));
}
}

Validate form in different controller action symfony

I have a controller action that returns a form to the view. When the form is submitted, the validation of this form needs to be done in a different action than the action returning the form.
This is a sample of the action that returns the form
/**
* #Route("/AjaxAddQuestionForm/{section}")
* #Template
* #ParamConverter("section", class="AppBundle:Section")
*/
public function ajaxAddQuestionFormAction(Request $request, $section)
{
$question = new Question();
$question->setSection($section);
$addQuestionForm = $this->createForm(new AddQuestionType(), $question);
return array(
'section' => $section,
'addAjaxQuestionForm' => $addQuestionForm->createView(),
);
}
And this is the action in which I am currently trying to get the validation to work.
/**
* #Route("/edit/{form}")
* #Template()
* #ParamConverter("form", class="AppBundle:Form")
*/
public function editAction(Request $request, $form)
{
$em = $this->getDoctrine()->getManager();
(...)
$questionForm = new Question();
$addQuestionForm = $this->createForm(new AddQuestionType(), $questionForm);
$addQuestionForm->handleRequest($request);
if ($addQuestionForm->isValid()) {
$em->persist($questionForm);
$em->flush();
return $this->redirectToRoute('app_form_edit', array('form' => $form_id));
}
(...)
The problem is that the validation in the second action is never called. Any idea on how I can get this working?
You should add form action if you want validate form on other url:
In ajaxAddQuestionFormAction:
$addQuestionForm = $this->createForm(new AddQuestionType(), $question,
array(
'action' => $this->generateUrl('edit_form')
));
edit action route:
*#Route("/edit", name="edit_form")

Print all Symfony2 forms

I currently have a script in Symfony where I generate a form in a controller. This form shows the content of the Entity "Page". If the user edits the form, and submits it, the form adjusts the corresponding data in the database.
/**
* Webpage allowing user to edit a page and her attributes
*
* #Route("/edit")
*/
public function editAction(Request $request)
{
/*
* Get an array of all the current pages stored in the database.
*
* foreach loop through each website and create a seperate form for them
*
*/
$em = $this->getDoctrine()->getManager();
$pages = $em->getRepository(Page::class)->findAll();
foreach ($pages as $page) {
$editform= $this->createFormBuilder($page)
->add('name', 'text')
->add('location', 'url')
->add('displayTime', 'integer')
->add('save', 'submit', array(
'label' => 'Edit page'
))
->getForm();
$editform->handleRequest($request);
if ($editform->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->flush();
return new Response('Page edited successfully - immediately effective');
}
}
return $this->render('WalldisplayBundle:Walldisplay:edit.html.twig',
array(
'editform' => $editform->createView()
));
}
Unfortunately, this only prints a form with the last entry in the database. What I'd like is to have a form created for -every- entry in the database, not just the last one. I've tried iterating through the Doctrine repository, no luck however. How could I solve this problem?
Maybe it will work. I have not tested.
/**
* Webpage allowing user to edit a page and her attributes
*
* #Route("/edit")
*/
public function editAction(Request $request)
{
/*
* Get an array of all the current pages stored in the database.
*
* foreach loop through each website and create a seperate form for them
*
*/
$em = $this->getDoctrine()->getManager();
$pages = $em->getRepository(Page::class)->findAll();
foreach ($pages as $key=>$page) {
$editforms[$key] = $this->createFormBuilder($page)
->add('name', 'text')
->add('location', 'url')
->add('displayTime', 'integer')
->add('save', 'submit', array(
'label' => 'Edit page'
))
->getForm();
foreach($editforms as $editform){
$editform->handleRequest($request);
if ($editform->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->flush();
}
}
return new Response('Page edited successfully - immediately effective');
}
foreach($editforms as $editform){
$editform->handleRequest($request);
if ($editform->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->flush();
}
foreach($editforms as $editform){
$arrayForm[$editform] = $editform->createView();
}
return $this->render('WalldisplayBundle:Walldisplay:edit.html.twig', $arrayForm);
}

Categories