Commit 4f1efc74 by Qiang Xue

validator cleanup.

parent 78396afb
...@@ -29,7 +29,7 @@ class EmailValidator extends Validator ...@@ -29,7 +29,7 @@ class EmailValidator extends Validator
*/ */
public $fullPattern = '/^[^@]*<[a-zA-Z0-9!#$%&\'*+\\/=?^_`{|}~-]+(?:\.[a-zA-Z0-9!#$%&\'*+\\/=?^_`{|}~-]+)*@(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?\.)+[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?>$/'; public $fullPattern = '/^[^@]*<[a-zA-Z0-9!#$%&\'*+\\/=?^_`{|}~-]+(?:\.[a-zA-Z0-9!#$%&\'*+\\/=?^_`{|}~-]+)*@(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?\.)+[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?>$/';
/** /**
* @var boolean whether to allow name in the email address (e.g. "Qiang Xue <qiang.xue@gmail.com>"). Defaults to false. * @var boolean whether to allow name in the email address (e.g. "John Smith <john.smith@example.com>"). Defaults to false.
* @see fullPattern * @see fullPattern
*/ */
public $allowName = false; public $allowName = false;
...@@ -78,16 +78,17 @@ class EmailValidator extends Validator ...@@ -78,16 +78,17 @@ class EmailValidator extends Validator
public function validateValue($value) public function validateValue($value)
{ {
// make sure string length is limited to avoid DOS attacks // make sure string length is limited to avoid DOS attacks
$valid = is_string($value) && strlen($value) <= 254 && (preg_match($this->pattern, $value) || $this->allowName && preg_match($this->fullPattern, $value)); $valid = is_string($value) && strlen($value) <= 254
&& (preg_match($this->pattern, $value) || $this->allowName && preg_match($this->fullPattern, $value));
if ($valid) { if ($valid) {
$domain = rtrim(substr($value, strpos($value, '@') + 1), '>'); $domain = rtrim(substr($value, strpos($value, '@') + 1), '>');
} if ($this->checkMX && function_exists('checkdnsrr')) {
if ($valid && $this->checkMX && function_exists('checkdnsrr')) {
$valid = checkdnsrr($domain, 'MX'); $valid = checkdnsrr($domain, 'MX');
} }
if ($valid && $this->checkPort && function_exists('fsockopen')) { if ($valid && $this->checkPort && function_exists('fsockopen')) {
$valid = fsockopen($domain, 25) !== false; $valid = fsockopen($domain, 25) !== false;
} }
}
return $valid; return $valid;
} }
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
*/ */
namespace yii\validators; namespace yii\validators;
use yii\base\InvalidConfigException;
/** /**
* ExistValidator validates that the attribute value exists in a table. * ExistValidator validates that the attribute value exists in a table.
...@@ -21,9 +22,9 @@ namespace yii\validators; ...@@ -21,9 +22,9 @@ namespace yii\validators;
class ExistValidator extends Validator class ExistValidator extends Validator
{ {
/** /**
* @var string the yii\db\ActiveRecord class name or alias of the class * @var string the ActiveRecord class name or alias of the class
* that should be used to look for the attribute value being validated. * that should be used to look for the attribute value being validated.
* Defaults to null, meaning using the yii\db\ActiveRecord class of * Defaults to null, meaning using the ActiveRecord class of
* the attribute being validated. * the attribute being validated.
* @see attributeName * @see attributeName
*/ */
...@@ -47,8 +48,7 @@ class ExistValidator extends Validator ...@@ -47,8 +48,7 @@ class ExistValidator extends Validator
* *
* @param \yii\db\ActiveRecord $object the object being validated * @param \yii\db\ActiveRecord $object the object being validated
* @param string $attribute the attribute being validated * @param string $attribute the attribute being validated
* * @throws InvalidConfigException if table doesn't have column specified
* @throws \yii\base\Exception if table doesn't have column specified
*/ */
public function validateAttribute($object, $attribute) public function validateAttribute($object, $attribute)
{ {
...@@ -62,14 +62,14 @@ class ExistValidator extends Validator ...@@ -62,14 +62,14 @@ class ExistValidator extends Validator
$attributeName = ($this->attributeName === null) ? $attribute : $this->attributeName; $attributeName = ($this->attributeName === null) ? $attribute : $this->attributeName;
$table = $className::getTableSchema(); $table = $className::getTableSchema();
if (($column = $table->getColumn($attributeName)) === null) { if (($column = $table->getColumn($attributeName)) === null) {
throw new \yii\base\Exception('Table "' . $table->name . '" does not have a column named "' . $attributeName . '"'); throw new InvalidConfigException('Table "' . $table->name . '" does not have a column named "' . $attributeName . '"');
} }
$query = $className::find(); $query = $className::find();
$query->where(array($column->name => $value)); $query->where(array($column->name => $value));
if (!$query->exists()) { if (!$query->exists()) {
$message = ($this->message !== null) ? $this->message : \Yii::t('yii', '{attribute} "{value}" is invalid.'); $message = ($this->message !== null) ? $this->message : \Yii::t('yii', '{attribute} "{value}" is invalid.');
$this->addError($object, $attribute, $message, array('{value}' => $value)); $this->addError($object, $attribute, $message);
} }
} }
} }
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
*/ */
namespace yii\validators; namespace yii\validators;
use yii\base\InvalidConfigException;
/** /**
* FilterValidator converts the attribute value according to a filter. * FilterValidator converts the attribute value according to a filter.
...@@ -45,12 +46,12 @@ class FilterValidator extends Validator ...@@ -45,12 +46,12 @@ class FilterValidator extends Validator
* If there is any error, the error message is added to 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 \yii\base\Model $object the object being validated
* @param string $attribute the attribute being validated * @param string $attribute the attribute being validated
* @throws \yii\base\Exception if filter property is not a valid callback * @throws InvalidConfigException if filter property is not a valid callback
*/ */
public function validateAttribute($object, $attribute) public function validateAttribute($object, $attribute)
{ {
if ($this->filter === null) { if ($this->filter === null) {
throw new \yii\base\Exception('The "filter" property must be specified with a valid callback.'); throw new InvalidConfigException('The "filter" property must be specified with a valid callback.');
} }
$object->$attribute = call_user_func($this->filter, $object->$attribute); $object->$attribute = call_user_func($this->filter, $object->$attribute);
} }
......
...@@ -85,6 +85,8 @@ class InlineValidator extends Validator ...@@ -85,6 +85,8 @@ class InlineValidator extends Validator
if ($this->clientValidate !== null) { if ($this->clientValidate !== null) {
$method = $this->clientValidate; $method = $this->clientValidate;
return $object->$method($attribute); return $object->$method($attribute);
} else {
return null;
} }
} }
} }
\ No newline at end of file
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
*/ */
namespace yii\validators; namespace yii\validators;
use yii\base\InvalidConfigException;
/** /**
* RangeValidator validates that the attribute value is among a list of values. * RangeValidator validates that the attribute value is among a list of values.
...@@ -45,7 +46,7 @@ class RangeValidator extends Validator ...@@ -45,7 +46,7 @@ class RangeValidator extends Validator
* If there is any error, the error message is added to 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 \yii\base\Model $object the object being validated
* @param string $attribute the attribute being validated * @param string $attribute the attribute being validated
* @throws \yii\base\Exception if the "range" property is not an array * @throws InvalidConfigException if the "range" property is not an array
*/ */
public function validateAttribute($object, $attribute) public function validateAttribute($object, $attribute)
{ {
...@@ -54,7 +55,7 @@ class RangeValidator extends Validator ...@@ -54,7 +55,7 @@ class RangeValidator extends Validator
return; return;
} }
if (!is_array($this->range)) { if (!is_array($this->range)) {
throw new \yii\base\Exception('The "range" property must be specified as an array.'); throw new InvalidConfigException('The "range" property must be specified as an array.');
} }
if (!$this->not && !in_array($value, $this->range, $this->strict)) { if (!$this->not && !in_array($value, $this->range, $this->strict)) {
$message = ($this->message !== null) ? $this->message : \Yii::t('yii', '{attribute} should be in the list.'); $message = ($this->message !== null) ? $this->message : \Yii::t('yii', '{attribute} should be in the list.');
...@@ -70,12 +71,12 @@ class RangeValidator extends Validator ...@@ -70,12 +71,12 @@ class RangeValidator extends Validator
* @param \yii\base\Model $object the data object being validated * @param \yii\base\Model $object the data object being validated
* @param string $attribute the name of the attribute to be validated. * @param string $attribute the name of the attribute to be validated.
* @return string the client-side validation script. * @return string the client-side validation script.
* @throws \yii\base\Exception if the "range" property is not an array * @throws InvalidConfigException if the "range" property is not an array
*/ */
public function clientValidateAttribute($object, $attribute) public function clientValidateAttribute($object, $attribute)
{ {
if (!is_array($this->range)) { if (!is_array($this->range)) {
throw new \yii\base\Exception('The "range" property must be specified as an array.'); throw new InvalidConfigException('The "range" property must be specified as an array.');
} }
if (($message = $this->message) === null) { if (($message = $this->message) === null) {
......
...@@ -77,13 +77,13 @@ class RegularExpressionValidator extends Validator ...@@ -77,13 +77,13 @@ class RegularExpressionValidator extends Validator
$pattern = $this->pattern; $pattern = $this->pattern;
$pattern = preg_replace('/\\\\x\{?([0-9a-fA-F]+)\}?/', '\u$1', $pattern); $pattern = preg_replace('/\\\\x\{?([0-9a-fA-F]+)\}?/', '\u$1', $pattern);
$delim = substr($pattern, 0, 1); $deliminator = substr($pattern, 0, 1);
$endpos = strrpos($pattern, $delim, 1); $pos = strrpos($pattern, $deliminator, 1);
$flag = substr($pattern, $endpos + 1); $flag = substr($pattern, $pos + 1);
if ($delim !== '/') { if ($deliminator !== '/') {
$pattern = '/' . str_replace('/', '\\/', substr($pattern, 1, $endpos - 1)) . '/'; $pattern = '/' . str_replace('/', '\\/', substr($pattern, 1, $pos - 1)) . '/';
} else { } else {
$pattern = substr($pattern, 0, $endpos + 1); $pattern = substr($pattern, 0, $pos + 1);
} }
if (!empty($flag)) { if (!empty($flag)) {
$pattern .= preg_replace('/[^igm]/', '', $flag); $pattern .= preg_replace('/[^igm]/', '', $flag);
......
...@@ -52,9 +52,10 @@ class RequiredValidator extends Validator ...@@ -52,9 +52,10 @@ class RequiredValidator extends Validator
} }
} else { } else {
if (!$this->strict && $value != $this->requiredValue || $this->strict && $value !== $this->requiredValue) { if (!$this->strict && $value != $this->requiredValue || $this->strict && $value !== $this->requiredValue) {
$message = ($this->message !== null) ? $this->message : \Yii::t('yii', '{attribute} must be "{requiredValue}".', $message = ($this->message !== null) ? $this->message : \Yii::t('yii', '{attribute} must be "{requiredValue}".');
array('{requiredValue}' => $this->requiredValue)); $this->addError($object, $attribute, $message, array(
$this->addError($object, $attribute, $message); '{requiredValue}' => $this->requiredValue,
));
} }
} }
} }
......
<?php
/**
* SafeValidator class file.
*
* @link http://www.yiiframework.com/
* @copyright Copyright &copy; 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace yii\validators;
/**
* SafeValidator marks the associated attributes to be safe for massive assignments.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
*/
class SafeValidator extends Validator
{
/**
* 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
*/
public function validateAttribute($object, $attribute)
{
}
}
...@@ -64,8 +64,7 @@ class UniqueValidator extends Validator ...@@ -64,8 +64,7 @@ class UniqueValidator extends Validator
$query->where(array($column->name => $value)); $query->where(array($column->name => $value));
if ($object->getIsNewRecord()) { if ($object->getIsNewRecord()) {
// if current $object isn't in the database yet then it's OK just // if current $object isn't in the database yet then it's OK just to call exists()
// to call exists()
$exists = $query->exists(); $exists = $query->exists();
} else { } else {
// if current $object is in the database already we can't use exists() // if current $object is in the database already we can't use exists()
......
...@@ -195,6 +195,7 @@ abstract class Validator extends Component ...@@ -195,6 +195,7 @@ abstract class Validator extends Component
*/ */
public function clientValidateAttribute($object, $attribute) public function clientValidateAttribute($object, $attribute)
{ {
return null;
} }
/** /**
......
...@@ -6,10 +6,16 @@ ...@@ -6,10 +6,16 @@
* key-value-based (should allow storage-specific methods additionally to generic ones) * key-value-based (should allow storage-specific methods additionally to generic ones)
* redis (put it under framework/db/redis or perhaps framework/caching?) * redis (put it under framework/db/redis or perhaps framework/caching?)
- logging - logging
* WebTarget * WebTarget (TBD after web is in place): should consider using javascript and make it into a toolbar
* ProfileTarget * ProfileTarget (TBD after web is in place): should consider using javascript and make it into a toolbar
- caching - caching
* a console command to clear cached data * a console command to clear cached data
- validators
* FileValidator: depends on CUploadedFile
* CaptchaValidator: depends on CaptchaAction
* type conversion rules
* CompareValidator::clientValidateAttribute(): search for "CHtml::activeId"
* DateValidator: TBD
--- ---
...@@ -18,11 +24,6 @@ ...@@ -18,11 +24,6 @@
- Module should be able to define its own configuration including routes. Application should be able to overwrite it. - Module should be able to define its own configuration including routes. Application should be able to overwrite it.
* application * application
* security * security
- validators
* type conversion rules
* CompareValidator::clientValidateAttribute(): search for "CHtml::activeId"
* FileValidator, UniqueValidator, ExistValidator, DateValidator: TBD
* when getting errors from getErrors it will be good to have which validator (at least type) failed exactly.
- built-in console commands - built-in console commands
+ api doc builder + api doc builder
* support for markdown syntax * support for markdown syntax
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment