Issues

ZF-4915: multiCheckbox (_getErrorMessages()) fails if configuring custom validation message

Description

If user checks no options for a multiCheckbox element and a custom validation message is configured, the _getErrorMessages() function generates a warning and fails to return the custom message. The line that fails is " foreach ($value as $val)" because $value is set to null.

Made the following change to get around the problem: if (($this->isArray() || is_array($value)) && !empty($value)) {

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)) && !empty($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;
}

Comments

I have also ran into this issue when trying to implement a custom error message. Are there any plans to fix this issue, or am I assigning the error message in an incorrect way?

$element = $this->createElement('MultiCheckbox', 'checkbox'); $element->addErrorMessage('Foo');

Here is a patch for Zend/Form/Element.php

Pleas fix this ASAP

The suggested patch from Nils is broken. As far as i can see the logic should be the same as in the Element::getValue() method. I've added a proper patch.

As a workaround you can derive the MultiCheckbox and implement the _getErrorMessages() method on your own, until the error is fixed.

Here is a code snippet that shows a very similar issue that occurs when adding a custom error message to a multi select. In this case, _getErrorMessages returns an array with an extra dimension, which causes a Warning when the FormErrors View Helper tries to escape each error message:

<?php set_include_path(get_include_path() . PATH_SEPARATOR . 'library');

include('Zend/Form/Element/Multiselect.php'); include('Zend/View.php'); include('Zend/Version.php');

echo ("Zend_Version: " . Zend_Version::VERSION . "\n\n");

echo "PRINTING CONTROL ELEMENT:\n\n";

$control = new Zend_Form_Element_Multiselect('control');

$control->addMultiOptions( array( 1 => 'One', 2 => 'Two', 3 => 'Three', ) );

$control->isValid(array(1,4));

echo $control->render(new Zend_View());

echo "\n\nPRINTING BUG ELEMENT:\n\n";

$bug = new Zend_Form_Element_Multiselect('bug');

$bug->addMultiOptions( array( 1 => 'One', 2 => 'Two', 3 => 'Three', ) );

$bug->addErrorMessage('%value% is invalid');

$bug->isValid(array(1,4));

echo $bug->render(new Zend_View());

Any news on this?

The report and diagnosis are both incorrect. What happens is that the FormErrors view helper fails because the value passed to escape() is an array, not a string.

What needs to be done is to flatten the errors within _getErrorMessages() so that we don't get multiple error messsages per validator.

Resolved in trunk and 1.9 release branch. See r18554 for details on how it was accomplished.

Thank you! :-)