Skip to content

Commit 0c2eafa

Browse files
committed
refactor: split normalizer/denormalizer
1 parent c0a8d88 commit 0c2eafa

13 files changed

Lines changed: 1059 additions & 152 deletions

File tree

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the API Platform project.
5+
*
6+
* (c) Kévin Dunglas <dunglas@gmail.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
declare(strict_types=1);
13+
14+
namespace ApiPlatform\JsonApi\Serializer;
15+
16+
use ApiPlatform\Metadata\IriConverterInterface;
17+
use ApiPlatform\Metadata\Property\Factory\PropertyMetadataFactoryInterface;
18+
use ApiPlatform\Metadata\Property\Factory\PropertyNameCollectionFactoryInterface;
19+
use ApiPlatform\Metadata\Resource\Factory\ResourceMetadataCollectionFactoryInterface;
20+
use ApiPlatform\Metadata\ResourceAccessCheckerInterface;
21+
use ApiPlatform\Metadata\ResourceClassResolverInterface;
22+
use ApiPlatform\Serializer\AbstractItemNormalizer;
23+
use ApiPlatform\Serializer\TagCollectorInterface;
24+
use Symfony\Component\PropertyAccess\PropertyAccessorInterface;
25+
use Symfony\Component\Serializer\Exception\NotNormalizableValueException;
26+
use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactoryInterface;
27+
use Symfony\Component\Serializer\NameConverter\NameConverterInterface;
28+
29+
/**
30+
* Converts JSON:API data to objects (denormalization only).
31+
*
32+
* @author Kévin Dunglas <dunglas@gmail.com>
33+
* @author Amrouche Hamza <hamza.simperfit@gmail.com>
34+
* @author Baptiste Meyer <baptiste.meyer@gmail.com>
35+
*/
36+
final class ItemDenormalizer extends AbstractItemNormalizer
37+
{
38+
use ItemNormalizerTrait;
39+
40+
public function __construct(
41+
PropertyNameCollectionFactoryInterface $propertyNameCollectionFactory,
42+
PropertyMetadataFactoryInterface $propertyMetadataFactory,
43+
IriConverterInterface $iriConverter,
44+
ResourceClassResolverInterface $resourceClassResolver,
45+
?PropertyAccessorInterface $propertyAccessor = null,
46+
?NameConverterInterface $nameConverter = null,
47+
?ClassMetadataFactoryInterface $classMetadataFactory = null,
48+
array $defaultContext = [],
49+
?ResourceMetadataCollectionFactoryInterface $resourceMetadataCollectionFactory = null,
50+
?ResourceAccessCheckerInterface $resourceAccessChecker = null,
51+
protected ?TagCollectorInterface $tagCollector = null,
52+
) {
53+
parent::__construct(
54+
$propertyNameCollectionFactory,
55+
$propertyMetadataFactory,
56+
$iriConverter,
57+
$resourceClassResolver,
58+
$propertyAccessor,
59+
$nameConverter,
60+
$classMetadataFactory,
61+
$defaultContext,
62+
$resourceMetadataCollectionFactory,
63+
$resourceAccessChecker,
64+
$tagCollector
65+
);
66+
}
67+
68+
/**
69+
* {@inheritdoc}
70+
*
71+
* @throws NotNormalizableValueException
72+
*/
73+
public function denormalize(mixed $data, string $type, ?string $format = null, array $context = []): mixed
74+
{
75+
// Avoid issues with proxies if we populated the object
76+
if (!isset($context[self::OBJECT_TO_POPULATE]) && isset($data['data']['id'])) {
77+
if (true !== ($context['api_allow_update'] ?? true)) {
78+
throw new NotNormalizableValueException('Update is not allowed for this operation.');
79+
}
80+
81+
$context[self::OBJECT_TO_POPULATE] = $this->iriConverter->getResourceFromIri(
82+
$data['data']['id'],
83+
$context + ['fetch_data' => false]
84+
);
85+
}
86+
87+
// Merge attributes and relationships, into format expected by the parent normalizer
88+
$dataToDenormalize = array_merge(
89+
$data['data']['attributes'] ?? [],
90+
$data['data']['relationships'] ?? []
91+
);
92+
93+
return parent::denormalize(
94+
$dataToDenormalize,
95+
$type,
96+
$format,
97+
$context
98+
);
99+
}
100+
}

src/JsonApi/Serializer/ItemNormalizer.php

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,8 @@
2222
use ApiPlatform\Metadata\ResourceAccessCheckerInterface;
2323
use ApiPlatform\Metadata\ResourceClassResolverInterface;
2424
use ApiPlatform\Metadata\UrlGeneratorInterface;
25-
use ApiPlatform\Metadata\Util\ClassInfoTrait;
2625
use ApiPlatform\Metadata\Util\TypeHelper;
2726
use ApiPlatform\Serializer\AbstractItemNormalizer;
28-
use ApiPlatform\Serializer\CacheKeyTrait;
29-
use ApiPlatform\Serializer\ContextTrait;
3027
use ApiPlatform\Serializer\TagCollectorInterface;
3128
use Symfony\Component\ErrorHandler\Exception\FlattenException;
3229
use Symfony\Component\PropertyAccess\PropertyAccessorInterface;
@@ -48,16 +45,12 @@
4845
* @author Kévin Dunglas <dunglas@gmail.com>
4946
* @author Amrouche Hamza <hamza.simperfit@gmail.com>
5047
* @author Baptiste Meyer <baptiste.meyer@gmail.com>
48+
*
49+
* @todo Denormalization methods should be deprecated in 5.x, use ItemDenormalizer instead
5150
*/
5251
final class ItemNormalizer extends AbstractItemNormalizer
5352
{
54-
use CacheKeyTrait;
55-
use ClassInfoTrait;
56-
use ContextTrait;
57-
58-
public const FORMAT = 'jsonapi';
59-
60-
private array $componentsCache = [];
53+
use ItemNormalizerTrait;
6154

6255
public function __construct(PropertyNameCollectionFactoryInterface $propertyNameCollectionFactory, PropertyMetadataFactoryInterface $propertyMetadataFactory, IriConverterInterface $iriConverter, ResourceClassResolverInterface $resourceClassResolver, ?PropertyAccessorInterface $propertyAccessor = null, ?NameConverterInterface $nameConverter = null, ?ClassMetadataFactoryInterface $classMetadataFactory = null, array $defaultContext = [], ?ResourceMetadataCollectionFactoryInterface $resourceMetadataCollectionFactory = null, ?ResourceAccessCheckerInterface $resourceAccessChecker = null, protected ?TagCollectorInterface $tagCollector = null)
6356
{

0 commit comments

Comments
 (0)