양식 유효성 검사 - 엔티티 필드의로드 오버라이드
-
21-12-2019 - |
문제
FoSrestBundle을 기반으로 REST API를 구축하고 있습니다.일부 엔티티를 만들려면 소비자가 Post HTTP 요청에서 다음 JSON을 보냅니다.
{
"myentity":
{
"field1": "field1 value",
"field2": "field2 value",
"user": 1,
"createdAt": {"date":{"year":"2012", "month":"11", "day":"8"}, "time":{"hour":"13","minute":"22"}}
}
}
.
필드 사용자는 사용자의 ID를 포함합니다.사용자 전자 메일 또는 전화 번호로 변경하고 싶습니다.엔티티 사용자의 인스턴스를 만들고 Myentity 인스턴스에 패스를 만들 수있는 방법을 알아 내려고합니다.
여기에 내 양식의 샘플 코드가 있습니다.
<?php
namespace Acme\DemoBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class MyFormType extends AbstractType
{
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('field1')
->add('field2')
->add('createdAt')
->add('user');
}
/**
* @param OptionsResolverInterface $resolver
*/
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Acme\DemoBundle\Entity\MyEntity',
'csrf_protection' => false
));
}
/**
* @return string
*/
public function getName()
{
return 'myform';
}
}
.
은 API 소비자가 제공 한 데이터를 확인하는 방법입니다.
/**
* @Rest\View
*/
public function saveAction()
{
return $this->processForm(new MyEntity());
}
/**
* @Rest\View
*/
private function processForm(MyEntity $myEntity)
{
$form = $this->createForm(new MyFormType(), $myEntity);
$form->bind($this->getRequest());
if ($form->isValid()) {
//$position->save();
$response = new Response();
$response->setStatusCode(204);
return $response;
}
return $this->view($form, 400);
}
. 해결책
해결!
DataTransformer를 사용했습니다. http://symfony.com/ko/doc/current/cookbook/form/data_transformers.html
DataTransformer를 만들어야합니다.
<?php
namespace Acme\DemoBundle\Form;
use Symfony\Component\Form\DataTransformerInterface;
use Symfony\Component\Form\Exception\TransformationFailedException;
use Doctrine\Common\Persistence\ObjectManager;
use Acme\DemoBundle\Entity\User;
class PhoneNumberToUserTransformer implements DataTransformerInterface {
/**
* @var ObjectManager
*/
private $om;
/**
* @param ObjectManager $om
*/
public function __construct(ObjectManager $om) {
$this->om = $om;
}
/**
* Transforms an object (User) to a string (phonenumber).
*
* @param User|null $issue
* @return string
*/
public function transform($user) {
if (null === $user) {
return "";
}
return $user->getPhonenumber();
}
/**
* Transforms a string (phonenumber) to an object (User).
*
* @param string $phonenumber
* @return User|null
* @throws TransformationFailedException if object (user) is not found.
*/
public function reverseTransform($phonenumber) {
if (!$phonenumber) {
return null;
}
$user = $this->om
->getRepository('AcmeDemoBundle:User')
->findOneBy(array('phonenumber' => $phonenumber))
;
if (null === $user) {
throw new TransformationFailedException(sprintf(
'L\'utilisateur avec le numéro "%s" ne peut pas être trouvé!', $phonenumber
));
}
return $user;
}
}
?>
.
양식 정의 :
public function buildForm(FormBuilderInterface $builder, array $options) {
$entityManager = $options['em'];
$transformer = new PhoneNumberToUserTransformer($entityManager);
$builder
->add('field1')
->add('field2')
->add('createdAt')
->add($builder->create('user', 'text')->addModelTransformer($transformer));
}
/**
* @param OptionsResolverInterface $resolver
*/
public function setDefaultOptions(OptionsResolverInterface $resolver) {
$resolver->setDefaults(array(
'data_class' => 'Acme\DemoBundle\Entity\MyEntity',
'csrf_protection' => false,
'em' => null
));
}
.
및 마지막으로 컨트롤러에서 :
$form = $this->createForm(new MyFormType(), $myentity, array(
'em' => $this->getDoctrine()->getManager()
));
. 제휴하지 않습니다 StackOverflow