目次

Apricot バリデーション

y2sunlight 2020-08-25

Apricot ドキュメント に戻る

目次


Valitronの利用

Apricotでは Valitron を使いサーバ側のバリデーションで使用します。詳しい使い方やメソッドについては Valitron の READMEを参照して下さい。

Valitron の典型的な使用例を示します:

$input = ['account' => 'root'];      // フォームの入力変数を取得する
$v = new Valitron\Validator($input); // バリデータを作る
$v->rule('required', 'account');     // ルールを適用する
 
if(!$v->validate()) // 検証する
{
    $errors = $v->errors();
    // 失敗の時は、入力変数とエラー内容を伴って前ページにリダイレクトする
}


Valitronの設定

以下はApricotが提供している初期のValitronの設定ファイル( validator.setting.php )です。

/your-project/config/setting

validator.setting.php
<?php
/**
 * This file contains Valitron\Validator settings.
 */
$lang = \Apricot\Lang::getLangCode();
return
[
    'lang_dir' => assets_dir('lang/'.$lang),
    'lang' => 'vlucas.valitron',
];

lang_dir の 初期設定値は /your-project/assets/lang/{LangCode} で、{LangCode}ISO 639-1で定義された2文字の言語コードです。Apricotはこの言語コードをセットアップ時に自動取得します。

lang は 言語ファイル名から拡張子を除いたベース名を指定します。この例の場合、実際の言語ファイル名は vlucas.valitron.php になります。利用者が英語で使用している場合、言語ファイルのフルパスは、以下のようになります:

/your-project/assets/lang/en/vlucas.valitron.php

多言語化についての詳細は「フロントエンド」を参照して下さい。


Valitronのセットアップ

Valitron には以下のセットアップファイルが存在します。

/your-project/config/setup

validator.setup.php
<?php
/**
 * Initial settings of Valitron\Validator
 */
return function():bool
{
    \Valitron\Validator::langDir(config('validator.lang_dir'));
    \Valitron\Validator::lang(config('validator.lang'));
 
    //-------------------------------------------------------------------
    // Adds custom rules
    //-------------------------------------------------------------------
    /*
     * unique rule: Check for unique attributes
     * [Example] rule('unique','Unique column name','Table name','ID column name')
     */
    Valitron\Validator::addRule('unique', function($field, $value, array $params, array $fields)
    {
        if (count($params)<1) return false;
 
        $query = ORM::forTable($params[0])->where($field, $value);
        if ((count($params)>1) && array_key_exists($params[1], $fields))
        {
            $id_field = $params[1];
            $query = $query->where_not_equal($id_field, $fields[$id_field]);
        }
        $users = $query->findOne();
 
        return ($users===false);
 
    }, 'is not unique');
 
    return true; // Must return true on success
};

Apricotのスケルトンでは、上の例のように、言語ファイルの場所を設定した後、Valitron\Validator::addRule() メソッドを使ってカスタムルール( 'unique' )を追加しています。新しいルールを追加するには、上の例を参考にして下さい。addRule() メソッドについては Valitron のREADME を参照して下さい。

uniqueルール

uniqueルールはデーターベースのユニーク制約の為のルールです。

使用法: rule('unique', $unique_column_name, $table_name, $id_column_name)

userテーブルのaccountカラムがユニーク制約を持っている場合、バリデーションルールは以下のように設定します。

$v = new \Valitron\Validator($inputs);
$v->rule('unique','account', 'user', 'id');


言語ファイル

Valitronの設定」でも述べたようにバリデーション用の言語ファイルは、初期設定では、以下のディレクトリに言語毎に配置されています。

/your-project/assets/lang/{Language Code}/vlucas.valitron.php

言語ファイルの内容は、バリデーション失敗時のメッセージです。これらのファイルは、アプリケーションでサポートする全ての言語毎に作成して下さい。デフォルトの言語は、環境変数 APP_LANG で指定してます。

以下の初期実装されている言語ファイルの抜粋を示します。配列のキーがルールー名、値がメッセージです。

/your-project/assets/lang/ja

vlucas.valitron.php
<?php
 
return array(
    'required'      => "を入力してください",
    'equals'        => "は「%s」と同じ内容を入力してください",
    'numeric'       => "は数値を入力してください",
    'integer'       => "は半角数字で入力してください",
    'length'        => "は%d文字で入力してください",
    'min'           => "には%sより大きな値を入力してください",
    'max'           => "には%sより小さな値を入力してください",
    'email'         => "の書式が正しくありません",
    'url'           => "はURLの書式として正しくありません",
    'alpha'         => "は半角英字で入力してください",
    'alphaNum'      => "は半角英数字で入力してください",
    'ascii'         => "は半角文字で入力して下さい",
    'unique'        => "は既に使用されています",
 
    // ...
);

