Zend проверить множественный выбор значения - PullRequest
2 голосов
/ 29 июля 2011

Существует многоэлементный элемент в форме. Необходимо проверить, сколько элементов выбрано в нем (минимальное и максимальное количество).

Проблема в том, что когда элемент может иметь несколько значений, каждое значение проверяется отдельно.

Я попытался установить isArray на false, чтобы проверить значение с помощью моего пользовательского валидатора ArraySize, но появилась новая проблема: все значение массива передается в InArray валидатор, и проверка не удалась. Поэтому мне пришлось отключить его, установив registerInArrayValidator в false.

Теперь я могу проверить значение для количества выбранных значений, но не могу проверить их соответствие предоставленным параметрам.

Есть ли способ решить проблему без создания еще одного пользовательского валидатора?

Ответы [ 2 ]

0 голосов
/ 14 июля 2015

Примечание: я предполагаю, что это Zend 1.

Единственный способ сделать это - расширить Multiselect и использовать собственный isValid. Таким образом, вы можете видеть полный массив значений, а не только одно значение за раз.

Ниже приведен мой класс Multiselect

<?php
/**
 * My_MinMaxMultiselect
 */
class My_MinMaxMultiselect extends Zend_Form_Element_Multiselect
{
    /**
     * Validate element contains the correct number of
     * selected items. Check value against minValue/maxValue
     *
     * @param mixed $value
     * @param mixed $context
     * @return boolean
     */
    public function isValid($value, $context = null)
    {
        // Call Parent first to cause chain and setValue
        $parentValid = parent::isValid($value, $context);

        $valid = true;

        if ((('' === $value) || (null === $value))
            && !$this->isRequired()
            && $this->getAllowEmpty()
        ) {
            return $valid;
        }

        // Get All Values
        $minValue = $this->getMinValue();
        $maxValue = $this->getMaxValue();

        $count = 0;
        if (is_array($value)) {
            $count = count($value);
        }

        if ($minValue && $count < $minValue) {
            $valid = false;
            $this->addError('The number of selected items must be greater than or equal to ' . $minValue);
        }

        if ($maxValue && $count > $maxValue) {
            $valid = false;
            $this->addError('The number of selected items must be less than or equal to ' . $maxValue);
        }

        return ($parentValid && $valid);
    }

    /**
     * Get the Minimum number of selected values
     *
     * @access public
     * @return int
     */
    public function getMinValue()
    {
        return $this->getAttrib('min_value');
    }

    /**
     * Get the Maximum number of selected values
     *
     * @access public
     * @return int
     */
    public function getMaxValue()
    {
        return $this->getAttrib('max_value');
    }

    /**
     * Set the Minimum number of selected Values
     *
     * @param int $minValue
     * @return $this
     * @throws Bad_Exception
     * @throws Zend_Form_Exception
     */
    public function setMinValue($minValue)
    {
        if (is_int($minValue)) {
            if ($minValue > 0) {
                $this->setAttrib('min_value', $minValue);
            }

            return $this;
        } else {
            throw new Bad_Exception ('Invalid value supplied to setMinValue');
        }
    }

    /**
     * Set the Maximum number of selected values
     *
     * @param int $maxValue
     * @return $this
     * @throws Bad_Exception
     * @throws Zend_Form_Exception
     */
    public function setMaxValue($maxValue)
    {
        if (is_int($maxValue)) {
            if ($maxValue > 0) {
                $this->setAttrib('max_value', $maxValue);
            }

            return $this;
        } else {
            throw new Bad_Exception ('Invalid value supplied to setMaxValue');
        }
    }

    /**
     * Retrieve error messages and perform translation and value substitution.
     * Overridden to avoid errors from above being output once per value
     *
     * @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))
                && !empty($value)
            ) {
                $aggregateMessages = array();
                foreach ($value as $val) {
                    $aggregateMessages[] = str_replace('%value%', $val, $message);
                }
                // Add additional array unique to avoid the same error for all values
                $messages[$key] = implode($this->getErrorMessageSeparator(), array_unique($aggregateMessages));
            } else {
                $messages[$key] = str_replace('%value%', $value, $message);
            }
        }

        return $messages;
    }
}

Чтобы использовать это в форме, где пользователь должен выбрать ровно 3 варианта:

    $favouriteSports = new MinMaxMultiselect('favourite_sports');
    $favouriteSports
        ->addMultiOptions(array(
            'Football',
            'Cricket',
            'Golf',
            'Squash',
            'Rugby'
        ))
        ->setRequired()
        ->setLabel('Favourite Sports')
        ->setMinValue(3)
        ->setMaxValue(3);
0 голосов
/ 04 августа 2011

Хотя хорошо, когда вы можете выжать без необходимости написания собственного валидатора, нет ничего плохого в том, чтобы писать его, когда вам нужно сделать что-то немного необычное.

Это звучит как один из тех случаев.

...