Skip to content

Commit

Permalink
Refactored validators.
Browse files Browse the repository at this point in the history
  • Loading branch information
qiangxue committed Dec 6, 2013
1 parent 1c76175 commit cb4a8c7
Show file tree
Hide file tree
Showing 34 changed files with 501 additions and 665 deletions.
4 changes: 2 additions & 2 deletions docs/guide/validation.md
Expand Up @@ -172,10 +172,10 @@ operate without model do. In our case to validate an email we can do the followi
```php
$email = 'test@example.com';
$validator = new yii\validators\EmailValidator();
if ($validator->validateValue($email)) {
if ($validator->validate($email, $error)) {
echo 'Email is valid.';
} else {
echo 'Email is not valid.'
echo $error;
}
```

Expand Down
2 changes: 1 addition & 1 deletion framework/yii/base/Model.php
Expand Up @@ -321,7 +321,7 @@ public function validate($attributes = null, $clearErrors = true)
}
if ($this->beforeValidate()) {
foreach ($this->getActiveValidators() as $validator) {
$validator->validate($this, $attributes);
$validator->validateAttributes($this, $attributes);
}
$this->afterValidate();
return !$this->hasErrors();
Expand Down
32 changes: 6 additions & 26 deletions framework/yii/captcha/CaptchaValidator.php
Expand Up @@ -38,7 +38,7 @@ class CaptchaValidator extends Validator


/**
* Initializes the validator.
* @inheritdoc
*/
public function init()
{
Expand All @@ -49,28 +49,13 @@ public function init()
}

/**
* Validates the attribute of the object.
* If there is any error, the error message is added to the object.
* @param \yii\base\Model $object the object being validated
* @param string $attribute the attribute being validated
* @inheritdoc
*/
public function validateAttribute($object, $attribute)
{
$value = $object->$attribute;
if (!$this->validateValue($value)) {
$this->addError($object, $attribute, $this->message);
}
}

/**
* Validates the given value.
* @param mixed $value the value to be validated.
* @return boolean whether the value is valid.
*/
public function validateValue($value)
protected function validateValue($value)
{
$captcha = $this->createCaptchaAction();
return !is_array($value) && $captcha->validate($value, $this->caseSensitive);
$valid = !is_array($value) && $captcha->validate($value, $this->caseSensitive);
return $valid ? null : [$this->message, []];
}

/**
Expand All @@ -93,12 +78,7 @@ public function createCaptchaAction()
}

/**
* Returns the JavaScript needed for performing client-side validation.
* @param \yii\base\Model $object the data object being validated
* @param string $attribute the name of the attribute to be validated.
* @param \yii\web\View $view the view object that is going to be used to render views or view files
* containing a model form with this validator applied.
* @return string the client-side validation script.
* @inheritdoc
*/
public function clientValidateAttribute($object, $attribute, $view)
{
Expand Down
38 changes: 11 additions & 27 deletions framework/yii/validators/BooleanValidator.php
Expand Up @@ -37,7 +37,7 @@ class BooleanValidator extends Validator
public $strict = false;

/**
* Initializes the validator.
* @inheritdoc
*/
public function init()
{
Expand All @@ -48,40 +48,24 @@ public function init()
}

/**
* Validates the attribute of the object.
* If there is any error, the error message is added to the object.
* @param \yii\base\Model $object the object being validated
* @param string $attribute the attribute being validated
* @inheritdoc
*/
public function validateAttribute($object, $attribute)
protected function validateValue($value)
{
$value = $object->$attribute;
if (!$this->validateValue($value)) {
$this->addError($object, $attribute, $this->message, [
$valid = !$this->strict && ($value == $this->trueValue || $value == $this->falseValue)
|| $this->strict && ($value === $this->trueValue || $value === $this->falseValue);
if (!$valid) {
return [$this->message, [
'true' => $this->trueValue,
'false' => $this->falseValue,
]);
]];
} else {
return null;
}
}

/**
* Validates the given value.
* @param mixed $value the value to be validated.
* @return boolean whether the value is valid.
*/
public function validateValue($value)
{
return !$this->strict && ($value == $this->trueValue || $value == $this->falseValue)
|| $this->strict && ($value === $this->trueValue || $value === $this->falseValue);
}

/**
* Returns the JavaScript needed for performing client-side validation.
* @param \yii\base\Model $object the data object being validated
* @param string $attribute the name of the attribute to be validated.
* @param \yii\web\View $view the view object that is going to be used to render views or view files
* containing a model form with this validator applied.
* @return string the client-side validation script.
* @inheritdoc
*/
public function clientValidateAttribute($object, $attribute, $view)
{
Expand Down
75 changes: 35 additions & 40 deletions framework/yii/validators/CompareValidator.php
Expand Up @@ -41,7 +41,7 @@ class CompareValidator extends Validator
*/
public $compareAttribute;
/**
* @var string the constant value to be compared with. When both this property
* @var mixed the constant value to be compared with. When both this property
* and [[compareAttribute]] are set, this property takes precedence.
* @see compareAttribute
*/
Expand All @@ -66,12 +66,13 @@ class CompareValidator extends Validator
* - `{attribute}`: the label of the attribute being validated
* - `{value}`: the value of the attribute being validated
* - `{compareValue}`: the value or the attribute label to be compared with
* - `{compareAttribute}`: the label of the attribute to be compared with
*/
public $message;


/**
* Initializes the validator.
* @inheritdoc
*/
public function init()
{
Expand Down Expand Up @@ -109,11 +110,7 @@ public function init()
}

/**
* Validates the attribute of the object.
* If there is any error, the error message is added to the object.
* @param \yii\base\Model $object the object being validated
* @param string $attribute the attribute being validated
* @throws InvalidConfigException if CompareValidator::operator is invalid
* @inheritdoc
*/
public function validateAttribute($object, $attribute)
{
Expand All @@ -130,18 +127,7 @@ public function validateAttribute($object, $attribute)
$compareLabel = $object->getAttributeLabel($compareAttribute);
}

switch ($this->operator) {
case '==': $valid = $value == $compareValue; break;
case '===': $valid = $value === $compareValue; break;
case '!=': $valid = $value != $compareValue; break;
case '!==': $valid = $value !== $compareValue; break;
case '>': $valid = $value > $compareValue; break;
case '>=': $valid = $value >= $compareValue; break;
case '<': $valid = $value < $compareValue; break;
case '<=': $valid = $value <= $compareValue; break;
default: $valid = false; break;
}
if (!$valid) {
if (!$this->compareValues($this->operator, $value, $compareValue)) {
$this->addError($object, $attribute, $this->message, [
'compareAttribute' => $compareLabel,
'compareValue' => $compareValue,
Expand All @@ -150,38 +136,47 @@ public function validateAttribute($object, $attribute)
}

/**
* Validates the given value.
* @param mixed $value the value to be validated.
* @return boolean whether the value is valid.
* @throws InvalidConfigException if [[compareValue]] is not set.
* @inheritdoc
*/
public function validateValue($value)
protected function validateValue($value)
{
if ($this->compareValue === null) {
throw new InvalidConfigException('CompareValidator::compareValue must be set.');
}
if (!$this->compareValues($this->operator, $value, $this->compareValue)) {
return [$this->message, [
'compareAttribute' => $this->compareValue,
'compareValue' => $this->compareValue,
]];
} else {
return null;
}
}

switch ($this->operator) {
case '==': return $value == $this->compareValue;
case '===': return $value === $this->compareValue;
case '!=': return $value != $this->compareValue;
case '!==': return $value !== $this->compareValue;
case '>': return $value > $this->compareValue;
case '>=': return $value >= $this->compareValue;
case '<': return $value < $this->compareValue;
case '<=': return $value <= $this->compareValue;
/**
* Compares two values with the specified operator.
* @param string $operator the comparison operator
* @param mixed $value the value being compared
* @param mixed $compareValue another value being compared
* @return boolean whether the comparison using the specified operator is true.
*/
protected function compareValues($operator, $value, $compareValue)
{
switch ($operator) {
case '==': return $value == $compareValue;
case '===': return $value === $compareValue;
case '!=': return $value != $compareValue;
case '!==': return $value !== $compareValue;
case '>': return $value > $compareValue;
case '>=': return $value >= $compareValue;
case '<': return $value < $compareValue;
case '<=': return $value <= $compareValue;
default: return false;
}
}

/**
* Returns the JavaScript needed for performing client-side validation.
* @param \yii\base\Model $object the data object being validated
* @param string $attribute the name of the attribute to be validated
* @return string the client-side validation script
* @param \yii\web\View $view the view object that is going to be used to render views or view files
* containing a model form with this validator applied.
* @throws InvalidConfigException if CompareValidator::operator is invalid
* @inheritdoc
*/
public function clientValidateAttribute($object, $attribute, $view)
{
Expand Down
33 changes: 14 additions & 19 deletions framework/yii/validators/DateValidator.php
Expand Up @@ -32,7 +32,7 @@ class DateValidator extends Validator
public $timestampAttribute;

/**
* Initializes the validator.
* @inheritdoc
*/
public function init()
{
Expand All @@ -43,36 +43,31 @@ public function init()
}

/**
* Validates the attribute of the object.
* If there is any error, the error message is added to the object.
* @param \yii\base\Model $object the object being validated
* @param string $attribute the attribute being validated
* @inheritdoc
*/
public function validateAttribute($object, $attribute)
{
$value = $object->$attribute;
if (is_array($value)) {
$this->addError($object, $attribute, $this->message);
return;
}
$date = DateTime::createFromFormat($this->format, $value);
$errors = DateTime::getLastErrors();
if ($date === false || $errors['error_count'] || $errors['warning_count']) {
$this->addError($object, $attribute, $this->message);
$result = $this->validateValue($value);
if (!empty($result)) {
$this->addError($object, $attribute, $result[0], $result[1]);
} elseif ($this->timestampAttribute !== null) {
$date = DateTime::createFromFormat($this->format, $value);
$object->{$this->timestampAttribute} = $date->getTimestamp();
}
}

/**
* Validates the given value.
* @param mixed $value the value to be validated.
* @return boolean whether the value is valid.
* @inheritdoc
*/
public function validateValue($value)
protected function validateValue($value)
{
DateTime::createFromFormat($this->format, $value);
if (is_array($value)) {
return [$this->message, []];
}
$date = DateTime::createFromFormat($this->format, $value);
$errors = DateTime::getLastErrors();
return $errors['error_count'] === 0 && $errors['warning_count'] === 0;
$invalid = $date === false || $errors['error_count'] || $errors['warning_count'];
return $invalid ? [$this->message, []] : null;
}
}
4 changes: 1 addition & 3 deletions framework/yii/validators/DefaultValueValidator.php
Expand Up @@ -29,9 +29,7 @@ class DefaultValueValidator extends Validator
public $skipOnEmpty = false;

/**
* Validates the attribute of the object.
* @param \yii\base\Model $object the object being validated
* @param string $attribute the attribute being validated
* @inheritdoc
*/
public function validateAttribute($object, $attribute)
{
Expand Down

3 comments on commit cb4a8c7

@jom
Copy link
Contributor

@jom jom commented on cb4a8c7 Dec 6, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SafeValidator no longer works. Should we be making attributes as safe with scenarios instead?

@cebe
Copy link
Member

@cebe cebe commented on cb4a8c7 Dec 7, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope, should be fixed. @qiangxue am I right that validateValue() has to be implemented to return null in SafeValidator?

@egorpromo
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@qiangxue Good work 👍

Please sign in to comment.