3

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

这是我的自定义验证器:我的另一个已解决的问题

问题是下一个:在此处输入图像描述

如您所见,错误消息显示了两次。当我尝试在 validate 方法中转储某些内容时,vardump 也会显示两次。知道为什么 validate 被调用了两次吗?这是在我使用 $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(),
    ) );
}

编辑2:

验证功能:

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

3 回答 3

5

如果您使用验证组并将验证器应用于多个组,则这是可能的。@IsDOI()注释是什么意思?如果它可以应用验证,您首先validation.yml通过此自定义注释添加验证器,然后再添加验证器。

于 2013-07-19T13:43:43.683 回答
0

问题是你要渲染它两次。

这里:

     {{ form_errors(form) }}

其次是:

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

由于您在单个位置显示错误,因此我建议仅使用第一种方法。

form_errors 树枝参考中所述:

form_errors(查看)

呈现给定字段的任何错误。

{{ form_errors(form.name) }}

{# render any "global" errors #}
{{ form_errors(form) }}
于 2013-07-16T12:53:39.177 回答
0

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

但这里是我的建议:

  1. 在您的验证器中,有两种可能的情况会引发以下违规行为

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

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

  2. 我不知道您的Form -Class 的代码,但也许您将自定义验证器应用于多个字段?还要单独删除每个字段的验证,以查看抛出重复错误消息的位置。

  3. 我能想象的最后一个错误是自定义Form-Template。如果您有一个检查,您是否可以{{ form_error(form) }}多次调用该块或任何其他块。

我希望我的一个建议对你有所帮助。

于 2013-07-17T13:47:54.513 回答