Completed
Pull Request — master (#58)
by Ilya
01:50
created

ValidateListener::onKernelController()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 25
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 13
nc 3
nop 1
dl 0
loc 25
rs 9.8333
c 1
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Damax\Common\Bridge\Symfony\Bundle\Listener;
6
7
use Damax\Common\Bridge\Symfony\Bundle\Annotation\Validate;
8
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
9
use Symfony\Component\HttpFoundation\JsonResponse;
10
use Symfony\Component\HttpFoundation\Response;
11
use Symfony\Component\HttpKernel\Event\ControllerEvent;
12
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
13
use Symfony\Component\HttpKernel\KernelEvents;
14
use Symfony\Component\Serializer\SerializerInterface;
15
use Symfony\Component\Validator\Validator\ValidatorInterface;
16
17
class ValidateListener implements EventSubscriberInterface
18
{
19
    private const CONTENT_TYPE = 'json';
20
21
    private $serializer;
22
23
    private $validator;
24
25
    public function __construct(SerializerInterface $serializer, ValidatorInterface $validator)
26
    {
27
        $this->serializer = $serializer;
28
        $this->validator = $validator;
29
    }
30
31
    public static function getSubscribedEvents(): array
32
    {
33
        return [
34
            KernelEvents::CONTROLLER => ['onKernelController', -17],
35
        ];
36
    }
37
38
    /**
39
     * @throws BadRequestHttpException
40
     */
41
    public function onKernelController(ControllerEvent $event)
42
    {
43
        $request = $event->getRequest();
44
45
        if (!$request->attributes->get('_validate')) {
46
            return;
47
        }
48
49
        /** @var Validate $config */
50
        $config = $request->attributes->get('_validate');
51
52
        $object = $request->attributes->get($config->param());
53
54
        // Validate object and send problem response on failure.
55
        $violations = $this->validator->validate($object, null, $config->groups());
56
        if ($violations->count()) {
57
            $controller = function () use ($violations) {
58
                return JsonResponse::fromJsonString(
59
                    $this->serializer->serialize($violations, self::CONTENT_TYPE),
60
                    Response::HTTP_BAD_REQUEST,
61
                    ['Content-Type' => 'application/problem+json']
62
                );
63
            };
64
65
            $event->setController($controller);
66
        }
67
    }
68
}
69