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

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

Last change on this file since 6527 was 6527, checked in by ogawa, 15 years ago

行末の半角スペースを削除

File size: 12.2 KB
Line 
1<?php
2/**
3 * @copyright 2005-2008 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        // エラーメッセージに名称変更を適用
141        $msg = preg_replace_callback('/WORD_[A-Z_]+/', create_function('$m', 'return defined($m[0]) ? constant($m[0]) : $m[0];'), $msg);
142
143        $this->errors[$key] = $msg;
144    }
145
146    /**
147     * validate
148     *
149     * @access public
150     * @return boolean エラーが発生しなかったかどうか
151     */
152    function validate()
153    {
154        foreach ($this->rules as $key => $rule) {
155            $rule = $this->_initRule($key, $rule);
156
157            $values = array();
158            if (isset($this->requests[$key])) {
159                if (!is_array($this->requests[$key])) {
160                    $values = array($this->requests[$key]);
161                } else {
162                    $values = $this->requests[$key];
163                }
164            }
165
166            if (empty($rule['is_array'])) {
167                $reqval = array_shift($values);
168                $result = $this->_filter($reqval, $rule['pre_filter']);
169
170                // 必須項目チェック
171                if (is_null($result) || $result === '') {
172                    if (!empty($rule['required'])) {
173                        if (isset($rule['required_error'])) {
174                            $error = $rule['required_error'];
175                        } else {
176                            $error = "{$rule['caption']}を入力してください";
177                        }
178                        $this->_setError($key, $error);
179                    } else {
180                        if (isset($rule['default'])) {
181                            $result = $rule['default'];
182                        } else {
183                            $result = null;
184                        }
185                    }
186                } else {
187                    $this->_validate($key, $result, $rule);
188                }
189            } else {
190                $result = array();
191                $empty = true;
192                foreach ($values as $k => $value) {
193                    $value = $this->_filter($value, $rule['pre_filter']);
194                    if (is_null($value) || $value === '') {
195                        continue;
196                    }
197
198                    $this->_validate($key, $value, $rule);
199                    $result[$k] = $value;
200                    $empty = false;
201                }
202                if ($empty) {
203                    if (!empty($rule['required'])) {
204                        if (isset($rule['required_error'])) {
205                            $error = $rule['required_error'];
206                        } else {
207                            $error = "{$rule['caption']}を入力してください";
208                        }
209                        $this->_setError($key, $error);
210                    } else {
211                        if (isset($rule['default'])) {
212                            $result = array($rule['default']);
213                        } else {
214                            $result = array();
215                        }
216                    }
217                }
218            }
219
220            $this->_setParam($key, $result);
221        }
222
223        return empty($this->errors);
224    }
225
226    /**
227     * 検証ルールの初期化
228     *
229     * @access private
230     * @param string $key
231     * @param array $rule
232     * @return array 初期化済み検証ルール
233     */
234    function _initRule($key, $rule)
235    {
236        if (!isset($rule['caption'])) {
237            $rule['caption'] = $key;
238        }
239
240        if (!isset($rule['pre_filter'])) {
241            $rule['pre_filter'] = $this->default_filter;
242        }
243
244        if (empty($rule['type'])) {
245            $rule['type'] = 'string';
246        }
247
248        if ($rule['type'] == 'int') {
249            $rule['pre_filter'] = $rule['pre_filter'] . ',intval';
250        }
251
252        return $rule;
253    }
254
255    /**
256     * _filter
257     *
258     * @access private
259     * @param string $value
260     * @param string $filter
261     * @return string フィルターを通した値
262     */
263    function _filter($value, $filter)
264    {
265        $filters = explode(',', $filter);
266        foreach ($filters as $filter) {
267            if (!empty($filter)) {
268                switch ($filter) {
269                case 'trim':
270                    if (OPENPNE_TRIM_DOUBLEBYTE_SPACE) {
271                        // 全角スペースに対応
272                        $value = preg_replace('/^[\s ]+/u', '', $value);
273                        $value = preg_replace('/[\s ]+$/u', '', $value);
274                    } else {
275                        $value = trim($value);
276                    }
277                    break;
278                case 'ltrim':
279                    if (OPENPNE_TRIM_DOUBLEBYTE_SPACE) {
280                        // 全角スペースに対応
281                        $value = preg_replace('/^[\s ]+/u', '', $value);
282                    } else {
283                        $value = ltrim($value);
284                    }
285                    break;
286                case 'rtrim':
287                    if (OPENPNE_TRIM_DOUBLEBYTE_SPACE) {
288                        // 全角スペースに対応
289                        $value = preg_replace('/[\s ]+$/u', '', $value);
290                    } else {
291                        $value = rtrim($value);
292                    }
293                    break;
294                case 'ntrim':
295                    // NULL バイト・制御文字(HT,LF,NBSP以外)をすべて削除
296                    $value = preg_replace("/[\x{0}-\x{08}\x{0b}-\x{1f}\x{7f}-\x{9f}\x{ad}]/u", '', $value);
297                    break;
298                case 'mysqltext':
299                    if (is_string($value) && strlen($value) > 65535) {
300                        $value = mb_strcut($value, 0, 65535);
301                    }
302                    break;
303                case 'intval':
304                    if (is_numeric($value)) {
305                        $value = (int)$value;
306                    }
307                    break;
308                }
309            }
310        }
311        return $value;
312    }
313
314    /**
315     * _validate
316     *
317     * @access private
318     * @param string $key
319     * @param string $reqval
320     * @param array $rule
321     * @return boolean
322     */
323    function _validate($key, $reqval, $rule)
324    {
325        // 型チェック
326        switch (strtolower($rule['type'])) {
327        case 'int':
328            if (!is_numeric($reqval)) {
329                if (isset($rule['type_error'])) {
330                    $error = $rule['type_error'];
331                } else {
332                    $error = "{$rule['caption']}は数値で入力してください";
333                }
334                $this->_setError($key, $error);
335                return false;
336            }
337            break;
338        case 'bool':
339            if ($reqval != '0' && $reqval != '1') {
340                if (isset($rule['type_error'])) {
341                    $error = $rule['type_error'];
342                } else {
343                    $error = "{$rule['caption']}の値が不正です";
344                }
345                $this->_setError($key, $error);
346                return false;
347            }
348            break;
349        case 'string':
350            break;
351        case 'regexp':
352            if (isset($rule['regexp']) && !preg_match($rule['regexp'], $reqval)) {
353                if (isset($rule['type_error'])) {
354                    $error = $rule['type_error'];
355                } else {
356                    $error = "{$rule['caption']}を正しく入力してください";
357                }
358                $this->_setError($key, $error);
359                return false;
360            }
361            break;
362        default:
363            $error = "{$rule['type']}は未定義の型です";
364            $this->_setError($key, $error);
365            return false;
366        }
367
368        // min/max チェック
369        switch ($rule['type']) {
370        case 'int':
371            // min
372            if (isset($rule['min']) && $reqval < intval($rule['min'])) {
373                if (isset($rule['min_error'])) {
374                    $error = $rule['min_error'];
375                } else {
376                    $error = "{$rule['caption']}{$rule['min']}以上の数値で入力してください";
377                }
378                $this->_setError($key, $error);
379                return false;
380            }
381            // max
382            if (isset ($rule['max']) && $reqval > $rule['max']) {
383                if (isset($rule['max_error'])) {
384                    $error = $rule['max_error'];
385                } else {
386                    $error = "{$rule['caption']}{$rule['max']}以下の数値で入力してください";
387                }
388                $this->_setError($key, $error);
389                return false;
390            }
391            break;
392        case 'string':
393        case 'regexp':
394            // min
395            if (isset($rule['min']) && (mb_strwidth($reqval, 'UTF-8') < $rule['min'])) {
396                if (isset($rule['min_error'])) {
397                    $error = $rule['min_error'];
398                } else {
399                    $error = "{$rule['caption']}は半角{$rule['min']}文字以上で入力してください";
400                }
401                $this->_setError($key, $error);
402                return false;
403            }
404            // max
405            if (isset($rule['max']) && (mb_strwidth($reqval, 'UTF-8') > $rule['max'])) {
406                if (isset($rule['max_error'])) {
407                    $error = $rule['max_error'];
408                } else {
409                    $error = "{$rule['caption']}は半角{$rule['max']}文字以内で入力してください";
410                }
411                $this->_setError($key, $error);
412                return false;
413            }
414            break;
415        }
416
417        return true;
418    }
419}
420
421?>
Note: See TracBrowser for help on using the repository browser.