summaryrefslogtreecommitdiff
path: root/framework/validators
diff options
context:
space:
mode:
authorPatrick Seeger <pseeger@ccwn.org>2012-04-13 23:11:05 +0200
committerPatrick Seeger <pseeger@ccwn.org>2012-04-13 23:11:05 +0200
commit341cc4dd9c53ffbfb863e026dd58549c1082c7a7 (patch)
tree1bbbed20313bafb9b063b6b4d894fe580d8b000f /framework/validators
yii-framework 1.1.10 hinzugefügtHEADmaster
Diffstat (limited to 'framework/validators')
-rw-r--r--framework/validators/CBooleanValidator.php93
-rw-r--r--framework/validators/CCaptchaValidator.php123
-rw-r--r--framework/validators/CCompareValidator.php216
-rw-r--r--framework/validators/CDateValidator.php76
-rw-r--r--framework/validators/CDefaultValueValidator.php50
-rw-r--r--framework/validators/CEmailValidator.php118
-rw-r--r--framework/validators/CExistValidator.php92
-rw-r--r--framework/validators/CFileValidator.php251
-rw-r--r--framework/validators/CFilterValidator.php49
-rw-r--r--framework/validators/CInlineValidator.php81
-rw-r--r--framework/validators/CNumberValidator.php176
-rw-r--r--framework/validators/CRangeValidator.php97
-rw-r--r--framework/validators/CRegularExpressionValidator.php94
-rw-r--r--framework/validators/CRequiredValidator.php108
-rw-r--r--framework/validators/CSafeValidator.php31
-rw-r--r--framework/validators/CStringValidator.php177
-rw-r--r--framework/validators/CTypeValidator.php110
-rw-r--r--framework/validators/CUniqueValidator.php129
-rw-r--r--framework/validators/CUnsafeValidator.php37
-rw-r--r--framework/validators/CUrlValidator.php139
-rw-r--r--framework/validators/CValidator.php261
21 files changed, 2508 insertions, 0 deletions
diff --git a/framework/validators/CBooleanValidator.php b/framework/validators/CBooleanValidator.php
new file mode 100644
index 0000000..d61afc5
--- /dev/null
+++ b/framework/validators/CBooleanValidator.php
@@ -0,0 +1,93 @@
+<?php
+/**
+ * CBooleanValidator class file.
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @link http://www.yiiframework.com/
+ * @copyright Copyright &copy; 2008-2011 Yii Software LLC
+ * @license http://www.yiiframework.com/license/
+ */
+
+/**
+ * CBooleanValidator validates that the attribute value is either {@link trueValue} or {@link falseValue}.
+ *
+ * When using the {@link message} property to define a custom error message, the message
+ * may contain additional placeholders that will be replaced with the actual content. In addition
+ * to the "{attribute}" placeholder, recognized by all validators (see {@link CValidator}),
+ * CBooleanValidator allows for the following placeholders to be specified:
+ * <ul>
+ * <li>{true}: replaced with value representing the true status {@link trueValue}.</li>
+ * <li>{false}: replaced with value representing the false status {@link falseValue}.</li>
+ * </ul>
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @version $Id: CBooleanValidator.php 3515 2011-12-28 12:29:24Z mdomba $
+ * @package system.validators
+ */
+class CBooleanValidator extends CValidator
+{
+ /**
+ * @var mixed the value representing true status. Defaults to '1'.
+ */
+ public $trueValue='1';
+ /**
+ * @var mixed the value representing false status. Defaults to '0'.
+ */
+ public $falseValue='0';
+ /**
+ * @var boolean whether the comparison to {@link trueValue} and {@link falseValue} is strict.
+ * When this is true, the attribute value and type must both match those of {@link trueValue} or {@link falseValue}.
+ * Defaults to false, meaning only the value needs to be matched.
+ */
+ public $strict=false;
+ /**
+ * @var boolean whether the attribute value can be null or empty. Defaults to true,
+ * meaning that if the attribute is empty, it is considered valid.
+ */
+ public $allowEmpty=true;
+
+ /**
+ * Validates the attribute of the object.
+ * If there is any error, the error message is added to the object.
+ * @param CModel $object the object being validated
+ * @param string $attribute the attribute being validated
+ */
+ protected function validateAttribute($object,$attribute)
+ {
+ $value=$object->$attribute;
+ if($this->allowEmpty && $this->isEmpty($value))
+ return;
+ if(!$this->strict && $value!=$this->trueValue && $value!=$this->falseValue
+ || $this->strict && $value!==$this->trueValue && $value!==$this->falseValue)
+ {
+ $message=$this->message!==null?$this->message:Yii::t('yii','{attribute} must be either {true} or {false}.');
+ $this->addError($object,$attribute,$message,array(
+ '{true}'=>$this->trueValue,
+ '{false}'=>$this->falseValue,
+ ));
+ }
+ }
+
+ /**
+ * Returns the JavaScript needed for performing client-side validation.
+ * @param CModel $object the data object being validated
+ * @param string $attribute the name of the attribute to be validated.
+ * @return string the client-side validation script.
+ * @see CActiveForm::enableClientValidation
+ * @since 1.1.7
+ */
+ public function clientValidateAttribute($object,$attribute)
+ {
+ $message=$this->message!==null ? $this->message : Yii::t('yii','{attribute} must be either {true} or {false}.');
+ $message=strtr($message, array(
+ '{attribute}'=>$object->getAttributeLabel($attribute),
+ '{true}'=>$this->trueValue,
+ '{false}'=>$this->falseValue,
+ ));
+ return "
+if(".($this->allowEmpty ? "$.trim(value)!='' && " : '')."value!=".CJSON::encode($this->trueValue)." && value!=".CJSON::encode($this->falseValue).") {
+ messages.push(".CJSON::encode($message).");
+}
+";
+ }
+}
diff --git a/framework/validators/CCaptchaValidator.php b/framework/validators/CCaptchaValidator.php
new file mode 100644
index 0000000..87f844c
--- /dev/null
+++ b/framework/validators/CCaptchaValidator.php
@@ -0,0 +1,123 @@
+<?php
+/**
+ * CCaptchaValidator class file.
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @link http://www.yiiframework.com/
+ * @copyright Copyright &copy; 2008-2011 Yii Software LLC
+ * @license http://www.yiiframework.com/license/
+ */
+
+/**
+ * CCaptchaValidator validates that the attribute value is the same as the verification code displayed in the CAPTCHA.
+ *
+ * CCaptchaValidator should be used together with {@link CCaptchaAction}.
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @version $Id: CCaptchaValidator.php 3124 2011-03-25 15:48:05Z qiang.xue $
+ * @package system.validators
+ * @since 1.0
+ */
+class CCaptchaValidator extends CValidator
+{
+ /**
+ * @var boolean whether the comparison is case sensitive. Defaults to false.
+ */
+ public $caseSensitive=false;
+ /**
+ * @var string ID of the action that renders the CAPTCHA image. Defaults to 'captcha',
+ * meaning the 'captcha' action declared in the current controller.
+ * This can also be a route consisting of controller ID and action ID.
+ */
+ public $captchaAction='captcha';
+ /**
+ * @var boolean whether the attribute value can be null or empty.
+ * Defaults to false, meaning the attribute is invalid if it is empty.
+ */
+ public $allowEmpty=false;
+
+ /**
+ * Validates the attribute of the object.
+ * If there is any error, the error message is added to the object.
+ * @param CModel $object the object being validated
+ * @param string $attribute the attribute being validated
+ */
+ protected function validateAttribute($object,$attribute)
+ {
+ $value=$object->$attribute;
+ if($this->allowEmpty && $this->isEmpty($value))
+ return;
+ $captcha=$this->getCaptchaAction();
+ if(!$captcha->validate($value,$this->caseSensitive))
+ {
+ $message=$this->message!==null?$this->message:Yii::t('yii','The verification code is incorrect.');
+ $this->addError($object,$attribute,$message);
+ }
+ }
+
+ /**
+ * Returns the CAPTCHA action object.
+ * @return CCaptchaAction the action object
+ * @since 1.1.7
+ */
+ protected function getCaptchaAction()
+ {
+ if(($captcha=Yii::app()->getController()->createAction($this->captchaAction))===null)
+ {
+ if(strpos($this->captchaAction,'/')!==false) // contains controller or module
+ {
+ if(($ca=Yii::app()->createController($this->captchaAction))!==null)
+ {
+ list($controller,$actionID)=$ca;
+ $captcha=$controller->createAction($actionID);
+ }
+ }
+ if($captcha===null)
+ throw new CException(Yii::t('yii','CCaptchaValidator.action "{id}" is invalid. Unable to find such an action in the current controller.',
+ array('{id}'=>$this->captchaAction)));
+ }
+ return $captcha;
+ }
+
+ /**
+ * Returns the JavaScript needed for performing client-side validation.
+ * @param CModel $object the data object being validated
+ * @param string $attribute the name of the attribute to be validated.
+ * @return string the client-side validation script.
+ * @see CActiveForm::enableClientValidation
+ * @since 1.1.7
+ */
+ public function clientValidateAttribute($object,$attribute)
+ {
+ $captcha=$this->getCaptchaAction();
+ $message=$this->message!==null ? $this->message : Yii::t('yii','The verification code is incorrect.');
+ $message=strtr($message, array(
+ '{attribute}'=>$object->getAttributeLabel($attribute),
+ ));
+ $code=$captcha->getVerifyCode(false);
+ $hash=$captcha->generateValidationHash($this->caseSensitive ? $code : strtolower($code));
+ $js="
+var hash = $('body').data('{$this->captchaAction}.hash');
+if (hash == null)
+ hash = $hash;
+else
+ hash = hash[".($this->caseSensitive ? 0 : 1)."];
+for(var i=value.length-1, h=0; i >= 0; --i) h+=value.".($this->caseSensitive ? '' : 'toLowerCase().')."charCodeAt(i);
+if(h != hash) {
+ messages.push(".CJSON::encode($message).");
+}
+";
+
+ if($this->allowEmpty)
+ {
+ $js="
+if($.trim(value)!='') {
+ $js
+}
+";
+ }
+
+ return $js;
+ }
+}
+
diff --git a/framework/validators/CCompareValidator.php b/framework/validators/CCompareValidator.php
new file mode 100644
index 0000000..c226b3b
--- /dev/null
+++ b/framework/validators/CCompareValidator.php
@@ -0,0 +1,216 @@
+<?php
+/**
+ * CCompareValidator class file.
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @link http://www.yiiframework.com/
+ * @copyright Copyright &copy; 2008-2011 Yii Software LLC
+ * @license http://www.yiiframework.com/license/
+ */
+
+/**
+ * CCompareValidator compares the specified attribute value with another value and validates if they are equal.
+ *
+ * The value being compared with can be another attribute value
+ * (specified via {@link compareAttribute}) or a constant (specified via
+ * {@link compareValue}. When both are specified, the latter takes
+ * precedence. If neither is specified, the attribute will be compared
+ * with another attribute whose name is by appending "_repeat" to the source
+ * attribute name.
+ *
+ * The comparison can be either {@link strict} or not.
+ *
+ * CCompareValidator supports different comparison operators.
+ * Previously, it only compares to see if two values are equal or not.
+ *
+ * When using the {@link message} property to define a custom error message, the message
+ * may contain additional placeholders that will be replaced with the actual content. In addition
+ * to the "{attribute}" placeholder, recognized by all validators (see {@link CValidator}),
+ * CCompareValidator allows for the following placeholders to be specified:
+ * <ul>
+ * <li>{compareValue}: replaced with the constant value being compared with {@link compareValue}.</li>
+ * </ul>
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @version $Id: CCompareValidator.php 3515 2011-12-28 12:29:24Z mdomba $
+ * @package system.validators
+ * @since 1.0
+ */
+class CCompareValidator extends CValidator
+{
+ /**
+ * @var string the name of the attribute to be compared with
+ */
+ public $compareAttribute;
+ /**
+ * @var string the constant value to be compared with
+ */
+ public $compareValue;
+ /**
+ * @var boolean whether the comparison is strict (both value and type must be the same.)
+ * Defaults to false.
+ */
+ public $strict=false;
+ /**
+ * @var boolean whether the attribute value can be null or empty. Defaults to false.
+ * If this is true, it means the attribute is considered valid when it is empty.
+ */
+ public $allowEmpty=false;
+ /**
+ * @var string the operator for comparison. Defaults to '='.
+ * The followings are valid operators:
+ * <ul>
+ * <li>'=' or '==': validates to see if the two values are equal. If {@link strict} is true, the comparison
+ * will be done in strict mode (i.e. checking value type as well).</li>
+ * <li>'!=': validates to see if the two values are NOT equal. If {@link strict} is true, the comparison
+ * will be done in strict mode (i.e. checking value type as well).</li>
+ * <li>'>': validates to see if the value being validated is greater than the value being compared with.</li>
+ * <li>'>=': validates to see if the value being validated is greater than or equal to the value being compared with.</li>
+ * <li>'<': validates to see if the value being validated is less than the value being compared with.</li>
+ * <li>'<=': validates to see if the value being validated is less than or equal to the value being compared with.</li>
+ * </ul>
+ */
+ public $operator='=';
+
+ /**
+ * Validates the attribute of the object.
+ * If there is any error, the error message is added to the object.
+ * @param CModel $object the object being validated
+ * @param string $attribute the attribute being validated
+ */
+ protected function validateAttribute($object,$attribute)
+ {
+ $value=$object->$attribute;
+ if($this->allowEmpty && $this->isEmpty($value))
+ return;
+ if($this->compareValue!==null)
+ $compareTo=$compareValue=$this->compareValue;
+ else
+ {
+ $compareAttribute=$this->compareAttribute===null ? $attribute.'_repeat' : $this->compareAttribute;
+ $compareValue=$object->$compareAttribute;
+ $compareTo=$object->getAttributeLabel($compareAttribute);
+ }
+
+ switch($this->operator)
+ {
+ case '=':
+ case '==':
+ if(($this->strict && $value!==$compareValue) || (!$this->strict && $value!=$compareValue))
+ {
+ $message=$this->message!==null?$this->message:Yii::t('yii','{attribute} must be repeated exactly.');
+ $this->addError($object,$attribute,$message,array('{compareAttribute}'=>$compareTo));
+ }
+ break;
+ case '!=':
+ if(($this->strict && $value===$compareValue) || (!$this->strict && $value==$compareValue))
+ {
+ $message=$this->message!==null?$this->message:Yii::t('yii','{attribute} must not be equal to "{compareValue}".');
+ $this->addError($object,$attribute,$message,array('{compareAttribute}'=>$compareTo,'{compareValue}'=>$compareValue));
+ }
+ break;
+ case '>':
+ if($value<=$compareValue)
+ {
+ $message=$this->message!==null?$this->message:Yii::t('yii','{attribute} must be greater than "{compareValue}".');
+ $this->addError($object,$attribute,$message,array('{compareAttribute}'=>$compareTo,'{compareValue}'=>$compareValue));
+ }
+ break;
+ case '>=':
+ if($value<$compareValue)
+ {
+ $message=$this->message!==null?$this->message:Yii::t('yii','{attribute} must be greater than or equal to "{compareValue}".');
+ $this->addError($object,$attribute,$message,array('{compareAttribute}'=>$compareTo,'{compareValue}'=>$compareValue));
+ }
+ break;
+ case '<':
+ if($value>=$compareValue)
+ {
+ $message=$this->message!==null?$this->message:Yii::t('yii','{attribute} must be less than "{compareValue}".');
+ $this->addError($object,$attribute,$message,array('{compareAttribute}'=>$compareTo,'{compareValue}'=>$compareValue));
+ }
+ break;
+ case '<=':
+ if($value>$compareValue)
+ {
+ $message=$this->message!==null?$this->message:Yii::t('yii','{attribute} must be less than or equal to "{compareValue}".');
+ $this->addError($object,$attribute,$message,array('{compareAttribute}'=>$compareTo,'{compareValue}'=>$compareValue));
+ }
+ break;
+ default:
+ throw new CException(Yii::t('yii','Invalid operator "{operator}".',array('{operator}'=>$this->operator)));
+ }
+ }
+
+ /**
+ * Returns the JavaScript needed for performing client-side validation.
+ * @param CModel $object the data object being validated
+ * @param string $attribute the name of the attribute to be validated.
+ * @return string the client-side validation script.
+ * @see CActiveForm::enableClientValidation
+ * @since 1.1.7
+ */
+ public function clientValidateAttribute($object,$attribute)
+ {
+ if($this->compareValue !== null)
+ {
+ $compareTo=$this->compareValue;
+ $compareValue=CJSON::encode($this->compareValue);
+ }
+ else
+ {
+ $compareAttribute=$this->compareAttribute === null ? $attribute . '_repeat' : $this->compareAttribute;
+ $compareValue="\$('#" . (CHtml::activeId($object, $compareAttribute)) . "').val()";
+ $compareTo=$object->getAttributeLabel($compareAttribute);
+ }
+
+ $message=$this->message;
+ switch($this->operator)
+ {
+ case '=':
+ case '==':
+ if($message===null)
+ $message=Yii::t('yii','{attribute} must be repeated exactly.');
+ $condition='value!='.$compareValue;
+ break;
+ case '!=':
+ if($message===null)
+ $message=Yii::t('yii','{attribute} must not be equal to "{compareValue}".');
+ $condition='value=='.$compareValue;
+ break;
+ case '>':
+ if($message===null)
+ $message=Yii::t('yii','{attribute} must be greater than "{compareValue}".');
+ $condition='parseFloat(value)<=parseFloat('.$compareValue.')';
+ break;
+ case '>=':
+ if($message===null)
+ $message=Yii::t('yii','{attribute} must be greater than or equal to "{compareValue}".');
+ $condition='parseFloat(value)<parseFloat('.$compareValue.')';
+ break;
+ case '<':
+ if($message===null)
+ $message=Yii::t('yii','{attribute} must be less than "{compareValue}".');
+ $condition='parseFloat(value)>=parseFloat('.$compareValue.')';
+ break;
+ case '<=':
+ if($message===null)
+ $message=Yii::t('yii','{attribute} must be less than or equal to "{compareValue}".');
+ $condition='parseFloat(value)>parseFloat('.$compareValue.')';
+ break;
+ default:
+ throw new CException(Yii::t('yii','Invalid operator "{operator}".',array('{operator}'=>$this->operator)));
+ }
+
+ $message=strtr($message,array(
+ '{attribute}'=>$object->getAttributeLabel($attribute),
+ '{compareValue}'=>$compareTo,
+ ));
+
+ return "
+if(".($this->allowEmpty ? "$.trim(value)!='' && " : '').$condition.") {
+ messages.push(".CJSON::encode($message).");
+}
+";
+ }
+}
diff --git a/framework/validators/CDateValidator.php b/framework/validators/CDateValidator.php
new file mode 100644
index 0000000..74b921b
--- /dev/null
+++ b/framework/validators/CDateValidator.php
@@ -0,0 +1,76 @@
+<?php
+/**
+ * CDateValidator class file.
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @link http://www.yiiframework.com/
+ * @copyright Copyright &copy; 2008-2011 Yii Software LLC
+ * @license http://www.yiiframework.com/license/
+ */
+
+/**
+ * CDateValidator verifies if the attribute represents a date, time or datetime.
+ *
+ * By setting the {@link format} property, one can specify what format the date value
+ * must be in. If the given date value doesn't follow the format, the attribute is considered as invalid.
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @version $Id: CDateValidator.php 2799 2011-01-01 19:31:13Z qiang.xue $
+ * @package system.validators
+ * @since 1.1.7
+ */
+class CDateValidator extends CValidator
+{
+ /**
+ * @var mixed the format pattern that the date value should follow.
+ * This can be either a string or an array representing multiple formats.
+ * Defaults to 'MM/dd/yyyy'. Please see {@link CDateTimeParser} for details
+ * about how to specify a date format.
+ */
+ public $format='MM/dd/yyyy';
+ /**
+ * @var boolean whether the attribute value can be null or empty. Defaults to true,
+ * meaning that if the attribute is empty, it is considered valid.
+ */
+ public $allowEmpty=true;
+ /**
+ * @var string the name of the attribute to receive the parsing result.
+ * When this property is not null and the validation is successful, the named attribute will
+ * receive the parsing result.
+ */
+ public $timestampAttribute;
+
+ /**
+ * Validates the attribute of the object.
+ * If there is any error, the error message is added to the object.
+ * @param CModel $object the object being validated
+ * @param string $attribute the attribute being validated
+ */
+ protected function validateAttribute($object,$attribute)
+ {
+ $value=$object->$attribute;
+ if($this->allowEmpty && $this->isEmpty($value))
+ return;
+
+ $formats=is_string($this->format) ? array($this->format) : $this->format;
+ $valid=false;
+ foreach($formats as $format)
+ {
+ $timestamp=CDateTimeParser::parse($value,$format,array('month'=>1,'day'=>1,'hour'=>0,'minute'=>0,'second'=>0));
+ if($timestamp!==false)
+ {
+ $valid=true;
+ if($this->timestampAttribute!==null)
+ $object->{$this->timestampAttribute}=$timestamp;
+ break;
+ }
+ }
+
+ if(!$valid)
+ {
+ $message=$this->message!==null?$this->message : Yii::t('yii','The format of {attribute} is invalid.');
+ $this->addError($object,$attribute,$message);
+ }
+ }
+}
+
diff --git a/framework/validators/CDefaultValueValidator.php b/framework/validators/CDefaultValueValidator.php
new file mode 100644
index 0000000..24f9e05
--- /dev/null
+++ b/framework/validators/CDefaultValueValidator.php
@@ -0,0 +1,50 @@
+<?php
+/**
+ * CDefaultValueValidator class file.
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @link http://www.yiiframework.com/
+ * @copyright Copyright &copy; 2008-2011 Yii Software LLC
+ * @license http://www.yiiframework.com/license/
+ */
+
+/**
+ * CDefaultValueValidator sets the attributes with the specified value.
+ * It does not do validation. Its existence is mainly to allow
+ * specifying attribute default values in a dynamic way.
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @version $Id: CDefaultValueValidator.php 3515 2011-12-28 12:29:24Z mdomba $
+ * @package system.validators
+ */
+class CDefaultValueValidator extends CValidator
+{
+ /**
+ * @var mixed the default value to be set to the specified attributes.
+ */
+ public $value;
+ /**
+ * @var boolean whether to set the default value only when the attribute value is null or empty string.
+ * Defaults to true. If false, the attribute will always be assigned with the default value,
+ * even if it is already explicitly assigned a value.
+ */
+ public $setOnEmpty=true;
+
+ /**
+ * Validates the attribute of the object.
+ * @param CModel $object the object being validated
+ * @param string $attribute the attribute being validated
+ */
+ protected function validateAttribute($object,$attribute)
+ {
+ if(!$this->setOnEmpty)
+ $object->$attribute=$this->value;
+ else
+ {
+ $value=$object->$attribute;
+ if($value===null || $value==='')
+ $object->$attribute=$this->value;
+ }
+ }
+}
+
diff --git a/framework/validators/CEmailValidator.php b/framework/validators/CEmailValidator.php
new file mode 100644
index 0000000..68def75
--- /dev/null
+++ b/framework/validators/CEmailValidator.php
@@ -0,0 +1,118 @@
+<?php
+/**
+ * CEmailValidator class file.
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @link http://www.yiiframework.com/
+ * @copyright Copyright &copy; 2008-2011 Yii Software LLC
+ * @license http://www.yiiframework.com/license/
+ */
+
+/**
+ * CEmailValidator validates that the attribute value is a valid email address.
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @version $Id: CEmailValidator.php 3515 2011-12-28 12:29:24Z mdomba $
+ * @package system.validators
+ * @since 1.0
+ */
+class CEmailValidator extends CValidator
+{
+ /**
+ * @var string the regular expression used to validate the attribute value.
+ * @see http://www.regular-expressions.info/email.html
+ */
+ public $pattern='/^[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 string the regular expression used to validate email addresses with the name part.
+ * This property is used only when {@link allowName} is true.
+ * @see allowName
+ */
+ 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.
+ * @see fullPattern
+ */
+ public $allowName=false;
+ /**
+ * @var boolean whether to check the MX record for the email address.
+ * Defaults to false. To enable it, you need to make sure the PHP function 'checkdnsrr'
+ * exists in your PHP installation.
+ */
+ public $checkMX=false;
+ /**
+ * @var boolean whether to check port 25 for the email address.
+ * Defaults to false.
+ */
+ public $checkPort=false;
+ /**
+ * @var boolean whether the attribute value can be null or empty. Defaults to true,
+ * meaning that if the attribute is empty, it is considered valid.
+ */
+ public $allowEmpty=true;
+
+ /**
+ * Validates the attribute of the object.
+ * If there is any error, the error message is added to the object.
+ * @param CModel $object the object being validated
+ * @param string $attribute the attribute being validated
+ */
+ protected function validateAttribute($object,$attribute)
+ {
+ $value=$object->$attribute;
+ if($this->allowEmpty && $this->isEmpty($value))
+ return;
+ if(!$this->validateValue($value))
+ {
+ $message=$this->message!==null?$this->message:Yii::t('yii','{attribute} is not a valid email address.');
+ $this->addError($object,$attribute,$message);
+ }
+ }
+
+ /**
+ * Validates a static value to see if it is a valid email.
+ * Note that this method does not respect {@link allowEmpty} property.
+ * This method is provided so that you can call it directly without going through the model validation rule mechanism.
+ * @param mixed $value the value to be validated
+ * @return boolean whether the value is a valid email
+ * @since 1.1.1
+ */
+ public function validateValue($value)
+ {
+ // 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));
+ if($valid)
+ $domain=rtrim(substr($value,strpos($value,'@')+1),'>');
+ if($valid && $this->checkMX && function_exists('checkdnsrr'))
+ $valid=checkdnsrr($domain,'MX');
+ if($valid && $this->checkPort && function_exists('fsockopen'))
+ $valid=fsockopen($domain,25)!==false;
+ return $valid;
+ }
+
+ /**
+ * Returns the JavaScript needed for performing client-side validation.
+ * @param CModel $object the data object being validated
+ * @param string $attribute the name of the attribute to be validated.
+ * @return string the client-side validation script.
+ * @see CActiveForm::enableClientValidation
+ * @since 1.1.7
+ */
+ public function clientValidateAttribute($object,$attribute)
+ {
+ $message=$this->message!==null ? $this->message : Yii::t('yii','{attribute} is not a valid email address.');
+ $message=strtr($message, array(
+ '{attribute}'=>$object->getAttributeLabel($attribute),
+ ));
+
+ $condition="!value.match({$this->pattern})";
+ if($this->allowName)
+ $condition.=" && !value.match({$this->fullPattern})";
+
+ return "
+if(".($this->allowEmpty ? "$.trim(value)!='' && " : '').$condition.") {
+ messages.push(".CJSON::encode($message).");
+}
+";
+ }
+}
diff --git a/framework/validators/CExistValidator.php b/framework/validators/CExistValidator.php
new file mode 100644
index 0000000..9c1d5ce
--- /dev/null
+++ b/framework/validators/CExistValidator.php
@@ -0,0 +1,92 @@
+<?php
+/**
+ * CExistValidator class file.
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @link http://www.yiiframework.com/
+ * @copyright Copyright &copy; 2008-2011 Yii Software LLC
+ * @license http://www.yiiframework.com/license/
+ */
+
+/**
+ * CExistValidator validates that the attribute value exists in a table.
+ *
+ * This validator is often used to verify that a foreign key contains a value
+ * that can be found in the foreign table.
+ *
+ * When using the {@link message} property to define a custom error message, the message
+ * may contain additional placeholders that will be replaced with the actual content. In addition
+ * to the "{attribute}" placeholder, recognized by all validators (see {@link CValidator}),
+ * CExistValidator allows for the following placeholders to be specified:
+ * <ul>
+ * <li>{value}: replaced with value of the attribute.</li>
+ * </ul>
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @version $Id: CExistValidator.php 3549 2012-01-27 15:36:43Z qiang.xue $
+ * @package system.validators
+ */
+class CExistValidator extends CValidator
+{
+ /**
+ * @var string the ActiveRecord class name that should be used to
+ * look for the attribute value being validated. Defaults to null,
+ * meaning using the ActiveRecord class of the attribute being validated.
+ * You may use path alias to reference a class name here.
+ * @see attributeName
+ */
+ public $className;
+ /**
+ * @var string the ActiveRecord class attribute name that should be
+ * used to look for the attribute value being validated. Defaults to null,
+ * meaning using the name of the attribute being validated.
+ * @see className
+ */
+ public $attributeName;
+ /**
+ * @var array additional query criteria. This will be combined with the condition
+ * that checks if the attribute value exists in the corresponding table column.
+ * This array will be used to instantiate a {@link CDbCriteria} object.
+ */
+ public $criteria=array();
+ /**
+ * @var boolean whether the attribute value can be null or empty. Defaults to true,
+ * meaning that if the attribute is empty, it is considered valid.
+ */
+ public $allowEmpty=true;
+
+ /**
+ * Validates the attribute of the object.
+ * If there is any error, the error message is added to the object.
+ * @param CModel $object the object being validated
+ * @param string $attribute the attribute being validated
+ */
+ protected function validateAttribute($object,$attribute)
+ {
+ $value=$object->$attribute;
+ if($this->allowEmpty && $this->isEmpty($value))
+ return;
+
+ $className=$this->className===null?get_class($object):Yii::import($this->className);
+ $attributeName=$this->attributeName===null?$attribute:$this->attributeName;
+ $finder=CActiveRecord::model($className);
+ $table=$finder->getTableSchema();
+ if(($column=$table->getColumn($attributeName))===null)
+ throw new CException(Yii::t('yii','Table "{table}" does not have a column named "{column}".',
+ array('{column}'=>$attributeName,'{table}'=>$table->name)));
+
+ $criteria=array('condition'=>$column->rawName.'=:vp','params'=>array(':vp'=>$value));
+ if($this->criteria!==array())
+ {
+ $criteria=new CDbCriteria($criteria);
+ $criteria->mergeWith($this->criteria);
+ }
+
+ if(!$finder->exists($criteria))
+ {
+ $message=$this->message!==null?$this->message:Yii::t('yii','{attribute} "{value}" is invalid.');
+ $this->addError($object,$attribute,$message,array('{value}'=>CHtml::encode($value)));
+ }
+ }
+}
+
diff --git a/framework/validators/CFileValidator.php b/framework/validators/CFileValidator.php
new file mode 100644
index 0000000..d90d70e
--- /dev/null
+++ b/framework/validators/CFileValidator.php
@@ -0,0 +1,251 @@
+<?php
+/**
+ * CFileValidator class file.
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @link http://www.yiiframework.com/
+ * @copyright Copyright &copy; 2008-2011 Yii Software LLC
+ * @license http://www.yiiframework.com/license/
+ */
+
+/**
+ * CFileValidator verifies if an attribute is receiving a valid uploaded file.
+ *
+ * It uses the model class and attribute name to retrieve the information
+ * about the uploaded file. It then checks if a file is uploaded successfully,
+ * if the file size is within the limit and if the file type is allowed.
+ *
+ * This validator will attempt to fetch uploaded data if attribute is not
+ * previously set. Please note that this cannot be done if input is tabular:
+ * <pre>
+ * foreach($models as $i=>$model)
+ * $model->attribute = CUploadedFile::getInstance($model, "[$i]attribute");
+ * </pre>
+ * Please note that you must use {@link CUploadedFile::getInstances} for multiple
+ * file uploads.
+ *
+ * When using CFileValidator with an active record, the following code is often used:
+ * <pre>
+ * if($model->save())
+ * {
+ * // single upload
+ * $model->attribute->saveAs($path);
+ * // multiple upload
+ * foreach($model->attribute as $file)
+ * $file->saveAs($path);
+ * }
+ * </pre>
+ *
+ * You can use {@link CFileValidator} to validate the file attribute.
+ *
+ * In addition to the {@link message} property for setting a custom error message,
+ * CFileValidator has a few custom error messages you can set that correspond to different
+ * validation scenarios. When the file is too large, you may use the {@link tooLarge} property
+ * to define a custom error message. Similarly for {@link tooSmall}, {@link wrongType} and
+ * {@link tooMany}. The messages may contain additional placeholders that will be replaced
+ * with the actual content. In addition to the "{attribute}" placeholder, recognized by all
+ * validators (see {@link CValidator}), CFileValidator allows for the following placeholders
+ * to be specified:
+ * <ul>
+ * <li>{file}: replaced with the name of the file.</li>
+ * <li>{limit}: when using {@link tooLarge}, replaced with {@link maxSize};
+ * when using {@link tooSmall}, replaced with {@link maxSize}; and when using {@link tooMany}
+ * replaced with {@link maxFiles}.</li>
+ * <li>{extensions}: when using {@link wrongType}, it will be replaced with the allowed extensions.</li>
+ * </ul>
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @version $Id: CFileValidator.php 3491 2011-12-17 05:17:57Z jefftulsa $
+ * @package system.validators
+ * @since 1.0
+ */
+class CFileValidator extends CValidator
+{
+ /**
+ * @var boolean whether the attribute requires a file to be uploaded or not.
+ * Defaults to false, meaning a file is required to be uploaded.
+ */
+ public $allowEmpty=false;
+ /**
+ * @var mixed a list of file name extensions that are allowed to be uploaded.
+ * This can be either an array or a string consisting of file extension names
+ * separated by space or comma (e.g. "gif, jpg").
+ * Extension names are case-insensitive. Defaults to null, meaning all file name
+ * extensions are allowed.
+ */
+ public $types;
+ /**
+ * @var integer the minimum number of bytes required for the uploaded file.
+ * Defaults to null, meaning no limit.
+ * @see tooSmall
+ */
+ public $minSize;
+ /**
+ * @var integer the maximum number of bytes required for the uploaded file.
+ * Defaults to null, meaning no limit.
+ * Note, the size limit is also affected by 'upload_max_filesize' INI setting
+ * and the 'MAX_FILE_SIZE' hidden field value.
+ * @see tooLarge
+ */
+ public $maxSize;
+ /**
+ * @var string the error message used when the uploaded file is too large.
+ * @see maxSize
+ */
+ public $tooLarge;
+ /**
+ * @var string the error message used when the uploaded file is too small.
+ * @see minSize
+ */
+ public $tooSmall;
+ /**
+ * @var string the error message used when the uploaded file has an extension name
+ * that is not listed among {@link extensions}.
+ */
+ public $wrongType;
+ /**
+ * @var integer the maximum file count the given attribute can hold.
+ * It defaults to 1, meaning single file upload. By defining a higher number,
+ * multiple uploads become possible.
+ */
+ public $maxFiles=1;
+ /**
+ * @var string the error message used if the count of multiple uploads exceeds
+ * limit.
+ */
+ public $tooMany;
+
+ /**
+ * Set the attribute and then validates using {@link validateFile}.
+ * If there is any error, the error message is added to the object.
+ * @param CModel $object the object being validated
+ * @param string $attribute the attribute being validated
+ */
+ protected function validateAttribute($object, $attribute)
+ {
+ if($this->maxFiles > 1)
+ {
+ $files=$object->$attribute;
+ if(!is_array($files) || !isset($files[0]) || !$files[0] instanceof CUploadedFile)
+ $files = CUploadedFile::getInstances($object, $attribute);
+ if(array()===$files)
+ return $this->emptyAttribute($object, $attribute);
+ if(count($files) > $this->maxFiles)
+ {
+ $message=$this->tooMany!==null?$this->tooMany : Yii::t('yii', '{attribute} cannot accept more than {limit} files.');
+ $this->addError($object, $attribute, $message, array('{attribute}'=>$attribute, '{limit}'=>$this->maxFiles));
+ }
+ else
+ foreach($files as $file)
+ $this->validateFile($object, $attribute, $file);
+ }
+ else
+ {
+ $file = $object->$attribute;
+ if(!$file instanceof CUploadedFile)
+ {
+ $file = CUploadedFile::getInstance($object, $attribute);
+ if(null===$file)
+ return $this->emptyAttribute($object, $attribute);
+ }
+ $this->validateFile($object, $attribute, $file);
+ }
+ }
+
+ /**
+ * Internally validates a file object.
+ * @param CModel $object the object being validated
+ * @param string $attribute the attribute being validated
+ * @param CUploadedFile $file uploaded file passed to check against a set of rules
+ */
+ protected function validateFile($object, $attribute, $file)
+ {
+ if(null===$file || ($error=$file->getError())==UPLOAD_ERR_NO_FILE)
+ return $this->emptyAttribute($object, $attribute);
+ else if($error==UPLOAD_ERR_INI_SIZE || $error==UPLOAD_ERR_FORM_SIZE || $this->maxSize!==null && $file->getSize()>$this->maxSize)
+ {
+ $message=$this->tooLarge!==null?$this->tooLarge : Yii::t('yii','The file "{file}" is too large. Its size cannot exceed {limit} bytes.');
+ $this->addError($object,$attribute,$message,array('{file}'=>$file->getName(), '{limit}'=>$this->getSizeLimit()));
+ }
+ else if($error==UPLOAD_ERR_PARTIAL)
+ throw new CException(Yii::t('yii','The file "{file}" was only partially uploaded.',array('{file}'=>$file->getName())));
+ else if($error==UPLOAD_ERR_NO_TMP_DIR)
+ throw new CException(Yii::t('yii','Missing the temporary folder to store the uploaded file "{file}".',array('{file}'=>$file->getName())));
+ else if($error==UPLOAD_ERR_CANT_WRITE)
+ throw new CException(Yii::t('yii','Failed to write the uploaded file "{file}" to disk.',array('{file}'=>$file->getName())));
+ else if(defined('UPLOAD_ERR_EXTENSION') && $error==UPLOAD_ERR_EXTENSION) // available for PHP 5.2.0 or above
+ throw new CException(Yii::t('yii','File upload was stopped by extension.'));
+
+ if($this->minSize!==null && $file->getSize()<$this->minSize)
+ {
+ $message=$this->tooSmall!==null?$this->tooSmall : Yii::t('yii','The file "{file}" is too small. Its size cannot be smaller than {limit} bytes.');
+ $this->addError($object,$attribute,$message,array('{file}'=>$file->getName(), '{limit}'=>$this->minSize));
+ }
+
+ if($this->types!==null)
+ {
+ if(is_string($this->types))
+ $types=preg_split('/[\s,]+/',strtolower($this->types),-1,PREG_SPLIT_NO_EMPTY);
+ else
+ $types=$this->types;
+ if(!in_array(strtolower($file->getExtensionName()),$types))
+ {
+ $message=$this->wrongType!==null?$this->wrongType : Yii::t('yii','The file "{file}" cannot be uploaded. Only files with these extensions are allowed: {extensions}.');
+ $this->addError($object,$attribute,$message,array('{file}'=>$file->getName(), '{extensions}'=>implode(', ',$types)));
+ }
+ }
+ }
+
+ /**
+ * Raises an error to inform end user about blank attribute.
+ * @param CModel $object the object being validated
+ * @param string $attribute the attribute being validated
+ */
+ protected function emptyAttribute($object, $attribute)
+ {
+ if(!$this->allowEmpty)
+ {
+ $message=$this->message!==null?$this->message : Yii::t('yii','{attribute} cannot be blank.');
+ $this->addError($object,$attribute,$message);
+ }
+ }
+
+ /**
+ * Returns the maximum size allowed for uploaded files.
+ * This is determined based on three factors:
+ * <ul>
+ * <li>'upload_max_filesize' in php.ini</li>
+ * <li>'MAX_FILE_SIZE' hidden field</li>
+ * <li>{@link maxSize}</li>
+ * </ul>
+ *
+ * @return integer the size limit for uploaded files.
+ */
+ protected function getSizeLimit()
+ {
+ $limit=ini_get('upload_max_filesize');
+ $limit=$this->sizeToBytes($limit);
+ if($this->maxSize!==null && $limit>0 && $this->maxSize<$limit)
+ $limit=$this->maxSize;
+ if(isset($_POST['MAX_FILE_SIZE']) && $_POST['MAX_FILE_SIZE']>0 && $_POST['MAX_FILE_SIZE']<$limit)
+ $limit=$_POST['MAX_FILE_SIZE'];
+ return $limit;
+ }
+
+ /**
+ * Converts php.ini style size to bytes
+ *
+ * @param string $sizeStr $sizeStr
+ * @return int
+ */
+ private function sizeToBytes($sizeStr)
+ {
+ switch (substr($sizeStr, -1))
+ {
+ case 'M': case 'm': return (int)$sizeStr * 1048576;
+ case 'K': case 'k': return (int)$sizeStr * 1024;
+ case 'G': case 'g': return (int)$sizeStr * 1073741824;
+ default: return (int)$sizeStr;
+ }
+ }
+} \ No newline at end of file
diff --git a/framework/validators/CFilterValidator.php b/framework/validators/CFilterValidator.php
new file mode 100644
index 0000000..6e8f564
--- /dev/null
+++ b/framework/validators/CFilterValidator.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ * CFilterValidator class file.
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @link http://www.yiiframework.com/
+ * @copyright Copyright &copy; 2008-2011 Yii Software LLC
+ * @license http://www.yiiframework.com/license/
+ */
+
+/**
+ * CFilterValidator transforms the data being validated based on a filter.
+ *
+ * CFilterValidator is actually not a validator but a data processor.
+ * It invokes the specified filter method to process the attribute value
+ * and save the processed value back to the attribute. The filter method
+ * must follow the following signature:
+ * <pre>
+ * function foo($value) {...return $newValue; }
+ * </pre>
+ * Many PHP functions qualify this signature (e.g. trim).
+ *
+ * To specify the filter method, set {@link filter} property to be the function name.
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @version $Id: CFilterValidator.php 2799 2011-01-01 19:31:13Z qiang.xue $
+ * @package system.validators
+ * @since 1.0
+ */
+class CFilterValidator extends CValidator
+{
+ /**
+ * @var callback the filter method
+ */
+ public $filter;
+
+ /**
+ * Validates the attribute of the object.
+ * If there is any error, the error message is added to the object.
+ * @param CModel $object the object being validated
+ * @param string $attribute the attribute being validated
+ */
+ protected function validateAttribute($object,$attribute)
+ {
+ if($this->filter===null || !is_callable($this->filter))
+ throw new CException(Yii::t('yii','The "filter" property must be specified with a valid callback.'));
+ $object->$attribute=call_user_func_array($this->filter,array($object->$attribute));
+ }
+}
diff --git a/framework/validators/CInlineValidator.php b/framework/validators/CInlineValidator.php
new file mode 100644
index 0000000..f88350d
--- /dev/null
+++ b/framework/validators/CInlineValidator.php
@@ -0,0 +1,81 @@
+<?php
+/**
+ * CInlineValidator class file.
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @link http://www.yiiframework.com/
+ * @copyright Copyright &copy; 2008-2011 Yii Software LLC
+ * @license http://www.yiiframework.com/license/
+ */
+
+/**
+ * CInlineValidator represents a validator which is defined as a method in the object being validated.
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @version $Id: CInlineValidator.php 3517 2011-12-28 23:22:21Z mdomba $
+ * @package system.validators
+ * @since 1.0
+ */
+class CInlineValidator extends CValidator
+{
+ /**
+ * @var string the name of the validation method defined in the active record class
+ */
+ public $method;
+ /**
+ * @var array additional parameters that are passed to the validation method
+ */
+ public $params;
+ /**
+ * @var string the name of the method that returns the client validation code (See {@link clientValidateAttribute}).
+ */
+ public $clientValidate;
+
+ /**
+ * Validates the attribute of the object.
+ * If there is any error, the error message is added to the object.
+ * @param CModel $object the object being validated
+ * @param string $attribute the attribute being validated
+ */
+ protected function validateAttribute($object,$attribute)
+ {
+ $method=$this->method;
+ $object->$method($attribute,$this->params);
+ }
+
+ /**
+ * Returns the JavaScript code needed to perform client-side validation by calling the {@link clientValidate} method.
+ * In the client validation code, these variables are predefined:
+ * <ul>
+ * <li>value: the current input value associated with this attribute.</li>
+ * <li>messages: an array that may be appended with new error messages for the attribute.</li>
+ * <li>attribute: a data structure keeping all client-side options for the attribute</li>
+ * </ul>
+ * <b>Example</b>:
+ *
+ * If {@link clientValidate} is set to "clientValidate123", clientValidate123() is the name of
+ * the method that returns the client validation code and can look like:
+ * <pre>
+ * <?php
+ * public function clientValidate123($attribute)
+ * {
+ * $js = "if(value != '123') { messages.push('Value should be 123'); }";
+ * return $js;
+ * }
+ * ?>
+ * </pre>
+ * @param CModel $object the data object being validated
+ * @param string $attribute the name of the attribute to be validated.
+ * @return string the client-side validation script.
+ * @see CActiveForm::enableClientValidation
+ * @since 1.1.9
+ */
+ public function clientValidateAttribute($object,$attribute)
+ {
+ if($this->clientValidate!==null)
+ {
+ $method=$this->clientValidate;
+ return $object->$method($attribute);
+ }
+ }
+}
diff --git a/framework/validators/CNumberValidator.php b/framework/validators/CNumberValidator.php
new file mode 100644
index 0000000..d40322b
--- /dev/null
+++ b/framework/validators/CNumberValidator.php
@@ -0,0 +1,176 @@
+<?php
+/**
+ * CNumberValidator class file.
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @link http://www.yiiframework.com/
+ * @copyright Copyright &copy; 2008-2011 Yii Software LLC
+ * @license http://www.yiiframework.com/license/
+ */
+
+/**
+ * CNumberValidator validates that the attribute value is a number.
+ *
+ * In addition to the {@link message} property for setting a custom error message,
+ * CNumberValidator has a couple custom error messages you can set that correspond to different
+ * validation scenarios. To specify a custom message when the numeric value is too big,
+ * you may use the {@link tooBig} property. Similarly with {@link tooSmall}.
+ * The messages may contain additional placeholders that will be replaced
+ * with the actual content. In addition to the "{attribute}" placeholder, recognized by all
+ * validators (see {@link CValidator}), CNumberValidator allows for the following placeholders
+ * to be specified:
+ * <ul>
+ * <li>{min}: when using {@link tooSmall}, replaced with the lower limit of the number {@link min}.</li>
+ * <li>{max}: when using {@link tooBig}, replaced with the upper limit of the number {@link max}.</li>
+ * </ul>
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @version $Id: CNumberValidator.php 3491 2011-12-17 05:17:57Z jefftulsa $
+ * @package system.validators
+ * @since 1.0
+ */
+class CNumberValidator extends CValidator
+{
+ /**
+ * @var boolean whether the attribute value can only be an integer. Defaults to false.
+ */
+ public $integerOnly=false;
+ /**
+ * @var boolean whether the attribute value can be null or empty. Defaults to true,
+ * meaning that if the attribute is empty, it is considered valid.
+ */
+ public $allowEmpty=true;
+ /**
+ * @var integer|float upper limit of the number. Defaults to null, meaning no upper limit.
+ */
+ public $max;
+ /**
+ * @var integer|float lower limit of the number. Defaults to null, meaning no lower limit.
+ */
+ public $min;
+ /**
+ * @var string user-defined error message used when the value is too big.
+ */
+ public $tooBig;
+ /**
+ * @var string user-defined error message used when the value is too small.
+ */
+ public $tooSmall;
+ /**
+ * @var string the regular expression for matching integers.
+ * @since 1.1.7
+ */
+ public $integerPattern='/^\s*[+-]?\d+\s*$/';
+ /**
+ * @var string the regular expression for matching numbers.
+ * @since 1.1.7
+ */
+ public $numberPattern='/^\s*[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?\s*$/';
+
+
+ /**
+ * Validates the attribute of the object.
+ * If there is any error, the error message is added to the object.
+ * @param CModel $object the object being validated
+ * @param string $attribute the attribute being validated
+ */
+ protected function validateAttribute($object,$attribute)
+ {
+ $value=$object->$attribute;
+ if($this->allowEmpty && $this->isEmpty($value))
+ return;
+ if($this->integerOnly)
+ {
+ if(!preg_match($this->integerPattern,"$value"))
+ {
+ $message=$this->message!==null?$this->message:Yii::t('yii','{attribute} must be an integer.');
+ $this->addError($object,$attribute,$message);
+ }
+ }
+ else
+ {
+ if(!preg_match($this->numberPattern,"$value"))
+ {
+ $message=$this->message!==null?$this->message:Yii::t('yii','{attribute} must be a number.');
+ $this->addError($object,$attribute,$message);
+ }
+ }
+ if($this->min!==null && $value<$this->min)
+ {
+ $message=$this->tooSmall!==null?$this->tooSmall:Yii::t('yii','{attribute} is too small (minimum is {min}).');
+ $this->addError($object,$attribute,$message,array('{min}'=>$this->min));
+ }
+ if($this->max!==null && $value>$this->max)
+ {
+ $message=$this->tooBig!==null?$this->tooBig:Yii::t('yii','{attribute} is too big (maximum is {max}).');
+ $this->addError($object,$attribute,$message,array('{max}'=>$this->max));
+ }
+ }
+
+ /**
+ * Returns the JavaScript needed for performing client-side validation.
+ * @param CModel $object the data object being validated
+ * @param string $attribute the name of the attribute to be validated.
+ * @return string the client-side validation script.
+ * @see CActiveForm::enableClientValidation
+ * @since 1.1.7
+ */
+ public function clientValidateAttribute($object,$attribute)
+ {
+ $label=$object->getAttributeLabel($attribute);
+
+ if(($message=$this->message)===null)
+ $message=$this->integerOnly ? Yii::t('yii','{attribute} must be an integer.') : Yii::t('yii','{attribute} must be a number.');
+ $message=strtr($message, array(
+ '{attribute}'=>$label,
+ ));
+
+ if(($tooBig=$this->tooBig)===null)
+ $tooBig=Yii::t('yii','{attribute} is too big (maximum is {max}).');
+ $tooBig=strtr($tooBig, array(
+ '{attribute}'=>$label,
+ '{max}'=>$this->max,
+ ));
+
+ if(($tooSmall=$this->tooSmall)===null)
+ $tooSmall=Yii::t('yii','{attribute} is too small (minimum is {min}).');
+ $tooSmall=strtr($tooSmall, array(
+ '{attribute}'=>$label,
+ '{min}'=>$this->min,
+ ));
+
+ $pattern=$this->integerOnly ? $this->integerPattern : $this->numberPattern;
+ $js="
+if(!value.match($pattern)) {
+ messages.push(".CJSON::encode($message).");
+}
+";
+ if($this->min!==null)
+ {
+ $js.="
+if(value<{$this->min}) {
+ messages.push(".CJSON::encode($tooSmall).");
+}
+";
+ }
+ if($this->max!==null)
+ {
+ $js.="
+if(value>{$this->max}) {
+ messages.push(".CJSON::encode($tooBig).");
+}
+";
+ }
+
+ if($this->allowEmpty)
+ {
+ $js="
+if($.trim(value)!='') {
+ $js
+}
+";
+ }
+
+ return $js;
+ }
+}
diff --git a/framework/validators/CRangeValidator.php b/framework/validators/CRangeValidator.php
new file mode 100644
index 0000000..bc844ba
--- /dev/null
+++ b/framework/validators/CRangeValidator.php
@@ -0,0 +1,97 @@
+<?php
+/**
+ * CRangeValidator class file.
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @link http://www.yiiframework.com/
+ * @copyright Copyright &copy; 2008-2011 Yii Software LLC
+ * @license http://www.yiiframework.com/license/
+ */
+
+/**
+ * CRangeValidator validates that the attribute value is among the list (specified via {@link range}).
+ * You may invert the validation logic with help of the {@link not} property (available since 1.1.5).
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @version $Id: CRangeValidator.php 3120 2011-03-25 01:50:48Z qiang.xue $
+ * @package system.validators
+ * @since 1.0
+ */
+class CRangeValidator extends CValidator
+{
+ /**
+ * @var array list of valid values that the attribute value should be among
+ */
+ public $range;
+ /**
+ * @var boolean whether the comparison is strict (both type and value must be the same)
+ */
+ public $strict=false;
+ /**
+ * @var boolean whether the attribute value can be null or empty. Defaults to true,
+ * meaning that if the attribute is empty, it is considered valid.
+ */
+ public $allowEmpty=true;
+ /**
+ * @var boolean whether to invert the validation logic. Defaults to false. If set to true,
+ * the attribute value should NOT be among the list of values defined via {@link range}.
+ * @since 1.1.5
+ **/
+ public $not=false;
+
+ /**
+ * Validates the attribute of the object.
+ * If there is any error, the error message is added to the object.
+ * @param CModel $object the object being validated
+ * @param string $attribute the attribute being validated
+ */
+ protected function validateAttribute($object,$attribute)
+ {
+ $value=$object->$attribute;
+ if($this->allowEmpty && $this->isEmpty($value))
+ return;
+ if(!is_array($this->range))
+ throw new CException(Yii::t('yii','The "range" property must be specified with a list of values.'));
+ if(!$this->not && !in_array($value,$this->range,$this->strict))
+ {
+ $message=$this->message!==null?$this->message:Yii::t('yii','{attribute} is not in the list.');
+ $this->addError($object,$attribute,$message);
+ }
+ else if($this->not && in_array($value,$this->range,$this->strict))
+ {
+ $message=$this->message!==null?$this->message:Yii::t('yii','{attribute} is in the list.');
+ $this->addError($object,$attribute,$message);
+ }
+ }
+
+ /**
+ * Returns the JavaScript needed for performing client-side validation.
+ * @param CModel $object the data object being validated
+ * @param string $attribute the name of the attribute to be validated.
+ * @return string the client-side validation script.
+ * @see CActiveForm::enableClientValidation
+ * @since 1.1.7
+ */
+ public function clientValidateAttribute($object,$attribute)
+ {
+ if(!is_array($this->range))
+ throw new CException(Yii::t('yii','The "range" property must be specified with a list of values.'));
+
+ if(($message=$this->message)===null)
+ $message=$this->not ? Yii::t('yii','{attribute} is in the list.') : Yii::t('yii','{attribute} is not in the list.');
+ $message=strtr($message,array(
+ '{attribute}'=>$object->getAttributeLabel($attribute),
+ ));
+
+ $range=array();
+ foreach($this->range as $value)
+ $range[]=(string)$value;
+ $range=CJSON::encode($range);
+
+ return "
+if(".($this->allowEmpty ? "$.trim(value)!='' && " : '').($this->not ? "$.inArray(value, $range)>=0" : "$.inArray(value, $range)<0").") {
+ messages.push(".CJSON::encode($message).");
+}
+";
+ }
+} \ No newline at end of file
diff --git a/framework/validators/CRegularExpressionValidator.php b/framework/validators/CRegularExpressionValidator.php
new file mode 100644
index 0000000..3506d99
--- /dev/null
+++ b/framework/validators/CRegularExpressionValidator.php
@@ -0,0 +1,94 @@
+<?php
+/**
+ * CRegularExpressionValidator class file.
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @link http://www.yiiframework.com/
+ * @copyright Copyright &copy; 2008-2011 Yii Software LLC
+ * @license http://www.yiiframework.com/license/
+ */
+
+/**
+ * CRegularExpressionValidator validates that the attribute value matches to the specified {@link pattern regular expression}.
+ * You may invert the validation logic with help of the {@link not} property (available since 1.1.5).
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @version $Id: CRegularExpressionValidator.php 3120 2011-03-25 01:50:48Z qiang.xue $
+ * @package system.validators
+ * @since 1.0
+ */
+class CRegularExpressionValidator extends CValidator
+{
+ /**
+ * @var string the regular expression to be matched with
+ */
+ public $pattern;
+ /**
+ * @var boolean whether the attribute value can be null or empty. Defaults to true,
+ * meaning that if the attribute is empty, it is considered valid.
+ */
+ public $allowEmpty=true;
+ /**
+ * @var boolean whether to invert the validation logic. Defaults to false. If set to true,
+ * the regular expression defined via {@link pattern} should NOT match the attribute value.
+ * @since 1.1.5
+ **/
+ public $not=false;
+
+ /**
+ * Validates the attribute of the object.
+ * If there is any error, the error message is added to the object.
+ * @param CModel $object the object being validated
+ * @param string $attribute the attribute being validated
+ */
+ protected function validateAttribute($object,$attribute)
+ {
+ $value=$object->$attribute;
+ if($this->allowEmpty && $this->isEmpty($value))
+ return;
+ if($this->pattern===null)
+ throw new CException(Yii::t('yii','The "pattern" property must be specified with a valid regular expression.'));
+ if((!$this->not && !preg_match($this->pattern,$value)) || ($this->not && preg_match($this->pattern,$value)))
+ {
+ $message=$this->message!==null?$this->message:Yii::t('yii','{attribute} is invalid.');
+ $this->addError($object,$attribute,$message);
+ }
+ }
+
+ /**
+ * Returns the JavaScript needed for performing client-side validation.
+ * @param CModel $object the data object being validated
+ * @param string $attribute the name of the attribute to be validated.
+ * @return string the client-side validation script.
+ * @see CActiveForm::enableClientValidation
+ * @since 1.1.7
+ */
+ public function clientValidateAttribute($object,$attribute)
+ {
+ if($this->pattern===null)
+ throw new CException(Yii::t('yii','The "pattern" property must be specified with a valid regular expression.'));
+
+ $message=$this->message!==null ? $this->message : Yii::t('yii','{attribute} is invalid.');
+ $message=strtr($message, array(
+ '{attribute}'=>$object->getAttributeLabel($attribute),
+ ));
+
+ $pattern=$this->pattern;
+ $pattern=preg_replace('/\\\\x\{?([0-9a-fA-F]+)\}?/', '\u$1', $pattern);
+ $delim=substr($pattern, 0, 1);
+ $endpos=strrpos($pattern, $delim, 1);
+ $flag=substr($pattern, $endpos + 1);
+ if ($delim!=='/')
+ $pattern='/' . str_replace('/', '\\/', substr($pattern, 1, $endpos - 1)) . '/';
+ else
+ $pattern = substr($pattern, 0, $endpos + 1);
+ if (!empty($flag))
+ $pattern .= preg_replace('/[^igm]/', '', $flag);
+
+ return "
+if(".($this->allowEmpty ? "$.trim(value)!='' && " : '').($this->not ? '' : '!')."value.match($pattern)) {
+ messages.push(".CJSON::encode($message).");
+}
+";
+ }
+} \ No newline at end of file
diff --git a/framework/validators/CRequiredValidator.php b/framework/validators/CRequiredValidator.php
new file mode 100644
index 0000000..fd54629
--- /dev/null
+++ b/framework/validators/CRequiredValidator.php
@@ -0,0 +1,108 @@
+<?php
+/**
+ * CRequiredValidator class file.
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @link http://www.yiiframework.com/
+ * @copyright Copyright &copy; 2008-2011 Yii Software LLC
+ * @license http://www.yiiframework.com/license/
+ */
+
+/**
+ * CRequiredValidator validates that the specified attribute does not have null or empty value.
+ *
+ * When using the {@link message} property to define a custom error message, the message
+ * may contain additional placeholders that will be replaced with the actual content. In addition
+ * to the "{attribute}" placeholder, recognized by all validators (see {@link CValidator}),
+ * CRequiredValidator allows for the following placeholders to be specified:
+ * <ul>
+ * <li>{value}: replaced with the desired value {@link requiredValue}.</li>
+ * </ul>
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @version $Id: CRequiredValidator.php 3515 2011-12-28 12:29:24Z mdomba $
+ * @package system.validators
+ * @since 1.0
+ */
+class CRequiredValidator extends CValidator
+{
+ /**
+ * @var mixed the desired value that the attribute must have.
+ * If this is null, the validator will validate that the specified attribute does not have null or empty value.
+ * If this is set as a value that is not null, the validator will validate that
+ * the attribute has a value that is the same as this property value.
+ * Defaults to null.
+ */
+ public $requiredValue;
+ /**
+ * @var boolean whether the comparison to {@link requiredValue} is strict.
+ * When this is true, the attribute value and type must both match those of {@link requiredValue}.
+ * Defaults to false, meaning only the value needs to be matched.
+ * This property is only used when {@link requiredValue} is not null.
+ */
+ public $strict=false;
+ /**
+ * Validates the attribute of the object.
+ * If there is any error, the error message is added to the object.
+ * @param CModel $object the object being validated
+ * @param string $attribute the attribute being validated
+ */
+ protected function validateAttribute($object,$attribute)
+ {
+ $value=$object->$attribute;
+ if($this->requiredValue!==null)
+ {
+ if(!$this->strict && $value!=$this->requiredValue || $this->strict && $value!==$this->requiredValue)
+ {
+ $message=$this->message!==null?$this->message:Yii::t('yii','{attribute} must be {value}.',
+ array('{value}'=>$this->requiredValue));
+ $this->addError($object,$attribute,$message);
+ }
+ }
+ else if($this->isEmpty($value,true))
+ {
+ $message=$this->message!==null?$this->message:Yii::t('yii','{attribute} cannot be blank.');
+ $this->addError($object,$attribute,$message);
+ }
+ }
+
+ /**
+ * Returns the JavaScript needed for performing client-side validation.
+ * @param CModel $object the data object being validated
+ * @param string $attribute the name of the attribute to be validated.
+ * @return string the client-side validation script.
+ * @see CActiveForm::enableClientValidation
+ * @since 1.1.7
+ */
+ public function clientValidateAttribute($object,$attribute)
+ {
+ $message=$this->message;
+ if($this->requiredValue!==null)
+ {
+ if($message===null)
+ $message=Yii::t('yii','{attribute} must be {value}.');
+ $message=strtr($message, array(
+ '{value}'=>$this->requiredValue,
+ '{attribute}'=>$object->getAttributeLabel($attribute),
+ ));
+ return "
+if(value!=" . CJSON::encode($this->requiredValue) . ") {
+ messages.push(".CJSON::encode($message).");
+}
+";
+ }
+ else
+ {
+ if($message===null)
+ $message=Yii::t('yii','{attribute} cannot be blank.');
+ $message=strtr($message, array(
+ '{attribute}'=>$object->getAttributeLabel($attribute),
+ ));
+ return "
+if($.trim(value)=='') {
+ messages.push(".CJSON::encode($message).");
+}
+";
+ }
+ }
+}
diff --git a/framework/validators/CSafeValidator.php b/framework/validators/CSafeValidator.php
new file mode 100644
index 0000000..edcfa1e
--- /dev/null
+++ b/framework/validators/CSafeValidator.php
@@ -0,0 +1,31 @@
+<?php
+/**
+ * CSafeValidator class file.
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @link http://www.yiiframework.com/
+ * @copyright Copyright &copy; 2008-2011 Yii Software LLC
+ * @license http://www.yiiframework.com/license/
+ */
+
+/**
+ * CSafeValidator marks the associated attributes to be safe for massive assignments.
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @version $Id: CSafeValidator.php 2799 2011-01-01 19:31:13Z qiang.xue $
+ * @package system.validators
+ * @since 1.1
+ */
+class CSafeValidator extends CValidator
+{
+ /**
+ * Validates the attribute of the object.
+ * If there is any error, the error message is added to the object.
+ * @param CModel $object the object being validated
+ * @param string $attribute the attribute being validated
+ */
+ protected function validateAttribute($object,$attribute)
+ {
+ }
+}
+
diff --git a/framework/validators/CStringValidator.php b/framework/validators/CStringValidator.php
new file mode 100644
index 0000000..2553af6
--- /dev/null
+++ b/framework/validators/CStringValidator.php
@@ -0,0 +1,177 @@
+<?php
+/**
+ * CStringValidator class file.
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @link http://www.yiiframework.com/
+ * @copyright Copyright &copy; 2008-2011 Yii Software LLC
+ * @license http://www.yiiframework.com/license/
+ */
+
+/**
+ * CStringValidator validates that the attribute value is of certain length.
+ *
+ * Note, this validator should only be used with string-typed attributes.
+ *
+ * In addition to the {@link message} property for setting a custom error message,
+ * CStringValidator has a couple custom error messages you can set that correspond to different
+ * validation scenarios. For defining a custom message when the string is too short,
+ * you may use the {@link tooShort} property. Similarly with {@link tooLong}. The messages may contain
+ * placeholders that will be replaced with the actual content. In addition to the "{attribute}"
+ * placeholder, recognized by all validators (see {@link CValidator}), CStringValidator allows for the following
+ * placeholders to be specified:
+ * <ul>
+ * <li>{min}: when using {@link tooShort}, replaced with minimum length, {@link min}, if set.</li>
+ * <li>{max}: when using {@link tooLong}, replaced with the maximum length, {@link max}, if set.</li>
+ * <li>{length}: when using {@link message}, replaced with the exact required length, {@link is}, if set.</li>
+ * </ul>
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @version $Id: CStringValidator.php 3491 2011-12-17 05:17:57Z jefftulsa $
+ * @package system.validators
+ * @since 1.0
+ */
+class CStringValidator extends CValidator
+{
+ /**
+ * @var integer maximum length. Defaults to null, meaning no maximum limit.
+ */
+ public $max;
+ /**
+ * @var integer minimum length. Defaults to null, meaning no minimum limit.
+ */
+ public $min;
+ /**
+ * @var integer exact length. Defaults to null, meaning no exact length limit.
+ */
+ public $is;
+ /**
+ * @var string user-defined error message used when the value is too short.
+ */
+ public $tooShort;
+ /**
+ * @var string user-defined error message used when the value is too long.
+ */
+ public $tooLong;
+ /**
+ * @var boolean whether the attribute value can be null or empty. Defaults to true,
+ * meaning that if the attribute is empty, it is considered valid.
+ */
+ public $allowEmpty=true;
+ /**
+ * @var string the encoding of the string value to be validated (e.g. 'UTF-8').
+ * This property is used only when mbstring PHP extension is enabled.
+ * The value of this property will be used as the 2nd parameter of the
+ * mb_strlen() function. If this property is not set, the application charset
+ * will be used.
+ * If this property is set false, then strlen() will be used even if mbstring is enabled.
+ * @since 1.1.1
+ */
+ public $encoding;
+
+ /**
+ * Validates the attribute of the object.
+ * If there is any error, the error message is added to the object.
+ * @param CModel $object the object being validated
+ * @param string $attribute the attribute being validated
+ */
+ protected function validateAttribute($object,$attribute)
+ {
+ $value=$object->$attribute;
+ if($this->allowEmpty && $this->isEmpty($value))
+ return;
+
+ if(function_exists('mb_strlen') && $this->encoding!==false)
+ $length=mb_strlen($value, $this->encoding ? $this->encoding : Yii::app()->charset);
+ else
+ $length=strlen($value);
+
+ if($this->min!==null && $length<$this->min)
+ {
+ $message=$this->tooShort!==null?$this->tooShort:Yii::t('yii','{attribute} is too short (minimum is {min} characters).');
+ $this->addError($object,$attribute,$message,array('{min}'=>$this->min));
+ }
+ if($this->max!==null && $length>$this->max)
+ {
+ $message=$this->tooLong!==null?$this->tooLong:Yii::t('yii','{attribute} is too long (maximum is {max} characters).');
+ $this->addError($object,$attribute,$message,array('{max}'=>$this->max));
+ }
+ if($this->is!==null && $length!==$this->is)
+ {
+ $message=$this->message!==null?$this->message:Yii::t('yii','{attribute} is of the wrong length (should be {length} characters).');
+ $this->addError($object,$attribute,$message,array('{length}'=>$this->is));
+ }
+ }
+
+ /**
+ * Returns the JavaScript needed for performing client-side validation.
+ * @param CModel $object the data object being validated
+ * @param string $attribute the name of the attribute to be validated.
+ * @return string the client-side validation script.
+ * @see CActiveForm::enableClientValidation
+ * @since 1.1.7
+ */
+ public function clientValidateAttribute($object,$attribute)
+ {
+ $label=$object->getAttributeLabel($attribute);
+
+ if(($message=$this->message)===null)
+ $message=Yii::t('yii','{attribute} is of the wrong length (should be {length} characters).');
+ $message=strtr($message, array(
+ '{attribute}'=>$label,
+ '{length}'=>$this->is,
+ ));
+
+ if(($tooShort=$this->tooShort)===null)
+ $tooShort=Yii::t('yii','{attribute} is too short (minimum is {min} characters).');
+ $tooShort=strtr($tooShort, array(
+ '{attribute}'=>$label,
+ '{min}'=>$this->min,
+ ));
+
+ if(($tooLong=$this->tooLong)===null)
+ $tooLong=Yii::t('yii','{attribute} is too long (maximum is {max} characters).');
+ $tooLong=strtr($tooLong, array(
+ '{attribute}'=>$label,
+ '{max}'=>$this->max,
+ ));
+
+ $js='';
+ if($this->min!==null)
+ {
+ $js.="
+if(value.length<{$this->min}) {
+ messages.push(".CJSON::encode($tooShort).");
+}
+";
+ }
+ if($this->max!==null)
+ {
+ $js.="
+if(value.length>{$this->max}) {
+ messages.push(".CJSON::encode($tooLong).");
+}
+";
+ }
+ if($this->is!==null)
+ {
+ $js.="
+if(value.length!={$this->is}) {
+ messages.push(".CJSON::encode($message).");
+}
+";
+ }
+
+ if($this->allowEmpty)
+ {
+ $js="
+if($.trim(value)!='') {
+ $js
+}
+";
+ }
+
+ return $js;
+ }
+}
+
diff --git a/framework/validators/CTypeValidator.php b/framework/validators/CTypeValidator.php
new file mode 100644
index 0000000..e82c1a5
--- /dev/null
+++ b/framework/validators/CTypeValidator.php
@@ -0,0 +1,110 @@
+<?php
+/**
+ * CTypeValidator class file.
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @link http://www.yiiframework.com/
+ * @copyright Copyright &copy; 2008-2011 Yii Software LLC
+ * @license http://www.yiiframework.com/license/
+ */
+
+/**
+ * CTypeValidator verifies if the attribute is of the type specified by {@link type}.
+ *
+ * The following data types are supported:
+ * <ul>
+ * <li><b>integer</b> A 32-bit signed integer data type.</li>
+ * <li><b>float</b> A double-precision floating point number data type.</li>
+ * <li><b>string</b> A string data type.</li>
+ * <li><b>array</b> An array value. </li>
+ * <li><b>date</b> A date data type.</li>
+ * <li><b>time</b> A time data type.</li>
+ * <li><b>datetime</b> A date and time data type.</li>
+ * </ul>
+ *
+ * For <b>date</b> type, the property {@link dateFormat}
+ * will be used to determine how to parse the date string. If the given date
+ * value doesn't follow the format, the attribute is considered as invalid.
+ *
+ * Starting from version 1.1.7, we have a dedicated date validator {@link CDateValidator}.
+ * Please consider using this validator to validate a date-typed value.
+ *
+ * When using the {@link message} property to define a custom error message, the message
+ * may contain additional placeholders that will be replaced with the actual content. In addition
+ * to the "{attribute}" placeholder, recognized by all validators (see {@link CValidator}),
+ * CTypeValidator allows for the following placeholders to be specified:
+ * <ul>
+ * <li>{type}: replaced with data type the attribute should be {@link type}.</li>
+ * </ul>
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @version $Id: CTypeValidator.php 3515 2011-12-28 12:29:24Z mdomba $
+ * @package system.validators
+ * @since 1.0
+ */
+class CTypeValidator extends CValidator
+{
+ /**
+ * @var string the data type that the attribute should be. Defaults to 'string'.
+ * Valid values include 'string', 'integer', 'float', 'array', 'date', 'time' and 'datetime'.
+ */
+ public $type='string';
+ /**
+ * @var string the format pattern that the date value should follow. Defaults to 'MM/dd/yyyy'.
+ * Please see {@link CDateTimeParser} for details about how to specify a date format.
+ * This property is effective only when {@link type} is 'date'.
+ */
+ public $dateFormat='MM/dd/yyyy';
+ /**
+ * @var string the format pattern that the time value should follow. Defaults to 'hh:mm'.
+ * Please see {@link CDateTimeParser} for details about how to specify a time format.
+ * This property is effective only when {@link type} is 'time'.
+ */
+ public $timeFormat='hh:mm';
+ /**
+ * @var string the format pattern that the datetime value should follow. Defaults to 'MM/dd/yyyy hh:mm'.
+ * Please see {@link CDateTimeParser} for details about how to specify a datetime format.
+ * This property is effective only when {@link type} is 'datetime'.
+ */
+ public $datetimeFormat='MM/dd/yyyy hh:mm';
+ /**
+ * @var boolean whether the attribute value can be null or empty. Defaults to true,
+ * meaning that if the attribute is empty, it is considered valid.
+ */
+ public $allowEmpty=true;
+
+ /**
+ * Validates the attribute of the object.
+ * If there is any error, the error message is added to the object.
+ * @param CModel $object the object being validated
+ * @param string $attribute the attribute being validated
+ */
+ protected function validateAttribute($object,$attribute)
+ {
+ $value=$object->$attribute;
+ if($this->allowEmpty && $this->isEmpty($value))
+ return;
+
+ if($this->type==='integer')
+ $valid=preg_match('/^[-+]?[0-9]+$/',trim($value));
+ else if($this->type==='float')
+ $valid=preg_match('/^[-+]?([0-9]*\.)?[0-9]+([eE][-+]?[0-9]+)?$/',trim($value));
+ else if($this->type==='date')
+ $valid=CDateTimeParser::parse($value,$this->dateFormat,array('month'=>1,'day'=>1,'hour'=>0,'minute'=>0,'second'=>0))!==false;
+ else if($this->type==='time')
+ $valid=CDateTimeParser::parse($value,$this->timeFormat)!==false;
+ else if($this->type==='datetime')
+ $valid=CDateTimeParser::parse($value,$this->datetimeFormat, array('month'=>1,'day'=>1,'hour'=>0,'minute'=>0,'second'=>0))!==false;
+ else if($this->type==='array')
+ $valid=is_array($value);
+ else
+ return;
+
+ if(!$valid)
+ {
+ $message=$this->message!==null?$this->message : Yii::t('yii','{attribute} must be {type}.');
+ $this->addError($object,$attribute,$message,array('{type}'=>$this->type));
+ }
+ }
+}
+
diff --git a/framework/validators/CUniqueValidator.php b/framework/validators/CUniqueValidator.php
new file mode 100644
index 0000000..d48b35f
--- /dev/null
+++ b/framework/validators/CUniqueValidator.php
@@ -0,0 +1,129 @@
+<?php
+/**
+ * CUniqueValidator class file.
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @link http://www.yiiframework.com/
+ * @copyright Copyright &copy; 2008-2011 Yii Software LLC
+ * @license http://www.yiiframework.com/license/
+ */
+
+/**
+ * CUniqueValidator validates that the attribute value is unique in the corresponding database table.
+ *
+ * When using the {@link message} property to define a custom error message, the message
+ * may contain additional placeholders that will be replaced with the actual content. In addition
+ * to the "{attribute}" placeholder, recognized by all validators (see {@link CValidator}),
+ * CUniqueValidator allows for the following placeholders to be specified:
+ * <ul>
+ * <li>{value}: replaced with current value of the attribute.</li>
+ * </ul>
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @version $Id: CUniqueValidator.php 3549 2012-01-27 15:36:43Z qiang.xue $
+ * @package system.validators
+ * @since 1.0
+ */
+class CUniqueValidator extends CValidator
+{
+ /**
+ * @var boolean whether the comparison is case sensitive. Defaults to true.
+ * Note, by setting it to false, you are assuming the attribute type is string.
+ */
+ public $caseSensitive=true;
+ /**
+ * @var boolean whether the attribute value can be null or empty. Defaults to true,
+ * meaning that if the attribute is empty, it is considered valid.
+ */
+ public $allowEmpty=true;
+ /**
+ * @var string the ActiveRecord class name that should be used to
+ * look for the attribute value being validated. Defaults to null, meaning using
+ * the class of the object currently being validated.
+ * You may use path alias to reference a class name here.
+ * @see attributeName
+ */
+ public $className;
+ /**
+ * @var string the ActiveRecord class attribute name that should be
+ * used to look for the attribute value being validated. Defaults to null,
+ * meaning using the name of the attribute being validated.
+ * @see className
+ */
+ public $attributeName;
+ /**
+ * @var array additional query criteria. This will be combined with the condition
+ * that checks if the attribute value exists in the corresponding table column.
+ * This array will be used to instantiate a {@link CDbCriteria} object.
+ */
+ public $criteria=array();
+ /**
+ * @var string the user-defined error message. The placeholders "{attribute}" and "{value}"
+ * are recognized, which will be replaced with the actual attribute name and value, respectively.
+ */
+ public $message;
+ /**
+ * @var boolean whether this validation rule should be skipped if when there is already a validation
+ * error for the current attribute. Defaults to true.
+ * @since 1.1.1
+ */
+ public $skipOnError=true;
+
+
+ /**
+ * Validates the attribute of the object.
+ * If there is any error, the error message is added to the object.
+ * @param CModel $object the object being validated
+ * @param string $attribute the attribute being validated
+ */
+ protected function validateAttribute($object,$attribute)
+ {
+ $value=$object->$attribute;
+ if($this->allowEmpty && $this->isEmpty($value))
+ return;
+
+ $className=$this->className===null?get_class($object):Yii::import($this->className);
+ $attributeName=$this->attributeName===null?$attribute:$this->attributeName;
+ $finder=CActiveRecord::model($className);
+ $table=$finder->getTableSchema();
+ if(($column=$table->getColumn($attributeName))===null)
+ throw new CException(Yii::t('yii','Table "{table}" does not have a column named "{column}".',
+ array('{column}'=>$attributeName,'{table}'=>$table->name)));
+
+ $columnName=$column->rawName;
+ $criteria=new CDbCriteria(array(
+ 'condition'=>$this->caseSensitive ? "$columnName=:value" : "LOWER($columnName)=LOWER(:value)",
+ 'params'=>array(':value'=>$value),
+ ));
+ if($this->criteria!==array())
+ $criteria->mergeWith($this->criteria);
+
+ if(!$object instanceof CActiveRecord || $object->isNewRecord || $object->tableName()!==$finder->tableName())
+ $exists=$finder->exists($criteria);
+ else
+ {
+ $criteria->limit=2;
+ $objects=$finder->findAll($criteria);
+ $n=count($objects);
+ if($n===1)
+ {
+ if($column->isPrimaryKey) // primary key is modified and not unique
+ $exists=$object->getOldPrimaryKey()!=$object->getPrimaryKey();
+ else
+ {
+ // non-primary key, need to exclude the current record based on PK
+ $exists=array_shift($objects)->getPrimaryKey()!=$object->getOldPrimaryKey();
+ }
+ }
+ else
+ $exists=$n>1;
+ }
+
+ if($exists)
+ {
+ $message=$this->message!==null?$this->message:Yii::t('yii','{attribute} "{value}" has already been taken.');
+ $this->addError($object,$attribute,$message,array('{value}'=>CHtml::encode($value)));
+ }
+ }
+}
+
diff --git a/framework/validators/CUnsafeValidator.php b/framework/validators/CUnsafeValidator.php
new file mode 100644
index 0000000..c92f26c
--- /dev/null
+++ b/framework/validators/CUnsafeValidator.php
@@ -0,0 +1,37 @@
+<?php
+/**
+ * CUnsafeValidator class file.
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @link http://www.yiiframework.com/
+ * @copyright Copyright &copy; 2008-2011 Yii Software LLC
+ * @license http://www.yiiframework.com/license/
+ */
+
+/**
+ * CUnsafeValidator marks the associated attributes to be unsafe so that they cannot be massively assigned.
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @version $Id: CUnsafeValidator.php 2799 2011-01-01 19:31:13Z qiang.xue $
+ * @package system.validators
+ * @since 1.0
+ */
+class CUnsafeValidator extends CValidator
+{
+ /**
+ * @var boolean whether attributes listed with this validator should be considered safe for massive assignment.
+ * Defaults to false.
+ * @since 1.1.4
+ */
+ public $safe=false;
+ /**
+ * Validates the attribute of the object.
+ * If there is any error, the error message is added to the object.
+ * @param CModel $object the object being validated
+ * @param string $attribute the attribute being validated
+ */
+ protected function validateAttribute($object,$attribute)
+ {
+ }
+}
+
diff --git a/framework/validators/CUrlValidator.php b/framework/validators/CUrlValidator.php
new file mode 100644
index 0000000..0ee080e
--- /dev/null
+++ b/framework/validators/CUrlValidator.php
@@ -0,0 +1,139 @@
+<?php
+/**
+ * CUrlValidator class file.
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @link http://www.yiiframework.com/
+ * @copyright Copyright &copy; 2008-2011 Yii Software LLC
+ * @license http://www.yiiframework.com/license/
+ */
+
+/**
+ * CUrlValidator validates that the attribute value is a valid http or https URL.
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @version $Id: CUrlValidator.php 3242 2011-05-28 14:31:04Z qiang.xue $
+ * @package system.validators
+ * @since 1.0
+ */
+class CUrlValidator extends CValidator
+{
+ /**
+ * @var string the regular expression used to validate the attribute value.
+ * Since version 1.1.7 the pattern may contain a {schemes} token that will be replaced
+ * by a regular expression which represents the {@see validSchemes}.
+ */
+ public $pattern='/^{schemes}:\/\/(([A-Z0-9][A-Z0-9_-]*)(\.[A-Z0-9][A-Z0-9_-]*)+)/i';
+ /**
+ * @var array list of URI schemes which should be considered valid. By default, http and https
+ * are considered to be valid schemes.
+ * @since 1.1.7
+ **/
+ public $validSchemes=array('http','https');
+ /**
+ * @var string the default URI scheme. If the input doesn't contain the scheme part, the default
+ * scheme will be prepended to it (thus changing the input). Defaults to null, meaning a URL must
+ * contain the scheme part.
+ * @since 1.1.7
+ **/
+ public $defaultScheme;
+ /**
+ * @var boolean whether the attribute value can be null or empty. Defaults to true,
+ * meaning that if the attribute is empty, it is considered valid.
+ */
+ public $allowEmpty=true;
+
+ /**
+ * Validates the attribute of the object.
+ * If there is any error, the error message is added to the object.
+ * @param CModel $object the object being validated
+ * @param string $attribute the attribute being validated
+ */
+ protected function validateAttribute($object,$attribute)
+ {
+ $value=$object->$attribute;
+ if($this->allowEmpty && $this->isEmpty($value))
+ return;
+ if(($value=$this->validateValue($value))!==false)
+ $object->$attribute=$value;
+ else
+ {
+ $message=$this->message!==null?$this->message:Yii::t('yii','{attribute} is not a valid URL.');
+ $this->addError($object,$attribute,$message);
+ }
+ }
+
+ /**
+ * Validates a static value to see if it is a valid URL.
+ * Note that this method does not respect {@link allowEmpty} property.
+ * This method is provided so that you can call it directly without going through the model validation rule mechanism.
+ * @param mixed $value the value to be validated
+ * @return mixed false if the the value is not a valid URL, otherwise the possibly modified value ({@see defaultScheme})
+ * @since 1.1.1
+ */
+ public function validateValue($value)
+ {
+ if(is_string($value) && strlen($value)<2000) // make sure the length is limited to avoid DOS attacks
+ {
+ if($this->defaultScheme!==null && strpos($value,'://')===false)
+ $value=$this->defaultScheme.'://'.$value;
+
+ if(strpos($this->pattern,'{schemes}')!==false)
+ $pattern=str_replace('{schemes}','('.implode('|',$this->validSchemes).')',$this->pattern);
+ else
+ $pattern=$this->pattern;
+
+ if(preg_match($pattern,$value))
+ return $value;
+ }
+ return false;
+ }
+
+ /**
+ * Returns the JavaScript needed for performing client-side validation.
+ * @param CModel $object the data object being validated
+ * @param string $attribute the name of the attribute to be validated.
+ * @return string the client-side validation script.
+ * @see CActiveForm::enableClientValidation
+ * @since 1.1.7
+ */
+ public function clientValidateAttribute($object,$attribute)
+ {
+ $message=$this->message!==null ? $this->message : Yii::t('yii','{attribute} is not a valid URL.');
+ $message=strtr($message, array(
+ '{attribute}'=>$object->getAttributeLabel($attribute),
+ ));
+
+ if(strpos($this->pattern,'{schemes}')!==false)
+ $pattern=str_replace('{schemes}','('.implode('|',$this->validSchemes).')',$this->pattern);
+ else
+ $pattern=$this->pattern;
+
+ $js="
+if(!value.match($pattern)) {
+ messages.push(".CJSON::encode($message).");
+}
+";
+ if($this->defaultScheme!==null)
+ {
+ $js="
+if(!value.match(/:\\/\\//)) {
+ value=".CJSON::encode($this->defaultScheme)."+'://'+value;
+}
+$js
+";
+ }
+
+ if($this->allowEmpty)
+ {
+ $js="
+if($.trim(value)!='') {
+ $js
+}
+";
+ }
+
+ return $js;
+ }
+}
+
diff --git a/framework/validators/CValidator.php b/framework/validators/CValidator.php
new file mode 100644
index 0000000..45e5bd1
--- /dev/null
+++ b/framework/validators/CValidator.php
@@ -0,0 +1,261 @@
+<?php
+/**
+ * CValidator class file.
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @link http://www.yiiframework.com/
+ * @copyright Copyright &copy; 2008-2011 Yii Software LLC
+ * @license http://www.yiiframework.com/license/
+ */
+
+/**
+ * CValidator is the base class for all validators.
+ *
+ * Child classes must implement the {@link validateAttribute} method.
+ *
+ * The following properties are defined in CValidator:
+ * <ul>
+ * <li>{@link attributes}: array, list of attributes to be validated;</li>
+ * <li>{@link message}: string, the customized error message. The message
+ * may contain placeholders that will be replaced with the actual content.
+ * For example, the "{attribute}" placeholder will be replaced with the label
+ * of the problematic attribute. Different validators may define additional
+ * placeholders.</li>
+ * <li>{@link on}: string, in which scenario should the validator be in effect.
+ * This is used to match the 'on' parameter supplied when calling {@link CModel::validate}.</li>
+ * </ul>
+ *
+ * When using {@link createValidator} to create a validator, the following aliases
+ * are recognized as the corresponding built-in validator classes:
+ * <ul>
+ * <li>required: {@link CRequiredValidator}</li>
+ * <li>filter: {@link CFilterValidator}</li>
+ * <li>match: {@link CRegularExpressionValidator}</li>
+ * <li>email: {@link CEmailValidator}</li>
+ * <li>url: {@link CUrlValidator}</li>
+ * <li>unique: {@link CUniqueValidator}</li>
+ * <li>compare: {@link CCompareValidator}</li>
+ * <li>length: {@link CStringValidator}</li>
+ * <li>in: {@link CRangeValidator}</li>
+ * <li>numerical: {@link CNumberValidator}</li>
+ * <li>captcha: {@link CCaptchaValidator}</li>
+ * <li>type: {@link CTypeValidator}</li>
+ * <li>file: {@link CFileValidator}</li>
+ * <li>default: {@link CDefaultValueValidator}</li>
+ * <li>exist: {@link CExistValidator}</li>
+ * <li>boolean: {@link CBooleanValidator}</li>
+ * <li>date: {@link CDateValidator}</li>
+ * <li>safe: {@link CSafeValidator}</li>
+ * <li>unsafe: {@link CUnsafeValidator}</li>
+ * </ul>
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @version $Id: CValidator.php 3515 2011-12-28 12:29:24Z mdomba $
+ * @package system.validators
+ * @since 1.0
+ */
+abstract class CValidator extends CComponent
+{
+ /**
+ * @var array list of built-in validators (name=>class)
+ */
+ public static $builtInValidators=array(
+ 'required'=>'CRequiredValidator',
+ 'filter'=>'CFilterValidator',
+ 'match'=>'CRegularExpressionValidator',
+ 'email'=>'CEmailValidator',
+ 'url'=>'CUrlValidator',
+ 'unique'=>'CUniqueValidator',
+ 'compare'=>'CCompareValidator',
+ 'length'=>'CStringValidator',
+ 'in'=>'CRangeValidator',
+ 'numerical'=>'CNumberValidator',
+ 'captcha'=>'CCaptchaValidator',
+ 'type'=>'CTypeValidator',
+ 'file'=>'CFileValidator',
+ 'default'=>'CDefaultValueValidator',
+ 'exist'=>'CExistValidator',
+ 'boolean'=>'CBooleanValidator',
+ 'safe'=>'CSafeValidator',
+ 'unsafe'=>'CUnsafeValidator',
+ 'date'=>'CDateValidator',
+ );
+
+ /**
+ * @var array list of attributes to be validated.
+ */
+ public $attributes;
+ /**
+ * @var string the user-defined error message. Different validators may define various
+ * placeholders in the message that are to be replaced with actual values. All validators
+ * recognize "{attribute}" placeholder, which will be replaced with the label of the attribute.
+ */
+ public $message;
+ /**
+ * @var boolean whether this validation rule should be skipped when there is already a validation
+ * error for the current attribute. Defaults to false.
+ * @since 1.1.1
+ */
+ public $skipOnError=false;
+ /**
+ * @var array list of scenarios that the validator should be applied.
+ * Each array value refers to a scenario name with the same name as its array key.
+ */
+ public $on;
+ /**
+ * @var boolean whether attributes listed with this validator should be considered safe for massive assignment.
+ * Defaults to true.
+ * @since 1.1.4
+ */
+ public $safe=true;
+ /**
+ * @var boolean whether to perform client-side validation. Defaults to true.
+ * Please refer to {@link CActiveForm::enableClientValidation} for more details about client-side validation.
+ * @since 1.1.7
+ */
+ public $enableClientValidation=true;
+
+ /**
+ * Validates a single attribute.
+ * This method should be overridden by child classes.
+ * @param CModel $object the data object being validated
+ * @param string $attribute the name of the attribute to be validated.
+ */
+ abstract protected function validateAttribute($object,$attribute);
+
+
+ /**
+ * Creates a validator object.
+ * @param string $name the name or class of the validator
+ * @param CModel $object the data object being validated that may contain the inline validation method
+ * @param mixed $attributes list of attributes to be validated. This can be either an array of
+ * the attribute names or a string of comma-separated attribute names.
+ * @param array $params initial values to be applied to the validator properties
+ * @return CValidator the validator
+ */
+ public static function createValidator($name,$object,$attributes,$params=array())
+ {
+ if(is_string($attributes))
+ $attributes=preg_split('/[\s,]+/',$attributes,-1,PREG_SPLIT_NO_EMPTY);
+
+ if(isset($params['on']))
+ {
+ if(is_array($params['on']))
+ $on=$params['on'];
+ else
+ $on=preg_split('/[\s,]+/',$params['on'],-1,PREG_SPLIT_NO_EMPTY);
+ }
+ else
+ $on=array();
+
+ if(method_exists($object,$name))
+ {
+ $validator=new CInlineValidator;
+ $validator->attributes=$attributes;
+ $validator->method=$name;
+ if(isset($params['clientValidate']))
+ {
+ $validator->clientValidate=$params['clientValidate'];
+ unset($params['clientValidate']);
+ }
+ $validator->params=$params;
+ if(isset($params['skipOnError']))
+ $validator->skipOnError=$params['skipOnError'];
+ }
+ else
+ {
+ $params['attributes']=$attributes;
+ if(isset(self::$builtInValidators[$name]))
+ $className=Yii::import(self::$builtInValidators[$name],true);
+ else
+ $className=Yii::import($name,true);
+ $validator=new $className;
+ foreach($params as $name=>$value)
+ $validator->$name=$value;
+ }
+
+ $validator->on=empty($on) ? array() : array_combine($on,$on);
+
+ return $validator;
+ }
+
+ /**
+ * Validates the specified object.
+ * @param CModel $object the data object being validated
+ * @param array $attributes the list of attributes to be validated. Defaults to null,
+ * meaning every attribute listed in {@link attributes} will be validated.
+ */
+ public function validate($object,$attributes=null)
+ {
+ if(is_array($attributes))
+ $attributes=array_intersect($this->attributes,$attributes);
+ else
+ $attributes=$this->attributes;
+ foreach($attributes as $attribute)
+ {
+ if(!$this->skipOnError || !$object->hasErrors($attribute))
+ $this->validateAttribute($object,$attribute);
+ }
+ }
+
+ /**
+ * Returns the JavaScript needed for performing client-side validation.
+ * Do not override this method if the validator does not support client-side validation.
+ * Two predefined JavaScript variables can be used:
+ * <ul>
+ * <li>value: the value to be validated</li>
+ * <li>messages: an array used to hold the validation error messages for the value</li>
+ * </ul>
+ * @param CModel $object the data object being validated
+ * @param string $attribute the name of the attribute to be validated.
+ * @return string the client-side validation script. Null if the validator does not support client-side validation.
+ * @see CActiveForm::enableClientValidation
+ * @since 1.1.7
+ */
+ public function clientValidateAttribute($object,$attribute)
+ {
+ }
+
+ /**
+ * Returns a value indicating whether the validator applies to the specified scenario.
+ * A validator applies to a scenario as long as any of the following conditions is met:
+ * <ul>
+ * <li>the validator's "on" property is empty</li>
+ * <li>the validator's "on" property contains the specified scenario</li>
+ * </ul>
+ * @param string $scenario scenario name
+ * @return boolean whether the validator applies to the specified scenario.
+ */
+ public function applyTo($scenario)
+ {
+ return empty($this->on) || isset($this->on[$scenario]);
+ }
+
+ /**
+ * Adds an error about the specified attribute to the active record.
+ * This is a helper method that performs message selection and internationalization.
+ * @param CModel $object the data object being validated
+ * @param string $attribute the attribute being validated
+ * @param string $message the error message
+ * @param array $params values for the placeholders in the error message
+ */
+ protected function addError($object,$attribute,$message,$params=array())
+ {
+ $params['{attribute}']=$object->getAttributeLabel($attribute);
+ $object->addError($attribute,strtr($message,$params));
+ }
+
+ /**
+ * Checks if the given value is empty.
+ * A value is considered empty if it is null, an empty array, or the trimmed result is an empty string.
+ * Note that this method is different from PHP empty(). It will return false when the value is 0.
+ * @param mixed $value the value to be checked
+ * @param boolean $trim whether to perform trimming before checking if the string is empty. Defaults to false.
+ * @return boolean whether the value is empty
+ */
+ protected function isEmpty($value,$trim=false)
+ {
+ return $value===null || $value===array() || $value==='' || $trim && is_scalar($value) && trim($value)==='';
+ }
+}
+