tstr
tstr

Reputation: 1276

Symfony PUT method

I want send data via PUT method, my controller action:

public function updateTestAction(Request $request)
{
    $em = $this->getDoctrine()->getManager();
    $progress = $em->getRepository('CodeCatsPanelBundle:Progress')->find(5);
    //$form = $this->createForm(new ProgressType(), $progress, array('method' => 'PUT'))->add('submit', 'submit');
    $form = $this->createForm(new ProgressType(), $progress)->add('submit', 'submit');

    $form->handleRequest($request);

    return $this->render('CodeCatsPanelBundle:Progress:test.html.twig', [
        'form' => $form->createView(),
        'valid' => $form->isValid(),
        'progress' => $progress,
        'request' => $request
    ]);
}

the first one form works correct, but when I change method to PUT I receive validation error:

This form should not contain extra fields.

I know that Symfony2 use post and extra hidden field _method but how to valid data in this case?

Upvotes: 0

Views: 8334

Answers (2)

Mick
Mick

Reputation: 31919

Most browsers do not support sending PUT and DELETE requests via the method attribute in an HTML form.

Fortunately, Symfony provides you with a simple way of working around this limitation.

Symfony 3

  1. Enable http-method-override

In web/app.php:

Request::enableHttpMethodParameterOverride(); // add this line
  1. Choose one of the following override:

In a Twig Template

{# app/Resources/views/default/new.html.twig #}
{{ form_start(form, {'action': path('target_route'), 'method': 'GET'}) }}

In a Form

form = $this->createForm(new TaskType(), $task, array(
    'action' => $this->generateUrl('target_route'),
    'method' => 'GET',
));

In a Controller / the lazy way

$form = $this->createFormBuilder($task)
    ->setAction($this->generateUrl('target_route'))
    ->setMethod('GET')
    ->add('task', 'text')
    ->add('dueDate', 'date')
    ->add('save', 'submit')
    ->getForm();

Post-Symfony 2.2

Same as above, just Step 2, Step 1 is done by default.

Pre-Symfony 2.2

Same as above, Step 1 and 2.


References

Upvotes: 1

Leo Silence
Leo Silence

Reputation: 1192

just add a hidden input in your template like:

<form action='your route'>
  <input type='hidden' name='_method' value='PUT'>
  //do something.......
</form>

in your action:

public function updateTestAction(Request $request)
{
   $em = $this->getDoctrine()->getManager();
   $progress = $em->getRepository('CodeCatsPanelBundle:Progress')->find(5);
   $form = $this->createForm(new ProgressType(), $progress)->add('submit', 'submit');

   $form->handleRequest($request);

   if ($form->isValid()){
     //do something
   }

   return $this->render('CodeCatsPanelBundle:Progress:test.html.twig', [
       'form' => $form->createView(),
       'valid' => $form->isValid(),//you need this? 
       'progress' => $progress,
       'request' => $request
   ]);
}

in your route config file:

 yourRouteName:
    path:      /path
    defaults:  { _controller: yourBundle:XX:updateTest }
    requirements: 
      _method: [PUT]

Upvotes: 2

Related Questions