Laravelでバリデーションルールにorやandがほしかった話

経緯と概要

携わってるプロジェクトで、メールアドレスのバリデーションを変えるということになった。

既存会員 : オリジナルの正規表現

新規会員 : Laravelのemailルール(RFC準拠)

となったのだが、

f:id:tkfric:20180824170604p:plain

結果としてこの形で全員救う必要性が出てきた。

でも、正規表現も当てて、Laravelのemailも当てて…という都合の良いものはいくら調べても出てこなくて、 結果自力でどうにかするかと思い立ち実装した次第。

実装した内容

前提として

  • Laravel5.3
  • PHP7.0

バリデーションルールを複数指定し(Laravel内のもの、カスタム問わず)、

  • or : どちらかが通る
  • and : どちらも通る

としてカスタムバリデーションルールを作った。

まず、カスタムバリデーションを記述するファイルとして app\Providers\ValidationServiceProvider.php を作成

処理の概要としては、指定されたバリデーションルールで1つずつバリデータを通すだけの簡単なもの。

/**
 * 複数のバリデーションルールでorチェックする
 */
Validator::extend('or', function ($attribute, $value, $parameters, $validator) {
    foreach ($parameters as $key => $val) {
        $validator = Validator::make([$attribute => $value], [$attribute => $val]);
        if ($validator->fails()) {
            continue;
        }
        return true;
    }
    return false;
});

/**
 * 複数のバリデーションルールでandチェックする
 */
Validator::extend('and', function ($attribute, $value, $parameters, $validator) {
    foreach ($parameters as $key => $val) {
        $validator = Validator::make([$attribute => $value], [$attribute => $val]);
        if ($validator->fails()) {
            return false;
        }
    }
    return true;
});

最後に

こんなことする必要あったのかなぁ