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

api-platform / core / 16705318661

03 Aug 2025 01:05PM UTC coverage: 0.0% (-21.9%) from 21.944%
16705318661

Pull #7317

github

web-flow
Merge 1ca8642ff into d06b1a0a0
Pull Request #7317: Fix/4372 skip null values in hal

0 of 14 new or added lines in 3 files covered. (0.0%)

11680 existing lines in 376 files now uncovered.

0 of 51817 relevant lines covered (0.0%)

0.0 hits per line

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

0.0
/src/State/Provider/ContentNegotiationProvider.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\Error as ErrorOperation;
17
use ApiPlatform\Metadata\HttpOperation;
18
use ApiPlatform\Metadata\Operation;
19
use ApiPlatform\Metadata\Util\ContentNegotiationTrait;
20
use ApiPlatform\State\ProviderInterface;
21
use Negotiation\Negotiator;
22
use Symfony\Component\HttpFoundation\Request;
23
use Symfony\Component\HttpKernel\Exception\UnsupportedMediaTypeHttpException;
24

25
final class ContentNegotiationProvider implements ProviderInterface
26
{
27
    use ContentNegotiationTrait;
28

29
    /**
30
     * @param array<string, string[]> $formats
31
     * @param array<string, string[]> $errorFormats
32
     */
33
    public function __construct(private readonly ?ProviderInterface $decorated = null, ?Negotiator $negotiator = null, private readonly array $formats = [], private readonly array $errorFormats = [])
34
    {
UNCOV
35
        $this->negotiator = $negotiator ?? new Negotiator();
×
36
    }
37

38
    public function provide(Operation $operation, array $uriVariables = [], array $context = []): object|array|null
39
    {
UNCOV
40
        if (!($request = $context['request'] ?? null) || !$operation instanceof HttpOperation) {
×
41
            return $this->decorated?->provide($operation, $uriVariables, $context);
×
42
        }
43

UNCOV
44
        $isErrorOperation = $operation instanceof ErrorOperation;
×
45

UNCOV
46
        $formats = $operation->getOutputFormats() ?? ($isErrorOperation ? $this->errorFormats : $this->formats);
×
UNCOV
47
        $this->addRequestFormats($request, $formats);
×
UNCOV
48
        $request->attributes->set('input_format', $this->getInputFormat($operation, $request));
×
UNCOV
49
        $request->setRequestFormat($this->getRequestFormat($request, $formats, !$isErrorOperation));
×
50

UNCOV
51
        return $this->decorated?->provide($operation, $uriVariables, $context);
×
52
    }
53

54
    /**
55
     * Adds the supported formats to the request.
56
     *
57
     * This is necessary for {@see Request::getMimeType} and {@see Request::getMimeTypes} to work.
58
     * Note that this replaces default mime types configured at {@see Request::initializeFormats}
59
     *
60
     * @param array<string, string|string[]> $formats
61
     */
62
    private function addRequestFormats(Request $request, array $formats): void
63
    {
UNCOV
64
        foreach ($formats as $format => $mimeTypes) {
×
UNCOV
65
            $request->setFormat($format, (array) $mimeTypes);
×
66
        }
67
    }
68

69
    /**
70
     * Flattened the list of MIME types.
71
     *
72
     * @param array<string, string|string[]> $formats
73
     *
74
     * @return array<string, string>
75
     */
76
    private function flattenMimeTypes(array $formats): array
77
    {
UNCOV
78
        $flattenedMimeTypes = [];
×
UNCOV
79
        foreach ($formats as $format => $mimeTypes) {
×
UNCOV
80
            foreach ($mimeTypes as $mimeType) {
×
UNCOV
81
                $flattenedMimeTypes[$mimeType] = $format;
×
82
            }
83
        }
84

UNCOV
85
        return $flattenedMimeTypes;
×
86
    }
87

88
    /**
89
     * Extracts the format from the Content-Type header and check that it is supported.
90
     *
91
     * @throws UnsupportedMediaTypeHttpException
92
     */
93
    private function getInputFormat(HttpOperation $operation, Request $request): ?string
94
    {
95
        if (
UNCOV
96
            false === ($input = $operation->getInput())
×
UNCOV
97
            || (\is_array($input) && null === $input['class'])
×
UNCOV
98
            || false === $operation->canDeserialize()
×
99
        ) {
UNCOV
100
            return null;
×
101
        }
102

UNCOV
103
        $contentType = $request->headers->get('CONTENT_TYPE');
×
UNCOV
104
        if (null === $contentType || '' === $contentType) {
×
UNCOV
105
            return null;
×
106
        }
107

UNCOV
108
        $formats = $operation->getInputFormats() ?? [];
×
UNCOV
109
        if ($format = $this->getMimeTypeFormat($contentType, $formats)) {
×
UNCOV
110
            return $format;
×
111
        }
112

UNCOV
113
        if (!$request->isMethodSafe() && 'DELETE' !== $request->getMethod()) {
×
UNCOV
114
            $supportedMimeTypes = [];
×
UNCOV
115
            foreach ($formats as $mimeTypes) {
×
UNCOV
116
                foreach ($mimeTypes as $mimeType) {
×
UNCOV
117
                    $supportedMimeTypes[] = $mimeType;
×
118
                }
119
            }
120

UNCOV
121
            throw new UnsupportedMediaTypeHttpException(\sprintf('The content-type "%s" is not supported. Supported MIME types are "%s".', $contentType, implode('", "', $supportedMimeTypes)));
×
122
        }
123

124
        return null;
×
125
    }
126
}
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