ZF-5412: Zend_Form_Element_MultiCheckBox::addError() array problem
Description
If you try to add an error to a Zend_Form_Element_MultiCheckBox element an php warning will occur: {quote}Warning: Invalid argument supplied for foreach() in ........\library\Zend\Form\Element.php on line 2101{quote}
You can reproduce the error by executing this little snippet:
$element = new Zend_Form_Element_MultiCheckBox('someVar');
$element->addMultiOptions(array('hello', 'world'))
->setLabel("Hello world")
->setRequired(false)
->addError('someError');
Comments
Posted by Tobias Petry (ice-breaker) on 2009-01-06T05:04:53.000+0000
There has been a bug in addError some time ago, which affected Zend_Element::addError (#ZF-3852). Don't know if this is a help for anybody.
Posted by Tobias Petry (ice-breaker) on 2009-01-06T05:21:20.000+0000
The codeblock of the library is the following:
if ($this->isArray() || is_array($value)) { $aggregateMessages = array(); foreach ($value as $val) { $aggregateMessages[] = str_replace('%value%', $val, $message); } $messages[$key] = $aggregateMessages; }The problem seems to be the if-clause. isArray is true, but $value is an empty string, when i run my snippet from above. So the source tries to iterate a string, which does not work and the php-warning for the for-each-loop is thrown. I changed the if-clause to make an AND instead of an OR and it does work:
if ($this->isArray() && is_array($value)) { $aggregateMessages = array(); foreach ($value as $val) { $aggregateMessages[] = str_replace('%value%', $val, $message); } $messages[$key] = $aggregateMessages; }So now, has $value to be an array if we want to loop. It does work, but i don't know if i break something different, but i can't image it, because value HAS TO BE an array for iterating.
Posted by Artur Bodera (joust) on 2009-01-22T03:01:15.000+0000
This also breaks when using {{addErrorMessages()}} So there is no good way to display errors with this field.
See also: ZF-5603
Posted by Artur Bodera (joust) on 2009-01-22T03:44:50.000+0000
When using {{addErrorMessages()}} the bug is in {{Zend_Form_Element::_getErrorMessages()}}.
When we add error with {{Zend_Form_Element::addError()}} the following is executed:
Let's take a look at {{markAsError()}} function:
The problem is in {{_getErrorMessages}} function. The resulting {{$message}} var, in case of {{Multi}} field will look like this:
It's structure is unknown for {{Zend_View_Helper_FormErrors}}, therefore there are errors.
I strongly suggest to give full control over the method of validating {{Multi}} elements! As for now validators are run on each and every selected value, but there is no way to validate THE WHOLE FIELD, nor give it a GLOBAL SINGLE custom error message. Current architecture does NOT allow i.e. to create a {{Zend_Validate_Count}} which would throw error if less (or more) number of fields have been selected.
Posted by Tobias Petry (ice-breaker) on 2009-05-05T04:09:24.000+0000
This patch resolves the problem.
Posted by Tobias Petry (ice-breaker) on 2009-09-11T16:18:37.000+0000
added new patch with unit tests.
current Zend_Form trunk is defect, test with 1.9.2 final, it's working with no side effects.
Posted by Tobias Petry (ice-breaker) on 2010-06-10T04:39:34.000+0000
fixed with #ZF-4915