Можно ли получить значение из другого поля формы внутри DataTransformer для поля?
Я могу создать приглашение, связанное с электронной почтой, а затем, когда пользователь зарегистрируется, он должен ввести код приглашения, он будет работать, даже если этот код не связан с введенным им электронным адресом, потому что поле Invitation
является DataTransformer
который проверяет значение внутри БД, Я бы хотел проверить внутри этого запроса, если письмо существует.
MainForm
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 к FieldType, которая делает dataTransformer:
InvitationType
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
Поэтому, если у кого-то такая же проблема, я нашел решение.
Сначала создайте службу для своего настраиваемого типа поля, введя @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
должен 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
, кусок торта.
Вы можете ввести свое значение в трансформатор
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;
}
}
$emailValue
из поля формы? Я имею в виду, $emailValue
должно быть значением поля ввода email
при $emailValue
. Итак, когда мы отправляем форму, преобразователь проверяет code
и email
на entityManager