4

I'm trying to persist an object via Symfony's Form component. It's not working.

When submitting the form, Symfony redirects me to the actual form, with the data previously submitted appearing in the url with GET method. In the Profiler, I can observe that there is "no POST parameters".

The Controller :

<?php

namespace AppBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
use AppBundle\Entity\Quest;
use AppBundle\Form\QuestType;

class QuestController extends Controller
{
\\...
    /**
     * @Route("/admin/quest/add", name="quest_add")
     */
  public function addAction(Request $request)
  {
    $quest = new Quest();
    $form = $this->createForm(QuestType::class, $quest);
    $form->handleRequest($request);

    if ($form->isSubmitted() && $form->isValid()) {
      $em = $this->getDoctrine()->getManager();
      $em->persist($quest);
      $em->flush();

      return $this->redirectToRoute('quest_view');
    }

    return $this->render('admin/quest/add.html.twig', array(
      'form' => $form->createView(),
    ));
  }
}

The Type:

<?php

namespace AppBundle\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\DateTimeType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\Extension\Core\Type\IntegerType;

class QuestType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
        ->add('questName',      TextType::class)
        ->add('questCost',      IntegerType::class)
        ->add('nbEnigma',       IntegerType::class)
        ->add('dateStart',      DateTimeType::class)
        ->add('dateEnd',        DateTimeType::class)
        ->add('rewardFinish',   IntegerType::class)
        ->add('rewardFurther',  IntegerType::class)
        ->add('speech',         TextareaType::class)
        ;
    }
\\...
}

The View:

/* ... */
<div class="well">
  {{ form_start(form) }}
  {{ form_errors(form) }}

  {{ form_row(form.questName) }}
  /* ... */

  <input type="submit" value="Create" method="post" class="btn btn-default pull-right" />

  {{ form_end(form) }}
</div>
/* ... */

Note that I don't use validations for the moment.

The Entity I use is OK, the corresponding table has been created in my PostgreSQL DB via Symfony console, configuration of the parameters.yml is OK too. I can post these elements if needed.

So what could possibly go wrong ? Is that a problem in my Wamp installation or configuration, such as Apache concerns for example ? The fact is I have no clue where the problem is.

Please note that I'm a totally beginner in web-developping. I actually try to learn PHP as well as Symfony2.


EDITS following comments

1) Resulting HTML shows that the form resulting from the Twig render is setting the method of the form to "POST" : <form name="quest" method="post">

2) Adding @Method({"GET", "POST"}) under the @Route with use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method; didn't changed anything.

3.1) Informations about my Environment :

  • Wampserver 2.5 (32 bits & PHP 5.5.12, Apache 2.4.9 )
  • PostgreSQL 9.3.2
  • Symfony 2.8.1, using Standard Edition + FOSUserBundle ~2.0@dev
  • Working with Doctrine2
  • Working logged as SuperAdmin (it's a backend form located in my /admin directory) in the dev environment (app_dev.php).

3.2) In my same environment, I've reproduced various forms shown in 3 different online tutorials (from Symfony book, from openclassrooms.com, and from dynamic-mess.com), and it all ended in this same way.

4) Just in case, I just went to restart the project, by reinstalling Symfony, with the same version and the same configuration, with the same Wampserver and PostgreSQL. I just kept an eye on preventing to miss some steps. It still does'nt work.

5) TEST of a Basic HTML form in my environment : Using a Form without a Class (without Entity)

The Controller :

<?php

namespace AppBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Form\Extension\Core\Type\TextType;

class QuestController extends Controller
{

// ...

    /**
     * @Route("/admin/test/add", name="test")
     */
    public function testAction(Request $request)
    {
        $defaultData = array('message' => 'Type your message here');
        $form = $this->createFormBuilder($defaultData)
            ->add('nametest', TextType::class)
            ->getForm();

        $form->handleRequest($request);

        if ($form->isValid()) {
            $data = $form->getData();
        }

    return $this->render('admin/test.html.twig', array(
      'form' => $form->createView(),
     ));
    }
}

The View :

/* ... */

