Go with that : makes it totally general purpose for all comparions
Here's a suggestion for an implementation - a few class constants and a switch for the comparion:
class CCompareValidator extends CValidator
{
const EQUAL=0;
const NOT_EQUAL=1;
const GREATER=2;
const NOT_GREATER=3;
const LESS=4;
const NOT_LESS=5;
/**
* @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 integer The type of comparison to perform
* Defaults to self::EQUAL.
*/
public $type=self::EQUAL;
/**
* @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 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 the object being validated
* @param string the attribute being validated
*/
protected function validateAttribute($object,$attribute)
{
$value=$object->$attribute;
if($this->allowEmpty && ($value===null || $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->type)
{
case self::NOT_EQUAL:
if(($this->strict && $value===$compareValue) || (!$this->strict && $value==$compareValue))
{
$message=$this->message!==null?$this->message:Yii::t('yii','{attribute} must not be equal to {compareAttribute}.');
$this->addError($object,$attribute,$message,array('{compareAttribute}'=>$compareTo));
}
break;
case self::GREATER:
if(($this->strict && gettype($value)!==gettype($compareValue)) || ($value<=$compareValue))
{
$message=$this->message!==null?$this->message:Yii::t('yii','{attribute} must be greater than {compareAttribute}.');
$this->addError($object,$attribute,$message,array('{compareAttribute}'=>$compareTo));
}
break;
case self::NOT_GREATER:
if(($this->strict && gettype($value)!==gettype($compareValue)) || ($value>$compareValue))
{
$message=$this->message!==null?$this->message:Yii::t('yii','{attribute} must not be greater than {compareAttribute}.');
$this->addError($object,$attribute,$message,array('{compareAttribute}'=>$compareTo));
}
break;
case self::LESS:
if(($this->strict && gettype($value)!==gettype($compareValue)) || ($value>=$compareValue))
{
$message=$this->message!==null?$this->message:Yii::t('yii','{attribute} must not be less than {compareAttribute}.');
$this->addError($object,$attribute,$message,array('{compareAttribute}'=>$compareTo));
}
break;
case self::NOT_LESS:
if(($this->strict && gettype($value)!==gettype($compareValue)) || ($value<$compareValue))
{
$message=$this->message!==null?$this->message:Yii::t('yii','{attribute} must not be less than {compareAttribute}.');
$this->addError($object,$attribute,$message,array('{compareAttribute}'=>$compareTo));
}
break;
default: //self::EQUAL
if(($this->strict && $value!==$compareValue) || (!$this->strict && $value!=$compareValue))
{
$message=$this->message!==null?$this->message:Yii::t('yii','{attribute} must be equal to {compareAttribute}.');
$this->addError($object,$attribute,$message,array('{compareAttribute}'=>$compareTo));
}
break;
} // switch
}
}