我正在编写自己的CAPTCHA类,当表单未验证时,出于显而易见的原因,我不想使用之前的答案预先填充验证码输入。我只想在渲染之前清除输入。
我发现 data 选项仅用于默认值,该值由用户输入的内容覆盖。我尝试了以下代码:
$form->get('captcha')->setData(null);
..请求与表单绑定后,但抛出AlreadyBoundException
。我实际上已经设法使用它:
if (isset($formView->children['captcha'])) {
$formView->children['captcha']->vars['value'] = null;
}
但这看起来不错,绝对不符合Symfony的标准。我已经查看了构建表单时可以提供的其他选项,但我看不到任何注意事项。
有没有人有任何想法?
顺便说一句,我有一半期望Symfony2附带一个CAPTCHA解决方案,这主要是一个学习练习,而我习惯了这个框架。
答案 0 :(得分:5)
我认为您希望处理此表单字段,例如Symfony处理password
字段:它不会被填充。我们来看看PasswordType:
namespace Symfony\Component\Form\Extension\Core\Type;
class PasswordType extends AbstractType
{
public function buildView(FormView $view, FormInterface $form, array $options)
{
if ($options['always_empty'] || !$form->isSubmitted()) {
$view->vars['value'] = '';
}
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'always_empty' => true,
'trim' => false,
));
}
//...
}
因此,它非常简单:只需在FormType的$view->vars['value'] = ''
方法中添加buildView
(即CaptchaType)。这意味着该字段的数据未被清除,但不会传递给Twig模板。不同的方法,但结果是相同的:验证失败后密码字段保持为空。
如果你真的很懒,你可以使用PasswordType,但由于该字段的输入将被屏蔽(*****),这会使烦人的验证码字段变得更糟。
您的表单类型可能如下所示:
class CaptchaType extends AbstractType
{
/**
* {@inheritdoc}
*/
public function buildView(FormView $view, FormInterface $form, array $options)
{
$view->vars['value'] = '';
}
/**
* {@inheritdoc}
*/
public function getParent()
{
return __NAMESPACE__.'\TextType';
}
/**
* {@inheritdoc}
*/
public function getName()
{
return $this->getBlockPrefix();
}
/**
* {@inheritdoc}
*/
public function getBlockPrefix()
{
return 'captcha';
}
}
编辑: 刚刚发现CaptchaBundle取得了same approach。
答案 1 :(得分:3)
在处理请求之前,有一种有趣的方法可以修改请求。然而,我看看斯蒂芬的答案,因为它看起来更干净。
像这样:
public function indexAction(Request $request)
{
$form = $this->createForm(Form::class);
$subData=$request->request->get('form');
$subData['task']=null;
$request->request->set('form',$subData);
$form->handleRequest($request);
if ($form->isValid()) {
//do stuff
}
return $this->render('default/index.html.twig', array(
'form' => $form->createView()
));
}
使用名称'表格'获取提交的数据作为一个值数组,将所述值更改为null,然后使用新值设置请求的值并让表单处理它。
一个简单的表格
class Form extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('task')
->add('save', SubmitType::class);
}
}
无论您输入什么内容,提交表单后数据始终为空。当然,您需要在将值设置为null之前验证验证码。
答案 2 :(得分:0)
当控件发现表单无效时,您可以将不完整的实体传递给调用的操作。
public function updateAction(Request $request, $id) { $entity = $this->EM()->getRepository('Bundle:Entity')->find($id); if (!$entity) { throw $this->createNotFoundException('Unable to find Entity entity.'); } $form = $this->createForm(new RecommendationType() ,$entity ,array( 'attr' => array( ,'entity' => $entity ) ) ); $form->bind($request); if ($form->isValid()) { $this->EM()->persist($entity); $this->EM()->flush(); return $this->redirect($this->generateUrl('entity_show' ,array('id' => $id))); } else { $entity->setCapthca(Null); } return $this->render('Bundle:Entity:edit.html.twig' ,array( 'entity' => $entity ,'form' => $form->createView() ) ); }
创建操作会有类似的修改。