Symfony3 表单类型,通过 id 引用其他实体

Symfony3 form type, reference other entity by id

我正在构建一个 API 并使用表单进行数据绑定,现在我希望能够传递实体的 ID,获取引用并将其附加到项目,这是一个示例:

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder->add('credit');
    $builder->add('currency', 'currency');
    $builder->add('borrower', BorrowerType::class, [
        'required' => true
    ]);

    $builder->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event) {
        $data = $event->getData();
        $borrower = $this->em->getReference(Borrower::class, $data['borrower']);
        $data['borrower'] = $borrower;
    });
}

这个returns"ERROR: This value is not valid.\n"

这是我的测试要求:

    $client->request('POST', $endpoint, [
        'loan' => [
            'credit' => '1000',
            'currency' => 'EUR',
            'borrower' => $borrower->getId()
        ]
    ]);

“$event->getData()”是您的实际实体,如果此表单在其选项解析器中使用默认实体,或者如果您在创建表单时通过控制器传递实体。

public function buildForm(FormBuilderInterface $builder, array $options)
 {
    $builder->add('credit');
    $builder->add('currency', 'currency');
    $builder->add('borrower', BorrowerType::class, [
         'required' => true
    ]);

    $builder->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event) {
        $entity = $event->getData();

         //The following doesn't make a lot of sense
         //The borrower will already be set

        $borrower = $this->em->getReference(Borrower::class, $entity->getBorrower());
        $entity->setBorrower($borrower);
    });
 }

就像这种检查用户是否必须输入密码(如果是新用户)或者如果用户已经存在则不需要输入密码的标准方法一样。

$builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) {
        $user = $event->getData();
        $form = $event->getForm();
        $formParams = [
            'type' => PasswordType::class,
            'first_options' => ['label' => 'Password'],
            'second_options' => ['label' => 'Repeat Password'],
        ];

        if ((!$user || null === $user->getId())) {
            $formParams['constraints'] = new NotBlank();
        } else {
            $formParams['required'] = false;
        }

        $form->add('plainPassword', RepeatedType::class, $formParams);
    });

如果此表单正在创建或更新实体,则借款人信息会在实体创建时设置到该实体。

实现此 "symfonic" 方法的一种直接方法是使用 DataTransformer

DataTransformer 将采用一种数据格式并将其转换为另一种格式(类型)。

你可以使用的是一个 ViewTransformer,在 Transform() 阶段,它将获取实体和 return 它的 id 而在 ReverseTransform() 它获取 id 并通过使用存储库检索实体。

类似

class BorrowerToIdTransform implements DataTransformerInterface
{
    private $manager;

    public function __construct(ObjectManager $manager)
    {
        $this->manager = $manager;
    }

    /**
     * Transforms an object (Borrower) to a string (id).
     *
     * @param  Borrower|null $issue
     * @return string
     */
    public function transform($borrower)
    {
        if (null === $borrower) {
            return '';
        }

        return $borrower->getId();
    }

    /**
     * Transforms a string (id) to an object (Borrower).
     *
     * @param  string $id
     * @return Borrower|null
     * @throws TransformationFailedException if object (issue) is not found.
     */
    public function reverseTransform($id)
    {
        if (!$id) {
            return;
        }

        $borrower = $this->manager
            ->getRepository(Borrower::class)
            ->find($id)
        ;

        if (null === $borrower) {
            throw new TransformationFailedException(sprintf(
                'A borrower with "%s" id does not exist!',
                $id
            ));
        }

        return $issue;
    }
}