diff --git a/Normalizer/AbstractObjectNormalizer.php b/Normalizer/AbstractObjectNormalizer.php index e15c89e8..3275d976 100644 --- a/Normalizer/AbstractObjectNormalizer.php +++ b/Normalizer/AbstractObjectNormalizer.php @@ -566,6 +566,10 @@ private function validateAndDenormalizeLegacy(array $types, string $currentClass return (float) $data; } + if (LegacyType::BUILTIN_TYPE_BOOL === $builtinType && \is_string($data) && ($context[self::FILTER_BOOL] ?? false)) { + return filter_var($data, \FILTER_VALIDATE_BOOL, \FILTER_NULL_ON_FAILURE); + } + if ((LegacyType::BUILTIN_TYPE_FALSE === $builtinType && false === $data) || (LegacyType::BUILTIN_TYPE_TRUE === $builtinType && true === $data)) { return $data; } @@ -797,6 +801,10 @@ private function validateAndDenormalize(Type $type, string $currentClass, string return (float) $data; } + if (TypeIdentifier::BOOL === $typeIdentifier && \is_string($data) && ($context[self::FILTER_BOOL] ?? false)) { + return filter_var($data, \FILTER_VALIDATE_BOOL, \FILTER_NULL_ON_FAILURE); + } + $dataMatchesExpectedType = match ($typeIdentifier) { TypeIdentifier::ARRAY => \is_array($data), TypeIdentifier::BOOL => \is_bool($data), diff --git a/Tests/Normalizer/AbstractObjectNormalizerTest.php b/Tests/Normalizer/AbstractObjectNormalizerTest.php index 6f625650..e1b1031d 100644 --- a/Tests/Normalizer/AbstractObjectNormalizerTest.php +++ b/Tests/Normalizer/AbstractObjectNormalizerTest.php @@ -1196,6 +1196,34 @@ public function provideBooleanTypesData() [['foo' => false], TruePropertyDummy::class], ]; } + + /** + * @dataProvider provideDenormalizeWithFilterBoolData + */ + public function testDenormalizeBooleanTypeWithFilterBool(array $data, ?bool $expectedFoo) + { + $normalizer = new AbstractObjectNormalizerWithMetadataAndPropertyTypeExtractors(); + + $dummy = $normalizer->denormalize($data, BoolPropertyDummy::class, null, [AbstractNormalizer::FILTER_BOOL => true]); + + $this->assertSame($expectedFoo, $dummy->foo); + } + + public function provideDenormalizeWithFilterBoolData(): array + { + return [ + [['foo' => 'true'], true], + [['foo' => '1'], true], + [['foo' => 'yes'], true], + [['foo' => 'false'], false], + [['foo' => '0'], false], + [['foo' => 'no'], false], + [['foo' => ''], false], + [['foo' => null], null], + [['foo' => 'null'], null], + [['foo' => 'something'], null], + ]; + } } class AbstractObjectNormalizerDummy extends AbstractObjectNormalizer @@ -1481,6 +1509,12 @@ class TruePropertyDummy public $foo; } +class BoolPropertyDummy +{ + /** @var null|bool */ + public $foo; +} + class SerializerCollectionDummy implements SerializerInterface, DenormalizerInterface { private array $normalizers;