-
-
Notifications
You must be signed in to change notification settings - Fork 979
Expand file tree
/
Copy pathDeserializeListener.php
More file actions
92 lines (77 loc) · 3.15 KB
/
Copy pathDeserializeListener.php
File metadata and controls
92 lines (77 loc) · 3.15 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
<?php
/*
* This file is part of the API Platform project.
*
* (c) Kévin Dunglas <dunglas@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
declare(strict_types=1);
namespace ApiPlatform\Symfony\EventListener;
use ApiPlatform\Metadata\Resource\Factory\ResourceMetadataCollectionFactoryInterface;
use ApiPlatform\State\ProviderInterface;
use ApiPlatform\State\SerializerContextBuilderInterface;
use ApiPlatform\State\Util\OperationRequestInitiatorTrait;
use ApiPlatform\State\Util\RequestAttributesExtractor;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\Exception\UnsupportedMediaTypeHttpException;
/**
* Updates the entity retrieved by the data provider with data contained in the request body.
*
* @author Kévin Dunglas <dunglas@gmail.com>
*/
final class DeserializeListener
{
use OperationRequestInitiatorTrait;
public const OPERATION_ATTRIBUTE_KEY = 'deserialize';
/**
* @param ProviderInterface<object> $provider
*/
public function __construct(
private ProviderInterface $provider,
?ResourceMetadataCollectionFactoryInterface $resourceMetadataFactory = null,
) {
$this->resourceMetadataCollectionFactory = $resourceMetadataFactory;
}
/**
* Deserializes the data sent in the requested format.
*
* @throws UnsupportedMediaTypeHttpException
*/
public function onKernelRequest(RequestEvent $event): void
{
$request = $event->getRequest();
$method = $request->getMethod();
$operation = $this->initializeOperation($request);
if (
!($attributes = RequestAttributesExtractor::extractAttributes($request))
|| !$attributes['receive']
|| !$operation
) {
return;
}
if (null === $operation->canDeserialize()) {
$operation = $operation->withDeserialize(\in_array($method, ['POST', 'PUT', 'PATCH'], true));
}
$denormalizationContext = $operation->getDenormalizationContext() ?? [];
if ($operation->canDeserialize() && !isset($denormalizationContext[SerializerContextBuilderInterface::ASSIGN_OBJECT_TO_POPULATE])) {
$method = $operation->getMethod();
$assignObjectToPopulate = 'POST' === $method
|| 'PATCH' === $method
|| ('PUT' === $method && !($operation->getExtraProperties()['standard_put'] ?? true));
$operation = $operation->withDenormalizationContext($denormalizationContext + [SerializerContextBuilderInterface::ASSIGN_OBJECT_TO_POPULATE => $assignObjectToPopulate]);
}
if (!$operation->canDeserialize()) {
if (!$request->attributes->has('data')) {
$request->attributes->set('data', null);
}
return;
}
$this->provider->provide($operation, $request->attributes->get('_api_uri_variables') ?? [], [
'request' => $request,
'uri_variables' => $request->attributes->get('_api_uri_variables') ?? [],
'resource_class' => $operation->getClass(),
]);
}
}