2013-07-16 3 views
3

У меня есть собственный валидатор в моем проекте Symfony2. Проверка достоверности, но метод как-то обращается дважды.Пользовательский валидатор обратился дважды

Вот мой валидатора: My other resolved question

Проблема заключается в следующем: enter image description here

Как вы можете видеть, отображается сообщение об ошибке дважды. Когда я пытаюсь var dump что-то в методе validate, vardump также отображается дважды. Любая идея, почему валидат вызывается дважды? Это вызывается, когда я использую $ form-> bind ($ request); в моем контроллере.

EDIT

Вот шаблон веточка:

{% extends 'MerrinMainBundle::layout.html.twig' %} 

{% block page_title %} 
MDPI Conversion system (Merrin) 3.0 - New Conversion 
{% endblock %} 

{% block main %} 
{% for flashMessage in app.session.flashbag.get('user-notice') %} 
    <div class="flash-notice"> 
     {% autoescape false %} 
     {{ flashMessage }} 
     {% endautoescape %} 
    </div> 
{% endfor %} 
<h1>Create New Manuscript</h1> 
{% if valid == false %} 
     <div class="error"> 
     {{ form_errors(form) }} 
     {{ form_errors(form.doi) }} 
      {{ form_errors(form.publisher) }} 
      {{ form_errors(form.file) }} 
     </div> 
    {% endif %} 

    <form action="{{ path }}" method="POST" {{ form_enctype(form) }}> 
    </form> 

{% endblock %} 

И вызов контроллер

public function createAction() 
{  
    $em_scipub  = $this->getDoctrine()->getManager(); 
    $em_mdpipub  = $this->getDoctrine()->getManager('mdpipub'); 

    $enquiry = new Manuscript(); 

    $formType = new NewManuscriptType(); 
    $form  = $this->createForm($formType, $enquiry); 

    $request = $this->getRequest(); 
    $valid  = true; 
    $error  = ''; 

    if ($request->isMethod('POST')) { 

     $form->bind($request); 

     if ($form->isValid()) { 

      ... do something ... 

      $em_scipub->persist($enquiry); 

      $em_scipub->flush(); 

      $flash_message = "<a href='edit/".$enquiry->getId()."'>New Manuscript</a> sucessfully created."; 

       $this->get('session')->getFlashBag()->set('user-notice', $flash_message); 

       return $this->redirect($this->generateUrl('MerrinMainBundle_new')); 
     } 
     else 
      $valid = false; 
    } 

    $path = $this->generateUrl('MerrinMainBundle_new'); 

    return $this->render('MerrinMainBundle:Pages:new_conversion.html.twig.twig', array(
      'valid' => $valid, 
      'path' => $path, 
      'form' => $form->createView(), 
    )); 
} 

EDIT2:

Функция Validate:

public function validate($value, Constraint $constraint) 
{  
    $doi = $value->getDoi(); 

    preg_match('/[^\/]+/i', $doi, $publisherDoiAbbr); 
    if($publisherDoiAbbr[0] !== $value->getPublisher()->getDoiAbbreviation()) { 
     $this->context->addViolation($constraint->message_publisher_DOI); 
    } 
    else { 
     preg_match("/[a-z]+/",$doi, $journalDoiAbbr); 

     $em_mdpipub = $this->entityManager; 
     $journal = $em_mdpipub->getRepository('MerrinMdpiPubBundle:Journal')->findOneBy(array('doi_abbreviation' => $journalDoiAbbr)); 

     if($journal == null) { 
      $this->context->addViolation($constraint->message_journal_DOI); 
     } 
    } 

    preg_match('/\d*$/i', $doi, $doiNumericPart); 
    if(strlen($doiNumericPart[0]) < 8) { 
     $this->context->addViolation($constraint->message_volume_issue_firstpage_DOI); 
    } 
} 

И шаблон веточка:

{% extends 'MerrinMainBundle::layout.html.twig' %} 

{% block page_title %} 
MDPI Conversion system (Merrin) 3.0 - New Conversion 
{% endblock %} 

{% block main %} 
{% for flashMessage in app.session.flashbag.get('user-notice') %} 
<div class="flash-notice"> 
    {% autoescape false %} 
    {{ flashMessage }} 
    {% endautoescape %} 
</div> 
{% endfor %} 
<h1>Create New Manuscript</h1> 
{% if valid == false %} 
     <div class="error"> 
      {{ form_errors(form) }} 
      {{ form_errors(form.doi) }} 
      {{ form_errors(form.publisher) }} 
      {{ form_errors(form.file) }} 
     </div> 
    {% endif %} 

    <form action="{{ path }}" method="POST" {{ form_enctype(form) }}> 
     <div style="float:left;"> 
      <table width="700"> 
       <tr> 
        <td> 
         {{ form_label(form.doi) }} 
        </td> 
        <td> 
         {{ form_widget(form.doi, { 'attr': {'size': 40} }) }} 
        </td> 
       </tr> 
       <tr> 
        <td> 
         {{ form_label(form.publisher) }} 
        </td> 
        <td> 
         {{ form_widget(form.publisher) }} 
        </td> 
       </tr> 
       <tr> 
        <td> 
         {{ form_label(form.file) }} 
        </td> 
        <td> 
         {{ form_widget(form.file) }} 
        </td> 
       </tr> 
       <tr> 
        <td> 
         &nbsp; 
        </td> 
        <td> 
         <input class="submit-confirm-button" type="submit" name="update-text" value="submit" /> 
         <a class="cancel-link" href="{{ path('MerrinMainBundle_homepage') }}">Cancel</a> 
        </td> 
       </tr> 
      </table> 
     </div> 
     {{ form_rest(form) }} 
    </form> 
{% endblock %} 

