Search code examples
phpsymfonysymfony-formssymfony-3.2

Symfony 3 passing object through redirects


I'm currently learning Symfony forms. And the code that I'm having trouble with isn't working the way I would like. What I'm trying to do is have a user submit data to my Default Controller, and is that data is valid, have it redirected to another method so that I can do something like submit that data to the database.

What I'm having issues with is passing the data, which is a Task Object with a simple name and date field to a another named route.

Here is some of the code that I have written, is just a basic form as a class kind of structure.

TaskType.php

namespace AppBundle\Entity\Forms;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\DateType;

use AppBundle\Entity\Forms\Task;

use Symfony\Component\OptionsResolver\OptionsResolver;


class TaskType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
    $builder
        ->add('task', TextType::class)
        ->add('dueDate', DateType::class, array('label' => 'Register'))
        ->add('save', SubmitType::class)
    ;
}

public function configureOptions(OptionsResolver $resolver)
{
    $resolver->setDefaults(array(
        'data_class' => Task::class,
    ));
}

DefaultController.php

...

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

use AppBundle\Entity\Forms\TaskType;


use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\DateType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;

...

/**
 * @Route("/", name="homepage")
 */
public function indexAction(Request $request)
{


    $form = $this->createForm(TaskType::class);
    $form->handleRequest($request);

if ($form->isSubmitted() && $form->isValid()) {
    // $form->getData() holds the submitted values
    // but, the original `$task` variable has also been updated
    $task = $form->getData();

    // ... perform some action, such as saving the task to the database
    // for example, if Task is a Doctrine entity, save it!
    // $em = $this->getDoctrine()->getManager();
    // $em->persist($task);
    // $em->flush();

    return $this->redirectToRoute('success', array($task));
}

return $this->render('forms/task.html.twig', array(
    'form' => $form->createView(),
));

}

/**
* @Route("/success", name="success")
*/

public function successAction(Request $request) {
    dump($request);die;
}

So, as you can see, I'm just passing in the task in as a array. In this code I thought maybe I could access the task through he request, but that didn't seem to work. And when I tried to add in a Task[] $task parameter to the successAction, the task isn't found.

So is there a way to access the object here in the second action? or I'm i just kind of backwards here? Should I do the inserting of the data or any other data manipulation prior to doing the redirect? Or is there a way of passing the Task object to another method in the controller so that I can handle the data there?

Thank for your input


Solution

  • The parameters you pass will be ignored since the route "success" does not take any arguments. Additionally I don't think you can pass objects. You could serialize it e.g. as a json string and then deserialize it.

    I think the best choice for your approach would be to use a Session to save the data (make sure the object is serializable):

    $this->container->get('session')->set('task', $task);
    
    return $this->redirectToRoute('success');
    

    and then retrieve it in your success action:

    public function successAction(Request $request) {
        $task = $this->container->get('session')->get('task');
        if ($task === null || !$task instanceof Task) {
            return $this->createNotFoundException();
        }
        // Do something
    }
    

    Also see: https://symfony.com/doc/current/components/http_foundation/sessions.html#main