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

api-platform / core / 15133993414

20 May 2025 09:30AM UTC coverage: 26.313% (-1.2%) from 27.493%
15133993414

Pull #7161

github

web-flow
Merge e2c03d45f into 5459ba375
Pull Request #7161: fix(metadata): infer parameter string type from schema

0 of 2 new or added lines in 1 file covered. (0.0%)

11019 existing lines in 363 files now uncovered.

12898 of 49018 relevant lines covered (26.31%)

34.33 hits per line

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

93.62
/src/Metadata/Util/ContentNegotiationTrait.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\Metadata\Util;
15

16
use Negotiation\Negotiator;
17
use Symfony\Component\HttpFoundation\Request;
18
use Symfony\Component\HttpKernel\Exception\NotAcceptableHttpException;
19
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
20

21
/**
22
 * @internal
23
 */
24
trait ContentNegotiationTrait
25
{
26
    private Negotiator $negotiator;
27

28
    /**
29
     * Gets the format associated with the mime type.
30
     *
31
     * Adapted from {@see Request::getFormat}.
32
     *
33
     * @param array<string, string|string[]> $formats
34
     */
35
    private function getMimeTypeFormat(string $mimeType, array $formats): ?string
36
    {
UNCOV
37
        $canonicalMimeType = null;
567✔
UNCOV
38
        $pos = strpos($mimeType, ';');
567✔
UNCOV
39
        if (false !== $pos) {
567✔
40
            $canonicalMimeType = trim(substr($mimeType, 0, $pos));
×
41
        }
42

UNCOV
43
        foreach ($formats as $format => $mimeTypes) {
567✔
UNCOV
44
            if (\in_array($mimeType, $mimeTypes, true)) {
566✔
UNCOV
45
                return $format;
566✔
46
            }
UNCOV
47
            if (null !== $canonicalMimeType && \in_array($canonicalMimeType, $mimeTypes, true)) {
262✔
48
                return $format;
×
49
            }
50
        }
51

UNCOV
52
        return null;
4✔
53
    }
54

55
    /**
56
     * Flattened the list of MIME types.
57
     *
58
     * @param array<string, string|string[]> $formats
59
     *
60
     * @return array<string, string>
61
     */
62
    private function flattenMimeTypes(array $formats): array
63
    {
UNCOV
64
        $flattenedMimeTypes = [];
264✔
UNCOV
65
        foreach ($formats as $format => $mimeTypes) {
264✔
UNCOV
66
            foreach ($mimeTypes as $mimeType) {
264✔
UNCOV
67
                $flattenedMimeTypes[$mimeType] = $format;
264✔
68
            }
69
        }
70

UNCOV
71
        return $flattenedMimeTypes;
264✔
72
    }
73

74
    /**
75
     * @param array<string, string|string[]> $formats
76
     */
77
    private function getRequestFormat(Request $request, array $formats, bool $throw = true): string
78
    {
UNCOV
79
        $mimeTypes = [];
946✔
UNCOV
80
        $flattenedMimeTypes = [];
946✔
81

UNCOV
82
        if ($routeFormat = $request->attributes->get('_format') ?: null) {
946✔
UNCOV
83
            if (isset($formats[$routeFormat])) {
24✔
UNCOV
84
                $mimeTypes = Request::getMimeTypes($routeFormat);
22✔
UNCOV
85
                $flattenedMimeTypes = $this->flattenMimeTypes([$routeFormat => $mimeTypes]);
22✔
86
            } elseif ($throw) {
2✔
87
                throw new NotFoundHttpException(\sprintf('Format "%s" is not supported', $routeFormat));
2✔
88
            }
89
        }
90

UNCOV
91
        if (!$mimeTypes) {
946✔
UNCOV
92
            $flattenedMimeTypes = $this->flattenMimeTypes($formats);
924✔
UNCOV
93
            $mimeTypes = array_keys($flattenedMimeTypes);
924✔
94
        }
95

96
        // First, try to guess the format from the Accept header
97
        /** @var string|null $accept */
UNCOV
98
        $accept = $request->headers->get('Accept');
946✔
UNCOV
99
        if (null !== $accept) {
946✔
UNCOV
100
            if ($mediaType = $this->negotiator->getBest($accept, $mimeTypes)) {
472✔
UNCOV
101
                return $this->getMimeTypeFormat($mediaType->getType(), $formats);
454✔
102
            }
103

UNCOV
104
            if ($throw) {
31✔
105
                throw $this->getNotAcceptableHttpException($accept, $flattenedMimeTypes);
5✔
106
            }
107
        }
108

109
        // Then, use the Symfony request format if available and applicable
UNCOV
110
        $requestFormat = $request->getRequestFormat('') ?: null;
507✔
UNCOV
111
        if (null !== $requestFormat) {
507✔
112
            $mimeType = $request->getMimeType($requestFormat);
49✔
113

114
            if (isset($flattenedMimeTypes[$mimeType])) {
49✔
115
                return $requestFormat;
47✔
116
            }
117

118
            if ($throw) {
2✔
119
                throw $this->getNotAcceptableHttpException($mimeType, $flattenedMimeTypes);
×
120
            }
121
        }
122

123
        // Finally, if no Accept header nor Symfony request format is set, return the default format
UNCOV
124
        return array_key_first($formats);
491✔
125
    }
126

127
    /**
128
     * Retrieves an instance of NotAcceptableHttpException.
129
     */
130
    private function getNotAcceptableHttpException(string $accept, array $mimeTypes): NotAcceptableHttpException
131
    {
132
        return new NotAcceptableHttpException(\sprintf(
5✔
133
            'Requested format "%s" is not supported. Supported MIME types are "%s".',
5✔
134
            $accept,
5✔
135
            implode('", "', array_keys($mimeTypes))
5✔
136
        ));
5✔
137
    }
138

139
    /**
140
     * Adds the supported formats to the request.
141
     *
142
     * This is necessary for {@see Request::getMimeType} and {@see Request::getMimeTypes} to work.
143
     *
144
     * @param array<string, string|string[]> $formats
145
     */
146
    private function addRequestFormats(Request $request, array $formats): void
147
    {
UNCOV
148
        foreach ($formats as $format => $mimeTypes) {
15✔
UNCOV
149
            $request->setFormat($format, (array) $mimeTypes);
15✔
150
        }
151
    }
152
}
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