1
0

Added new (clean) yii boilerplate

This commit is contained in:
2014-05-13 12:40:42 +02:00
parent 1d6d975a16
commit 99d29b432b
1983 changed files with 653465 additions and 17 deletions

View File

@@ -0,0 +1,92 @@
<?php
/**
* CBooleanValidator class file.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @link http://www.yiiframework.com/
* @copyright 2008-2013 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>
* @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 ? "jQuery.trim(value)!='' && " : '')."value!=".CJSON::encode($this->trueValue)." && value!=".CJSON::encode($this->falseValue).") {
messages.push(".CJSON::encode($message).");
}
";
}
}

View File

@@ -0,0 +1,124 @@
<?php
/**
* CCaptchaValidator class file.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @link http://www.yiiframework.com/
* @copyright 2008-2013 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>
* @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();
// reason of array checking is explained here: https://github.com/yiisoft/yii/issues/1955
if(is_array($value) || !$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.
* @throws CException if {@link action} is invalid
* @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 = jQuery('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(jQuery.trim(value)!='') {
$js
}
";
}
return $js;
}
}

View File

@@ -0,0 +1,202 @@
<?php
/**
* CCompareValidator class file.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @link http://www.yiiframework.com/
* @copyright 2008-2013 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>
* <li>{compareAttribute}: replaced with the label of the attribute being compared with ({@link compareAttribute}).</li>
* </ul>
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @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
* @throws CException if invalid operator is used
*/
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.');
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}".');
break;
case '>':
if($value<=$compareValue)
$message=$this->message!==null?$this->message:Yii::t('yii','{attribute} must be greater than "{compareValue}".');
break;
case '>=':
if($value<$compareValue)
$message=$this->message!==null?$this->message:Yii::t('yii','{attribute} must be greater than or equal to "{compareValue}".');
break;
case '<':
if($value>=$compareValue)
$message=$this->message!==null?$this->message:Yii::t('yii','{attribute} must be less than "{compareValue}".');
break;
case '<=':
if($value>$compareValue)
$message=$this->message!==null?$this->message:Yii::t('yii','{attribute} must be less than or equal to "{compareValue}".');
break;
default:
throw new CException(Yii::t('yii','Invalid operator "{operator}".',array('{operator}'=>$this->operator)));
}
if(!empty($message))
$this->addError($object,$attribute,$message,array('{compareAttribute}'=>$compareTo,'{compareValue}'=>$compareValue));
}
/**
* 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.
* @throws CException if invalid operator is used
* @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="jQuery('#" . (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),
'{compareAttribute}'=>$compareTo,
));
return "
if(".($this->allowEmpty ? "jQuery.trim(value)!='' && " : '').$condition.") {
messages.push(".CJSON::encode($message).".replace('{compareValue}', ".$compareValue."));
}
";
}
}

View File

@@ -0,0 +1,81 @@
<?php
/**
* CDateValidator class file.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @link http://www.yiiframework.com/
* @copyright 2008-2013 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;
$valid=false;
// reason of array checking is explained here: https://github.com/yiisoft/yii/issues/1955
if(!is_array($value))
{
$formats=is_string($this->format) ? array($this->format) : $this->format;
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);
}
}
}

View File

@@ -0,0 +1,50 @@
<?php
/**
* CDefaultValueValidator class file.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @link http://www.yiiframework.com/
* @copyright 2008-2013 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
/**
* CDefaultValueValidator sets the attributes with the specified value.
* It does not do validation but rather allows setting a default value at the
* same time validation is performed. Usually this happens when calling either
* <code>$model->validate()</code> or <code>$model->save()</code>.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @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;
}
}
}

View File

@@ -0,0 +1,204 @@
<?php
/**
* CEmailValidator class file.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @link http://www.yiiframework.com/
* @copyright 2008-2013 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>
* @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.
* Please note that this check may fail due to temporary problems even if email is deliverable.
*/
public $checkMX=false;
/**
* @var boolean whether to check port 25 for the email address.
* Defaults to false. To enable it, ensure that the PHP functions 'dns_get_record' and
* 'fsockopen' are available in your PHP installation.
* Please note that this check may fail due to temporary problems even if email is deliverable.
*/
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;
/**
* @var boolean whether validation process should care about IDN (internationalized domain names). Default
* value is false which means that validation of emails containing IDN will always fail.
* @since 1.1.13
*/
public $validateIDN=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->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)
{
if(is_string($value) && $this->validateIDN)
$value=$this->encodeIDN($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') && function_exists('dns_get_record'))
$valid=$this->checkMxPorts($domain);
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)
{
if($this->validateIDN)
{
Yii::app()->getClientScript()->registerCoreScript('punycode');
// punycode.js works only with the domains - so we have to extract it before punycoding
$validateIDN='
var info = value.match(/^(.[^@]+)@(.+)$/);
if (info)
value = info[1] + "@" + punycode.toASCII(info[2]);
';
}
else
$validateIDN='';
$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 "
$validateIDN
if(".($this->allowEmpty ? "jQuery.trim(value)!='' && " : '').$condition.") {
messages.push(".CJSON::encode($message).");
}
";
}
/**
* Retrieves the list of MX records for $domain and checks if port 25
* is opened on any of these.
* @since 1.1.11
* @param string $domain domain to be checked
* @return boolean true if a reachable MX server has been found
*/
protected function checkMxPorts($domain)
{
$records=dns_get_record($domain, DNS_MX);
if($records===false || empty($records))
return false;
usort($records,array($this,'mxSort'));
foreach($records as $record)
{
$handle=@fsockopen($record['target'],25);
if($handle!==false)
{
fclose($handle);
return true;
}
}
return false;
}
/**
* Determines if one MX record has higher priority as another
* (i.e. 'pri' is lower). Used by {@link checkMxPorts}.
* @since 1.1.11
* @param mixed $a first item for comparison
* @param mixed $b second item for comparison
* @return boolean
*/
protected function mxSort($a, $b)
{
if($a['pri']==$b['pri'])
return 0;
return ($a['pri']<$b['pri'])?-1:1;
}
/**
* Converts given IDN to the punycode.
* @param string $value IDN to be converted.
* @return string resulting punycode.
* @since 1.1.13
*/
private function encodeIDN($value)
{
if(preg_match_all('/^(.*)@(.*)$/',$value,$matches))
{
if(function_exists('idn_to_ascii'))
$value=$matches[1][0].'@'.idn_to_ascii($matches[2][0]);
else
{
require_once(Yii::getPathOfAlias('system.vendors.Net_IDNA2.Net').DIRECTORY_SEPARATOR.'IDNA2.php');
$idna=new Net_IDNA2();
$value=$matches[1][0].'@'.@$idna->encode($matches[2][0]);
}
}
return $value;
}
}

