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);
}
/**