From 90f835f1ef31342527c6ec64868a901db286be15 Mon Sep 17 00:00:00 2001 From: Guilhem Niot Date: Wed, 2 Dec 2020 15:38:38 +0100 Subject: [PATCH] Allow to not document form types fields (#1752) * Allow the usage of `@SWG\Definition` on form types * Allow to not document form types fields * Reduce the number of changes --- .../Compiler/ConfigurationPass.php | 1 + Form/Extension/DocumentationExtension.php | 2 +- ModelDescriber/FormModelDescriber.php | 22 +++++++++++++++++-- Tests/Functional/Form/UserType.php | 7 ++++++ Tests/Functional/FunctionalTest.php | 1 + 5 files changed, 30 insertions(+), 3 deletions(-) diff --git a/DependencyInjection/Compiler/ConfigurationPass.php b/DependencyInjection/Compiler/ConfigurationPass.php index df128be..8ea1aca 100644 --- a/DependencyInjection/Compiler/ConfigurationPass.php +++ b/DependencyInjection/Compiler/ConfigurationPass.php @@ -29,6 +29,7 @@ final class ConfigurationPass implements CompilerPassInterface $container->register('nelmio_api_doc.model_describers.form', FormModelDescriber::class) ->setPublic(false) ->addArgument(new Reference('form.factory')) + ->addArgument(new Reference('annotation_reader')) ->addTag('nelmio_api_doc.model_describer', ['priority' => 100]); } } diff --git a/Form/Extension/DocumentationExtension.php b/Form/Extension/DocumentationExtension.php index 0bebeef..2cc03a4 100644 --- a/Form/Extension/DocumentationExtension.php +++ b/Form/Extension/DocumentationExtension.php @@ -29,7 +29,7 @@ class DocumentationExtension extends AbstractTypeExtension public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults(['documentation' => []]) - ->setAllowedTypes('documentation', ['array']); + ->setAllowedTypes('documentation', ['array', 'bool']); } public function getExtendedType() diff --git a/ModelDescriber/FormModelDescriber.php b/ModelDescriber/FormModelDescriber.php index c18f270..cc7284d 100644 --- a/ModelDescriber/FormModelDescriber.php +++ b/ModelDescriber/FormModelDescriber.php @@ -11,10 +11,12 @@ namespace Nelmio\ApiDocBundle\ModelDescriber; +use Doctrine\Common\Annotations\Reader; use EXSyst\Component\Swagger\Schema; use Nelmio\ApiDocBundle\Describer\ModelRegistryAwareInterface; use Nelmio\ApiDocBundle\Describer\ModelRegistryAwareTrait; use Nelmio\ApiDocBundle\Model\Model; +use Nelmio\ApiDocBundle\ModelDescriber\Annotations\AnnotationsReader; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\Extension\Core\Type\FormType; use Symfony\Component\Form\FormConfigBuilderInterface; @@ -32,10 +34,15 @@ final class FormModelDescriber implements ModelDescriberInterface, ModelRegistry use ModelRegistryAwareTrait; private $formFactory; + private $doctrineReader; - public function __construct(FormFactoryInterface $formFactory = null) + public function __construct(FormFactoryInterface $formFactory = null, Reader $reader = null) { $this->formFactory = $formFactory; + $this->doctrineReader = $reader; + if (null === $reader) { + @trigger_error(sprintf('Not passing a doctrine reader to the constructor of %s is deprecated since version 3.8 and won\'t be allowed in version 5.', self::class), E_USER_DEPRECATED); + } } public function describe(Model $model, Schema $schema) @@ -51,6 +58,11 @@ final class FormModelDescriber implements ModelDescriberInterface, ModelRegistry $class = $model->getType()->getClassName(); + if (null !== $this->doctrineReader) { + $annotationsReader = new AnnotationsReader($this->doctrineReader, $this->modelRegistry); + $annotationsReader->updateDefinition(new \ReflectionClass($class), $schema); + } + $form = $this->formFactory->create($class, null, $model->getOptions() ?? []); $this->parseForm($schema, $form); } @@ -66,6 +78,12 @@ final class FormModelDescriber implements ModelDescriberInterface, ModelRegistry foreach ($form as $name => $child) { $config = $child->getConfig(); + + // This field must not be documented + if ($config->hasOption('documentation') && false === $config->getOption('documentation')) { + continue; + } + $property = $properties->get($name); if ($config->getRequired()) { @@ -75,7 +93,7 @@ final class FormModelDescriber implements ModelDescriberInterface, ModelRegistry $schema->setRequired($required); } - if ($config->hasOption('documentation')) { + if ($config->hasOption('documentation') && is_array($config->getOption('documentation'))) { $property->merge($config->getOption('documentation')); } diff --git a/Tests/Functional/Form/UserType.php b/Tests/Functional/Form/UserType.php index a05591c..063a01a 100644 --- a/Tests/Functional/Form/UserType.php +++ b/Tests/Functional/Form/UserType.php @@ -12,6 +12,7 @@ namespace Nelmio\ApiDocBundle\Tests\Functional\Form; use Nelmio\ApiDocBundle\Tests\Functional\Entity\User; +use Swagger\Annotations as SWG; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\Extension\Core\Type\CollectionType; use Symfony\Component\Form\Extension\Core\Type\SubmitType; @@ -19,6 +20,11 @@ use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; +/** + * @SWG\Definition( + * description="this is the description of an user" + * ) + */ class UserType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options) @@ -42,6 +48,7 @@ class UserType extends AbstractType ->add('document', DocumentType::class, ['class' => 'Document']) ->add('documents', DocumentType::class, ['class' => 'Document', 'multiple' => true]) ->add('extended_builtin', ExtendedBuiltinType::class, ['required_option' => 'foo']) + ->add('hidden', DummyType::class, ['documentation' => false]) ->add('save', SubmitType::class); } diff --git a/Tests/Functional/FunctionalTest.php b/Tests/Functional/FunctionalTest.php index f9023e1..5759256 100644 --- a/Tests/Functional/FunctionalTest.php +++ b/Tests/Functional/FunctionalTest.php @@ -211,6 +211,7 @@ class FunctionalTest extends WebTestCase { $this->assertEquals([ 'type' => 'object', + 'description' => 'this is the description of an user', 'properties' => [ 'strings' => [ 'items' => ['type' => 'string'],