2013-02-22 29 views
11

Tôi đang viết lớp CAPTCHA của riêng mình và khi biểu mẫu không xác thực, tôi không muốn điền trước hình ảnh xác thực bằng câu trả lời trước đó, vì lý do hiển nhiên. Tôi chỉ muốn rõ ràng đầu vào trước khi nó được hiển thị.Cách xóa giá trị trường bằng biểu mẫu Symfony2

Tôi đã phát hiện ra tùy chọn dữ liệu chỉ dành cho giá trị mặc định, được ghi đè bởi những gì người dùng nhập. Tôi đã thử các mã sau:

$form->get('captcha')->setData(null); 

.. Sau khi yêu cầu được ràng buộc với các hình thức, nhưng một AlreadyBoundException được ném. Tôi đã thực sự quản lý để làm cho nó hoạt động với:

if (isset($formView->children['captcha'])) { 
    $formView->children['captcha']->vars['value'] = null; 
} 

Nhưng điều đó có vẻ sai và chắc chắn không đạt tiêu chuẩn của Symfony. Tôi đã xem xét các tùy chọn khác mà bạn có thể cung cấp khi tạo biểu mẫu, nhưng tôi không thể thấy bất kỳ lưu ý nào.

Có ai có ý tưởng nào không?

Nhân tiện, tôi hy vọng một nửa Symfony2 được đóng gói cùng với giải pháp CAPTCHA, đây chủ yếu là một bài tập học tập trong khi tôi quen với khung công tác.

+0

Làm cách nào để bạn tạo biểu mẫu của mình? Trực tiếp trong bộ điều khiển của bạn? Bạn đang sử dụng fullstack hay chỉ là thành phần biểu mẫu? – Schwierig

+0

Tôi có toàn bộ ứng dụng Symfony. Biểu mẫu có lớp riêng của nó, mở rộng AbstractType, xử lý thêm từng trường. – Adam

+0

Bạn có thể đăng mã Loại của bạn không? – Schwierig

Trả lời

5

Tôi nghĩ rằng bạn muốn xử lý trường biểu mẫu này như Symfony xử lý trường password: nó sẽ không được điền. Chúng ta hãy nhìn vào 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, 
     )); 
    } 

    //... 
} 

Vì vậy, nó khá đơn giản: chỉ cần thêm $view->vars['value'] = '' trong phương pháp buildView của FormType của bạn (ví dụ: CaptchaType). Điều đó có nghĩa là dữ liệu của trường không được xóa, nhưng nó sẽ không được chuyển tới mẫu Twig. Cách tiếp cận khác nhau, nhưng kết quả là như nhau: trường mật khẩu vẫn trống sau khi xác thực không thành công.

Nếu bạn thực sự lười biếng, bạn có thể sử dụng PasswordType, nhưng vì đầu vào của trường đó sẽ bị che dấu (*****), điều đó sẽ làm cho trường captcha gây phiền nhiễu thậm chí tệ hơn.

Loại Mẫu của bạn có thể trông như thế này:

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'; 
    } 
} 

Edit: Chỉ cần phát hiện ra rằng CaptchaBundle lấy same approach.

0

Bạn có thể chuyển một thực thể không đầy đủ cho hành động được gọi khi điều khiển của bạn tìm biểu mẫu không hợp lệ.

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() 
      ) 
     ); 
} 

create hành động sẽ phải thay đổi tương tự.

+0

Cảm ơn, nhưng biểu mẫu liên hệ không phải là một thực thể. Nó chỉ là một loại hình thức với các chi tiết được gửi qua email; không có getter/setters trên đó. – Adam

3

Có một cách thú vị để sửa đổi Yêu cầu trước khi xử lý yêu cầu. Tuy nhiên tôi sẽ nhìn vào câu trả lời của Stephan vì nó có vẻ sạch sẽ hơn.

Something như vậy:

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() 
    )); 
} 

Nhận gửi dữ liệu với tên 'hình thức' như một mảng các giá trị, thay đổi giá trị cho biết null, sau đó thiết lập giá trị của yêu cầu với cái mới và có dạng xử lý nó.

Và một hình thức đơn giản

class Form extends AbstractType 
{ 
    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     $builder 
      ->add('task') 
      ->add('save', SubmitType::class);  

    } 

} 

Không có vấn đề gì bạn gõ, dữ liệu sẽ luôn được null sau khi nộp mẫu đơn. Tất nhiên, bạn cần xác minh captcha trước khi thiết lập giá trị thành null.

Các vấn đề liên quan