ここの情報は古いです。ご理解頂いた上でお取り扱いください。

source: OpenPNE/trunk/webapp/lib/OpenPNE/Validator.php @ 85

Last change on this file since 85 was 85, checked in by ogawa, 17 years ago
File size: 11.6 KB
Line 
1<?php
2/**
3 * @copyright 2005-2006 OpenPNE Project
4 * @license   http://www.php.net/license/3_01.txt PHP License 3.01
5 */
6
7/**
8 * ユーザ入力値バリデータクラス
9 */
10class OpenPNE_Validator
11{
12    /**
13     * @var array 検証ルール
14     * @access private
15     */
16    var $rules = array();
17
18    /**
19     * @var array 検証済みリクエストパラメタ
20     * @access private
21     */
22    var $params = array();
23
24    /**
25     * @var array エラー
26     * @access private
27     */
28    var $errors = array();
29
30    /**
31     * @var array 検証対象リクエストパラメタ
32     * @access private
33     */
34    var $requests = array();
35
36    /**
37     * @var string デフォルトフィルター
38     */
39    var $default_filter = 'ntrim,rtrim,mysqltext';
40
41    /**
42     * バリデータの初期化
43     *
44     * @param array $rules
45     * @param array $requests
46     */
47    function OpenPNE_Validator($rules = array(), $requests = array())
48    {
49        $this->rules = $rules;
50        if ($requests) {
51            $this->requests = $requests;
52        } else {
53            $this->requests = $_REQUEST;
54        }
55    }
56
57    /**
58     * ルールの追加
59     *
60     * @access public
61     * @param array $rules
62     */
63    function addRules($rules)
64    {
65        $this->rules = array_merge($this->rules, (array)$rules);
66    }
67
68    /**
69     * ルールをiniファイルから追加
70     *
71     * @access public
72     * @param string $ini_path
73     */
74    function addIniSetting($ini_path)
75    {
76        if (!is_readable($ini_path) ||
77            !$rules = parse_ini_file($ini_path, true)) {
78
79            return false;
80        }
81
82        $this->addRules($rules);
83        return true;
84    }
85
86    /**
87     * (検証済み)リクエストパラメータを取得
88     *
89     * @access public
90     * @return array
91     */
92    function getParams()
93    {
94        return $this->params;
95    }
96
97    /**
98     * エラー情報を取得
99     *
100     * @access public
101     * @return array
102     */
103    function getErrors()
104    {
105        return $this->errors;
106    }
107
108    /**
109     * (検証前の)リクエストパラメータを追加
110     *
111     * @access public
112     * @param array $requests
113     */
114    function addRequests($requests)
115    {
116        $this->requests = array_merge($this->requests, (array)$requests);
117    }
118
119    /**
120     * パラメータに検証済みの値をセット
121     *
122     * @access private
123     * @param string $key
124     * @param string $value
125     */
126    function _setParam($key, $value)
127    {
128        $this->params[$key] = $value;
129    }
130
131    /**
132     * エラー情報を設定
133     *
134     * @access private
135     * @param string $key
136     * @param string $msg エラーメッセージ
137     */
138    function _setError($key, $msg)
139    {
140        $this->errors[$key] = $msg;
141    }
142
143    /**
144     * validate
145     *
146     * @access public
147     * @return boolean エラーが発生しなかったかどうか
148     */
149    function validate()
150    {
151        foreach ($this->rules as $key => $rule) {
152            $rule = $this->_initRule($key, $rule);
153
154            $values = array();
155            if (isset($this->requests[$key])) {
156                if (!is_array($this->requests[$key])) {
157                    $values = array($this->requests[$key]);
158                } else {
159                    $values = $this->requests[$key];
160                }
161            }
162
163            if (empty($rule['is_array'])) {
164                $reqval = array_shift($values);
165                $result = $this->_filter($reqval, $rule['pre_filter']);
166
167                // 必須項目チェック
168                if (is_null($result) || $result === '') {
169                    if (!empty($rule['required'])) {
170                        if (isset($rule['required_error'])) {
171                            $error = $rule['required_error'];
172                        } else {
173                            $error = "{$rule['caption']}を入力してください";
174                        }
175                        $this->_setError($key, $error);
176                    } else {
177                        if (isset($rule['default'])) {
178                            $result = $rule['default'];
179                        } else {
180                            $result = null;
181                        }
182                    }
183                } else {
184                    $this->_validate($key, $result, $rule);
185                }
186            } else {
187                $result = array();
188                $empty = true;
189                foreach ($values as $k => $value) {
190                    $value = $this->_filter($value, $rule['pre_filter']);
191                    if (is_null($value) || $value === '') {
192                        continue;
193                    }
194
195                    $this->_validate($key, $value, $rule);
196                    $result[$k] = $value;
197                    $empty = false;
198                }
199                if ($empty) {
200                    if (!empty($rule['required'])) {
201                        if (isset($rule['required_error'])) {
202                            $error = $rule['required_error'];
203                        } else {
204                            $error = "{$rule['caption']}を入力してください";
205                        }
206                        $this->_setError($key, $error);
207                    } else {
208                        if (isset($rule['default'])) {
209                            $result = array($rule['default']);
210                        } else {
211                            $result = array();
212                        }
213                    }
214                }
215            }
216
217            $this->_setParam($key, $result);
218        }
219
220        return empty($this->errors);
221    }
222
223    /**
224     * 検証ルールの初期化
225     *
226     * @access private
227     * @param string $key
228     * @param array $rule
229     * @return array 初期化済み検証ルール
230     */
231    function _initRule($key, $rule)
232    {
233        if (!isset($rule['caption'])) {
234            $rule['caption'] = $key;
235        }
236
237        if (!isset($rule['pre_filter'])) {
238            $rule['pre_filter'] = $this->default_filter;
239        }
240
241        if (empty($rule['type'])) {
242            $rule['type'] = 'string';
243        }
244
245        return $rule;
246    }
247
248    /**
249     * _filter
250     *
251     * @access private
252     * @param string $value
253     * @param string $filter
254     * @return string フィルターを通した値
255     */
256    function _filter($value, $filter)
257    {
258        $filters = explode(',', $filter);
259        foreach ($filters as $filter) {
260            if (!empty($filter)) {
261                switch ($filter) {
262                case 'trim':
263                    if (OPENPNE_TRIM_DOUBLEBYTE_SPACE) {
264                        // 全角スペースに対応
265                        $value = mb_ereg_replace('^(\s| )+', '', $value);
266                        $value = mb_ereg_replace('(\s| )+$', '', $value);
267                    } else {
268                        $value = trim($value);
269                    }
270                    break;
271                case 'ltrim':
272                    if (OPENPNE_TRIM_DOUBLEBYTE_SPACE) {
273                        // 全角スペースに対応
274                        $value = mb_ereg_replace('^(\s| )+', '', $value);
275                    } else {
276                        $value = ltrim($value);
277                    }
278                    break;
279                case 'rtrim':
280                    if (OPENPNE_TRIM_DOUBLEBYTE_SPACE) {
281                        // 全角スペースに対応
282                        $value = mb_ereg_replace('(\s| )+$', '', $value);
283                    } else {
284                        $value = rtrim($value);
285                    }
286                    break;
287                case 'ntrim':
288                    // NULL バイトをすべて削除
289                    $value = str_replace("\0", '', $value);
290                    break;
291                case 'mysqltext':
292                    if (is_string($value) && strlen($value) > 65535) {
293                        $value = mb_strcut($value, 0, 65535);
294                    }
295                    break;
296                }
297            }
298        }
299        return $value;
300    }
301
302    /**
303     * _validate
304     *
305     * @access private
306     * @param string $key
307     * @param string $reqval
308     * @param array $rule
309     * @return boolean
310     */
311    function _validate($key, $reqval, $rule)
312    {
313        // 型チェック
314        switch (strtolower($rule['type'])) {
315        case 'int':
316            if (!is_numeric($reqval)) {
317                if (isset($rule['type_error'])) {
318                    $error = $rule['type_error'];
319                } else {
320                    $error = "{$rule['caption']}は数値で入力してください";
321                }
322                $this->_setError($key, $error);
323                return false;
324            }
325            break;
326        case 'bool':
327            if ($reqval != '0' && $reqval != '1') {
328                if (isset($rule['type_error'])) {
329                    $error = $rule['type_error'];
330                } else {
331                    $error = "{$rule['caption']}の値が不正です";
332                }
333                $this->_setError($key, $error);
334                return false;
335            }
336            break;
337        case 'string':
338            break;
339        case 'regexp':
340            if (isset($rule['regexp']) && !preg_match($rule['regexp'], $reqval)) {
341                if (isset($rule['type_error'])) {
342                    $error = $rule['type_error'];
343                } else {
344                    $error = "{$rule['caption']}を正しく入力してください";
345                }
346                $this->_setError($key, $error);
347                return false;
348            }
349            break;
350        default:
351            $error = "{$rule['type']}は未定義の型です";
352            $this->_setError($key, $error);
353            return false;
354        }
355
356        // min/max チェック
357        switch ($rule['type']) {
358        case 'int':
359            // min
360            if (isset($rule['min']) && $reqval < intval($rule['min'])) {
361                if (isset($rule['min_error'])) {
362                    $error = $rule['min_error'];
363                } else {
364                    $error = "{$rule['caption']}{$rule['min']}以上の数値で入力してください";
365                }
366                $this->_setError($key, $error);
367                return false;
368            }
369            // max
370            if (isset ($rule['max']) && $reqval > $rule['max']) {
371                if (isset($rule['max_error'])) {
372                    $error = $rule['max_error'];
373                } else {
374                    $error = "{$rule['caption']}{$rule['max']}以下の数値で入力してください";
375                }
376                $this->_setError($key, $error);
377                return false;
378            }
379            break;
380        case 'string':
381        case 'regexp':
382            // min
383            if (isset($rule['min']) && (mb_strwidth($reqval, 'UTF-8') < $rule['min'])) {
384                if (isset($rule['min_error'])) {
385                    $error = $rule['min_error'];
386                } else {
387                    $error = "{$rule['caption']}は半角{$rule['min']}文字以上で入力してください";
388                }
389                $this->_setError($key, $error);
390                return false;
391            }
392            // max
393            if (isset($rule['max']) && (mb_strwidth($reqval, 'UTF-8') > $rule['max'])) {
394                if (isset($rule['max_error'])) {
395                    $error = $rule['max_error'];
396                } else {
397                    $error = "{$rule['caption']}は半角{$rule['max']}文字以内で入力してください";
398                }
399                $this->_setError($key, $error);
400                return false;
401            }
402            break;
403        }
404
405        return true;
406    }
407}
408
409?>
Note: See TracBrowser for help on using the repository browser.