diff --git a/CHANGELOG.md b/CHANGELOG.md index 6cb1f2175..eb60d4ba5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ # CHANGELOG +* Add filtering model properties by route area to `JMSModelDescriber` + ## 4.33.5 * Added new optional parameter `$context` to` PropertyDescriberInterface::supports()` @@ -25,7 +27,7 @@ ## 4.32.3 * Deprecated `Nelmio\ApiDocBundle\Annotation` namespace in favor of `Nelmio\ApiDocBundle\Attribute` namespace in preparation for 5.x. Consider upgrading to the new attribute syntax. -```diff +```diff - use Nelmio\ApiDocBundle\Annotation\Areas; - use Nelmio\ApiDocBundle\Annotation\Model; - use Nelmio\ApiDocBundle\Annotation\Operation; @@ -84,7 +86,7 @@ nelmio_api_doc: ## 4.24.0 -* Added support for some integer ranges (https://phpstan.org/writing-php-code/phpdoc-types#integer-ranges). +* Added support for some integer ranges (https://phpstan.org/writing-php-code/phpdoc-types#integer-ranges). Annotations attached to integer properties like: ```php /** @@ -109,9 +111,9 @@ Dropped support for PHP 7.2 and PHP 7.3. PHP 7.4 is the minimum required version pool: app.cache item_id: nelmio_api_doc.docs areas: - default: + default: ... - area1: + area1: ... ``` Result in cache keys: `nelmio_api_doc.docs.default` & `nelmio_api_doc.docs.area1` to be used respectively. @@ -124,7 +126,7 @@ Dropped support for PHP 7.2 and PHP 7.3. PHP 7.4 is the minimum required version pool: app.cache item_id: nelmio_api_doc.docs.default ... - area1: + area1: cache: pool: app.cache item_id: nelmio_api_doc.docs.area1 @@ -186,7 +188,7 @@ doc-api: pool: app.cache item_id: nelmio_api_doc.docs ``` - + ## 4.20.0 * Added Redocly as an alternative to Swagger UI. https://github.com/Redocly/redoc. diff --git a/src/ApiDocGenerator.php b/src/ApiDocGenerator.php index cedcd1614..f18234c53 100644 --- a/src/ApiDocGenerator.php +++ b/src/ApiDocGenerator.php @@ -50,6 +50,8 @@ final class ApiDocGenerator */ private $openApiVersion; + private ?string $area = null; + private Generator $generator; /** @@ -86,6 +88,11 @@ public function setOpenApiVersion(?string $openApiVersion): void $this->openApiVersion = $openApiVersion; } + public function setArea(string $area): void + { + $this->area = $area; + } + public function generate(): OpenApi { if (null !== $this->openApi) { @@ -108,7 +115,7 @@ public function generate(): OpenApi $context = Util::createContext(['version' => $this->generator->getVersion()]); $this->openApi = new OpenApi(['_context' => $context]); - $modelRegistry = new ModelRegistry($this->modelDescribers, $this->openApi, $this->alternativeNames); + $modelRegistry = new ModelRegistry($this->modelDescribers, $this->openApi, $this->alternativeNames, $this->area); if (null !== $this->logger) { $modelRegistry->setLogger($this->logger); } diff --git a/src/Model/Model.php b/src/Model/Model.php index 1a911d156..8c88feeca 100644 --- a/src/Model/Model.php +++ b/src/Model/Model.php @@ -27,6 +27,8 @@ final class Model */ private array $serializationContext; + private ?string $area = null; + /** * @param string[]|null $groups * @param mixed[]|null $options @@ -73,6 +75,16 @@ public function getHash(): string return md5(serialize([$this->type, $this->getSerializationContext()])); } + public function setArea(?string $area): void + { + $this->area = $area; + } + + public function getArea(): ?string + { + return $this->area; + } + /** * @return mixed[] */ diff --git a/src/Model/ModelRegistry.php b/src/Model/ModelRegistry.php index 544b3037e..1d944e650 100644 --- a/src/Model/ModelRegistry.php +++ b/src/Model/ModelRegistry.php @@ -53,6 +53,8 @@ final class ModelRegistry */ private iterable $modelDescribers; + private ?string $area; + private OA\OpenApi $api; /** @@ -61,10 +63,11 @@ final class ModelRegistry * * @internal */ - public function __construct($modelDescribers, OA\OpenApi $api, array $alternativeNames = []) + public function __construct($modelDescribers, OA\OpenApi $api, array $alternativeNames = [], ?string $area = null) { $this->modelDescribers = $modelDescribers; $this->api = $api; + $this->area = $area; $this->logger = new NullLogger(); foreach (array_reverse($alternativeNames) as $alternativeName => $criteria) { $this->alternativeNames[] = $model = new Model( @@ -81,6 +84,7 @@ public function __construct($modelDescribers, OA\OpenApi $api, array $alternativ public function register(Model $model): string { + $model->setArea($this->area); $hash = $model->getHash(); if (!isset($this->models[$hash])) { $this->models[$hash] = $model; diff --git a/src/ModelDescriber/JMSModelDescriber.php b/src/ModelDescriber/JMSModelDescriber.php index 9520bc3a7..3bec6cb0a 100644 --- a/src/ModelDescriber/JMSModelDescriber.php +++ b/src/ModelDescriber/JMSModelDescriber.php @@ -15,6 +15,7 @@ use JMS\Serializer\Context; use JMS\Serializer\ContextFactory\SerializationContextFactoryInterface; use JMS\Serializer\Exclusion\GroupsExclusionStrategy; +use JMS\Serializer\Exclusion\VersionExclusionStrategy; use JMS\Serializer\Metadata\ClassMetadata; use JMS\Serializer\Naming\PropertyNamingStrategyInterface; use JMS\Serializer\SerializationContext; @@ -232,6 +233,11 @@ public function getSerializationContext(Model $model): Context } } + $area = $model->getArea(); + if (null !== $area) { + $context->addExclusionStrategy(new VersionExclusionStrategy($area)); + } + return $context; } diff --git a/src/Render/RenderOpenApi.php b/src/Render/RenderOpenApi.php index a7d1ae5c5..5b3056218 100644 --- a/src/Render/RenderOpenApi.php +++ b/src/Render/RenderOpenApi.php @@ -11,6 +11,7 @@ namespace Nelmio\ApiDocBundle\Render; +use Nelmio\ApiDocBundle\ApiDocGenerator; use Nelmio\ApiDocBundle\Exception\RenderInvalidArgumentException; use OpenApi\Annotations\OpenApi; use OpenApi\Annotations\Server; @@ -81,8 +82,14 @@ public function render(string $format, string $area, array $options = []): strin throw new RenderInvalidArgumentException(sprintf('Format "%s" is not supported.', $format)); } + $generator = $this->generatorLocator->get($area); + + if ($generator instanceof ApiDocGenerator) { + $generator->setArea($area); + } + /** @var OpenApi $spec */ - $spec = $this->generatorLocator->get($area)->generate(); + $spec = $generator->generate(); $tmpServers = $spec->servers; try { $spec->servers = $this->getServersFromOptions($spec, $options);