View File

@@ -0,0 +1,119 @@
<?php
/**
* CExistValidator class file.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @link http://www.yiiframework.com/
* @copyright 2008-2013 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>
* @package system.validators
*/
class CExistValidator 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 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 mixed additional query criteria. Either an array or CDbCriteria.
* 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
* @throws CException if given table does not have specified column name
*/
protected function validateAttribute($object,$attribute)
{
$value=$object->$attribute;
if($this->allowEmpty && $this->isEmpty($value))
return;
if(is_array($value))
{
// https://github.com/yiisoft/yii/issues/1955
$this->addError($object,$attribute,Yii::t('yii','{attribute} is invalid.'));
return;
}
$className=$this->className===null?get_class($object):Yii::import($this->className);
$attributeName=$this->attributeName===null?$attribute:$this->attributeName;
$finder=$this->getModel($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();
if($this->criteria!==array())
$criteria->mergeWith($this->criteria);
$tableAlias = empty($criteria->alias) ? $finder->getTableAlias(true) : $criteria->alias;
$valueParamName = CDbCriteria::PARAM_PREFIX.CDbCriteria::$paramCount++;
$criteria->addCondition($this->caseSensitive ? "{$tableAlias}.{$columnName}={$valueParamName}" : "LOWER({$tableAlias}.{$columnName})=LOWER({$valueParamName})");
$criteria->params[$valueParamName] = $value;
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)));
}
}
/**
* Given active record class name returns new model instance.
*
* @param string $className active record class name.
* @return CActiveRecord active record model instance.
*
* @since 1.1.14
*/
protected function getModel($className)
{
return CActiveRecord::model($className);
}
}

View File

