A gateway/firewall task to be able to talk someone about the real job
Fibinger Ádám
2021-10-22 fd7692eae00cbb0db3e6b732f68357e3c64a8a8b
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
<?php
 
namespace App\EventListener;
 
use ApiPlatform\Core\Util\RequestAttributesExtractor;
use ApiPlatform\Core\Validator\ValidatorInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use ApiPlatform\Core\EventListener\DeserializeListener as DecoratedListener;
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
use ApiPlatform\Core\Serializer\SerializerContextBuilderInterface;
 
/**
 * We need this to be able to accept application/x-www-form-urlencoded type data
 */
final class DeserializeListener
{
    private $decorated;
    private $denormalizer;
    private $serializerContextBuilder;
 
    public function __construct(
        DenormalizerInterface $denormalizer,
        SerializerContextBuilderInterface $serializerContextBuilder,
        DecoratedListener $decorated,
        ValidatorInterface $validator
    )
    {
        $this->denormalizer = $denormalizer;
        $this->serializerContextBuilder = $serializerContextBuilder;
        $this->decorated = $decorated;
    }
 
    public function onKernelRequest(RequestEvent $event): void
    {
        $request = $event->getRequest();
        if ($request->isMethodCacheable() || $request->isMethod(Request::METHOD_DELETE))
        {
            return;
        }
 
        if ('form' === $request->getContentType())
        {
            $this->denormalizeFormRequest($request);
        }
        else
        {
            $this->decorated->onKernelRequest($event);
        }
    }
 
    private function denormalizeFormRequest(Request $request): void
    {
        if (!$attributes = RequestAttributesExtractor::extractAttributes($request))
        {
            return;
        }
        $context = $this->serializerContextBuilder->createFromRequest($request, false, $attributes);
        $populated = $request->attributes->get('data');
 
        if (null !== $populated)
        {
            $context['object_to_populate'] = $populated;
        }
 
        $data = $request->request->all();
        $object = $this->denormalizer->denormalize($data, $attributes['resource_class'], null, $context);
        $request->attributes->set('data', $object);
    }
}