Skip to content

Commit 2d1443b

Browse files
feature #23404 [Serializer] AbstractObjectNormalizer: Allow to disable type enforcement (ogizanagi)
This PR was merged into the 3.4 branch. Discussion ---------- [Serializer] AbstractObjectNormalizer: Allow to disable type enforcement | Q | A | ------------- | --- | Branch? | 3.4 <!-- see comment below --> | Bug fix? | no | New feature? | yes <!-- don't forget updating src/**/CHANGELOG.md files --> | BC breaks? | no | Deprecations? | no <!-- don't forget updating UPGRADE-*.md files --> | Tests pass? | yes (failure unrelated) | Fixed tickets | N/A <!-- #-prefixed issue number(s), if any --> | License | MIT | Doc PR | N/A This allows to denormalize simple DTOs with public properties using the property-info component and the `ObjectNormalizer`. The raised exception is not really useful in such cases, as it cannot be easily handled gracefully to build a proper violation response (too generic and no real hint on the complete attribute path for instance). Instead, I use the validator component to validate my DTOs and the properties' types, get a proper violation list, and build a response from it. I wasn't really inspired for the `DISABLE_TYPE_ENFORCEMENT` name. Commits ------- 959ac2a [Serializer] AbstractObjectNormalizer: Allow to disable type enforcement
2 parents b89ccad + 1bfb91f commit 2d1443b

File tree

3 files changed

+21
-0
lines changed

3 files changed

+21
-0
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
CHANGELOG
22
=========
33

4+
3.4.0
5+
-----
6+
7+
* added `AbstractObjectNormalizer::DISABLE_TYPE_ENFORCEMENT` context option
8+
to disable throwing an `UnexpectedValueException` on a type mismatch
9+
410
3.3.0
511
-----
612

Normalizer/AbstractObjectNormalizer.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ abstract class AbstractObjectNormalizer extends AbstractNormalizer
3232
const ENABLE_MAX_DEPTH = 'enable_max_depth';
3333
const DEPTH_KEY_PATTERN = 'depth_%s::%s';
3434
const ALLOW_EXTRA_ATTRIBUTES = 'allow_extra_attributes';
35+
const DISABLE_TYPE_ENFORCEMENT = 'disable_type_enforcement';
3536

3637
private $propertyTypeExtractor;
3738
private $attributesCache = array();
@@ -286,6 +287,10 @@ private function validateAndDenormalize($currentClass, $attribute, $data, $forma
286287
}
287288
}
288289

290+
if (!empty($context[self::DISABLE_TYPE_ENFORCEMENT])) {
291+
return $data;
292+
}
293+
289294
throw new UnexpectedValueException(sprintf('The type of the "%s" attribute for class "%s" must be one of "%s" ("%s" given).', $attribute, $currentClass, implode('", "', array_keys($expectedTypes)), gettype($data)));
290295
}
291296

Tests/Normalizer/ObjectNormalizerTest.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -628,6 +628,16 @@ public function testRejectInvalidKey()
628628
$serializer->denormalize(array('inners' => array('a' => array('foo' => 1))), ObjectOuter::class);
629629
}
630630

631+
public function testDoNotRejectInvalidTypeOnDisableTypeEnforcementContextOption()
632+
{
633+
$extractor = new PropertyInfoExtractor(array(), array(new PhpDocExtractor()));
634+
$normalizer = new ObjectNormalizer(null, null, null, $extractor);
635+
$serializer = new Serializer(array($normalizer));
636+
$context = array(ObjectNormalizer::DISABLE_TYPE_ENFORCEMENT => true);
637+
638+
$this->assertSame('foo', $serializer->denormalize(array('number' => 'foo'), JsonNumber::class, null, $context)->number);
639+
}
640+
631641
public function testExtractAttributesRespectsFormat()
632642
{
633643
$normalizer = new FormatAndContextAwareNormalizer();

0 commit comments

Comments
 (0)