Buy

Inspect the HTML and check out the <form> element. Notice: this does not have an action attribute. This means that the form will submit right back to the same route and controller that renders it. You can totally change this, but we won't.

In other words, our single action method will be responsible for rendering the form and processing it when the request method is POST.

Before we do any processing, we need the request. Type-hint it as an argument:

46 lines src/AppBundle/Controller/Admin/GenusAdminController.php
... lines 1 - 7
use Symfony\Component\HttpFoundation\Request;
... lines 9 - 12
class GenusAdminController extends Controller
{
... lines 15 - 31
public function newAction(Request $request)
{
... lines 34 - 44
}
}

$form->handleRequest()

Next, to actually handle the submit, call $form->handleRequest() and pass it the $request object:

46 lines src/AppBundle/Controller/Admin/GenusAdminController.php
... lines 1 - 12
class GenusAdminController extends Controller
{
... lines 15 - 31
public function newAction(Request $request)
{
$form = $this->createForm(GenusFormType::class);
// only handles data on POST
$form->handleRequest($request);
... lines 38 - 44
}
}

This is really cool: the $form knows what fields it has on it. So $form->handleRequest() goes out and grabs the post data off of the $request object for those specific fields and processes them.

The confusing thing is that this only does this for POST requests. If this is a GET request - like the user simply navigated to the form - the handleRequest() method does nothing and our form renders just like it did before.

Tip

You can configure the form to submit on GET requests if you want. This is useful for search forms

But if the form was just submitted, then we'll want to do something with that information, like save a new Genus to the database. Add an if statement: if ($form->isSubmitted() && $form->isValid()):

46 lines src/AppBundle/Controller/Admin/GenusAdminController.php
... lines 1 - 12
class GenusAdminController extends Controller
{
... lines 15 - 31
public function newAction(Request $request)
{
$form = $this->createForm(GenusFormType::class);
// only handles data on POST
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
... line 39
}
... lines 41 - 44
}
}

In other words, if this is a POST request and if the form passed all validation. We'll add validation soon.

Fetching $form->getData()

If we get inside this if statement, life is good. For now, just dump the submitted data: dump($form->getData()) and then die;:

46 lines src/AppBundle/Controller/Admin/GenusAdminController.php
... lines 1 - 12
class GenusAdminController extends Controller
{
... lines 15 - 31
public function newAction(Request $request)
{
$form = $this->createForm(GenusFormType::class);
// only handles data on POST
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
dump($form->getData());die;
}
... lines 41 - 44
}
}

OK, let's see what this dumps out!

Fill out the form with very realistic data and submit. Check that out! It dumps and associative array with the three fields we added to the form. That's so simple! We added 3 fields to the form, rendered them in a template, and got those three values as an associative array.

Now, it would be very, very easy to use that associative array to create a new Genus object, populate it with the data, and save it via Doctrine.

But, it would be awesomesauce if the form framework could do our job for us. I mean, use the data to automatically create the Genus object, populate it, and return that to us. Let's do that.

Leave a comment!

  • 2016-08-08 weaverryan

    Definitely! I also leave off isSubmitted() in practice - it's nice to show to beginners at first, but I'm too lazy to include it after ;).

    Thanks for the note!

  • 2016-08-08 3amprogrammer

    Checking if form is valid is totally fine, as isValid checks for isSubmitted also :)

  • 2016-07-13 Carlo Mario Chierotti

    Thank you Victor!

    Carlo

  • 2016-07-13 Victor Bocharsky

    Hey Carlo!

    Good catch! BTW, you should move the session save path to a directory that is not shared between host and guest machines in case you want to use "handler_id: session.handler.native_file". For more information please check this issue.

    Cheers!

  • 2016-07-13 Carlo Mario Chierotti

    Hello Ryan,

    I followed your advice I was NOT able to retrieve the value from the session.

    I checked ALL the differences between my code and your code and I found this difference in config.yml:

    YOURS
    session:
    handler_id: ~

    MINE
    session:
    handler_id: session.handler.native_file

    I updated my config.yml and BOOM: problem solved.

    I am using a standard Debian Jessie VM in Vagrant, I don't know why the standard setup doesn't work.

    thank you for your help!

    Carlo

  • 2016-07-12 weaverryan

    Hey Carlos!

    Hmm - this doesn't sound good at all :). Victor was right - basically the *only* way you can mess this up is by forgetting to render the field (which you haven't done!). I've only seen CSRF tokens fail *one* other time ever, and it was when someone had misconfigured their session storage (which is not something you normally need to configure at all). CSRF tokens work via your session - so this is *possibly* the problem.

    Here's how you can see if your session is working.

    1) Find your favorite controller and add the following:


    $this->get('session')->set('testing_value', 'yay');

    2) Go to the URL that executes this controller

    3) Update the code in your controller


    // $this->get('session')->set('testing_value', 'yay');
    dump($this->get('session')->get('testing_value'));die;

    4) Go back to that URL. Were we able to load the value from the session?

    Cheers!

  • 2016-07-11 Carlo Mario Chierotti

    hello Victor,

    I checked the source of the page and I confirm my form has the hidden field with the token.

    when I submit the form and I check in the profiler the POST parameters, the _token value is the same as the value I saw in the form, but I still get the error message about the CSRF token.

    thank you for your help.

    carlo

  • 2016-07-11 Victor Bocharsky

    Hey Carlo Mario Chierotti ,

    How does your form look like? Probably, you forget to render a SCRF hidden field. Actually, you don't need to render it manually, Symfony does it behind the scene when {{ form_end(form) }} is called. Do you have a `form_end` call on your page? If so, just open this form page in your browser to regenerate SCRF token and submit this form again.

    Cheers!

  • 2016-07-08 Carlo Mario Chierotti

    Hello,

    let me say your tutorials are really awesome!

    I have a question for you. when I try to dump the data with

    dump($form->getData());

    it get this warning:

    The CSRF token is invalid. Please try to resubmit the form.

    I double checked the code but the error remains the same. can you please help me?

    thank you!

    carlo