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

api-platform / core / 17061771168

19 Aug 2025 06:44AM UTC coverage: 0.0%. First build
17061771168

Pull #7299

github

web-flow
Merge 560c166c3 into 6491bfc7a
Pull Request #7299: feat(symfony): stop watch system provider/processor

0 of 36 new or added lines in 10 files covered. (0.0%)

0 of 51906 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
 * @experimental
36
 */
37
final class ParameterProvider implements ProviderInterface, StopwatchAwareInterface
38
{
39
    use ParameterParserTrait;
40
    use StopwatchAwareTrait;
41

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

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

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

59
        $parameters = $operation->getParameters();
×
60

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

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

74
        $context = ['operation' => $operation] + $context;
×
75

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

84
            if (($default = $parameter->getSchema()['default'] ?? false) && ($value instanceof ParameterNotFound || !$value)) {
×
85
                $value = $default;
×
86
            }
87

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

92
        if ($parameters) {
×
93
            $operation = $operation->withParameters($parameters);
×
94
        }
95

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

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

104
        return $this->decorated?->provide($operation, $uriVariables, $context);
×
105
    }
106

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

121
            $values = $uriVariables;
×
122

123
            if (!\array_key_exists($key, $uriVariables)) {
×
124
                continue;
×
125
            }
126

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

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

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

143
        return $operation;
×
144
    }
145

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

155
        if (null === ($provider = $parameter->getProvider())) {
×
156
            return $operation;
×
157
        }
158

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

164
            return $operation;
×
165
        }
166

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

172
            $provider = $this->locator->get($provider);
×
173
        }
174

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

179
        return $operation;
×
180
    }
181
}
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