2014-01-09 2 views
1

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); 
} 

답변

1

가 해결을! 양식 정의에서

<?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() 
)); 
당신은 DataTransformer을 만들 필요가 http://symfony.com/en/doc/current/cookbook/form/data_transformers.html

:

은 내가 DataTransformer를 사용