Chrisotopher
Chrisotopher

Reputation: 13

FosRestBundele PUT Method doesn't work with Forms but POST or GET works perfectly

I'm trying to build a simple Restful-Service with Symfony2 and the FosRestBundle.

If I send my request with the GET or POST method the response comes as expected.

If I use the PUT or PATCH method the result is empty.

FormType

namespace MobileService\UserBundle\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;

class CurrentLocationType extends AbstractType
{
/**
 * @param FormBuilderInterface $builder
 * @param array $options
 */
public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('latitude')
        ->add('longitude')
        ->add('city')
        ->add('zip')
    ;
}

/**
 * @param OptionsResolverInterface $resolver
 */
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
    $resolver->setDefaults(array(
        'data_class' => 'MobileService\UserBundle\Entity\CurrentLocation',
        'csrf_protection' => false
    ));
}

/**
 * @return string
 */
public function getName()
{
    return '';
}
}

My Controller's putAction($id) and postAction($id) are exactly the same.

Controller/Action

public function putAction($id)
{
    $request = $this->getRequest();
    $method=$request->getMethod();

    $em = $this->getDoctrine()->getManager();
    $location = $em->getRepository('MobileServiceUserBundle:CurrentLocation')->find($id);

    $form = $this->createForm(new CurrentLocationType(), $location, array('method' => $method));
    $form->submit($request, false);

    if ($form->isValid()) {
        $em->persist($location);
        $em->flush();
    }
    else die('Invalid form.');

    return array(
        'location' => $form->getData(),
    );
}

Result with PUT request:

{"location":{"id":1,"latitude":0,"longitude":0,"city":"","zip":0}}

Result with POST request:

{"location":{"id":1,"latitude":51.4681,"longitude":6.9174,"city":"Essen","zip":451361}}

The output of console route:debug

new_profiles                      GET    ANY    ANY  /profiles/new.{_format}           
get_profiles                      GET    ANY    ANY  /profiles/{id}.{_format}          
get_locations                     GET    ANY    ANY  /locations.{_format}              
get_location                      GET    ANY    ANY  /locations/{id}.{_format}         
post_locations                    POST   ANY    ANY  /locations.{_format}              
put_location                      PUT    ANY    ANY  /locations/{id}.{_format}         
get_images                        GET    ANY    ANY  /images.{_format}   

Upvotes: 1

Views: 1032

Answers (2)

AntoineWDG
AntoineWDG

Reputation: 549

Since you know your request is going to be a PUT request, it seems silly to use the following :

  $method=$request->getMethod();

Instead try to use this :

  $method= 'PUT';

Moreover, the $request object should be passed as a parameter in your action instead of retrieving it from the request object, and instead of using this :

$form->submit($request, false);

You should use this :

$form->handleRequest($request);

To sum it up here is the code I would use :

public function putAction($id, Request $request)
{
    $method='PUT';

    $em = $this->getDoctrine()->getManager();
    $location = $em->getRepository('MobileServiceUserBundle:CurrentLocation')->find($id);

    $form = $this->createForm(new CurrentLocationType(), $location, array('method' => $method));
    $form->handleRequest($request);

    if ($form->isValid()) {
        $em->persist($location);
        $em->flush();
    }
    else die('Invalid form.');

    return array(
        'location' => $form->getData(),
    );
}

Don't forget the proper use statement for the Request object.

Upvotes: 2

Nicolai Fröhlich
Nicolai Fröhlich

Reputation: 52493

Not all browsers support PUT|PATCH|DELETE requests.

They will usually send a POST request even if the form has method="PUT" for example.

Solution:

Symfony has a simple workaround for this situation.

Add a hidden input field named _method with value PUT or PATCH to your form.

You can read more about changing the request method in the following two cookbook articles:

Upvotes: 0

Related Questions