2014-01-09 60 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

解決了!

我用DataTransformer:http://symfony.com/en/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() 
));