ucym / CodeLapse

Fast coding for Small-scale PHP projects.
http://ucym.github.io/CodeLapse/
0 stars 1 forks source link

Validation #11

Open ucym opened 9 years ago

ucym commented 9 years ago

Feature

入力値検証を行い、パターンにマッチしない値の検出を行う

通常の値検証に加え、クライアントサイドのリアルタイム検証用のコード出力を行う。 バリデーションルールの鯖蔵間の二重定義を避け検証ルールの保守コストを下げたい。

また、クライアントサイドのリアルタイム検証を少ない時間で実装したい。

Ideal code sample

<?php
//
//-- 基本的な使い方
//
Validator::addRule('noDuplicatedEmail', function ($value, $fieldName, array $options) {
    $resutSet = DB::query('SELECT "" FROM `users` WHERE `email` = ?', [$value]);
    return $resultSet->fetch() === false;
}, function ($fieldName, $param) {
    return <<<JS
    // function (value, fieldName) {
        // trueを返すか resolveで trueを返されれば検証を通過
        // falseを返すか rejectすれば検証エラーを発生
        return new Promise(function (res, rej) {
            $.ajax({url: "/api/checkConflict", data:{email: value}, dataType: "json"})
                .done(function (res) {
                    res(res.conflict);  // res.conflict: Boolean
                })
                .fail(rej);
        });
    // }email_confirm
JS;
});

Validator::define(/* nullable -> */ 'register')
    ->rule('name',          ['required', 'minLength' => 4, 'maxLength' => 5])
    // ラベルを指定するときはフィールド名を "フィールド名:ラベル"形式で指定
    // ->rule('name:名前',   ['required', 'minLength' => 4, 'maxLength' => 5])
    // ->rule('email:メールアドレス',         ['required', 'email', 'noDuplicatedEmail'])
    ->rule('email',         ['required', 'email', 'noDuplicatedEmail'])
    ->rule('email_confirm', ['required', 'equals' => 'email'])
    ->rule('password',      ['required', 'minLength' => 6, 'maxLength' => 20])
    ->rule('password_confirm', ['required', 'equals' => 'password'])
    ->rule('credit_card',   ['required', 'credit_card' => ['visa', 'master']])
    ->rule('agree',         ['required', 'accepted']);

if (Validator::check($_POST, /* nullable -> */ 'register')) {
    echo 'Hello';
} else {
    echo 'Invalid!';
}

//
//-- 複数の設定を読み込む
//
$rules = [
    'name'              => ['required', 'minLength' => 4, 'maxLength' => 5],
    'email'             => ['required', 'email', 'noDuplicatedEmail'],
    'email_confirm'     => ['required', 'equals' => 'email'],
    'password'          => ['required', 'minLength' => 6, 'maxLength' => 20],
    'password_confirm'  => ['required', 'equals' => 'password'],
    'credit_card'       => ['required', 'credit_card' => ['visa', 'mastercard']],
    'agree'             => ['required', 'accepted']
];

// あるいはConfigクラスを用いて読み込む
// $rules = Config::get('validators.register');
if (Validator::check($_POST, $rules)) {
    echo 'Hello';
} else {
    echo 'Invalid!';
}

//
//-- 設定の再利用
//
Validator::addRule('validTwitterId', function ($value, $fieldName, array $options) {
    return preg_match('/^@[a-zA-Z0-9_]+$/', $value) === 1;
}, function ($fieldName, $param) {
    return 'return /^@[a-zA-Z0-9_]+$/.test(value);';
});

$rules = Config::get('validators.register');
Validator::define($rules, /* nullable -> */ 'regist with twitter')
    // email, email_confirm を検査項目から除外
    ->remove('email', 'email_confirm')
    // 新しい検査項目を追加
    ->rule('twitter_id', ['required', 'validTwitterId']);

if (Validator::check($_POST, 'regist with twitter')) {
    echo 'Hello';
} else {
    echo 'Invalid!';
}

Spec

ucym commented 9 years ago

Valitronでおkなのでは?