Issues

ZF-5150: addError() doesn't work as described.

Description

Zend_Form_Element::addError() has the following description: "Add an error message and mark element as failed validation". This implies that Zend_Form_Element::addError() also sets the element to fail validation. The method Zend_Form_Element::addErrorMessage() on the other hand has the following description: "Add a custom error message to return in the event of failed validation" Which seems to be a more accurate description of what Zend_Form_Element::addError() actually does. On another note, Zend_Form::addError() has the same description with the word "element" in them, which makes the matter even more confusing. Also, Zend_Form_Element::addError() calls Zend_Form_Element::markAsError() which has the following description: "Mark the element as being in a failed validation state". This leads me to believe that addError() was meant to actually make validation fail, but that doesn't seem to be the case.

Comments

Does anyone have a workaround for this issue for the present? The best I could make up was to make isValid in Form check to see if _errorsExist was true; if so, valid is set to false, else _errorsExist set to !valid. Otherwise there doesn't seem to be a check that would make sure that a user-set error (called by formObject->setError() and ->markAsError()) was noted. I haven't tested this with "regular" use cases, but I don't see why it shouldn't work unless someone sets the error state of the form independently (as we are trying to do).

I can't see a failure.

addError: Adds a error message and marks the element as being failed in any case (also when validation would be successfull) addErrorMessage: Adds a error message but the element is only being failed when the validation itself fails markAsError: Marks the element as being failed

By my understanding, if a form is marked as failed, it should not be valid i.e. - isValid should return false. However, it does not; it returns true no matter if it is marked failed or not; only a validator that has failed causes isValid to return false. Have I misunderstood the the idea of a "failed" form as being "invalid" as well?

I've been following this ticket for a while for the very same reason.

I'd like to have some way to easily add an error to a form element without having to write a full-blown validator. "addError" sounds like it would do exactly that, but apparently that is not the intention.

The documentation isn't clear enough for me to figure out what, exactly, "addError" is supposed to do. Probably because "failed" and "invalid" could mean the same thing or different things depending on who you ask.

To be honest the discussion is less about addError() than is about isValid. isValid checks the validators and sets _errorsExists to true or false solely based upon the validators and with no regard to the previous value of _errorsExists. This causes a problem because, should one have previously set the form as having an error, it is invalidated by isValid. Even more interesting is that the function isError (which I discovered yesterday, which returns the value of _errorsExists) is rendered impotent by a call to isValid. This suggests two scenarios.

  1. Every form must be validated by a validator only and no application logic.

  2. This is a bug.

Which is it? If the former, then why offer the ability to set the error state? Is it an issue of access by validators? If so, why not set access privileges to such functions as "protected", so as to prevent this issue?

It's a bug, and I will address it for the next release.

Do you know in which version it will be fixed ?

Cause the next release at the time of your postings was 1.8.0

I'm using ZF 1.8.4. Exists there a workaround for this bug ? Will this bug exist anymore in ZF 1.9.0 ?

Should now be resolved in trunk and 1.9 release branch. isValid() in both Zend_Form and Zend_Form_Element check to see if the element has been manually marked with errors, and, if so, fails validation.

Hey guys, Im not 100% sure if this has been resolved or maybe I am miss using the addError() method. Basicly, I've just done this as a quick test. It works as expected if you leave both fields blank. If you fill in the bottom field, and leave the top one blank, the message gets displayed. If you fill in both fields, isValid() fails as expected however the message is never displayed on the form?? If i call markAsError after isValid it gets displayed. if i call markAsError() before isValid, this just makes no difference.

All i want to be able to do , is add a custom condition, call addError('message') and have that message display on the form? That to me seams like a pretty easy thing to do but I just cant get it to work.

I just figure if i call addError, isValid will fail, and the message will be displayed? Its just odd, the custom message only gets displayed if some other kind of validation fails like the required 2nd field??

Any Ideas or work arounds would be great?

public function testAction() 
{
    $fld = new Zend_Form_Element_Text('bork');
    $fld->setLabel('Test Field');
    $fld->setRequired(true);

    $fld1 = new Zend_Form_Element_Text('zoot');
    $fld1->setLabel('Another Field');
    $fld1->setRequired(true);

    $form = new Zend_Form();
    $form->addElements(array($fld, $fld1, new Zend_Form_Element_Submit('break me')));

    if ($this->_request->isPost()) {

        $fld->addError('This should be Displayed!!');


        if ($form->isValid($this->_request->getParams())) {
            echo 'this is ok';
            die;
        }

        // You have to do this or the message wont display!!!!   
        //$fld->markAsError();
    }


    $this->view->form = $form;
}

Thanks Guys

Hey guys, By overriding the isValid method I can call parent::isValid($data) and then do any custom checks. Any calls to addError() after the parent::isValid actualy makes the form display the error. Still not sure if the above code i posted is a bug or desired?

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

    // do some custom validation, at least these messages get displayed on the form now.
    if (true) {
        $this->getElement('bork')->addError('Monkey Business');
        $valid = false;
    }

    return $valid;
}