ZF2-443: breakChainOnFailure

Description

In my form I have a single text field asking for an email address and attached is this filter -> http://pastebin.com/Layp35J3

When the form is submitted with a test email address of test@example.com! It fails, which is expected. But it returns multiple errors instead of a single error.

I've attempted to add the following on the same level of the validator name and option:

'break_chain_on_failure' => true 'breakChainOnFailure' => true true

All three options all result in the same problem, the chain is not broken.

Here is the JSON return: {"form_messages":{"primary_email":{"emailAddressInvalidHostname":"\u0027example.com!\u0027 is not a valid hostname for the email address","hostnameUnknownTld":"The input appears to be a DNS hostname but cannot match TLD against known list","hostnameInvalidLocalName":"The input does not appear to be a valid local network name"}}}

IRC: weierophinney, thought perhaps it could have been the 'required' => true statement as the breakonchain would need to be acted upon there too. So I removed that line completely and also tried 'required' => false but the same situation happens.

Comments

You are getting multiple messages from the same validator. The email validator is failing and giving you 3 errors as to why it failed. Then it stops the validator chain and does not continue. I believe this is the correct behavior.

Does that make sense?

I believe what you mentioned is correct. I'll explain a little further just so we are clear. Firstly I'd like to reference ZF1 just so we are on the same page -> http://pastebin.com/6VRGULa8

Notice all the TRUE statements after each validator. In ZF1 this would break the chain and return only 1 error message, regardless of how many validators exist. Using this example if you entered a value but it did not meet the regex and the stringlength then only the regex error would be displayed. Then if you meet the requirements of the regex then the stringlength error would show.

So now in ZF2 I'd like to do the same thing. So using the EmailValidator you mentioned as an example. It is currently returning more than one error for that validator. I would like to only return one error message. Then once the form is submitted again, if there is another check that failed for EmailValidator, it would return only that error.

So instead of multiple errors being returned on a formfield, I'd like only one. It would continue this way until all validators are happy.

Yeah, I get exactly what you're saying. Actually ZF1 DOES work this way. Zend_Validate_EmailAddress in the above example would return an array(3) with three error messages and stop the chain. Just like in ZF2.

Try running the following test in ZF1 and seeing what the var_dump shows:


/**
 * Ensures that a validator may break the chain
 *
 * @return void
 */
public function testBreakChainOnFailure2()
{
    $this->_validator->addValidator(new Zend_Validate_StringLength(array(
        'encoding'  => 'UTF-8',
        'min'       => 5,
        'max'       => 320
    )), true);
    $this->_validator->addValidator(new Zend_Validate_EmailAddress(), true);
    $this->assertFalse($this->_validator->isValid('test@example.com!'));
    var_dump($this->_validator->getMessages());
}

Well snap, I guess I never even noticed it before. What a game changer haha!

Alright, before I close this out can you give me an example on the proper way to breakchain the zf2 way? I may be a little confused on the proper syntax / area to put this ability. I'm unclear if this goes in the options, attributes, or on a whole new level. I appreciate it and thank you for setting me straight. This was bugging me but now I see my errors =)

Hey Sammie, no problem.

That's kind of a loaded question. ;-) As with many things in ZF, there are a few ways to accomplish this. Take a look at the end-user documentation for breaking validator chains. http://packages.zendframework.com/docs/latest/…

Good luck!

I really don't enjoy reopening an issue but I took your advice and created this -> http://pastebin.com/SBbfs5Vx

I added the TRUE statements to break the chain. But when I enter a single alpha character. I am returning a validator of StringLength is less than 2 characters and also string must be a digit.

I would have expected to only return the StringLength error due to the break in chain.

As an additional test I looked at the ValidatorChain.php file in Zend and changed all the $breakChainOnFailure = false to $breakChainOnFailure = true. This way in case it was a setting on my side it wouldn't matter as now I'm forcing it from the source to breakchain. But the same error situation is happening.

Sammie,

This really isn't the place to ask questions like this. As far as I can see, this STILL isn't a bug.

The correct way to break chain on failure with your provided code is: http://pastebin.com/qchQ3Qwz

Hope that helps.

John