cakePHP4のバリデーションを動的に変更する方法(既存のルールをcontroller側で一時的に無効化する方法)

概要

cakePHP4のバリデーションを動的に変更する方法(既存のルールをcontroller側で一時的に無効化する方法)について解説します。

例えば、ユーザー情報の登録、パスワード変更において以下のような要件があったとします。このとき、UsersTableのvalidationDefaultに設定済みのルールを動的に変更するにはどうしたら良いでしょうか?

  • ユーザー追加時には現在のパスワードのチェックは不要
  • ユーザー情報編集時に、パスワード欄に入力があれば、現在のパスワード、確認用パスワードをチェックする。
  • ユーザー情報編集時に、パスワード欄に入力が無ければ、現在のパスワード、確認用パスワードをチェック不要。
前提環境
  • Hosting Server: さくらインターネット
  • PHP: 7.4.9
  • cakePHP: 4.1.1

コードのポイント

動的にValidatorの設定を変更する方法はいくつか考えられますが、今回はあらかじめ必要な設定を全て記入し、必要に応じて設定を外していく方法を使用します。

controllerからvalidatorを取得するには「$this->(モデル名->getValidator();」を使います。

設定を外していくには「offsetUnset」を使用します。

サンプルコード

※注意!
本来ならばパスワードの文字数や確認用パスワードとの一致など、ルールがもっと必要ですが、サンプルコードのため除外しています。

/src/Model/Table/UsersTable.php

public function validationDefault(Validator $validator): Validator
{
    $validator
        ->requirePresence('email')
        ->notEmptyString('email', 'メールアドレスは省略出来ません。')
        ->email('email', false, 'メールアドレスの形式ではありません。')

        ->requirePresence('username')
        ->notEmptyString('username', 'ユーザ名は省略出来ません。')

        ->requirePresence('password')
        ->notEmptyString('password', 'パスワードは省略出来ません。')

        ->requirePresence('password_check')
        ->notEmptyString('password_check', '確認用パスワードは省略出来ません。')


    return $validator;
}

/src/Controller/UsersController.php

public function edit($id = null)
{
    $user = $this->Users->get($id);
    if ($this->request->is(['patch', 'post', 'put'])) { 
        // パスワードに入力があるか確認、パスワードがなければ更新対象としない。
        if (empty($this->request->getData('password'))) {
            // バリデーションのルールを解除する。
            $this->offsetPasswordValidator();
            // 更新対象からも外しておく
            $user->setAccess('password', false);
        } else {
            $user->setAccess('password', true);
        }

        $user = $this->Users->patchEntity($user, $this->request->getData());

        if ($this->Users->save($user)) {
            $this->Flash->success(__('ユーザー情報の変更を保存しました。'));
            return $this->redirect(['controller'=>'pages', 'action' => 'index']);
        } else {
            $this->Flash->error(__('ユーザー情報の変更の保存に失敗しました。もう一度お試しください。'));
        }
    }

    // 編集画面表示時点ではパスワードの入力があるかどうかわからないので
    // バリデーションのルールを解除する。
    // ここで解除しないと、パスワードが必須のままになる。
    $this->offsetPasswordValidator();
    $this->set(compact('user'));
}

// バリデーションのルール解除用の関数。
// 複数回呼ばれるので関数にまとめた。
private function offsetPasswordValidator()
{
    $validator = $this->Users->getValidator();
    $validator->offsetUnset('password_now');
    $validator->offsetUnset('password');
    $validator->offsetUnset('password_check');
}

コメントする

CAPTCHA