From 32f55b24a2d1d665dc001a0f8b67865340829f58 Mon Sep 17 00:00:00 2001 From: soyuka Date: Thu, 17 Oct 2024 09:24:52 +0200 Subject: [PATCH] fix: multiple parameter provider #6673 --- src/State/Provider/ParameterProvider.php | 2 +- .../Issue6673/MutlipleParameterProvider.php | 62 +++++++++++++++++++ .../Parameters/ParameterProviderTest.php | 25 ++++++++ 3 files changed, 88 insertions(+), 1 deletion(-) create mode 100644 tests/Fixtures/TestBundle/ApiResource/Issue6673/MutlipleParameterProvider.php create mode 100644 tests/Functional/Parameters/ParameterProviderTest.php diff --git a/src/State/Provider/ParameterProvider.php b/src/State/Provider/ParameterProvider.php index 7ffa0c1b923..548d364b7e7 100644 --- a/src/State/Provider/ParameterProvider.php +++ b/src/State/Provider/ParameterProvider.php @@ -49,13 +49,13 @@ public function provide(Operation $operation, array $uriVariables = [], array $c $request->attributes->set('_api_header_parameters', $request->headers->all()); } - $context = ['operation' => $operation] + $context; $parameters = $operation->getParameters(); foreach ($parameters ?? [] as $parameter) { $extraProperties = $parameter->getExtraProperties(); unset($extraProperties['_api_values']); $parameters->add($parameter->getKey(), $parameter = $parameter->withExtraProperties($extraProperties)); + $context = ['operation' => $operation] + $context; $values = $this->getParameterValues($parameter, $request, $context); $value = $this->extractParameterValues($parameter, $values); diff --git a/tests/Fixtures/TestBundle/ApiResource/Issue6673/MutlipleParameterProvider.php b/tests/Fixtures/TestBundle/ApiResource/Issue6673/MutlipleParameterProvider.php new file mode 100644 index 00000000000..1b694695470 --- /dev/null +++ b/tests/Fixtures/TestBundle/ApiResource/Issue6673/MutlipleParameterProvider.php @@ -0,0 +1,62 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace ApiPlatform\Tests\Fixtures\TestBundle\ApiResource\Issue6673; + +use ApiPlatform\Metadata\GetCollection; +use ApiPlatform\Metadata\Operation; +use ApiPlatform\Metadata\Parameter; +use ApiPlatform\Metadata\QueryParameter; + +#[GetCollection( + uriTemplate: 'issue6673', + outputFormats: ['json'], + parameters: [ + 'a' => new QueryParameter( + provider: [self::class, 'parameterOneProvider'], + ), + 'b' => new QueryParameter( + provider: [self::class, 'parameterTwoProvider'], + ), + ], + provider: [self::class, 'provide'] +)] +final readonly class MutlipleParameterProvider +{ + public function __construct(public string $id) + { + } + + public static function provide(Operation $operation): ?array + { + return $operation->getNormalizationContext(); + } + + public static function parameterOneProvider(Parameter $parameter, array $parameters = [], array $context = []): ?Operation + { + $operation = $context['operation']; + $context = $operation->getNormalizationContext() ?? []; + $context['a'] = $parameter->getValue(); + + return $operation->withNormalizationContext($context); + } + + public static function parameterTwoProvider(Parameter $parameter, array $parameters = [], array $context = []): ?Operation + { + $operation = $context['operation']; + $context = $operation->getNormalizationContext() ?? []; + $context['b'] = $parameter->getValue(); + + return $operation->withNormalizationContext($context); + } +} diff --git a/tests/Functional/Parameters/ParameterProviderTest.php b/tests/Functional/Parameters/ParameterProviderTest.php new file mode 100644 index 00000000000..5cb2a1f9431 --- /dev/null +++ b/tests/Functional/Parameters/ParameterProviderTest.php @@ -0,0 +1,25 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace ApiPlatform\Tests\Functional\Parameters; + +use ApiPlatform\Symfony\Bundle\Test\ApiTestCase; + +final class ParameterProviderTest extends ApiTestCase +{ + public function testMultipleParameterProviderShouldChangeTheOperation(): void + { + $response = self::createClient()->request('GET', 'issue6673?a=1&b=2', ['headers' => ['accept' => 'application/json']]); + $this->assertArraySubset(['a' => '1', 'b' => '2'], $response->toArray(false)); + } +}