EDIT 3:

Вот как я подаю валидатор к объекту:

/** 
* Manuscript 
* 
* @IsDOI() 
* @ORM\Table(name="manuscripts") 
* @ORM\Entity(repositoryClass="Merrin\MainBundle\Repository\ManuscriptRepository") 
* @ORM\HasLifecycleCallbacks 
* 
*/ 
class Manuscript 
{ 
.... 
} 

EDIT 4 :

Когда я пытаюсь vardump в

$form->getErrors(); 

я получаю массив с двумя значениями:

array(2) { 
    [0]=&gt; 
    object(Symfony\Component\Form\FormError)#507 (4) { 
    ["message":"Symfony\Component\Form\FormError":private]=&gt; 
    string(77) "The Publisher DOI abbreviation does not correspond to the DOI you filled in !" 
    ["messageTemplate":protected]=&gt; 
    string(77) "The Publisher DOI abbreviation does not correspond to the DOI you filled in !" 
    ["messageParameters":protected]=&gt; 
    array(0) { 
    } 
    ["messagePluralization":protected]=&gt; 
    NULL 
    } 
    [1]=&gt; 
    object(Symfony\Component\Form\FormError)#542 (4) { 
    ["message":"Symfony\Component\Form\FormError":private]=&gt; 
    string(77) "The Publisher DOI abbreviation does not correspond to the DOI you filled in !" 
    ["messageTemplate":protected]=&gt; 
    string(77) "The Publisher DOI abbreviation does not correspond to the DOI you filled in !" 
    ["messageParameters":protected]=&gt; 
    array(0) { 
    } 
    ["messagePluralization":protected]=&gt; 
    NULL 
    } 
} 
+0

Можете ли вы опубликовать «шаблон твига» и «действие контроллера»? – ferdynator

+0

@ byf-ferdy, обязательно, я отредактирую свой вопрос. –

+0

также покажите нам определение валидации и код для пользовательского валидатора. Также, пожалуйста, разместите полную версию шаблона ветки, на всякий случай – saamorim

ответ

4

Это возможно, если вы используете validation groups и применяете валидатор для нескольких групп. А что значит @IsDOI() аннотация? Если это применит проверку, возможно, что вы сначала добавите валидатор в validation.yml и второй через эту пользовательскую аннотацию.

+1

Отлично @forgottenbas, большое вам спасибо. Фактически, я добавлял валидацию в validation.yml, а также в Entity как @IsDOI(), поэтому я дважды проверял. Я понял, что нам нужно добавить валидатор в обоих местах, а не то, что плакет является опциональным. –

+0

Дай мне щедрость? :) –

+0

Готово, наслаждайся ... :) –

0

Проблема заключается в том, что вы делаете его в два раз.

Здесь:

 {{ form_errors(form) }} 

следуют:

 {{ form_errors(form.doi) }} 
    {{ form_errors(form.publisher) }} 
    {{ form_errors(form.file) }} 

Поскольку вы показываете ошибки в одном месте, я рекомендую использовать только первый метод.

Как указано в form_errors twig reference:

form_errors (вид)

Визуализирует какие-либо ошибки для данного поля.

{{ form_errors(form.name) }} 

{# render any "global" errors #} 
{{ form_errors(form) }} 
+0

Спасибо, saamorim. Итак, теоретически, если я удалю все form_errors, кроме frist one: '{{form_errors (form)}}', я должен ошибка только один раз. К сожалению, это не так. Есть идеи? –

+0

попытайтесь отладить ошибки формы, чтобы увидеть, какая из них вызывает ошибку. Используете ли вы [error_bubbling] (http://symfony.com/doc/current/reference/forms/types/text.html#error-bubbling)? – ferdynator

+0

@Saamorim - По умолчанию глобальные ошибки не будут отображаться в полевых ошибках, так что проблема будет в другом месте –

0

Поскольку у вас есть много пользовательского кода (EntityManager, Validator), трудно сказать, ошибка с количеством кода вы предоставляете, потому что это не представляется возможным воссоздать ошибку локально.

Но вот мои предложения:

  1. В вашем валидатора есть два возможных случая следующее нарушение выкинут

    $this->context->addViolation($constraint->message_publisher_DOI); 
    

    В обоих случаях сообщение об ошибке одно и то же , Возможно, оба эти случая применяются. Попробуйте выполнить debug, добавив отдельное сообщение об ошибке для обоих случаев.

  2. Я не знаю код вашего Форма -Класс, но, возможно, вы применяете свой собственный валидатор для нескольких полей? Также удалите проверки для каждого поля отдельно, чтобы увидеть, где выбрано дублирующееся сообщение об ошибке.

  3. Одна из последних ошибок, которые я могу себе представить, будет таможней Форма-шаблон. Если у вас есть одна проверка, можете ли вы несколько раз позвонить в блок {{ form_error(form) }} или любой другой блок.

Я надеюсь, что одно из моих предложений действительно помогло вам.

+0

Спасибо, Ф-Ферди. Некоторые комментарии: 1. В моем валидаторе '$ this-> context-> addViolation ($ constraint-> message_publisher_DOI);' используется только один раз, а не дважды. Я также упомянул, что метод Validate вызывает по какой-то причине дважды, поэтому этот метод в порядке. 2. Пользовательский валидатор применяется к классу Entity, а не к полю. 3. '{{form_error (form)}}' вызывается только один раз. –

+0

@Milos справедливые точки. Где вы применяете ** Validator ** к ** Entity **? – ferdynator

+0

валидатор применяется в самой сущности, я редактирую свой вопрос с самого начала сущности. –

Смежные вопросы