From 1302bc7568fc1ead9304b8c11d3d2fe5c7ba76c9 Mon Sep 17 00:00:00 2001 From: Baptiste Lafontaine Date: Mon, 4 Apr 2022 11:42:44 +0200 Subject: [PATCH] Create an enum model describer (#1965) * Create an enum model describer * Bump Api-Platform Co-authored-by: Guilhem Niot --- ModelDescriber/EnumModelDescriber.php | 34 +++++++++++++++++++ Resources/config/services.xml | 4 +++ .../Functional/Controller/ApiController81.php | 7 ++++ Tests/Functional/Entity/Article81.php | 12 +++++++ Tests/Functional/Entity/ArticleType81.php | 9 +++++ Tests/Functional/FunctionalTest.php | 11 ++++++ composer.json | 2 +- 7 files changed, 78 insertions(+), 1 deletion(-) create mode 100644 ModelDescriber/EnumModelDescriber.php create mode 100644 Tests/Functional/Entity/Article81.php create mode 100644 Tests/Functional/Entity/ArticleType81.php diff --git a/ModelDescriber/EnumModelDescriber.php b/ModelDescriber/EnumModelDescriber.php new file mode 100644 index 0000000..41fba6e --- /dev/null +++ b/ModelDescriber/EnumModelDescriber.php @@ -0,0 +1,34 @@ +getType()->getClassName(); + + $enums = []; + foreach ($enumClass::cases() as $enumCase) { + $enums[] = $enumCase->value; + } + + $schema->type = is_subclass_of($enumClass, \IntBackedEnum::class) ? 'int' : 'string'; + $schema->enum = $enums; + } + + public function supports(Model $model): bool + { + if (!function_exists('enum_exists')) { + return false; + } + + return Type::BUILTIN_TYPE_OBJECT === $model->getType()->getBuiltinType() + && enum_exists($model->getType()->getClassName()) + && is_subclass_of($model->getType()->getClassName(), \BackedEnum::class); + } +} diff --git a/Resources/config/services.xml b/Resources/config/services.xml index 9d2c38c..99be6ea 100644 --- a/Resources/config/services.xml +++ b/Resources/config/services.xml @@ -79,6 +79,10 @@ + + + + diff --git a/Tests/Functional/Controller/ApiController81.php b/Tests/Functional/Controller/ApiController81.php index 71f3629..b12f5cd 100644 --- a/Tests/Functional/Controller/ApiController81.php +++ b/Tests/Functional/Controller/ApiController81.php @@ -15,6 +15,7 @@ use Nelmio\ApiDocBundle\Annotation\Areas; use Nelmio\ApiDocBundle\Annotation\Model; use Nelmio\ApiDocBundle\Annotation\Security; use Nelmio\ApiDocBundle\Tests\Functional\Entity\Article; +use Nelmio\ApiDocBundle\Tests\Functional\Entity\Article81; use OpenApi\Attributes as OA; use Symfony\Component\Routing\Annotation\Route; @@ -65,4 +66,10 @@ class ApiController81 extends ApiController80 #[OA\PathParameter] string $product_id ) { } + + #[Route('/enum')] + #[OA\Response(response: '201', description: '', attachables: [new Model(type: Article81::class)])] + public function enum() + { + } } diff --git a/Tests/Functional/Entity/Article81.php b/Tests/Functional/Entity/Article81.php new file mode 100644 index 0000000..3904801 --- /dev/null +++ b/Tests/Functional/Entity/Article81.php @@ -0,0 +1,12 @@ +assertFalse($model->additionalProperties); } + + /** + * @requires PHP >= 8.1 + */ + public function testEnumSupport() + { + $model = $this->getModel('ArticleType81'); + + $this->assertSame('string', $model->type); + $this->assertCount(2, $model->enum); + } } diff --git a/composer.json b/composer.json index d69570a..0d12f33 100644 --- a/composer.json +++ b/composer.json @@ -48,7 +48,7 @@ "symfony/twig-bundle": "^4.4|^5.2|^6.0", "symfony/validator": "^4.4|^5.2|^6.0", - "api-platform/core": "^2.4", + "api-platform/core": "^2.6.8", "friendsofsymfony/rest-bundle": "^2.8|^3.0", "willdurand/hateoas-bundle": "^1.0|^2.0", "jms/serializer-bundle": "^2.3|^3.0|^4.0",