I faced with a next problem. I'm trying to validate field in different ways, depening on action: phone is should be unique on user create, and should not on user edit, so:
public function rules()
{
return [
[['owner_id','card_code', 'name', 'phone', 'birthday','language', 'last_ip'], 'required'],
[['account_id'], 'required', 'on' => 'update'],
[['account_id'], 'exist', 'skipOnError' => true, 'targetClass' => Accounts::className(), 'targetAttribute' => ['account_id' => 'id'], 'on' => 'update'],
[['owner_id', 'account_id', 'active', 'last_carwash'], 'integer'],
[['birthday', 'last_active', 'last_update', 'last_sync'], 'safe'],
[['car_number', 'role', 'status'], 'string'],
[['card_code', 'car_number', 'name', 'phone', 'password', 'auth_key', 'language'], 'string', 'max' => 255],
[['last_ip'], 'ip'],
[['name'], 'string', 'min' => 5],
['password', 'string', 'min' => 6, 'message' => Yii::t('app', 'The password must contain at least 6 symbols.')/*, 'on' => 'create'*/],
['password', 'match', 'pattern' => '/[A-z]/', 'message' => Yii::t('app', 'The password must contain at least 1 letter.')/*, 'on' => 'create'*/],
['password', 'match', 'pattern' => '/[0-9]/', 'message' => Yii::t('app', 'The password must contain at least 1 number.')/*, 'on' => 'create'*/],
[['password'], 'required', 'on' => 'create'],
[['phone'], 'validatePhone', 'except' => 'update'/*, 'skipOnEmpty' => false*/],
[['email'], 'email'],
[['email'], 'validateEmail', 'except' => 'update'/*, 'skipOnEmpty' => false*/],
];
}
I'm using AJAX validation:
$form = ActiveForm::begin([
'enableAjaxValidation' => true,
'validationUrl' => \yii\helpers\Url::to('/user/validation'),
]);
Validation actions:
public function validatePhone()
{
$phone = preg_filter( '/[^0-9]*/','', $this->phone );
$u = Users::findOne(['phone' => $phone]);
if($u)
/*if($this->id != $u->id)*/
$this->addError('phone', Yii::t('app', 'This phone is already taken.'));
}
public function validateEmail()
{
$email = $this->email;
if (!filter_var($email, FILTER_VALIDATE_EMAIL))
$this->addError('email', Yii::t('app', 'Please, enter correct email'));
$u = Users::findOne(['email' => $email]);
if($u)
$this->addError('email', Yii::t('app', 'This email is already taken.'));
}
In controller actions
public function actionCreate()
{
if ( Yii::$app->request->post() != NULL ) {
$data = Yii::$app->request->post('Users');
$model = new Users;
$model->scenario = 'create';
...//lots of a code
if(!$model->validate()){var_dump($model->errors);exit;}
$model->save();
return $this->redirect(['view', 'id' => $model->id]);
}
public function actionUpdate($id)
{
$model = $this->findModel($id);
$model->scenario = 'update';
$model->setScenario('update');// same as ^ , but who knows...
$data = Yii::$app->request->post();
if( $data )
{
...//lots of code
if(!$model->validate()){var_dump($model->errors);exit;}
$model->save();
return $this->redirect(['view', 'id' => $model->id]);
}
return $this->render('update', [
'model' => $model,
]);
}
public function actionValidation()
{
if (Yii::$app->request->isAjax) {
Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
$model = new \app\models\Users();
if($model->load(Yii::$app->request->post()))
return \yii\widgets\ActiveForm::validate($model);
}
throw new \yii\web\BadRequestHttpException( Yii::t('app', 'Bad request.') );
}
protected function findModel($id)
{
if (($model = Users::findOne($id)) !== null) {
return $model;
}
throw new NotFoundHttpException(Yii::t('app', 'The requested page does not exist.'));
}
Scenario:
public function scenarios()
{
$scenarios = parent::scenarios();
$scenarios['create'] = ['account_id', 'card_code', 'name', 'phone', 'email', 'car_number', 'birthday', 'role', 'password'];
$scenarios['update'] = ['account_id', 'card_code', 'name', 'phone', 'email', 'car_number', 'birthday', 'role', 'password'];
return $scenarios;
}
but it doesn't work at all at any forms.
If i delete 'on' => 'create'
it works fine, but in ALL forms, what is unwanted.
So how can i use validatePhone and validateEmail only in create scenario?