From 0b05a23625051342262ab47388161aabfcfa29b5 Mon Sep 17 00:00:00 2001 From: Guilhem Niot Date: Wed, 5 Jul 2017 15:41:53 +0200 Subject: [PATCH] Use request base url --- Controller/DocumentationController.php | 10 +++++++-- Controller/SwaggerUiController.php | 10 +++++++-- Describer/ApiPlatformDescriber.php | 31 ++++++++++++++++---------- Resources/config/api_platform.xml | 1 + Tests/Functional/SwaggerUiTest.php | 20 ++++++++++++----- 5 files changed, 51 insertions(+), 21 deletions(-) diff --git a/Controller/DocumentationController.php b/Controller/DocumentationController.php index 1c218e457..5129d0455 100644 --- a/Controller/DocumentationController.php +++ b/Controller/DocumentationController.php @@ -13,6 +13,7 @@ use Nelmio\ApiDocBundle\ApiDocGenerator; use Symfony\Component\HttpFoundation\JsonResponse; +use Symfony\Component\HttpFoundation\Request; final class DocumentationController { @@ -23,8 +24,13 @@ public function __construct(ApiDocGenerator $apiDocGenerator) $this->apiDocGenerator = $apiDocGenerator; } - public function __invoke() + public function __invoke(Request $request) { - return new JsonResponse($this->apiDocGenerator->generate()->toArray()); + $spec = $this->apiDocGenerator->generate()->toArray(); + if ('' !== $request->getBaseUrl()) { + $spec['basePath'] = $request->getBaseUrl(); + } + + return new JsonResponse($spec); } } diff --git a/Controller/SwaggerUiController.php b/Controller/SwaggerUiController.php index 44ed7a273..f0febea1f 100644 --- a/Controller/SwaggerUiController.php +++ b/Controller/SwaggerUiController.php @@ -12,6 +12,7 @@ namespace Nelmio\ApiDocBundle\Controller; use Nelmio\ApiDocBundle\ApiDocGenerator; +use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; final class SwaggerUiController @@ -25,10 +26,15 @@ public function __construct(ApiDocGenerator $apiDocGenerator, \Twig_Environment $this->twig = $twig; } - public function __invoke() + public function __invoke(Request $request) { + $spec = $this->apiDocGenerator->generate()->toArray(); + if ('' !== $request->getBaseUrl()) { + $spec['basePath'] = $request->getBaseUrl(); + } + return new Response( - $this->twig->render('@NelmioApiDoc/SwaggerUi/index.html.twig', ['swagger_data' => ['spec' => $this->apiDocGenerator->generate()->toArray()]]), + $this->twig->render('@NelmioApiDoc/SwaggerUi/index.html.twig', ['swagger_data' => ['spec' => $spec]]), Response::HTTP_OK, ['Content-Type' => 'text/html'] ); diff --git a/Describer/ApiPlatformDescriber.php b/Describer/ApiPlatformDescriber.php index c243997a6..04a486377 100644 --- a/Describer/ApiPlatformDescriber.php +++ b/Describer/ApiPlatformDescriber.php @@ -13,25 +13,32 @@ use ApiPlatform\Core\Documentation\Documentation; use ApiPlatform\Core\Swagger\Serializer\DocumentationNormalizer; +use Symfony\Component\Routing\Generator\UrlGeneratorInterface; +use Symfony\Component\Routing\RequestContext; final class ApiPlatformDescriber extends ExternalDocDescriber { - public function __construct(Documentation $documentation, DocumentationNormalizer $normalizer, bool $overwrite = false) + public function __construct(Documentation $documentation, DocumentationNormalizer $normalizer, UrlGeneratorInterface $urlGenerator) { - parent::__construct(function () use ($documentation, $normalizer) { + parent::__construct(function () use ($documentation, $normalizer, $urlGenerator) { + $baseContext = $urlGenerator->getContext(); + $urlGenerator->setContext(new RequestContext()); + try { + $basePath = $urlGenerator->generate('api_entrypoint'); + } finally { + $urlGenerator->setContext($baseContext); + } + $documentation = (array) $normalizer->normalize($documentation); - // Remove base path - if (isset($documentation['basePath'])) { - $paths = []; - foreach ($documentation['paths'] as $path => $value) { - $paths['/'.ltrim($documentation['basePath'].'/'.ltrim($path, '/'), '/')] = $value; - } - - unset($documentation['basePath']); - $documentation['paths'] = $paths; + unset($documentation['basePath']); + + foreach ($documentation['paths'] as $path => $value) { + $paths['/'.ltrim($basePath.'/'.ltrim($path, '/'), '/')] = $value; } + $documentation['paths'] = $paths; + return $documentation; - }, $overwrite); + }); } } diff --git a/Resources/config/api_platform.xml b/Resources/config/api_platform.xml index e52e2831c..0d0b05b94 100644 --- a/Resources/config/api_platform.xml +++ b/Resources/config/api_platform.xml @@ -7,6 +7,7 @@ + diff --git a/Tests/Functional/SwaggerUiTest.php b/Tests/Functional/SwaggerUiTest.php index b294c3388..c8761acd6 100644 --- a/Tests/Functional/SwaggerUiTest.php +++ b/Tests/Functional/SwaggerUiTest.php @@ -13,28 +13,38 @@ class SwaggerUiTest extends WebTestCase { + protected static function createClient(array $options = [], array $server = []) + { + return parent::createClient([], ['PHP_SELF' => '/app_dev.php/docs', 'SCRIPT_FILENAME' => '/var/www/app/web/app_dev.php']); + } + public function testSwaggerUi() { $client = self::createClient(); - $crawler = $client->request('GET', '/docs/'); + $crawler = $client->request('GET', '/app_dev.php/docs/'); $response = $client->getResponse(); $this->assertEquals(200, $response->getStatusCode()); $this->assertEquals('text/html; charset=UTF-8', $response->headers->get('Content-Type')); - $swaggerUiSpec = json_decode($crawler->filterXPath('//script[@id="swagger-data"]')->text(), true); - $this->assertEquals($this->getSwaggerDefinition()->toArray(), $swaggerUiSpec['spec']); + $expected = $this->getSwaggerDefinition()->toArray(); + $expected['basePath'] = '/app_dev.php'; + + $this->assertEquals($expected, json_decode($crawler->filterXPath('//script[@id="swagger-data"]')->text(), true)['spec']); } public function testJsonDocs() { $client = self::createClient(); - $crawler = $client->request('GET', '/docs.json'); + $crawler = $client->request('GET', '/app_dev.php/docs.json'); $response = $client->getResponse(); $this->assertEquals(200, $response->getStatusCode()); $this->assertEquals('application/json', $response->headers->get('Content-Type')); - $this->assertEquals($this->getSwaggerDefinition()->toArray(), json_decode($response->getContent(), true)); + $expected = $this->getSwaggerDefinition()->toArray(); + $expected['basePath'] = '/app_dev.php'; + + $this->assertEquals($expected, json_decode($response->getContent(), true)); } }