ZF-5559: Zend_Form::isErrors() could check for errors on the fly

Description

At the end of isValid(), _errorsExist is set based on the return value. isErrors() then returns the value of _errorsExist.

What I find a common usage pattern is to override isValid() in many forms to add an additional check or two, without having to write a validator which I would only use once anyways. Something like this


    public function isValid($data)
    {
        $valid = parent::isValid($data);

        // Check that password and passwordConfirmation match
        if ($this->password->getValue() !== $this->passwordConfirmation->getValue()) {
            $this->passwordConfirmation->addErrorMessage('Not the same as password.')->markAsError();
            $valid = false;
        }

        return $valid;
    }

Now imagine the passwords don't match. The call to isValid() will return false, as expected. However, if you subsequently call $form->isErrors(), it will return FALSE (i.e., "no errors").

The reason for this is that _errorsExist is set in the base class, before everything was validated (in the derived class).

Of course, I could have called $this->markAsError() manually, but IMO isErrors() should always return true if a previous call to isValid() returned false, for the sake of consistency, like it does with the base class.

Therefore I propose, if there aren't other problems that I'm missing, that isErrors() is reworked to something like this:


    /**
     * Are there errors in the form?
     * 
     * @return bool
     */
    public function isErrors()   
    {
        $errors = $this->_errorsExist;

        if (!$errors) {
            foreach ($this->getElements() as $key => $element) {
                if ($element->hasErrors())
                    $errors = true;
                    break;
                }
            }
        }

        return $errors;
    }

This way if form is markAsError()'d manually it will still return that is has errors (even if the validators didn't report one), but it will never say that it doesn't have errors when isValid() reports it does.

Comments

I second that issue (I just ran into that strange behaviour of Zend_Form). I would also file it as a bug instead of a simple improvement.

To complete Jaka Jancar's fix, I would also add a loop to check for sub forms :{


foreach ($this->getSubForms() as $key => $subForm) {
                if ($subForm->isErrors()) {
                    $errors = true;
                    break;
                }
            }
{

Bulk change of all issues last updated before 1st January 2010 as "Won't Fix".

Feel free to re-open and provide a patch if you want to fix this issue.