Skip to content

Commit d207767

Browse files
bug #57541 [Serializer] [ObjectNormalizer] Use bool filter when FILTER_BOOL is set (Maximilian Zumbansen)
This PR was squashed before being merged into the 7.1 branch. Discussion ---------- [Serializer] [ObjectNormalizer] Use bool filter when FILTER_BOOL is set | Q | A | ------------- | --- | Branch? | 7.1 <!-- see below --> | Bug fix? | yes | New feature? | no <!-- please update src/**/CHANGELOG.md files --> | Deprecations? | no <!-- please update UPGRADE-*.md and src/**/CHANGELOG.md files --> | Issues | Fix #57540 <!-- prefix each issue number with "Fix #", no need to create an issue if none exists, explain below instead --> | License | MIT With 7.1 it is possible to map query booleans to php bool parameters (https://symfony.com/blog/new-in-symfony-7-1-misc-improvements-part-3#mapping-boolean-query-string-parameters). But as we found out, this only works when the DTO is initialized via `construct`. Otherwise the `FILTER_BOOL` flag will be ignored and e.g. "false" will be deserialized as `true`. To fix this, I suggest to look for the `FILTER_BOOL` in the context and apply the filter, when the type is `bool` and the data is `string`. Commits ------- 6e657e8e91 [Serializer] [ObjectNormalizer] Use bool filter when FILTER_BOOL is set
2 parents a61c583 + 5969918 commit d207767

File tree

2 files changed

+42
-0
lines changed

2 files changed

+42
-0
lines changed

Normalizer/AbstractObjectNormalizer.php

+8
Original file line numberDiff line numberDiff line change
@@ -566,6 +566,10 @@ private function validateAndDenormalizeLegacy(array $types, string $currentClass
566566
return (float) $data;
567567
}
568568

569+
if (LegacyType::BUILTIN_TYPE_BOOL === $builtinType && \is_string($data) && ($context[self::FILTER_BOOL] ?? false)) {
570+
return filter_var($data, \FILTER_VALIDATE_BOOL, \FILTER_NULL_ON_FAILURE);
571+
}
572+
569573
if ((LegacyType::BUILTIN_TYPE_FALSE === $builtinType && false === $data) || (LegacyType::BUILTIN_TYPE_TRUE === $builtinType && true === $data)) {
570574
return $data;
571575
}
@@ -797,6 +801,10 @@ private function validateAndDenormalize(Type $type, string $currentClass, string
797801
return (float) $data;
798802
}
799803

804+
if (TypeIdentifier::BOOL === $typeIdentifier && \is_string($data) && ($context[self::FILTER_BOOL] ?? false)) {
805+
return filter_var($data, \FILTER_VALIDATE_BOOL, \FILTER_NULL_ON_FAILURE);
806+
}
807+
800808
$dataMatchesExpectedType = match ($typeIdentifier) {
801809
TypeIdentifier::ARRAY => \is_array($data),
802810
TypeIdentifier::BOOL => \is_bool($data),

Tests/Normalizer/AbstractObjectNormalizerTest.php

+34
Original file line numberDiff line numberDiff line change
@@ -1196,6 +1196,34 @@ public function provideBooleanTypesData()
11961196
[['foo' => false], TruePropertyDummy::class],
11971197
];
11981198
}
1199+
1200+
/**
1201+
* @dataProvider provideDenormalizeWithFilterBoolData
1202+
*/
1203+
public function testDenormalizeBooleanTypeWithFilterBool(array $data, ?bool $expectedFoo)
1204+
{
1205+
$normalizer = new AbstractObjectNormalizerWithMetadataAndPropertyTypeExtractors();
1206+
1207+
$dummy = $normalizer->denormalize($data, BoolPropertyDummy::class, null, [AbstractNormalizer::FILTER_BOOL => true]);
1208+
1209+
$this->assertSame($expectedFoo, $dummy->foo);
1210+
}
1211+
1212+
public function provideDenormalizeWithFilterBoolData(): array
1213+
{
1214+
return [
1215+
[['foo' => 'true'], true],
1216+
[['foo' => '1'], true],
1217+
[['foo' => 'yes'], true],
1218+
[['foo' => 'false'], false],
1219+
[['foo' => '0'], false],
1220+
[['foo' => 'no'], false],
1221+
[['foo' => ''], false],
1222+
[['foo' => null], null],
1223+
[['foo' => 'null'], null],
1224+
[['foo' => 'something'], null],
1225+
];
1226+
}
11991227
}
12001228

12011229
class AbstractObjectNormalizerDummy extends AbstractObjectNormalizer
@@ -1481,6 +1509,12 @@ class TruePropertyDummy
14811509
public $foo;
14821510
}
14831511

1512+
class BoolPropertyDummy
1513+
{
1514+
/** @var null|bool */
1515+
public $foo;
1516+
}
1517+
14841518
class SerializerCollectionDummy implements SerializerInterface, DenormalizerInterface
14851519
{
14861520
private array $normalizers;

0 commit comments

Comments
 (0)