mirror of
https://github.com/yiisoft/yii2.git
synced 2025-11-03 22:32:40 +08:00
Merge branch 'master' into iss18604
This commit is contained in:
@ -22,8 +22,10 @@ Yii Framework 2 Change Log
|
||||
- Bug #18593: Fix setting the `maxlength` attribute for `Html::activeInput()` and `Html::activeTextArea()` based on `length` parameter of validator (BSCheshir)
|
||||
- Bug #18592: Fix `yii\db\Command::getRawSql()` to not replace query params in invalid places (sartor)
|
||||
- Bug #18590: Fix `yii\web\UrlManager` to instantiate cache only when it's actually needed (bizley)
|
||||
- Enh #18569: Add `NumberValidator::$allowArray` (raidkon)
|
||||
- Bug #18613: Do not call static methods non-statically in `BaseActiveRecord` (samdark)
|
||||
|
||||
|
||||
2.0.41.1 March 04, 2021
|
||||
-----------------------
|
||||
|
||||
|
||||
@ -24,6 +24,12 @@ use yii\web\JsExpression;
|
||||
*/
|
||||
class NumberValidator extends Validator
|
||||
{
|
||||
/**
|
||||
* @var bool whether to allow array type attribute. Defaults to false.
|
||||
* @since 2.0.42
|
||||
*/
|
||||
public $allowArray = false;
|
||||
|
||||
/**
|
||||
* @var bool whether the attribute value can only be an integer. Defaults to false.
|
||||
*/
|
||||
@ -81,20 +87,27 @@ class NumberValidator extends Validator
|
||||
public function validateAttribute($model, $attribute)
|
||||
{
|
||||
$value = $model->$attribute;
|
||||
if ($this->isNotNumber($value)) {
|
||||
if (is_array($value) && !$this->allowArray) {
|
||||
$this->addError($model, $attribute, $this->message);
|
||||
return;
|
||||
}
|
||||
$pattern = $this->integerOnly ? $this->integerPattern : $this->numberPattern;
|
||||
$values = !is_array($value) ? [$value] : $value;
|
||||
foreach ($values as $value) {
|
||||
if ($this->isNotNumber($value)) {
|
||||
$this->addError($model, $attribute, $this->message);
|
||||
return;
|
||||
}
|
||||
$pattern = $this->integerOnly ? $this->integerPattern : $this->numberPattern;
|
||||
|
||||
if (!preg_match($pattern, StringHelper::normalizeNumber($value))) {
|
||||
$this->addError($model, $attribute, $this->message);
|
||||
}
|
||||
if ($this->min !== null && $value < $this->min) {
|
||||
$this->addError($model, $attribute, $this->tooSmall, ['min' => $this->min]);
|
||||
}
|
||||
if ($this->max !== null && $value > $this->max) {
|
||||
$this->addError($model, $attribute, $this->tooBig, ['max' => $this->max]);
|
||||
if (!preg_match($pattern, StringHelper::normalizeNumber($value))) {
|
||||
$this->addError($model, $attribute, $this->message);
|
||||
}
|
||||
if ($this->min !== null && $value < $this->min) {
|
||||
$this->addError($model, $attribute, $this->tooSmall, ['min' => $this->min]);
|
||||
}
|
||||
if ($this->max !== null && $value > $this->max) {
|
||||
$this->addError($model, $attribute, $this->tooBig, ['max' => $this->max]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -103,16 +116,22 @@ class NumberValidator extends Validator
|
||||
*/
|
||||
protected function validateValue($value)
|
||||
{
|
||||
if ($this->isNotNumber($value)) {
|
||||
if (is_array($value) && !$this->allowArray) {
|
||||
return [Yii::t('yii', '{attribute} is invalid.'), []];
|
||||
}
|
||||
$pattern = $this->integerOnly ? $this->integerPattern : $this->numberPattern;
|
||||
if (!preg_match($pattern, StringHelper::normalizeNumber($value))) {
|
||||
return [$this->message, []];
|
||||
} elseif ($this->min !== null && $value < $this->min) {
|
||||
return [$this->tooSmall, ['min' => $this->min]];
|
||||
} elseif ($this->max !== null && $value > $this->max) {
|
||||
return [$this->tooBig, ['max' => $this->max]];
|
||||
$values = !is_array($value) ? [$value] : $value;
|
||||
foreach ($values as $value) {
|
||||
if ($this->isNotNumber($value)) {
|
||||
return [Yii::t('yii', '{attribute} is invalid.'), []];
|
||||
}
|
||||
$pattern = $this->integerOnly ? $this->integerPattern : $this->numberPattern;
|
||||
if (!preg_match($pattern, StringHelper::normalizeNumber($value))) {
|
||||
return [$this->message, []];
|
||||
} elseif ($this->min !== null && $value < $this->min) {
|
||||
return [$this->tooSmall, ['min' => $this->min]];
|
||||
} elseif ($this->max !== null && $value > $this->max) {
|
||||
return [$this->tooBig, ['max' => $this->max]];
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
@ -100,6 +100,48 @@ class NumberValidatorTest extends TestCase
|
||||
$this->assertFalse($val->validate(true));
|
||||
}
|
||||
|
||||
public function testValidateValueArraySimple()
|
||||
{
|
||||
$val = new NumberValidator();
|
||||
$this->assertFalse($val->validate([20]));
|
||||
$this->assertFalse($val->validate([0]));
|
||||
$this->assertFalse($val->validate([-20]));
|
||||
$this->assertFalse($val->validate(['20']));
|
||||
$this->assertFalse($val->validate([25.45]));
|
||||
$this->assertFalse($val->validate([false]));
|
||||
$this->assertFalse($val->validate([true]));
|
||||
|
||||
$val = new NumberValidator();
|
||||
$val->allowArray = true;
|
||||
$this->assertTrue($val->validate([20]));
|
||||
$this->assertTrue($val->validate([0]));
|
||||
$this->assertTrue($val->validate([-20]));
|
||||
$this->assertTrue($val->validate(['20']));
|
||||
$this->assertTrue($val->validate([25.45]));
|
||||
$this->assertFalse($val->validate([false]));
|
||||
$this->assertFalse($val->validate([true]));
|
||||
|
||||
$this->setPointDecimalLocale();
|
||||
$this->assertFalse($val->validate(['25,45']));
|
||||
$this->setCommaDecimalLocale();
|
||||
$this->assertTrue($val->validate(['25,45']));
|
||||
$this->restoreLocale();
|
||||
|
||||
$this->assertFalse($val->validate(['12:45']));
|
||||
$val = new NumberValidator(['integerOnly' => true]);
|
||||
$val->allowArray = true;
|
||||
$this->assertTrue($val->validate([20]));
|
||||
$this->assertTrue($val->validate([0]));
|
||||
$this->assertFalse($val->validate([25.45]));
|
||||
$this->assertTrue($val->validate(['20']));
|
||||
$this->assertFalse($val->validate(['25,45']));
|
||||
$this->assertTrue($val->validate(['020']));
|
||||
$this->assertTrue($val->validate([0x14]));
|
||||
$this->assertFalse($val->validate(['0x14'])); // todo check this
|
||||
$this->assertFalse($val->validate([false]));
|
||||
$this->assertFalse($val->validate([true]));
|
||||
}
|
||||
|
||||
public function testValidateValueAdvanced()
|
||||
{
|
||||
$val = new NumberValidator();
|
||||
@ -222,6 +264,101 @@ class NumberValidatorTest extends TestCase
|
||||
$this->assertTrue($model->hasErrors('attr_number'));
|
||||
}
|
||||
|
||||
public function testValidateAttributeArray()
|
||||
{
|
||||
$val = new NumberValidator();
|
||||
$val->allowArray = true;
|
||||
$model = new FakedValidationModel();
|
||||
$model->attr_number = ['5.5e1'];
|
||||
$val->validateAttribute($model, 'attr_number');
|
||||
$this->assertFalse($model->hasErrors('attr_number'));
|
||||
$model->attr_number = ['43^32']; //expression
|
||||
$val->validateAttribute($model, 'attr_number');
|
||||
$this->assertTrue($model->hasErrors('attr_number'));
|
||||
$val = new NumberValidator(['min' => 10]);
|
||||
$val->allowArray = true;
|
||||
$model = new FakedValidationModel();
|
||||
$model->attr_number = [10];
|
||||
$val->validateAttribute($model, 'attr_number');
|
||||
$this->assertFalse($model->hasErrors('attr_number'));
|
||||
$model->attr_number = [5];
|
||||
$val->validateAttribute($model, 'attr_number');
|
||||
$this->assertTrue($model->hasErrors('attr_number'));
|
||||
$val = new NumberValidator(['max' => 10]);
|
||||
$val->allowArray = true;
|
||||
$model = new FakedValidationModel();
|
||||
$model->attr_number = [10];
|
||||
$val->validateAttribute($model, 'attr_number');
|
||||
$this->assertFalse($model->hasErrors('attr_number'));
|
||||
$model->attr_number = [15];
|
||||
$val->validateAttribute($model, 'attr_number');
|
||||
$this->assertTrue($model->hasErrors('attr_number'));
|
||||
$val = new NumberValidator(['max' => 10, 'integerOnly' => true]);
|
||||
$val->allowArray = true;
|
||||
$model = new FakedValidationModel();
|
||||
$model->attr_number = [10];
|
||||
$val->validateAttribute($model, 'attr_number');
|
||||
$this->assertFalse($model->hasErrors('attr_number'));
|
||||
$model->attr_number = [3.43];
|
||||
$val->validateAttribute($model, 'attr_number');
|
||||
$this->assertTrue($model->hasErrors('attr_number'));
|
||||
$val = new NumberValidator(['min' => 1]);
|
||||
$val->allowArray = true;
|
||||
$model = FakedValidationModel::createWithAttributes(['attr_num' => [[1], [2], [3]]]);
|
||||
$val->validateAttribute($model, 'attr_num');
|
||||
$this->assertTrue($model->hasErrors('attr_num'));
|
||||
|
||||
// @see https://github.com/yiisoft/yii2/issues/11672
|
||||
$model = new FakedValidationModel();
|
||||
$model->attr_number = new \stdClass();
|
||||
$val->validateAttribute($model, 'attr_number');
|
||||
$this->assertTrue($model->hasErrors('attr_number'));
|
||||
|
||||
|
||||
$val = new NumberValidator();
|
||||
$model = new FakedValidationModel();
|
||||
$model->attr_number = ['5.5e1'];
|
||||
$val->validateAttribute($model, 'attr_number');
|
||||
$this->assertTrue($model->hasErrors('attr_number'));
|
||||
$model->attr_number = ['43^32']; //expression
|
||||
$val->validateAttribute($model, 'attr_number');
|
||||
$this->assertTrue($model->hasErrors('attr_number'));
|
||||
$val = new NumberValidator(['min' => 10]);
|
||||
$model = new FakedValidationModel();
|
||||
$model->attr_number = [10];
|
||||
$val->validateAttribute($model, 'attr_number');
|
||||
$this->assertTrue($model->hasErrors('attr_number'));
|
||||
$model->attr_number = [5];
|
||||
$val->validateAttribute($model, 'attr_number');
|
||||
$this->assertTrue($model->hasErrors('attr_number'));
|
||||
$val = new NumberValidator(['max' => 10]);
|
||||
$model = new FakedValidationModel();
|
||||
$model->attr_number = [10];
|
||||
$val->validateAttribute($model, 'attr_number');
|
||||
$this->assertTrue($model->hasErrors('attr_number'));
|
||||
$model->attr_number = [15];
|
||||
$val->validateAttribute($model, 'attr_number');
|
||||
$this->assertTrue($model->hasErrors('attr_number'));
|
||||
$val = new NumberValidator(['max' => 10, 'integerOnly' => true]);
|
||||
$model = new FakedValidationModel();
|
||||
$model->attr_number = [10];
|
||||
$val->validateAttribute($model, 'attr_number');
|
||||
$this->assertTrue($model->hasErrors('attr_number'));
|
||||
$model->attr_number = [3.43];
|
||||
$val->validateAttribute($model, 'attr_number');
|
||||
$this->assertTrue($model->hasErrors('attr_number'));
|
||||
$val = new NumberValidator(['min' => 1]);
|
||||
$model = FakedValidationModel::createWithAttributes(['attr_num' => [[1], [2], [3]]]);
|
||||
$val->validateAttribute($model, 'attr_num');
|
||||
$this->assertTrue($model->hasErrors('attr_num'));
|
||||
|
||||
// @see https://github.com/yiisoft/yii2/issues/11672
|
||||
$model = new FakedValidationModel();
|
||||
$model->attr_number = new \stdClass();
|
||||
$val->validateAttribute($model, 'attr_number');
|
||||
$this->assertTrue($model->hasErrors('attr_number'));
|
||||
}
|
||||
|
||||
public function testValidateAttributeWithLocaleWhereDecimalPointIsComma()
|
||||
{
|
||||
$val = new NumberValidator();
|
||||
|
||||
Reference in New Issue
Block a user