Issues

ZF-5603: Zend_Form_Element_Multicheckbox / Multi throws warning, doesn't show errors after using errorMessages

Issue Type: Bug Created: 2009-01-21T15:29:04.000+0000 Last Updated: 2012-11-20T20:53:39.000+0000 Status: Closed Fix version(s): Reporter: Artur Bodera (joust) Assignee: None Tags: - Zend_Form

Related issues: - ZF-4915

Attachments:

Description

<pre class="highlight">
$form = new Zend_Form();
$form->addElements(array(
    array('multiCheckbox','foobar',array(
        'label' => 'Some label',
        'required' => true,
        'multiOptions' => array(
            '1'=>'Foo',
            '2'=>'bar',
        ),
        'errorMessages' => array('You have not selected anything!'),
    )),
));

With default decorators this will throw warning and will not show errors box.

<pre class="highlight">
 Warning: htmlspecialchars() expects parameter 1 to be string, array given in [...] system/library/Zend/View/Abstract.php on line 804
12  0.3047  2529936 Zend_Form->render( ??? )    ../%%8E^8E3^8E32E77A%%index.tpl.php:83
13  0.3068  2538848 Zend_Form_Decorator_FormElements->render( ??? ) ../Form.php:2595
14  0.3362  2601416 Zend_Form_Element->render( ??? )    ../FormElements.php:100
15  0.3462  2617836 Zend_Form_Decorator_Errors->render( ??? )   ../Element.php:1911
16  0.3463  2617836 Zend_View_Smarty->formErrors( ???, ??? )    ../Errors.php:60
17  0.3463  2617836 Zend_View_Abstract->__call( ???, ??? )  ../Abstract.php:0
18  0.3463  2617836 call_user_func_array ( ???, ??? )   ../Abstract.php:318
19  0.3464  2617836 Zend_View_Helper_FormErrors->formErrors( ???, ??? ) ../Abstract.php:0
20  0.3465  2618084 Zend_View_Abstract->escape( ??? )   ../FormErrors.php:79
21  0.3465  2618084 call_user_func ( ???, ???, ???, ??? )   ../Abstract.php:804

This is probably because isValid() tries to validate each value in "Multi" separately (!?) and then passes an array of errors to decorator.

Comments

Posted by Artur Bodera (joust) on 2009-01-22T03:13:05.000+0000

I've done some digging. I know what causes it...

At default, after setting required=>true the Multi field has Zend_Validator_NotEmpty attached to it. When form is validated, Zend_Form::isValid() function get's called, and with no checkboxes set it loops through fields with:

<pre class="highlight">
  foreach ($this->getElements() as $key => $element) {
            $element->setTranslator($translator);
            if (!isset($data[$key])) {
                $valid = $element->isValid(null, $data) && $valid;
            } else {
                $valid = $element->isValid($data[$key], $data) && $valid;
            }
        }

This one is crucial:

<pre class="highlight">
            if (!isset($data[$key])) {
                $valid = $element->isValid(null, $data) && $valid;

So the element is validated with null value. Then it goes to Zend_Form_Element::isValid() which on line 1325 does this:

<pre class="highlight">
if ($this->_hasErrorMessages()) {
      $messages = $this->_getErrorMessages();
      $errors   = $messages;
} else {

And here we are at Zend_Form_Element::_getErrorMessages() which is:

<pre class="highlight">
/**
     * Retrieve error messages and perform translation and value substitution
     *
     * @return array
     */
    protected function _getErrorMessages()
    {
        $translator = $this->getTranslator();
        $messages   = $this->getErrorMessages();
        $value      = $this->getValue();
        foreach ($messages as $key => $message) {
            if (null !== $translator) {
                $message = $translator->translate($message);
            }
            if ($this->isArray() || is_array($value)) {
                $aggregateMessages = array();
                foreach ($value as $val) {
                    $aggregateMessages[] = str_replace('%value%', $val, $message);
                }
                $messages[$key] = $aggregateMessages;
            } else {
                $messages[$key] = str_replace('%value%', $value, $message);
            }
        }
        return $messages;
    }

The error is at :

<pre class="highlight">
if ($this->isArray() || is_array($value)) {
                $aggregateMessages = array();
                foreach ($value as $val) {

As the Multi field always returns true for isArray() the $value of null is used in a foreach()

Posted by Artur Bodera (joust) on 2009-01-22T03:42:46.000+0000

This is very close to ZF-5412.

Posted by Thomas Hamacher (thamacher) on 2009-08-20T08:09:24.000+0000

This is exactly the same issue. I already posted a patch and a workaround for this.

Posted by Rob Allen (rob) on 2012-11-20T20:53:39.000+0000

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.

Have you found an issue?

See the Overview section for more details.

Copyright

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

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

Contacts