[CakePHP4]Formのバリデーションチェックの前にデータを加工してバリデーションをおこなう方法

[CakePHP4]Formのバリデーションチェックの前にデータを加工してバリデーションをおこなう方法
2023年10月11日2023年10月11日

CakePHP4でFormから送信されてくる値をバリデーション前に加工してバリデーションをおこないたいことがあると思います。

例えば、大文字を小文字にしたいだったり全角を半角に変換したい等、入力値のクレンジングを行いたい場合はModelクラスにbeforeMarshal()をぜひ使ってみてください。

今回の事象

当ブログの記事URLはSEOを意識して任意の文字列を入力するようにしています。AutoIncrementの連番だと記事数が少なくて見せたくない気持ちもありますw

記事URLの文字列は、基本的に半角 or ハイフンのみを許可しており、それ以外は拒否するようになっているのですが、日本語を英語変換かけてスペースを消したりするのが面倒だったりします。

971231313412

そこでバリデーションを実行する前にデータを加工してバリデーションを通したいと思いました。

通常であればコントローラーに書く方法もありますが、スマートな感じがしないです。

controller
if ($idStr = $this->request->getData('id_str')) {
    $idStr = id_str_create($idStr);
}
$article = $this->Articles->patchEntity($article, ['id_str' => $idStr] + $this->request->getData());
if ($this->Articles->save($article)) {

}

ModelクラスのbeforeMarshal()を使おう

CakePHPには便利なメソッドが準備されています。バリデーション前にデータを加工したい場合は、beforeMarshal()を使います。

下記の処理は記事URLの文字列がある場合は、指定のフォーマットに変換をかけている処理になります。returnは不要です。

Model.php
use ArrayObject;
use Cake\Event\Event;

public function beforeMarshal(Event $event, ArrayObject $data, ArrayObject $options)
{
    if (isset($data['id_str']) && preg_match('/[A-Z ]/', $data['id_str'])) {
        $data['id_str'] = id_str_create($data['id_str']);
    }
}

似たようなメソッドとして、beforeSave()メソッドがあります。beforeSave()はバリデーションを通過後、保存処理の直前に呼ばれるメソッドになります。

バリデーション前に加工加工したい場合は「beforeMarshal()」を使いましょう。

最後に

Formのバリデーションチェックの前にデータを加工してバリデーションをおこなう方法について紹介しました。

あまり使う機会は少ないかもしれませんが便利なメソッドなのでコントローラー等に記述するのではなくbeforeMarshal()を活用しましょう。

コメント

コメントを残す

お名前(任意)
コメント:新規