Skip to content

Commit aaf4452

Browse files
committed
feat: complete collectDenormalizationErrors implementation
1 parent ceb2140 commit aaf4452

34 files changed

+228
-100
lines changed

features/main/validation.feature

+37-5
Original file line numberDiff line numberDiff line change
@@ -73,37 +73,69 @@ Feature: Using validations groups
7373
"""
7474
And the header "Content-Type" should be equal to "application/ld+json; charset=utf-8"
7575

76+
@!mongodb
7677
@createSchema
7778
Scenario: Create a resource with collectDenormalizationErrors
7879
When I add "Content-type" header equal to "application/ld+json"
7980
And I send a "POST" request to "/dummy_collect_denormalization" with body:
8081
"""
8182
{
8283
"foo": 3,
83-
"bar": "baz"
84+
"bar": "baz",
85+
"qux": true,
86+
"uuid": "y",
87+
"relatedDummy": 8,
88+
"relatedDummies": 76
8489
}
8590
"""
8691
Then the response status code should be 422
8792
And the response should be in JSON
93+
And the header "Content-Type" should be equal to "application/ld+json; charset=utf-8"
8894
And the JSON should be equal to:
8995
"""
9096
{
9197
"@context": "/contexts/ConstraintViolationList",
9298
"@type": "ConstraintViolationList",
9399
"hydra:title": "An error occurred",
94-
"hydra:description": "foo: The type of the \"foo\" attribute must be \"bool\", \"int\" given.\nbar: The type of the \"bar\" attribute must be \"int\", \"string\" given.",
100+
"hydra:description": "This value should be of type unknown.\nqux: This value should be of type string.\nfoo: This value should be of type bool.\nbar: This value should be of type int.\nuuid: This value should be of type uuid.\nrelatedDummy: This value should be of type array|string.\nrelatedDummies: This value should be of type array.",
95101
"violations": [
102+
{
103+
"propertyPath": "",
104+
"message": "This value should be of type unknown.",
105+
"code": "0",
106+
"hint": "Failed to create object because the class misses the \"baz\" property."
107+
},
108+
{
109+
"propertyPath": "qux",
110+
"message": "This value should be of type string.",
111+
"code": "0"
112+
},
96113
{
97114
"propertyPath": "foo",
98-
"message": "The type of the \"foo\" attribute must be \"bool\", \"int\" given.",
115+
"message": "This value should be of type bool.",
99116
"code": "0"
100117
},
101118
{
102119
"propertyPath": "bar",
103-
"message": "The type of the \"bar\" attribute must be \"int\", \"string\" given.",
120+
"message": "This value should be of type int.",
121+
"code": "0"
122+
},
123+
{
124+
"propertyPath": "uuid",
125+
"message": "This value should be of type uuid.",
126+
"code": "0",
127+
"hint": "Invalid UUID string: y"
128+
},
129+
{
130+
"propertyPath": "relatedDummy",
131+
"message": "This value should be of type array|string.",
132+
"code": "0"
133+
},
134+
{
135+
"propertyPath": "relatedDummies",
136+
"message": "This value should be of type array.",
104137
"code": "0"
105138
}
106139
]
107140
}
108141
"""
109-
And the header "Content-Type" should be equal to "application/ld+json; charset=utf-8"

src/JsonApi/Serializer/ItemNormalizer.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -192,12 +192,12 @@ protected function setAttributeValue(object $object, string $attribute, mixed $v
192192
* @see http://jsonapi.org/format/#document-resource-object-linkage
193193
*
194194
* @throws RuntimeException
195-
* @throws NotNormalizableValueException
195+
* @throws UnexpectedValueException
196196
*/
197197
protected function denormalizeRelation(string $attributeName, ApiProperty $propertyMetadata, string $className, mixed $value, ?string $format, array $context): object
198198
{
199199
if (!\is_array($value) || !isset($value['id'], $value['type'])) {
200-
throw new NotNormalizableValueException('Only resource linkage supported currently, see: http://jsonapi.org/format/#document-resource-object-linkage.');
200+
throw new UnexpectedValueException('Only resource linkage supported currently, see: http://jsonapi.org/format/#document-resource-object-linkage.');
201201
}
202202

203203
try {

src/Metadata/ApiResource.php

+14-12
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ public function __construct(
112112
protected ?array $cacheHeaders = null,
113113
protected ?array $normalizationContext = null,
114114
protected ?array $denormalizationContext = null,
115+
protected ?bool $collectDenormalizationErrors = null,
115116
protected ?array $hydraContext = null,
116117
protected ?array $openapiContext = null, // TODO Remove in 4.0
117118
protected bool|OpenApiOperation|null $openapi = null,
@@ -150,7 +151,6 @@ public function __construct(
150151
$processor = null,
151152
protected ?OptionsInterface $stateOptions = null,
152153
protected array $extraProperties = [],
153-
protected ?bool $collectDenormalizationErrors = null,
154154
) {
155155
$this->operations = null === $operations ? null : new Operations($operations);
156156
$this->provider = $provider;
@@ -538,6 +538,19 @@ public function withDenormalizationContext(array $denormalizationContext): self
538538
return $self;
539539
}
540540

541+
public function getCollectDenormalizationErrors(): ?bool
542+
{
543+
return $this->collectDenormalizationErrors;
544+
}
545+
546+
public function withCollectDenormalizationErrors(bool $collectDenormalizationErrors = null): self
547+
{
548+
$self = clone $this;
549+
$self->collectDenormalizationErrors = $collectDenormalizationErrors;
550+
551+
return $self;
552+
}
553+
541554
/**
542555
* @return string[]|null
543556
*/
@@ -1049,17 +1062,6 @@ public function withStateOptions(?OptionsInterface $stateOptions): self
10491062
{
10501063
$self = clone $this;
10511064
$self->stateOptions = $stateOptions;
1052-
}
1053-
1054-
public function getCollectDenormalizationErrors(): ?bool
1055-
{
1056-
return $this->collectDenormalizationErrors;
1057-
}
1058-
1059-
public function withCollectDenormalizationErrors(bool $collectDenormalizationErrors = null): self
1060-
{
1061-
$self = clone $this;
1062-
$self->collectDenormalizationErrors = $collectDenormalizationErrors;
10631065

10641066
return $self;
10651067
}

src/Metadata/Delete.php

+1
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ public function __construct(
6868
?string $description = null,
6969
?array $normalizationContext = null,
7070
?array $denormalizationContext = null,
71+
?bool $collectDenormalizationErrors = null,
7172
?string $security = null,
7273
?string $securityMessage = null,
7374
?string $securityPostDenormalize = null,

src/Metadata/Extractor/XmlResourceExtractor.php

+1
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ private function buildBase(\SimpleXMLElement $resource): array
135135
'securityPostValidationMessage' => $this->phpize($resource, 'securityPostValidationMessage', 'string'),
136136
'normalizationContext' => isset($resource->normalizationContext->values) ? $this->buildValues($resource->normalizationContext->values) : null,
137137
'denormalizationContext' => isset($resource->denormalizationContext->values) ? $this->buildValues($resource->denormalizationContext->values) : null,
138+
'collectDenormalizationErrors' => $this->phpize($resource, 'collectDenormalizationErrors', 'bool'),
138139
'validationContext' => isset($resource->validationContext->values) ? $this->buildValues($resource->validationContext->values) : null,
139140
'filters' => $this->buildArrayValue($resource, 'filter'),
140141
'order' => isset($resource->order->values) ? $this->buildValues($resource->order->values) : null,

src/Metadata/Extractor/YamlResourceExtractor.php

+1
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@ private function buildBase(array $resource): array
159159
'output' => $this->phpize($resource, 'output', 'bool|string'),
160160
'normalizationContext' => $this->buildArrayValue($resource, 'normalizationContext'),
161161
'denormalizationContext' => $this->buildArrayValue($resource, 'denormalizationContext'),
162+
'collectDenormalizationErrors' => $this->phpize($resource, 'collectDenormalizationErrors', 'bool'),
162163
'validationContext' => $this->buildArrayValue($resource, 'validationContext'),
163164
'filters' => $this->buildArrayValue($resource, 'filters'),
164165
'order' => $this->buildArrayValue($resource, 'order'),

src/Metadata/Extractor/schema/resources.xsd

+1
Original file line numberDiff line numberDiff line change
@@ -459,6 +459,7 @@
459459
<xsd:attribute type="xsd:string" name="securityPostDenormalizeMessage"/>
460460
<xsd:attribute type="xsd:string" name="securityPostValidation"/>
461461
<xsd:attribute type="xsd:string" name="securityPostValidationMessage"/>
462+
<xsd:attribute type="xsd:boolean" name="collectDenormalizationErrors"/>
462463
</xsd:attributeGroup>
463464

464465
<xsd:attributeGroup name="extendedBase">

src/Metadata/Get.php

+1
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ public function __construct(
6868
?string $description = null,
6969
?array $normalizationContext = null,
7070
?array $denormalizationContext = null,
71+
?bool $collectDenormalizationErrors = null,
7172
?string $security = null,
7273
?string $securityMessage = null,
7374
?string $securityPostDenormalize = null,

src/Metadata/GetCollection.php

+2-1
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ public function __construct(
7070
?string $description = null,
7171
?array $normalizationContext = null,
7272
?array $denormalizationContext = null,
73+
?bool $collectDenormalizationErrors = null,
7374
?string $security = null,
7475
?string $securityMessage = null,
7576
?string $securityPostDenormalize = null,
@@ -100,7 +101,7 @@ public function __construct(
100101
?OptionsInterface $stateOptions = null,
101102
array $extraProperties = [],
102103
) {
103-
parent::__construct(self::METHOD_GET, $uriTemplate, $types, $formats, $inputFormats, $outputFormats, $uriVariables, $routePrefix, $routeName, $defaults, $requirements, $options, $stateless, $sunset, $acceptPatch, $status, $host, $schemes, $condition, $controller, $cacheHeaders, $hydraContext, $openapiContext, $openapi, $exceptionToStatus, $queryParameterValidationEnabled, $shortName, $class, $paginationEnabled, $paginationType, $paginationItemsPerPage, $paginationMaximumItemsPerPage, $paginationPartial, $paginationClientEnabled, $paginationClientItemsPerPage, $paginationClientPartial, $paginationFetchJoinCollection, $paginationUseOutputWalkers, $paginationViaCursor, $order, $description, $normalizationContext, $denormalizationContext, $security, $securityMessage, $securityPostDenormalize, $securityPostDenormalizeMessage, $securityPostValidation, $securityPostValidationMessage, $deprecationReason, $filters, $validationContext, $input, $output, $mercure, $messenger, $elasticsearch, $urlGenerationStrategy, $read, $deserialize, $validate, $write, $serialize, $fetchPartial, $forceEager, $priority, $name, $provider, $processor, $stateOptions, $extraProperties);
104+
parent::__construct(self::METHOD_GET, $uriTemplate, $types, $formats, $inputFormats, $outputFormats, $uriVariables, $routePrefix, $routeName, $defaults, $requirements, $options, $stateless, $sunset, $acceptPatch, $status, $host, $schemes, $condition, $controller, $cacheHeaders, $hydraContext, $openapiContext, $openapi, $exceptionToStatus, $queryParameterValidationEnabled, $shortName, $class, $paginationEnabled, $paginationType, $paginationItemsPerPage, $paginationMaximumItemsPerPage, $paginationPartial, $paginationClientEnabled, $paginationClientItemsPerPage, $paginationClientPartial, $paginationFetchJoinCollection, $paginationUseOutputWalkers, $paginationViaCursor, $order, $description, $normalizationContext, $denormalizationContext, $collectDenormalizationErrors, $security, $securityMessage, $securityPostDenormalize, $securityPostDenormalizeMessage, $securityPostValidation, $securityPostValidationMessage, $deprecationReason, $filters, $validationContext, $input, $output, $mercure, $messenger, $elasticsearch, $urlGenerationStrategy, $read, $deserialize, $validate, $write, $serialize, $fetchPartial, $forceEager, $priority, $name, $provider, $processor, $stateOptions, $extraProperties);
104105
$this->itemUriTemplate = $itemUriTemplate;
105106
}
106107

src/Metadata/GraphQl/DeleteMutation.php

+1
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ public function __construct(
4545
?string $description = null,
4646
?array $normalizationContext = null,
4747
?array $denormalizationContext = null,
48+
?bool $collectDenormalizationErrors = null,
4849
?string $security = null,
4950
?string $securityMessage = null,
5051
?string $securityPostDenormalize = null,

src/Metadata/GraphQl/Operation.php

+4-3
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ public function __construct(
4949
?string $description = null,
5050
?array $normalizationContext = null,
5151
?array $denormalizationContext = null,
52+
?bool $collectDenormalizationErrors = null,
5253
?string $security = null,
5354
?string $securityMessage = null,
5455
?string $securityPostDenormalize = null,
@@ -75,9 +76,8 @@ public function __construct(
7576
?string $name = null,
7677
?string $provider = null,
7778
?string $processor = null,
78-
protected ?OptionsInterface $stateOptions = null,
79+
?OptionsInterface $stateOptions = null,
7980
array $extraProperties = [],
80-
?bool $collectDenormalizationErrors = null,
8181
) {
8282
// Abstract operation properties
8383
$this->shortName = $shortName;
@@ -97,6 +97,7 @@ public function __construct(
9797
$this->description = $description;
9898
$this->normalizationContext = $normalizationContext;
9999
$this->denormalizationContext = $denormalizationContext;
100+
$this->collectDenormalizationErrors = $collectDenormalizationErrors;
100101
$this->security = $security;
101102
$this->securityMessage = $securityMessage;
102103
$this->securityPostDenormalize = $securityPostDenormalize;
@@ -123,8 +124,8 @@ public function __construct(
123124
$this->name = $name;
124125
$this->provider = $provider;
125126
$this->processor = $processor;
127+
$this->stateOptions = $stateOptions;
126128
$this->extraProperties = $extraProperties;
127-
$this->collectDenormalizationErrors = $collectDenormalizationErrors;
128129
}
129130

130131
public function getResolver(): ?string

src/Metadata/GraphQl/Query.php

+1
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ public function __construct(
4444
?string $description = null,
4545
?array $normalizationContext = null,
4646
?array $denormalizationContext = null,
47+
?bool $collectDenormalizationErrors = null,
4748
?string $security = null,
4849
?string $securityMessage = null,
4950
?string $securityPostDenormalize = null,

src/Metadata/GraphQl/QueryCollection.php

+1
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ public function __construct(
4545
?string $description = null,
4646
?array $normalizationContext = null,
4747
?array $denormalizationContext = null,
48+
?bool $collectDenormalizationErrors = null,
4849
?string $security = null,
4950
?string $securityMessage = null,
5051
?string $securityPostDenormalize = null,

src/Metadata/GraphQl/Subscription.php

+1
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ public function __construct(
4444
?string $description = null,
4545
?array $normalizationContext = null,
4646
?array $denormalizationContext = null,
47+
?bool $collectDenormalizationErrors = null,
4748
?string $security = null,
4849
?string $securityMessage = null,
4950
?string $securityPostDenormalize = null,

src/Metadata/HttpOperation.php

+2-15
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ public function __construct(
121121
?string $description = null,
122122
?array $normalizationContext = null,
123123
?array $denormalizationContext = null,
124+
?bool $collectDenormalizationErrors = null,
124125
?string $security = null,
125126
?string $securityMessage = null,
126127
?string $securityPostDenormalize = null,
@@ -149,7 +150,6 @@ public function __construct(
149150
$processor = null,
150151
?OptionsInterface $stateOptions = null,
151152
array $extraProperties = [],
152-
?bool $collectDenormalizationErrors = null,
153153
) {
154154
$this->shortName = $shortName;
155155
$this->description = $description;
@@ -158,6 +158,7 @@ public function __construct(
158158
$this->deprecationReason = $deprecationReason;
159159
$this->normalizationContext = $normalizationContext;
160160
$this->denormalizationContext = $denormalizationContext;
161+
$this->collectDenormalizationErrors = $collectDenormalizationErrors;
161162
$this->validationContext = $validationContext;
162163
$this->filters = $filters;
163164
$this->elasticsearch = $elasticsearch;
@@ -196,7 +197,6 @@ public function __construct(
196197
$this->processor = $processor;
197198
$this->extraProperties = $extraProperties;
198199
$this->stateOptions = $stateOptions;
199-
$this->collectDenormalizationErrors = $collectDenormalizationErrors;
200200
}
201201

202202
public function getMethod(): ?string
@@ -567,17 +567,4 @@ public function withQueryParameterValidationEnabled(bool $queryParameterValidati
567567

568568
return $self;
569569
}
570-
571-
public function getCollectDenormalizationErrors(): ?bool
572-
{
573-
return $this->collectDenormalizationErrors;
574-
}
575-
576-
public function withCollectDenormalizationErrors(bool $collectDenormalizationErrors = null): self
577-
{
578-
$self = clone $this;
579-
$self->collectDenormalizationErrors = $collectDenormalizationErrors;
580-
581-
return $self;
582-
}
583570
}

src/Metadata/NotExposed.php

+1
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ public function __construct(
7676
?string $description = null,
7777
?array $normalizationContext = null,
7878
?array $denormalizationContext = null,
79+
?bool $collectDenormalizationErrors = null,
7980
?string $security = null,
8081
?string $securityMessage = null,
8182
?string $securityPostDenormalize = null,

src/Metadata/Operation.php

+14-12
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ public function __construct(
6060
protected ?string $description = null,
6161
protected ?array $normalizationContext = null,
6262
protected ?array $denormalizationContext = null,
63+
protected ?bool $collectDenormalizationErrors = null,
6364
protected ?string $security = null,
6465
protected ?string $securityMessage = null,
6566
protected ?string $securityPostDenormalize = null,
@@ -94,7 +95,6 @@ public function __construct(
9495
$processor = null,
9596
protected ?OptionsInterface $stateOptions = null,
9697
protected array $extraProperties = [],
97-
protected ?bool $collectDenormalizationErrors = null,
9898
) {
9999
$this->input = $input;
100100
$this->output = $output;
@@ -328,6 +328,19 @@ public function withDenormalizationContext(array $denormalizationContext = []):
328328
return $self;
329329
}
330330

331+
public function getCollectDenormalizationErrors(): ?bool
332+
{
333+
return $this->collectDenormalizationErrors;
334+
}
335+
336+
public function withCollectDenormalizationErrors(bool $collectDenormalizationErrors = null): self
337+
{
338+
$self = clone $this;
339+
$self->collectDenormalizationErrors = $collectDenormalizationErrors;
340+
341+
return $self;
342+
}
343+
331344
public function getSecurity(): ?string
332345
{
333346
return $this->security;
@@ -704,17 +717,6 @@ public function withStateOptions(?OptionsInterface $stateOptions): self
704717
{
705718
$self = clone $this;
706719
$self->stateOptions = $stateOptions;
707-
}
708-
709-
public function getCollectDenormalizationErrors(): ?bool
710-
{
711-
return $this->collectDenormalizationErrors;
712-
}
713-
714-
public function withCollectDenormalizationErrors(bool $collectDenormalizationErrors = null): self
715-
{
716-
$self = clone $this;
717-
$self->collectDenormalizationErrors = $collectDenormalizationErrors;
718720

719721
return $self;
720722
}

src/Metadata/Patch.php

+1
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ public function __construct(
6969
?string $description = null,
7070
?array $normalizationContext = null,
7171
?array $denormalizationContext = null,
72+
?bool $collectDenormalizationErrors = null,
7273
?string $security = null,
7374
?string $securityMessage = null,
7475
?string $securityPostDenormalize = null,

src/Metadata/Post.php

+1
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ public function __construct(
7171
?string $description = null,
7272
?array $normalizationContext = null,
7373
?array $denormalizationContext = null,
74+
?bool $collectDenormalizationErrors = null,
7475
?string $security = null,
7576
?string $securityMessage = null,
7677
?string $securityPostDenormalize = null,

0 commit comments

Comments
 (0)