まーだからどうしたって話ですけれども。キーもできればバリデーションしたいところだけど、時間の都合により却下。相変わらず再帰処理は自分の想像力の限界を超えかけてるんだぜ...。
Agavi もそうだけど、意外と PHPフレームワークの Validator は多次元配列に対応していない。Symfony とかはどうなんすかね。そういえば OpenPNE の次期バージョンは Symfony になるそうな。
と、いうわけでとりあえず必要な箇所を再帰的に。
function _validateRecursiveArray (&$rule, &$result, &$key, &$values, &$empty)
{
foreach ($values as $k => $value) {
if (is_array($value)) {
$this->_validateRecursiveArray($rule, $result[$k], $key, $value, $empty);
}
else {
$value = $this->_filter($value, $rule['pre_filter']);
if (is_null($value) || $value === '') {
continue;
}
$this->_validate($key, $value, $rule);
$result[$k] = $value;
$empty = false;
}
}
}
そして validate 関数を修正。
/**
* validate
*
* @access public
* @return boolean エラーが発生しなかったかどうか
*/
function validate()
{
foreach ($this->rules as $key => $rule) {
$rule = $this->_initRule($key, $rule);
$values = array();
if (isset($this->requests[$key])) {
if (!is_array($this->requests[$key])) {
$values = array($this->requests[$key]);
}
else {
$values = $this->requests[$key];
}
}
if (empty($rule['is_array'])) {
$reqval = array_shift($values);
$result = $this->_filter($reqval, $rule['pre_filter']);
// 必須項目チェック
if (is_null($result) || $result === '') {
if (!empty($rule['required'])) {
if (isset($rule['required_error'])) {
$error = $rule['required_error'];
}
else {
$error = "{$rule['caption']}を入力してください";
}
$this->_setError($key, $error);
}
else {
if (isset($rule['default'])) {
$result = $rule['default'];
} else {
$result = null;
}
}
}
else {
$this->_validate($key, $result, $rule);
}
}
else {
$result = array();
$empty = true;
$this->_validateRecursiveArray($rule, $result, $key, $values, $empty);
if ($empty) {
if (!empty($rule['required'])) {
if (isset($rule['required_error'])) {
$error = $rule['required_error'];
}
else {
$error = "{$rule['caption']}を入力してください";
}
$this->_setError($key, $error);
}
else {
if (isset($rule['default'])) {
$result = array($rule['default']);
}
else {
$result = array();
}
}
}
}
$this->_setParam($key, $result);
}
return empty($this->errors);
}