Skip to content

Commit

Permalink
Fixed array normalization for form post
Browse files Browse the repository at this point in the history
  • Loading branch information
florianv committed Mar 2, 2015
1 parent 02fd642 commit 5591869
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 12 deletions.
22 changes: 19 additions & 3 deletions EventListener/BodyListener.php
Expand Up @@ -15,6 +15,7 @@
use FOS\RestBundle\Normalizer\ArrayNormalizerInterface;
use FOS\RestBundle\Normalizer\Exception\NormalizationException;
use Symfony\Component\HttpFoundation\ParameterBag;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\HttpKernel\Exception\UnsupportedMediaTypeHttpException;
Expand Down Expand Up @@ -87,10 +88,10 @@ public function onKernelRequest(GetResponseEvent $event)
$request = $event->getRequest();
$method = $request->getMethod();
$contentType = $request->headers->get('Content-Type');
$isFormPostRequest = in_array($contentType, array('multipart/form-data', 'application/x-www-form-urlencoded'), true) && 'POST' === $method;
$normalizeRequest = $this->normalizeForms && $isFormPostRequest;
$isFormRequest = $this->isFormRequest($request);
$normalizeRequest = $this->normalizeForms && $isFormRequest;

if (!$isFormPostRequest && in_array($method, array('POST', 'PUT', 'PATCH', 'DELETE'))) {
if (!$isFormRequest && in_array($method, array('POST', 'PUT', 'PATCH', 'DELETE'))) {
$format = null === $contentType
? $request->getRequestFormat()
: $request->getFormat($contentType);
Expand Down Expand Up @@ -139,4 +140,19 @@ private function isNotAnEmptyDeleteRequestWithNoSetContentType($method, $content
{
return false === ('DELETE' === $method && empty($content) && null === $contentType);
}

private function isFormRequest(Request $request)
{
if (!in_array($request->getMethod(), array('POST', 'PUT', 'PATCH', 'DELETE'))) {
return false;
}

$contentTypeParts = explode(';', $request->headers->get('Content-Type'));

if (isset($contentTypeParts[0])) {
return in_array($contentTypeParts[0], array('multipart/form-data', 'application/x-www-form-urlencoded'));
}

return false;
}
}
47 changes: 38 additions & 9 deletions Tests/EventListener/BodyListenerTest.php
Expand Up @@ -135,22 +135,32 @@ public function testOnKernelRequestWithNormalizer()
$this->assertEquals($normalizedData, $request->request->all());
}

public function testOnKernelRequestNormalizationWithForms()
/**
* @dataProvider formNormalizationProvider
*/
public function testOnKernelRequestNormalizationWithForms($method, $contentType, $mustBeNormalized)
{
$data = array('foo_bar' => 'foo_bar');
$normalizedData = array('fooBar' => 'foo_bar');
$decoderProvider = $this->getMock('FOS\RestBundle\Decoder\DecoderProviderInterface');

$normalizer = $this->getMock('FOS\RestBundle\Normalizer\ArrayNormalizerInterface');
$normalizer
->expects($this->once())
->method('normalize')
->with($data)
->will($this->returnValue($normalizedData));

if ($mustBeNormalized) {
$normalizer
->expects($this->once())
->method('normalize')
->with($data)
->will($this->returnValue($normalizedData));
} else {
$normalizer
->expects($this->never())
->method('normalize');
}

$request = new Request(array(), $data, array(), array(), array(), array(), 'foo');
$request->headers->set('Content-Type', 'multipart/form-data');
$request->setMethod('POST');
$request->headers->set('Content-Type', $contentType);
$request->setMethod($method);

$event = $this->getMockBuilder('Symfony\Component\HttpKernel\Event\GetResponseEvent')
->disableOriginalConstructor()
Expand All @@ -163,7 +173,26 @@ public function testOnKernelRequestNormalizationWithForms()
$listener = new BodyListener($decoderProvider, false, $normalizer, true);
$listener->onKernelRequest($event);

$this->assertEquals($normalizedData, $request->request->all());
if ($mustBeNormalized) {
$this->assertEquals($normalizedData, $request->request->all());
} else {
$this->assertEquals($data, $request->request->all());
}
}

public function formNormalizationProvider()
{
$cases = array();

foreach (array('POST', 'PUT', 'PATCH', 'DELETE') as $method) {
$cases[] = array($method, 'multipart/form-data', true);
$cases[] = array($method, 'multipart/form-data; boundary=AaB03x', true);
$cases[] = array($method, 'application/x-www-form-urlencoded', true);
$cases[] = array($method, 'application/x-www-form-urlencoded; charset=utf-8', true);
$cases[] = array($method, 'unknown', false);
}

return $cases;
}

/**
Expand Down

0 comments on commit 5591869

Please sign in to comment.