3

Symfony2 プロジェクトにカスタム バリデーターがあります。検証は正常に機能しますが、メソッドは何らかの理由で 2 回アクセスされます。

これが私のカスタムバリデータです:私の他の解決された質問

問題は次です。ここに画像の説明を入力

ご覧のとおり、エラー メッセージが 2 回表示されます。検証メソッドで何かを var ダンプしようとすると、vardump も 2 回表示されます。検証が2回呼び出される理由は何ですか? これは、$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();

2 つの値を持つ配列を取得しています。

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

問題は、それを 2 回レンダリングしていることです。

ここ:

     {{ form_errors(form) }}

に続く:

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

エラーを 1 か所に表示しているため、最初の方法のみを使用することをお勧めします。

form_errors twig リファレンスに記載されているとおり:

form_errors(表示)

指定されたフィールドのエラーを表示します。

{{ form_errors(form.name) }}

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

多くのカスタム コード (EntityManager、Validator) があるため、ローカルでエラーを再現することはできないため、提供するコードの量でエラーを特定するのは困難です。

しかし、ここに私の提案があります:

  1. Validatorには、次の違反がスローされる 2 つのケースが考えられます。

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

    どちらの場合も、エラー メッセージは同じです。たぶん、これらの両方のケースが当てはまります。両方のケースに個別のエラー メッセージを追加して、これをデバッグしてみてください。

  2. あなたのForm -Class のコードはわかりませんが、カスタムバリデーターを複数のフィールドに適用しているのではないでしょうか? また、各フィールドの検証を個別に削除して、重複したエラー メッセージがスローされる場所を確認します。

  3. 私が想像できる最後の間違いは、カスタムForm-Templateです。{{ form_error(form) }}1 つある場合は、ブロックまたは他のブロックを複数回呼び出す可能性があるかどうかを確認してください。

私の提案の1つがお役に立てば幸いです。

于 2013-07-17T13:47:54.513 に答える