diff --git a/Describer/ParameterRefMergeDescriber.php b/Describer/ParameterRefMergeDescriber.php
deleted file mode 100644
index bebf8d3..0000000
--- a/Describer/ParameterRefMergeDescriber.php
+++ /dev/null
@@ -1,79 +0,0 @@
-getPaths() as $path) {
- /** @var Operation $operation */
- foreach ($path->getOperations() as $operation) {
- $this->checkOperation($api, $operation);
- }
- }
- }
-
- /**
- * This method removes parameters that also have a ref version as they will be duplicated otherwise.
- */
- private function checkOperation(Swagger $api, Operation $operation)
- {
- $parametersToRemove = [];
-
- /** @var Parameter[] $globalParams */
- $globalParams = $api->getParameters();
- /** @var Parameters|Parameter[] $currentParams */
- $currentParams = $operation->getParameters();
-
- foreach ($currentParams as $parameter) {
- $ref = $parameter->getRef();
-
- if (null === $ref) {
- // we only concern ourselves with '$ref' parameters
- continue;
- }
-
- $ref = \mb_substr($ref, 13); // trim the '#/parameters/' part of ref
- if (!isset($globalParams[$ref])) {
- // this really shouldn't happen, if it does there will be other failures elsewhere, so just ignore here
- continue;
- }
-
- $refParameter = $globalParams[$ref];
- // param ids are in form {name}/{in}
- $refParameterId = \sprintf('%s/%s', $refParameter->getName(), $refParameter->getIn());
- if ($currentParams->has($refParameterId)) {
- // if we got here it means a duplicate parameter is directly defined, schedule it for removal
- $parametersToRemove[] = $currentParams->get($refParameterId);
- }
- }
-
- foreach ($parametersToRemove as $parameterToRemove) {
- $currentParams->remove($parameterToRemove);
- }
- }
-}
diff --git a/Resources/config/fos_rest.xml b/Resources/config/fos_rest.xml
index ede8766..dbf8f2f 100644
--- a/Resources/config/fos_rest.xml
+++ b/Resources/config/fos_rest.xml
@@ -7,7 +7,7 @@
-
+
diff --git a/Resources/config/php_doc.xml b/Resources/config/php_doc.xml
index 47b2624..2adc859 100644
--- a/Resources/config/php_doc.xml
+++ b/Resources/config/php_doc.xml
@@ -5,7 +5,7 @@
-
+
diff --git a/Resources/config/services.xml b/Resources/config/services.xml
index c6ad025..978930e 100644
--- a/Resources/config/services.xml
+++ b/Resources/config/services.xml
@@ -32,10 +32,6 @@
-
-
-
-
diff --git a/RouteDescriber/RouteMetadataDescriber.php b/RouteDescriber/RouteMetadataDescriber.php
index ed67dd2..180237c 100644
--- a/RouteDescriber/RouteMetadataDescriber.php
+++ b/RouteDescriber/RouteMetadataDescriber.php
@@ -14,6 +14,9 @@ namespace Nelmio\ApiDocBundle\RouteDescriber;
use EXSyst\Component\Swagger\Swagger;
use Symfony\Component\Routing\Route;
+/**
+ * Should be last route describer executed to make sure all params are set.
+ */
final class RouteMetadataDescriber implements RouteDescriberInterface
{
use RouteDescriberTrait;
@@ -26,12 +29,39 @@ final class RouteMetadataDescriber implements RouteDescriberInterface
$requirements = $route->getRequirements();
$compiledRoute = $route->compile();
+ $globalParams = $api->getParameters();
+ $existingParams = [];
+ foreach ($operation->getParameters() as $id => $parameter) {
+ $ref = $parameter->getRef();
+ if (null === $ref) {
+ $existingParams[$id] = true;
+
+ // we only concern ourselves with '$ref' parameters
+ continue;
+ }
+
+ $ref = \mb_substr($ref, 13); // trim the '#/parameters/' part of ref
+ if (!isset($globalParams[$ref])) {
+ // this shouldn't happen, so just ignore here
+ continue;
+ }
+
+ $refParameter = $globalParams[$ref];
+
+ // param ids are in form {name}/{in}
+ $existingParams[\sprintf('%s/%s', $refParameter->getName(), $refParameter->getIn())] = true;
+ }
+
// Don't include host requirements
foreach ($compiledRoute->getPathVariables() as $pathVariable) {
if ('_format' === $pathVariable) {
continue;
}
+ if (isset($existingParams[$pathVariable.'/path'])) {
+ continue; // ignore this param, it is already defined
+ }
+
$parameter = $operation->getParameters()->get($pathVariable, 'path');
$parameter->setRequired(true);
@@ -39,7 +69,7 @@ final class RouteMetadataDescriber implements RouteDescriberInterface
$parameter->setType('string');
}
- if (isset($requirements[$pathVariable])) {
+ if (isset($requirements[$pathVariable]) && null === $parameter->getPattern()) {
$parameter->setPattern($requirements[$pathVariable]);
}
}
diff --git a/Tests/Describer/ParameterRefMergeDescriberTest.php b/Tests/Describer/ParameterRefMergeDescriberTest.php
deleted file mode 100644
index bd2b666..0000000
--- a/Tests/Describer/ParameterRefMergeDescriberTest.php
+++ /dev/null
@@ -1,64 +0,0 @@
- '2.0',
- 'info' => ['title' => 'Ref Test'],
- 'paths' => [
- '/api/{version}/product' => [
- 'get' => [
- 'parameters' => [
- [
- '$ref' => '#/parameters/versionParam',
- ],
- [
- 'name' => 'version',
- 'in' => 'path',
- 'required' => true,
- 'type' => 'string',
- 'pattern' => 'v\\d+',
- ],
- ],
- ],
- ],
- ],
- 'parameters' => [
- 'versionParam' => [
- 'name' => 'version',
- 'in' => 'path',
- 'required' => true,
- 'type' => 'string',
- ],
- ],
- ];
- $api = new Swagger($apiDef);
- $this->describer->describe($api);
-
- $describedData = $api->toArray();
- // only one parameter should remain as they were duplicates
- $this->assertCount(1, $describedData['paths']['/api/{version}/product']['get']['parameters']);
- }
-
- protected function setUp()
- {
- $this->describer = new ParameterRefMergeDescriber();
- }
-}
diff --git a/Tests/Functional/FunctionalTest.php b/Tests/Functional/FunctionalTest.php
index c3ea09a..1f2536a 100644
--- a/Tests/Functional/FunctionalTest.php
+++ b/Tests/Functional/FunctionalTest.php
@@ -433,4 +433,9 @@ class FunctionalTest extends WebTestCase
$this->assertSame('This is post', $postOperation->getDescription());
$this->assertSame('Worked well!', $postOperation->getResponses()->get(200)->getDescription());
}
+
+ public function testNoDuplicatedParameters()
+ {
+ $this->assertFalse($this->getOperation('/api/article/{id}', 'get')->getParameters()->has('id', 'path'));
+ }
}