Question

I have a custom validator on my Symfony2 project. The validation works fine, but the method is somehow accessed twice.

Here is my custom validator: My other resolved question

The problem is the next: enter image description here

As you can see, the error message is displayed twice. When I am trying to var dump something in the validate method, the vardump is also displayed twice. Any idea why the validate is called twice? This is called when I am using $form->bind($request); in my controller.

EDIT

Here is the twig template:

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

And the controller call

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:

The validate function:

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);  
    }   
}

And the twig template:

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

Here is how I am applying the validator to the entity:

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

EDIT 4:

When I try to vardump the

$form->getErrors();

I am getting an array with two values:

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
  }
}
Was it helpful?

Solution

This is possible if you are using validation groups and apply validator to several groups. And what @IsDOI() annotation mean? If its apply validation possible that you first add validator in validation.yml and second via this custom annotation.

OTHER TIPS

The problem is that you're rendering it twice.

Here:

     {{ form_errors(form) }}

followed by:

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

Since you are displaying the errors in single place, I recommend using only the first method.

As stated in the form_errors twig reference:

form_errors(view)

Renders any errors for the given field.

{{ form_errors(form.name) }}

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

Since you have a lot of custom code (EntityManager, Validator) it is hard to tell the error with the amount of code you provide because it's not possible to recreate the error locally.

But here are my suggestions:

  1. In your Validator there are two possible cases the following violation gets thrown

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

    On both occasions the error message is the same. Maybe both of these cases apply. Try to debug this by adding an individual error message for both cases.

  2. I don't know the code of your Form-Class but maybe you apply your custom validator to multiple fields? Also remove validations for each field individually to see where the duplicate error message is thrown.

  3. One last mistake I can imagine would be a custom Form-Template. If you have one check whether or not you maybe call the {{ form_error(form) }} block or any other block multiple times.

I hope one of my suggestions did help you.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top