Skip to content

Commit 8d5dde4

Browse files
committed
Fix stuff
1 parent 2141440 commit 8d5dde4

File tree

14 files changed

+113
-153
lines changed

14 files changed

+113
-153
lines changed

features/main/content_negotiation.feature

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,8 @@ Feature: Content Negotiation support
6363
"jsonData": [],
6464
"arrayData": [],
6565
"name_converted": null,
66-
"relatedOwnedDummy": null,
67-
"relatedOwningDummy": null,
66+
"relatedOwnedDummy": null,
67+
"relatedOwningDummy": null,
6868
"id": 1,
6969
"name": "XML!",
7070
"alias": null,

src/GraphQl/Resolver/ResourceFieldResolver.php

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,16 +42,15 @@ public function __construct(IriConverterInterface $iriConverter, ResourceClassRe
4242
public function __invoke($source, $args, $context, ResolveInfo $info)
4343
{
4444
$property = null;
45-
if ('id' === $info->fieldName && isset($source[ItemNormalizer::ITEM_KEY])) {
45+
if ('id' === $info->fieldName && !isset($source['_id']) && isset($source[ItemNormalizer::ITEM_KEY])) {
4646
$object = unserialize($source[ItemNormalizer::ITEM_KEY]);
4747
if ($this->resourceClassResolver->isResourceClass($this->getObjectClass($object))) {
4848
return $this->iriConverter->getIriFromItem($object);
4949
}
5050
}
5151

52-
if ('_id' === $info->fieldName && isset($source['id'])) {
53-
// if we set _id in the normalizer we take it
54-
$property = $source['_id'] ?? $source['id'];
52+
if ('_id' === $info->fieldName && !isset($source['_id']) && isset($source['id'])) {
53+
$property = $source['id'];
5554
} elseif (\is_array($source) && isset($source[$info->fieldName])) {
5655
$property = $source[$info->fieldName];
5756
} elseif (isset($source->{$info->fieldName})) {

src/GraphQl/Serializer/ItemNormalizer.php

Lines changed: 8 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,7 @@
1616
use ApiPlatform\Core\Metadata\Property\PropertyMetadata;
1717
use ApiPlatform\Core\Serializer\ItemNormalizer as BaseItemNormalizer;
1818
use ApiPlatform\Core\Util\ClassInfoTrait;
19-
use Symfony\Component\Serializer\Exception\LogicException;
2019
use Symfony\Component\Serializer\Exception\UnexpectedValueException;
21-
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
2220

2321
/**
2422
* GraphQL normalizer.
@@ -47,28 +45,21 @@ public function supportsNormalization($data, $format = null, array $context = []
4745
*/
4846
public function normalize($object, $format = null, array $context = [])
4947
{
50-
if (!$this->handleNonResource && $object !== $transformed = $this->transformOutput($object, $context)) {
51-
if (!$this->serializer instanceof NormalizerInterface) {
52-
throw new LogicException('Cannot normalize the transformed value because the injected serializer is not a normalizer');
53-
}
54-
55-
$context['api_normalize'] = true;
56-
$context['resource_class'] = $this->getObjectClass($transformed);
57-
$context['origin_resource'] = $object;
58-
59-
return $this->serializer->normalize($transformed, $format, $context);
48+
if (!$this->handleNonResource && null !== $outputClass = $this->getOutputClass($this->getObjectClass($object), $context)) {
49+
return parent::normalize($object, $format, $context);
6050
}
6151

6252
$data = parent::normalize($object, $format, $context);
6353
if (!\is_array($data)) {
6454
throw new UnexpectedValueException('Expected data to be an array');
6555
}
6656

67-
// we're handling the case where we have an Output class, we need the IRI from the origin resource
68-
if (($context['origin_resource'] ?? false) && isset($data['id'])) {
69-
$data['_id'] = $data['id'];
70-
$data['id'] = $this->iriConverter->getIriFromItem($context['origin_resource']);
71-
unset($context['origin_resource']);
57+
if ($this->handleNonResource) {
58+
// when using an output class, get the IRI from the resource
59+
if (isset($context['api_resource']) && isset($data['id'])) {
60+
$data['_id'] = $data['id'];
61+
$data['id'] = $this->iriConverter->getIriFromItem($context['api_resource']);
62+
}
7263
}
7364

7465
$data[self::ITEM_KEY] = serialize($object); // calling serialize prevent weird normalization process done by Webonyx's GraphQL PHP

src/Hal/Serializer/ItemNormalizer.php

Lines changed: 4 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,12 @@
1313

1414
namespace ApiPlatform\Core\Hal\Serializer;
1515

16-
use ApiPlatform\Core\Exception\RuntimeException;
1716
use ApiPlatform\Core\Serializer\AbstractItemNormalizer;
1817
use ApiPlatform\Core\Serializer\ContextTrait;
1918
use ApiPlatform\Core\Util\ClassInfoTrait;
2019
use Symfony\Component\Serializer\Exception\LogicException;
2120
use Symfony\Component\Serializer\Exception\UnexpectedValueException;
2221
use Symfony\Component\Serializer\Mapping\AttributeMetadataInterface;
23-
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
2422

2523
/**
2624
* Converts between objects and array including HAL metadata.
@@ -50,26 +48,8 @@ public function supportsNormalization($data, $format = null, array $context = []
5048
*/
5149
public function normalize($object, $format = null, array $context = [])
5250
{
53-
if (!$this->handleNonResource && $object !== $transformed = $this->transformOutput($object, $context)) {
54-
if (!$this->serializer instanceof NormalizerInterface) {
55-
throw new LogicException('Cannot normalize the transformed value because the injected serializer is not a normalizer');
56-
}
57-
58-
$context['api_normalize'] = true;
59-
$context['resource_class'] = $this->getObjectClass($transformed);
60-
61-
return $this->serializer->normalize($transformed, $format, $context);
62-
}
63-
64-
if ($this->handleNonResource && $context['api_normalize'] ?? false) {
65-
$object = $this->transformOutput($object, $context);
66-
$data = $this->initContext($this->getObjectClass($object), $context);
67-
$rawData = parent::normalize($object, $format, $context);
68-
if (!\is_array($rawData)) {
69-
return $rawData;
70-
}
71-
72-
return $data + $rawData;
51+
if ($this->handleNonResource || null !== $outputClass = $this->getOutputClass($this->getObjectClass($object), $context)) {
52+
return parent::normalize($object, $format, $context);
7353
}
7454

7555
if (!isset($context['cache_key'])) {
@@ -105,11 +85,11 @@ public function supportsDenormalization($data, $type, $format = null, array $con
10585
/**
10686
* {@inheritdoc}
10787
*
108-
* @throws RuntimeException
88+
* @throws LogicException
10989
*/
11090
public function denormalize($data, $class, $format = null, array $context = [])
11191
{
112-
throw new RuntimeException(sprintf('%s is a read-only format.', self::FORMAT));
92+
throw new LogicException(sprintf('%s is a read-only format.', self::FORMAT));
11393
}
11494

11595
/**

src/JsonApi/Serializer/ItemNormalizer.php

Lines changed: 19 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
use ApiPlatform\Core\Api\IriConverterInterface;
1717
use ApiPlatform\Core\Api\OperationType;
1818
use ApiPlatform\Core\Api\ResourceClassResolverInterface;
19-
use ApiPlatform\Core\Exception\InvalidArgumentException;
2019
use ApiPlatform\Core\Exception\ItemNotFoundException;
2120
use ApiPlatform\Core\Metadata\Property\Factory\PropertyMetadataFactoryInterface;
2221
use ApiPlatform\Core\Metadata\Property\Factory\PropertyNameCollectionFactoryInterface;
@@ -25,7 +24,9 @@
2524
use ApiPlatform\Core\Serializer\AbstractItemNormalizer;
2625
use ApiPlatform\Core\Util\ClassInfoTrait;
2726
use Symfony\Component\PropertyAccess\PropertyAccessorInterface;
28-
use Symfony\Component\Serializer\Exception\LogicException;
27+
use Symfony\Component\Serializer\Exception\NotNormalizableValueException;
28+
use Symfony\Component\Serializer\Exception\RuntimeException;
29+
use Symfony\Component\Serializer\Exception\UnexpectedValueException;
2930
use Symfony\Component\Serializer\NameConverter\NameConverterInterface;
3031
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
3132
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
@@ -63,22 +64,7 @@ public function supportsNormalization($data, $format = null, array $context = []
6364
*/
6465
public function normalize($object, $format = null, array $context = [])
6566
{
66-
if (!$this->handleNonResource && $object !== $transformed = $this->transformOutput($object, $context)) {
67-
if (!$this->serializer instanceof NormalizerInterface) {
68-
throw new LogicException('Cannot normalize the transformed value because the injected serializer is not a normalizer');
69-
}
70-
71-
$context['api_normalize'] = true;
72-
$context['resource_class'] = $this->getObjectClass($transformed);
73-
74-
return $this->serializer->normalize($transformed, $format, $context);
75-
}
76-
77-
if ($this->handleNonResource && $context['api_normalize'] ?? false) {
78-
$object = $this->transformOutput($object, $context);
79-
$context['api_normalize'] = true;
80-
$context['resource_class'] = $this->getObjectClass($object);
81-
67+
if ($this->handleNonResource || null !== $outputClass = $this->getOutputClass($this->getObjectClass($object), $context)) {
8268
return parent::normalize($object, $format, $context);
8369
}
8470

@@ -135,13 +121,15 @@ public function supportsDenormalization($data, $type, $format = null, array $con
135121

136122
/**
137123
* {@inheritdoc}
124+
*
125+
* @throws NotNormalizableValueException
138126
*/
139127
public function denormalize($data, $class, $format = null, array $context = [])
140128
{
141129
// Avoid issues with proxies if we populated the object
142130
if (!isset($context[self::OBJECT_TO_POPULATE]) && isset($data['data']['id'])) {
143131
if (isset($context['api_allow_update']) && true !== $context['api_allow_update']) {
144-
throw new InvalidArgumentException('Update is not allowed for this operation.');
132+
throw new NotNormalizableValueException('Update is not allowed for this operation.');
145133
}
146134

147135
$context[self::OBJECT_TO_POPULATE] = $this->iriConverter->getItemFromIri(
@@ -184,6 +172,9 @@ protected function setAttributeValue($object, $attribute, $value, $format = null
184172
* {@inheritdoc}
185173
*
186174
* @see http://jsonapi.org/format/#document-resource-object-linkage
175+
*
176+
* @throws RuntimeException
177+
* @throws NotNormalizableValueException
187178
*/
188179
protected function denormalizeRelation(string $attributeName, PropertyMetadata $propertyMetadata, string $className, $value, string $format = null, array $context)
189180
{
@@ -194,24 +185,26 @@ protected function denormalizeRelation(string $attributeName, PropertyMetadata $
194185
if ($this->serializer instanceof DenormalizerInterface) {
195186
return $this->serializer->denormalize($value, $className, $format, $context);
196187
}
197-
throw new InvalidArgumentException(sprintf('The injected serializer must be an instance of "%s".', DenormalizerInterface::class));
188+
throw new RuntimeException(sprintf('The injected serializer must be an instance of "%s".', DenormalizerInterface::class));
198189
}
199190

200191
if (!\is_array($value) || !isset($value['id'], $value['type'])) {
201-
throw new InvalidArgumentException('Only resource linkage supported currently, see: http://jsonapi.org/format/#document-resource-object-linkage.');
192+
throw new NotNormalizableValueException('Only resource linkage supported currently, see: http://jsonapi.org/format/#document-resource-object-linkage.');
202193
}
203194

204195
try {
205196
return $this->iriConverter->getItemFromIri($value['id'], $context + ['fetch_data' => true]);
206197
} catch (ItemNotFoundException $e) {
207-
throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e);
198+
throw new RuntimeException($e->getMessage(), $e->getCode(), $e);
208199
}
209200
}
210201

211202
/**
212203
* {@inheritdoc}
213204
*
214205
* @see http://jsonapi.org/format/#document-resource-object-linkage
206+
*
207+
* @throws RuntimeException
215208
*/
216209
protected function normalizeRelation(PropertyMetadata $propertyMetadata, $relatedObject, string $resourceClass, string $format = null, array $context)
217210
{
@@ -224,7 +217,7 @@ protected function normalizeRelation(PropertyMetadata $propertyMetadata, $relate
224217
if ($this->serializer instanceof NormalizerInterface) {
225218
return $this->serializer->normalize($relatedObject, $format, $context);
226219
}
227-
throw new InvalidArgumentException(sprintf('The injected serializer must be an instance of "%s".', NormalizerInterface::class));
220+
throw new RuntimeException(sprintf('The injected serializer must be an instance of "%s".', NormalizerInterface::class));
228221
}
229222
} else {
230223
$iri = $this->iriConverter->getIriFromItem($relatedObject);
@@ -236,7 +229,7 @@ protected function normalizeRelation(PropertyMetadata $propertyMetadata, $relate
236229
$context['api_sub_level'] = true;
237230

238231
if (!$this->serializer instanceof NormalizerInterface) {
239-
throw new InvalidArgumentException(sprintf('The injected serializer must be an instance of "%s".', NormalizerInterface::class));
232+
throw new RuntimeException(sprintf('The injected serializer must be an instance of "%s".', NormalizerInterface::class));
240233
}
241234
$data = $this->serializer->normalize($relatedObject, $format, $context);
242235
unset($context['api_sub_level']);
@@ -328,7 +321,7 @@ private function getComponents($object, string $format = null, array $context)
328321
*
329322
* @param object $object
330323
*
331-
* @throws InvalidArgumentException
324+
* @throws UnexpectedValueException
332325
*/
333326
private function getPopulatedRelations($object, string $format = null, array $context, array $relationships): array
334327
{
@@ -367,7 +360,7 @@ private function getPopulatedRelations($object, string $format = null, array $co
367360
// Many to many relationship
368361
foreach ($attributeValue as $attributeValueElement) {
369362
if (!isset($attributeValueElement['data'])) {
370-
throw new InvalidArgumentException(sprintf('The JSON API attribute \'%s\' must contain a "data" key.', $relationshipName));
363+
throw new UnexpectedValueException(sprintf('The JSON API attribute \'%s\' must contain a "data" key.', $relationshipName));
371364
}
372365
unset($attributeValueElement['data']['attributes']);
373366
$data[$relationshipName]['data'][] = $attributeValueElement['data'];

src/JsonLd/Serializer/ItemNormalizer.php

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515

1616
use ApiPlatform\Core\Api\IriConverterInterface;
1717
use ApiPlatform\Core\Api\ResourceClassResolverInterface;
18-
use ApiPlatform\Core\Exception\InvalidArgumentException;
1918
use ApiPlatform\Core\JsonLd\ContextBuilderInterface;
2019
use ApiPlatform\Core\Metadata\Property\Factory\PropertyMetadataFactoryInterface;
2120
use ApiPlatform\Core\Metadata\Property\Factory\PropertyNameCollectionFactoryInterface;
@@ -25,9 +24,9 @@
2524
use ApiPlatform\Core\Util\ClassInfoTrait;
2625
use Symfony\Component\PropertyAccess\PropertyAccessorInterface;
2726
use Symfony\Component\Serializer\Exception\LogicException;
27+
use Symfony\Component\Serializer\Exception\NotNormalizableValueException;
2828
use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactoryInterface;
2929
use Symfony\Component\Serializer\NameConverter\NameConverterInterface;
30-
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
3130

3231
/**
3332
* Converts between objects and array including JSON-LD and Hydra metadata.
@@ -61,24 +60,22 @@ public function supportsNormalization($data, $format = null, array $context = []
6160

6261
/**
6362
* {@inheritdoc}
63+
*
64+
* @throws LogicException
6465
*/
6566
public function normalize($object, $format = null, array $context = [])
6667
{
67-
if (!$this->handleNonResource && $object !== $transformed = $this->transformOutput($object, $context)) {
68-
if (!$this->serializer instanceof NormalizerInterface) {
69-
throw new LogicException('Cannot normalize the transformed value because the injected serializer is not a normalizer');
70-
}
71-
72-
$context['api_normalize'] = true;
73-
$context['resource_class'] = $this->getObjectClass($transformed);
74-
$context['origin_resource'] = $object;
75-
76-
return $this->serializer->normalize($transformed, $format, $context);
68+
if (!$this->handleNonResource && null !== $outputClass = $this->getOutputClass($this->getObjectClass($object), $context)) {
69+
return parent::normalize($object, $format, $context);
7770
}
7871

79-
if ($this->handleNonResource && $context['api_normalize'] ?? false) {
80-
if (($context['origin_resource'] ?? false)) {
81-
$context['output']['iri'] = $this->iriConverter->getIriFromItem($context['origin_resource']);
72+
if ($this->handleNonResource) {
73+
if (!($context['api_normalize'] ?? false)) {
74+
throw new LogicException('"api_normalize" must be set to true in context to normalize non-resource');
75+
}
76+
77+
if (isset($context['api_resource'])) {
78+
$context['output']['iri'] = $this->iriConverter->getIriFromItem($context['api_resource']);
8279
}
8380

8481
$data = $this->createJsonLdContext($this->contextBuilder, $object, $context);
@@ -120,14 +117,14 @@ public function supportsDenormalization($data, $type, $format = null, array $con
120117
/**
121118
* {@inheritdoc}
122119
*
123-
* @throws InvalidArgumentException
120+
* @throws NotNormalizableValueException
124121
*/
125122
public function denormalize($data, $class, $format = null, array $context = [])
126123
{
127124
// Avoid issues with proxies if we populated the object
128125
if (isset($data['@id']) && !isset($context[self::OBJECT_TO_POPULATE])) {
129126
if (isset($context['api_allow_update']) && true !== $context['api_allow_update']) {
130-
throw new InvalidArgumentException('Update is not allowed for this operation.');
127+
throw new NotNormalizableValueException('Update is not allowed for this operation.');
131128
}
132129

133130
$context[self::OBJECT_TO_POPULATE] = $this->iriConverter->getItemFromIri($data['@id'], $context + ['fetch_data' => true]);

0 commit comments

Comments
 (0)