Skip to content

Commit 05afcae

Browse files
committed
[jsonhal] Correct normalization of output class
1 parent 90e9b15 commit 05afcae

File tree

2 files changed

+99
-5
lines changed

2 files changed

+99
-5
lines changed

features/hal/input_output.feature

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
Feature: HAL DTO input and output
2+
In order to use a hypermedia API
3+
As a client software developer
4+
I need to be able to use DTOs on my resources as Input or Output objects.
5+
6+
Background:
7+
Given I add "Accept" header equal to "application/hal+json"
8+
9+
@createSchema
10+
Scenario: Get an item with a custom output
11+
Given there is a DummyDtoCustom
12+
When I send a "GET" request to "/dummy_dto_custom_output/1"
13+
Then the response status code should be 200
14+
And the response should be in JSON
15+
And the header "Content-Type" should be equal to "application/hal+json; charset=utf-8"
16+
And the JSON should be a superset of:
17+
"""
18+
{
19+
"_links": {
20+
"self": {
21+
"href": "/dummy_dto_customs/1"
22+
}
23+
},
24+
"foo": "test",
25+
"bar": 1
26+
}
27+
"""
28+
29+
@createSchema
30+
Scenario: Get a collection with a custom output
31+
Given there are 2 DummyDtoCustom
32+
When I send a "GET" request to "/dummy_dto_custom_output"
33+
Then the response status code should be 200
34+
And the response should be in JSON
35+
And the header "Content-Type" should be equal to "application/hal+json; charset=utf-8"
36+
And the JSON should be a superset of:
37+
"""
38+
{
39+
"_embedded": {
40+
"item": [
41+
{
42+
"_links": {
43+
"self": {
44+
"href": "/dummy_dto_customs/1"
45+
}
46+
},
47+
"foo": "test",
48+
"bar": 1
49+
},
50+
{
51+
"_links": {
52+
"self": {
53+
"href": "/dummy_dto_customs/2"
54+
}
55+
},
56+
"foo": "test",
57+
"bar": 2
58+
}
59+
]
60+
}
61+
}
62+
"""

src/Hal/Serializer/ItemNormalizer.php

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,14 +48,40 @@ public function supportsNormalization($data, $format = null, array $context = []
4848
*/
4949
public function normalize($object, $format = null, array $context = [])
5050
{
51-
if ($this->handleNonResource || null !== $outputClass = $this->getOutputClass($this->getObjectClass($object), $context)) {
51+
if (!$this->handleNonResource && null !== $outputClass = $this->getOutputClass($this->getObjectClass($object), $context)) {
5252
return parent::normalize($object, $format, $context);
5353
}
5454

5555
if (!isset($context['cache_key'])) {
5656
$context['cache_key'] = $this->getHalCacheKey($format, $context);
5757
}
5858

59+
if ($this->handleNonResource) {
60+
if (isset($context['api_resource'])) {
61+
$originalResource = $context['api_resource'];
62+
unset($context['api_resource']);
63+
}
64+
65+
$rawData = parent::normalize($object, $format, $context);
66+
if (!\is_array($rawData)) {
67+
return $rawData;
68+
}
69+
70+
if (!isset($originalResource)) {
71+
return $rawData;
72+
}
73+
74+
$metadataData = [
75+
'_links' => [
76+
'self' => [
77+
'href' => $this->iriConverter->getIriFromItem($originalResource),
78+
],
79+
],
80+
];
81+
82+
return $metadataData + $rawData;
83+
}
84+
5985
$resourceClass = $this->resourceClassResolver->getResourceClass($object, $context['resource_class'] ?? null, true);
6086
$context = $this->initContext($resourceClass, $context);
6187
$context['iri'] = $this->iriConverter->getIriFromItem($object);
@@ -66,12 +92,18 @@ public function normalize($object, $format = null, array $context = [])
6692
return $rawData;
6793
}
6894

69-
$data = ['_links' => ['self' => ['href' => $context['iri']]]];
95+
$metadataData = [
96+
'_links' => [
97+
'self' => [
98+
'href' => $context['iri'],
99+
],
100+
],
101+
];
70102
$components = $this->getComponents($object, $format, $context);
71-
$data = $this->populateRelation($data, $object, $format, $context, $components, 'links');
72-
$data = $this->populateRelation($data, $object, $format, $context, $components, 'embedded');
103+
$metadataData = $this->populateRelation($metadataData, $object, $format, $context, $components, 'links');
104+
$metadataData = $this->populateRelation($metadataData, $object, $format, $context, $components, 'embedded');
73105

74-
return $data + $rawData;
106+
return $metadataData + $rawData;
75107
}
76108

77109
/**

0 commit comments

Comments
 (0)