• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

api-platform / core / 6173831445

13 Sep 2023 02:23PM UTC coverage: 36.999% (-0.1%) from 37.094%
6173831445

push

github

soyuka
chore: subtree component descriptions

10101 of 27301 relevant lines covered (37.0%)

19.98 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/src/State/Provider/DeserializeProvider.php
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\State\Provider;
15

16
use ApiPlatform\Metadata\HttpOperation;
17
use ApiPlatform\Metadata\Operation;
18
use ApiPlatform\Serializer\SerializerContextBuilderInterface;
19
use ApiPlatform\State\ProviderInterface;
20
use ApiPlatform\Symfony\Validator\Exception\ValidationException;
21
use Symfony\Component\HttpKernel\Exception\UnsupportedMediaTypeHttpException;
22
use Symfony\Component\Serializer\Exception\NotNormalizableValueException;
23
use Symfony\Component\Serializer\Exception\PartialDenormalizationException;
24
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
25
use Symfony\Component\Serializer\SerializerInterface;
26
use Symfony\Component\Validator\Constraints\Type;
27
use Symfony\Component\Validator\ConstraintViolation;
28
use Symfony\Component\Validator\ConstraintViolationList;
29
use Symfony\Contracts\Translation\LocaleAwareInterface;
30
use Symfony\Contracts\Translation\TranslatorInterface;
31
use Symfony\Contracts\Translation\TranslatorTrait;
32

33
final class DeserializeProvider implements ProviderInterface
34
{
35
    public function __construct(private readonly ProviderInterface $decorated, private readonly SerializerInterface $serializer, private readonly SerializerContextBuilderInterface $serializerContextBuilder, private ?TranslatorInterface $translator = null)
36
    {
37
        if (null === $this->translator) {
×
38
            $this->translator = new class() implements TranslatorInterface, LocaleAwareInterface {
×
39
                use TranslatorTrait;
40
            };
×
41
            $this->translator->setLocale('en');
×
42
        }
43
    }
44

45
    public function provide(Operation $operation, array $uriVariables = [], array $context = []): object|array|null
46
    {
47
        $data = $this->decorated->provide($operation, $uriVariables, $context);
×
48

49
        // We need request content
50
        if (!$operation instanceof HttpOperation || !($request = $context['request'] ?? null)) {
×
51
            return $data;
×
52
        }
53

54
        if (
55
            !($operation->canDeserialize() ?? true)
×
56
            || !\in_array($method = $operation->getMethod(), ['POST', 'PUT', 'PATCH'], true)
×
57
        ) {
58
            return $data;
×
59
        }
60

61
        $contentType = $request->headers->get('CONTENT_TYPE');
×
62
        if (null === $contentType) {
×
63
            throw new UnsupportedMediaTypeHttpException('The "Content-Type" header must exist.');
×
64
        }
65

66
        $serializerContext = $this->serializerContextBuilder->createFromRequest($request, false, [
×
67
            'resource_class' => $operation->getClass(),
×
68
            'operation' => $operation,
×
69
        ]);
×
70

71
        $serializerContext['uri_variables'] = $uriVariables;
×
72

73
        if (!$format = $request->attributes->get('input_format') ?? null) {
×
74
            throw new UnsupportedMediaTypeHttpException('Format not supported.');
×
75
        }
76

77
        if (
78
            null !== $data
×
79
            && (
80
                'POST' === $method
×
81
                || 'PATCH' === $method
×
82
                || ('PUT' === $method && !($operation->getExtraProperties()['standard_put'] ?? false))
×
83
            )
84
        ) {
85
            $serializerContext[AbstractNormalizer::OBJECT_TO_POPULATE] = $data;
×
86
        }
87

88
        try {
89
            return $this->serializer->deserialize((string) $request->getContent(), $operation->getClass(), $format, $serializerContext);
×
90
        } catch (PartialDenormalizationException $e) {
×
91
            $violations = new ConstraintViolationList();
×
92
            foreach ($e->getErrors() as $exception) {
×
93
                if (!$exception instanceof NotNormalizableValueException) {
×
94
                    continue;
×
95
                }
96
                $message = (new Type($exception->getExpectedTypes() ?? []))->message;
×
97
                $parameters = [];
×
98
                if ($exception->canUseMessageForUser()) {
×
99
                    $parameters['hint'] = $exception->getMessage();
×
100
                }
101
                $violations->add(new ConstraintViolation($this->translator->trans($message, ['{{ type }}' => implode('|', $exception->getExpectedTypes() ?? [])], 'validators'), $message, $parameters, null, $exception->getPath(), null, null, (string) $exception->getCode()));
×
102
            }
103
            if (0 !== \count($violations)) {
×
104
                throw new ValidationException($violations);
×
105
            }
106
        }
107

108
        return $data;
×
109
    }
110
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc