コントローラ側の値を使ってカスタマイズした検証をCakePHPで行いたいとき

メモみたいなものです、ちょっと汚いですがすみません。

前提

普段データの検証するときは***Table.phpにてbuildRulesを使うと思います。

ですが、このbuildRulesは基本的にテーブル内の変数のみ対象で、コントローラ側の変数は受け付けません。

たとえばコントローラ側でsummary_idというIDがあるとします。そのsummary_idが1のもの、かつ****みたいな条件のものしか受け付けたくないときの検証はどうやって記述すればいいでしょうか。

buildRulesのほかに新たな関数を書き、beforeFilterで読み込むようにします。

以下ではその作業のまとめをかければと思います。

1. ***Table にてカスタム関数を書く

    public function buildAdditionalRulesForAdding(
        RulesChecker $rules,
        $summary_id
    )
    {
        $rules
            ->add(
                function ($entity, $options) use ($summary_id) {
                    $hoge = [];
                    ~~~ $hoge, $summary_id 周りの処理 ~~~

                    return empty($hoge;
                },
                'code_must_be_uniq',
                [
                    'errorField' => 'summary_id',
                    'message' => __("その顧客コードはすでに使用されています"),
                ]
            );
    }

2. Trait.php にてTable.phpの関数を読み込む関数を実装

==============================
略
==============================

trait ManagementTrait {

    private function beforeFilterForManagement(Event $event)
    {
        // コントローラー側の値を使用するアプリケーションルールを生成
        $this->Users
            ->getEventManager()
            ->on(
                'Model.buildRules',
                function (Event $event, RulesChecker $rules) {
                    $summary_id = $this->getSummaryId();
                    $rules = DataTable::buildAdditionalRulesForAdding($rules, $summary_id);
                    return $rules;
                }
            );
    }
}

3. ***Controller.php にてTraitを読み込む

initializeの前で読み込みます。

そして、そのあとにbeforeFilterという関数にて上記のTraitの関数を宣言します。

class *****Controller extends AppController
{
    use ManagementTrait;

    public function initialize()

================================================
略
================================================

    public function beforeFilter(Event $event)
    {
        parent::beforeFilter($event);
        $this->beforeFilterForManagement($event);
    }

これでカスタマイズされたルールが読み込まれることになります。

完全に自分用なので読めなかったら申し訳ないです。。。