PageRenderTime 66ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/profiles/opigno_lms/modules/contrib/h5p/modules/h5peditor/h5peditor/h5peditor-file.class.php

https://bitbucket.org/gunnarslette/mme-opigno-demo
PHP | 272 lines | 174 code | 35 blank | 63 comment | 25 complexity | f8bf2f8e0850caab41f8e71f2d4e997c MD5 | raw file
Possible License(s): LGPL-2.1, MPL-2.0-no-copyleft-exception, LGPL-2.0, CC-BY-SA-3.0, BSD-3-Clause, MIT
  1. <?php
  2. /**
  3. * Class
  4. */
  5. class H5peditorFile {
  6. private $result, $field, $interface;
  7. public $type, $name, $path, $mime, $size;
  8. /**
  9. * Constructor. Process data for file uploaded through the editor.
  10. */
  11. function __construct($interface) {
  12. $field = filter_input(INPUT_POST, 'field', FILTER_SANITIZE_STRING, FILTER_FLAG_NO_ENCODE_QUOTES);
  13. // Check for file upload.
  14. if ($field === NULL || empty($_FILES) || !isset($_FILES['file'])) {
  15. return;
  16. }
  17. $this->interface = $interface;
  18. // Create a new result object.
  19. $this->result = new stdClass();
  20. // Get the field.
  21. $this->field = json_decode($field);
  22. // Check if uploaded base64 encoded file
  23. if (isset($_POST) && isset($_POST['dataURI']) && $_POST['dataURI'] !== '') {
  24. $data = $_POST['dataURI'];
  25. // Extract data from string
  26. list($type, $data) = explode(';', $data);
  27. list(, $data) = explode(',', $data);
  28. $this->data = base64_decode($data);
  29. // Extract file type and extension
  30. list(, $type) = explode(':', $type);
  31. list(, $extension) = explode('/', $type);
  32. $this->type = $type;
  33. $this->extension = $extension;
  34. $this->size = strlen($this->data);
  35. }
  36. else {
  37. // Handle temporarily uploaded form file
  38. if (function_exists('finfo_file')) {
  39. $finfo = finfo_open(FILEINFO_MIME_TYPE);
  40. $this->type = finfo_file($finfo, $_FILES['file']['tmp_name']);
  41. finfo_close($finfo);
  42. }
  43. elseif (function_exists('mime_content_type')) {
  44. // Deprecated, only when finfo isn't available.
  45. $this->type = mime_content_type($_FILES['file']['tmp_name']);
  46. }
  47. else {
  48. $this->type = $_FILES['file']['type'];
  49. }
  50. $this->extension = pathinfo($_FILES['file']['name'], PATHINFO_EXTENSION);
  51. $this->size = $_FILES['file']['size'];
  52. }
  53. }
  54. /**
  55. * Indicates if an uploaded file was found or not.
  56. *
  57. * @return boolean
  58. */
  59. public function isLoaded() {
  60. return is_object($this->result);
  61. }
  62. /**
  63. * Check current file up agains mime types and extensions in the given list.
  64. *
  65. * @param array $mimes List to check against.
  66. * @return boolean
  67. */
  68. public function check($mimes) {
  69. $ext = strtolower($this->extension);
  70. foreach ($mimes as $mime => $extension) {
  71. if (is_array($extension)) {
  72. // Multiple extensions
  73. if (in_array($ext, $extension)) {
  74. $this->type = $mime;
  75. return TRUE;
  76. }
  77. }
  78. elseif (/*$this->type === $mime && */$ext === $extension) {
  79. // TODO: Either remove everything that has to do with mime types, or make it work
  80. // Currently we're experiencing trouble with mime types on different servers...
  81. $this->type = $mime;
  82. return TRUE;
  83. }
  84. }
  85. return FALSE;
  86. }
  87. /**
  88. * Validate the file.
  89. *
  90. * @return boolean
  91. */
  92. public function validate() {
  93. if (isset($this->result->error)) {
  94. return FALSE;
  95. }
  96. // Check for field type.
  97. if (!isset($this->field->type)) {
  98. $this->result->error = $this->interface->t('Unable to get field type.');
  99. return FALSE;
  100. }
  101. // Check if mime type is allowed.
  102. if ((isset($this->field->mimes) && !in_array($this->type, $this->field->mimes)) || substr($this->extension, 0, 3) === 'php') {
  103. $this->result->error = $this->interface->t("File type isn't allowed.");
  104. return FALSE;
  105. }
  106. // Type specific validations.
  107. switch ($this->field->type) {
  108. default:
  109. $this->result->error = $this->interface->t('Invalid field type.');
  110. return FALSE;
  111. case 'image':
  112. $allowed = array(
  113. 'image/png' => 'png',
  114. 'image/jpeg' => array('jpg', 'jpeg'),
  115. 'image/gif' => 'gif',
  116. );
  117. if (!$this->check($allowed)) {
  118. $this->result->error = $this->interface->t('Invalid image file format. Use jpg, png or gif.');
  119. return FALSE;
  120. }
  121. // Get image size from base64 string
  122. if (isset($this->data)) {
  123. if (!function_exists('getimagesizefromstring')) {
  124. $uri = 'data://application/octet-stream;base64,' . base64_encode($this->data);
  125. $image = getimagesize($uri);
  126. }
  127. else {
  128. $image = getimagesizefromstring($this->data);
  129. }
  130. }
  131. else {
  132. // Image size from temp file
  133. $image = @getimagesize($_FILES['file']['tmp_name']);
  134. }
  135. if (!$image) {
  136. $this->result->error = $this->interface->t('File is not an image.');
  137. return FALSE;
  138. }
  139. $this->result->width = $image[0];
  140. $this->result->height = $image[1];
  141. $this->result->mime = $this->type;
  142. break;
  143. case 'audio':
  144. $allowed = array(
  145. 'audio/mpeg' => 'mp3',
  146. 'audio/mp3' => 'mp3',
  147. 'audio/x-wav' => 'wav',
  148. 'audio/wav' => 'wav',
  149. //'application/ogg' => 'ogg',
  150. 'audio/ogg' => 'ogg',
  151. //'video/ogg' => 'ogg',
  152. );
  153. if (!$this->check($allowed)) {
  154. $this->result->error = $this->interface->t('Invalid audio file format. Use mp3 or wav.');
  155. return FALSE;
  156. }
  157. $this->result->mime = $this->type;
  158. break;
  159. case 'video':
  160. $allowed = array(
  161. 'video/mp4' => 'mp4',
  162. 'video/webm' => 'webm',
  163. // 'application/ogg' => 'ogv',
  164. 'video/ogg' => 'ogv',
  165. );
  166. if (!$this->check($allowed)) {
  167. $this->result->error = $this->interface->t('Invalid video file format. Use mp4 or webm.');
  168. return FALSE;
  169. }
  170. $this->result->mime = $this->type;
  171. break;
  172. case 'file':
  173. // TODO: Try to get file extension for type and check that it matches the current extension.
  174. $this->result->mime = $this->type;
  175. }
  176. return TRUE;
  177. }
  178. /**
  179. * Get the type of the current file.
  180. *
  181. * @return string
  182. */
  183. public function getType() {
  184. return $this->field->type;
  185. }
  186. /**
  187. * Get the name of the current file.
  188. *
  189. * @return string
  190. */
  191. public function getName() {
  192. static $name;
  193. if (empty($name)) {
  194. $name = uniqid($this->field->name . '-');
  195. // Add extension to name
  196. if (isset($this->data)) {
  197. $name .= '.' . $this->extension;
  198. }
  199. else {
  200. $matches = array();
  201. preg_match('/([a-z0-9]{1,})$/i', $_FILES['file']['name'], $matches);
  202. if (isset($matches[0])) {
  203. $name .= '.' . $matches[0];
  204. }
  205. }
  206. }
  207. return $name;
  208. }
  209. /**
  210. * Get file data if created from string.
  211. *
  212. * @return string|NULL
  213. */
  214. public function getData() {
  215. return (empty($this->data) ? NULL : $this->data);
  216. }
  217. /**
  218. * Get result from file processing.
  219. */
  220. public function getResult() {
  221. return json_encode($this->result);
  222. }
  223. /**
  224. * Print result from file processing.
  225. */
  226. public function printResult() {
  227. $this->result->path = $this->getType() . 's/' . $this->getName() . '#tmp';
  228. // text/plain is used to support IE
  229. header('Cache-Control: no-cache');
  230. header('Content-type: text/plain; charset=utf-8');
  231. print $this->getResult();
  232. }
  233. }