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