自定义验证器访问两次

时间:2013-07-16 09:31:12

标签: php symfony dependency-injection customvalidator

我的Symfony2项目上有自定义验证器。 验证工作正常,但该方法以某种方式访问​​了两次。

这是我的自定义验证器:My other resolved question

问题是下一个:enter image description here

如您所见,错误消息显示两次。当我在validate方法中尝试var转储时,vardump也会显示两次。知道为什么两次调用验证?当我使用$ form-> bind($ request)时调用它;在我的控制器里。

修改

这是树枝模板:

{% 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:

验证功能:

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 %}

编辑3:

以下是我将验证器应用于实体的方法:

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

编辑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
  }
}

3 个答案:

答案 0 :(得分:4)

如果您使用validation groups并将验证器应用于多个组,则可以执行此操作。 @IsDOI()注释是什么意思?如果可以应用验证,则首先在validation.yml中添加验证器,然后通过此自定义注释添加验证器。

答案 1 :(得分: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) }}

答案 2 :(得分:0)

由于您有很多自定义代码(EntityManager,Validator),很难用您提供的代码量来判断错误,因为无法在本地重新创建错误。

但这是我的建议:

  1. 验证程序中,有两种情况可能会引发以下违规行为

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

    在两种情况下,错误消息都是相同的。也许这两种情况都适用。尝试通过为两种情况添加单独的错误消息来调试

  2. 我不知道您的表单类的代码,但是您可能将自定义验证器应用于多个字段?还要单独删除每个字段的验证,以查看引发重复错误消息的位置。

  3. 我能想到的最后一个错误是自定义表单模板。如果您有一个检查是否可以多次调用{{ form_error(form) }}块或任何其他块。

  4. 我希望我的一条建议对您有所帮助。