Browse Source

w

tags/2.0.0-beta
Qiang Xue 14 years ago
parent
commit
b51c3bc77c
  1. 85
      framework/validators/BooleanValidator.php
  2. 123
      framework/validators/CaptchaValidator.php
  3. 209
      framework/validators/CompareValidator.php
  4. 76
      framework/validators/DateValidator.php
  5. 51
      framework/validators/DefaultValueValidator.php
  6. 121
      framework/validators/EmailValidator.php
  7. 86
      framework/validators/ExistValidator.php
  8. 235
      framework/validators/FileValidator.php
  9. 49
      framework/validators/FilterValidator.php
  10. 41
      framework/validators/InlineValidator.php
  11. 163
      framework/validators/NumberValidator.php
  12. 97
      framework/validators/RangeValidator.php
  13. 94
      framework/validators/RegularExpressionValidator.php
  14. 102
      framework/validators/RequiredValidator.php
  15. 31
      framework/validators/SafeValidator.php
  16. 164
      framework/validators/StringValidator.php
  17. 105
      framework/validators/TypeValidator.php
  18. 124
      framework/validators/UniqueValidator.php
  19. 37
      framework/validators/UnsafeValidator.php
  20. 139
      framework/validators/UrlValidator.php
  21. 258
      framework/validators/Validator.php

85
framework/validators/BooleanValidator.php

@ -0,0 +1,85 @@
<?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}.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @version $Id: CBooleanValidator.php 3120 2011-03-25 01:50:48Z qiang.xue $
* @package system.validators
* @since 1.0.10
*/
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) . ");
}
";
}
}

123
framework/validators/CaptchaValidator.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;
}
}

209
framework/validators/CompareValidator.php

@ -0,0 +1,209 @@
<?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.
*
* Starting from version 1.0.8, CCompareValidator supports different comparison operators.
* Previously, it only compares to see if two values are equal or not.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @version $Id: CCompareValidator.php 3120 2011-03-25 01:50:48Z qiang.xue $
* @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>
* @since 1.0.8
*/
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 = 'value<=' . $compareValue;
break;
case '>=':
if ($message === null)
$message = Yii::t('yii', '{attribute} must be greater than or equal to "{compareValue}".');
$condition = 'value<' . $compareValue;
break;
case '<':
if ($message === null)
$message = Yii::t('yii', '{attribute} must be less than "{compareValue}".');
$condition = 'value>=' . $compareValue;
break;
case '<=':
if ($message === null)
$message = Yii::t('yii', '{attribute} must be less than or equal to "{compareValue}".');
$condition = 'value>' . $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) . ");
}
";
}
}

76
framework/validators/DateValidator.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);
}
}
}

51
framework/validators/DefaultValueValidator.php

@ -0,0 +1,51 @@
<?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 2799 2011-01-01 19:31:13Z qiang.xue $
* @package system.validators
* @since 1.0.2
*/
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;
}
}
}

121
framework/validators/EmailValidator.php

@ -0,0 +1,121 @@
<?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 3242 2011-05-28 14:31:04Z qiang.xue $
* @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.
* @since 1.0.5
* @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.
* @since 1.0.5
* @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.
* @since 1.0.4
*/
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) . ");
}
";
}
}

86
framework/validators/ExistValidator.php

@ -0,0 +1,86 @@
<?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.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @version $Id: CExistValidator.php 2799 2011-01-01 19:31:13Z qiang.xue $
* @package system.validators
* @since 1.0.4
*/
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.
* @since 1.0.8
*/
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}' => $value));
}
}
}

235
framework/validators/FileValidator.php

@ -0,0 +1,235 @@
<?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.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @version $Id: CFileValidator.php 2799 2011-01-01 19:31:13Z qiang.xue $
* @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);
elseif ($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()));
}
elseif ($error == UPLOAD_ERR_PARTIAL)
throw new CException(Yii::t('yii', 'The file "{file}" was only partially uploaded.', array('{file}' => $file->getName())));
elseif ($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())));
elseif ($error == UPLOAD_ERR_CANT_WRITE)
throw new CException(Yii::t('yii', 'Failed to write the uploaded file "{file}" to disk.', array('{file}' => $file->getName())));
elseif (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;
}
}
}

49
framework/validators/FilterValidator.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));
}
}

41
framework/validators/InlineValidator.php

@ -0,0 +1,41 @@
<?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 2799 2011-01-01 19:31:13Z qiang.xue $
* @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;
/**
* 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);
}
}

163
framework/validators/NumberValidator.php

@ -0,0 +1,163 @@
<?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.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @version $Id: CNumberValidator.php 3190 2011-04-16 23:40:21Z qiang.xue $
* @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;
}
}

97
framework/validators/RangeValidator.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);
}
elseif ($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) . ");
}
";
}
}

94
framework/validators/RegularExpressionValidator.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) . ");
}
";
}
}

102
framework/validators/RequiredValidator.php

@ -0,0 +1,102 @@
<?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.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @version $Id: CRequiredValidator.php 3157 2011-04-02 19:21:06Z qiang.xue $
* @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.
* @since 1.0.10
*/
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.
* @since 1.0.10
*/
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);
}
}
elseif ($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) . ");
}
";
}
}
}

31
framework/validators/SafeValidator.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)
{
}
}

164
framework/validators/StringValidator.php

@ -0,0 +1,164 @@
<?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.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @version $Id: CStringValidator.php 3148 2011-03-31 21:44:00Z alexander.makarow $
* @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;
}
}

105
framework/validators/TypeValidator.php

@ -0,0 +1,105 @@
<?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 (available since version 1.0.5).</li>
* <li><b>datetime</b> A date and time data type (available since version 1.0.5).</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.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @version $Id: CTypeValidator.php 3052 2011-03-12 14:27:07Z qiang.xue $
* @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'.
* Note that 'time' and 'datetime' have been available since version 1.0.5.
*/
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'.
* @since 1.0.5
*/
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'.
* @since 1.0.5
*/
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));
elseif ($this->type === 'float')
$valid = preg_match('/^[-+]?([0-9]*\.)?[0-9]+([eE][-+]?[0-9]+)?$/', trim($value));
elseif ($this->type === 'date')
$valid = CDateTimeParser::parse($value, $this->dateFormat, array('month' => 1, 'day' => 1, 'hour' => 0, 'minute' => 0, 'second' => 0)) !== false;
elseif ($this->type === 'time')
$valid = CDateTimeParser::parse($value, $this->timeFormat) !== false;
elseif ($this->type === 'datetime')
$valid = CDateTimeParser::parse($value, $this->datetimeFormat, array('month' => 1, 'day' => 1, 'hour' => 0, 'minute' => 0, 'second' => 0)) !== false;
elseif ($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));
}
}
}

124
framework/validators/UniqueValidator.php

@ -0,0 +1,124 @@
<?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.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @version $Id: CUniqueValidator.php 3260 2011-06-13 20:56:54Z alexander.makarow $
* @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
* @since 1.0.8
*/
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
* @since 1.0.8
*/
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.
* @since 1.0.8
*/
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}' => $value));
}
}
}

37
framework/validators/UnsafeValidator.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)
{
}
}

139
framework/validators/UrlValidator.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;
}
}

258
framework/validators/Validator.php

@ -0,0 +1,258 @@
<?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 3160 2011-04-03 01:08:23Z qiang.xue $
* @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 if 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;
$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.
* @since 1.0.2
*/
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
* @since 1.0.9
*/
protected function isEmpty($value, $trim = false)
{
return $value === null || $value === array() || $value === '' || $trim && is_scalar($value) && trim($value) === '';
}
}
Loading…
Cancel
Save