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;
}
}
我正在构建一个 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;
}
}