@@ -0,0 +1,305 @@
<?php
/**
* CFileValidator class file.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @link http://www.yiiframework.com/
* @copyright 2008-2013 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>
* $model->attribute = CUploadedFile::getInstance($model, "attribute");
* 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 minSize}; 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>
* @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 mixed a list of MIME-types of the file that are allowed to be uploaded.
* This can be either an array or a string consisting of MIME-types separated
* by space or comma (e.g. "image/gif, image/jpeg"). MIME-types are
* case-insensitive. Defaults to null, meaning all MIME-types are allowed.
* In order to use this property fileinfo PECL extension should be installed.
* @since 1.1.11
*/
public $mimeTypes;
/**
* @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 types}.
*/
public $wrongType;
/**
* @var string the error message used when the uploaded file has a MIME-type
* that is not listed among {@link mimeTypes}. In order to use this property
* fileinfo PECL extension should be installed.
* @since 1.1.11
*/
public $wrongMimeType;
/**
* @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;
/**
* @var boolean whether attributes listed with this validator should be considered safe for massive assignment.
* For this validator it defaults to false.
* @since 1.1.12
*/
public $safe=false;
/**
* 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
* @throws CException if failed to upload the file
*/
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','A PHP extension stopped the file upload.'));
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)));
}
}
if($this->mimeTypes!==null)
{
if(function_exists('finfo_open'))
{
$mimeType=false;
if($info=finfo_open(defined('FILEINFO_MIME_TYPE') ? FILEINFO_MIME_TYPE : FILEINFO_MIME))
$mimeType=finfo_file($info,$file->getTempName());
}
elseif(function_exists('mime_content_type'))
$mimeType=mime_content_type($file->getTempName());
else
throw new CException(Yii::t('yii','In order to use MIME-type validation provided by CFileValidator fileinfo PECL extension should be installed.'));
if(is_string($this->mimeTypes))
$mimeTypes=preg_split('/[\s,]+/',strtolower($this->mimeTypes),-1,PREG_SPLIT_NO_EMPTY);
else
$mimeTypes=$this->mimeTypes;
if($mimeType===false || !in_array(strtolower($mimeType),$mimeTypes))
{
$message=$this->wrongMimeType!==null?$this->wrongMimeType : Yii::t('yii','The file "{file}" cannot be uploaded. Only files of these MIME-types are allowed: {mimeTypes}.');
$this->addError($object,$attribute,$message,array('{file}'=>$file->getName(), '{mimeTypes}'=>implode(', ',$mimeTypes)));
}
}
}
/**
* 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. Examples of size strings are: 150, 1g, 500k, 5M (size suffix
* is case insensitive). If you pass here the number with a fractional part, then everything after
* the decimal point will be ignored (php.ini values common behavior). For example 1.5G value would be
* treated as 1G and 1073741824 number will be returned as a result. This method is public
* (was private before) since 1.1.11.
*
* @param string $sizeStr the size string to convert.
* @return integer the byte count in the given size string.
* @since 1.1.11
*/
public function sizeToBytes($sizeStr)
{
// get the latest character
switch (strtolower(substr($sizeStr, -1)))
{
case 'm': return (int)$sizeStr * 1048576; // 1024 * 1024
case 'k': return (int)$sizeStr * 1024; // 1024
case 'g': return (int)$sizeStr * 1073741824; // 1024 * 1024 * 1024
default: return (int)$sizeStr; // do nothing
}
}
}

View File

@@ -0,0 +1,49 @@
<?php
/**
* CFilterValidator class file.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @link http://www.yiiframework.com/
* @copyright 2008-2013 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 'built in' 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>
* @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
* @throws CException if given {@link filter} is not callable
*/
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));
}
}

View File

@@ -0,0 +1,82 @@
<?php
/**
* CInlineValidator class file.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @link http://www.yiiframework.com/
* @copyright 2008-2013 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>
* @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,$params)
* {
* if(!isset($params['message']))
* $params['message']='Value should be 123';
* $js = "if(value != '123') { messages.push($params['message']); }";
* 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,$this->params);
}
}
}

View File

@@ -0,0 +1,183 @@
<?php
/**
* CNumberValidator class file.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @link http://www.yiiframework.com/
* @copyright 2008-2013 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>
* @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(!is_numeric($value))
{
// https://github.com/yiisoft/yii/issues/1955
// https://github.com/yiisoft/yii/issues/1669
$message=$this->message!==null?$this->message:Yii::t('yii','{attribute} must be a number.');
$this->addError($object,$attribute,$message);
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(jQuery.trim(value)!='') {
$js
}
";
}
return $js;
}
}

View File

@@ -0,0 +1,110 @@
<?php
/**
* CRangeValidator class file.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @link http://www.yiiframework.com/
* @copyright 2008-2013 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>
* @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
* @throws CException if given {@link range} is not an array
*/
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.'));
$result = false;
if($this->strict)
$result=in_array($value,$this->range,true);
else
{
foreach($this->range as $r)
{
$result=(strcmp($r,$value)===0);
if($result)
break;
}
}
if(!$this->not && !$result)
{
$message=$this->message!==null?$this->message:Yii::t('yii','{attribute} is not in the list.');
$this->addError($object,$attribute,$message);
}
elseif($this->not && $result)
{
$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.
* @throws CException if given {@link range} is not an array
* @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 ? "jQuery.trim(value)!='' && " : '').($this->not ? "jQuery.inArray(value, $range)>=0" : "jQuery.inArray(value, $range)<0").") {
messages.push(".CJSON::encode($message).");
}
";
}
}

