1 <?php
2
3 4 5 6 7
8
9 10 11 12 13 14 15 16
17 function rex_mediapool_filename($FILENAME, $doSubindexing = true)
18 {
19
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
35 if (!rex_mediapool_isAllowedMediaType($NFILENAME)) {
36
37
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
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 61 62 63 64 65 66 67 68 69 70 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
94 $srcFile = rex_path::media($FILENAME);
95 $dstFile = rex_path::media($NFILENAME);
96
97 $success = true;
98 if ($isFileUpload) {
99 if (!@move_uploaded_file($FILE['tmp_name'], $dstFile)) {
100 $message[] = rex_i18n::msg('pool_file_movefailed');
101 $success = false;
102 }
103 } else {
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
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
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
163 if ($success) {
164 rex_extension::registerPoint(new rex_extension_point('MEDIA_ADDED', '', $RETURN));
165 }
166
167 return $RETURN;
168 }
169
170 171 172 173 174 175 176 177 178 179 180
181 function rex_mediapool_updateMedia($FILE, &$FILEINFOS, $userlogin = null)
182 {
183 $RETURN = [];
184
185 $FILESQL = rex_sql::factory();
186
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
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
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 256 257 258 259 260 261 262
263
264
265 if ($RETURN['ok']) {
266 rex_extension::registerPoint(new rex_extension_point('MEDIA_UPDATED', '', $RETURN));
267 }
268
269 return $RETURN;
270 }
271
272 273 274 275 276 277 278 279 280 281 282 283 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);
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
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 325 326 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 352 353 354
355 function rex_mediapool_mediaIsInUse($filename)
356 {
357 $sql = rex_sql::factory();
358
359
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
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 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 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 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 561 562 563 564 565 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
582
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 597 598 599 600 601 602 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 625 626 627 628 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)) {
640 $whitelist[] = $ext;
641 }
642 }
643 }
644 return $whitelist;
645 }
646
647 648 649 650 651
652 function rex_mediapool_getMediaTypeBlacklist()
653 {
654 return rex_addon::get('mediapool')->getProperty('blocked_extensions');
655 }
656