2 /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
5 * HTML class for a file upload field
9 * LICENSE: This source file is subject to version 3.01 of the PHP license
10 * that is available through the world-wide-web at the following URI:
11 * http://www.php.net/license/3_01.txt If you did not receive a copy of
12 * the PHP License and are unable to obtain it through the web, please
13 * send a note to license@php.net so we can mail you a copy immediately.
16 * @package HTML_QuickForm
17 * @author Adam Daniel <adaniel1@eesus.jnj.com>
18 * @author Bertrand Mansion <bmansion@mamasam.com>
19 * @author Alexey Borzov <avb@php.net>
20 * @copyright 2001-2011 The PHP Group
21 * @license http://www.php.net/license/3_01.txt PHP License 3.01
23 * @link http://pear.php.net/package/HTML_QuickForm
27 * Base class for <input /> form elements
29 require_once 'HTML/QuickForm/input.php';
31 // register file-related rules
32 if (class_exists('HTML_QuickForm')) {
33 HTML_QuickForm::registerRule('uploadedfile', 'callback', '_ruleIsUploadedFile', 'HTML_QuickForm_file');
34 HTML_QuickForm::registerRule('maxfilesize', 'callback', '_ruleCheckMaxFileSize', 'HTML_QuickForm_file');
35 HTML_QuickForm::registerRule('mimetype', 'callback', '_ruleCheckMimeType', 'HTML_QuickForm_file');
36 HTML_QuickForm::registerRule('filename', 'callback', '_ruleCheckFileName', 'HTML_QuickForm_file');
40 * HTML class for a file upload field
43 * @package HTML_QuickForm
44 * @author Adam Daniel <adaniel1@eesus.jnj.com>
45 * @author Bertrand Mansion <bmansion@mamasam.com>
46 * @author Alexey Borzov <avb@php.net>
47 * @version Release: 3.2.16
50 class HTML_QuickForm_file extends HTML_QuickForm_input
55 * Uploaded file data, from $_FILES
66 * @param string Input field name attribute
67 * @param string Input field label
68 * @param mixed (optional)Either a typical HTML attribute string
69 * or an associative array
73 function HTML_QuickForm_file($elementName=null, $elementLabel=null, $attributes=null)
75 HTML_QuickForm_input::HTML_QuickForm_input($elementName, $elementLabel, $attributes);
76 $this->setType('file');
83 * Sets size of file element
85 * @param int Size of file element
89 function setSize($size)
91 $this->updateAttributes(array('size' => $size));
98 * Returns size of file element
106 return $this->getAttribute('size');
113 * Freeze the element so that only its value is returned
127 * Sets value for file element.
129 * Actually this does nothing. The function is defined here to override
130 * HTML_Quickform_input's behaviour of setting the 'value' attribute. As
131 * no sane user-agent uses <input type="file">'s value for anything
132 * (because of security implications) we implement file's value as a
133 * read-only property with a special meaning.
135 * @param mixed Value for file element
139 function setValue($value)
142 } //end func setValue
148 * Returns information about the uploaded file
156 return $this->_value;
157 } // end func getValue
160 // {{{ onQuickFormEvent()
163 * Called by HTML_QuickForm whenever form event is made on this element
165 * @param string Name of event
166 * @param mixed event arguments
167 * @param object calling object
172 function onQuickFormEvent($event, $arg, &$caller)
176 if ($caller->getAttribute('method') == 'get') {
177 return PEAR::raiseError('Cannot add a file upload field to a GET method form');
179 $this->_value = $this->_findValue();
180 $caller->updateAttributes(array('enctype' => 'multipart/form-data'));
181 $caller->setMaxFileSize();
184 $this->onQuickFormEvent('createElement', $arg, $caller);
185 return $this->onQuickFormEvent('updateValue', null, $caller);
187 case 'createElement':
188 $className = get_class($this);
189 $this->$className($arg[0], $arg[1], $arg[2]);
193 } // end func onQuickFormEvent
196 // {{{ moveUploadedFile()
199 * Moves an uploaded file into the destination
201 * @param string Destination directory path
202 * @param string New file name
204 * @return bool Whether the file was moved successfully
206 function moveUploadedFile($dest, $fileName = '')
208 if ($dest != '' && substr($dest, -1) != '/') {
211 $fileName = ($fileName != '') ? $fileName : basename($this->_value['name']);
212 return move_uploaded_file($this->_value['tmp_name'], $dest . $fileName);
213 } // end func moveUploadedFile
216 // {{{ isUploadedFile()
219 * Checks if the element contains an uploaded file
222 * @return bool true if file has been uploaded, false otherwise
224 function isUploadedFile()
226 return $this->_ruleIsUploadedFile($this->_value);
227 } // end func isUploadedFile
230 // {{{ _ruleIsUploadedFile()
233 * Checks if the given element contains an uploaded file
235 * @param array Uploaded file info (from $_FILES)
237 * @return bool true if file has been uploaded, false otherwise
239 function _ruleIsUploadedFile($elementValue)
241 if ((isset($elementValue['error']) && $elementValue['error'] == 0) ||
242 (!empty($elementValue['tmp_name']) && $elementValue['tmp_name'] != 'none')) {
243 return is_uploaded_file($elementValue['tmp_name']);
247 } // end func _ruleIsUploadedFile
250 // {{{ _ruleCheckMaxFileSize()
253 * Checks that the file does not exceed the max file size
255 * @param array Uploaded file info (from $_FILES)
256 * @param int Max file size
258 * @return bool true if filesize is lower than maxsize, false otherwise
260 function _ruleCheckMaxFileSize($elementValue, $maxSize)
262 if (!empty($elementValue['error']) &&
263 (UPLOAD_ERR_FORM_SIZE == $elementValue['error'] || UPLOAD_ERR_INI_SIZE == $elementValue['error'])) {
266 if (!HTML_QuickForm_file::_ruleIsUploadedFile($elementValue)) {
269 return ($maxSize >= @filesize($elementValue['tmp_name']));
270 } // end func _ruleCheckMaxFileSize
273 // {{{ _ruleCheckMimeType()
276 * Checks if the given element contains an uploaded file of the right mime type
278 * @param array Uploaded file info (from $_FILES)
279 * @param mixed Mime Type (can be an array of allowed types)
281 * @return bool true if mimetype is correct, false otherwise
283 function _ruleCheckMimeType($elementValue, $mimeType)
285 if (!HTML_QuickForm_file::_ruleIsUploadedFile($elementValue)) {
288 if (is_array($mimeType)) {
289 return in_array($elementValue['type'], $mimeType);
291 return $elementValue['type'] == $mimeType;
292 } // end func _ruleCheckMimeType
295 // {{{ _ruleCheckFileName()
298 * Checks if the given element contains an uploaded file of the filename regex
300 * @param array Uploaded file info (from $_FILES)
301 * @param string Regular expression
303 * @return bool true if name matches regex, false otherwise
305 function _ruleCheckFileName($elementValue, $regex)
307 if (!HTML_QuickForm_file::_ruleIsUploadedFile($elementValue)) {
310 return (bool)preg_match($regex, $elementValue['name']);
311 } // end func _ruleCheckFileName
317 * Tries to find the element value from the values array
319 * Needs to be redefined here as $_FILES is populated differently from
320 * other arrays when element name is of the form foo[bar]
322 * @param bool $sc1 unused, for signature compatibility
327 function _findValue(&$sc1 = null)
329 if (empty($_FILES)) {
332 $elementName = $this->getName();
333 if (isset($_FILES[$elementName])) {
334 return $_FILES[$elementName];
335 } elseif (false !== ($pos = strpos($elementName, '['))) {
337 array('\\', '\''), array('\\\\', '\\\''),
338 substr($elementName, 0, $pos)
340 $idx = "['" . str_replace(
341 array('\\', '\'', ']', '['), array('\\\\', '\\\'', '', "']['"),
342 substr($elementName, $pos + 1, -1)
344 $props = array('name', 'type', 'size', 'tmp_name', 'error');
345 $code = "if (!isset(\$_FILES['{$base}']['name']{$idx})) {\n" .
348 " \$value = array();\n";
349 foreach ($props as $prop) {
350 $code .= " \$value['{$prop}'] = \$_FILES['{$base}']['{$prop}']{$idx};\n";
352 return eval($code . " return \$value;\n}\n");
359 } // end class HTML_QuickForm_file