Custom Validation
Update: Check out our new Yii2 Developer Exchange site at http://yii2x.com. It’s devoted exclusively for Yii2 developers to make it easier to find news, tips, tutorials and extensions related to Yii2.
Custom Validation
Yii’s model validation rules are extremely useful (see Declaring Validation Rules and Model Rules Validation Reference). There is also documentation on creating your own custom validation rule.
Here’s my own example of creating a custom validation rule which requires a database query. The example below validates that an email list address doesn’t exist already in the database for a specific user. In my applications, different users can reuse list addresses – so Yii’s default unique rule does not work.
public function rules() { return array( array('message_id, subject, modified_at', 'required'), ... array('address', 'addressNotInUseByUser', 'on'=>'insert'), ... ); }
Note the $ symbol must be used on both $this-> and $attribute public function.
// for validating inserts public function addressNotInUseByUser($attribute) { if (!Yii::app()->user->isGuest and Elist::model()->exists('address=:address and owner_id=:owner_id',array(':address'=>$this->$attribute,':owner_id'=>Yii::app()->user->id))) $this->addError($attribute, 'Sorry, you\'re already using that name for another list.'); }
// for validating updates // called from Controller::Update() action before save as shown below public function addressAlreadyInUse($address,$list_id,$owner_id) { if (Elist::model()->active()->countByAttributes(array('address'=>$address,'owner_id'=>$owner_id),'id<>'.$list_id)>0) { return true; } else return false; }
Here’s code in the controller during the Update action that calls the validation rule with paramaters before saving the changed record:
if(isset($_POST['Elist'])) { $model->attributes=$_POST['Elist']; $model->full_address=$model->address.'@easylist.io'; if ($model->prefix=='') $model->prefix = $model->address; if ($model->addressAlreadyInUse($model->address,$model->id,$model->owner_id)) { Yii::app()->user->setFlash('update_duplicate','Sorry, you already have a list with that name.'); $this->redirect(array('update','id'=>$model->id)); } if($model->save()) $this->redirect(array('view','id'=>$model->id)); }