$validator = new \yii\validators\BooleanValidator([
'trueValue' => true,
'falseValue' => false,
'strict' => true
]);
$validator->validate('someIncorrectValue', $errorMessage);
var_dump($errorMessage);
string(49) "the input value must be either "true" or "false"."
string(41) "the input value must be either "1" or ""."
| Q | A |
| --- | --- |
| Yii version | 2.0.6 |
| PHP version | 5.5.9 |
| Operating system | Ubuntu 14.04 |
I'll fix it now
I don't think it is a bug. quotes are missing as values should be string. PHP's true/false are converted to '1' and '' :
$validator = new \yii\validators\BooleanValidator([
'trueValue' => 'true',
'falseValue' => 'false',
'strict' => true
]);
see http://stackoverflow.com/questions/11921690/why-doesnt-php-print-true-false.
But it's not correct in massages
maybe but that is how PHP works. how would I expect true to be converted to 'true' when echo true; outputs 1. how can I tell : set trueValue and falseValue to whatever is considered native true and false in PHP ?
Here key significance 'strict' => true and it not apply to echo;
If you set parameters different from the String for the Validator, then the message is likely to be used only in logs. Because the $POST data is String values from Web. Therefore, the error message should be conditional, but correct.
exactly I set 'strict' to PHP's true while I expect 'trueValue' to receive a string with value 'true'. it is different. what if I'm saving that to a MySQL BIT(1) column I may set the attribute to true as I know PHP will send 1 instead ? what if I'm doing a POST with a javascript true expecting it to be converted to a string 'true' and figure out later that it was same as sending 1. you don't think it may confuse people ?
A value of model is valid always by:
$nonStrictValidator = new BooleanValidator([
'trueValue' => true,
'falseValue' => false,
'strict' => false,
]);
and the message error will not throw never. Because I guess it will be used for the internal code only and messege error the input value must be either "true" or "false" is more correct in this case.
Fixed in 91bc1b5
Oh !! you meant only changing the error message output !! Sorry @githubjeka I guess I've been reading all backwards ! I definitively need some rest.
@tunecino np .. You made me think about a necessity in this validator and his behavior.
@samdark @SilverFire
To avoid such ambiguities here you could be remove strict param of the validator in v2.1.
class BooleanValidator extends Validator
{
/**
* @var string the value representing true status. Defaults to '1'.
*/
public $trueValue = '1';
/**
* @var string the value representing false status. Defaults to '0'.
*/
public $falseValue = '0';
/**
* @inheritdoc
*/
public function init()
{
parent::init();
if (!is_string($this->trueValue) || !is_string($this->falseValue)) {
throw new InvalidConfigException();
}
if ($this->message === null) {
$this->message = Yii::t('yii', '{attribute} must be either "{true}" or "{false}".');
}
}
/**
* @inheritdoc
*/
protected function validateValue($value)
{
$valid = ($value === $this->trueValue || $value === $this->falseValue);
if (!$valid) {
return [$this->message, [
'true' => $this->trueValue,
'false' =>$this->falseValue,
]];
}
return null;
}
/**
* @inheritdoc
*/
public function clientValidateAttribute($model, $attribute, $view)
{
$options = [
'trueValue' => $this->trueValue,
'falseValue' => $this->falseValue,
'message' => Yii::$app->getI18n()->format($this->message, [
'attribute' => $model->getAttributeLabel($attribute),
'true' => $this->trueValue,
'false' => $this->falseValue,
], Yii::$app->language),
];
if ($this->skipOnEmpty) {
$options['skipOnEmpty'] = 1;
}
$options['strict'] = 1;
ValidationAsset::register($view);
return 'yii.validation.boolean(value, messages, ' . json_encode($options, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE) . ');';
}
}
or remove this validator :hocho: and use RangeValidator
Most helpful comment
But it's not correct in massages