beforeValidate

またCakePHP 1.1系の話です。

* beforeValidate

Use this callback to modify model data before it is validated. (中略)In this context, model data is accessible via $this->data.

vaidateする前にbeforeValidateが呼ばれて、そこで$this->dataを書き換えることができる。この説明を読むと、たとえば半角英数を入力して欲しいところに全角英数が入力された時に、beforeValidateで全角半角変換をしてvalidationを通す、とかいう使い方ができそうだけど、実際は違うみたい。

何でかというと、model_php5.phpのModel::invalidFieldsは

    function invalidFields($data = array()) {
        if (empty($data)) {
            $data = $this->data;
        }

        if (!$this->beforeValidate()) {
(中略)
        foreach ($this->validate as $field_name => $validator) {
            if (isset($data[$field_name]) && !preg_match($validator, $data[$field_name])) {
                $this->invalidate($field_name);
            }
        }

つまり、まず$this->dataを$dataにコピーしてからbeforeValidateを呼び出し、validation自体はさっきコピーした$dataに対して行っているように見える。だからbeforeValidateで$this->dataを書き換えてもvalidationの結果には影響しない。けどsaveの結果には影響する。何でこんな風になっているんだろう。

あとこのinvalidFieldsの中に出てくる

        if (!empty($data)) {
            $data = $data;
        } elseif (isset($this->data)) {
            $data = $this->data;
        }

$data = $data;って何だろう?参照がらみかな(deep copyをしたかったとか)。