diff --git a/Form/Extension/DocumentationExtension.php b/Form/Extension/DocumentationExtension.php new file mode 100644 index 0000000..2dcd1f9 --- /dev/null +++ b/Form/Extension/DocumentationExtension.php @@ -0,0 +1,39 @@ + + */ +class DocumentationExtension extends AbstractTypeExtension +{ + public function buildForm(FormBuilderInterface $builder, array $options) + { + $builder->setAttribute('documentation', $options['documentation']); + } + + public function configureOptions(OptionsResolver $resolver) + { + $resolver->setDefaults(['documentation' => []]) + ->setAllowedTypes('documentation', ['array']); + } + + public function getExtendedType() + { + return FormType::class; + } +} diff --git a/ModelDescriber/FormModelDescriber.php b/ModelDescriber/FormModelDescriber.php index 414bb99..13c3836 100644 --- a/ModelDescriber/FormModelDescriber.php +++ b/ModelDescriber/FormModelDescriber.php @@ -64,6 +64,19 @@ final class FormModelDescriber implements ModelDescriberInterface, ModelRegistry foreach ($form as $name => $child) { $config = $child->getConfig(); $property = $properties->get($name); + + if ($config->getRequired()) { + $required = $schema->getRequired() ?? []; + $required[] = $name; + + $schema->setRequired($required); + } + + $property->merge($config->getOption('documentation')); + if (null !== $property->getType()) { + continue; // Type manually defined + } + for ($type = $config->getType(); null !== $type; $type = $type->getParent()) { $blockPrefix = $type->getBlockPrefix(); @@ -148,20 +161,13 @@ final class FormModelDescriber implements ModelDescriberInterface, ModelRegistry } if ($type->getInnerType() && ($formClass = get_class($type->getInnerType())) && !$this->isBuiltinType($formClass)) { - //if form type is not builtin in Form component. + // if form type is not builtin in Form component. $model = new Model(new Type(Type::BUILTIN_TYPE_OBJECT, false, $formClass)); $property->setRef($this->modelRegistry->register($model)); break; } } - - if ($config->getRequired()) { - $required = $schema->getRequired() ?? []; - $required[] = $name; - - $schema->setRequired($required); - } } } diff --git a/Resources/config/services.xml b/Resources/config/services.xml index ecceef3..1f4393a 100644 --- a/Resources/config/services.xml +++ b/Resources/config/services.xml @@ -45,6 +45,12 @@ + + + + + + diff --git a/Tests/Functional/Form/UserType.php b/Tests/Functional/Form/UserType.php index 4b52fd6..0f12719 100644 --- a/Tests/Functional/Form/UserType.php +++ b/Tests/Functional/Form/UserType.php @@ -25,7 +25,8 @@ class UserType extends AbstractType ->add('dummy', DummyType::class) ->add('dummies', CollectionType::class, [ 'entry_type' => DummyType::class, - ]); + ]) + ->add('quz', DummyType::class, ['documentation' => ['type' => 'string', 'description' => 'User type.'], 'required' => false]); } public function configureOptions(OptionsResolver $resolver) diff --git a/Tests/Functional/FunctionalTest.php b/Tests/Functional/FunctionalTest.php index d500016..1c1d19d 100644 --- a/Tests/Functional/FunctionalTest.php +++ b/Tests/Functional/FunctionalTest.php @@ -213,6 +213,10 @@ class FunctionalTest extends WebTestCase 'type' => 'array', 'example' => sprintf('[{%s}]', DummyType::class), ], + 'quz' => [ + 'type' => 'string', + 'description' => 'User type.', + ], ], 'required' => ['dummy', 'dummies'], ], $this->getModel('UserType')->toArray());