Skip to content

Commit 103fc31

Browse files
committed
Use separate instance of ItemNormalizer for non-resource
1 parent 7a2e69e commit 103fc31

File tree

20 files changed

+244
-185
lines changed

20 files changed

+244
-185
lines changed

src/Bridge/Symfony/Bundle/Resources/config/api.xml

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,12 +101,31 @@
101101
<argument>null</argument>
102102
<argument type="tagged" tag="api_platform.data_transformer" on-invalid="ignore" />
103103
<argument type="service" id="api_platform.metadata.resource.metadata_factory" on-invalid="ignore" />
104-
<argument>true</argument>
104+
<argument>false</argument>
105105

106-
<!-- After the DataURINormalizer but before the object denormalizer -->
106+
<!-- After the DataUriNormalizer but before the ObjectNormalizer -->
107107
<tag name="serializer.normalizer" priority="-923" />
108108
</service>
109109

110+
<service id="api_platform.serializer.normalizer.item.non_resource" class="ApiPlatform\Core\Serializer\ItemNormalizer" public="false">
111+
<argument type="service" id="api_platform.metadata.property.name_collection_factory" />
112+
<argument type="service" id="api_platform.metadata.property.metadata_factory" />
113+
<argument type="service" id="api_platform.iri_converter" />
114+
<argument type="service" id="api_platform.resource_class_resolver" />
115+
<argument type="service" id="api_platform.property_accessor" />
116+
<argument type="service" id="api_platform.name_converter" on-invalid="ignore" />
117+
<argument type="service" id="serializer.mapping.class_metadata_factory" on-invalid="ignore" />
118+
<argument type="service" id="api_platform.item_data_provider" on-invalid="ignore" />
119+
<argument>%api_platform.allow_plain_identifiers%</argument>
120+
<argument>null</argument>
121+
<argument type="tagged" tag="api_platform.data_transformer" on-invalid="ignore" />
122+
<argument type="service" id="api_platform.metadata.resource.metadata_factory" on-invalid="ignore" />
123+
<argument>true</argument>
124+
125+
<!-- After the DataUriNormalizer but before the ObjectNormalizer -->
126+
<tag name="serializer.normalizer" priority="-925" />
127+
</service>
128+
110129
<!-- Resources Operations path resolver -->
111130

112131
<service id="api_platform.operation_path_resolver" alias="api_platform.operation_path_resolver.router" public="false" />

src/Bridge/Symfony/Bundle/Resources/config/elasticsearch.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@
5656
<argument type="service" id="property_info" on-invalid="ignore" />
5757
<argument type="service" id="serializer.mapping.class_discriminator_resolver" on-invalid="ignore" />
5858

59-
<!-- After the DataURINormalizer but before the object denormalizer -->
59+
<!-- After the DataUriNormalizer but before the ObjectNormalizer -->
6060
<tag name="serializer.normalizer" priority="-922" />
6161
</service>
6262

src/Bridge/Symfony/Bundle/Resources/config/graphql.xml

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,11 +79,30 @@
7979
<argument>null</argument>
8080
<argument type="tagged" tag="api_platform.data_transformer" on-invalid="ignore" />
8181
<argument type="service" id="api_platform.metadata.resource.metadata_factory" on-invalid="ignore" />
82-
<argument>true</argument>
82+
<argument>false</argument>
8383

