mirror of
https://github.com/retailcrm/NelmioApiDocBundle.git
synced 2025-02-02 23:59:26 +03:00
Support for extended builtin form types
This commit is contained in:
parent
bf52f136ce
commit
b4ba46f9c2
@ -16,10 +16,12 @@ use Nelmio\ApiDocBundle\Describer\ModelRegistryAwareInterface;
|
|||||||
use Nelmio\ApiDocBundle\Describer\ModelRegistryAwareTrait;
|
use Nelmio\ApiDocBundle\Describer\ModelRegistryAwareTrait;
|
||||||
use Nelmio\ApiDocBundle\Model\Model;
|
use Nelmio\ApiDocBundle\Model\Model;
|
||||||
use Symfony\Component\Form\AbstractType;
|
use Symfony\Component\Form\AbstractType;
|
||||||
|
use Symfony\Component\Form\Extension\Core\Type\FormType;
|
||||||
use Symfony\Component\Form\FormConfigBuilderInterface;
|
use Symfony\Component\Form\FormConfigBuilderInterface;
|
||||||
use Symfony\Component\Form\FormFactoryInterface;
|
use Symfony\Component\Form\FormFactoryInterface;
|
||||||
use Symfony\Component\Form\FormInterface;
|
use Symfony\Component\Form\FormInterface;
|
||||||
use Symfony\Component\Form\FormTypeInterface;
|
use Symfony\Component\Form\FormTypeInterface;
|
||||||
|
use Symfony\Component\Form\ResolvedFormTypeInterface;
|
||||||
use Symfony\Component\PropertyInfo\Type;
|
use Symfony\Component\PropertyInfo\Type;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -94,8 +96,18 @@ final class FormModelDescriber implements ModelDescriberInterface, ModelRegistry
|
|||||||
*/
|
*/
|
||||||
private function findFormType(FormConfigBuilderInterface $config, $property): bool
|
private function findFormType(FormConfigBuilderInterface $config, $property): bool
|
||||||
{
|
{
|
||||||
for ($type = $config->getType(); null !== $type; $type = $type->getParent()) {
|
$type = $config->getType();
|
||||||
$blockPrefix = $type->getBlockPrefix();
|
|
||||||
|
if (!$builtinFormType = $this->getBuiltinFormType($type)) {
|
||||||
|
// if form type is not builtin in Form component.
|
||||||
|
$model = new Model(new Type(Type::BUILTIN_TYPE_OBJECT, false, get_class($type->getInnerType())));
|
||||||
|
$property->setRef($this->modelRegistry->register($model));
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
$blockPrefix = $builtinFormType->getBlockPrefix();
|
||||||
|
|
||||||
if ('text' === $blockPrefix) {
|
if ('text' === $blockPrefix) {
|
||||||
$property->setType('string');
|
$property->setType('string');
|
||||||
@ -150,6 +162,8 @@ final class FormModelDescriber implements ModelDescriberInterface, ModelRegistry
|
|||||||
|
|
||||||
if ('checkbox' === $blockPrefix) {
|
if ('checkbox' === $blockPrefix) {
|
||||||
$property->setType('boolean');
|
$property->setType('boolean');
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ('collection' === $blockPrefix) {
|
if ('collection' === $blockPrefix) {
|
||||||
@ -180,15 +194,7 @@ final class FormModelDescriber implements ModelDescriberInterface, ModelRegistry
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
} while ($builtinFormType = $builtinFormType->getParent());
|
||||||
if ($type->getInnerType() && ($formClass = get_class($type->getInnerType())) && !$this->isBuiltinType($formClass)) {
|
|
||||||
// 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));
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -209,8 +215,21 @@ final class FormModelDescriber implements ModelDescriberInterface, ModelRegistry
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function isBuiltinType(string $type): bool
|
/**
|
||||||
|
* @param ResolvedFormTypeInterface $type
|
||||||
|
*
|
||||||
|
* @return ResolvedFormTypeInterface|null
|
||||||
|
*/
|
||||||
|
private function getBuiltinFormType(ResolvedFormTypeInterface $type)
|
||||||
{
|
{
|
||||||
return 0 === strpos($type, 'Symfony\Component\Form\Extension\Core\Type');
|
do {
|
||||||
|
$class = get_class($type->getInnerType());
|
||||||
|
|
||||||
|
if (FormType::class !== $class && 0 === strpos($class, 'Symfony\Component\Form\Extension\Core\Type\\')) {
|
||||||
|
return $type;
|
||||||
|
}
|
||||||
|
} while ($type = $type->getParent());
|
||||||
|
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
36
Tests/Functional/Form/ExtendedBuiltinType.php
Normal file
36
Tests/Functional/Form/ExtendedBuiltinType.php
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the NelmioApiDocBundle package.
|
||||||
|
*
|
||||||
|
* (c) Nelmio
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Nelmio\ApiDocBundle\Tests\Functional\Form;
|
||||||
|
|
||||||
|
use Symfony\Component\Form\AbstractType;
|
||||||
|
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
|
||||||
|
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||||
|
|
||||||
|
class ExtendedBuiltinType extends AbstractType
|
||||||
|
{
|
||||||
|
public function configureOptions(OptionsResolver $resolver)
|
||||||
|
{
|
||||||
|
$resolver
|
||||||
|
->setDefaults([
|
||||||
|
'choices' => [
|
||||||
|
'foo' => 'foo',
|
||||||
|
'bar' => 'bar',
|
||||||
|
],
|
||||||
|
])
|
||||||
|
->setRequired('required_option');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getParent(): string
|
||||||
|
{
|
||||||
|
return ChoiceType::class;
|
||||||
|
}
|
||||||
|
}
|
@ -35,7 +35,8 @@ class UserType extends AbstractType
|
|||||||
'entry_type' => DummyEmptyType::class,
|
'entry_type' => DummyEmptyType::class,
|
||||||
'required' => false,
|
'required' => false,
|
||||||
])
|
])
|
||||||
->add('quz', DummyType::class, ['documentation' => ['type' => 'string', 'description' => 'User type.'], 'required' => false]);
|
->add('quz', DummyType::class, ['documentation' => ['type' => 'string', 'description' => 'User type.'], 'required' => false])
|
||||||
|
->add('extended_builtin', ExtendedBuiltinType::class, ['required_option' => 'foo']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function configureOptions(OptionsResolver $resolver)
|
public function configureOptions(OptionsResolver $resolver)
|
||||||
|
@ -243,8 +243,12 @@ class FunctionalTest extends WebTestCase
|
|||||||
'type' => 'string',
|
'type' => 'string',
|
||||||
'description' => 'User type.',
|
'description' => 'User type.',
|
||||||
],
|
],
|
||||||
|
'extended_builtin' => [
|
||||||
|
'type' => 'string',
|
||||||
|
'enum' => ['foo', 'bar'],
|
||||||
|
],
|
||||||
],
|
],
|
||||||
'required' => ['dummy', 'dummies'],
|
'required' => ['dummy', 'dummies', 'extended_builtin'],
|
||||||
], $this->getModel('UserType')->toArray());
|
], $this->getModel('UserType')->toArray());
|
||||||
|
|
||||||
$this->assertEquals([
|
$this->assertEquals([
|
||||||
|
Loading…
x
Reference in New Issue
Block a user