CakePHP入門（４） 〜バリデーション〜　

基本的なバリデーションの使い方について記述していきます。
# 主なメソッド

例を挙げて見ていきましょう。

```php:/src/Model/Table/UsersTable.php
<?php
namespace App\Model\Table;
 
use Cake\ORM\Query;
use Cake\ORM\RulesChecker;
use Cake\ORM\Table;
use Cake\Validation\Validator;
 
class UsersTable extends Table
{
    public function initialize(array $config)
    {
        parent::initialize($config);
 
        $this->setTable('users');
        $this->setDisplayField('username');
        $this->setPrimaryKey('id');
    }
    public function validationDefault(Validator $validator)
    {
        $validator
            ->integer('id')
            ->allowEmpty('id', 'create');
 
        $validator
            ->scalar('username')
            ->requirePresence('username', 'create')
            ->maxLength('username', 50)
            ->notEmpty('username');

        $validator
            ->scalar('email')
            ->requirePresence('email', 'create')
            ->notEmpty('email', 'required email'),
            ->email('email');
  
        $validator
            ->integer('age')
            ->requirePresence('age', 'create')
            ->notEmpty('age');

        return $validator;
    }
}
```
`validationDefault`メソッドでバリデーションを行っています。

## integer, scalar
値の型を設定するために使います。

```php
$validator->integer('フィールド名');
$validator-> scalar('フィールド名');
```

`integer`は値を整数型に、`scaler`はテキスト型に設定します。

## allowEmpty, notEmpty

`allowEmpty`は空の値を許可し、逆に`notEmpty`は空なら許可しません。

```php
$validator->allowEmpty('フィールド名');
```

`notEmpty`では、ルールに違反して空白だった場合にメッセージを表示することも可能です。

```php
$validator->notEmpty('フィールド名', 'メッセージ');
```

##requirePresence
指定したフィールドをNOT NULL相当にし、なおかつ必須項目にします。

```php
$validator->requirePresence('フィールド名');
```


## maxLength
指定した最大文字数を超えていないかどうかチェックをチェックします。

```php
$validator->maxLength('フィールド名', 文字数, 'メッセージ');
```

## email
メールアドレスの形式に沿っているかどうかチェックします。

```php
$validator->email('フィールド名', false, 'メッセージ');
```

第２引数には、MXレコードをチェックするかどうかを指定します。指定しなければデフォルトの`false`になります。

# バリデーションルールの追加
## add
`add`メソッドを用いることで、バリデーションに独自のルールを追加できます。

```php
$validator->add('フィールド名', 'ルール名', 配列); 
```

`/src/Model/Table/UsersTable.php`のバリデーションの部分を以下のように変更しました。電話番号のチェックに`add`メソッドを使っています。

```php
　…（略）…

    public function validationDefault(Validator $validator)
    {
        $validator
            ->integer('id')
            ->allowEmpty('id', 'create');
 
        $validator
            ->scalar('username')
            ->requirePresence('username', 'create')
            ->notEmpty('username','input username!');
  
        $validator
            ->scalar('email')
            ->requirePresence('email', 'create')
            ->notEmpty('email', 'required email')
            ->email('email');
        ]);

        $validator
            ->integer('age')
            ->requirePresence('age', 'create')
            ->notEmpty('age');
 
        $validator
            ->scalar('tel')
            ->requirePresence('tel', 'create')
            ->notEmpty('tel','required tel')
            ////電話番号形式のチェック ////
            ->add('tel', 'custom',[
                'rule' =>[$this, 'tel_check'],
                'message' => 'invalid tel'
            ]);
            ////////////////////////////////
 
        $validator
            ->scalar('email')
            ->requirePresence('email', 'create')
            ->notEmpty('email', 'required email')
            ->email('email');
        ]);
 
        return $validator;
    }

    //    電話番号フォーマットのチェック
    public function tel_check($value, $context)
    {
        //boolで返さないとエラー
        return (bool) preg_match('/^[0-9]{2,5}-?[0-9]{2,5}-?[0-9]{2,5}$/', $value);
    }

　…（略）…
```

追加した箇所を見ていきましょう。`tel`フィールドの部分です。

```php
->notEmpty('tel','required tel')
->add('tel', 'custom',[
       'rule' =>[$this, 'tel_check'],
       'message' => 'invalid tel'
       ]);
```

この`add`メソッドでは、`tel`という名前のフィールドに対して、`custom`というルール名で、`tel_check`というメソッドを呼び出しています。


## 独自メソッドの引数

`tel_check`を見てみましょう。

```php
    public function tel_check($value, $context)
    {
        //boolで返さないとエラー
        return (bool) preg_match('/^[0-9]{2,5}-?[0-9]{2,5}-?[0-9]{2,5}$/', $value);
    }
````

`tel_check`には、2つの引数がありますね。

### $value
`$value`には、対象フィールドに入力した値が入ります。例えば、`tel_check`のバリデーション対象フィールドは`tel`なので、`tel`フィールドに入力した値が入ります。

```:var_dump($value);
string(8) "123-1234"
```

### $context
`$context`は配列型の値で、`'newRecord'`、`'data'`、`'field'`、`'providers'`という４つの要素を持ちます。

#### $context['newRecord']
レコードが新しく作られたものであるかどうかについて、bool型の値が入っています。

```:var_dump($context['newRecord']);
bool(true)
```

#### $context['data']
全てのフィールドに入力した、それぞれの値が入ります。例えば`tel_check`の`$context['data']`を見れば、`tel`以外のフィールドに入力された値も調べることができます。

```:var_dump($context['data']);
array(4) { ["username"]=> string(13) "ユーザーA" ["email"]=> string(14) "aaaa@gmail.com" ["age"]=> string(2) "20" ["tel"]=> string(8) "123-1234" }
```

#### $context['field']
対象フィールドの名前が入ります。

```:var_dump($context['field']);
string(3) "tel"
```

#### $context['providers']
（公式ドキュメント曰く）「プロバイダーオブジェクトについての完成されたリスト」を持つようです。

```:var_dump($context['providers']);
array(2) { ["table"]=> object(App\Model\Table\UsersTable)#210 (8) { ["registryAlias"]=> string(5) "Users" ["table"]=> string(5) "users" ["alias"]=> string(5) "Users" ["entityClass"]=> string(21) "App\Model\Entity\User" ["associations"]=> array(0) { } ["behaviors"]=> array(1) { [0]=> string(9) "Timestamp" } ["defaultConnection"]=> string(7) "default" ["connectionName"]=> string(7) "default" } ["default"]=> object(Cake\Validation\RulesProvider)#237 (2) { ["_class":protected]=> string(26) "Cake\Validation\Validation" ["_reflection":protected]=> object(ReflectionClass)#238 (1) { ["name"]=> string(26) "Cake\Validation\Validation" } } }
```


# その他のメソッド一覧
以下のページが参考になるので、興味のある方はご覧になってみて下さい。

URL
http://ivystar.jp/programming/php/cakephp-php-programming/validation-rule-list-of-cakephp-3/

---

CakePHP入門（１）〜初期設定〜
https://qiita.com/jinto/items/f4545dfb02160c424d48


CakePHP入門（２）〜ファイルの作成〜
https://qiita.com/jinto/items/fe1da36b65fd6e704338

CakePHP入門（３） 〜レイアウト〜　
https://qiita.com/jinto/items/c9138faf65e417616086