本記事は Laravel Advent Calendar 2016 の 6 日目の記事です。
はじめに
公式のカスタムバリデーションのドキュメントが今ひとつ分かりにくいので、手順をまとめることにした。
今回はサンプルとして ふりがな のバリデーションを作成する。
※以前に書いた通常バリデーションの応用
http://qiita.com/komatzz/items/422bcba9847ca3a79fe9
##環境
- CentOS 7
- PHP 7
- Laravel 5.3
カスタムバリデーション作成手順
サービスプロバイダー作成
php artisan make:provider ValidatorServiceProvider
作成されたクラスを以下のように編集。
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Domain\CustomValidator;
class ValidatorServiceProvider extends ServiceProvider
{
/**
* Bootstrap the application services.
*
* @return void
*/
public function boot()
{
\Validator::resolver(function ($translator, $data, $rules, $messages) {
return new CustomValidator($translator, $data, $rules, $messages);
});
}
/**
* Register the application services.
*
* @return void
*/
public function register()
{
//
}
}
作成したサービスプロバイダーを設定ファイルに追加
'providers' => [
...
App\Providers\ValidatorServiceProvider::class,
...
カスタムバリデーションのロジックを書くファイルを作成する
今回はdomain
というディレクトリを作成し、その下にCustomValidator.php
を作成した。
namespace Domain;
class CustomValidator extends \Illuminate\Validation\Validator
{
/**
* ふりがなのバリデーション
*
* @param $attribute
* @param $value
* @param $parameters
* @return bool
*/
public function validateKana($attribute, $value, $parameters)
{
if (mb_strlen($value) > 100) {
return false;
}
if (preg_match('/[^ぁ-んー]/u', $value) !== 0) {
return false;
}
return true;
}
}
オートロードの設定
composer.json
の psr-4 設定に にdomain
ディレクトリ配下をオートロードできるように追加する
※これに気づかなくてハマった
...
"autoload": {
"psr-4": {
"App\\": "app/",
"Domain\\": "domain/",
}
}
...
エラーメッセージファイルに追加
return [
...
'kana' => ':attributeはひらがなで入力をしてください。',
...
'attributes' => [
...
'family_name_kana' => 'ふりがな(せい)',
'given_name_kana' => 'ふりがな(めい)',
...
],
カスタムバリデーションを使う
使い方は通常のバリデーションと同じで、
'family_name_kana' => 'required|kana',
のように使いたいバリデーションを|
区切りで指定すれば良い。
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests;
use App\Http\Controllers\Controller;
use Validator;
class RegistersController extends Controller
{
...
public function confirm(Request $request, $registerToken)
{
\Validator::make(
[
'family_name_kana' => trim($request->get('family_name_kana')),
'given_name_kana' => trim($request->get('given_name_kana')),
],
[
'family_name_kana' => 'required|kana',
'given_name_kana' => 'required|kana',
]
}->validate();
}
return view('registers/registers_confirm');
...
}
バリデーション実施結果
ふりがな(せい)
をカタカナで POST したので、ちゃんと引っかかっている。
テストコード作成
ちゃんとバリデーションできているかどうかテストするコードを書く。
<?php
/**
* かなのバリデーションのテストクラス
*/
namespace Tests\Domain\Validation;
use Validator;
class KanaTest extends \TestCase
{
/**
* 正常系テスト
*
* @dataProvider successParamsProvider
* @param array $values
*/
public function testSuccess($values)
{
$validator = \Validator::make(
[
'family_name_kana' => $values,
'given_name_kana' => $values,
],
[
'family_name_kana' => 'required|kana',
'given_name_kana' => 'required|kana',
]
);
$this->assertTrue(
$validator->passes()
);
}
/**
* 正常系パラメータ用のデータプロバイダー
*
* @return array
*/
public function successParamsProvider()
{
return [
'ひらがな' => [
'やきにくていしょく',
],
'大きな文字列(かなは100文字まで)' => [
str_repeat('あ', 100)
],
];
}
/**
* 異常系テスト
*
* @dataProvider failParamsProvider
* かなに不適切な文字が入力されている
*
* @param array $values
*/
public function testFail($values)
{
$validator = \Validator::make(
[
'family_name_kana' => $values,
'given_name_kana' => $values,
],
[
'family_name_kana' => 'required|kana',
'given_name_kana' => 'required|kana',
]
);
$this->assertTrue(
$validator->fails()
);
}
/**
* 異常系パラメータ用のデータプロバイダー
*
* @return array
*/
public function failParamsProvider()
{
return [
'数字' => [
1,
],
'漢字' => [
'焼肉定食',
],
'カタカナ' => [
'ヤキニクテイショク',
],
'大きな文字列(かなは100文字まで)' => [
str_repeat('あ', 101),
],
'NULL' => [
null,
],
'空' => [
'',
],
'スクリプト' => [
'<script>alert(1);</script>',
],
'\'' => [
'\'',
],
'/' => [
'/',
],
'<' => [
'<',
],
'¥' => [
'¥',
],
];
}
}
解説
- ひらがな かつ、100文字以内かどうかをテストしている
- PHPUnit のデータプロバイダーという機能を使うと簡潔にテストコードが書けて、失敗したときにどこで失敗したのか分かりやすい
ひとこと
これでバリデーション処理に関しては、ほとんど対応できるようになった。