uploadedfile.class.php 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. <?php
  2. /**
  3. * [WeEngine System] Copyright (c) 2014 WE7.CC
  4. * WeEngine is NOT a free software, it under the license terms, visited http://www.we7.cc/ for more details.
  5. */
  6. class UploadedFile extends SplFileInfo {
  7. private static $errors = array(
  8. UPLOAD_ERR_OK,
  9. UPLOAD_ERR_INI_SIZE,
  10. UPLOAD_ERR_FORM_SIZE,
  11. UPLOAD_ERR_PARTIAL,
  12. UPLOAD_ERR_NO_FILE,
  13. UPLOAD_ERR_NO_TMP_DIR,
  14. UPLOAD_ERR_CANT_WRITE,
  15. UPLOAD_ERR_EXTENSION,
  16. );
  17. private $clientFilename;
  18. private $clientMediaType;
  19. private $error;
  20. private $file;
  21. private $moved = false;
  22. private $size;
  23. public function __construct(
  24. $streamOrFile,
  25. $size,
  26. $errorStatus,
  27. $clientFilename = null,
  28. $clientMediaType = null
  29. ) {
  30. $this->setError($errorStatus);
  31. $this->setSize($size);
  32. $this->setClientFilename($clientFilename);
  33. $this->setClientMediaType($clientMediaType);
  34. parent::__construct($streamOrFile);
  35. if ($this->isOk()) {
  36. $this->setStreamOrFile($streamOrFile);
  37. }
  38. }
  39. private function setStreamOrFile($streamOrFile) {
  40. if (is_string($streamOrFile)) {
  41. $this->file = $streamOrFile;
  42. } else {
  43. throw new InvalidArgumentException(
  44. 'Invalid stream or file provided for UploadedFile'
  45. );
  46. }
  47. }
  48. private function setError($error) {
  49. if (false === is_int($error)) {
  50. throw new InvalidArgumentException(
  51. 'Upload file error status must be an integer'
  52. );
  53. }
  54. if (false === in_array($error, self::$errors)) {
  55. throw new InvalidArgumentException(
  56. 'Invalid error status for UploadedFile'
  57. );
  58. }
  59. $this->error = $error;
  60. }
  61. private function setSize($size) {
  62. if (false === is_int($size)) {
  63. throw new InvalidArgumentException(
  64. 'Upload file size must be an integer'
  65. );
  66. }
  67. $this->size = $size;
  68. }
  69. private function isStringOrNull($param) {
  70. return in_array(gettype($param), array('string', 'NULL'));
  71. }
  72. private function isStringNotEmpty($param) {
  73. return is_string($param) && false === empty($param);
  74. }
  75. private function setClientFilename($clientFilename) {
  76. if (false === $this->isStringOrNull($clientFilename)) {
  77. throw new InvalidArgumentException(
  78. 'Upload file client filename must be a string or null'
  79. );
  80. }
  81. $this->clientFilename = $clientFilename;
  82. }
  83. private function setClientMediaType($clientMediaType) {
  84. if (false === $this->isStringOrNull($clientMediaType)) {
  85. throw new InvalidArgumentException(
  86. 'Upload file client media type must be a string or null'
  87. );
  88. }
  89. $this->clientMediaType = $clientMediaType;
  90. }
  91. public function isOk() {
  92. return $this->error === UPLOAD_ERR_OK;
  93. }
  94. public function isMoved() {
  95. return $this->moved;
  96. }
  97. private function validateActive() {
  98. if (false === $this->isOk()) {
  99. throw new RuntimeException('Cannot retrieve stream due to upload error');
  100. }
  101. if ($this->isMoved()) {
  102. throw new RuntimeException('Cannot retrieve stream after it has already been moved');
  103. }
  104. }
  105. public function moveTo($targetPath) {
  106. $this->validateActive();
  107. if (false === $this->isStringNotEmpty($targetPath)) {
  108. throw new InvalidArgumentException(
  109. 'Invalid path provided for move operation; must be a non-empty string'
  110. );
  111. }
  112. if ($this->file) {
  113. $this->moved = php_sapi_name() == 'cli'
  114. ? rename($this->file, $targetPath)
  115. : move_uploaded_file($this->file, $targetPath);
  116. }
  117. if (false === $this->moved) {
  118. throw new RuntimeException(
  119. sprintf('Uploaded file could not be moved to %s', $targetPath)
  120. );
  121. }
  122. }
  123. public function getSize() {
  124. return $this->size;
  125. }
  126. public function getError() {
  127. return $this->error;
  128. }
  129. public function getClientFilename() {
  130. return $this->clientFilename;
  131. }
  132. public function getClientMediaType() {
  133. return $this->clientMediaType;
  134. }
  135. public function isImage() {
  136. return $this->isOk() && in_array($this->clientMediaType, array());
  137. }
  138. public function clientExtension() {
  139. return pathinfo($this->getClientFilename(), PATHINFO_EXTENSION);
  140. }
  141. public function allowExt($ext) {
  142. return $this->clientExtension() === $ext;
  143. }
  144. public function getContent() {
  145. return file_get_contents($this->file);
  146. }
  147. public static function createFromGlobal() {
  148. $files = array();
  149. foreach ($_FILES as $key => $file) {
  150. $createFiles = static::create($file);
  151. $files[$key] = $createFiles;
  152. }
  153. return $files;
  154. }
  155. private static function create($file) {
  156. if (is_array($file['tmp_name'])) {
  157. return static::createArrayFile($file);
  158. }
  159. return static::createUploadedFile($file);
  160. }
  161. public static function createArrayFile($files) {
  162. $data = array();
  163. foreach (array_keys($files['tmp_name']) as $key) {
  164. $file = array(
  165. 'tmp_name' => $files['tmp_name'][$key],
  166. 'size' => $files['size'][$key],
  167. 'error' => $files['error'][$key],
  168. 'name' => $files['name'][$key],
  169. 'type' => $files['type'][$key],
  170. );
  171. $data[$key] = self::createUploadedFile($file);
  172. }
  173. return $data;
  174. }
  175. private static function createUploadedFile($value) {
  176. $upfile = new static(
  177. $value['tmp_name'],
  178. $value['size'],
  179. $value['error'],
  180. $value['name'],
  181. $value['type']
  182. );
  183. return $upfile;
  184. }
  185. }