PageRenderTime 46ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/panada/Resources/Upload.php

http://github.com/panada/Panada
PHP | 496 lines | 286 code | 74 blank | 136 comment | 33 complexity | 64eaf45ff291770439dee51372f4133a MD5 | raw file
Possible License(s): BSD-3-Clause
  1. <?php
  2. /**
  3. * Panada Upload API.
  4. *
  5. * @link http://panadaframework.com/
  6. *
  7. * @license http://www.opensource.org/licenses/bsd-license.php
  8. * @author Iskandar Soesman <k4ndar@yahoo.com>
  9. *
  10. * @since Version 0.1
  11. */
  12. namespace Resources;
  13. if (!defined('PIMG_RESIZE')) {
  14. define('PIMG_RESIZE', 'resize');
  15. }
  16. if (!defined('PIMG_CROP')) {
  17. define('PIMG_CROP', 'crop');
  18. }
  19. if (!defined('PIMG_RESIZE_CROP')) {
  20. define('PIMG_RESIZE_CROP', 'resize_crop');
  21. }
  22. class Upload
  23. {
  24. /**
  25. * @var array Define the varible.
  26. */
  27. public $file;
  28. /**
  29. *@var object Error message container.
  30. */
  31. public $error;
  32. /**
  33. * @var array Initiate the error mesages.
  34. */
  35. public $errorMessages = array();
  36. /**
  37. * @var string Folder location.
  38. */
  39. public $folderLocation = '';
  40. /**
  41. * @var string Define file name manually.
  42. */
  43. public $setFileName = '';
  44. /**
  45. * @var bool Need auto rename the file?
  46. */
  47. public $autoRename = false;
  48. /**
  49. * @var bool Remove any space in file name.
  50. */
  51. public $stripSpaces = true;
  52. /**
  53. * @var int Define maximum file size.
  54. */
  55. public $maximumSize = 0;
  56. /**
  57. * @var bool Create subdirectory automaticly. The format is "destination_folder/year/month".
  58. */
  59. public $autoCreateFolder = false;
  60. /**
  61. * @var array Collect the file information: name, extension, path etc...
  62. */
  63. public $getFileInfo = array();
  64. /**
  65. * @var string Any files that are allowed.
  66. */
  67. public $permittedFileType = '';
  68. /**
  69. * @var object Instance for Image modifier class (Library_image).
  70. */
  71. public $image;
  72. /**
  73. * @var string Option to edit image base on Library_image class. The option is resize | crop | resize_crop
  74. */
  75. public $editImage = array();
  76. /**
  77. * Class constructor.
  78. */
  79. public function __construct()
  80. {
  81. $this->initErrorMessages();
  82. }
  83. /**
  84. * Setter for option.
  85. *
  86. * @param string | array $var
  87. * @param mix $value
  88. */
  89. public function setOption($var, $value = false)
  90. {
  91. if (is_string($var)) {
  92. $this->$var = $value;
  93. }
  94. if (is_array($var)) {
  95. foreach ($var as $key => $value) {
  96. $this->$key = $value;
  97. }
  98. }
  99. return $this;
  100. }
  101. /**
  102. * Do the Processing upload.
  103. *
  104. * @param array $_FILES variable
  105. *
  106. * @return bool
  107. */
  108. public function now($file)
  109. {
  110. $this->file = $file;
  111. $this->errorHandler();
  112. if (!empty($this->error)) {
  113. return false;
  114. }
  115. if (!$this->upload()) {
  116. return false;
  117. }
  118. if (!empty($this->editImage)) {
  119. foreach ($this->editImage as $editImage) {
  120. // Initiate Image class
  121. $this->image = new Image();
  122. // See Image class line 65
  123. $this->image->folder = $this->folderLocation;
  124. // Assign each config for Image class
  125. foreach ($editImage as $key => $val) {
  126. $this->image->$key = $val;
  127. }
  128. if (!$this->image->edit($this->getFileInfo['name'])) {
  129. $this->_setErrorMessage(14);
  130. return false;
  131. }
  132. }
  133. }
  134. return true;
  135. }
  136. /**
  137. * List of error messages.
  138. */
  139. private function initErrorMessages()
  140. {
  141. $this->errorMessages = array(
  142. 1 => 'File upload failed due to unknown error.',
  143. 2 => 'No folder located. Please define the folder location.',
  144. 3 => 'The uploaded file exceeds the upload_max_filesize directive in php.ini.',
  145. 4 => 'The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form.',
  146. 5 => 'The uploaded file was only partially uploaded.',
  147. 6 => 'No file was uploaded.',
  148. 7 => 'Missing a temporary folder.',
  149. 8 => 'Failed to write file to disk.',
  150. 9 => 'File upload stopped by extension.',
  151. 10 => 'Folder you\'ve defined does not exist.',
  152. 11 => 'Can\'t create new folder in your defined folder.',
  153. 12 => 'Uploaded file not permitted.',
  154. 13 => 'The uploaded file exceeds the maximum size.',
  155. 14 => 'File uploaded, but editing image has failed with the following error(s): ',
  156. 15 => 'Folder you specified not writeable.',
  157. );
  158. }
  159. /**
  160. * Set the error mesage.
  161. *
  162. * @param int
  163. */
  164. private function _setErrorMessage($code)
  165. {
  166. $image_error = ($code == 14 && isset($this->image->errorMessages)) ? implode(', ', $this->image->errorMessages) : null;
  167. $handler = new \stdClass();
  168. $handler->code = $code;
  169. $handler->message = $this->errorMessages[$code].$image_error;
  170. $this->error = $handler;
  171. }
  172. /**
  173. * Error checker before uploading proceed.
  174. */
  175. private function errorHandler()
  176. {
  177. /*
  178. * Check is folder destionation has set.
  179. */
  180. if (empty($this->folderLocation)) {
  181. $this->_setErrorMessage(2);
  182. return false;
  183. }
  184. /*
  185. * Does it folder exist?
  186. */
  187. if (!is_dir($this->folderLocation)) {
  188. // Create a folder if not exits
  189. $arr = explode('/', $this->folderLocation);
  190. $path = '';
  191. if (substr($this->folderLocation, 0, 1) == '/') {
  192. $path = '/';
  193. }
  194. foreach ($arr as $name) {
  195. if (empty($name)) {
  196. continue;
  197. }
  198. $path .= $name.'/';
  199. if (!is_dir($path)) {
  200. if (!mkdir($path, 0777)) {
  201. $this->_setErrorMessage(11);
  202. //$this->_setErrorMessage(10);
  203. return false;
  204. }
  205. }
  206. }
  207. }
  208. /*
  209. * Does it folder writable?
  210. */
  211. if (!is_writable($this->folderLocation)) {
  212. $this->_setErrorMessage(15);
  213. return false;
  214. }
  215. /*
  216. * Make sure the file size not more then user defined.
  217. */
  218. if ($this->maximumSize > 0 && $this->file['size'] > $this->maximumSize) {
  219. $this->_setErrorMessage(13);
  220. return false;
  221. }
  222. /*
  223. * Checking error in uploading proccess.
  224. */
  225. if ($this->file['error']) {
  226. switch ($this->file['error']) {
  227. case UPLOAD_ERR_INI_SIZE:
  228. $this->_setErrorMessage(3);
  229. return false;
  230. case UPLOAD_ERR_FORM_SIZE:
  231. $this->_setErrorMessage(4);
  232. return false;
  233. case UPLOAD_ERR_PARTIAL:
  234. $this->_setErrorMessage(5);
  235. return false;
  236. case UPLOAD_ERR_NO_FILE:
  237. $this->_setErrorMessage(6);
  238. return false;
  239. case UPLOAD_ERR_NO_TMP_DIR:
  240. $this->_setErrorMessage(7);
  241. return false;
  242. case UPLOAD_ERR_CANT_WRITE:
  243. $this->_setErrorMessage(8);
  244. return false;
  245. case UPLOAD_ERR_EXTENSION:
  246. $this->_setErrorMessage(9);
  247. return false;
  248. default:
  249. $this->_setErrorMessage(1);
  250. }
  251. }
  252. /*
  253. * Make sure this file are permitted.
  254. */
  255. if (!empty($this->permittedFileType)) {
  256. if (!preg_match('!\.('.$this->permittedFileType.')$!i', $this->file['name'])) {
  257. $this->_setErrorMessage(12);
  258. return false;
  259. }
  260. }
  261. }
  262. public static function getFileExtension($file)
  263. {
  264. $ext = explode('.', $file);
  265. return end($ext);
  266. }
  267. /**
  268. * Do uploading.
  269. * ID: Lakukan ungguh.
  270. */
  271. private function upload()
  272. {
  273. $fileExtension = self::getFileExtension($this->file['name']);
  274. if ($this->autoRename) {
  275. $name = time().rand().'.'.$fileExtension;
  276. } elseif (!empty($this->setFileName)) {
  277. $name = $this->setFileName.'.'.$fileExtension;
  278. } else {
  279. $name = $this->file['name'];
  280. }
  281. // Remove space in file name.
  282. if ($this->stripSpaces) {
  283. $name = str_replace(' ', '_', $name);
  284. }
  285. // Save file extension.
  286. $this->getFileInfo['extension'] = $fileExtension;
  287. // Save file name.
  288. $this->getFileInfo['name'] = $name;
  289. // Save folder location.
  290. $this->getFileInfo['folder'] = $this->folderLocation;
  291. // Save mime type.
  292. $mime = self::getMimeTypes($name);
  293. $this->getFileInfo['mime'] = $mime['type'];
  294. // Save file size.
  295. $this->getFileInfo['size'] = $this->file['size'];
  296. $file_path = $this->folderLocation.'/'.$name;
  297. if (move_uploaded_file($this->file['tmp_name'], $file_path)) {
  298. return true;
  299. } else {
  300. $this->_setErrorMessage(1);
  301. return false;
  302. }
  303. }
  304. /**
  305. * Define file mime type. Original from Wordpress 3.0 get_allowed_mime_types() function in wp-includes/functions.php.
  306. *
  307. * @param string
  308. *
  309. * @return bool|array
  310. */
  311. public static function getMimeTypes($file_name = '')
  312. {
  313. if (empty($file_name)) {
  314. return false;
  315. }
  316. $mimes = array(
  317. 'jpg|jpeg|jpe' => 'image/jpeg',
  318. 'gif' => 'image/gif',
  319. 'png' => 'image/png',
  320. 'bmp' => 'image/bmp',
  321. 'tif|tiff' => 'image/tiff',
  322. 'ico' => 'image/x-icon',
  323. 'asf|asx|wax|wmv|wmx' => 'video/asf',
  324. 'avi' => 'video/avi',
  325. 'divx' => 'video/divx',
  326. 'flv' => 'video/x-flv',
  327. 'mov|qt' => 'video/quicktime',
  328. 'mpeg|mpg|mpe' => 'video/mpeg',
  329. 'txt|asc|c|cc|h' => 'text/plain',
  330. 'csv' => 'text/csv',
  331. 'tsv' => 'text/tab-separated-values',
  332. 'rtx' => 'text/richtext',
  333. 'css' => 'text/css',
  334. 'htm|html' => 'text/html',
  335. 'mp3|m4a|m4b' => 'audio/mpeg',
  336. 'mp4|m4v' => 'video/mp4',
  337. 'ra|ram' => 'audio/x-realaudio',
  338. 'wav' => 'audio/wav',
  339. 'ogg|oga' => 'audio/ogg',
  340. 'ogv' => 'video/ogg',
  341. 'mid|midi' => 'audio/midi',
  342. 'wma' => 'audio/wma',
  343. 'mka' => 'audio/x-matroska',
  344. 'mkv' => 'video/x-matroska',
  345. 'rtf' => 'application/rtf',
  346. 'js' => 'application/javascript',
  347. 'pdf' => 'application/pdf',
  348. 'doc|docx' => 'application/msword',
  349. 'pot|pps|ppt|pptx|ppam|pptm|sldm|ppsm|potm' => 'application/vnd.ms-powerpoint',
  350. 'wri' => 'application/vnd.ms-write',
  351. 'xla|xls|xlsx|xlt|xlw|xlam|xlsb|xlsm|xltm' => 'application/vnd.ms-excel',
  352. 'mdb' => 'application/vnd.ms-access',
  353. 'mpp' => 'application/vnd.ms-project',
  354. 'docm|dotm' => 'application/vnd.ms-word',
  355. 'pptx|sldx|ppsx|potx' => 'application/vnd.openxmlformats-officedocument.presentationml',
  356. 'xlsx|xltx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml',
  357. 'docx|dotx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml',
  358. 'onetoc|onetoc2|onetmp|onepkg' => 'application/onenote',
  359. 'swf' => 'application/x-shockwave-flash',
  360. 'class' => 'application/java',
  361. 'tar' => 'application/x-tar',
  362. 'zip' => 'application/zip',
  363. 'gz|gzip' => 'application/x-gzip',
  364. 'exe' => 'application/x-msdownload',
  365. // openoffice formats
  366. 'odt' => 'application/vnd.oasis.opendocument.text',
  367. 'odp' => 'application/vnd.oasis.opendocument.presentation',
  368. 'ods' => 'application/vnd.oasis.opendocument.spreadsheet',
  369. 'odg' => 'application/vnd.oasis.opendocument.graphics',
  370. 'odc' => 'application/vnd.oasis.opendocument.chart',
  371. 'odb' => 'application/vnd.oasis.opendocument.database',
  372. 'odf' => 'application/vnd.oasis.opendocument.formula',
  373. // wordperfect formats
  374. 'wp|wpd' => 'application/wordperfect',
  375. // php formats
  376. 'php|php4|php3|phtml' => 'application/x-httpd-php',
  377. 'phps' => 'application/x-httpd-php-source',
  378. );
  379. foreach ($mimes as $ext_preg => $mime_match) {
  380. $ext_preg = '!\.('.$ext_preg.')$!i';
  381. if (preg_match($ext_preg, $file_name, $ext_matches)) {
  382. $file['type'] = $mime_match;
  383. $file['ext'] = $ext_matches[1];
  384. break;
  385. }
  386. }
  387. return $file;
  388. }
  389. /**
  390. * Getter for getFileInfo property.
  391. *
  392. * @return array
  393. */
  394. public function getFileInfo()
  395. {
  396. return $this->getFileInfo;
  397. }
  398. /**
  399. * Getter for error property.
  400. *
  401. * @return mix
  402. */
  403. public function getError($property = false)
  404. {
  405. if (!$property) {
  406. return $this->error;
  407. }
  408. return $this->error->$property;
  409. }
  410. /**
  411. * Setter for error message.
  412. *
  413. * @param array $messages
  414. *
  415. * @return object
  416. */
  417. public function setErrorMessage($messages = array())
  418. {
  419. $this->errorMessages = array_replace($this->errorMessages, $messages);
  420. return $this;
  421. }
  422. } //End Upload Class