エラーメッセージ

エラーが発生した場合、メッセージの前にはエラーの対象となった入力変数の名前が付きます。例えば以下の場合:

$v =(new \Valitron\Validator($inputs))
$v->rule('required', 'account'); 

エラー発生時のメッセージは「accountを入力してください」になります。「account」を「ユーザアカウント」のようなラベルに変更したい場合は、labels() メソッドを使用して次のようにします。

rule('required', 'account'); 
$v->labels(['account' => 'ユーザアカウント']);


ValidatorErrorBagクラス

App\Foundation\ValidatorErrorBag クラスはApricotコアの Apricot\Foundation\ErrorBag を継承したバリデーション用のエラーバッグクラスです。

ValidatorErrorBag には、'validator' という名前が付いています。この名前によって他のエラーバッグと区別することができます。'ValidatorErrorBag'のコンストラクターの引数は Valitron\Validator errors() メソッドから返される連想配列です。

以下は、コントローラ(またはインターセプター)内での ValidatorErrorBag の典型的な使用方法です:

if(!$v->validate()) // 検証する
{
    $errorBag = new ValidatorErrorBag($v->errors());
 
    // 入力変数とエラー内容を伴って前ページにリダイレクトする
    return redirect(back())->withInputs()->withErrors($errorBag);
}

ValidatorErrorBag で使えるメソッドについては「エラーバッグ」を参照して下さい。

以下は、HTMLテンプレード内でエラーバッグの使用例です。

@if($errors->count())
    @foreach($errors as $key=>$value)
         {{$value}}<br>
    @endforeach
@endif

$errors はフレームワークによって自動的に作られる ErrorBag 型のテンプレート変数です。レスポンスインスタンスの withErrors() メソッド によってフラッシュに格納されたエラーバッグは、$errors 変数を使って取り出すことができます。


バリデーションの使用例

バリデーションの使用例として、ユーザインターセプター( UserInterceptor )のinsertメソッドを以下に示します。このメソッドはユーザコントローラのinsertアクションのインターセプターとして動作します。

/your-project/app/Controllers/Interceptors

UserInterceptor.php
<?php
/**
 * Interceptor for insert method.
 *
 * @return void|\Apricot\Foundation\Response return Response if failed
 */
public function insert(Controller $controller)
{
    $inputs = Input::all();
 
    // Validation
    $v =(new \Valitron\Validator($inputs))
    ->rule('required', ['account','password'])
    ->rule('alphaNum','account')
    ->rule('unique','account','user','id')
    ->rule('ascii','password')
    ->rule('equals','password','password_confirmation')
    ->rule('email', 'email')
    ->labels(inputLabels('messages.user.create'));
 
    if(!$v->validate())
    {
        $errorBag = new ValidatorErrorBag($v->errors());
        return redirect(back())->withInputs()->withErrors($errorBag);
    }
 
    // Removes unnecessary inputs
    Input::remove('password_confirmation');
}

この例では、Input::all() で入力変数を取得した後に、それを使って Validator のインスタンスを生成します。

バリデーションルールの適用

バリデーションルールの適用には、rule() メソッドを使います。rule() メソッドに渡す第1引数はルール名、第2引数は入力変数変数名、第3引数以降はオプションでルールによって異なります。この例では、以下のバリデーションルールを使用しています。

この他の使用できるルールについては、ValitronのREADMEBuilt-in Validation Rules の項を参照して下さい。但し、uniqueルールはApricotのカスタムルールです。

入力変数のラベリング

labels() メソッドを使うとエラーメッセージで使用される入力変数にラベルを付けることができます。labels() メソッドに渡す引数は、変数名とラベルの連想配列です。この連想配列を作成するのに inputLabels() ボイラープレートを使用すると便利です。inputLabels('messages.user.create') の引数には、言語メッセージのドット表記キーを指定します。以下はこの例で使用している言語ファイルの内容です。

/your-project/asetts/lang/ja

messages.php
<?php
return [
    'user'=>[
        'create'=>[
            'account'=>'アカウント',
            'password'=>'パスワード',
            'password_confirmation'=>'パスワード(確認)',
            'email'=>'メールアドレス',
        ],
    ],
];

言語ファイル及び言語メッセージについては、多言語化を参照して下さい。

バリデーションの実行

バリデーションの実行には、validate() メソッドを使用します。バリデーションが失敗した時、errors() メソッドでバリデーションエラーを取得し、それを withErrors() を使って エラーバッグとしてフラッシュ変数に保存します。そして、redirect()で前画面にリダイレクトするレスポンスオブジェクトを生成しそれを返します。