Validatorの設計

昨日の続き

昨日はValidatorが子を持つといったが、これそんなことせずに、ValidatorManagerがValidatorをプールしておけばいいんじゃないかと。
重要なのはvalidate/action_name.iniで設定されたパラメータを持ったバリデータが識別されて、違う部分でも使えれば良いわけで。

このプール方式を用いる利点は既存のvalidatorが何の変更を受けないこと。ValidatorManagerとValidatorConfigHandlerを修正すればよい。あとは、子バリデータを用いたいValidatorが勝手にプールから持って来ればよい。ValidatorはもともとContextインスタンスを持っているのでここからValidatorManagerを取得し、

$validatorManager->getValidator('name');

としてやることによって所望のバリデータを取得する。これでやりたいことができるようになるのではないだろうか。

バリデータ設定ファイル

MojaviAgaviではバリデータの設定はアクションごとに行う。しかに実際には、検索IDなどモジュールごとに共通の値や、ユーザIDなどアプリケーション全体で共通の値があり、それらについて毎回同じバリデータ設定をするのは開発効率も悪く、また保守性も損なわれる。
そこで、バリデータの設定ファイルは
Action>Module>Global
の優先順位で設定できるようにした方がよいと思う。

たとえば

;; config/validate.ini
[UserIdValidator]
  class = "RegexValidator"
  param.pattern = "/\w{10}/i"
  param.match   = "Yes"

;; {module}/validate/module.ini
[SearchIdValidator]
  class = "NumberValidator"
  param.max = 10000
  param.min = 0

;; {module}/validate/{action}.ini
[methods]
  get = "uid"
  post = "uid,search_id"

[names]
  uid.required = "Yes"
  uid.required_msg = "user_id is needed!"
  uid.validators = "UserIdValidator"

  search_id.required = "No"
  search_id.validators = "SearchIdValidator"

みたいな設定ができたり。
同じグローバルバリデータを使って

;; Default/validate/login.ini
[names]
  user_data.required = "Yes"
  user_data.required_msg = "Need"
  user_data.validators = "UserDataValidator"

[UserDataValidator]
  class = "AssocArrayValidator" ;連想配列バリデータ
  param.keys = "uid,passwd"
  param.uid.required = "Yes"
  param.uid.validators = "UserIdValidator"

  param.passwd.required = "No"
  param.passwd.validators = "PasswordValidator"

[PasswordValidator]
  (以下略) 

みたいにして扱うことができる。
ちなみに、AssocArrayValidatorは連想配列用Validatorとなる。
$_POSTや$_GETなんかを扱うなら、このValidatorをルートしたValidatorTreeを形成してやれば良いんじゃないかと思ってたりもする。