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

api-platform / core / 18118486316

30 Sep 2025 04:11AM UTC coverage: 0.0% (-22.0%) from 21.956%
18118486316

Pull #7397

github

web-flow
Merge e92aeff57 into 55fd65795
Pull Request #7397: fix(jsonschema/jsonld): make `@id` and `@type` properties required only in the JSON-LD schema for output

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

12143 existing lines in 402 files now uncovered.

0 of 53916 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/ParameterProvider.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\Metadata\Parameter;
19
use ApiPlatform\State\Exception\ParameterNotSupportedException;
20
use ApiPlatform\State\Exception\ProviderNotFoundException;
21
use ApiPlatform\State\ParameterNotFound;
22
use ApiPlatform\State\ParameterProvider\ReadLinkParameterProvider;
23
use ApiPlatform\State\ProviderInterface;
24
use ApiPlatform\State\StopwatchAwareInterface;
25
use ApiPlatform\State\StopwatchAwareTrait;
26
use ApiPlatform\State\Util\ParameterParserTrait;
27
use ApiPlatform\State\Util\RequestParser;
28
use Psr\Container\ContainerInterface;
29

30
/**
31
 * Loops over parameters to:
32
 *   - compute its values set as extra properties from the Parameter object (`_api_values`)
33
 *   - call the Parameter::provider if any and updates the Operation
34
 */
