表单覆盖实体字段的加载



我正在构建一个基于 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 AcmeDemoBundleForm;
use SymfonyComponentFormAbstractType;
use SymfonyComponentFormFormBuilderInterface;
use SymfonyComponentFormFormEvents;
use SymfonyComponentFormFormEvent;
use SymfonyComponentOptionsResolverOptionsResolverInterface;
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' => 'AcmeDemoBundleEntityMyEntity',
            'csrf_protection' => false
        ));
    }
    /**
     * @return string
     */
    public function getName()
    {
        return 'myform';
    }
}

这就是我验证 API 使用者提供的数据的方式:

/**
 * @RestView
 */
public function saveAction()
{
    return $this->processForm(new MyEntity());
}
/**
 * @RestView
 */
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/en/doc/current/cookbook/form/data_transformers.html

您必须创建一个数据转换器:

<?php
namespace AcmeDemoBundleForm;
use SymfonyComponentFormDataTransformerInterface;
use SymfonyComponentFormExceptionTransformationFailedException;
use DoctrineCommonPersistenceObjectManager;
use AcmeDemoBundleEntityUser;
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' => 'AcmeDemoBundleEntityMyEntity',
        'csrf_protection' => false,
        'em' => null
    ));
}

最后在控制器中:

$form = $this->createForm(new MyFormType(), $myentity, array(
    'em' => $this->getDoctrine()->getManager()
));

最新更新