嵌入自定义类时猜测自定义表单类型

时间:2019-08-30 11:20:07

标签: symfony symfony-forms

两个简单的类构成了我的应用程序模型:MoneyProduct

由于Money应用程序表单可重复使用,因此我决定创建扩展MoneyType的{​​{1}}。

AbstractType
// App\Entity\Product

/**
* @ORM\Embedded(class="Money\Money")
*/
private $price;
// App\Form\ProductType

$builder->add('price', MoneyType::class)

是否可以猜测字段类型而无需明确指定以获得以下代码?

// App\Form\Type\MoneyType

class MoneyType extends AbstractType
{
    private $transformer;

    public function __construct(MoneyToArrayTransformer $transformer)
    {
        $this->transformer = $transformer;
    }

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('amount', NumberType::class, [
                'html5' => true,
                'constraints' => [
                    new NotBlank(),
                    new PositiveOrZero(),
                ],
                'attr' => [
                    'min' => '0',
                    'step' => '0.01',
                ],
            ])
            ->add('currency', ChoiceType::class, [
                'choices' => $this->getCurrenciesChoices(),
                'constraints' => [
                    new NotBlank(),
                ],
            ]);

        $builder->addModelTransformer($this->transformer);
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        parent::configureOptions($resolver);

        $resolver->setDefaults([
            'data_class' => null
        ]);
    }

    ...
}

欢迎任何帮助。预先谢谢你。

2 个答案:

答案 0 :(得分:1)

您可以实现一个custom TypeGuesser来读取原则metadata并检查该字段是否是所需类型的可嵌入对象。这是一个基本的实现

namespace App\Form\TypeGuesser;

use App\Form\Type\MoneyType;

use Symfony\Component\Form\Guess\Guess;
use Symfony\Component\Form\Guess\TypeGuess;
use Symfony\Component\Form\FormTypeGuesserInterface;

use Doctrine\ORM\EntityManagerInterface;

class MoneyTypeGuesser implements FormTypeGuesserInterface
{
    private $em;

    public function __construct(EntityManagerInterface $em)
    {
        $this->em = $em;    
    }

    public function guessType($class, $property) 
    {
        if (!$metadata = $this->em->getClassMetadata($class)) {
            return null;
        }

        if (
            isset($metadata->embeddedClasses[$property]) && 
            'Money\Money' == $metadata->embeddedClasses[$property]['class']
        ) {
            return new TypeGuess(MoneyType::class, [], Guess::HIGH_CONFIDENCE);
        }
    }

    // Other interface functions ommited for brevity, you can return null
}

您可以看到实现here所需的所有接口方法。

答案 1 :(得分:0)

Form TypeGuesser主要基于注释@var Money\Money,并且您应该能够为自己的类型构建向下猜测器,请参见https://symfony.com/doc/current/form/type_guesser.html

还请查看https://github.com/symfony/symfony/blob/4.3/src/Symfony/Bridge/Doctrine/Form/DoctrineOrmTypeGuesser.php,了解如何根据教义性的特定类型猜测类型。

您可以使用这两个示例来得出自己的应用特定猜测器。