OSDN Git Service

cc029641d1d482a77f7011a1ae1480827135e42f
[ethna/ethna.git] / class / Plugin / Validator / File.php
1 <?php
2 // vim: foldmethod=marker
3 /**
4  *  File.php
5  *
6  *  @author     ICHII Takashi <ichii386@schweetheart.jp>
7  *  @license    http://www.opensource.org/licenses/bsd-license.php The BSD License
8  *  @package    Ethna
9  *  @version    $Id$
10  */
11
12 // UPLOAD_ERR_* が未定義の場合
13 if (defined('UPLOAD_ERR_OK') == false) { // PHP 4.3.0
14     define('UPLOAD_ERR_OK', 0);
15 }
16 if (defined('UPLOAD_ERR_INI_SIZE') == false) { // PHP 4.3.0
17     define('UPLOAD_ERR_INI_SIZE', 1);
18 }
19 if (defined('UPLOAD_ERR_FORM_SIZE') == false) { // PHP 4.3.0
20     define('UPLOAD_ERR_FORM_SIZE', 2);
21 }
22 if (defined('UPLOAD_ERR_PARTIAL') == false) { // PHP 4.3.0
23     define('UPLOAD_ERR_PARTIAL', 3);
24 }
25 if (defined('UPLOAD_ERR_NO_FILE') == false) { // PHP 4.3.0
26     define('UPLOAD_ERR_NO_FILE', 4);
27 }
28 if (defined('UPLOAD_ERR_NO_TMP_DIR') == false) { // PHP 4.3.10, 5.0.3
29     define('UPLOAD_ERR_NO_TMP_DIR', 6);
30 }
31 if (defined('UPLOAD_ERR_CANT_WRITE') == false) { // PHP 5.1.0
32     define('UPLOAD_ERR_CANT_WRITE', 7);
33 }
34
35 // {{{ Ethna_Plugin_Validator_File
36 /**
37  *  ファイルチェックプラグイン
38  *
39  *  @author     ICHII Takashi <ichii386@schweetheart.jp>
40  *  @access     public
41  *  @package    Ethna
42  */
43 class Ethna_Plugin_Validator_File extends Ethna_Plugin_Validator
44 {
45     /** @var    bool    配列を受け取るかフラグ */
46     var $accept_array = false;
47
48     /**
49      *  アップロードされたファイルのチェックを行う
50      *  XXX: プラグインのエラーコードを修正する
51      *
52      *  @access public
53      *  @param  string  $name       フォームの名前
54      *  @param  mixed   $var        フォームの値
55      *  @param  array   $params     プラグインのパラメータ
56      */
57     function &validate($name, $var, $params)
58     {
59         $true = true;
60         if ($this->getFormType($name) != VAR_TYPE_FILE) {
61             return $true;
62         }
63
64         // そもそもアップロードされていない場合はスキップ
65         if ($var['error'] == UPLOAD_ERR_NO_FILE) {
66             return $true;
67         }
68
69
70         // エラーコードの検査
71         $msg = '';
72         switch ($var['error']) {
73         case UPLOAD_ERR_INI_SIZE: 
74             $msg = _et("Uploaded file size exceeds php.ini's upload_max_filesize directive.");
75             break;
76         case UPLOAD_ERR_FORM_SIZE:
77             $msg = _et('Uploaded File size exceeds MAX_FILE_SIZE specified in HTML Form.');
78             break;
79         case UPLOAD_ERR_PARTIAL:
80             $msg= _et('File was only uploaded patially.');
81             break;
82         case UPLOAD_ERR_NO_FILE:
83             $msg = _et('File was not uploaded.');
84             break;
85         case UPLOAD_ERR_NO_TMP_DIR:
86             $msg = _et('Temporary folder was not found.');
87             break;
88         case UPLOAD_ERR_CANT_WRITE:
89             $msg= _et('Could not write uploaded file to disk.');
90             break;
91         }
92         if ($msg != '') {
93             if (isset($params['error'])) {
94                 $msg = $params['error'];
95             }
96             return Ethna::raiseNotice($msg, E_FORM_WRONGTYPE_FILE);
97         }
98
99
100         // tmp_name の検査
101         if (isset($var['tmp_name']) == false || is_uploaded_file($var['tmp_name']) == false) {
102             if (isset($params['error'])) {
103                 $msg = $params['error'];
104             } else {
105                 $msg = _et('invalid tmp_name.');
106             }
107             return Ethna::raiseNotice($msg, E_FORM_WRONGTYPE_FILE);
108         }
109
110         // size の検査
111         if (isset($params['size_max'])) {
112             $st = stat($var['tmp_name']);
113             if ($st[7] > $this->_getSizeAsBytes($params['size_max'])) {
114                 if (isset($params['error'])) {
115                     $msg = $params['error'];
116                 } else {
117                     $msg = _et('Uploaded file size must be less than %s.');
118                 }
119                 return Ethna::raiseNotice($msg, E_FORM_WRONGTYPE_FILE, array($params['size_max']));
120             }
121         }
122         if (isset($params['size_min'])) {
123             $st = stat($var['tmp_name']);
124             if ($st[7] < $this->_getSizeAsBytes($params['size_min'])) {
125                 if (isset($params['error'])) {
126                     $msg = $params['error'];
127                 } else {
128                     $msg = _et('Uploaded file size must be more than %s.');
129                 }
130                 return Ethna::raiseNotice($msg, E_FORM_WRONGTYPE_FILE, array($params['size_min']));
131             }
132         }
133
134
135         // type の検査
136         if (isset($params['type'])) {
137             $type_list = to_array($params['type']);
138             $posted_mime = explode('/', $var['type'], 2);
139             foreach ($type_list as $type) {
140                 $wanted_mime = explode('/', $type, 2);
141                 $test = (count($wanted_mime) == 1)
142                         ? (strcasecmp($wanted_mime[0], $posted_mime[0]) == 0)
143                 : (strcasecmp($type, $var['type']) == 0);  
144                 if ($test == true) {
145                     break;
146                 }
147             }
148             if ($test == false) {
149                 if (isset($params['error'])) {
150                     $msg = $params['error'];
151                 } else {
152                     $msg = _et('Invalid file type.');
153                 }
154                 return Ethna::raiseNotice($msg, E_FORM_WRONGTYPE_FILE);
155             }
156         }
157
158         // name(ファイル名)の検査
159         if (isset($params['name'])) {
160             $test = ($params['name']{0} == '/')
161                 ? preg_match($params['name'], $var['name'])
162                 : (strcmp($params['name'], $var['name']) == 0);
163             if ($test == false) {
164                 if (isset($params['error'])) {
165                     $msg = $params['error'];
166                 } else {
167                     $msg = _et('Invalid file name.');
168                 }
169                 return Ethna::raiseNotice($msg, E_FORM_WRONGTYPE_FILE);
170             }
171         }
172
173         return $true;
174     }
175
176
177     function _getSizeAsBytes($size)
178     {
179         $unit = 1;
180         if (preg_match('/^([0-9]+)([mk])?(b(ytes?)?)?$/i', trim($size), $matches)) {
181             if (isset($matches[1])) {
182                 $size = $matches[1];
183             }
184             if (isset($matches[2])) {
185                 if (strtolower($matches[2]) === 'm') {
186                     $unit = 1048576;
187                 } else if (strtolower($matches[2]) === 'k') {
188                     $unit = 1024;
189                 }
190             }
191         }
192         return intval($matches[1]) * $unit;
193     }
194 }
195 // }}}
196 ?>