我的Symfony2项目上有自定义验证器。 验证工作正常,但该方法以某种方式访问了两次。
这是我的自定义验证器:My other resolved question
问题是下一个:
如您所见,错误消息显示两次。当我在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>
</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]=>
object(Symfony\Component\Form\FormError)#507 (4) {
["message":"Symfony\Component\Form\FormError":private]=>
string(77) "The Publisher DOI abbreviation does not correspond to the DOI you filled in !"
["messageTemplate":protected]=>
string(77) "The Publisher DOI abbreviation does not correspond to the DOI you filled in !"
["messageParameters":protected]=>
array(0) {
}
["messagePluralization":protected]=>
NULL
}
[1]=>
object(Symfony\Component\Form\FormError)#542 (4) {
["message":"Symfony\Component\Form\FormError":private]=>
string(77) "The Publisher DOI abbreviation does not correspond to the DOI you filled in !"
["messageTemplate":protected]=>
string(77) "The Publisher DOI abbreviation does not correspond to the DOI you filled in !"
["messageParameters":protected]=>
array(0) {
}
["messagePluralization":protected]=>
NULL
}
}
答案 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),很难用您提供的代码量来判断错误,因为无法在本地重新创建错误。
但这是我的建议:
在验证程序中,有两种情况可能会引发以下违规行为
$this->context->addViolation($constraint->message_publisher_DOI);
在两种情况下,错误消息都是相同的。也许这两种情况都适用。尝试通过为两种情况添加单独的错误消息来调试。
我不知道您的表单类的代码,但是您可能将自定义验证器应用于多个字段?还要单独删除每个字段的验证,以查看引发重复错误消息的位置。
我能想到的最后一个错误是自定义表单模板。如果您有一个检查是否可以多次调用{{ form_error(form) }}
块或任何其他块。
我希望我的一条建议对您有所帮助。