Laravelでカスタムバリエーションを本格的にやる


Laravel5時代にかなりつくり込んで、Laravel8で久しぶりに触ったのでメモ。

カスタムバリデーションに関してドキュメントにはRulesってのを追加するというものが書かれています。
https://readouble.com/laravel/8.x/ja/validation.html

でもリクエストをつくってバリデーションしたい時にあまり良くなさそうです。
いくつか方法がありそうですが、本格的にカスタムする場合、大元のValidatorをカスタムにしてしまうのが良さそうです。

Validatorのカスタム

Laravelの基本の動きのカスタムときたら、プロバイダーを作って呼び出すようにすればOKですね。
app/Providers/ValidatorServiceProvider.php を作成。
config/app.php で呼び出しを書いておきます。

ValidatorServiceProvider.php
<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;

class ValidatorServiceProvider extends ServiceProvider
{
    /**
     * Bootstrap the application services.
     *
     * @return void
     */
    public function boot(): void
    {
        $this->app['validator']->resolver(function($translator, $data, $rules, $messages, $customAttributes) {
            return new \App\Custom\Validator($translator, $data, $rules, $messages, $customAttributes);
        });
    }
}

上記の例の場合 app/Custom/Validator.php を用意します。
中身は \Illuminate\Validation\Validator を継承して、 validateXXX() って関数を作れば、ルールで xxx が呼び出せるようになります。

app/Custom/Validator.php
<?php

namespace App\Custom;

class Validator extends \Illuminate\Validation\Validator
{
    /**
     * 電話番号チェック
     *
     * @param  string  $attribute
     * @param  mixed   $value
     * @return bool
     */
    public function validateTel(string $attribute, mixed $value): bool
    {
        return preg_match('/^0[0-9]{1,4}-[0-9]{1,4}-[0-9]{1,4}$/', $value);
    }
}

Translatorもカスタマイズしたい

そんなこともあるかもしれないです。
gettextで国際化してるときにとかで使いました。
そんなときは $translator をカスタムにしてやればOK。
Translatorは Illuminate\Contracts\Translation\Translator のインターフェースを実装しておけばOKです。

ValidatorServiceProvider.php
<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;

class ValidatorServiceProvider extends ServiceProvider
{
    /**
     * Bootstrap the application services.
     *
     * @return void
     */
    public function boot(): void
    {
        $this->app['validator']->resolver(function($translator, $data, $rules, $messages, $customAttributes) {
            $translator = new \App\Custom\Translator;
            return new \App\Custom\Validator($translator, $data, $rules, $messages, $customAttributes);
        });
    }
}