tohokuaikiのチラシの裏

技術的ネタとか。

EthnaのCustomバリデートが・・・

ActionFormをFormだけじゃなくて、普通にバリデータだけ使いたい場合・・・。
CSVデータの1行をFormデータとしてValidateしたい場合・・・

適当に

<?php
$tmp_af = new Hoge_Form_FooBar(Hoge_Controller::getInstance());
$tmp_af->set('foo', $foo);
$tmp_af->validate();
とかしてたんです。

だけど、カスタムValidateで引っかかりました。

理由は、
Ethna/class/Plugin/Validator/Custom.php
で、

<?php
        foreach ($method_list as $method) {
            if (method_exists($this->af, $method)) {
                $ret = $this->af->$method($name);

って、現実のActionForm見にいっちゃってるから。

Grep書けたところ他のValidatorでは$this->afしてるところが無くて、Validatorはそん時のNewされたActionFormに依存するべきなので、現物のHTTP由来のActionFormに依存するのはおかしいと思う。分離してほしい。


とりあえず、PHPの関数には引数を多く与えても何も言われないことから、
Ethna/class/ActionForm.php の 692行目に

<?php
$r = $v->validate($form_name, $form_vars, $plugin[$name], $this);

として

Ethna/class/Plugin/Validator/Custom.php

<?php
    public function validate($name, $var, $params, $af = null)
    {
        $true = true;
        $false = false;

        $method_list = preg_split('/\s*,\s*/', $params['custom'], -1, PREG_SPLIT_NO_EMPTY);
        if (is_array($method_list) == false) {
            return $true;
        }
        
        if (is_null($af)){
            $af = $this->af;
        }

        foreach ($method_list as $method) {
            if (method_exists($af, $method)) {
                $ret = $af->$method($name);
                if (Ethna::isError($ret)) {
                    // このエラーはすでに af::checkSomething() で ae::add()
                    // してある
                    return $false;
                }
            }
        }

        return $true;
    }

てな感じでどうでしょう。
if (is_null($af)){
は要らないな・・・。