file.php 10 KB

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