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

api-platform / core / 16531587208

25 Jul 2025 09:05PM UTC coverage: 0.0% (-22.1%) from 22.07%
16531587208

Pull #7225

github

web-flow
Merge 23f449a58 into 02a764950
Pull Request #7225: feat: json streamer

0 of 294 new or added lines in 31 files covered. (0.0%)

11514 existing lines in 375 files now uncovered.

0 of 51976 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\Util\ParameterParserTrait;
25
use ApiPlatform\State\Util\RequestParser;
26
use Psr\Container\ContainerInterface;
27

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

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

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

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

UNCOV
55
        $parameters = $operation->getParameters();
×
56

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

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

UNCOV
70
        $context = ['operation' => $operation] + $context;
×
71

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

UNCOV
80
            if (($default = $parameter->getSchema()['default'] ?? false) && ($value instanceof ParameterNotFound || !$value)) {
×
UNCOV
81
                $value = $default;
×
82
            }
83

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

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

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

UNCOV
96
        $request?->attributes->set('_api_operation', $operation);
×
UNCOV
97
        $context['operation'] = $operation;
×
98

UNCOV
99
        return $this->decorated?->provide($operation, $uriVariables, $context);
×
100
    }
101

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

UNCOV
116
            $values = $uriVariables;
×
117

UNCOV
118
            if (!\array_key_exists($key, $uriVariables)) {
×
UNCOV
119
                continue;
×
120
            }
121

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

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

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

UNCOV
138
        return $operation;
×
139
    }
140

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

UNCOV
150
        if (null === ($provider = $parameter->getProvider())) {
×
UNCOV
151
            return $operation;
×
152
        }
153

UNCOV
154
        if (\is_callable($provider)) {
×
UNCOV
155
            if (($op = $provider($parameter, $values, $context)) instanceof Operation) {
×
UNCOV
156
                $operation = $op;
×
157
            }
158

UNCOV
159
            return $operation;
×
160
        }
161

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

UNCOV
167
            $provider = $this->locator->get($provider);
×
168
        }
169

UNCOV
170
        if (($op = $provider->provide($parameter, $values, $context)) instanceof Operation) {
×
UNCOV
171
            $operation = $op;
×
172
        }
173

UNCOV
174
        return $operation;
×
175
    }
176
}
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