From e1c56ea001eb1a7f9d99ace4ff174faddaf2d348 Mon Sep 17 00:00:00 2001 From: soyuka Date: Mon, 5 Oct 2026 17:27:42 +0200 Subject: [PATCH] fix(openapi): don't suffix [] on bracketed array keys fixes #8634 --- src/OpenApi/Factory/OpenApiFactory.php | 2 +- .../Tests/Factory/OpenApiFactoryTest.php | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/OpenApi/Factory/OpenApiFactory.php b/src/OpenApi/Factory/OpenApiFactory.php index 5f28e7877c..5b554a2a0d 100644 --- a/src/OpenApi/Factory/OpenApiFactory.php +++ b/src/OpenApi/Factory/OpenApiFactory.php @@ -371,7 +371,7 @@ private function collectPaths(ApiResource $resource, ResourceMetadataCollection $parameterDescription = $p->getDescription() ?? "$resourceShortName $key"; $parameterRequired = $p->getRequired() ?? false; $linkParameter = $p->getOpenApi(); - $canSplitToArray = null === $linkParameter && 'query' === $in && 'array' === ($parameterSchema['type'] ?? null); + $canSplitToArray = null === $linkParameter && 'query' === $in && 'array' === ($parameterSchema['type'] ?? null) && !str_ends_with($key, '[]'); $defaultParameters = []; if (!$canSplitToArray || true !== $castToArray) { diff --git a/src/OpenApi/Tests/Factory/OpenApiFactoryTest.php b/src/OpenApi/Tests/Factory/OpenApiFactoryTest.php index 1cb077cf8e..bd6a43dcc5 100644 --- a/src/OpenApi/Tests/Factory/OpenApiFactoryTest.php +++ b/src/OpenApi/Tests/Factory/OpenApiFactoryTest.php @@ -1751,6 +1751,25 @@ public function testFilterlessArrayQueryParameterHonoursCastToArray(): void $this->assertCount(1, array_filter($linkParameterGuardParameters, static fn (Parameter $parameter): bool => 'foobar[]' === $parameter->getName())); } + public function testFilterlessArrayQueryParameterWithBracketKeyIsNotSuffixedTwice(): void + { + $arraySchema = ['type' => 'array', 'items' => ['type' => 'string']]; + + foreach ([null, true, false] as $castToArray) { + $parameters = $this->getGeneratedQueryParameters( + ['status[]' => new QueryParameter(key: 'status[]', schema: $arraySchema, castToArray: $castToArray)], + null, + ); + + $statusParameters = array_values(array_filter($parameters, static fn (Parameter $parameter): bool => str_starts_with($parameter->getName(), 'status'))); + + $this->assertCount(1, $statusParameters, \sprintf('castToArray: %s', var_export($castToArray, true))); + $this->assertSame('status[]', $statusParameters[0]->getName()); + $this->assertSame($arraySchema, $statusParameters[0]->getSchema()); + $this->assertCount(0, array_filter($parameters, static fn (Parameter $parameter): bool => 'status[][]' === $parameter->getName())); + } + } + public function testDeleteOperationWithDeserializeDocumentsRequestBody(): void { $resourceNameCollectionFactory = $this->createMock(ResourceNameCollectionFactoryInterface::class);