84-
<!-- After the DataURINormalizer but before the object denormalizer -->
84+
<!-- After the DataUriNormalizer but before the ObjectNormalizer -->
8585
<tag name="serializer.normalizer" priority="-922" />
8686
</service>
87+
88+
<service id="api_platform.graphql.normalizer.item.non_resource" class="ApiPlatform\Core\GraphQl\Serializer\ItemNormalizer" public="false">
89+
<argument type="service" id="api_platform.metadata.property.name_collection_factory" />
90+
<argument type="service" id="api_platform.metadata.property.metadata_factory" />
91+
<argument type="service" id="api_platform.iri_converter" />
92+
<argument type="service" id="api_platform.resource_class_resolver" />
93+
<argument type="service" id="api_platform.property_accessor" />
94+
<argument type="service" id="api_platform.name_converter" on-invalid="ignore" />
95+
<argument type="service" id="serializer.mapping.class_metadata_factory" on-invalid="ignore" />
96+
<argument type="service" id="api_platform.item_data_provider" on-invalid="ignore" />
97+
<argument>%api_platform.allow_plain_identifiers%</argument>
98+
<argument>null</argument>
99+
<argument type="tagged" tag="api_platform.data_transformer" on-invalid="ignore" />
100+
<argument type="service" id="api_platform.metadata.resource.metadata_factory" on-invalid="ignore" />
101+
<argument>true</argument>
102+
103+
<!-- After the DataUriNormalizer but before the ObjectNormalizer -->
104+
<tag name="serializer.normalizer" priority="-924" />
105+
</service>
87106
</services>
88107

89108
</container>

src/Bridge/Symfony/Bundle/Resources/config/hal.xml

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,30 @@
3939
<argument type="collection" />
4040
<argument type="tagged" tag="api_platform.data_transformer" on-invalid="ignore" />
4141
<argument type="service" id="api_platform.metadata.resource.metadata_factory" on-invalid="ignore" />
42-
<argument>true</argument>
42+
<argument>false</argument>
4343

44-
<!-- After the DataURINormalizer but before the object denormalizer -->
44+
<!-- After the DataUriNormalizer but before the ObjectNormalizer -->
4545
<tag name="serializer.normalizer" priority="-922" />
4646
</service>
47+
48+
<service id="api_platform.hal.normalizer.item.non_resource" class="ApiPlatform\Core\Hal\Serializer\ItemNormalizer" public="false">
49+
<argument type="service" id="api_platform.metadata.property.name_collection_factory" />
50+
<argument type="service" id="api_platform.metadata.property.metadata_factory" />
51+
<argument type="service" id="api_platform.iri_converter" />
52+
<argument type="service" id="api_platform.resource_class_resolver" />
53+
<argument type="service" id="api_platform.property_accessor" />
54+
<argument type="service" id="api_platform.name_converter" on-invalid="ignore" />
55+
<argument type="service" id="serializer.mapping.class_metadata_factory" on-invalid="ignore" />
56+
<argument>null</argument>
57+
<argument>false</argument>
58+
<argument type="collection" />
59+
<argument type="tagged" tag="api_platform.data_transformer" on-invalid="ignore" />
60+
<argument type="service" id="api_platform.metadata.resource.metadata_factory" on-invalid="ignore" />
61+
<argument>true</argument>
62+
63+
<!-- After the DataUriNormalizer but before the ObjectNormalizer -->
64+
<tag name="serializer.normalizer" priority="-924" />
65+
</service>
4766
</services>
4867

4968
</container>

src/Bridge/Symfony/Bundle/Resources/config/jsonapi.xml

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,28 @@
4141
<argument type="service" id="api_platform.metadata.resource.metadata_factory" />
4242
<argument type="collection" />
4343
<argument type="tagged" tag="api_platform.data_transformer" on-invalid="ignore" />
44-
<argument>true</argument>
44+
<argument>false</argument>
4545

46-
<!-- After the DataURINormalizer but before the object denormalizer -->
46+
<!-- After the DataUriNormalizer but before the ObjectNormalizer -->
4747
<tag name="serializer.normalizer" priority="-922" />
4848
</service>
4949

