Skip to content

Commit 547e842

Browse files
committed
Enable or disable removing false data for JsonToFormDecoder
1 parent a81b4ba commit 547e842

File tree

4 files changed

+56
-6
lines changed

4 files changed

+56
-6
lines changed

Decoder/JsonToFormDecoder.php

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,19 @@
1818
*/
1919
class JsonToFormDecoder implements DecoderInterface
2020
{
21+
/**
22+
* @var bool
23+
*/
24+
private $removeFalseData;
25+
26+
/**
27+
* @param bool $removeFalseData
28+
*/
29+
public function __construct($removeFalseData = true)
30+
{
31+
$this->removeFalseData = $removeFalseData;
32+
}
33+
2134
/**
2235
* Makes data decoded from JSON application/x-www-form-encoded compliant
2336
*
@@ -30,8 +43,12 @@ private function xWwwFormEncodedLike(&$data)
3043
// Encode recursively
3144
$this->xWwwFormEncodedLike($value);
3245
} elseif (false === $value) {
33-
// Checkbox-like behavior: remove false data
34-
unset($data[$key]);
46+
if ($this->removeFalseData) {
47+
// Checkbox-like behavior: remove false data
48+
unset($data[$key]);
49+
} else {
50+
$value = null;
51+
}
3552
} elseif (!is_string($value)) {
3653
// Convert everything to string
3754
// true values will be converted to '1', this is the default checkbox behavior

Resources/config/body_listener.xml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
<parameter key="fos_rest.normalizer.camel_keys.class">FOS\RestBundle\Normalizer\CamelKeysNormalizer</parameter>
1010
<parameter key="fos_rest.decoder.json.class">FOS\RestBundle\Decoder\JsonDecoder</parameter>
1111
<parameter key="fos_rest.decoder.jsontoform.class">FOS\RestBundle\Decoder\JsonToFormDecoder</parameter>
12+
<parameter key="fos_rest.decoder.jsontoform.remove_false_data">true</parameter>
1213
<parameter key="fos_rest.decoder.xml.class">FOS\RestBundle\Decoder\XmlDecoder</parameter>
1314
<parameter key="fos_rest.decoder_provider.class">FOS\RestBundle\Decoder\ContainerDecoderProvider</parameter>
1415
<parameter key="fos_rest.body_listener.class">FOS\RestBundle\EventListener\BodyListener</parameter>
@@ -21,7 +22,9 @@
2122

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

24-
<service id="fos_rest.decoder.jsontoform" class="%fos_rest.decoder.jsontoform.class%" />
25+
<service id="fos_rest.decoder.jsontoform" class="%fos_rest.decoder.jsontoform.class%">
26+
<argument>%fos_rest.decoder.jsontoform.remove_false_data%</argument>
27+
</service>
2528

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

Resources/doc/3-listener-support.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,8 +201,13 @@ fos_rest:
201201
Your custom decoder service must use a class that implements the
202202
``FOS\RestBundle\Decoder\DecoderInterface``.
203203
204-
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)
204+
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)
205205

206+
`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:
207+
```yaml
208+
parameters:
209+
fos_rest.decoder.jsontoform.remove_false_data: false
210+
```
206211
If the listener receives content that it tries to decode but the decode fails then a BadRequestHttpException will be thrown with the message:
207212
``'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.
208213

Tests/Decoder/JsonToFormDecoderTest.php

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,7 @@
2020
*/
2121
class JsonToFormDecoderTest extends \PHPUnit_Framework_TestCase
2222
{
23-
24-
public function testDecode()
23+
public function testDecodeWithRemovingFalseData()
2524
{
2625
$data = array(
2726
'arrayKey' => array(
@@ -48,4 +47,30 @@ public function testDecode()
4847
$this->assertEquals('bar', $decoded['stringKey']);
4948
}
5049

50+
public function testDecodeWithoutRemovingFalseData()
51+
{
52+
$data = array(
53+
'arrayKey' => array(
54+
'falseKey' => false,
55+
'stringKey' => 'foo',
56+
),
57+
'falseKey' => false,
58+
'trueKey' => true,
59+
'intKey' => 69,
60+
'floatKey' => 3.14,
61+
'stringKey' => 'bar',
62+
);
63+
$decoder = new JsonToFormDecoder(false);
64+
$decoded = $decoder->decode(json_encode($data));
65+
66+
$this->assertTrue(is_array($decoded));
67+
$this->assertTrue(is_array($decoded['arrayKey']));
68+
$this->assertNull($decoded['arrayKey']['falseKey']);
69+
$this->assertEquals('foo', $decoded['arrayKey']['stringKey']);
70+
$this->assertNull($decoded['falseKey']);
71+
$this->assertEquals('1', $decoded['trueKey']);
72+
$this->assertEquals('69', $decoded['intKey']);
73+
$this->assertEquals('3.14', $decoded['floatKey']);
74+
$this->assertEquals('bar', $decoded['stringKey']);
75+
}
5176
}

0 commit comments

Comments
 (0)