October CMSのafterValidateメソッドの使い方

OctoberのModelクラスにはオーバーライドすることができるイベントメソッドが複数あり、バリデーション前後や、レコードの作成前後、レコードの更新前後など、それぞれの処理の前後に開発者が任意の処理を加えることができます。

イベントメソッドの一覧はこちら

今回は「octoberのバリデーションチェックではできない選択内容の組み合わせエラーをチェックする」という実装をする際に、イベントメソッドのafterValidateを利用したのですが、使い方に苦戦したのでご紹介します。

環境

  • Laravel:5.5
  • October CMS:1.0

仕様

まずafterValidateを含む登録フローをざっくりですが整理してみました。
※今回はレコード作成時を想定しています。

①beforeValidate() → ②october側でバリデーションチェック  → ③afterValidate()
→ ④beforeCreate() → ⑤october側でレコード作成処理 → ⑥afterCreate()

簡単に書くとこんな感じでした。
私は③のafterValidateで、組み合わせエラーをチェックしようと考えました。

ValidationExceptionというクラスがあったので、これを利用して③でエラーがあればエクセプションを投げ、画面にエラー内容を表示するように実装しました。

Test1.php

ですが何度やっても②でエラーがあったとしても、③のエクセプションが優先して出てきてしまいました。

内部コードを調べてみると、以下のようなフローであることが分かりました。
beforeValidate() → october側でバリデーションチェック  → afterValidate()
→バリデーションエラーの出力

このことから、afterValidate内でエクセプションを投げてしまうと、バリデーションエラーが出力される前にエクセプションが投げられることになってしまうことが分かりました。

これを踏まえて実装を行いました。

実装

まず内部コードを見て、$this->validationErrorsには、october側のバリデーションエラーが入っていることが分かったので、そこにafterValidate内のエラー内容を追加するようにコードを変更してみました。

ただこれだけでは、afterValidateの内容が出力されませんでした。
原因は、october側のバリデーションチェックでエラーがあったかどうかのフラグを持っているらしく、afterValidateでエラーを追加しても、october側のバリデーションチェックでエラーが無ければ、afterValidateの内容は無かったことになってしまうようでした。

これを踏まえて、次のように変更しました。

これで、octoberのバリデーションエラーが先、afterValidateのエラーが後に、
$this->validationErrorsに格納されるため、表示の優先順位が問題なくなり、「バリデーションチェック後、status=”1″でpublished_atに値が無かった場合にエラーを投げる」という実装ができました。

まとめ

私は内部ソースを読んでこの方法を発見したので、正規の方法とは違っている可能性がありますが、私の探し方では公式の使い方が見つからなかったため、独自の方法をご紹介しました。

以上になります。

 

システム開発のご相談はこちらからお気軽にお問合せください。


コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です