diff --git a/ApiDocGenerator.php b/ApiDocGenerator.php
index ac93116..a82140d 100644
--- a/ApiDocGenerator.php
+++ b/ApiDocGenerator.php
@@ -12,7 +12,7 @@
namespace EXSyst\Bundle\ApiDocBundle;
use EXSyst\Bundle\ApiDocBundle\Describer\DescriberInterface;
-use EXSyst\Swagger\Swagger;
+use EXSyst\Component\Swagger\Swagger;
class ApiDocGenerator
{
diff --git a/Describer/DefaultDescriber.php b/Describer/DefaultDescriber.php
new file mode 100644
index 0000000..88a864e
--- /dev/null
+++ b/Describer/DefaultDescriber.php
@@ -0,0 +1,64 @@
+
+ */
+class DefaultDescriber implements DescriberInterface
+{
+ public function describe(Swagger $api)
+ {
+ // Info
+ $info = $api->getInfo();
+ if (null === $info->getTitle()) {
+ $info->setTitle('');
+ }
+ if (null === $info->getVersion()) {
+ $info->setVersion('0.0.0');
+ }
+
+ // Paths
+ $paths = $api->getPaths();
+ foreach ($paths as $uri => $path) {
+ // Path Parameters
+ preg_match_all('/\{(.+)\}/SU', $uri, $matches);
+ $pathParameters = $matches[1];
+
+ foreach ($path->getMethods() as $method) {
+ $operation = $path->getOperation($method);
+ $parameters = $operation->getParameters();
+
+ // Default Path Parameters
+ foreach ($pathParameters as $pathParameter) {
+ if ($parameters->has($pathParameter, 'path')) {
+ continue;
+ }
+
+ $parameters->get($pathParameter, 'path')
+ ->setRequired(true)
+ ->setType('string');
+ }
+
+ // Default Response
+ if (0 === iterator_count($operation->getResponses())) {
+ $defaultResponse = $operation->getResponses()->get('default');
+ $defaultResponse->setDescription('');
+ }
+ }
+ }
+ }
+}
diff --git a/Describer/DescriberInterface.php b/Describer/DescriberInterface.php
index a66fdaa..81f803a 100644
--- a/Describer/DescriberInterface.php
+++ b/Describer/DescriberInterface.php
@@ -11,7 +11,7 @@
namespace EXSyst\Bundle\ApiDocBundle\Describer;
-use EXSyst\Swagger\Swagger;
+use EXSyst\Component\Swagger\Swagger;
interface DescriberInterface
{
diff --git a/Describer/ExternalDocDescriber.php b/Describer/ExternalDocDescriber.php
index a7d83dd..d86d139 100644
--- a/Describer/ExternalDocDescriber.php
+++ b/Describer/ExternalDocDescriber.php
@@ -11,7 +11,7 @@
namespace EXSyst\Bundle\ApiDocBundle\Describer;
-use EXSyst\Swagger\Swagger;
+use EXSyst\Component\Swagger\Swagger;
class ExternalDocDescriber implements DescriberInterface
{
diff --git a/Describer/RouteDescriber.php b/Describer/RouteDescriber.php
index 3cd4a9c..f8e884e 100644
--- a/Describer/RouteDescriber.php
+++ b/Describer/RouteDescriber.php
@@ -13,7 +13,7 @@ namespace EXSyst\Bundle\ApiDocBundle\Describer;
use Doctrine\Common\Util\ClassUtils;
use EXSyst\Bundle\ApiDocBundle\RouteDescriber\RouteDescriberInterface;
-use EXSyst\Swagger\Swagger;
+use EXSyst\Component\Swagger\Swagger;
use Symfony\Bundle\FrameworkBundle\Controller\ControllerNameParser;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\Routing\Route;
diff --git a/Describer/SwaggerPhpDescriber.php b/Describer/SwaggerPhpDescriber.php
index 4d89666..8354a80 100644
--- a/Describer/SwaggerPhpDescriber.php
+++ b/Describer/SwaggerPhpDescriber.php
@@ -16,9 +16,22 @@ class SwaggerPhpDescriber extends ExternalDocDescriber
public function __construct(string $projectPath, bool $overwrite = false)
{
parent::__construct(function () use ($projectPath) {
- $annotation = \Swagger\scan($projectPath);
+ // Catch notices as the documentation can be completed by other describers
+ $prevHandler = set_error_handler(function ($type, $message, $file, $line, $context) use (&$prevHandler) {
+ if (E_USER_NOTICE === $type || E_USER_WARNING === $type) {
+ return;
+ }
- return json_decode(json_encode($annotation));
+ return null !== $prevHandler && call_user_func($prevHandler, $type, $message, $file, $line, $context);
+ });
+
+ try {
+ $annotation = \Swagger\scan($projectPath);
+
+ return json_decode(json_encode($annotation));
+ } finally {
+ restore_error_handler();
+ }
}, $overwrite);
}
}
diff --git a/Resources/config/services.xml b/Resources/config/services.xml
index ebdb4ba..26f39f9 100644
--- a/Resources/config/services.xml
+++ b/Resources/config/services.xml
@@ -24,6 +24,10 @@
+
+
+
+
diff --git a/RouteDescriber/NelmioAnnotationDescriber.php b/RouteDescriber/NelmioAnnotationDescriber.php
index e81bce6..2bc577c 100644
--- a/RouteDescriber/NelmioAnnotationDescriber.php
+++ b/RouteDescriber/NelmioAnnotationDescriber.php
@@ -12,8 +12,8 @@
namespace EXSyst\Bundle\ApiDocBundle\RouteDescriber;
use Doctrine\Common\Annotations\Reader;
-use EXSyst\Swagger\Parameter;
-use EXSyst\Swagger\Swagger;
+use EXSyst\Component\Swagger\Parameter;
+use EXSyst\Component\Swagger\Swagger;
use Nelmio\ApiDocBundle\Annotation\ApiDoc;
use Symfony\Component\Routing\Route;
diff --git a/RouteDescriber/PhpDocDescriber.php b/RouteDescriber/PhpDocDescriber.php
index 9fe8165..7c73b53 100644
--- a/RouteDescriber/PhpDocDescriber.php
+++ b/RouteDescriber/PhpDocDescriber.php
@@ -11,7 +11,7 @@
namespace EXSyst\Bundle\ApiDocBundle\RouteDescriber;
-use EXSyst\Swagger\Swagger;
+use EXSyst\Component\Swagger\Swagger;
use phpDocumentor\Reflection\DocBlockFactory;
use phpDocumentor\Reflection\DocBlockFactoryInterface;
use Symfony\Component\Routing\Route;
@@ -48,10 +48,14 @@ class PhpDocDescriber implements RouteDescriberInterface
if (null !== $docBlock) {
$operation->setSummary($docBlock->getSummary());
$operation->setDescription((string) $docBlock->getDescription());
- $operation->setDeprecated($operation->getDeprecated() || $docBlock->hasTag('deprecated'));
+ if ($docBlock->hasTag('deprecated')) {
+ $operation->setDeprecated(true);
+ }
}
if (null !== $classDocBlock) {
- $operation->setDeprecated($operation->getDeprecated() || $classDocBlock->hasTag('deprecated'));
+ if ($classDocBlock->hasTag('deprecated')) {
+ $operation->setDeprecated(true);
+ }
}
}
}
diff --git a/RouteDescriber/RouteDescriberInterface.php b/RouteDescriber/RouteDescriberInterface.php
index dbdcfce..38fa81e 100644
--- a/RouteDescriber/RouteDescriberInterface.php
+++ b/RouteDescriber/RouteDescriberInterface.php
@@ -11,7 +11,7 @@
namespace EXSyst\Bundle\ApiDocBundle\RouteDescriber;
-use EXSyst\Swagger\Swagger;
+use EXSyst\Component\Swagger\Swagger;
use Symfony\Component\Routing\Route;
interface RouteDescriberInterface
diff --git a/RouteDescriber/RouteDescriberTrait.php b/RouteDescriber/RouteDescriberTrait.php
index 258517a..2e01844 100644
--- a/RouteDescriber/RouteDescriberTrait.php
+++ b/RouteDescriber/RouteDescriberTrait.php
@@ -11,8 +11,8 @@
namespace EXSyst\Bundle\ApiDocBundle\RouteDescriber;
-use EXSyst\Swagger\Operation;
-use EXSyst\Swagger\Swagger;
+use EXSyst\Component\Swagger\Operation;
+use EXSyst\Component\Swagger\Swagger;
use Symfony\Component\Routing\Route;
/**
@@ -27,7 +27,7 @@ trait RouteDescriberTrait
*/
private function getOperations(Swagger $api, Route $route)
{
- $path = $api->getPaths()->get($route->getPath());
+ $path = $api->getPaths()->get($this->normalizePath($route->getPath()));
$methods = $route->getMethods() ?: Swagger::$METHODS;
foreach ($methods as $method) {
$method = strtolower($method);
@@ -40,4 +40,13 @@ trait RouteDescriberTrait
return $operations;
}
+
+ private function normalizePath(string $path)
+ {
+ if (substr($path, -10) === '.{_format}') {
+ $path = substr($path, 0, -10);
+ }
+
+ return $path;
+ }
}
diff --git a/RouteDescriber/RouteMetadataDescriber.php b/RouteDescriber/RouteMetadataDescriber.php
index 6228693..a32685b 100644
--- a/RouteDescriber/RouteMetadataDescriber.php
+++ b/RouteDescriber/RouteMetadataDescriber.php
@@ -11,7 +11,7 @@
namespace EXSyst\Bundle\ApiDocBundle\RouteDescriber;
-use EXSyst\Swagger\Swagger;
+use EXSyst\Component\Swagger\Swagger;
use Symfony\Component\Routing\Route;
class RouteMetadataDescriber implements RouteDescriberInterface
diff --git a/Tests/Describer/AbstractDescriberTest.php b/Tests/Describer/AbstractDescriberTest.php
new file mode 100644
index 0000000..861e973
--- /dev/null
+++ b/Tests/Describer/AbstractDescriberTest.php
@@ -0,0 +1,27 @@
+describer->describe($api);
+
+ return $api;
+ }
+}
diff --git a/Tests/Describer/SwaggerPhpDescriberTest.php b/Tests/Describer/SwaggerPhpDescriberTest.php
new file mode 100644
index 0000000..7bff009
--- /dev/null
+++ b/Tests/Describer/SwaggerPhpDescriberTest.php
@@ -0,0 +1,32 @@
+getSwaggerDoc();
+ $info = $api->getInfo();
+
+ $this->assertEquals('My Awesome App', $info->getTitle());
+ $this->assertEquals('1.3', $info->getVersion());
+ }
+
+ protected function setUp()
+ {
+ $this->describer = new SwaggerPhpDescriber(__DIR__.'/../Fixtures');
+ }
+}
diff --git a/Tests/Functional/Fixtures/SwaggerPhp/Info.php b/Tests/Fixtures/SwaggerPhp/Info.php
similarity index 100%
rename from Tests/Functional/Fixtures/SwaggerPhp/Info.php
rename to Tests/Fixtures/SwaggerPhp/Info.php
diff --git a/Tests/Functional/Controller/ApiController.php b/Tests/Functional/Controller/ApiController.php
index 382149f..8fd84d8 100644
--- a/Tests/Functional/Controller/ApiController.php
+++ b/Tests/Functional/Controller/ApiController.php
@@ -24,7 +24,7 @@ class ApiController
}
/**
- * @Route("/nelmio", methods={"POST"})
+ * @Route("/nelmio/{foo}", methods={"POST"})
* @ApiDoc(
* description="This action is described."
* )
diff --git a/Tests/Functional/FunctionalTest.php b/Tests/Functional/FunctionalTest.php
index 7da4091..203707f 100644
--- a/Tests/Functional/FunctionalTest.php
+++ b/Tests/Functional/FunctionalTest.php
@@ -22,7 +22,7 @@ class FunctionalTest extends WebTestCase
$this->assertEquals(['https'], $operation->getSchemes());
$this->assertEmpty($operation->getSummary());
$this->assertEmpty($operation->getDescription());
- $this->assertFalse($operation->getDeprecated());
+ $this->assertNull($operation->getDeprecated());
$parameters = $operation->getParameters();
$this->assertTrue($parameters->has('user', 'path'));
@@ -35,10 +35,14 @@ class FunctionalTest extends WebTestCase
public function testNelmioAction()
{
- $operation = $this->getOperation('/nelmio', 'post');
+ $operation = $this->getOperation('/nelmio/{foo}', 'post');
$this->assertEquals('This action is described.', $operation->getDescription());
$this->assertFalse($operation->getDeprecated());
+
+ $foo = $operation->getParameters()->get('foo', 'path');
+ $this->assertTrue($foo->getRequired());
+ $this->assertEquals('string', $foo->getType());
}
public function testDeprecatedAction()
@@ -50,13 +54,12 @@ class FunctionalTest extends WebTestCase
$this->assertTrue($operation->getDeprecated());
}
- public function testSwaggerPhpInfo()
+ public function testApiPlatform()
{
- $api = $this->getSwaggerDefinition();
- $info = $api->getInfo();
-
- $this->assertEquals('My Awesome App', $info->getTitle());
- $this->assertEquals('1.3', $info->getVersion());
+ $operation = $this->getOperation('/api/dummies', 'get');
+ $operation = $this->getOperation('/api/foo', 'get');
+ $operation = $this->getOperation('/api/foo', 'post');
+ $operation = $this->getOperation('/api/dummies/{id}', 'get');
}
private function getSwaggerDefinition()
diff --git a/composer.json b/composer.json
index f8664c1..d4a997d 100644
--- a/composer.json
+++ b/composer.json
@@ -11,7 +11,7 @@
"require": {
"php": "^7.0",
"symfony/framework-bundle": "^3.2",
- "exsyst/swagger": "~0.1"
+ "exsyst/swagger": "dev-master"
},
"require-dev": {
"symfony/validator": "^3.2",
@@ -24,7 +24,7 @@
"phpdocumentor/reflection-docblock": "^3.1",
"phpunit/phpunit": "^5.4",
"zircote/swagger-php": "^2.0",
- "api-platform/core": "^2.0"
+ "api-platform/core": "dev-master"
},
"suggest": {
"nelmio/api-doc-bundle": "For using the ApiDoc annotation.",