1 <?php
  2 
  3 /**
  4  * Funktionensammlung für den Medienpool.
  5  *
  6  * @package redaxo\mediapool
  7  */
  8 
  9 /**
 10  * Erstellt einen Filename der eindeutig ist für den Medienpool.
 11  *
 12  * @param string $FILENAME      Dateiname
 13  * @param bool   $doSubindexing
 14  *
 15  * @return string
 16  */
 17 function rex_mediapool_filename($FILENAME, $doSubindexing = true)
 18 {
 19     // ----- neuer filename und extension holen
 20     $NFILENAME = rex_string::normalize($FILENAME, '_', '.-@');
 21 
 22     if ('.' === $NFILENAME[0]) {
 23         $NFILENAME[0] = '_';
 24     }
 25 
 26     if (strrpos($NFILENAME, '.') != '') {
 27         $NFILE_NAME = substr($NFILENAME, 0, strlen($NFILENAME) - (strlen($NFILENAME) - strrpos($NFILENAME, '.')));
 28         $NFILE_EXT = substr($NFILENAME, strrpos($NFILENAME, '.'), strlen($NFILENAME) - strrpos($NFILENAME, '.'));
 29     } else {
 30         $NFILE_NAME = $NFILENAME;
 31         $NFILE_EXT = '';
 32     }
 33 
 34     // ---- ext checken - alle scriptendungen rausfiltern
 35     if (!rex_mediapool_isAllowedMediaType($NFILENAME)) {
 36         // make sure we dont add a 2nd file-extension to the file,
 37         // because some webspaces execute files like file.php.txt as a php script
 38         $NFILE_NAME .= str_replace('.', '_', $NFILE_EXT);
 39         $NFILE_EXT = '.txt';
 40     }
 41 
 42     $NFILENAME = $NFILE_NAME . $NFILE_EXT;
 43 
 44     if ($doSubindexing || $FILENAME != $NFILENAME) {
 45         // ----- datei schon vorhanden -> namen aendern -> _1 ..
 46         if (file_exists(rex_path::media($NFILENAME))) {
 47             $cnt = 1;
 48             while (file_exists(rex_path::media($NFILE_NAME . '_' . $cnt . $NFILE_EXT))) {
 49                 ++$cnt;
 50             }
 51 
 52             $NFILENAME = $NFILE_NAME . '_' . $cnt . $NFILE_EXT;
 53         }
 54     }
 55 
 56     return $NFILENAME;
 57 }
 58 
 59 /**
 60  * Holt ein upgeloadetes File und legt es in den Medienpool
 61  * Dabei wird kontrolliert ob das File schon vorhanden ist und es
 62  * wird eventuell angepasst, weiterhin werden die Fileinformationen übergeben.
 63  *
 64  * @param array  $FILE
 65  * @param int    $rex_file_category
 66  * @param array  $FILEINFOS
 67  * @param string $userlogin
 68  * @param bool   $doSubindexing
 69  *
 70  * @return array
 71  */
 72 function rex_mediapool_saveMedia($FILE, $rex_file_category, $FILEINFOS, $userlogin = null, $doSubindexing = true)
 73 {
 74     $rex_file_category = (int) $rex_file_category;
 75 
 76     $gc = rex_sql::factory();
 77     $gc->setQuery('SELECT * FROM ' . rex::getTablePrefix() . 'media_category WHERE id=' . $rex_file_category);
 78     if ($gc->getRows() != 1) {
 79         $rex_file_category = 0;
 80     }
 81 
 82     $isFileUpload = isset($FILE['tmp_name']);
 83     if ($isFileUpload) {
 84         $doSubindexing = true;
 85     }
 86 
 87     $FILENAME = $FILE['name'];
 88     $FILESIZE = $FILE['size'];
 89     $FILETYPE = $FILE['type'];
 90     $NFILENAME = rex_mediapool_filename($FILENAME, $doSubindexing);
 91     $message = [];
 92 
 93     // ----- alter/neuer filename
 94     $srcFile = rex_path::media($FILENAME);
 95     $dstFile = rex_path::media($NFILENAME);
 96 
 97     $success = true;
 98     if ($isFileUpload) { // Fileupload?
 99         if (!@move_uploaded_file($FILE['tmp_name'], $dstFile)) {
100             $message[] = rex_i18n::msg('pool_file_movefailed');
101             $success = false;
102         }
103     } else { // Filesync?
104         if (!@rename($srcFile, $dstFile)) {
105             $message[] = rex_i18n::msg('pool_file_movefailed');
106             $success = false;
107         }
108     }
109 
110     if ($success) {
111         @chmod($dstFile, rex::getFilePerm());
112 
113         // get widht height
114         $size = @getimagesize($dstFile);
115 
116         if ($FILETYPE == '' && isset($size['mime'])) {
117             $FILETYPE = $size['mime'];
118         }
119 
120         $FILESQL = rex_sql::factory();
121         $FILESQL->setTable(rex::getTablePrefix() . 'media');
122         $FILESQL->setValue('filetype', $FILETYPE);
123         $FILESQL->setValue('title', $FILEINFOS['title']);
124         $FILESQL->setValue('filename', $NFILENAME);
125         $FILESQL->setValue('originalname', $FILENAME);
126         $FILESQL->setValue('filesize', $FILESIZE);
127 
128         if ($size) {
129             $FILESQL->setValue('width', $size[0]);
130             $FILESQL->setValue('height', $size[1]);
131         }
132 
133         $FILESQL->setValue('category_id', $rex_file_category);
134         $FILESQL->addGlobalCreateFields($userlogin);
135         $FILESQL->addGlobalUpdateFields($userlogin);
136         $FILESQL->insert();
137 
138         if ($isFileUpload) {
139             $message[] = rex_i18n::msg('pool_file_added');
140         }
141 
142         if ($NFILENAME != $FILENAME) {
143             $message[] = rex_i18n::rawMsg('pool_file_renamed', $FILENAME, $NFILENAME);
144         }
145 
146         rex_media_cache::deleteList($rex_file_category);
147     }
148 
149     $RETURN['title'] = $FILEINFOS['title'];
150     $RETURN['type'] = $FILETYPE;
151     $RETURN['msg'] = implode('<br />', $message);
152     // Aus BC gruenden hier mit int 1/0
153     $RETURN['ok'] = $success ? 1 : 0;
154     $RETURN['filename'] = $NFILENAME;
155     $RETURN['old_filename'] = $FILENAME;
156 
157     if (isset($size)) {
158         $RETURN['width'] = $size[0];
159         $RETURN['height'] = $size[1];
160     }
161 
162     // ----- EXTENSION POINT
163     if ($success) {
164         rex_extension::registerPoint(new rex_extension_point('MEDIA_ADDED', '', $RETURN));
165     }
166 
167     return $RETURN;
168 }
169 
170 /**
171  * Holt ein upgeloadetes File und legt es in den Medienpool
172  * Dabei wird kontrolliert ob das File schon vorhanden ist und es
173  * wird eventuell angepasst, weiterhin werden die Fileinformationen übergeben.
174  *
175  * @param array  $FILE
176  * @param array  $FILEINFOS
177  * @param string $userlogin
178  *
179  * @return array
180  */
181 function rex_mediapool_updateMedia($FILE, &$FILEINFOS, $userlogin = null)
182 {
183     $RETURN = [];
184 
185     $FILESQL = rex_sql::factory();
186     // $FILESQL->setDebug();
187     $FILESQL->setTable(rex::getTablePrefix() . 'media');
188     $FILESQL->setWhere(['id' => $FILEINFOS['file_id']]);
189     $FILESQL->setValue('title', $FILEINFOS['title']);
190     $FILESQL->setValue('category_id', $FILEINFOS['rex_file_category']);
191 
192     $updated = false;
193     if ($FILE['name'] != '' && $FILE['name'] != 'none') {
194         $ffilename = $FILE['tmp_name'];
195         $ffiletype = $FILE['type'];
196         $ffilesize = $FILE['size'];
197 
198         $extensionNew = mb_strtolower(pathinfo($FILE['name'], PATHINFO_EXTENSION));
199         $extensionOld = mb_strtolower(pathinfo($FILEINFOS['filename'], PATHINFO_EXTENSION));
200 
201         static $jpgExtensions = ['jpg', 'jpeg'];
202 
203         if (
204             $extensionNew == $extensionOld ||
205             in_array($extensionNew, $jpgExtensions) && in_array($extensionOld, $jpgExtensions)
206         ) {
207             if (move_uploaded_file($ffilename, rex_path::media($FILEINFOS['filename'])) ||
208                     copy($ffilename, rex_path::media($FILEINFOS['filename']))
209             ) {
210                 $RETURN['msg'] = rex_i18n::msg('pool_file_changed');
211                 $FILEINFOS['filetype'] = $ffiletype;
212                 $FILEINFOS['filesize'] = $ffilesize;
213 
214                 $FILESQL->setValue('filetype', $FILEINFOS['filetype']);
215                 // $FILESQL->setValue('originalname',$ffilename);
216                 $FILESQL->setValue('filesize', $FILEINFOS['filesize']);
217                 if ($size = @getimagesize(rex_path::media($FILEINFOS['filename']))) {
218                     $FILESQL->setValue('width', $size[0]);
219                     $FILESQL->setValue('height', $size[1]);
220                 }
221                 @chmod(rex_path::media($FILEINFOS['filename']), rex::getFilePerm());
222                 $updated = true;
223             } else {
224                 $RETURN['msg'] = rex_i18n::msg('pool_file_upload_error');
225             }
226         } else {
227             $RETURN['msg'] = rex_i18n::msg('pool_file_upload_errortype');
228         }
229     } else {
230         if ($size = @getimagesize(rex_path::media($FILEINFOS['filename']))) {
231             $FILESQL->setValue('width', $size[0]);
232             $FILESQL->setValue('height', $size[1]);
233         }
234         $FILESQL->setValue('filesize', @filesize(rex_path::media($FILEINFOS['filename'])));
235     }
236 
237     // Aus BC gruenden hier mit int 1/0
238     $RETURN['ok'] = $updated ? 1 : 0;
239     if (!isset($RETURN['msg'])) {
240         $RETURN['msg'] = rex_i18n::msg('pool_file_infos_updated');
241         $RETURN['ok'] = 1;
242     }
243     if ($RETURN['ok'] == 1) {
244         $RETURN['filename'] = $FILEINFOS['filename'];
245         $RETURN['filetype'] = $FILEINFOS['filetype'];
246         $RETURN['id'] = $FILEINFOS['file_id'];
247     }
248 
249     $FILESQL->addGlobalUpdateFields($userlogin);
250     $FILESQL->update();
251 
252     rex_media_cache::delete($FILEINFOS['filename']);
253 
254     /*
255     $RETURN['title'] = $FILEINFOS['title'];
256     $RETURN['type'] = $FILETYPE;
257     $RETURN['msg'] = $message;
258     // Aus BC gruenden hier mit int 1/0
259     $RETURN['ok'] = $success ? 1 : 0;
260     $RETURN['filename'] = $NFILENAME;
261     $RETURN['old_filename'] = $FILENAME;
262     */
263 
264     // ----- EXTENSION POINT
265     if ($RETURN['ok']) {
266         rex_extension::registerPoint(new rex_extension_point('MEDIA_UPDATED', '', $RETURN));
267     }
268 
269     return $RETURN;
270 }
271 
272 /**
273  * Synchronisiert die Datei $physical_filename des Mediafolders in den
274  * Medienpool.
275  *
276  * @param string      $physical_filename
277  * @param int         $category_id
278  * @param string      $title
279  * @param null|int    $filesize
280  * @param null|string $filetype
281  * @param null|string $userlogin
282  *
283  * @return bool|array
284  */
285 function rex_mediapool_syncFile($physical_filename, $category_id, $title, $filesize = null, $filetype = null, $userlogin = null)
286 {
287     $abs_file = rex_path::media($physical_filename);
288 
289     if (!file_exists($abs_file)) {
290         return false;
291     }
292 
293     if (empty($filesize)) {
294         $filesize = filesize($abs_file);
295     }
296 
297     if (empty($filetype) && function_exists('mime_content_type')) {
298         $filetype = mime_content_type($abs_file);
299     }
300 
301     if (empty($filetype) && function_exists('finfo_open')) {
302         $finfo = finfo_open(FILEINFO_MIME_TYPE); // return mime type ala mimetype extension
303         $filetype = finfo_file($finfo, $abs_file);
304     }
305 
306     $FILE = [];
307     $FILE['name'] = $physical_filename;
308     $FILE['size'] = $filesize;
309     $FILE['type'] = $filetype;
310 
311     $FILEINFOS = [];
312     $FILEINFOS['title'] = $title;
313 
314     // check for previous 6th (unused) parameter $doSubindexing
315     if (is_bool($userlogin)) {
316         $userlogin = null;
317     }
318 
319     $RETURN = rex_mediapool_saveMedia($FILE, $category_id, $FILEINFOS, $userlogin, false);
320     return $RETURN;
321 }
322 
323 /**
324  * @param string $filename
325  *
326  * @return bool
327  */
328 function rex_mediapool_deleteMedia($filename)
329 {
330     if ($uses = rex_mediapool_mediaIsInUse($filename)) {
331         $msg = '<strong>' . rex_i18n::msg('pool_file_delete_error', $filename) . ' '
332             . rex_i18n::msg('pool_object_in_use_by') . '</strong><br />' . $uses;
333         return ['ok' => false, 'msg' => $msg];
334     }
335 
336     $sql = rex_sql::factory();
337     $sql->setQuery('DELETE FROM ' . rex::getTable('media') . ' WHERE filename = ? LIMIT 1', [$filename]);
338 
339     rex_file::delete(rex_path::media($filename));
340 
341     rex_media_cache::delete($filename);
342 
343     rex_extension::registerPoint(new rex_extension_point('MEDIA_DELETED', '', [
344         'filename' => $filename,
345     ]));
346 
347     return ['ok' => true, 'msg' => rex_i18n::msg('pool_file_deleted')];
348 }
349 
350 /**
351  * @param $filename
352  *
353  * @return bool|string
354  */
355 function rex_mediapool_mediaIsInUse($filename)
356 {
357     $sql = rex_sql::factory();
358 
359     // FIXME move structure stuff into structure addon
360     $values = [];
361     for ($i = 1; $i < 21; ++$i) {
362         $values[] = 'value' . $i . ' REGEXP ' . $sql->escape('(^|[^[:alnum:]+_-])'.$filename);
363     }
364 
365     $files = [];
366     $filelists = [];
367     $escapedFilename = $sql->escape($filename);
368     for ($i = 1; $i < 11; ++$i) {
369         $files[] = 'media' . $i . ' = ' . $escapedFilename;
370         $filelists[] = 'FIND_IN_SET(' . $escapedFilename . ', medialist' . $i . ')';
371     }
372 
373     $where = '';
374     $where .= implode(' OR ', $files) . ' OR ';
375     $where .= implode(' OR ', $filelists) . ' OR ';
376     $where .= implode(' OR ', $values);
377     $query = 'SELECT DISTINCT article_id, clang_id FROM ' . rex::getTablePrefix() . 'article_slice WHERE ' . $where;
378 
379     $warning = [];
380     $res = $sql->getArray($query);
381     if ($sql->getRows() > 0) {
382         $warning[0] = rex_i18n::msg('pool_file_in_use_articles') . '<br /><ul>';
383         foreach ($res as $art_arr) {
384             $aid = $art_arr['article_id'];
385             $clang = $art_arr['clang_id'];
386             $ooa = rex_article::get($aid, $clang);
387             $name = $ooa->getName();
388             $warning[0] .= '<li><a href="javascript:openPage(\'' . rex_url::backendPage('content', ['article_id' => $aid, 'mode' => 'edit', 'clang' => $clang]) . '\')">' . $name . '</a></li>';
389         }
390         $warning[0] .= '</ul>';
391     }
392 
393     // ----- EXTENSION POINT
394     $warning = rex_extension::registerPoint(new rex_extension_point('MEDIA_IS_IN_USE', $warning, [
395         'filename' => $filename,
396     ]));
397 
398     if (!empty($warning)) {
399         return implode('<br />', $warning);
400     }
401 
402     return false;
403 }
404 
405 /**
406  * Ausgabe des Medienpool Formulars.
407  */
408 function rex_mediapool_Mediaform($form_title, $button_title, $rex_file_category, $file_chooser, $close_form)
409 {
410     global $ftitle, $warning, $info;
411 
412     $s = '';
413 
414     $cats_sel = new rex_media_category_select();
415     $cats_sel->setStyle('class="form-control"');
416     $cats_sel->setSize(1);
417     $cats_sel->setName('rex_file_category');
418     $cats_sel->setId('rex-mediapool-category');
419     $cats_sel->setAttribute('class', 'selectpicker form-control');
420     $cats_sel->setAttribute('data-live-search', 'true');
421     $cats_sel->setAttribute('onchange', 'this.form.submit()');
422     $cats_sel->setSelected($rex_file_category);
423 
424     if (rex::getUser()->getComplexPerm('media')->hasAll()) {
425         $cats_sel->addOption(rex_i18n::msg('pool_kats_no'), '0');
426     }
427 
428     if (isset($warning)) {
429         if (is_array($warning)) {
430             if (count($warning) > 0) {
431                 $s .= rex_view::error(implode('<br />', $warning));
432             }
433         } elseif ($warning != '') {
434             $s .= rex_view::error($warning);
435         }
436         $warning = '';
437     }
438 
439     if (isset($info)) {
440         if (is_array($info)) {
441             if (count($info) > 0) {
442                 $s .= rex_view::success(implode('<br />', $info));
443             }
444         } elseif ($info != '') {
445             $s .= rex_view::success($info);
446         }
447         $info = '';
448     }
449 
450     if (!isset($ftitle)) {
451         $ftitle = '';
452     }
453 
454     $arg_fields = '';
455     foreach (rex_request('args', 'array') as $arg_name => $arg_value) {
456         $arg_fields .= '<input type="hidden" name="args[' . rex_escape($arg_name) . ']" value="' . rex_escape($arg_value) . '" />' . "\n";
457     }
458 
459     $opener_input_field = rex_request('opener_input_field', 'string');
460     if ($opener_input_field != '') {
461         $arg_fields .= '<input type="hidden" name="opener_input_field" value="' . rex_escape($opener_input_field) . '" />' . "\n";
462     }
463 
464     $add_submit = '';
465     if ($close_form && $opener_input_field != '') {
466         $add_submit = '<button class="btn btn-save" type="submit" name="saveandexit" value="' . rex_i18n::msg('pool_file_upload_get') . '"' . rex::getAccesskey(rex_i18n::msg('pool_file_upload_get'), 'save') . '>' . rex_i18n::msg('pool_file_upload_get') . '</button>';
467     }
468 
469     $panel = '';
470     $panel .= '<fieldset>';
471     $formElements = [];
472 
473     $e = [];
474     $e['label'] = '<label for="rex-mediapool-category">' . rex_i18n::msg('pool_file_category') . '</label>';
475     $e['field'] = $cats_sel->get();
476     $formElements[] = $e;
477 
478     $e = [];
479     $e['label'] = '<label for="rex-mediapool-title">' . rex_i18n::msg('pool_file_title') . '</label>';
480     $e['field'] = '<input class="form-control" type="text" id="rex-mediapool-title" name="ftitle" value="' . rex_escape($ftitle) . '" />';
481     $formElements[] = $e;
482 
483     $fragment = new rex_fragment();
484     $fragment->setVar('elements', $formElements, false);
485     $panel .= $fragment->parse('core/form/form.php');
486 
487     $panel .= rex_extension::registerPoint(new rex_extension_point('MEDIA_FORM_ADD', ''));
488 
489     if ($file_chooser) {
490         $e = [];
491         $e['label'] = '<label for="rex-mediapool-choose-file">' . rex_i18n::msg('pool_file_file') . '</label>';
492         $e['field'] = '<input id="rex-mediapool-choose-file" type="file" name="file_new" />';
493         $e['after'] = '<h3>' . rex_i18n::msg('phpini_settings') . '</h3>
494                         <dl class="dl-horizontal text-left">
495                         ' . ((rex_ini_get('file_uploads') == 0) ? '<dt><span class="text-warning">' . rex_i18n::msg('pool_upload') . '</span></dt><dd><span class="text-warning">' . rex_i18n::msg('pool_upload_disabled') . '</span></dd>' : '') . '
496                             <dt>' . rex_i18n::msg('pool_max_uploadsize') . ':</dt><dd>' . rex_formatter::bytes(rex_ini_get('upload_max_filesize')) . '</dd>
497                             <dt>' . rex_i18n::msg('pool_max_uploadtime') . ':</dt><dd>' . rex_ini_get('max_input_time') . 's</dd>
498                         </dl>';
499 
500         $fragment = new rex_fragment();
501         $fragment->setVar('elements', [$e], false);
502         $panel .= $fragment->parse('core/form/form.php');
503     }
504     $panel .= '</fieldset>';
505 
506     $formElements = [];
507 
508     $e = [];
509     $e['field'] = '<button class="btn btn-save rex-form-aligned" type="submit" name="save" value="' . $button_title . '"' . rex::getAccesskey($button_title, 'save') . '>' . $button_title . '</button>';
510     $formElements[] = $e;
511 
512     $e = [];
513     $e['field'] = $add_submit;
514     $formElements[] = $e;
515 
516     $fragment = new rex_fragment();
517     $fragment->setVar('elements', $formElements, false);
518     $buttons = $fragment->parse('core/form/submit.php');
519 
520     $fragment = new rex_fragment();
521     $fragment->setVar('class', 'edit', false);
522     $fragment->setVar('title', $form_title, false);
523     $fragment->setVar('body', $panel, false);
524     $fragment->setVar('buttons', $buttons, false);
525     $content = $fragment->parse('core/page/section.php');
526 
527     $s .= ' <form action="' . rex_url::currentBackendPage() . '" method="post" enctype="multipart/form-data" data-pjax="false">
528                 ' . rex_csrf_token::factory('mediapool')->getHiddenField() . '
529                 <fieldset>
530                     <input type="hidden" name="media_method" value="add_file" />
531                     ' . $arg_fields . '
532                     ' . $content . '
533                 </fieldset>
534             ';
535 
536     if ($close_form) {
537         $s .= '</form>' . "\n";
538     }
539 
540     return $s;
541 }
542 
543 /**
544  * Ausgabe des Medienpool Upload-Formulars.
545  */
546 function rex_mediapool_Uploadform($rex_file_category)
547 {
548     return rex_mediapool_Mediaform(rex_i18n::msg('pool_file_insert'), rex_i18n::msg('pool_file_upload'), $rex_file_category, true, true);
549 }
550 
551 /**
552  * Ausgabe des Medienpool Sync-Formulars.
553  */
554 function rex_mediapool_Syncform($rex_file_category)
555 {
556     return rex_mediapool_Mediaform(rex_i18n::msg('pool_sync_title'), rex_i18n::msg('pool_sync_button'), $rex_file_category, false, false);
557 }
558 
559 /**
560  * check if mediatpye(extension) is allowed for upload.
561  *
562  * @param string $filename
563  * @param array  $args
564  *
565  * @return bool
566  */
567 function rex_mediapool_isAllowedMediaType($filename, array $args = [])
568 {
569     $file_ext = mb_strtolower(rex_file::extension($filename));
570 
571     if ($filename === '' || strpos($file_ext, ' ') !== false || $file_ext === '') {
572         return false;
573     }
574 
575     if (0 === strpos($file_ext, 'php')) {
576         return false;
577     }
578 
579     $blacklist = rex_mediapool_getMediaTypeBlacklist();
580     foreach ($blacklist as $blackExtension) {
581         // blacklisted extensions are not allowed within filenames, to prevent double extension vulnerabilities:
582         // -> some webspaces execute files named file.php.txt as php
583         if (strpos($filename, '.'. $blackExtension) !== false) {
584             return false;
585         }
586     }
587 
588     $whitelist = rex_mediapool_getMediaTypeWhitelist($args);
589     if (count($whitelist) > 0 && !in_array($file_ext, $whitelist)) {
590         return false;
591     }
592     return true;
593 }
594 
595 /**
596  * Checks file against optional whitelist from property `allowed_mime_types`.
597  *
598  * @param string      $path     Path to the physical file
599  * @param null|string $filename Optional filename, will be used for extracting the file extension.
600  *                              If not given, the extension is extracted from `$path`.
601  *
602  * @return bool
603  */
604 function rex_mediapool_isAllowedMimeType($path, $filename = null)
605 {
606     $whitelist = rex_addon::get('mediapool')->getProperty('allowed_mime_types');
607 
608     if (!$whitelist) {
609         return true;
610     }
611 
612     $extension = mb_strtolower(rex_file::extension($filename ?: $path));
613 
614     if (!isset($whitelist[$extension])) {
615         return false;
616     }
617 
618     $mime_type = mime_content_type($path);
619 
620     return in_array($mime_type, $whitelist[$extension]);
621 }
622 
623 /**
624  * get whitelist of mediatypes(extensions) given via media widget "types" param.
625  *
626  * @param array $args widget params
627  *
628  * @return array whitelisted extensions
629  */
630 function rex_mediapool_getMediaTypeWhitelist($args = [])
631 {
632     $blacklist = rex_mediapool_getMediaTypeBlacklist();
633 
634     $whitelist = [];
635     if (isset($args['types'])) {
636         foreach (explode(',', $args['types']) as $ext) {
637             $ext = ltrim($ext, '.');
638             $ext = mb_strtolower($ext);
639             if (!in_array($ext, $blacklist)) { // whitelist cannot override any blacklist entry from master
640                 $whitelist[] = $ext;
641             }
642         }
643     }
644     return $whitelist;
645 }
646 
647 /**
648  * return global mediatype blacklist from master.inc.
649  *
650  * @return array blacklisted mediatype extensions
651  */
652 function rex_mediapool_getMediaTypeBlacklist()
653 {
654     return rex_addon::get('mediapool')->getProperty('blocked_extensions');
655 }
656