Backport(バックポート) #3811 » t-2982.patch
lib/validator/opValidatorChoice.class.php | ||
---|---|---|
<?php
|
||
class opValidatorChoice extends sfValidatorChoice
|
||
{
|
||
/**
|
||
* @see sfValidatorBase
|
||
*/
|
||
protected function doClean($value)
|
||
{
|
||
$choices = $this->getChoices();
|
||
if ($this->getOption('multiple'))
|
||
{
|
||
$value = $this->cleanMultiple($value, $choices);
|
||
}
|
||
else
|
||
{
|
||
if (!self::inChoices($value, $choices))
|
||
{
|
||
throw new sfValidatorError($this, 'invalid', array('value' => $value));
|
||
}
|
||
}
|
||
return $value;
|
||
}
|
||
/**
|
||
* Cleans a value when multiple is true.
|
||
*
|
||
* @param mixed $value The submitted value
|
||
*
|
||
* @return array The cleaned value
|
||
*/
|
||
protected function cleanMultiple($value, $choices)
|
||
{
|
||
if (!is_array($value))
|
||
{
|
||
$value = array($value);
|
||
}
|
||
foreach ($value as $v)
|
||
{
|
||
if (!self::inChoices($v, $choices))
|
||
{
|
||
throw new sfValidatorError($this, 'invalid', array('value' => $v));
|
||
}
|
||
}
|
||
$count = count($value);
|
||
if ($this->hasOption('min') && $count < $this->getOption('min'))
|
||
{
|
||
throw new sfValidatorError($this, 'min', array('count' => $count, 'min' => $this->getOption('min')));
|
||
}
|
||
if ($this->hasOption('max') && $count > $this->getOption('max'))
|
||
{
|
||
throw new sfValidatorError($this, 'max', array('count' => $count, 'max' => $this->getOption('max')));
|
||
}
|
||
return $value;
|
||
}
|
||
/**
|
||
* Checks if a value is part of given choices (see bug #4212)
|
||
*
|
||
* @param mixed $value The value to check
|
||
* @param array $choices The array of available choices
|
||
*
|
||
* @return Boolean
|
||
*/
|
||
static protected function inChoices($value, array $choices = array())
|
||
{
|
||
foreach ($choices as $choice)
|
||
{
|
||
if ((string) $choice === (string) $value)
|
||
{
|
||
return true;
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
}
|
test/unit/validator/opValidatorChoiceTest.php | ||
---|---|---|
<?php
|
||
include_once dirname(__FILE__) . '/../../bootstrap/unit.php';
|
||
$t = new lime_test(9, new lime_output_color());
|
||
$t->diag('opValidatorChoice');
|
||
$t->diag('->clean()');
|
||
$v = new opValidatorChoice(array(
|
||
'choices' => array('00', '000', '0.0'),
|
||
));
|
||
try
|
||
{
|
||
$v->clean('0');
|
||
$t->fail('->clean() throws a sfValidatorError if not in choices');
|
||
$t->skip('', 1);
|
||
}
|
||
catch (Exception $e)
|
||
{
|
||
$t->pass('->clean() throws a sfValidatorError if not in choices');
|
||
$t->is($e->getCode(), 'invalid', '->clean() throws a sfValidatorError');
|
||
}
|
||
$t->is($v->clean('00'), '00', '->clean() accepts in choices');
|
||
$t->is($v->clean('000'), '000', '->clean() accepts in choices');
|
||
$t->is($v->clean('0.0'), '0.0', '->clean() accepts in choices');
|
||
$v = new opValidatorChoice(array(
|
||
'choices' => array('011', '11.0'),
|
||
));
|
||
try
|
||
{
|
||
$v->clean('11');
|
||
$t->fail('->clean() throws a sfValidatorError if not in choices');
|
||
$t->skip('', 1);
|
||
}
|
||
catch (Exception $e)
|
||
{
|
||
$t->pass('->clean() throws a sfValidatorError if not in choices');
|
||
$t->is($e->getCode(), 'invalid', '->clean() throws a sfValidatorError');
|
||
}
|
||
$t->is($v->clean('011'), '011', '->clean() accepts in choices');
|
||
$t->is($v->clean('11.0'), '11.0', '->clean() accepts in choices');
|