50+
<service id="api_platform.jsonapi.normalizer.item.non_resource" class="ApiPlatform\Core\JsonApi\Serializer\ItemNormalizer" public="false">
51+
<argument type="service" id="api_platform.metadata.property.name_collection_factory" />
52+
<argument type="service" id="api_platform.metadata.property.metadata_factory" />
53+
<argument type="service" id="api_platform.iri_converter" />
54+
<argument type="service" id="api_platform.resource_class_resolver" />
55+
<argument type="service" id="api_platform.property_accessor" />
56+
<argument type="service" id="api_platform.jsonapi.name_converter.reserved_attribute_name" />
57+
<argument type="service" id="api_platform.metadata.resource.metadata_factory" />
58+
<argument type="collection" />
59+
<argument type="tagged" tag="api_platform.data_transformer" on-invalid="ignore" />
60+
<argument>true</argument>
61+
62+
<!-- After the DataUriNormalizer but before the ObjectNormalizer -->
63+
<tag name="serializer.normalizer" priority="-924" />
64+
</service>
65+
5066
<service id="api_platform.jsonapi.normalizer.constraint_violation_list" class="ApiPlatform\Core\JsonApi\Serializer\ConstraintViolationListNormalizer" public="false">
5167
<argument type="service" id="api_platform.metadata.property.metadata_factory" />
5268
<argument type="service" id="api_platform.jsonapi.name_converter.reserved_attribute_name" />

src/Bridge/Symfony/Bundle/Resources/config/jsonld.xml

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,30 @@
2727
<argument type="service" id="serializer.mapping.class_metadata_factory" on-invalid="ignore" />
2828
<argument type="collection" />
2929
<argument type="tagged" tag="api_platform.data_transformer" on-invalid="ignore" />
30-
<argument>true</argument>
30+
<argument>false</argument>
3131

32-
<!-- After the DataURINormalizer but before the object denormalizer -->
32+
<!-- After the DataUriNormalizer but before the ObjectNormalizer -->
3333
<tag name="serializer.normalizer" priority="-922" />
3434
</service>
3535

36+
<service id="api_platform.jsonld.normalizer.item.non_resource" class="ApiPlatform\Core\JsonLd\Serializer\ItemNormalizer" public="false">
37+
<argument type="service" id="api_platform.metadata.resource.metadata_factory" />
38+
<argument type="service" id="api_platform.metadata.property.name_collection_factory" />
39+
<argument type="service" id="api_platform.metadata.property.metadata_factory" />
40+
<argument type="service" id="api_platform.iri_converter" />
41+
<argument type="service" id="api_platform.resource_class_resolver" />
42+
<argument type="service" id="api_platform.jsonld.context_builder" />
43+
<argument type="service" id="api_platform.property_accessor" />
44+
<argument type="service" id="api_platform.name_converter" on-invalid="ignore" />
45+
<argument type="service" id="serializer.mapping.class_metadata_factory" on-invalid="ignore" />
46+
<argument type="collection" />
47+
<argument type="tagged" tag="api_platform.data_transformer" on-invalid="ignore" />
48+
<argument>true</argument>
49+
50+
<!-- After the DataUriNormalizer but before the ObjectNormalizer -->
51+
<tag name="serializer.normalizer" priority="-924" />
52+
</service>
53+
3654
<service id="api_platform.jsonld.encoder" class="ApiPlatform\Core\Serializer\JsonEncoder" public="false">
3755
<argument>jsonld</argument>
3856

src/GraphQl/Serializer/ItemNormalizer.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,9 @@ final class ItemNormalizer extends BaseItemNormalizer
2929
/**
3030
* {@inheritdoc}
3131
*/
32-
public function supportsNormalization($data, $format = null)
32+
public function supportsNormalization($data, $format = null, array $context = [])
3333
{
34-
return self::FORMAT === $format && parent::supportsNormalization($data, $format);
34+
return self::FORMAT === $format && parent::supportsNormalization($data, $format, $context);
3535
}
3636

3737
/**
@@ -58,9 +58,9 @@ protected function normalizeCollectionOfRelations(PropertyMetadata $propertyMeta
5858
/**
5959
* {@inheritdoc}
6060
*/
61-
public function supportsDenormalization($data, $type, $format = null)
61+
public function supportsDenormalization($data, $type, $format = null, array $context = [])
6262
{
63-
return self::FORMAT === $format && parent::supportsDenormalization($data, $type, $format);
63+
return self::FORMAT === $format && parent::supportsDenormalization($data, $type, $format, $context);
6464
}
6565

