バリデーションはお問い合わせフォームなどの作成に欠かせないものです。Cakephpではモデルテーブル内に、各フォームに合わせたバリデーションを記述していきます。元々Cakephpに用意されているバリデーションメソッドで要件を満たすことができればよいのですが、場合によっては独自のバリデートが必要になるケースも多々あると思います。
カスタムバリデートの実際に記述し、それをコールしてみましょう。
step
1CustomValidation.phpファイルを作成
場所は任意でよいのかも?ですが、とりあえずModel/Tableと密接するので、その配下にディレクトリとファイルを作成することにします。(少なくとも関連性がある場所がいい)
Model/Table/Validation
という形でディレクトリを作成しましょう。
step
2CustomValidationを記述してく
カスタムバリデートメソッドを CutomValidation.php 内で記述します。継承元はValidation
になります。
<?php declare(strict_types=1); namespace App\Model\Validation; use Cake\Validation\Validation; /** * カスタムバリデーション */ class CustomValidation extends Validation { /** * [独自validateルール関数] URLは正しいか? * * @param string $type 'pattern1' | 'pattern2' * @return bool */ public static function validateCorrectUrl($data, $type, $context): bool { $params = self::getParamsFromUrl($data); if (!$params) { return false; } // 当該パターン以外ならfalse if ($type != 'pattern1' || $type != 'pattern2') { return false; } // 期待するパラメータが存在した場合はバリデート通過 return true; } /** * urlからパラメータを抽出 * * @param string $url URL * @return array|false [期待するURLのパラメータ] */ private static function getParamsFromUrl($url) { // 正しいURLだった場合は各パラメータの値を返す // 略 } }
得にコードに意味はありません。(めんどくさいから最後略に...)
注意点としては、カスタムバリデート内の各メソッドにstaticが付与されていることです。
例えば、もし、static
にせず、validateCorrectUrl()
メソッド内に $this->getParamsFromUrl()
という形で呼び出したら、
Using $this when not in object context ~
という形でエラーになります。
Cakephpドキュメントを見てみると、
カスタムバリデートを利用する際、
// クラス名を使います。メソッドは静的なものでなければなりません。
$validator->setProvider('custom', 'App\Model\Validation');
https://book.cakephp.org/4/ja/core-libraries/validation.html#adding-validation-providers
という感じで、メソッドは静的なものであることが明記されています。
ドキュメントにしっかり目を通せば、エラーに遭遇することもないでしょうけども。まあ、注意ということで。
step
3テーブル内でカスタムバリデーションをsetProvider()で呼び出す
カスタムバリデートを利用するために、setProvider()
で呼び出します。
/** * entity生成時に作動するバリデーション * * @param \Cake\Validation\Validator $validator A Validator instance * @return \Cake\Validation\Validator */ public function validationDefault(Validator $validator): Validator { $validator->setProvider('customValidation', 'App\Model\Validation\CustomValidation'); $validator->add('correct_url', 'validateCorrectUrl', [ 'rule' => 'validateCorrectUrl', 'provider' => 'customValidation', 'message' => '正しいURLではありません', ]); }
ruleにカスタムプロバイダーメソッド、providerプロパティにsetProvider()
で指定したプロバイダ名で呼び出すことができます。
カスタムバリデーションの定義の仕方と、その呼び出しについてはこれで大丈夫だと思います。
カスタムバリデーションに追加引数を渡したい場合
カスタムバリデーションメソッドに追加で引数を渡したい場合は、
shortcode
'rule' => ['validateCorrectUrl', 'pattern1'],
という感じで、ruleプロパティを配列にしつつ、渡したい値を渡すことができます。
と、同時にどうやってカスタムプロバイダ内で受け取るのか?というと、
public function validateCorrectUrl($data, $type, $context): bool { // $typeの第二引数で値を取得できる var_dump($type); // 'pattern1' }
上記の様に第二引数で受け取ることができます。
カスタムバリデーションを任意テーブル内で定義しつつ呼び出す場合
別にカスタムバリデーションを外だし(外部ファイルでまとめる)するほどでもなくね?という場合もあるかと思います。
そのような場合、
// DefaultValidationメソッド内 $validator ->allowEmptyDate('fieldName') ->add('fieldName', 'fromTodayOn', [ 'rule' => [$this, 'fromTodayOn'], 'message' => '本日以降の日付を入力してください。', ]); } // fromTodyOn()はpublicで定義すること public function fromTodayOn() { // 任意実装(検証)後、true or false return true; }
ruleプロパティの配列第一引数を$thisとして自身を指定しておき、第二引数で fromTodayOn()
を指定することで、同テーブル内に定義されたカスタムバリデーションメソッドをコールすることができます。