<div class="well">
  {{ form_start(form) }}
  {{ form_errors(form) }}

  {{ form_row(form.nametest) }}
  <input type="submit" value="Create" method="post" class="btn btn-default pull-right" />

  {{ app.request }}

  {{ form_end(form) }}
</div>

/* ... */

For this test, I used the Twig global template variable {{ app.request }}.

Before clicking the submitting button, the page show these informations :

GET /gowinquest/web/app_dev.php/admin/test/add HTTP/1.1 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Encoding: gzip, deflate Accept-Language: fr,fr-FR;q=0.8,en-US;q=0.5,en;q=0.3 Cache-Control: max-age=0 Connection: keep-alive Cookie: __utma=111872281.2124856035.1451232730.1452442012.1452447222.32; __utmz=111872281.1451232730.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); __utmc=111872281; PPA_ID=not8odr8dlslv6eoo25l2llai6; webfx-tree-cookie-persistence=wfxt-14+wfxt-36+wfxt-20+wfxt-4+wfxt-16+wfxt-18+wfxt-6; PHPSESSID=h94nvh0nn315po8np66httkv56; __utmb=111872281.0.10.1452447222 Host: localhost User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:43.0) Gecko/20100101 Firefox/43.0 X-Php-Ob-Level: 1 

After, the resulting page discards these informations :

GET /gowinquest/web/app_dev.php/admin/test/add?form%5Bnametest%5D=blablabla&form%5B_token%5D=pzhE6hrzsNf3EYbHJLmEXf0miAh4J5jeOH_ccrmlmW4 HTTP/1.1 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Encoding: gzip, deflate Accept-Language: fr,fr-FR;q=0.8,en-US;q=0.5,en;q=0.3 Connection: keep-alive Cookie: __utma=111872281.2124856035.1451232730.1452442012.1452447222.32; __utmz=111872281.1451232730.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); __utmc=111872281; PPA_ID=not8odr8dlslv6eoo25l2llai6; webfx-tree-cookie-persistence=wfxt-14+wfxt-36+wfxt-20+wfxt-4+wfxt-16+wfxt-18+wfxt-6; PHPSESSID=h94nvh0nn315po8np66httkv56; __utmb=111872281.0.10.1452447222 Host: localhost Referer: http://localhost/gowinquest/web/app_dev.php/admin/test/add User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:43.0) Gecko/20100101 Firefox/43.0 X-Php-Ob-Level: 1  

6) I tried the Symfony's generator for CRUD controllers and templates on my Entity, IT WORKED ! My data was sending by POST, and has been registered in database.

But that's still a huge mistery to me, since the methods generated in the Controller and the Form by Symfony are the same than the methods I manually tried before...

The CRUD generator uses @Method({"GET", "POST"}) , that's the only difference I have observed with my initially code. But it is strange, because I also tried @Methodannotations by myself before and it didn't changed nothing (see my 2nd EDIT)...

Still, I'm a very beginner with PHP and with Symfony, a totally newbie, so for sure there is something evident that I missed... But what ? At this moment I have NO IDEA. Explanations are welcome, if someone's got a clue ? I've got to figure out the key of that mistery.

7) Here's the log provided by default by Symfony2.8 in app/logs/dev.log file, from the time I initially show the form until the request is redirected :