35
final class ParameterProvider implements ProviderInterface, StopwatchAwareInterface
36
{
37
    use ParameterParserTrait;
38
    use StopwatchAwareTrait;
39

40
    public function __construct(private readonly ?ProviderInterface $decorated = null, private readonly ?ContainerInterface $locator = null)
41
    {
UNCOV
42
    }
×
43

44
    public function provide(Operation $operation, array $uriVariables = [], array $context = []): object|array|null
45
    {
UNCOV
46
        $this->stopwatch?->start('api_platform.provider.parameter');
×
UNCOV
47
        $request = $context['request'] ?? null;
×
UNCOV
48
        if ($request && null === $request->attributes->get('_api_query_parameters')) {
×
UNCOV
49
            $queryString = RequestParser::getQueryString($request);
×
UNCOV
50
            $request->attributes->set('_api_query_parameters', $queryString ? RequestParser::parseRequestParams($queryString) : []);
×
51
        }
52

UNCOV
53
        if ($request && null === $request->attributes->get('_api_header_parameters')) {
×
UNCOV
54
            $request->attributes->set('_api_header_parameters', $request->headers->all());
×
55
        }
56

UNCOV
57
        $parameters = $operation->getParameters();
×
58

UNCOV
59
        if ($operation instanceof HttpOperation && true === $operation->getStrictQueryParameterValidation()) {
×
UNCOV
60
            $keys = [];
×
UNCOV
61
            foreach ($parameters as $parameter) {
×
UNCOV
62
                $keys[] = $parameter->getKey();
×
63
            }
64

UNCOV
65
            foreach (array_keys($request->attributes->get('_api_query_parameters')) as $key) {
×
UNCOV
66
                if (!\in_array($key, $keys, true)) {
×
UNCOV
67
                    throw new ParameterNotSupportedException($key);
×
68
                }
69
            }
70
        }
71

UNCOV
72
        $context = ['operation' => $operation] + $context;
×
73

UNCOV
74
        foreach ($parameters ?? [] as $parameter) {
×
UNCOV
75
            $values = $this->getParameterValues($parameter, $request, $context);
×
UNCOV
76
            $value = $this->extractParameterValues($parameter, $values);
×
77
            // we force API Platform's value extraction, use _api_query_parameters or _api_header_parameters if you need to set a value
UNCOV
78
            if (isset($parameter->getExtraProperties()['_api_values'])) {
×
UNCOV
79
                unset($parameter->getExtraProperties()['_api_values']);
×
80
            }
81

UNCOV
82
            if (null !== ($default = $parameter->getSchema()['default'] ?? null) && $value instanceof ParameterNotFound) {
×
UNCOV
83
                $value = $default;
×
84
            }
85

UNCOV
86
            $parameter->setValue($value);
×
UNCOV
87
            $context['operation'] = $operation = $this->callParameterProvider($operation, $parameter, $values, $context);
×
88
        }
89

UNCOV
90
        if ($parameters) {
×
UNCOV
91
            $operation = $operation->withParameters($parameters);
×
92
        }
93

UNCOV
94
        if ($operation instanceof HttpOperation) {
×
UNCOV
95
            $operation = $this->handlePathParameters($operation, $uriVariables, $context);
×
96
        }
97

UNCOV
98
        $request?->attributes->set('_api_operation', $operation);
×
UNCOV
99
        $context['operation'] = $operation;
×
UNCOV
100
        $this->stopwatch?->stop('api_platform.provider.parameter');
×
101

UNCOV
102
        return $this->decorated?->provide($operation, $uriVariables, $context);
×
103
    }
104

105
    /**
106
     * TODO: uriVariables could be a Parameters instance, it'd make things easier.
107
     *
108
     * @param array<string, mixed> $uriVariables
109
     * @param array<string, mixed> $context
110
     */
111
    private function handlePathParameters(HttpOperation $operation, array $uriVariables, array $context): HttpOperation
112
    {
UNCOV
113
        foreach ($operation->getUriVariables() ?? [] as $key => $uriVariable) {
×
UNCOV
114
            $uriVariable = $uriVariable->withKey($key);
×
UNCOV
115
            if ($uriVariable->getSecurity() && !$uriVariable->getProvider()) {
×
UNCOV
116
                $uriVariable = $uriVariable->withProvider(ReadLinkParameterProvider::class);
×
117
            }
118

UNCOV
119
            $values = $uriVariables;
×
120

UNCOV
121
            if (!\array_key_exists($key, $uriVariables)) {
×
UNCOV
122
                continue;
×
123
            }
124

UNCOV
125
            $value = $uriVariables[$key];
×
126
            // we force API Platform's value extraction, use _api_query_parameters or _api_header_parameters if you need to set a value
UNCOV
127
            if (isset($uriVariable->getExtraProperties()['_api_values'])) {
×
UNCOV
128
                unset($uriVariable->getExtraProperties()['_api_values']);
×
129
            }
130

UNCOV
131
            if (($default = $uriVariable->getSchema()['default'] ?? false) && ($value instanceof ParameterNotFound || !$value)) {
×
132
                $value = $default;
×
133
            }
134

UNCOV
135
            $uriVariable->setValue($value);
×
UNCOV
136
            if (($op = $this->callParameterProvider($operation, $uriVariable, $values, $context)) instanceof HttpOperation) {
×
UNCOV
137
                $context['operation'] = $operation = $op;
×
138
            }
139
        }
140

UNCOV
141
        return $operation;
×
142
    }
143

144
    /**
145
     * @param array<string,mixed> $context
146
     */
147
    private function callParameterProvider(Operation $operation, Parameter $parameter, mixed $values, array $context): Operation
148
    {
UNCOV
149
        if ($parameter->getValue() instanceof ParameterNotFound) {
×
UNCOV
150
            return $operation;
×
151
        }
152

UNCOV
153
        if (null === ($provider = $parameter->getProvider())) {
×
UNCOV
154
            return $operation;
×
155
        }
156

UNCOV
157
        if (\is_callable($provider)) {
×
UNCOV
158
            if (($op = $provider($parameter, $values, $context)) instanceof Operation) {
×
UNCOV
159
                $operation = $op;
×
160
            }
161

UNCOV
162
            return $operation;
×
163
        }
164

UNCOV
165
        if (\is_string($provider)) {
×
UNCOV
166
            if (!$this->locator->has($provider)) {
×
167
                throw new ProviderNotFoundException(\sprintf('Provider "%s" not found on operation "%s"', $provider, $operation->getName()));
×
168
            }
169

UNCOV
170
            $provider = $this->locator->get($provider);
×
171
        }
172

UNCOV
173
        if (($op = $provider->provide($parameter, $values, $context)) instanceof Operation) {
×
UNCOV
174
            $operation = $op;
×
175
        }
176

UNCOV
177
        return $operation;
×
178
    }
179
}
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