View File

@@ -0,0 +1,98 @@
<?php
/**
* CRegularExpressionValidator class file.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @link http://www.yiiframework.com/
* @copyright 2008-2013 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>
* @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
* @throws CException if given {@link pattern} is empty
*/
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.'));
// reason of array checking explained here: https://github.com/yiisoft/yii/issues/1955
if(is_array($value) ||
(!$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.
* @throws CException if given {@link pattern} is empty
* @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 ? "jQuery.trim(value)!='' && " : '').($this->not ? '' : '!')."value.match($pattern)) {
messages.push(".CJSON::encode($message).");
}
";
}
}

View File

@@ -0,0 +1,118 @@
<?php
/**
* CRequiredValidator class file.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @link http://www.yiiframework.com/
* @copyright 2008-2013 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>
* @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;
/**
* @var boolean whether the value should be trimmed with php trim() function when comparing strings.
* When set to false, the attribute value is not considered empty when it contains spaces.
* Defaults to true, meaning the value will be trimmed.
* @since 1.1.14
*/
public $trim=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->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,$this->trim))
{
$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),
));
if($this->trim)
$emptyCondition = "jQuery.trim(value)==''";
else
$emptyCondition = "value==''";
return "
if({$emptyCondition}) {
messages.push(".CJSON::encode($message).");
}
";
}
}
}

View File

@@ -0,0 +1,30 @@
<?php
/**
* CSafeValidator class file.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @link http://www.yiiframework.com/
* @copyright 2008-2013 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>
* @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)
{
}
}

View File

@@ -0,0 +1,183 @@
<?php
/**
* CStringValidator class file.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @link http://www.yiiframework.com/
* @copyright 2008-2013 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>
* @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(is_array($value))
{
// https://github.com/yiisoft/yii/issues/1955
$this->addError($object,$attribute,Yii::t('yii','{attribute} is invalid.'));
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(jQuery.trim(value)!='') {
$js
}
";
}
return $js;
}
}

View File

@@ -0,0 +1,132 @@
<?php
/**
* CTypeValidator class file.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @link http://www.yiiframework.com/
* @copyright 2008-2013 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>
* @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;
/**
* @var boolean whether the actual PHP type of attribute value should be checked.
* Defaults to false, meaning that correctly formatted strings are accepted for
* integer and float validators.
*
* @since 1.1.13
*/
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->allowEmpty && $this->isEmpty($value))
return;
if(!$this->validateValue($value))
{
$message=$this->message!==null?$this->message : Yii::t('yii','{attribute} must be {type}.');
$this->addError($object,$attribute,$message,array('{type}'=>$this->type));
}
}
/**
* Validates a static value.
* 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 valid
* @since 1.1.13
*/
public function validateValue($value)
{
$type=$this->type==='float' ? 'double' : $this->type;
if($type===gettype($value))
return true;
elseif($this->strict || is_array($value) || is_object($value) || is_resource($value) || is_bool($value))
return false;
if($type==='integer')
return (boolean)preg_match('/^[-+]?[0-9]+$/',trim($value));
elseif($type==='double')
return (boolean)preg_match('/^[-+]?([0-9]*\.)?[0-9]+([eE][-+]?[0-9]+)?$/',trim($value));
elseif($type==='date')
return CDateTimeParser::parse($value,$this->dateFormat,array('month'=>1,'day'=>1,'hour'=>0,'minute'=>0,'second'=>0))!==false;
elseif($type==='time')
return CDateTimeParser::parse($value,$this->timeFormat)!==false;
elseif($type==='datetime')
return CDateTimeParser::parse($value,$this->datetimeFormat, array('month'=>1,'day'=>1,'hour'=>0,'minute'=>0,'second'=>0))!==false;
return false;
}
}

View File