[2016-01-11 16:02:38] request.INFO: Matched route "_wdt". {"route_parameters":{"_controller":"web_profiler.controller.profiler:toolbarAction","token":"e945fe","_route":"_wdt"},"request_uri":"http://localhost/gowinquest/web/app_dev.php/_wdt/e945fe"} []
[2016-01-11 16:03:16] request.INFO: Matched route "quest_add". {"route_parameters":{"_controller":"AppBundle\\Controller\\QuestController::addAction","_route":"quest_add"},"request_uri":"http://localhost/gowinquest/web/app_dev.php/admin/quest/add?quest%5B_token%5D=74fPFHnb4NPKfAotccGEE9T4EDCUhaEHY4w-hqViwUw&quest%5BdateEnd%5D%5Bdate%5D%5Bday%5D=1&quest%5BdateEnd%5D%5Bdate%5D%5Bmonth%5D=1&quest%5BdateEnd%5D%5Bdate%5D%5Byear%5D=2011&quest%5BdateEnd%5D%5Btime%5D%5Bhour%5D=0&quest%5BdateEnd%5D%5Btime%5D%5Bminute%5D=0&quest%5BdateStart%5D%5Bdate%5D%5Bday%5D=1&quest%5BdateStart%5D%5Bdate%5D%5Bmonth%5D=1&quest%5BdateStart%5D%5Bdate%5D%5Byear%5D=2011&quest%5BdateStart%5D%5Btime%5D%5Bhour%5D=0&quest%5BdateStart%5D%5Btime%5D%5Bminute%5D=0&quest%5BnbEnigma%5D=1&quest%5BquestCost%5D=1&quest%5BquestName%5D=Test4&quest%5BrewardFinish%5D=1&quest%5BrewardFurther%5D=1&quest%5Bspeech%5D=test4speech"} []
[2016-01-11 16:03:16] security.DEBUG: Read existing security token from the session. {"key":"_security_main"} []
[2016-01-11 16:03:16] doctrine.DEBUG: SELECT t0.username AS username_1, t0.username_canonical AS username_canonical_2, t0.email AS email_3, t0.email_canonical AS email_canonical_4, t0.enabled AS enabled_5, t0.salt AS salt_6, t0.password AS password_7, t0.last_login AS last_login_8, t0.locked AS locked_9, t0.expired AS expired_10, t0.expires_at AS expires_at_11, t0.confirmation_token AS confirmation_token_12, t0.password_requested_at AS password_requested_at_13, t0.roles AS roles_14, t0.credentials_expired AS credentials_expired_15, t0.credentials_expire_at AS credentials_expire_at_16, t0.id AS id_17 FROM fos_user t0 WHERE t0.id = ? LIMIT 1 [1] []
[2016-01-11 16:03:16] security.DEBUG: User was reloaded from a user provider. {"username":"admin","provider":"FOS\\UserBundle\\Security\\EmailUserProvider"} []
[2016-01-11 16:03:17] security.DEBUG: Stored the security token in the session. {"key":"_security_main"} []
[2016-01-11 16:03:18] request.INFO: Matched route "_wdt". {"route_parameters":{"_controller":"web_profiler.controller.profiler:toolbarAction","token":"83737b","_route":"_wdt"},"request_uri":"http://localhost/gowinquest/web/app_dev.php/_wdt/83737b"} []

As for the Profiler (configured by default), there's nothing more than this :

