2013-07-29 2 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> 

Validators заявил в 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); 

EDIT: Теперь поиск ошибки выглядит следующим образом (благодаря 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; 
} 

Модификации предложил Педро Кордейро позволяет отказаться от рекурсии, но также сделать имена полей недоступными.

+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_validation является FALSE по умолчанию, вы должны добавить его тоже родителя образует ($builder->add('propertyName', new YourFormNameType(), array('cascade_validation ' => true));) - See this