How to create custom validation rule

How to create custom validation rule

In the scenarios where validation rules provided by the Yii framework won’t handle your requirements, you can create custom validation rules. One example is the "authenticate" validation rule provided in "LoginForm" model of Yii blog demo. You can create your own by following these steps.

  1. In rules() method of your model, specify name of your custom validation rule e.g check the validation rule for email

    	public function rules()
    	{
    		// NOTE: you should only define rules for those attributes that
    		// will receive user inputs.
    		return array(
    			array('service_id, review_date, rating, review', 'required'),
    			array('email', 'email'),
    			array('email', 'checkEmail','on'=>'guestUser'),			
    			array('review', 'safe'),
    			// The following rule is used by search().
    			// Please remove those attributes that should not be searched.
    			array('service_id, user_id,email', 'safe', 'on'=>'search'),
    		);
    	}
  2. Add a new method in your model with same name as your validation rule. In our case "checkEmail" 

    	/**
    	 * @param string the name of the attribute to be validated
    	 * @param array options specified in the validation rule
    	 */
    	public function checkEmail($attribute,$params)
    	{
    		$models = ServiceReviews::model()->findAllByAttributes(array('email' =>$this->email,'service_id'=>$this->service_id));
    		if(count($model)>0){
    			 $this->addError($attribute, 'You have already submitted review for this item');
    		}
    	}

    Note that the validation method should always have the specified signature.

  3. You can create a single validation methods for multiple fields and in that method use a switch statement for "$attribute". You can then use "$params" to customize error messages etc. for example.

    	public function rules()
    	{
    		// NOTE: you should only define rules for those attributes that
    		// will receive user inputs.
    		return array(
    			array('service_id, review_date, rating, review', 'required'),
    			array('email', 'email'),	
    			
    			array('email', 'checkUser','message'=>'Test message for email validation'),
    			array('user_id', 'checkUser','message'=>'Test message for user_id validation'),
    
    			array('review', 'safe'),
    			// The following rule is used by search().
    			// Please remove those attributes that should not be searched.
    			array('service_id, user_id,email', 'safe', 'on'=>'search'),
    		);
    	}
    
    	public function checkUser($attribute,$params)
    	{
    		switch($attribute){
    			case "email":
    				$models = ServiceReviews::model()->findAllByAttributes(array('email' =>$this->email,'service_id'=>$this->service_id));
    				if(count($models)>0){
    					 $this->addError($attribute, $params['message']);
    				}
    			break;
    			case "user_id":
    				if(Yii::app()->user->isGuest){
    					$models = ServiceReviews::model()->findAllByAttributes(array('user_id' =>Yii::app()->user->id,'service_id'=>$this->service_id));
    					if(count($models)>0){
    						 $this->addError($attribute, $params['message']);
    					}
    				}
    			break;
    		}
    
    	}

    "$params" argument of validation method is an array containing all the key/value pairs provided with the rule in "rules()" method.