Symfony2 DataTransformer中的访问请求参数


Access Request parameters inside Symfony2 DataTransformer

是否可以从 DataTransformer 中的另一个表单字段中获取字段的值?

我可以创建一个链接到电子邮件的邀请,然后当用户注册时,他必须输入一个邀请代码,即使该代码没有链接到他输入的电子邮件,它也会起作用,因为Invitation字段是一个检查数据库内值的DataTransformer。我想在该查询中检查电子邮件是否存在。

主窗体

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('invitation', 'invitation_type', array(
            'required' => true,
            'label' => false,
            'attr' => array(
                'placeholder' => 'form.invitation_code',
                'class' => 'form-control',
            )
        ))
    ;
}

invitation_type是一项服务,我将 entityManager 注入到呈现 dataTransformer 的字段类型中:

邀请函类型

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $transformer = new InvitationTransformer($this->entityManager);
    $builder->addModelTransformer($transformer);
}

然后是变压器

public function reverseTransform($value)
{
    $invitation = $this->entityManager->getRepository('Invitation')
        ->findOneBy(array(
            'code' => $value
        ));
    return $invitation;
}

这就是查询,正如我所说,无需检查电子邮件值即可工作,它会像'email' => $emailValue但是,我不知道如何访问$emailValue

您可以将值注入变压器

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $entity = $builder->getData();
    $email = $entity->getEmail();
    $transformer = new MyTransformer($email);
    $builder->add(
        $builder->create('sample', 'choice', array(
            'attr'     => array('class' => 'test')
        ))->addModelTransformer($transformer)
    )
}
class MyTransformer implements DataTransformerInterface {
    private $emailValue;
    public function __construct($emailValue)
    {
        $this->emailValue = $emailValue;
    }
    public function reverseTransform($value)
    {
        // Do something with $this->emailValue;
        $invitation = $this->entityManager->getRepository('Invitation')
            ->findOneBy(array('code' => $value));
        return $invitation;
    }
}
因此,

如果有人遇到同样的问题,我找到了解决方案。

首先为自定义字段类型创建一个服务,注入@request_stack

foo.form.type.invitation:
    class: Foo'BarBundle'Form'Type'InvitationType
    arguments: [ "@doctrine.orm.entity_manager" ]
    tags:
        - { name: form.type, alias: invitation_type}
    calls:
        - [setRequest, [@request_stack]]

然后创建自定义字段类型类,它将Request注入到DataTransformer

<?php
namespace Foo'BarBundle'Form'Type;
use Doctrine'ORM'EntityManager;
use Foo'BarBundle'Form'DataTransformer'InvitationTransformer;
use Symfony'Component'Form'AbstractType;
use Symfony'Component'Form'FormBuilderInterface;
use Symfony'Component'HttpFoundation'RequestStack;
class InvitationType extends AbstractType
{
    private $entityManager;
    protected $request;
    public function __construct(EntityManager $em)
    {
        $this->entityManager = $em;
    }
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $transformer = new InvitationTransformer($this->entityManager, $this->request);
        $builder->addModelTransformer($transformer);
    }
    public function getParent()
    {
        return 'text';
    }
    public function getName()
    {
        return 'invitation_type';
    }
    public function setRequest(RequestStack $request_stack)
    {
        $this->request = $request_stack->getCurrentRequest();
    }
}

然后我们的DataTransformer需要获取数据,更改值以匹配您的请求,当然

<?php
namespace Foo'BarBundle'Form'DataTransformer;
use Doctrine'ORM'EntityManager;
use Symfony'Component'Form'DataTransformerInterface;
use Symfony'Component'Form'Exception'UnexpectedTypeException;
use Symfony'Component'HttpFoundation'Request;
class InvitationTransformer implements DataTransformerInterface
{
    protected $entityManager;
    protected $request;
    public function __construct(EntityManager $entityManager, Request $request)
    {
        $this->entityManager    = $entityManager;
        $this->request          = $request;
    }
    public function transform($value)
    {
        if (null === $value) {
            return null;
        }
        if (!$value instanceof Invitation) {
            throw new UnexpectedTypeException($value, 'Foo'BarBundle'Entity'Invitation');
        }
        return $value->getCode();
    }
    public function reverseTransform($value)
    {
        if (null === $value || '' === $value) {
            return null;
        }
        if (!is_string($value)) {
            throw new UnexpectedTypeException($value, 'string');
        }
        $formData = $this->request->get('registration_form'); // Your MAIN form goes here
        $email = $formData['email']; // The value you need
        $invitation = $this->entityManager->getRepository('FooBarBundle:Invitation')
            ->findOneBy(array(
                'code'  => $value,
                'email' => $email
            ));
        if($this->entityManager->getRepository('FooBarBundle:User')->findOneBy(array("invitation" => $invitation))){
            return null;
        }
        return $invitation;
    }
}

现在,您可以访问DataTransformer内的参数袋,这是小菜一碟。