1<?php
2
3declare(strict_types=1);
4
5namespace JMS\Serializer\EventDispatcher\Subscriber;
6
7use JMS\Serializer\EventDispatcher\Event;
8use JMS\Serializer\EventDispatcher\EventSubscriberInterface;
9use JMS\Serializer\Exception\ValidationFailedException;
10use Symfony\Component\Validator\Validator\ValidatorInterface;
11
12final class SymfonyValidatorValidatorSubscriber implements EventSubscriberInterface
13{
14    /**
15     * @var ValidatorInterface
16     */
17    private $validator;
18
19    public function __construct(ValidatorInterface $validator)
20    {
21        $this->validator = $validator;
22    }
23
24    /**
25     * {@inheritdoc}
26     */
27    public static function getSubscribedEvents()
28    {
29        return [
30            ['event' => 'serializer.post_deserialize', 'method' => 'onPostDeserialize'],
31        ];
32    }
33
34    public function onPostDeserialize(Event $event): void
35    {
36        $context = $event->getContext();
37
38        if ($context->getDepth() > 0) {
39            return;
40        }
41
42        $validator = $this->validator;
43        $groups = $context->hasAttribute('validation_groups') ? $context->getAttribute('validation_groups') : null;
44
45        if (!$groups) {
46            return;
47        }
48
49        $constraints = $context->hasAttribute('validation_constraints') ? $context->getAttribute('validation_constraints') : null;
50
51        $list = $validator->validate($event->getObject(), $constraints, $groups);
52
53        if ($list->count() > 0) {
54            throw new ValidationFailedException($list);
55        }
56    }
57}
58