CCompareValidator.php 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. <?php
  2. /**
  3. * CCompareValidator class file.
  4. *
  5. * @author Qiang Xue <qiang.xue@gmail.com>
  6. * @link http://www.yiiframework.com/
  7. * @copyright 2008-2013 Yii Software LLC
  8. * @license http://www.yiiframework.com/license/
  9. */
  10. /**
  11. * CCompareValidator compares the specified attribute value with another value and validates if they are equal.
  12. *
  13. * The value being compared with can be another attribute value
  14. * (specified via {@link compareAttribute}) or a constant (specified via
  15. * {@link compareValue}. When both are specified, the latter takes
  16. * precedence. If neither is specified, the attribute will be compared
  17. * with another attribute whose name is by appending "_repeat" to the source
  18. * attribute name.
  19. *
  20. * The comparison can be either {@link strict} or not.
  21. *
  22. * CCompareValidator supports different comparison operators.
  23. * Previously, it only compares to see if two values are equal or not.
  24. *
  25. * When using the {@link message} property to define a custom error message, the message
  26. * may contain additional placeholders that will be replaced with the actual content. In addition
  27. * to the "{attribute}" placeholder, recognized by all validators (see {@link CValidator}),
  28. * CCompareValidator allows for the following placeholders to be specified:
  29. * <ul>
  30. * <li>{compareValue}: replaced with the constant value being compared with ({@link compareValue}).</li>
  31. * <li>{compareAttribute}: replaced with the label of the attribute being compared with ({@link compareAttribute}).</li>
  32. * </ul>
  33. *
  34. * @author Qiang Xue <qiang.xue@gmail.com>
  35. * @package system.validators
  36. * @since 1.0
  37. */
  38. class CCompareValidator extends CValidator
  39. {
  40. /**
  41. * @var string the name of the attribute to be compared with
  42. */
  43. public $compareAttribute;
  44. /**
  45. * @var string the constant value to be compared with
  46. */
  47. public $compareValue;
  48. /**
  49. * @var boolean whether the comparison is strict (both value and type must be the same.)
  50. * Defaults to false.
  51. */
  52. public $strict=false;
  53. /**
  54. * @var boolean whether the attribute value can be null or empty. Defaults to false.
  55. * If this is true, it means the attribute is considered valid when it is empty.
  56. */
  57. public $allowEmpty=false;
  58. /**
  59. * @var string the operator for comparison. Defaults to '='.
  60. * The followings are valid operators:
  61. * <ul>
  62. * <li>'=' or '==': validates to see if the two values are equal. If {@link strict} is true, the comparison
  63. * will be done in strict mode (i.e. checking value type as well).</li>
  64. * <li>'!=': validates to see if the two values are NOT equal. If {@link strict} is true, the comparison
  65. * will be done in strict mode (i.e. checking value type as well).</li>
  66. * <li>'>': validates to see if the value being validated is greater than the value being compared with.</li>
  67. * <li>'>=': validates to see if the value being validated is greater than or equal to the value being compared with.</li>
  68. * <li>'<': validates to see if the value being validated is less than the value being compared with.</li>
  69. * <li>'<=': validates to see if the value being validated is less than or equal to the value being compared with.</li>
  70. * </ul>
  71. */
  72. public $operator='=';
  73. /**
  74. * Validates the attribute of the object.
  75. * If there is any error, the error message is added to the object.
  76. * @param CModel $object the object being validated
  77. * @param string $attribute the attribute being validated
  78. * @throws CException if invalid operator is used
  79. */
  80. protected function validateAttribute($object,$attribute)
  81. {
  82. $value=$object->$attribute;
  83. if($this->allowEmpty && $this->isEmpty($value))
  84. return;
  85. if($this->compareValue!==null)
  86. $compareTo=$compareValue=$this->compareValue;
  87. else
  88. {
  89. $compareAttribute=$this->compareAttribute===null ? $attribute.'_repeat' : $this->compareAttribute;
  90. $compareValue=$object->$compareAttribute;
  91. $compareTo=$object->getAttributeLabel($compareAttribute);
  92. }
  93. switch($this->operator)
  94. {
  95. case '=':
  96. case '==':
  97. if(($this->strict && $value!==$compareValue) || (!$this->strict && $value!=$compareValue))
  98. $message=$this->message!==null?$this->message:Yii::t('yii','{attribute} must be repeated exactly.');
  99. break;
  100. case '!=':
  101. if(($this->strict && $value===$compareValue) || (!$this->strict && $value==$compareValue))
  102. $message=$this->message!==null?$this->message:Yii::t('yii','{attribute} must not be equal to "{compareValue}".');
  103. break;
  104. case '>':
  105. if($value<=$compareValue)
  106. $message=$this->message!==null?$this->message:Yii::t('yii','{attribute} must be greater than "{compareValue}".');
  107. break;
  108. case '>=':
  109. if($value<$compareValue)
  110. $message=$this->message!==null?$this->message:Yii::t('yii','{attribute} must be greater than or equal to "{compareValue}".');
  111. break;
  112. case '<':
  113. if($value>=$compareValue)
  114. $message=$this->message!==null?$this->message:Yii::t('yii','{attribute} must be less than "{compareValue}".');
  115. break;
  116. case '<=':
  117. if($value>$compareValue)
  118. $message=$this->message!==null?$this->message:Yii::t('yii','{attribute} must be less than or equal to "{compareValue}".');
  119. break;
  120. default:
  121. throw new CException(Yii::t('yii','Invalid operator "{operator}".',array('{operator}'=>$this->operator)));
  122. }
  123. if(!empty($message))
  124. $this->addError($object,$attribute,$message,array('{compareAttribute}'=>$compareTo,'{compareValue}'=>$compareValue));
  125. }
  126. /**
  127. * Returns the JavaScript needed for performing client-side validation.
  128. * @param CModel $object the data object being validated
  129. * @param string $attribute the name of the attribute to be validated.
  130. * @throws CException if invalid operator is used
  131. * @return string the client-side validation script.
  132. * @see CActiveForm::enableClientValidation
  133. * @since 1.1.7
  134. */
  135. public function clientValidateAttribute($object,$attribute)
  136. {
  137. if($this->compareValue !== null)
  138. {
  139. $compareTo=$this->compareValue;
  140. $compareValue=CJSON::encode($this->compareValue);
  141. }
  142. else
  143. {
  144. $compareAttribute=$this->compareAttribute === null ? $attribute . '_repeat' : $this->compareAttribute;
  145. $compareValue="jQuery('#" . (CHtml::activeId($object, $compareAttribute)) . "').val()";
  146. $compareTo=$object->getAttributeLabel($compareAttribute);
  147. }
  148. $message=$this->message;
  149. switch($this->operator)
  150. {
  151. case '=':
  152. case '==':
  153. if($message===null)
  154. $message=Yii::t('yii','{attribute} must be repeated exactly.');
  155. $condition='value!='.$compareValue;
  156. break;
  157. case '!=':
  158. if($message===null)
  159. $message=Yii::t('yii','{attribute} must not be equal to "{compareValue}".');
  160. $condition='value=='.$compareValue;
  161. break;
  162. case '>':
  163. if($message===null)
  164. $message=Yii::t('yii','{attribute} must be greater than "{compareValue}".');
  165. $condition='parseFloat(value)<=parseFloat('.$compareValue.')';
  166. break;
  167. case '>=':
  168. if($message===null)
  169. $message=Yii::t('yii','{attribute} must be greater than or equal to "{compareValue}".');
  170. $condition='parseFloat(value)<parseFloat('.$compareValue.')';
  171. break;
  172. case '<':
  173. if($message===null)
  174. $message=Yii::t('yii','{attribute} must be less than "{compareValue}".');
  175. $condition='parseFloat(value)>=parseFloat('.$compareValue.')';
  176. break;
  177. case '<=':
  178. if($message===null)
  179. $message=Yii::t('yii','{attribute} must be less than or equal to "{compareValue}".');
  180. $condition='parseFloat(value)>parseFloat('.$compareValue.')';
  181. break;
  182. default:
  183. throw new CException(Yii::t('yii','Invalid operator "{operator}".',array('{operator}'=>$this->operator)));
  184. }
  185. $message=strtr($message,array(
  186. '{attribute}'=>$object->getAttributeLabel($attribute),
  187. '{compareAttribute}'=>$compareTo,
  188. ));
  189. return "
  190. if(".($this->allowEmpty ? "jQuery.trim(value)!='' && " : '').$condition.") {
  191. messages.push(".CJSON::encode($message).".replace('{compareValue}', ".$compareValue."));
  192. }
  193. ";
  194. }
  195. }