ZF-5412: Zend_Form_Element_MultiCheckBox::addError() array problem

Issue Type: Bug Created: 2009-01-06T05:00:53.000+0000 Last Updated: 2010-06-10T04:39:38.000+0000 Status: Resolved Fix version(s): - 1.9.5 (27/Oct/09)

Reporter: Tobias Petry (ice-breaker) Assignee: Matthew Weier O'Phinney (matthew) Tags: - Zend_Form

Related issues: - ZF-4915

Attachments: - patch5412.txt


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:

<pre class="literal">
$element = new Zend_Form_Element_MultiCheckBox('someVar');
$element->addMultiOptions(array('hello', 'world'))
        ->setLabel("Hello world")


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:

<pre class="literal">
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:

<pre class="literal">
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:

<pre class="highlight">
* Add an error message and mark element as failed validation
* @param  string $message
* @return Zend_Form_Element
public function addError($message)
   return $this;

Let's take a look at markAsError() function:

<pre class="highlight">
    $messages       = $this->getMessages();
    $customMessages = $this->_getErrorMessages();
    $messages       = $messages + $customMessages;
    if (empty($messages)) {
        $this->_isError = true;
    } else {
        $this->_messages = $messages;
    return $this;

The problem is in _getErrorMessages function. The resulting $message var, in case of Multi field will look like this:

<pre class="highlight">
$messages = array(
    0 => array(
        0 => 'My custom errormessage',
        1 => 'My custom errormessage',
        2 => 'My custom errormessage'

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

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.