PageRenderTime 50ms CodeModel.GetById 22ms RepoModel.GetById 1ms app.codeStats 0ms

/classes/Uploader.php

https://gitlab.com/ivandevp/petshop
PHP | 299 lines | 226 code | 47 blank | 26 comment | 33 complexity | 3f99dab1daf48c683f14bbdfb21454af MD5 | raw file
  1. <?php
  2. /*
  3. * 2007-2016 PrestaShop
  4. *
  5. * NOTICE OF LICENSE
  6. *
  7. * This source file is subject to the Open Software License (OSL 3.0)
  8. * that is bundled with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://opensource.org/licenses/osl-3.0.php
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@prestashop.com so we can send you a copy immediately.
  14. *
  15. * DISCLAIMER
  16. *
  17. * Do not edit or add to this file if you wish to upgrade PrestaShop to newer
  18. * versions in the future. If you wish to customize PrestaShop for your
  19. * needs please refer to http://www.prestashop.com for more information.
  20. *
  21. * @author PrestaShop SA <contact@prestashop.com>
  22. * @copyright 2007-2016 PrestaShop SA
  23. * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
  24. * International Registered Trademark & Property of PrestaShop SA
  25. */
  26. class UploaderCore
  27. {
  28. const DEFAULT_MAX_SIZE = 10485760;
  29. private $_check_file_size;
  30. private $_accept_types;
  31. private $_files;
  32. private $_max_size;
  33. private $_name;
  34. private $_save_path;
  35. public function __construct($name = null)
  36. {
  37. $this->setName($name);
  38. $this->setCheckFileSize(true);
  39. $this->files = array();
  40. }
  41. public function setAcceptTypes($value)
  42. {
  43. if (is_array($value) && count($value)) {
  44. $value = array_map(array('Tools', 'strtolower'), $value);
  45. }
  46. $this->_accept_types = $value;
  47. return $this;
  48. }
  49. public function getAcceptTypes()
  50. {
  51. return $this->_accept_types;
  52. }
  53. public function setCheckFileSize($value)
  54. {
  55. $this->_check_file_size = $value;
  56. return $this;
  57. }
  58. public function getFilePath($file_name = null)
  59. {
  60. if (!isset($file_name)) {
  61. return tempnam($this->getSavePath(), $this->getUniqueFileName());
  62. }
  63. return $this->getSavePath().$file_name;
  64. }
  65. public function getFiles()
  66. {
  67. if (!isset($this->_files)) {
  68. $this->_files = array();
  69. }
  70. return $this->_files;
  71. }
  72. public function setMaxSize($value)
  73. {
  74. $this->_max_size = intval($value);
  75. return $this;
  76. }
  77. public function getMaxSize()
  78. {
  79. if (!isset($this->_max_size) || empty($this->_max_size)) {
  80. $this->setMaxSize(self::DEFAULT_MAX_SIZE);
  81. }
  82. return $this->_max_size;
  83. }
  84. public function setName($value)
  85. {
  86. $this->_name = $value;
  87. return $this;
  88. }
  89. public function getName()
  90. {
  91. return $this->_name;
  92. }
  93. public function setSavePath($value)
  94. {
  95. $this->_save_path = $value;
  96. return $this;
  97. }
  98. public function getPostMaxSizeBytes()
  99. {
  100. $post_max_size = ini_get('post_max_size');
  101. $bytes = trim($post_max_size);
  102. $last = strtolower($post_max_size[strlen($post_max_size) - 1]);
  103. switch ($last) {
  104. case 'g': $bytes *= 1024;
  105. case 'm': $bytes *= 1024;
  106. case 'k': $bytes *= 1024;
  107. }
  108. if ($bytes == '') {
  109. $bytes = null;
  110. }
  111. return $bytes;
  112. }
  113. public function getSavePath()
  114. {
  115. if (!isset($this->_save_path)) {
  116. $this->setSavePath(_PS_UPLOAD_DIR_);
  117. }
  118. return $this->_normalizeDirectory($this->_save_path);
  119. }
  120. public function getUniqueFileName($prefix = 'PS')
  121. {
  122. return uniqid($prefix, true);
  123. }
  124. public function checkFileSize()
  125. {
  126. return (isset($this->_check_file_size) && $this->_check_file_size);
  127. }
  128. public function process($dest = null)
  129. {
  130. $upload = isset($_FILES[$this->getName()]) ? $_FILES[$this->getName()] : null;
  131. if ($upload && is_array($upload['tmp_name'])) {
  132. $tmp = array();
  133. foreach ($upload['tmp_name'] as $index => $value) {
  134. $tmp[$index] = array(
  135. 'tmp_name' => $upload['tmp_name'][$index],
  136. 'name' => $upload['name'][$index],
  137. 'size' => $upload['size'][$index],
  138. 'type' => $upload['type'][$index],
  139. 'error' => $upload['error'][$index]
  140. );
  141. $this->files[] = $this->upload($tmp[$index], $dest);
  142. }
  143. } elseif ($upload) {
  144. $this->files[] = $this->upload($upload, $dest);
  145. }
  146. return $this->files;
  147. }
  148. public function upload($file, $dest = null)
  149. {
  150. if ($this->validate($file)) {
  151. if (isset($dest) && is_dir($dest)) {
  152. $file_path = $dest;
  153. } else {
  154. $file_path = $this->getFilePath(isset($dest) ? $dest : $file['name']);
  155. }
  156. if ($file['tmp_name'] && is_uploaded_file($file['tmp_name'])) {
  157. move_uploaded_file($file['tmp_name'], $file_path);
  158. } else {
  159. // Non-multipart uploads (PUT method support)
  160. file_put_contents($file_path, fopen('php://input', 'r'));
  161. }
  162. $file_size = $this->_getFileSize($file_path, true);
  163. if ($file_size === $file['size']) {
  164. $file['save_path'] = $file_path;
  165. } else {
  166. $file['size'] = $file_size;
  167. unlink($file_path);
  168. $file['error'] = Tools::displayError('Server file size is different from local file size');
  169. }
  170. }
  171. return $file;
  172. }
  173. protected function checkUploadError($error_code)
  174. {
  175. $error = 0;
  176. switch ($error_code) {
  177. case 1:
  178. $error = sprintf(Tools::displayError('The uploaded file exceeds %s'), ini_get('upload_max_filesize'));
  179. break;
  180. case 2:
  181. $error = sprintf(Tools::displayError('The uploaded file exceeds %s'), ini_get('post_max_size'));
  182. break;
  183. case 3:
  184. $error = Tools::displayError('The uploaded file was only partially uploaded');
  185. break;
  186. case 4:
  187. $error = Tools::displayError('No file was uploaded');
  188. break;
  189. case 6:
  190. $error = Tools::displayError('Missing temporary folder');
  191. break;
  192. case 7:
  193. $error = Tools::displayError('Failed to write file to disk');
  194. break;
  195. case 8:
  196. $error = Tools::displayError('A PHP extension stopped the file upload');
  197. break;
  198. default:
  199. break;
  200. }
  201. return $error;
  202. }
  203. protected function validate(&$file)
  204. {
  205. $file['error'] = $this->checkUploadError($file['error']);
  206. if ($file['error']) {
  207. return false;
  208. }
  209. $post_max_size = $this->getPostMaxSizeBytes();
  210. if ($post_max_size && ($this->_getServerVars('CONTENT_LENGTH') > $post_max_size)) {
  211. $file['error'] = Tools::displayError('The uploaded file exceeds the post_max_size directive in php.ini');
  212. return false;
  213. }
  214. if (preg_match('/\%00/', $file['name'])) {
  215. $file['error'] = Tools::displayError('Invalid file name');
  216. return false;
  217. }
  218. $types = $this->getAcceptTypes();
  219. //TODO check mime type.
  220. if (isset($types) && !in_array(Tools::strtolower(pathinfo($file['name'], PATHINFO_EXTENSION)), $types)) {
  221. $file['error'] = Tools::displayError('Filetype not allowed');
  222. return false;
  223. }
  224. if ($this->checkFileSize() && $file['size'] > $this->getMaxSize()) {
  225. $file['error'] = sprintf(Tools::displayError('File (size : %1s) is too big (max : %2s)'), $file['size'], $this->getMaxSize());
  226. return false;
  227. }
  228. return true;
  229. }
  230. protected function _getFileSize($file_path, $clear_stat_cache = false)
  231. {
  232. if ($clear_stat_cache) {
  233. clearstatcache(true, $file_path);
  234. }
  235. return filesize($file_path);
  236. }
  237. protected function _getServerVars($var)
  238. {
  239. return (isset($_SERVER[$var]) ? $_SERVER[$var] : '');
  240. }
  241. protected function _normalizeDirectory($directory)
  242. {
  243. $last = $directory[strlen($directory) - 1];
  244. if (in_array($last, array('/', '\\'))) {
  245. $directory[strlen($directory) - 1] = DIRECTORY_SEPARATOR;
  246. return $directory;
  247. }
  248. $directory .= DIRECTORY_SEPARATOR;
  249. return $directory;
  250. }
  251. }