2013-07-29 79 views
0

我有兩個密碼字段。這額外用於確認。 當兩者都爲空或密碼不匹配時,沒有錯誤消息。Symfony2重複類型不驗證

如何啓用或調試此驗證,我認爲應該開箱即用(http://symfony.com/doc/current/reference/forms/types/repeated.html#validation)?

class MyType extends AbstractType 
{ 
    public function setDefaultOptions(OptionsResolverInterface $resolver) 
    { 
     $resolver->setDefaults(array(
      'data_class' => 'My\\Bundle\\Entity\\User', 
     )); 
    } 

    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     ... 
     $builder->add('password', 'repeated', array(
      'invalid_message' => 'Passwords must match.', 
      'type'   => 'password', 
      'required'  => true, 
      'first_options' => array('label' => 'Password'), 
      'second_options' => array('label' => 'Repeat Password') 
     )); 

form.html.twig

... 
<form action="" method="post" novalidate> 
... 
<tr> 
    <td>{{ form_label(regForm.password.first) }}</td> 
    <td>{{ form_widget(regForm.password.first, { 'attr': {'pattern': '.{6,}','title': 'Minimum 6 characters long'} }) }}</td> 
</tr> 
<tr> 
    <td>{{ form_label(regForm.password.second) }}</td> 
    <td>{{ form_widget(regForm.password.second, { 'attr': {'pattern': '.{6,}', 'title': 'Minimum 6 characters long', 'data-equals': '#register_password_first'} }) }}</td> 
</tr> 

校驗在validation.yml聲明似乎在這個問題上沒有任何影響。

My\Bundle\Entity\User: 
    properties: 
     ... 
     password: 
      # this one does not work because of "repeated" type in buildForm()??? 
       - NotBlank: 
        message: "Password is required." 
       - MinLength: 
        limit: 6 
        message: "Password must have at least {{ limit }} characters." 

Controller.php這樣(原創版)

... 
if (!$form->isValid()) { 
    $formFields = $form->all(); 
    foreach ($formFields as $key => $field) { 
     if ($field->getErrorsAsString()) { 
      $errors = $field->getErrors(); 
      foreach ($errors as $error) { 
       $messages[$key][] = $error->getMessage(); 
      } 
     } 
    } 
    var_dump($messages); 

編輯:現在的錯誤檢索看起來像這樣(感謝alex.dominte):

public static function getFormErrorMessages(\Symfony\Component\Form\Form $form) 
{ 
    $messages = array(); 

    foreach ($form->getErrors() as $i => $error) { 
     $messages[$i] = $error->getMessage(); 
    } 

    foreach ($form->all() as $child) { 
     if (!$child->isValid()) { 
      $messages[$child->getName()] = self::getFormErrorMessages($child); 
     } 
    } 

    return $messages; 
} 

修改建議通過Pedro Cordeiro使得遞歸遞歸成爲可能,但也使字段名稱不可用。

+0

你能張貼您的控制器代碼?你忘了調用'$ form-> isValid()'? – cheesemacfly

+0

您需要一個{{form_error(regForm.password.first)}} – Cerad

+0

添加了一些控制器代碼 – coviex

回答

2

沒有足夠的遞歸

foreach ($formFields as $key => $field) { 
    if ($field->getErrorsAsString()) { 
     $errors = $field->getErrors(); 
     foreach ($errors as $error) { 
      $messages[$key][] = $error->getMessage(); 
     } 
    } 
} 

試試這個 - 應該爲所有嵌套的錯誤工作:

class FormHelper 
{ 
    public static function getErrorMessages($form) 
    { 
     $errors = array(); 
     if (!$form->isBound()) return $errors; 
     foreach ($form->getErrors() as $key => $error) { 
      $template = $error->getMessageTemplate(); 
      $parameters = $error->getMessageParameters(); 

      foreach ($parameters as $var => $value) { 
       $template = str_replace($var, $value, $template); 
      } 

      $errors[$key] = $template; 
     } 
     if ($form->hasChildren()) { 
      foreach ($form->getChildren() as $child) { 
       if (!$child->isValid()) { 
        $name = $child->getConfig()->getOption('title', $child->getName()); 
        $errors[$name] = self::getErrorMessages($child); 
       } 
      } 
     } 

     return $errors; 
    } 

} 
+0

**沒有足夠的遞歸** - 絕對正確。非常感謝 – coviex

0

你不顯示錯誤消息

{{ form_errors(regForm.password.first) }} 
{{ form_errors(regForm.password.second) }} 
3

兩件事情從您的定義缺失:

  • 1)error_bubbling必須在您的字段上手動設置爲TRUE,以便它們可以在 - > getErrors()函數中引發錯誤。
  • 2)cascade_validationFALSE默認情況下,你必須得把它添加到您的父母形成($builder->add('propertyName', new YourFormNameType(), array('cascade_validation ' => true));) - See this