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());