Reputation: 13
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
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
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