@@ -0,0 +1,151 @@
<?php
/**
* CUniqueValidator class file.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @link http://www.yiiframework.com/
* @copyright 2008-2013 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>
* @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 mixed additional query criteria. Either an array or CDbCriteria.
* 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
* @throws CException if given table does not have specified column name
*/
protected function validateAttribute($object,$attribute)
{
$value=$object->$attribute;
if($this->allowEmpty && $this->isEmpty($value))
return;
if(is_array($value))
{
// https://github.com/yiisoft/yii/issues/1955
$this->addError($object,$attribute,Yii::t('yii','{attribute} is invalid.'));
return;
}
$className=$this->className===null?get_class($object):Yii::import($this->className);
$attributeName=$this->attributeName===null?$attribute:$this->attributeName;
$finder=$this->getModel($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();
if($this->criteria!==array())
$criteria->mergeWith($this->criteria);
$tableAlias = empty($criteria->alias) ? $finder->getTableAlias(true) : $criteria->alias;
$valueParamName = CDbCriteria::PARAM_PREFIX.CDbCriteria::$paramCount++;
$criteria->addCondition($this->caseSensitive ? "{$tableAlias}.{$columnName}={$valueParamName}" : "LOWER({$tableAlias}.{$columnName})=LOWER({$valueParamName})");
$criteria->params[$valueParamName] = $value;
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)));
}
}
/**
* Given active record class name returns new model instance.
*
* @param string $className active record class name.
* @return CActiveRecord active record model instance.
*
* @since 1.1.14
*/
protected function getModel($className)
{
return CActiveRecord::model($className);
}
}

View File

@@ -0,0 +1,37 @@
<?php
/**
* CUnsafeValidator class file.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @link http://www.yiiframework.com/
* @copyright 2008-2013 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>
* @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.
* This validator does not do any validation as it is meant
* to only mark attributes as unsafe.
* @param CModel $object the object being validated
* @param string $attribute the attribute being validated
*/
protected function validateAttribute($object,$attribute)
{
}
}

View File

@@ -0,0 +1,204 @@
<?php
/**
* CUrlValidator class file.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @link http://www.yiiframework.com/
* @copyright 2008-2013 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>
* @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;
/**
* @var boolean whether validation process should care about IDN (internationalized domain names). Default
* value is false which means that validation of URLs containing IDN will always fail.
* @since 1.1.13
*/
public $validateIDN=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(($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 string $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($this->validateIDN)
$value=$this->encodeIDN($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 $this->validateIDN ? $this->decodeIDN($value) : $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)
{
if($this->validateIDN)
{
Yii::app()->getClientScript()->registerCoreScript('punycode');
// punycode.js works only with the domains - so we have to extract it before punycoding
$validateIDN='
var info = value.match(/^(.+:\/\/|)([^/]+)/);
if (info)
value = info[1] + punycode.toASCII(info[2]);
';
}
else
$validateIDN='';
$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="
$validateIDN
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(jQuery.trim(value)!='') {
$js
}
";
}
return $js;
}
/**
* Converts given IDN to the punycode.
* @param string $value IDN to be converted.
* @return string resulting punycode.
* @since 1.1.13
*/
private function encodeIDN($value)
{
if(preg_match_all('/^(.*):\/\/([^\/]+)(.*)$/',$value,$matches))
{
if(function_exists('idn_to_ascii'))
$value=$matches[1][0].'://'.idn_to_ascii($matches[2][0]).$matches[3][0];
else
{
require_once(Yii::getPathOfAlias('system.vendors.Net_IDNA2.Net').DIRECTORY_SEPARATOR.'IDNA2.php');
$idna=new Net_IDNA2();
$value=$matches[1][0].'://'.@$idna->encode($matches[2][0]).$matches[3][0];
}
}
return $value;
}
/**
* Converts given punycode to the IDN.
* @param string $value punycode to be converted.
* @return string resulting IDN.
* @since 1.1.13
*/
private function decodeIDN($value)
{
if(preg_match_all('/^(.*):\/\/([^\/]+)(.*)$/',$value,$matches))
{
if(function_exists('idn_to_utf8'))
$value=$matches[1][0].'://'.idn_to_utf8($matches[2][0]).$matches[3][0];
else
{
require_once(Yii::getPathOfAlias('system.vendors.Net_IDNA2.Net').DIRECTORY_SEPARATOR.'IDNA2.php');
$idna=new Net_IDNA2();
$value=$matches[1][0].'://'.@$idna->decode($matches[2][0]).$matches[3][0];
}
}
return $value;
}
}

View File

@@ -0,0 +1,279 @@
<?php
/**
* CValidator class file.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @link http://www.yiiframework.com/
* @copyright 2008-2013 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>
* @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 array list of scenarios that the validator should not be applied to.
* Each array value refers to a scenario name with the same name as its array key.
* @since 1.1.11
*/
public $except;
/**
* @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(isset($params['except']))
{
if(is_array($params['except']))
$except=$params['except'];
else
$except=preg_split('/[\s,]+/',$params['except'],-1,PREG_SPLIT_NO_EMPTY);
}
else
$except=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);
$validator->except=empty($except) ? array() : array_combine($except,$except);
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)
{
if(isset($this->except[$scenario]))
return false;
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)==='';
}
}