PageRenderTime 61ms CodeModel.GetById 29ms RepoModel.GetById 0ms app.codeStats 0ms

/library/spoon/form/file.php

https://github.com/JonckheereM/Public
PHP | 435 lines | 154 code | 80 blank | 201 comment | 57 complexity | b2cfb3024dea4dbdfec963f1955f45bf MD5 | raw file
  1. <?php
  2. /**
  3. * Spoon Library
  4. *
  5. * This source file is part of the Spoon Library. More information,
  6. * documentation and tutorials can be found @ http://www.spoon-library.com
  7. *
  8. * @package spoon
  9. * @subpackage form
  10. *
  11. *
  12. * @author Davy Hellemans <davy@spoon-library.com>
  13. * @author Tijs Verkoyen <tijs@spoon-library.com>
  14. * @author Dave Lens <dave@spoon-library.com>
  15. * @since 0.1.1
  16. */
  17. /**
  18. * Create an html filefield
  19. *
  20. * @package spoon
  21. * @subpackage form
  22. *
  23. *
  24. * @author Davy Hellemans <davy@spoon-library.com>
  25. * @since 0.1.1
  26. */
  27. class SpoonFormFile extends SpoonFormAttributes
  28. {
  29. /**
  30. * Class attribute on error
  31. *
  32. * @var string
  33. */
  34. protected $classError;
  35. /**
  36. * Errors stack
  37. *
  38. * @var string
  39. */
  40. protected $errors;
  41. /**
  42. * Filename (without extension)
  43. *
  44. * @var string
  45. */
  46. private $filename;
  47. /**
  48. * Class constructor.
  49. *
  50. * @return void
  51. * @param string $name
  52. * @param string[optional] $class
  53. * @param string[optional] $classError
  54. */
  55. public function __construct($name, $class = 'inputFilefield', $classError = 'inputFilefieldError')
  56. {
  57. // set name & id
  58. $this->attributes['id'] = SpoonFilter::toCamelCase((string) $name, '_', true);
  59. $this->attributes['name'] = (string) $name;
  60. // custom optional fields
  61. $this->attributes['class'] = (string) $class;
  62. $this->classError = (string) $classError;
  63. }
  64. /**
  65. * Adds an error to the error stack.
  66. *
  67. * @return void
  68. * @param string $error
  69. */
  70. public function addError($error)
  71. {
  72. $this->errors .= (string) $error;
  73. }
  74. /**
  75. * Retrieves the class based on the errors status.
  76. *
  77. * @return string
  78. */
  79. protected function getClassHTML()
  80. {
  81. // default value
  82. $value = '';
  83. // has errors
  84. if($this->errors != '')
  85. {
  86. // class & classOnError defined
  87. if($this->attributes['class'] != '' && $this->classError != '') $value = ' class="'. $this->attributes['class'] .' '. $this->classError .'"';
  88. // only class defined
  89. elseif($this->attributes['class'] != '') $value = ' class="'. $this->attributes['class'] .'"';
  90. // only error defined
  91. elseif($this->classError != '') $value = ' class="'. $this->classError .'"';
  92. }
  93. // no errors
  94. else
  95. {
  96. // class defined
  97. if($this->attributes['class'] != '') $value = ' class="'. $this->attributes['class'] .'"';
  98. }
  99. return $value;
  100. }
  101. /**
  102. * Retrieve the errors.
  103. *
  104. * @return string
  105. */
  106. public function getErrors()
  107. {
  108. return $this->errors;
  109. }
  110. /**
  111. * Retrieve the extension of the uploaded file.
  112. *
  113. * @return string
  114. * @param bool[optional] $lowercase
  115. */
  116. public function getExtension($lowercase = true)
  117. {
  118. return $this->isFilled() ? (SpoonFile::getExtension($_FILES[$this->attributes['name']]['name'], $lowercase)) : '';
  119. }
  120. /**
  121. * Retrieve the filename of the uploade file.
  122. *
  123. * @return string
  124. * @param bool[optional] $includeExtension
  125. */
  126. public function getFileName($includeExtension = true)
  127. {
  128. if($this->isFilled()) return (!$includeExtension) ? substr($_FILES[$this->attributes['name']]['name'], 0, strripos($_FILES[$this->attributes['name']]['name'], '.'. SpoonFile::getExtension($_FILES[$this->attributes['name']]['name'], false))) : $_FILES[$this->attributes['name']]['name'];
  129. return '';
  130. }
  131. /**
  132. * Retrieve the filesize of the file in a specified unit.
  133. *
  134. * @return int
  135. * @param string[optional] $unit
  136. * @param int[optional] $precision
  137. */
  138. public function getFileSize($unit = 'kb', $precision = null)
  139. {
  140. if($this->isFilled())
  141. {
  142. // redefine unit
  143. $unit = SpoonFilter::getValue(strtolower($unit), array('b', 'kb', 'mb', 'gb'), 'kb');
  144. // fetch size
  145. $size = $_FILES[$this->attributes['name']]['size'];
  146. // redefine prection
  147. if($precision !== null) $precision = (int) $precision;
  148. // bytes
  149. if($unit == 'b') return $size;
  150. // kilobytes
  151. if($unit == 'kb') return round(($size / 1024), $precision);
  152. // megabytes
  153. if($unit == 'mb') return round(($size / 1024 / 1024), $precision);
  154. // gigabytes
  155. if($unit == 'gb') return round(($size / 1024 / 1024 / 1024), $precision);
  156. }
  157. return 0;
  158. }
  159. /**
  160. * Get the temporary filename.
  161. *
  162. * @return string
  163. */
  164. public function getTempFileName()
  165. {
  166. return $this->isFilled() ? (string) $_FILES[$this->attributes['name']]['tmp_name'] : '';
  167. }
  168. /**
  169. * Checks if the extension is allowed.
  170. *
  171. * @return bool
  172. * @param array $extensions
  173. * @param string[optional] $error
  174. */
  175. public function isAllowedExtension(array $extensions, $error = null)
  176. {
  177. // file has been uploaded
  178. if($this->isFilled())
  179. {
  180. // search for extension
  181. $return = in_array(strtolower(SpoonFile::getExtension($_FILES[$this->attributes['name']]['name'])), $extensions);
  182. // add error if needed
  183. if(!$return && $error !== null) $this->setError($error);
  184. // return
  185. return $return;
  186. }
  187. // no file uploaded
  188. else
  189. {
  190. // add error if needed
  191. if($error !== null) $this->setError($error);
  192. // return
  193. return false;
  194. }
  195. }
  196. /**
  197. * Checks if the mime-type is allowed.
  198. * @see http://www.w3schools.com/media/media_mimeref.asp
  199. *
  200. * @return bool
  201. * @param array $allowedTypes
  202. * @param string[optional] $error
  203. */
  204. public function isAllowedMimeType(array $allowedTypes, $error = null)
  205. {
  206. // file has been uploaded
  207. if($this->isFilled())
  208. {
  209. // get image properties
  210. $properties = @getimagesize($_FILES[$this->attributes['name']]['tmp_name']);
  211. // invalid properties
  212. if($properties === false) $return = false;
  213. // search for mime-type
  214. else $return = in_array($properties['mime'], $allowedTypes);
  215. // add error if needed
  216. if(!$return && $error !== null) $this->setError($error);
  217. // return
  218. return $return;
  219. }
  220. // no file uploaded
  221. else
  222. {
  223. // add error if needed
  224. if($error !== null) $this->setError($error);
  225. // return
  226. return false;
  227. }
  228. }
  229. /**
  230. * Checks of the filesize is greater, equal or smaller than the given number + units.
  231. *
  232. * @return bool
  233. * @param int $size
  234. * @param string[optional] $unit
  235. * @param string[optional] $operator
  236. * @param string[optional] $error
  237. */
  238. public function isFilesize($size, $unit = 'kb', $operator = 'smaller', $error = null)
  239. {
  240. // file has been uploaded
  241. if($this->isFilled())
  242. {
  243. // define size
  244. $actualSize = $this->getFileSize($unit, 0);
  245. // operator
  246. $operator = SpoonFilter::getValue(strtolower($operator), array('smaller', 'equal', 'greater'), 'smaller');
  247. // smaller
  248. if($operator == 'smaller' && $actualSize < $size) return true;
  249. // equal
  250. if($operator == 'equal' && $actualSize == $size) return true;
  251. // greater
  252. if($operator == 'greater' && $actualSize > $size) return true;
  253. }
  254. // has error
  255. if($error !== null) $this->setError($error);
  256. return false;
  257. }
  258. /**
  259. * Checks for a valid file name (including dots but no slashes and other forbidden characters).
  260. *
  261. * @return bool
  262. * @param string[optional] $error
  263. */
  264. public function isFilename($error = null)
  265. {
  266. // correct filename
  267. if($this->isFilled() && SpoonFilter::isFilename($this->getFileName())) return true;
  268. // has error
  269. if($error !== null) $this->setError($error);
  270. return false;
  271. }
  272. /**
  273. * Checks if this field was submitted & filled.
  274. *
  275. * @return bool
  276. * @param string[optional] $error
  277. */
  278. public function isFilled($error = null)
  279. {
  280. // default error
  281. $hasError = true;
  282. // form submitted
  283. if($this->isSubmitted())
  284. {
  285. // submitted, no errors & has a name!
  286. if(isset($_FILES[$this->attributes['name']]) && $_FILES[$this->attributes['name']]['error'] == 0 && $_FILES[$this->attributes['name']] != '') $hasError = false;
  287. }
  288. // has erorr?
  289. if($hasError)
  290. {
  291. if($error !== null) $this->setError($error);
  292. return false;
  293. }
  294. return true;
  295. }
  296. /**
  297. * Attemps to move the uploaded file to the new location.
  298. *
  299. * @return bool
  300. * @param string $path
  301. * @param int[optional] $chmod
  302. */
  303. public function moveFile($path, $chmod = 0755)
  304. {
  305. // move the file
  306. $return = @move_uploaded_file($_FILES[$this->attributes['name']]['tmp_name'], (string) $path);
  307. // chmod file
  308. @chmod($path, $chmod);
  309. // return move file status
  310. return $return;
  311. }
  312. /**
  313. * Parses the html for this filefield.
  314. *
  315. * @return string
  316. * @param SpoonTemplate[optional] $template
  317. */
  318. public function parse(SpoonTemplate $template = null)
  319. {
  320. // name is required
  321. if($this->attributes['name'] == '') throw new SpoonFormException('A name is required for a file field. Please provide a name.');
  322. // start html generation
  323. $output = '<input type="file"';
  324. // add attributes
  325. $output .= $this->getAttributesHTML(array('[id]' => $this->attributes['id'], '[name]' => $this->attributes['name'])) .' />';
  326. // parse to template
  327. if($template !== null)
  328. {
  329. $template->assign('file'. SpoonFilter::toCamelCase($this->attributes['name']), $output);
  330. $template->assign('file'. SpoonFilter::toCamelCase($this->attributes['name']) .'Error', ($this->errors!= '') ? '<span class="formError">'. $this->errors .'</span>' : '');
  331. }
  332. return $output;
  333. }
  334. /**
  335. * Set the class on error.
  336. *
  337. * @return void
  338. * @param string $class
  339. */
  340. public function setClassOnError($class)
  341. {
  342. $this->classError = (string) $class;
  343. }
  344. /**
  345. * Overwrites the error stack.
  346. *
  347. * @return void
  348. * @param string $error
  349. */
  350. public function setError($error)
  351. {
  352. $this->errors = (string) $error;
  353. }
  354. }
  355. ?>