200 ::1 GET http://localhost/gowinquest/web/app_dev.php/admin/quest/add?quest%5B_token%5D=74fPFHnb4NPKfAotccGEE9T4EDCUhaEHY4w-hqViwUw&quest%5BdateEnd%5D%5Bdate%5D%5Bday%5D=1&quest%5BdateEnd%5D%5Bdate%5D%5Bmonth%5D=1&quest%5BdateEnd%5D%5Bdate%5D%5Byear%5D=2011&quest%5BdateEnd%5D%5Btime%5D%5Bhour%5D=0&quest%5BdateEnd%5D%5Btime%5D%5Bminute%5D=0&quest%5BdateStart%5D%5Bdate%5D%5Bday%5D=1&quest%5BdateStart%5D%5Bdate%5D%5Bmonth%5D=1&quest%5BdateStart%5D%5Bdate%5D%5Byear%5D=2011&quest%5BdateStart%5D%5Btime%5D%5Bhour%5D=0&quest%5BdateStart%5D%5Btime%5D%5Bminute%5D=0&quest%5BnbEnigma%5D=1&quest%5BquestCost%5D=1&quest%5BquestName%5D=test5&quest%5BrewardFinish%5D=1&quest%5BrewardFurther%5D=1&quest%5Bspeech%5D=test5
11-Jan-2016 16:24:32 ee563e
200 ::1 GET http://localhost/gowinquest/web/app_dev.php/admin/quest/add 11-Jan-2016 16:23:39 d0f70c
Mexicanoon
  • 339
  • 4
  • 14
  • 1
    Take a look at the resulting HTML and see if the form resulting from the Twig render is setting the method of the form to "POST." By the behavior you described, it seems that the button is making a GET request. – Robert Calove Jan 09 '16 at 18:38
  • i am not sure about that, but maybe try to add `@Method({"GET", "POST"})` under the `@Route` – mic4ael Jan 09 '16 at 18:40
  • @Robert Calove : Thank you for your comment. I tried what you've suggested, but it didn't solved it. Refer to the EDIT informations below the post. – Mexicanoon Jan 09 '16 at 19:41
  • @mic4ael : Thanks for your suggest. I tried it, it didn't worked. Refer to the EDIT informations below the post. – Mexicanoon Jan 09 '16 at 19:42
  • What is the environment? Is there anything in the settings for that environment that affect the issue? What version of symfony? Have you tried making a simple html form that submits via POST and see if it works? – craigh Jan 09 '16 at 19:49
  • Well try to create a small html form such as
    //simple input field here and simple submit button
    and then just print request->request. If nothing is returned something in your project configuration is wrong. If something is returned you know that your actual form is kinda broken. Afterwards debugging is getting quite easier as you know where the problemcomes from. This is not a solution, but a proper way to get the problem finally solved.
    – Tobias Jan 09 '16 at 20:28
  • And something else that has nothing to do with your current problem: I always stop on stackoverflow discussions that try to fix the problem, but don't point to best practices as if noboy cares. What is really ugly in your code - and I know this comes from the official Symfony website - is that your method is used to handle 2 different issues. One issue is to show the view, the other one is to save the data after sending the form.the single responsibility principle says that methods should do one thing, OAOO. I suggest to create 2 methods: One for showing the view and one for saving data – Tobias Jan 09 '16 at 20:48
  • @craigh : I've posted informations on my environment in an edit. Tell me if something else could be needed. – Mexicanoon Jan 10 '16 at 00:24
  • @Tobias : I've tried to create a simple form, I've encountered difficulties. I explain them in a edit on my post. As for the best pratices, I take notice of what you're explaining. I will implement it in my project. Thanks, it helps. – Mexicanoon Jan 10 '16 at 00:30
  • @Tobias : I've just made a simple test, please look at the bottom of my post. – Mexicanoon Jan 10 '16 at 16:40
  • @craigh : I've just made a simple test, please look at the bottom of my post. – Mexicanoon Jan 10 '16 at 16:43
  • I finally tried the Symfony CRUD generator. It generated the controllers, forms and templates, and it worked, it sent POST parameters. I can't explain what was wrong wih my code, see the edit at the bottom of my post for more informations. – Mexicanoon Jan 11 '16 at 08:26
  • Can you show everything from your application log from the time you initially show the form until the request is redirected? – xabbuh Jan 11 '16 at 10:32
  • @xabbuh : What I use concerning logs are the default tools of Symfony, see the results in the last edit of my post. – Mexicanoon Jan 11 '16 at 16:02
  • Your log starts with a GET request containing a lot of URL parameters. Do you really access the form initially via this URL? I would have expected to see two requests in your log. – xabbuh Jan 11 '16 at 16:12
  • @xabbuh : You're right, I missed the previous line. Corrected in the report. – Mexicanoon Jan 11 '16 at 16:28
  • 1
    @Mexicanoon The only thing I can think of could have been wrong and nobody suggested yet is that the configurations of wamps apache server disallow POST requests like here https://stackoverflow.com/a/1402480/5233188 – goulashsoup Sep 26 '17 at 20:32
  • Long time ago, but did you find any answer? Could you post your entity snippet before/after generating using Symfony CRUD? – nbonniot Feb 02 '18 at 11:14
  • @nbonniot Indeed, long time ago ! Funny, because I was thinking of this old question just yesterday. My Entity is entirely different today, and I have no version of its initial state (2 years ago). Presently I'm very busy (starting my start up), so I don't think I could try to reproduce this. Still don't know what happened, but I plead for an error on my part since I was a beginner. – Mexicanoon Feb 02 '18 at 17:59
  • @goulashsoup Maybe, but I can't remember having done any changes in wamp configuration before trying the CRUD generator that actually worked. – Mexicanoon Feb 02 '18 at 18:02

0 Answers0