file.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358
  1. <?php
  2. /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
  3. /**
  4. * HTML class for a file upload field
  5. *
  6. * PHP versions 4 and 5
  7. *
  8. * LICENSE: This source file is subject to version 3.01 of the PHP license
  9. * that is available through the world-wide-web at the following URI:
  10. * http://www.php.net/license/3_01.txt If you did not receive a copy of
  11. * the PHP License and are unable to obtain it through the web, please
  12. * send a note to license@php.net so we can mail you a copy immediately.
  13. *
  14. * @category HTML
  15. * @package HTML_QuickForm
  16. * @author Adam Daniel <adaniel1@eesus.jnj.com>
  17. * @author Bertrand Mansion <bmansion@mamasam.com>
  18. * @author Alexey Borzov <avb@php.net>
  19. * @copyright 2001-2009 The PHP Group
  20. * @license http://www.php.net/license/3_01.txt PHP License 3.01
  21. * @version CVS: $Id: file.php,v 1.25 2009/04/04 21:34:02 avb Exp $
  22. * @link http://pear.php.net/package/HTML_QuickForm
  23. */
  24. /**
  25. * Base class for <input /> form elements
  26. */
  27. //require_once 'HTML/QuickForm/input.php';
  28. // register file-related rules
  29. HTML_QuickForm::registerRule('uploadedfile', 'callback', '_ruleIsUploadedFile', 'HTML_QuickForm_file');
  30. HTML_QuickForm::registerRule('maxfilesize', 'callback', '_ruleCheckMaxFileSize', 'HTML_QuickForm_file');
  31. HTML_QuickForm::registerRule('mimetype', 'callback', '_ruleCheckMimeType', 'HTML_QuickForm_file');
  32. HTML_QuickForm::registerRule('filename', 'callback', '_ruleCheckFileName', 'HTML_QuickForm_file');
  33. /**
  34. * HTML class for a file upload field
  35. *
  36. * @category HTML
  37. * @package HTML_QuickForm
  38. * @author Adam Daniel <adaniel1@eesus.jnj.com>
  39. * @author Bertrand Mansion <bmansion@mamasam.com>
  40. * @author Alexey Borzov <avb@php.net>
  41. * @version Release: 3.2.11
  42. * @since 1.0
  43. */
  44. class HTML_QuickForm_file extends HTML_QuickForm_input
  45. {
  46. // {{{ properties
  47. /**
  48. * Uploaded file data, from $_FILES
  49. * @var array
  50. */
  51. var $_value = null;
  52. // }}}
  53. // {{{ constructor
  54. /**
  55. * Class constructor
  56. *
  57. * @param string Input field name attribute
  58. * @param string Input field label
  59. * @param mixed (optional)Either a typical HTML attribute string
  60. * or an associative array
  61. * @since 1.0
  62. * @access public
  63. */
  64. function HTML_QuickForm_file($elementName=null, $elementLabel=null, $attributes=null)
  65. {
  66. HTML_QuickForm_input::HTML_QuickForm_input($elementName, $elementLabel, $attributes);
  67. $this->setType('file');
  68. } //end constructor
  69. // }}}
  70. // {{{ setSize()
  71. /**
  72. * Sets size of file element
  73. *
  74. * @param int Size of file element
  75. * @since 1.0
  76. * @access public
  77. */
  78. function setSize($size)
  79. {
  80. $this->updateAttributes(array('size' => $size));
  81. } //end func setSize
  82. // }}}
  83. // {{{ getSize()
  84. /**
  85. * Returns size of file element
  86. *
  87. * @since 1.0
  88. * @access public
  89. * @return int
  90. */
  91. function getSize()
  92. {
  93. return $this->getAttribute('size');
  94. } //end func getSize
  95. // }}}
  96. // {{{ freeze()
  97. /**
  98. * Freeze the element so that only its value is returned
  99. *
  100. * @access public
  101. * @return bool
  102. */
  103. function freeze()
  104. {
  105. return false;
  106. } //end func freeze
  107. // }}}
  108. // {{{ setValue()
  109. /**
  110. * Sets value for file element.
  111. *
  112. * Actually this does nothing. The function is defined here to override
  113. * HTML_Quickform_input's behaviour of setting the 'value' attribute. As
  114. * no sane user-agent uses <input type="file">'s value for anything
  115. * (because of security implications) we implement file's value as a
  116. * read-only property with a special meaning.
  117. *
  118. * @param mixed Value for file element
  119. * @since 3.0
  120. * @access public
  121. */
  122. function setValue($value)
  123. {
  124. return null;
  125. } //end func setValue
  126. // }}}
  127. // {{{ getValue()
  128. /**
  129. * Returns information about the uploaded file
  130. *
  131. * @since 3.0
  132. * @access public
  133. * @return array
  134. */
  135. function getValue()
  136. {
  137. return $this->_value;
  138. } // end func getValue
  139. // }}}
  140. // {{{ onQuickFormEvent()
  141. /**
  142. * Called by HTML_QuickForm whenever form event is made on this element
  143. *
  144. * @param string Name of event
  145. * @param mixed event arguments
  146. * @param object calling object
  147. * @since 1.0
  148. * @access public
  149. * @return bool
  150. */
  151. function onQuickFormEvent($event, $arg, &$caller)
  152. {
  153. switch ($event) {
  154. case 'updateValue':
  155. if ($caller->getAttribute('method') == 'get') {
  156. return PEAR::raiseError('Cannot add a file upload field to a GET method form');
  157. }
  158. $this->_value = $this->_findValue();
  159. $caller->updateAttributes(array('enctype' => 'multipart/form-data'));
  160. $caller->setMaxFileSize();
  161. break;
  162. case 'addElement':
  163. $this->onQuickFormEvent('createElement', $arg, $caller);
  164. return $this->onQuickFormEvent('updateValue', null, $caller);
  165. break;
  166. case 'createElement':
  167. $className = get_class($this);
  168. $this->$className($arg[0], $arg[1], $arg[2]);
  169. break;
  170. }
  171. return true;
  172. } // end func onQuickFormEvent
  173. // }}}
  174. // {{{ moveUploadedFile()
  175. /**
  176. * Moves an uploaded file into the destination
  177. *
  178. * @param string Destination directory path
  179. * @param string New file name
  180. * @access public
  181. * @return bool Whether the file was moved successfully
  182. */
  183. function moveUploadedFile($dest, $fileName = '')
  184. {
  185. if ($dest != '' && substr($dest, -1) != '/') {
  186. $dest .= '/';
  187. }
  188. $fileName = ($fileName != '') ? $fileName : basename($this->_value['name']);
  189. return move_uploaded_file($this->_value['tmp_name'], $dest . $fileName);
  190. } // end func moveUploadedFile
  191. // }}}
  192. // {{{ isUploadedFile()
  193. /**
  194. * Checks if the element contains an uploaded file
  195. *
  196. * @access public
  197. * @return bool true if file has been uploaded, false otherwise
  198. */
  199. function isUploadedFile()
  200. {
  201. return $this->_ruleIsUploadedFile($this->_value);
  202. } // end func isUploadedFile
  203. // }}}
  204. // {{{ _ruleIsUploadedFile()
  205. /**
  206. * Checks if the given element contains an uploaded file
  207. *
  208. * @param array Uploaded file info (from $_FILES)
  209. * @access private
  210. * @return bool true if file has been uploaded, false otherwise
  211. */
  212. function _ruleIsUploadedFile($elementValue)
  213. {
  214. if ((isset($elementValue['error']) && $elementValue['error'] == 0) ||
  215. (!empty($elementValue['tmp_name']) && $elementValue['tmp_name'] != 'none')) {
  216. return is_uploaded_file($elementValue['tmp_name']);
  217. } else {
  218. return false;
  219. }
  220. } // end func _ruleIsUploadedFile
  221. // }}}
  222. // {{{ _ruleCheckMaxFileSize()
  223. /**
  224. * Checks that the file does not exceed the max file size
  225. *
  226. * @param array Uploaded file info (from $_FILES)
  227. * @param int Max file size
  228. * @access private
  229. * @return bool true if filesize is lower than maxsize, false otherwise
  230. */
  231. function _ruleCheckMaxFileSize($elementValue, $maxSize)
  232. {
  233. if (!empty($elementValue['error']) &&
  234. (UPLOAD_ERR_FORM_SIZE == $elementValue['error'] || UPLOAD_ERR_INI_SIZE == $elementValue['error'])) {
  235. return false;
  236. }
  237. if (!HTML_QuickForm_file::_ruleIsUploadedFile($elementValue)) {
  238. return true;
  239. }
  240. return ($maxSize >= @filesize($elementValue['tmp_name']));
  241. } // end func _ruleCheckMaxFileSize
  242. // }}}
  243. // {{{ _ruleCheckMimeType()
  244. /**
  245. * Checks if the given element contains an uploaded file of the right mime type
  246. *
  247. * @param array Uploaded file info (from $_FILES)
  248. * @param mixed Mime Type (can be an array of allowed types)
  249. * @access private
  250. * @return bool true if mimetype is correct, false otherwise
  251. */
  252. function _ruleCheckMimeType($elementValue, $mimeType)
  253. {
  254. if (!HTML_QuickForm_file::_ruleIsUploadedFile($elementValue)) {
  255. return true;
  256. }
  257. if (is_array($mimeType)) {
  258. return in_array($elementValue['type'], $mimeType);
  259. }
  260. return $elementValue['type'] == $mimeType;
  261. } // end func _ruleCheckMimeType
  262. // }}}
  263. // {{{ _ruleCheckFileName()
  264. /**
  265. * Checks if the given element contains an uploaded file of the filename regex
  266. *
  267. * @param array Uploaded file info (from $_FILES)
  268. * @param string Regular expression
  269. * @access private
  270. * @return bool true if name matches regex, false otherwise
  271. */
  272. function _ruleCheckFileName($elementValue, $regex)
  273. {
  274. if (!HTML_QuickForm_file::_ruleIsUploadedFile($elementValue)) {
  275. return true;
  276. }
  277. return (bool)preg_match($regex, $elementValue['name']);
  278. } // end func _ruleCheckFileName
  279. // }}}
  280. // {{{ _findValue()
  281. /**
  282. * Tries to find the element value from the values array
  283. *
  284. * Needs to be redefined here as $_FILES is populated differently from
  285. * other arrays when element name is of the form foo[bar]
  286. *
  287. * @access private
  288. * @return mixed
  289. */
  290. function _findValue(&$values = null)
  291. {
  292. if (empty($_FILES)) {
  293. return null;
  294. }
  295. $elementName = $this->getName();
  296. if (isset($_FILES[$elementName])) {
  297. return $_FILES[$elementName];
  298. } elseif (false !== ($pos = strpos($elementName, '['))) {
  299. $base = str_replace(
  300. array('\\', '\''), array('\\\\', '\\\''),
  301. substr($elementName, 0, $pos)
  302. );
  303. $idx = "['" . str_replace(
  304. array('\\', '\'', ']', '['), array('\\\\', '\\\'', '', "']['"),
  305. substr($elementName, $pos + 1, -1)
  306. ) . "']";
  307. $props = array('name', 'type', 'size', 'tmp_name', 'error');
  308. $code = "if (!isset(\$_FILES['{$base}']['name']{$idx})) {\n" .
  309. " return null;\n" .
  310. "} else {\n" .
  311. " \$value = array();\n";
  312. foreach ($props as $prop) {
  313. $code .= " \$value['{$prop}'] = \$_FILES['{$base}']['{$prop}']{$idx};\n";
  314. }
  315. return eval($code . " return \$value;\n}\n");
  316. } else {
  317. return null;
  318. }
  319. }
  320. // }}}
  321. } // end class HTML_QuickForm_file
  322. ?>