From d6ea99420ef2060e729345201b452ecdc706d9b7 Mon Sep 17 00:00:00 2001 From: Asmir Mustafic Date: Tue, 16 Apr 2019 12:13:33 +0200 Subject: [PATCH] Allow model describers on jms custom types (#1495) * allow model describers on jms custom types * add fallback describer * test custom type def * remove object_fallback describer from the container when jms is not active --- DependencyInjection/NelmioApiDocExtension.php | 2 ++ .../FallbackObjectModelDescriber.php | 28 ++++++++++++++++ ModelDescriber/JMSModelDescriber.php | 5 --- ModelDescriber/ObjectModelDescriber.php | 2 +- Resources/config/services.xml | 4 +++ Tests/Functional/Entity/JMSUser.php | 18 +++++++++++ Tests/Functional/JMSFunctionalTest.php | 18 +++++++++++ ...ssDoesNotExistsHandlerDefinedDescriber.php | 32 +++++++++++++++++++ Tests/Functional/TestKernel.php | 6 ++++ 9 files changed, 109 insertions(+), 6 deletions(-) create mode 100644 ModelDescriber/FallbackObjectModelDescriber.php create mode 100644 Tests/Functional/ModelDescriber/VirtualTypeClassDoesNotExistsHandlerDefinedDescriber.php diff --git a/DependencyInjection/NelmioApiDocExtension.php b/DependencyInjection/NelmioApiDocExtension.php index b0eaf66..0261496 100644 --- a/DependencyInjection/NelmioApiDocExtension.php +++ b/DependencyInjection/NelmioApiDocExtension.php @@ -173,6 +173,8 @@ final class NelmioApiDocExtension extends Extension implements PrependExtensionI new Reference('nelmio_api_doc.model_describers.jms.inner'), ]); } + } else { + $container->removeDefinition('nelmio_api_doc.model_describers.object_fallback'); } // Import the base configuration diff --git a/ModelDescriber/FallbackObjectModelDescriber.php b/ModelDescriber/FallbackObjectModelDescriber.php new file mode 100644 index 0000000..e437d0d --- /dev/null +++ b/ModelDescriber/FallbackObjectModelDescriber.php @@ -0,0 +1,28 @@ +getType()->getBuiltinType(); + } +} diff --git a/ModelDescriber/JMSModelDescriber.php b/ModelDescriber/JMSModelDescriber.php index 0ea6257..046fcce 100644 --- a/ModelDescriber/JMSModelDescriber.php +++ b/ModelDescriber/JMSModelDescriber.php @@ -177,11 +177,6 @@ class JMSModelDescriber implements ModelDescriberInterface, ModelRegistryAwareIn $property->setType('string'); $property->setFormat('date-time'); } else { - // we can use property type also for custom handlers, then we don't have here real class name - if (!class_exists($type['name'])) { - return null; - } - $model = new Model(new Type(Type::BUILTIN_TYPE_OBJECT, false, $type['name']), $groups); $property->setRef($this->modelRegistry->register($model)); diff --git a/ModelDescriber/ObjectModelDescriber.php b/ModelDescriber/ObjectModelDescriber.php index 388d490..aae6f19 100644 --- a/ModelDescriber/ObjectModelDescriber.php +++ b/ModelDescriber/ObjectModelDescriber.php @@ -124,6 +124,6 @@ class ObjectModelDescriber implements ModelDescriberInterface, ModelRegistryAwar public function supports(Model $model): bool { - return Type::BUILTIN_TYPE_OBJECT === $model->getType()->getBuiltinType(); + return Type::BUILTIN_TYPE_OBJECT === $model->getType()->getBuiltinType() && class_exists($model->getType()->getClassName()); } } diff --git a/Resources/config/services.xml b/Resources/config/services.xml index 4dd32e2..3502dde 100644 --- a/Resources/config/services.xml +++ b/Resources/config/services.xml @@ -46,6 +46,10 @@ + + + + diff --git a/Tests/Functional/Entity/JMSUser.php b/Tests/Functional/Entity/JMSUser.php index 389c09e..42577cb 100644 --- a/Tests/Functional/Entity/JMSUser.php +++ b/Tests/Functional/Entity/JMSUser.php @@ -126,6 +126,24 @@ class JMSUser */ private $status; + /** + * JMS custom types handled via Custom Type Handlers. + * + * @var string + * @Serializer\Type("VirtualTypeClassDoesNotExistsHandlerDefined") + * @Serializer\Expose + */ + private $virtualType1; + + /** + * JMS custom types handled via Custom Type Handlers. + * + * @var string + * @Serializer\Type("VirtualTypeClassDoesNotExistsHandlerNotDefined") + * @Serializer\Expose + */ + private $virtualType2; + /** * @Serializer\Type("array>") * @Serializer\Expose diff --git a/Tests/Functional/JMSFunctionalTest.php b/Tests/Functional/JMSFunctionalTest.php index b01783b..cda11f8 100644 --- a/Tests/Functional/JMSFunctionalTest.php +++ b/Tests/Functional/JMSFunctionalTest.php @@ -121,6 +121,12 @@ class JMSFunctionalTest extends WebTestCase 'description' => 'Only enabled users may be used in actions.', 'enum' => ['disabled', 'enabled'], ], + 'virtual_type1' => [ + '$ref' => '#/definitions/VirtualTypeClassDoesNotExistsHandlerDefined', + ], + 'virtual_type2' => [ + '$ref' => '#/definitions/VirtualTypeClassDoesNotExistsHandlerNotDefined', + ], 'last_update' => [ 'type' => 'date', ], @@ -174,6 +180,18 @@ class JMSFunctionalTest extends WebTestCase ], ], ], $this->getModel('JMSUser')->toArray()); + + $this->assertEquals([ + ], $this->getModel('VirtualTypeClassDoesNotExistsHandlerNotDefined')->toArray()); + + $this->assertEquals([ + 'type' => 'object', + 'properties' => [ + 'custom_prop' => [ + 'type' => 'string', + ], + ], + ], $this->getModel('VirtualTypeClassDoesNotExistsHandlerDefined')->toArray()); } public function testModelComplexDualDocumentation() diff --git a/Tests/Functional/ModelDescriber/VirtualTypeClassDoesNotExistsHandlerDefinedDescriber.php b/Tests/Functional/ModelDescriber/VirtualTypeClassDoesNotExistsHandlerDefinedDescriber.php new file mode 100644 index 0000000..1ac1dac --- /dev/null +++ b/Tests/Functional/ModelDescriber/VirtualTypeClassDoesNotExistsHandlerDefinedDescriber.php @@ -0,0 +1,32 @@ +setType('object'); + $schema->getProperties()->get('custom_prop')->setType('string'); + } + + public function supports(Model $model): bool + { + return Type::BUILTIN_TYPE_OBJECT === $model->getType()->getBuiltinType() + && 'VirtualTypeClassDoesNotExistsHandlerDefined' === $model->getType()->getClassName(); + } +} diff --git a/Tests/Functional/TestKernel.php b/Tests/Functional/TestKernel.php index 7e815f2..31d4b5c 100644 --- a/Tests/Functional/TestKernel.php +++ b/Tests/Functional/TestKernel.php @@ -16,12 +16,14 @@ use Bazinga\Bundle\HateoasBundle\BazingaHateoasBundle; use FOS\RestBundle\FOSRestBundle; use JMS\SerializerBundle\JMSSerializerBundle; use Nelmio\ApiDocBundle\NelmioApiDocBundle; +use Nelmio\ApiDocBundle\Tests\Functional\ModelDescriber\VirtualTypeClassDoesNotExistsHandlerDefinedDescriber; use Sensio\Bundle\FrameworkExtraBundle\SensioFrameworkExtraBundle; use Symfony\Bundle\FrameworkBundle\FrameworkBundle; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Bundle\TwigBundle\TwigBundle; use Symfony\Component\Config\Loader\LoaderInterface; use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Definition; use Symfony\Component\HttpKernel\Kernel; use Symfony\Component\Routing\RouteCollectionBuilder; @@ -163,6 +165,10 @@ class TestKernel extends Kernel ], ], ]); + + $def = new Definition(VirtualTypeClassDoesNotExistsHandlerDefinedDescriber::class); + $def->addTag('nelmio_api_doc.model_describer'); + $c->setDefinition('nelmio.test.jms.virtual_type.describer', $def); } /**