Skip to content

Commit

Permalink
Transform false data to null in all cases
Browse files Browse the repository at this point in the history
  • Loading branch information
meyerbaptiste committed Oct 9, 2014
1 parent 547e842 commit 909c67b
Show file tree
Hide file tree
Showing 4 changed files with 6 additions and 56 deletions.
23 changes: 4 additions & 19 deletions Decoder/JsonToFormDecoder.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,6 @@
*/
class JsonToFormDecoder implements DecoderInterface
{
/**
* @var bool
*/
private $removeFalseData;

/**
* @param bool $removeFalseData
*/
public function __construct($removeFalseData = true)
{
$this->removeFalseData = $removeFalseData;
}

/**
* Makes data decoded from JSON application/x-www-form-encoded compliant
*
Expand All @@ -43,12 +30,10 @@ private function xWwwFormEncodedLike(&$data)
// Encode recursively
$this->xWwwFormEncodedLike($value);
} elseif (false === $value) {
if ($this->removeFalseData) {
// Checkbox-like behavior: remove false data
unset($data[$key]);
} else {
$value = null;
}
// Checkbox-like behavior removes false data but PATCH HTTP method with just checkboxes does not work
// To fix this issue we prefer transform false data to null
// See https://github.com/FriendsOfSymfony/FOSRestBundle/pull/883
$value = null;
} elseif (!is_string($value)) {
// Convert everything to string
// true values will be converted to '1', this is the default checkbox behavior
Expand Down
5 changes: 1 addition & 4 deletions Resources/config/body_listener.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
<parameter key="fos_rest.normalizer.camel_keys.class">FOS\RestBundle\Normalizer\CamelKeysNormalizer</parameter>
<parameter key="fos_rest.decoder.json.class">FOS\RestBundle\Decoder\JsonDecoder</parameter>
<parameter key="fos_rest.decoder.jsontoform.class">FOS\RestBundle\Decoder\JsonToFormDecoder</parameter>
<parameter key="fos_rest.decoder.jsontoform.remove_false_data">true</parameter>
<parameter key="fos_rest.decoder.xml.class">FOS\RestBundle\Decoder\XmlDecoder</parameter>
<parameter key="fos_rest.decoder_provider.class">FOS\RestBundle\Decoder\ContainerDecoderProvider</parameter>
<parameter key="fos_rest.body_listener.class">FOS\RestBundle\EventListener\BodyListener</parameter>
Expand All @@ -22,9 +21,7 @@

<service id="fos_rest.decoder.json" class="%fos_rest.decoder.json.class%" />

<service id="fos_rest.decoder.jsontoform" class="%fos_rest.decoder.jsontoform.class%">
<argument>%fos_rest.decoder.jsontoform.remove_false_data%</argument>
</service>
<service id="fos_rest.decoder.jsontoform" class="%fos_rest.decoder.jsontoform.class%" />

<service id="fos_rest.decoder.xml" class="%fos_rest.decoder.xml.class%" />

Expand Down
7 changes: 1 addition & 6 deletions Resources/doc/3-listener-support.md
Original file line number Diff line number Diff line change
Expand Up @@ -201,13 +201,8 @@ fos_rest:
Your custom decoder service must use a class that implements the
``FOS\RestBundle\Decoder\DecoderInterface``.
If you want to be able to use form with checkbox (more than just one checkbox) and have true and false value (without any issue) you have to use: `fos_rest.decoder.jsontoform` (available since fosrest 0.8.0)
If you want to be able to use form with checkbox and have true and false value (without any issue) you have to use: `fos_rest.decoder.jsontoform` (available since fosrest 0.8.0)

`fos_rest.decoder.jsontoform` removes false values. In the case you have a form with just one checkbox or need to patch one checkbox it does not work. Instead of remove false value you can transform it to null. For this you need to override a parameter:
```yaml
parameters:
fos_rest.decoder.jsontoform.remove_false_data: false
```
If the listener receives content that it tries to decode but the decode fails then a BadRequestHttpException will be thrown with the message:
``'Invalid ' . $format . ' message received'``. When combined with the [exception controller support](4-exception-controller-support.md) this means your API will provide useful error messages to your API users if they are making invalid requests.

Expand Down
27 changes: 0 additions & 27 deletions Tests/Decoder/JsonToFormDecoderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,33 +36,6 @@ public function testDecodeWithRemovingFalseData()
$decoder = new JsonToFormDecoder();
$decoded = $decoder->decode(json_encode($data));

$this->assertTrue(is_array($decoded));
$this->assertTrue(is_array($decoded['arrayKey']));
$this->assertArrayNotHasKey('falseKey', $decoded['arrayKey']);
$this->assertEquals('foo', $decoded['arrayKey']['stringKey']);
$this->assertArrayNotHasKey('falseKey', $decoded);
$this->assertEquals('1', $decoded['trueKey']);
$this->assertEquals('69', $decoded['intKey']);
$this->assertEquals('3.14', $decoded['floatKey']);
$this->assertEquals('bar', $decoded['stringKey']);
}

public function testDecodeWithoutRemovingFalseData()
{
$data = array(
'arrayKey' => array(
'falseKey' => false,
'stringKey' => 'foo',
),
'falseKey' => false,
'trueKey' => true,
'intKey' => 69,
'floatKey' => 3.14,
'stringKey' => 'bar',
);
$decoder = new JsonToFormDecoder(false);
$decoded = $decoder->decode(json_encode($data));

$this->assertTrue(is_array($decoded));
$this->assertTrue(is_array($decoded['arrayKey']));
$this->assertNull($decoded['arrayKey']['falseKey']);
Expand Down

0 comments on commit 909c67b

Please sign in to comment.