PageRenderTime 39ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/src/administrator/components/com_jnewsletter/classes/lib.upload.php

http://kak.googlecode.com/
PHP | 360 lines | 315 code | 43 blank | 2 comment | 63 complexity | 9a0901d43003d2c04aa5e897cc8ea6b9 MD5 | raw file
Possible License(s): LGPL-2.1, Apache-2.0, BSD-3-Clause
  1. <?php
  2. defined('_JEXEC') OR die('Access Denied!');
  3. ### Copyright (C) 2006-2010 Joobi Limited. All rights reserved.
  4. ### License: GNU/GPL version 2 http://www.gnu.org/licenses/gpl-2.0.html
  5. define('UPLOAD_DEFAULT_CHMOD', 0644);
  6. class upload
  7. {
  8. var $files = array();
  9. var $_chmod = UPLOAD_DEFAULT_CHMOD;
  10. function upload()
  11. {
  12. $ini_size = preg_replace('/m/i', '000000', ini_get('upload_max_filesize'));
  13. if (function_exists('version_compare') &&
  14. version_compare(phpversion(), '4.1', 'ge'))
  15. {
  16. $this->post_files = $_FILES;
  17. $maxsize = (isset($_POST['MAX_FILE_SIZE'])) ?
  18. $_POST['MAX_FILE_SIZE'] : null;
  19. if (isset($_SERVER['CONTENT_TYPE'])) {
  20. $this->content_type = $_SERVER['CONTENT_TYPE'];
  21. }
  22. } else {
  23. global $POST_FILES, $SERVER_VARS;
  24. $this->post_files = $POST_FILES;
  25. $maxsize = (isset($POST_VARS['MAX_FILE_SIZE'])) ?
  26. $POST_VARS['MAX_FILE_SIZE'] : null;
  27. if (isset($SERVER_VARS['CONTENT_TYPE'])) {
  28. $this->content_type = $SERVER_VARS['CONTENT_TYPE'];
  29. }
  30. }
  31. if (empty($maxsize) || ($maxsize > $ini_size)) $maxsize = $ini_size;
  32. }
  33. function &getFiles($file = null)
  34. {
  35. static $is_built = false;
  36. if (!$is_built) {
  37. $files = &$this->_buildFiles();
  38. if (!$files) {
  39. $this->files['_error'] = &new Upload_File(
  40. '_error', null,
  41. null, null,
  42. null, 'error creating fake file',
  43. $this->_chmod);
  44. } else {
  45. $this->files = $files;
  46. }
  47. $is_built = true;
  48. }
  49. if ($file !== null) {
  50. if (is_int($file)) {
  51. $pos = 0;
  52. foreach ($this->files as $obj) {
  53. if ($pos == $file) {
  54. return $obj;
  55. }
  56. $pos++;
  57. }
  58. } elseif (is_string($file) && isset($this->files[$file])) {
  59. return $this->files[$file];
  60. }
  61. }
  62. return $this->files;
  63. }
  64. function &_buildFiles() {
  65. if (function_exists('version_compare') &&
  66. version_compare(phpversion(), '4.2.0', 'ge')) {
  67. $uploadError = array(
  68. 1 => _JNEWS_TOO_LARGE,
  69. 2 => _JNEWS_TOO_LARGE,
  70. 3 => _JNEWS_PARTIAL,
  71. 4 => _JNEWS_NO_USER_FILE
  72. );
  73. }
  74. $files = array();
  75. foreach ($this->post_files as $userfile => $value) {
  76. if (is_array($value['name'])) {
  77. foreach ($value['name'] as $key => $val) {
  78. $err = $value['error'][$key];
  79. if (isset($err) && $err !== 0 && isset($uploadError[$err])) {
  80. $error = $uploadError[$err];
  81. } else {
  82. $error = null;
  83. }
  84. $name = basename($value['name'][$key]);
  85. $tmp_name = $value['tmp_name'][$key];
  86. $size = $value['size'][$key];
  87. $type = $value['type'][$key];
  88. $formname = $userfile . "[$key]";
  89. $files[$formname] = new Upload_File($name, $tmp_name,
  90. $formname, $type, $size, $error, $this->_chmod);
  91. }
  92. } else {
  93. $err = $value['error'];
  94. if (isset($err) && $err !== 0 && isset($uploadError[$err])) {
  95. $error = $uploadError[$err];
  96. } else {
  97. $error = null;
  98. }
  99. $name = basename($value['name']);
  100. $tmp_name = $value['tmp_name'];
  101. $size = $value['size'];
  102. $type = $value['type'];
  103. $formname = $userfile;
  104. $files[$formname] = new Upload_File($name, $tmp_name,
  105. $formname, $type, $size, $error, $this->_chmod);
  106. }
  107. }
  108. return $files;
  109. }
  110. function isMissing() {
  111. if (count($this->post_files) < 1) {
  112. return jnewsletter::printM('error' , _JNEWS_NO_USER_FILE);
  113. }
  114. $files = array();
  115. $size = 0;
  116. foreach ($this->post_files as $userfile => $value) {
  117. if (is_array($value['name'])) {
  118. foreach ($value['name'] as $key => $val) {
  119. $size += $value['size'][$key];
  120. }
  121. } else {
  122. $size = $value['size'];
  123. }
  124. }
  125. if ($size == 0) {
  126. jnewsletter::printM('error' ,_JNEWS_NO_USER_FILE);
  127. }
  128. return false;
  129. }
  130. function setChmod($mode)
  131. {
  132. $this->_chmod = $mode;
  133. }
  134. }
  135. class Upload_File
  136. {
  137. var $upload = array();
  138. var $mode_name_selected = false;
  139. var $_extensions_check = array('php', 'phtm', 'phtml', 'php3', 'inc', 'exe', 'dmg');
  140. var $_extensions_mode = 'deny';
  141. var $_chmod = UPLOAD_DEFAULT_CHMOD;
  142. function Upload_File($name = null, $tmp = null, $formname = null,
  143. $type = null, $size = null, $error = null,
  144. $chmod = UPLOAD_DEFAULT_CHMOD)
  145. {
  146. $ext = null;
  147. if (empty($name) || $size == 0) {
  148. $error = _JNEWS_NO_USER_FILE;
  149. } elseif ($tmp == 'none') {
  150. $error = _JNEWS_TOO_LARGE;
  151. } else {
  152. if (($pos = strrpos($name, '.')) !== false) {
  153. $ext = substr($name, $pos + 1);
  154. }
  155. }
  156. if (function_exists('version_compare') &&
  157. version_compare(phpversion(), '4.1', 'ge')) {
  158. if (isset($_POST['MAX_FILE_SIZE']) &&
  159. $size > $_POST['MAX_FILE_SIZE']) {
  160. $error = _JNEWS_TOO_LARGE;
  161. }
  162. } else {
  163. global $POST_VARS;
  164. if (isset($POST_VARS['MAX_FILE_SIZE']) &&
  165. $size > $POST_VARS['MAX_FILE_SIZE']) {
  166. $error = _JNEWS_TOO_LARGE;
  167. }
  168. }
  169. $this->upload = array(
  170. 'real' => $name,
  171. 'name' => $name,
  172. 'form_name' => $formname,
  173. 'ext' => $ext,
  174. 'tmp_name' => $tmp,
  175. 'size' => $size,
  176. 'type' => $type,
  177. 'error' => $error
  178. );
  179. $this->_chmod = $chmod;
  180. }
  181. function setName($mode, $prepend = null, $append = null)
  182. {
  183. switch ($mode) {
  184. case 'uniq':
  185. $name = $this->nameToUniq($this->upload['real']);
  186. $this->upload['ext'] = $this->nameToSafe($this->upload['ext'], 40);
  187. $name .= '.' . $this->upload['ext'];
  188. break;
  189. case 'safe':
  190. $name = $this->nameToSafe($this->upload['real']);
  191. if (($pos = strrpos($name, '.')) !== false) {
  192. $this->upload['ext'] = substr($name, $pos + 1);
  193. } else {
  194. $this->upload['ext'] = '';
  195. }
  196. break;
  197. case 'real':
  198. $name = $this->upload['real'];
  199. break;
  200. default:
  201. $name = $mode;
  202. }
  203. $this->upload['name'] = $prepend . $name . $append;
  204. $this->mode_name_selected = true;
  205. return $this->upload['name'];
  206. }
  207. function nameToUniq($name)
  208. {
  209. return md5(uniqid( substr(trim('com_jnewsletter'.$name)),0,80 ,time()));
  210. }
  211. function nameToSafe($name, $maxlen=250)
  212. {
  213. $noalpha = 'ÁÉÍÓÚÝáéíóúýÂĘÎÔŰâęîôűŔČĚŇŮŕčěňůÄËĎÖÜäëďöü˙ĂăŐőĹĺŃńÇç@°şŞ';
  214. $alpha = 'AEIOUYaeiouyAEIOUaeiouAEIOUaeiouAEIOUaeiouyAaOoAaNnCcaooa';
  215. $name = substr($name, 0, $maxlen);
  216. $name = strtr($name, $noalpha, $alpha);
  217. return preg_replace('/[^a-zA-Z0-9,._\+\()\-]/', '_', $name);
  218. }
  219. function isValid()
  220. {
  221. if ($this->upload['error'] === null) {
  222. return true;
  223. }
  224. return false;
  225. }
  226. function isMissing()
  227. {
  228. if ($this->upload['error'] == _JNEWS_NO_USER_FILE) {
  229. return true;
  230. }
  231. return false;
  232. }
  233. function isError()
  234. {
  235. if (in_array($this->upload['error'], array(_JNEWS_TOO_LARGE))) {
  236. return true;
  237. }
  238. return false;
  239. }
  240. function moveTo($dir_dest, $overwrite = true)
  241. {
  242. if (!$this->isValid()) {
  243. return jnewsletter::printM('error' ,$this->upload['error']);
  244. }
  245. if (!$this->_evalValidExtensions()) {
  246. return jnewsletter::printM('error' ,_JNEWS_NOT_ALLOWED_EXTENSION);
  247. }
  248. $err_code = $this->_chk_dir_dest($dir_dest);
  249. if ($err_code !== false) {
  250. return jnewsletter::printM('error' ,$err_code);
  251. }
  252. if (!$this->mode_name_selected) {
  253. $this->setName('safe');
  254. }
  255. $name_dest = $dir_dest . DIRECTORY_SEPARATOR . $this->upload['name'];
  256. if (@is_file($name_dest)) {
  257. if ($overwrite !== true) {
  258. return jnewsletter::printM('error' ,_JNEWS_FILE_EXISTS);
  259. } elseif (!is_writable($name_dest)) {
  260. return jnewsletter::printM('error' ,_JNEWS_CANNOT_OVERWRITE);
  261. }
  262. }
  263. if (!@move_uploaded_file($this->upload['tmp_name'], $name_dest)) {
  264. return jnewsletter::printM('error' ,_JNEWS_E_FAIL_MOVE);
  265. }
  266. @chmod($name_dest, $this->_chmod);
  267. return $this->getProp('name');
  268. }
  269. function _chk_dir_dest($dir_dest)
  270. {
  271. if (!$dir_dest) {
  272. return _JNEWS_MISSING_DIR;
  273. }
  274. if (!@is_dir($dir_dest)) {
  275. return _JNEWS_IS_NOT_DIR;
  276. }
  277. if (!is_writeable($dir_dest)) {
  278. return _JNEWS_NO_WRITE_PERMS;
  279. }
  280. return false;
  281. }
  282. function getProp($name = null)
  283. {
  284. if ($name === null) {
  285. return $this->upload;
  286. }
  287. return $this->upload[$name];
  288. }
  289. function errorMsg()
  290. {
  291. return $this->errorCode($this->upload['error']);
  292. }
  293. function getMessage()
  294. {
  295. return $this->errorCode($this->upload['error']);
  296. }
  297. function setValidExtensions($exts, $mode = 'deny')
  298. {
  299. $this->_extensions_check = $exts;
  300. $this->_extensions_mode = $mode;
  301. }
  302. function _evalValidExtensions()
  303. {
  304. $exts = $this->_extensions_check;
  305. settype($exts, 'array');
  306. if ($this->_extensions_mode == 'deny') {
  307. if (in_array($this->getProp('ext'), $exts)) {
  308. return false;
  309. }
  310. } else {
  311. if (!in_array($this->getProp('ext'), $exts)) {
  312. return false;
  313. }
  314. }
  315. return true;
  316. }
  317. }