表格中有一个多选元素。需要验证其中选择了多少项(最小和最大计数)。
问题在于,当元素可以有多个值时,每个值都会单独验证。
我尝试将isArray
设置为false
以使用我的自定义验证程序ArraySize
验证该值,但出现了新问题:整个数组值传递给InArray
验证器和验证失败。所以我必须将registerInArrayValidator
设置为false
来关闭它。
现在我可以验证所选值的数量值,但无法验证它们与提供的选项的对应关系。
有没有办法解决问题而不再创建一个自定义验证器?
答案 0 :(得分:0)
注意:我假设这是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);
答案 1 :(得分:-1)
虽然你可以在不需要编写自定义验证器的情况下进行挤压,但是当你需要做一些与众不同的事情时,写一个是没有错的。
这听起来像是其中一种情况。