ZF-9002: Warning on form validation

Issue Type: Bug Created: 2010-01-28T15:34:02.000+0000 Last Updated: 2010-05-29T09:26:09.000+0000 Status: Resolved Fix version(s): Reporter: Stewart Lord (stewartlord) Assignee: Christian Albrecht (alab) Tags: - Zend_Form

Related issues: - ZF-4030



This is essentially a re-open of ZF-4030. I could not find a way to change the status of that issue.

Zend_Form_Decorator_Errors produces PHP warnings and erroneous output if $element->getMessages() produces a multi-dimensional array of errors instead of a single-dimensional array of messages. This will happen if the Errors decorator is attached to a form and the form has no form-level errors (e.g. messages added via addError()), but does contain elements with errors.

Suggested fix is to remove errors that are not strings:

Zend_Form_Decorator_Errors (line 53):

    // remove errors that are not strings.
    $errors = $element->getMessages();
    foreach ($errors as $key => $error) {
        if (!is_string($error)) {

The crux of the problem is actually the behaviour of Zend_Form::getMessages(), but that would be difficult to resolve and may break BC.


Posted by Matthew Weier O'Phinney (matthew) on 2010-01-29T04:40:43.000+0000

Why are you using the Errors decorator on a form object instead of the FormErrors decorator (which was designed specifically for handling the multi-dimensional arrays returned by Zend_Form::getMessages())?

Right now, it feels like you're using the wrong tool for the job. However, if you have a good reason for this and can detail the use case sufficiently, I'll investigate further.

Posted by Stewart Lord (stewartlord) on 2010-01-29T09:29:30.000+0000

Fair question. The FormErrors decorator has different behavior. It displays all of the implicit errors on a form (e.g. errors on the elements of the form). It does not display errors that are directly attached to the form (e.g. errors set explicitly via $form->addError()).

In this case, I want to display element errors on the elements, but form-level errors at the top of the form. The proposed fix allows the errors decorator to be used on both elements and forms. In my case it produces the desired behavior. It's also defensive which is probably good.

Posted by Stewart Lord (stewartlord) on 2010-01-29T09:33:44.000+0000

...It is probably worth noting that the getMessages() method of the Zend_Form object contributes to the problem because it has a bit of a split personality. In the case where errors have been explicitly set on the form it will return a single-dimensional array and will not include any of the implicit/element errors. If, however, the form does not have explicit errors, but does have elements with errors, it will return a multi-dimensional array.

In the first case, the standard Errors decorator works fine on forms. In the second case it produces warnings and erroneous output.

Hope that helps!

Posted by Matthew Weier O'Phinney (matthew) on 2010-01-29T11:07:00.000+0000

Stewart -- thanks for clarifying. I'll look into the behavior this coming month.

In the meantime, can you provide an example form that displays the issue? That will make writing up a test case easier. Thanks!

Posted by Stewart Lord (stewartlord) on 2010-01-29T11:53:23.000+0000

Sure, np...

This works fine:

    $form = new Zend_Form;
    $form->setView(new Zend_View);
    echo $form;

This breaks:

    $form = new Zend_Form;
    $form->setView(new Zend_View);
    echo $form;

FormErrors doesn't solve the problem because it won't show 'form-badness', only 'element-badness':

    $form = new Zend_Form;
    $form->setView(new Zend_View);
    echo $form;

Posted by Christian Albrecht (alab) on 2010-05-24T09:10:01.000+0000

This is fixed in trunk r22272 and merged into 1.10 release branch, in a way that FormErrors now render custom form errors.

Posted by Stewart Lord (stewartlord) on 2010-05-28T18:06:35.000+0000

Hi Christian, does the Errors decorator still produce warnings? Having FormErrors display both element-level errors and form level errors is not necessarily desirable. Consider the use case where you want form-level errors displayed at the top of the form, and element-level errors display next to the element.

Posted by Christian Albrecht (alab) on 2010-05-29T03:09:48.000+0000

Hi Stewart, uhh yes the Errors Decorator still produces a warning about htmlspecialchar getting wrong parameter type - look into it right after writing. For the FormErrors i introduced two more options showCustomFormErrors = (bool) & onlyCustomFormErrors (bool) as you can see in r22272, is it that what you meant?

Thanks for taking me back to that one :) don't know what i was doing, now there is a fix for the previous commit r22316 that does what i expected it to do.

Posted by Christian Albrecht (alab) on 2010-05-29T04:17:46.000+0000

So finally i think you can go with

<pre class="highlight">
$form->addDecorator('FormErrors', array('onlyCustomFormErrors' => true))

No more need to set Errors Decorator on the form :D

Posted by Christian Albrecht (alab) on 2010-05-29T04:23:33.000+0000

Now we may discuss if the default setting for onlyCustomFormErrors should be true instead of false.

Posted by Stewart Lord (stewartlord) on 2010-05-29T09:26:08.000+0000

Hi Christian, thanks for the follow-up. Those options are helpful. Yes, given that elements have the 'Errors' decorator by default, I think that onlyCustomFormErrors should be set to true initially.

Although the Errors decorator is no longer needed at the form-level, it might still be a good idea to apply the patch from the original description above. It's defensive and if someone attaches the Errors decorator to a form it will work. It's not obvious that you need one decorator for elements and another for the form.

Have you found an issue?

See the Overview section for more details.


© 2006-2018 by Zend, a Rogue Wave Company. Made with by awesome contributors.

This website is built using zend-expressive and it runs on PHP 7.