1 <?php
2 3 4 5 6 7 8
9
10 defined('JPATH_PLATFORM') or die;
11
12 13 14 15 16
17 class JHelperMedia
18 {
19 20 21 22 23 24 25 26 27
28 public function isImage($fileName)
29 {
30 static $imageTypes = 'xcf|odg|gif|jpg|png|bmp';
31
32 return preg_match("/\.(?:$imageTypes)$/i", $fileName);
33 }
34
35 36 37 38 39 40 41 42 43
44 public static function getTypeIcon($fileName)
45 {
46 return strtolower(substr($fileName, strrpos($fileName, '.') + 1));
47 }
48
49 50 51 52 53 54 55 56 57 58
59 private function getMimeType($file, $isImage = false)
60 {
61
62 $mime = false;
63
64 try
65 {
66 if ($isImage && function_exists('exif_imagetype'))
67 {
68 $mime = image_type_to_mime_type(exif_imagetype($file));
69 }
70 elseif ($isImage && function_exists('getimagesize'))
71 {
72 $imagesize = getimagesize($file);
73 $mime = isset($imagesize['mime']) ? $imagesize['mime'] : false;
74 }
75 elseif (function_exists('mime_content_type'))
76 {
77
78 $mime = mime_content_type($file);
79 }
80 elseif (function_exists('finfo_open'))
81 {
82
83 $finfo = finfo_open(FILEINFO_MIME_TYPE);
84 $mime = finfo_file($finfo, $file);
85 finfo_close($finfo);
86 }
87 }
88 catch (Exception $e)
89 {
90
91 return false;
92 }
93
94
95 if ($mime === 'application/octet-stream' && $isImage === true)
96 {
97 $mime = $this->getMimeType($file, false);
98 }
99
100
101 return $mime;
102 }
103
104 105 106 107 108 109 110 111 112 113
114 private function checkMimeType($mime, $component = 'com_media')
115 {
116 $params = JComponentHelper::getParams($component);
117
118 if ($params->get('check_mime', 1))
119 {
120
121 $allowedMime = array_map('trim', explode(',', $params->get('upload_mime')));
122
123
124 return !empty($mime) && in_array($mime, $allowedMime);
125 }
126
127
128 return true;
129 }
130
131 132 133 134 135 136 137 138 139 140
141 public function canUpload($file, $component = 'com_media')
142 {
143 $app = JFactory::getApplication();
144 $params = JComponentHelper::getParams($component);
145
146 if (empty($file['name']))
147 {
148 $app->enqueueMessage(JText::_('JLIB_MEDIA_ERROR_UPLOAD_INPUT'), 'error');
149
150 return false;
151 }
152
153 jimport('joomla.filesystem.file');
154
155 if (str_replace(' ', '', $file['name']) !== $file['name'] || $file['name'] !== JFile::makeSafe($file['name']))
156 {
157 $app->enqueueMessage(JText::_('JLIB_MEDIA_ERROR_WARNFILENAME'), 'error');
158
159 return false;
160 }
161
162 $filetypes = explode('.', $file['name']);
163
164 if (count($filetypes) < 2)
165 {
166
167 $app->enqueueMessage(JText::_('JLIB_MEDIA_ERROR_WARNFILETYPE'), 'error');
168
169 return false;
170 }
171
172 array_shift($filetypes);
173
174
175 $executable = array(
176 'php', 'js', 'exe', 'phtml', 'java', 'perl', 'py', 'asp', 'dll', 'go', 'ade', 'adp', 'bat', 'chm', 'cmd', 'com', 'cpl', 'hta', 'ins', 'isp',
177 'jse', 'lib', 'mde', 'msc', 'msp', 'mst', 'pif', 'scr', 'sct', 'shb', 'sys', 'vb', 'vbe', 'vbs', 'vxd', 'wsc', 'wsf', 'wsh',
178 );
179
180 $check = array_intersect($filetypes, $executable);
181
182 if (!empty($check))
183 {
184 $app->enqueueMessage(JText::_('JLIB_MEDIA_ERROR_WARNFILETYPE'), 'error');
185
186 return false;
187 }
188
189 $filetype = array_pop($filetypes);
190 $allowable = array_map('trim', explode(',', $params->get('upload_extensions')));
191 $ignored = array_map('trim', explode(',', $params->get('ignore_extensions')));
192
193 if ($filetype == '' || $filetype == false || (!in_array($filetype, $allowable) && !in_array($filetype, $ignored)))
194 {
195 $app->enqueueMessage(JText::_('JLIB_MEDIA_ERROR_WARNFILETYPE'), 'error');
196
197 return false;
198 }
199
200 $maxSize = (int) ($params->get('upload_maxsize', 0) * 1024 * 1024);
201
202 if ($maxSize > 0 && (int) $file['size'] > $maxSize)
203 {
204 $app->enqueueMessage(JText::_('JLIB_MEDIA_ERROR_WARNFILETOOLARGE'), 'error');
205
206 return false;
207 }
208
209 if ($params->get('restrict_uploads', 1))
210 {
211 $images = array_map('trim', explode(',', $params->get('image_extensions')));
212
213 if (in_array($filetype, $images))
214 {
215
216 if (!empty($file['tmp_name']))
217 {
218
219 $mime = $this->getMimeType($file['tmp_name'], true);
220
221
222 if ($mime != false)
223 {
224 $result = $this->checkMimeType($mime, $component);
225
226
227 if ($result === false)
228 {
229 $app->enqueueMessage(JText::sprintf('JLIB_MEDIA_ERROR_WARNINVALID_MIMETYPE', $mime), 'error');
230
231 return false;
232 }
233 }
234
235 else
236 {
237 $app->enqueueMessage(JText::_('JLIB_MEDIA_ERROR_WARNINVALID_IMG'), 'error');
238
239 return false;
240 }
241 }
242 else
243 {
244 $app->enqueueMessage(JText::_('JLIB_MEDIA_ERROR_WARNFILETOOLARGE'), 'error');
245
246 return false;
247 }
248 }
249 elseif (!in_array($filetype, $ignored))
250 {
251
252 $mime = $this->getMimeType($file['tmp_name'], false);
253
254
255 if ($mime != false)
256 {
257 $result = $this->checkMimeType($mime, $component);
258
259
260 if ($result === false)
261 {
262 $app->enqueueMessage(JText::sprintf('JLIB_MEDIA_ERROR_WARNINVALID_MIMETYPE', $mime), 'error');
263
264 return false;
265 }
266 }
267
268 else
269 {
270 $app->enqueueMessage(JText::_('JLIB_MEDIA_ERROR_WARNINVALID_MIME'), 'error');
271
272 return false;
273 }
274
275 if (!JFactory::getUser()->authorise('core.manage', $component))
276 {
277 $app->enqueueMessage(JText::_('JLIB_MEDIA_ERROR_WARNNOTADMIN'), 'error');
278
279 return false;
280 }
281 }
282 }
283
284 $xss_check = file_get_contents($file['tmp_name'], false, null, -1, 256);
285
286 $html_tags = array(
287 'abbr', 'acronym', 'address', 'applet', 'area', 'audioscope', 'base', 'basefont', 'bdo', 'bgsound', 'big', 'blackface', 'blink',
288 'blockquote', 'body', 'bq', 'br', 'button', 'caption', 'center', 'cite', 'code', 'col', 'colgroup', 'comment', 'custom', 'dd', 'del',
289 'dfn', 'dir', 'div', 'dl', 'dt', 'em', 'embed', 'fieldset', 'fn', 'font', 'form', 'frame', 'frameset', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6',
290 'head', 'hr', 'html', 'iframe', 'ilayer', 'img', 'input', 'ins', 'isindex', 'keygen', 'kbd', 'label', 'layer', 'legend', 'li', 'limittext',
291 'link', 'listing', 'map', 'marquee', 'menu', 'meta', 'multicol', 'nobr', 'noembed', 'noframes', 'noscript', 'nosmartquotes', 'object',
292 'ol', 'optgroup', 'option', 'param', 'plaintext', 'pre', 'rt', 'ruby', 's', 'samp', 'script', 'select', 'server', 'shadow', 'sidebar',
293 'small', 'spacer', 'span', 'strike', 'strong', 'style', 'sub', 'sup', 'table', 'tbody', 'td', 'textarea', 'tfoot', 'th', 'thead', 'title',
294 'tr', 'tt', 'ul', 'var', 'wbr', 'xml', 'xmp', '!DOCTYPE', '!--',
295 );
296
297 foreach ($html_tags as $tag)
298 {
299
300 if (stripos($xss_check, '<' . $tag . ' ') !== false || stripos($xss_check, '<' . $tag . '>') !== false)
301 {
302 $app->enqueueMessage(JText::_('JLIB_MEDIA_ERROR_WARNIEXSS'), 'error');
303
304 return false;
305 }
306 }
307
308 return true;
309 }
310
311 312 313 314 315 316 317 318 319 320 321
322 public static function imageResize($width, $height, $target)
323 {
324 325 326 327 328
329 if ($width > $height)
330 {
331 $percentage = ($target / $width);
332 }
333 else
334 {
335 $percentage = ($target / $height);
336 }
337
338
339 $width = round($width * $percentage);
340 $height = round($height * $percentage);
341
342 return array($width, $height);
343 }
344
345 346 347 348 349 350 351 352 353
354 public function countFiles($dir)
355 {
356 $total_file = 0;
357 $total_dir = 0;
358
359 if (is_dir($dir))
360 {
361 $d = dir($dir);
362
363 while (($entry = $d->read()) !== false)
364 {
365 if ($entry[0] !== '.' && strpos($entry, '.html') === false && strpos($entry, '.php') === false && is_file($dir . DIRECTORY_SEPARATOR . $entry))
366 {
367 $total_file++;
368 }
369
370 if ($entry[0] !== '.' && is_dir($dir . DIRECTORY_SEPARATOR . $entry))
371 {
372 $total_dir++;
373 }
374 }
375
376 $d->close();
377 }
378
379 return array($total_file, $total_dir);
380 }
381
382 383 384 385 386 387 388 389 390 391
392 public function toBytes($val)
393 {
394 switch ($val[strlen($val) - 1])
395 {
396 case 'M':
397 case 'm':
398 return (int) $val * 1048576;
399 case 'K':
400 case 'k':
401 return (int) $val * 1024;
402 case 'G':
403 case 'g':
404 return (int) $val * 1073741824;
405 default:
406 return $val;
407 }
408 }
409 }
410