PageRenderTime 54ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/VisitorChat/admin/program/upload.php

https://bitbucket.org/cgcamilo/multiflora
PHP | 162 lines | 124 code | 18 blank | 20 comment | 13 complexity | 276e3917c6eac4cd400199cd6138d66b MD5 | raw file
  1. <?php
  2. /**
  3. * Handle file uploads via XMLHttpRequest
  4. */
  5. class qqUploadedFileXhr {
  6. /**
  7. * Save the file to the specified path
  8. * @return boolean TRUE on success
  9. */
  10. function save($path) {
  11. $input = fopen("php://input", "r");
  12. $temp = tmpfile();
  13. $realSize = stream_copy_to_stream($input, $temp);
  14. fclose($input);
  15. if ($realSize != $this->getSize()){
  16. return false;
  17. }
  18. $target = fopen($path, "w");
  19. fseek($temp, 0, SEEK_SET);
  20. stream_copy_to_stream($temp, $target);
  21. fclose($target);
  22. return true;
  23. }
  24. function getName() {
  25. return $_GET['qqfile'];
  26. }
  27. function getSize() {
  28. if (isset($_SERVER["CONTENT_LENGTH"])){
  29. return (int)$_SERVER["CONTENT_LENGTH"];
  30. } else {
  31. throw new Exception('Getting content length is not supported.');
  32. }
  33. }
  34. }
  35. /**
  36. * Handle file uploads via regular form post (uses the $_FILES array)
  37. */
  38. class qqUploadedFileForm {
  39. /**
  40. * Save the file to the specified path
  41. * @return boolean TRUE on success
  42. */
  43. function save($path) {
  44. if(!move_uploaded_file($_FILES['qqfile']['tmp_name'], $path)){
  45. return false;
  46. }
  47. return true;
  48. }
  49. function getName() {
  50. return $_FILES['qqfile']['name'];
  51. }
  52. function getSize() {
  53. return $_FILES['qqfile']['size'];
  54. }
  55. }
  56. class qqFileUploader {
  57. private $allowedExtensions = array();
  58. private $sizeLimit = 2097150;
  59. private $file;
  60. function __construct(array $allowedExtensions = array(), $sizeLimit = 2097150){
  61. $allowedExtensions = array_map("strtolower", $allowedExtensions);
  62. $this->allowedExtensions = $allowedExtensions;
  63. $this->sizeLimit = $sizeLimit;
  64. $this->checkServerSettings();
  65. if (isset($_GET['qqfile'])) {
  66. $this->file = new qqUploadedFileXhr();
  67. } elseif (isset($_FILES['qqfile'])) {
  68. $this->file = new qqUploadedFileForm();
  69. } else {
  70. $this->file = false;
  71. }
  72. }
  73. private function checkServerSettings(){
  74. $postSize = $this->toBytes(ini_get('post_max_size'));
  75. $uploadSize = $this->toBytes(ini_get('upload_max_filesize'));
  76. if ($postSize < $this->sizeLimit || $uploadSize < $this->sizeLimit){
  77. $size = max(1, $this->sizeLimit / 1024 / 1024) . 'M';
  78. die("{'error':'increase post_max_size and upload_max_filesize to $size'}");
  79. }
  80. }
  81. private function toBytes($str){
  82. $val = trim($str);
  83. $last = strtolower($str[strlen($str)-1]);
  84. switch($last) {
  85. case 'g': $val *= 1024;
  86. case 'm': $val *= 1024;
  87. case 'k': $val *= 1024;
  88. }
  89. return $val;
  90. }
  91. /**
  92. * Returns array('success'=>true) or array('error'=>'error message')
  93. */
  94. function handleUpload($uploadDirectory, $replaceOldFile = FALSE){
  95. if (!is_writable($uploadDirectory)){
  96. return array('error' => "Server error. Upload directory isn't writable.");
  97. }
  98. if (!$this->file){
  99. return array('error' => 'No files were uploaded.');
  100. }
  101. $size = $this->file->getSize();
  102. if ($size == 0) {
  103. return array('error' => 'File is empty');
  104. }
  105. if ($size > $this->sizeLimit) {
  106. return array('error' => 'File is too large');
  107. }
  108. $pathinfo = pathinfo($this->file->getName());
  109. $filename = $pathinfo['filename'];
  110. $filename = uniqid();
  111. $ext = $pathinfo['extension'];
  112. if($this->allowedExtensions && !in_array(strtolower($ext), $this->allowedExtensions)){
  113. $these = implode(', ', $this->allowedExtensions);
  114. return array('error' => 'File has an invalid extension, it should be one of '. $these . '.');
  115. }
  116. if(!$replaceOldFile){
  117. /// don't overwrite previous files that were uploaded
  118. while (file_exists($uploadDirectory . $filename . '.' . $ext)) {
  119. $filename .= rand(10, 99);
  120. }
  121. }
  122. if ($this->file->save($uploadDirectory . $filename . '.' . $ext)){
  123. return array('success'=>true,'filename'=>$filename.'.'.$ext);
  124. } else {
  125. return array('error'=> 'Could not save uploaded file.' .
  126. 'The upload was cancelled, or server error encountered');
  127. }
  128. }
  129. }
  130. // list of valid extensions, ex. array("jpeg", "xml", "bmp")
  131. $allowedExtensions = $_['ALLOWED_FILE_EXT'];
  132. // max file size in bytes
  133. $sizeLimit = 2 * 1024 * 1024;
  134. $uploader = new qqFileUploader($allowedExtensions, $sizeLimit);
  135. $result = $uploader->handleUpload('../uploads/');
  136. // to pass data through iframe you will need to encode all html tags
  137. echo htmlspecialchars(json_encode($result), ENT_NOQUOTES);