6666
/**

src/Hal/Serializer/ItemNormalizer.php

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313

1414
namespace ApiPlatform\Core\Hal\Serializer;
1515

16-
use ApiPlatform\Core\Exception\InvalidArgumentException;
1716
use ApiPlatform\Core\Exception\RuntimeException;
1817
use ApiPlatform\Core\Serializer\AbstractItemNormalizer;
1918
use ApiPlatform\Core\Serializer\ContextTrait;
@@ -38,26 +37,22 @@ final class ItemNormalizer extends AbstractItemNormalizer
3837
/**
3938
* {@inheritdoc}
4039
*/
41-
public function supportsNormalization($data, $format = null)
40+
public function supportsNormalization($data, $format = null, array $context = [])
4241
{
43-
return self::FORMAT === $format && parent::supportsNormalization($data, $format);
42+
return self::FORMAT === $format && parent::supportsNormalization($data, $format, $context);
4443
}
4544

4645
/**
4746
* {@inheritdoc}
4847
*/
4948
public function normalize($object, $format = null, array $context = [])
5049
{
51-
if (!isset($context['cache_key'])) {
52-
$context['cache_key'] = $this->getHalCacheKey($format, $context);
53-
}
54-
55-
$object = $this->transformOutput($object, $context);
50+
if ($this->handleNonResource && ($context['api_normalize'] ?? false) || null !== $outputClass = $this->getOutputClass($this->getObjectClass($object), $context)) {
51+
if (isset($outputClass)) {
52+
$object = $this->transformOutput($object, $context);
53+
}
5654

57-
try {
58-
$resourceClass = $this->resourceClassResolver->getResourceClass($object, $context['resource_class'] ?? null, true);
59-
} catch (InvalidArgumentException $e) {
60-
$data = $this->initContext(\get_class($object), $context);
55+
$data = $this->initContext($this->getObjectClass($object), $context);
6156
$rawData = parent::normalize($object, $format, $context);
6257
if (!\is_array($rawData)) {
6358
return $rawData;
@@ -66,6 +61,11 @@ public function normalize($object, $format = null, array $context = [])
6661
return $data + $rawData;
6762
}
6863

64+
if (!isset($context['cache_key'])) {
65+
$context['cache_key'] = $this->getHalCacheKey($format, $context);
66+
}
67+
68+
$resourceClass = $this->resourceClassResolver->getResourceClass($object, $context['resource_class'] ?? null, true);
6969
$context = $this->initContext($resourceClass, $context);
7070
$context['iri'] = $this->iriConverter->getIriFromItem($object);
7171
$context['api_normalize'] = true;
@@ -86,7 +86,7 @@ public function normalize($object, $format = null, array $context = [])
8686
/**
8787
* {@inheritdoc}
8888
*/
89-
public function supportsDenormalization($data, $type, $format = null)
89+
public function supportsDenormalization($data, $type, $format = null, array $context = [])
9090
{
9191
return false;
9292
}

src/JsonApi/Serializer/ItemNormalizer.php

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
use ApiPlatform\Core\Metadata\Property\PropertyMetadata;
2424
use ApiPlatform\Core\Metadata\Resource\Factory\ResourceMetadataFactoryInterface;
2525
use ApiPlatform\Core\Serializer\AbstractItemNormalizer;
26+
use ApiPlatform\Core\Util\ClassInfoTrait;
2627
use Symfony\Component\PropertyAccess\PropertyAccessorInterface;
2728
use Symfony\Component\Serializer\NameConverter\NameConverterInterface;
2829
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
@@ -37,34 +38,42 @@
3738
*/
3839
final class ItemNormalizer extends AbstractItemNormalizer
3940
{
41+
use ClassInfoTrait;
42+
4043
const FORMAT = 'jsonapi';
4144

4245
private $componentsCache = [];
4346

44-
public function __construct(PropertyNameCollectionFactoryInterface $propertyNameCollectionFactory, PropertyMetadataFactoryInterface $propertyMetadataFactory, IriConverterInterface $iriConverter, ResourceClassResolverInterface $resourceClassResolver, PropertyAccessorInterface $propertyAccessor = null, NameConverterInterface $nameConverter = null, ResourceMetadataFactoryInterface $resourceMetadataFactory, array $defaultContext = [], iterable $dataTransformers = [], bool $allowUnmappedClass = false)
47+
public function __construct(PropertyNameCollectionFactoryInterface $propertyNameCollectionFactory, PropertyMetadataFactoryInterface $propertyMetadataFactory, IriConverterInterface $iriConverter, ResourceClassResolverInterface $resourceClassResolver, PropertyAccessorInterface $propertyAccessor = null, NameConverterInterface $nameConverter = null, ResourceMetadataFactoryInterface $resourceMetadataFactory, array $defaultContext = [], iterable $dataTransformers = [], bool $handleNonResource = false)
4548
{
46-
parent::__construct($propertyNameCollectionFactory, $propertyMetadataFactory, $iriConverter, $resourceClassResolver, $propertyAccessor, $nameConverter, null, null, false, $defaultContext, $dataTransformers, $resourceMetadataFactory, $allowUnmappedClass);
49+
parent::__construct($propertyNameCollectionFactory, $propertyMetadataFactory, $iriConverter, $resourceClassResolver, $propertyAccessor, $nameConverter, null, null, false, $defaultContext, $dataTransformers, $resourceMetadataFactory, $handleNonResource);
4750
}
4851

4952
/**
5053
* {@inheritdoc}
5154
*/
52-
public function supportsNormalization($data, $format = null)
55+
public function supportsNormalization($data, $format = null, array $context = [])
5356
{
54-
return self::FORMAT === $format && parent::supportsNormalization($data, $format);
57+
return self::FORMAT === $format && parent::supportsNormalization($data, $format, $context);
5558
}
5659

5760
/**
5861
* {@inheritdoc}
5962
*/
6063
public function normalize($object, $format = null, array $context = [])
6164
{
65+
if ($this->handleNonResource && ($context['api_normalize'] ?? false) || null !== $outputClass = $this->getOutputClass($this->getObjectClass($object), $context)) {
66+
if (isset($outputClass)) {
67+
$object = $this->transformOutput($object, $context);
68+
}
69+
70+
return parent::normalize($object, $format, $context);
71+
}
72+
6273
if (!isset($context['cache_key'])) {
6374
$context['cache_key'] = $this->getJsonApiCacheKey($format, $context);
6475
}
6576

66-
$object = $this->transformOutput($object, $context);
67-
6877
// Get and populate attributes data
6978
$objectAttributesData = parent::normalize($object, $format, $context);
7079

@@ -73,12 +82,7 @@ public function normalize($object, $format = null, array $context = [])
7382
}
7483

7584
// Get and populate item type
76-
try {
77-
$resourceClass = $this->resourceClassResolver->getResourceClass($object, $context['resource_class'] ?? null, true);
78-
} catch (InvalidArgumentException $e) {
79-
return parent::normalize($object, $format, $context);
80-
}
81-
85+
$resourceClass = $this->resourceClassResolver->getResourceClass($object, $context['resource_class'] ?? null, true);
8286
$resourceMetadata = $this->resourceMetadataFactory->create($resourceClass);
8387

8488
// Get and populate relations
@@ -112,9 +116,9 @@ public function normalize($object, $format = null, array $context = [])
112116
/**
113117
* {@inheritdoc}
114118
*/
115-
public function supportsDenormalization($data, $type, $format = null)
119+
public function supportsDenormalization($data, $type, $format = null, array $context = [])
116120
{
117-
return self::FORMAT === $format && parent::supportsDenormalization($data, $type, $format);
121+
return self::FORMAT === $format && parent::supportsDenormalization($data, $type, $format, $context);
118122
}
119123

120124
/**
@@ -252,7 +256,7 @@ protected function isAllowedAttribute($classOrObject, $attribute, $format = null
252256
*/
253257
private function getComponents($object, string $format = null, array $context)
254258
{
255-
$cacheKey = \get_class($object).'-'.$context['cache_key'];
259+
$cacheKey = $this->getObjectClass($object).'-'.$context['cache_key'];
256260

257261
if (isset($this->componentsCache[$cacheKey])) {
258262
return $this->componentsCache[$cacheKey];

0 commit comments

Comments
 (0)