ILIAS  trunk Revision v12.0_alpha-377-g3641b37b9db
class.ilObjMediaObject.php
Go to the documentation of this file.
1<?php
2
28
29define("IL_MODE_ALIAS", 1);
30define("IL_MODE_OUTPUT", 2);
31define("IL_MODE_FULL", 3);
32
37{
38 public const DEFAULT_THUMB_SIZE = 80;
39 public const DEFAULT_PREVIEW_SIZE = 400;
43 protected ilObjUser $user;
44 public bool $is_alias;
45 public string $origin_id;
46 public array $media_items;
47 public bool $contains_int_link;
49
50 public function __construct(
51 int $a_id = 0
52 ) {
53 global $DIC;
54
55 $this->user = $DIC->user();
56 $this->app_event_handler = $DIC["ilAppEventHandler"];
57 $this->lng = $DIC->language();
58 $this->is_alias = false;
59 $this->media_items = array();
60 $this->contains_int_link = false;
61 $this->type = "mob";
62 parent::__construct($a_id, false);
63 $this->image_converter = $DIC->fileConverters()->legacyImages();
64 $this->domain = $DIC->mediaObjects()->internal()->domain();
65 $this->manager = $this->domain->mediaObject();
66 $this->thumbs = $this->domain->thumbs();
67 }
68
69 public static function _exists(
70 int $id,
71 bool $reference = false,
72 ?string $type = null
73 ): bool {
74 if (is_int(strpos($id, "_"))) {
76 }
77
78 if (parent::_exists($id) && ilObject::_lookupType($id) === "mob") {
79 return true;
80 }
81 return false;
82 }
83
84 public function delete(): bool
85 {
86 $mob_logger = ilLoggerFactory::getLogger('mob');
87 $mob_logger->debug("ilObjMediaObject: Delete called for media object ID '" . $this->getId() . "'.");
88
89 if (!($this->getId() > 0)) {
90 return false;
91 }
92
93 $usages = $this->getUsages();
94
95 $mob_logger->debug("ilObjMediaObject: ... Found " . count($usages) . " usages.");
96
97 if (count($usages) == 0) {
98 // delete meta data of mob
99 $this->deleteMetaData();
100
101 // delete media items
103
104 // this is just to make sure, there should be no entries left at
105 // this point as they depend on the usage
106 self::handleQuotaUpdate($this);
107
108 // delete object
109 parent::delete();
110
111 $mob_logger->debug("ilObjMediaObject: ... deleted.");
112 } else {
113 foreach ($usages as $u) {
114 $mob_logger->debug("ilObjMediaObject: ... usage type:" . $u["type"] .
115 ", id:" . $u["id"] .
116 ", lang:" . ($u["lang"] ?? "") .
117 ", hist_nr:" . ($u["hist_nr"] ?? "") . ".");
118 }
119 $mob_logger->debug("ilObjMediaObject: ... not deleted.");
120 }
121 return true;
122 }
123
124 protected function beforeMDUpdateListener(string $a_element): bool
125 {
126 switch ($a_element) {
127 case 'General':
128 // Update Title and description
129 $paths = $this->domain->metadata()->learningObjectMetadata()->paths();
130 $reader = $this->domain->metadata()->learningObjectMetadata()->read(
131 0,
132 $this->getId(),
133 $this->getType(),
134 $paths->custom()->withNextStep('general')->get()
135 );
136
137 ilObject::_writeTitle($this->getId(), $reader->firstData($paths->title())->value());
138 ilObject::_writeDescription($this->getId(), $reader->firstData($paths->descriptions())->value());
139 break;
140 }
141 return false; // prevent parent from creating ilMD
142 }
143
144 protected function beforeCreateMetaData(): bool
145 {
146 $ilUser = $this->user;
147
148 $this->domain->metadata()->learningObjectMetadata()->derive()->fromBasicProperties(
149 $this->getTitle(),
150 $this->getLongDescription(),
151 $ilUser->getPref('language')
152 )->forObject(0, $this->getId(), $this->getType());
153
154 return false; // avoid parent to create md
155 }
156
157 protected function beforeUpdateMetaData(): bool
158 {
159 $paths = $this->domain->metadata()->learningObjectMetadata()->paths();
160
161 $manipulator = $this->domain->metadata()->learningObjectMetadata()
162 ->manipulate(0, $this->getId(), $this->getType())
163 ->prepareCreateOrUpdate($paths->title(), $this->getTitle());
164
165 if ($this->getDescription() !== '') {
166 $manipulator = $manipulator->prepareCreateOrUpdate($paths->firstDescription(), $this->getDescription());
167 } else {
168 $manipulator = $manipulator->prepareDelete($paths->firstDescription());
169 }
170
171 $manipulator->execute();
172
173 return false;
174 }
175
176 protected function beforeDeleteMetaData(): bool
177 {
178 // Delete meta data
179 $this->domain->metadata()->learningObjectMetadata()
180 ->deleteAll(0, $this->getId(), $this->getType());
181
182 return false;
183 }
184
185
186 public function addMediaItem(
187 ilMediaItem $a_item
188 ): void {
189 $this->media_items[] = $a_item;
190 }
191
192 public function &getMediaItems(): array
193 {
194 return $this->media_items;
195 }
196
200 public function getMediaItem(
201 string $a_purpose
202 ): ?ilMediaItem {
203 foreach ($this->media_items as $media_item) {
204 if ($media_item->getPurpose() == $a_purpose) {
205 return $media_item;
206 }
207 }
208 return null;
209 }
210
211 public function removeMediaItem(
212 string $a_purpose
213 ): void {
214 foreach ($this->media_items as $key => $media_item) {
215 if ($media_item->getPurpose() == $a_purpose) {
216 unset($this->media_items[$key]);
217 }
218 }
219 // update numbers and keys
220 $i = 1;
221 $media_items = array();
222 foreach ($this->media_items as $media_item) {
223 $media_items [$i] = $media_item;
224 $media_item->setMobId($this->getId());
225 $media_item->setNr($i);
226 $i++;
227 }
228 $this->media_items = $media_items;
229 }
230
231 public function removeAllMediaItems(): void
232 {
233 $this->media_items = array();
234 }
235
236 public function hasFullscreenItem(): bool
237 {
238 return $this->hasPurposeItem("Fullscreen");
239 }
240
244 public function hasPurposeItem(string $purpose): bool
245 {
246 if (is_object($this->getMediaItem($purpose))) {
247 return true;
248 } else {
249 return false;
250 }
251 }
252
257 public function read(): void
258 {
259 parent::read();
261 }
262
263 public function setAlias(bool $a_is_alias): void
264 {
265 $this->is_alias = $a_is_alias;
266 }
267
268 public function isAlias(): bool
269 {
270 return $this->is_alias;
271 }
272
276 public function setOriginID(string $a_id): void
277 {
278 $this->origin_id = $a_id;
279 }
280
281 public function getOriginID(): string
282 {
283 return $this->origin_id;
284 }
285
286 public function create(
287 bool $a_create_meta_data = false,
288 bool $a_save_media_items = true,
289 int $from_mob_id = 0
290 ): int {
291 $id = parent::create();
292
293 if (!$a_create_meta_data) {
294 $this->createMetaData();
295 }
296 $this->manager->create(
297 $id,
298 $this->getTitle(),
299 $from_mob_id
300 );
301
302 if ($a_save_media_items) {
303 $media_items = $this->getMediaItems();
304 for ($i = 0; $i < count($media_items); $i++) {
305 $item = $media_items[$i];
306 $item->setMobId($this->getId());
307 $item->setNr($i + 1);
308 $item->create();
309 }
310 }
311
312 self::handleQuotaUpdate($this);
313
314 $ilAppEventHandler = $this->app_event_handler;
315 $ilAppEventHandler->raise(
316 'components/ILIAS/MediaObjects',
317 'create',
318 array('object' => $this,
319 'obj_type' => 'mob',
320 'obj_id' => $this->getId())
321 );
322
323 return $id;
324 }
325
326 public function update(bool $a_upload = false): bool
327 {
328 parent::update();
329
330 if (!$a_upload) {
331 $this->updateMetaData();
332 }
333
334 // iterate all items
335 $media_items = $this->getMediaItems();
337
338 $j = 1;
339 foreach ($media_items as $key => $val) {
340 $item = $val;
341 if (is_object($item)) {
342 $item->setMobId($this->getId());
343 $item->setNr($j);
344 if ($item->getLocationType() == "Reference") {
345 $item->extractUrlParameters();
346 }
347 $item->create();
348 $j++;
349 }
350 }
351
352 $this->manager->updateLastChange($this->getId());
353
354 self::handleQuotaUpdate($this);
355 $ilAppEventHandler = $this->app_event_handler;
356 $ilAppEventHandler->raise(
357 'components/ILIAS/MediaObjects',
358 'update',
359 array('object' => $this,
360 'obj_type' => 'mob',
361 'obj_id' => $this->getId())
362 );
363
364 return true;
365 }
366
370 protected static function handleQuotaUpdate(
371 ilObjMediaObject $a_mob
372 ): void {
373 }
374
378 public static function _getDirectory(
379 int $a_mob_id
380 ): string {
381 return ilFileUtils::getWebspaceDir() . "/" . self::_getRelativeDirectory($a_mob_id);
382 }
383
387 public static function _getRelativeDirectory(int $a_mob_id): string
388 {
389 return "mobs/mm_" . $a_mob_id;
390 }
391
395 public static function _getURL(
396 int $a_mob_id
397 ): string {
398 return ilUtil::getHtmlPath(ilFileUtils::getWebspaceDir() . "/mobs/mm_" . $a_mob_id);
399 }
400
404 public static function _lookupItemPath(
405 int $a_mob_id,
406 bool $a_url_encode = false,
407 bool $a_web = true,
408 string $a_purpose = ""
409 ): string {
410 if ($a_purpose == "") {
411 $a_purpose = "Standard";
412 }
413 $location = ilMediaItem::_lookupLocationForMobId($a_mob_id, $a_purpose);
414 if (preg_match("/https?\:/i", $location)) {
415 return $location;
416 }
417
418 if ($a_url_encode) {
419 $location = rawurlencode($location);
420 }
421
422 $path = ($a_web)
423 ? ILIAS_HTTP_PATH
424 : ".";
425
426 return $path . "/public/data/" . CLIENT_ID . "/mobs/mm_" . $a_mob_id . "/" . $location;
427 }
428
433 public function createDirectory(): void
434 {
437 if (!is_dir($path)) {
438 throw new ilMediaObjectsException("Failed to create directory $path.");
439 }
440 }
441
442 public function getFilesOfDirectory(
443 string $dir_path = ""
444 ): array {
445 return $this->manager->getFilesOfPath(
446 $this->getId(),
447 $dir_path
448 );
449 }
450
459 public function getXML(
460 int $a_mode = IL_MODE_FULL,
461 int $a_inst = 0,
462 bool $a_sign_locals = false,
463 bool $offline = false
464 ): string {
465 $ilUser = $this->user;
466 $xml = "";
467 switch ($a_mode) {
468 case IL_MODE_ALIAS:
469 $xml = "<MediaObject>";
470 $xml .= "<MediaAlias OriginId=\"il__mob_" . $this->getId() . "\"/>";
471 $media_items = $this->getMediaItems();
472 for ($i = 0; $i < count($media_items); $i++) {
473 $item = $media_items[$i];
474 $xml .= "<MediaAliasItem Purpose=\"" . $item->getPurpose() . "\">";
475
476 // Layout
477 $width = ($item->getWidth() != "")
478 ? "Width=\"" . $item->getWidth() . "\""
479 : "";
480 $height = ($item->getHeight() != "")
481 ? "Height=\"" . $item->getHeight() . "\""
482 : "";
483 $halign = ($item->getHAlign() != "")
484 ? "HorizontalAlign=\"" . $item->getHAlign() . "\""
485 : "";
486 $xml .= "<Layout $width $height $halign />";
487
488 // Caption
489 if ($item->getCaption() != "") {
490 $xml .= "<Caption Align=\"bottom\">" .
491 $this->escapeProperty($item->getCaption()) . "</Caption>";
492 }
493
494 // Text Representation
495 if ($item->getTextRepresentation() != "") {
496 $xml .= "<TextRepresentation>" .
497 $this->escapeProperty($item->getTextRepresentation()) . "</TextRepresentation>";
498 }
499
500 // Parameter
501 $parameters = $item->getParameters();
502 foreach ($parameters as $name => $value) {
503 $xml .= "<Parameter Name=\"$name\" Value=\"" . $this->escapeProperty($value) . "\"/>";
504 }
505 $xml .= $item->getMapAreasXML();
506 $xml .= "</MediaAliasItem>";
507 }
508 break;
509
510 // for output we need technical sections of meta data
511 case IL_MODE_OUTPUT:
512
513 // get first technical section
514 // $meta = $this->getMetaData();
515 $xml = "<MediaObject Id=\"il__mob_" . $this->getId() . "\">";
516
517 $media_items = $this->getMediaItems();
518 for ($i = 0; $i < count($media_items); $i++) {
519 $item = $media_items[$i];
520
521 $xml .= "<MediaItem Purpose=\"" . $item->getPurpose() . "\">";
522 if ($a_sign_locals && $item->getLocationType() == "LocalFile") {
523 // pre irss file
524 if (is_file($this->getDataDirectory() . "/" . $item->getLocation())) {
525 $location = ilWACSignedPath::signFile($this->getDataDirectory() . "/" . $item->getLocation());
526 $location = substr($location, strrpos($location, "/") + 1);
527 } else {
528 if ($offline) {
529 $location = $item->getLocation();
530 } else {
531 $location = $this->manager->getLocalSrc(
532 $this->getId(),
533 $item->getLocation()
534 );
535 }
536 }
537 } else {
538 $location = trim($item->getLocation());
539 // irss
540 if ($item->getLocationType() === "LocalFile" &&
541 !is_file($this->getDataDirectory() . "/" . $item->getLocation())) {
542 $location = $this->manager->getLocalSrc(
543 $this->getId(),
544 $item->getLocation()
545 );
546 }
547 if ($item->getLocationType() != "LocalFile") { //#25941
549 }
550 }
551
552 $xml .= "<Location Type=\"" . $item->getLocationType() . "\">" .
553 $this->handleAmps($location) . "</Location>";
554
555 // Format
556 $xml .= "<Format>" . $item->getFormat() . "</Format>";
557
558 // Layout
559 $width = ($item->getWidth() != "")
560 ? "Width=\"" . $item->getWidth() . "\""
561 : "";
562 $height = ($item->getHeight() != "")
563 ? "Height=\"" . $item->getHeight() . "\""
564 : "";
565 $halign = ($item->getHAlign() != "")
566 ? "HorizontalAlign=\"" . $item->getHAlign() . "\""
567 : "";
568 $xml .= "<Layout $width $height $halign />";
569
570 // Caption
571 if ($item->getCaption() != "") {
572 $xml .= "<Caption Align=\"bottom\">" .
573 $this->escapeProperty($item->getCaption()) . "</Caption>";
574 }
575
576 // Text Representation
577 if ($item->getTextRepresentation() != "") {
578 $xml .= "<TextRepresentation>" .
579 $this->escapeProperty($item->getTextRepresentation()) . "</TextRepresentation>";
580 }
581
582 // Title
583 if ($this->getTitle() != "") {
584 $xml .= "<Title>" .
585 $this->escapeProperty($this->getTitle()) . "</Title>";
586 }
587
588 // Parameter
589 $parameters = $item->getParameters();
590 if ($item->getFormat() === "video/vimeo") {
591 $parameters = ilExternalMediaAnalyzer::extractVimeoParameters($item->getLocation());
592 }
593 foreach ($parameters as $name => $value) {
594 $xml .= "<Parameter Name=\"$name\" Value=\"" . $this->escapeProperty($value) . "\"/>";
595 }
596 $xml .= $item->getMapAreasXML();
597
598 // Subtitles
599 if ($item->getPurpose() == "Standard") {
600 $this->manager->generateMissingVTT($this->getId());
601 $srts = $this->getSrtFiles(true);
602 foreach ($srts as $srt) {
603 $def = "";
604 $meta_lang = "";
605 if ($ilUser->getLanguage() != $meta_lang &&
606 $ilUser->getLanguage() == $srt["language"]) {
607 $def = ' Default="true" ';
608 }
609 $xml .= "<Subtitle File=\"" . $srt["src"] .
610 "\" Language=\"" . $srt["language"] . "\" " . $def . "/>";
611 }
612 }
613 if ($this->getVideoPreviewPic(true)) {
614 $xml .= "<PreviewPic File=\"" . $this->getVideoPreviewPic(true) .
615 "\" />";
616 }
617 if ($item->getLocationType() == "LocalFile") {
618 $lpos = strrpos($location, "/");
619 $base_url = substr($location, 0, $lpos);
620 $xml .= "<Url Base=\"" . $base_url .
621 "\" />";
622 }
623 $xml .= "</MediaItem>";
624 }
625 break;
626
627 // full xml for export
628 case IL_MODE_FULL:
629 $xml = "<MediaObject>";
630
631 // Title and Identifier
632 $xml .= "<Identifier Entry=\"il_" . IL_INST_ID . "_mob_" . $this->getId() . "\"/>";
633 if ($this->getTitle() != "") {
634 $xml .= "<Title>" .
635 $this->escapeProperty($this->getTitle()) . "</Title>";
636 }
637
638 $media_items = $this->getMediaItems();
639 for ($i = 0; $i < count($media_items); $i++) {
640 $item = $media_items[$i];
641
642 // highlight mode
643 $xml .= "<MediaItem Purpose=\"" . $item->getPurpose() . "\">";
644
645 // Location
646 $xml .= "<Location Type=\"" . $item->getLocationType() . "\">" .
647 $this->handleAmps($item->getLocation()) . "</Location>";
648
649 // Format
650 $xml .= "<Format>" . $item->getFormat() . "</Format>";
651
652 // Layout
653 $width = ($item->getWidth() != "")
654 ? "Width=\"" . $item->getWidth() . "\""
655 : "";
656 $height = ($item->getHeight() != "")
657 ? "Height=\"" . $item->getHeight() . "\""
658 : "";
659 $halign = ($item->getHAlign() != "")
660 ? "HorizontalAlign=\"" . $item->getHAlign() . "\""
661 : "";
662 $xml .= "<Layout $width $height $halign />";
663
664 // Caption
665 if ($item->getCaption() != "") {
666 $xml .= "<Caption Align=\"bottom\">" .
667 str_replace("&", "&amp;", $item->getCaption()) . "</Caption>";
668 }
669
670 // Text Representation
671 if ($item->getTextRepresentation() != "") {
672 $xml .= "<TextRepresentation>" .
673 str_replace("&", "&amp;", $item->getTextRepresentation()) . "</TextRepresentation>";
674 }
675
676 // Parameter
677 $parameters = $item->getParameters();
678 foreach ($parameters as $name => $value) {
679 $xml .= "<Parameter Name=\"$name\" Value=\"$value\"/>";
680 }
681 $xml .= $item->getMapAreasXML(true, $a_inst);
682 $xml .= "</MediaItem>";
683 }
684 break;
685 }
686 $xml .= "</MediaObject>";
687 return $xml;
688 }
689
693 protected function escapeProperty(
694 string $a_value
695 ): string {
696 return htmlspecialchars($a_value);
697 }
698
699
703 public function handleAmps(
704 string $a_str
705 ): string {
706 $a_str = str_replace("&amp;", "&", $a_str);
707 $a_str = str_replace("&", "&amp;", $a_str);
708 return $a_str;
709 }
710
711 public function exportXML(
712 ilXmlWriter $a_xml_writer,
713 int $a_inst = 0
714 ): void {
715 $a_xml_writer->appendXML($this->getXML(IL_MODE_FULL, $a_inst));
716 }
717
718
727 public function exportFiles(
728 string $a_target_dir
729 ): void {
730 $subdir = "il_" . IL_INST_ID . "_mob_" . $this->getId();
731 ilFileUtils::makeDir($a_target_dir . "/objects/" . $subdir);
732
733 $mobdir = ilFileUtils::getWebspaceDir() . "/mobs/mm_" . $this->getId();
734 ilFileUtils::rCopy($mobdir, $a_target_dir . "/objects/" . $subdir);
735 }
736
737 public function modifyExportIdentifier(
738 string $a_tag,
739 string $a_param,
740 string $a_value
741 ): string {
742 if ($a_tag == "Identifier" && $a_param == "Entry") {
743 $a_value = ilUtil::insertInstIntoID($a_value);
744 }
745
746 return $a_value;
747 }
748
749
751 // EDIT METHODS: these methods act on the media alias in the dom
753
758 public function setContainsIntLink(
759 bool $a_contains_link
760 ): void {
761 $this->contains_int_link = $a_contains_link;
762 }
763
768 public function containsIntLink(): bool
769 {
770 return $this->contains_int_link;
771 }
772
773 public static function _deleteAllUsages(
774 string $a_type,
775 int $a_id,
776 ?int $a_usage_hist_nr = 0,
777 string $a_lang = "-"
778 ): void {
779 global $DIC;
780
781 $ilDB = $DIC->database();
782
783 $and_hist = "";
784 if (!is_null($a_usage_hist_nr)) {
785 $and_hist = " AND usage_hist_nr = " . $ilDB->quote($a_usage_hist_nr, "integer");
786 }
787
788 $mob_ids = array();
789 $set = $ilDB->query("SELECT id FROM mob_usage" .
790 " WHERE usage_type = " . $ilDB->quote($a_type, "text") .
791 " AND usage_id = " . $ilDB->quote($a_id, "integer") .
792 " AND usage_lang = " . $ilDB->quote($a_lang, "text") .
793 $and_hist);
794 while ($row = $ilDB->fetchAssoc($set)) {
795 $mob_ids[] = $row["id"];
796 }
797
798 $q = "DELETE FROM mob_usage WHERE usage_type = " .
799 $ilDB->quote($a_type, "text") .
800 " AND usage_id= " . $ilDB->quote($a_id, "integer") .
801 " AND usage_lang = " . $ilDB->quote($a_lang, "text") .
802 $and_hist;
803 $ilDB->manipulate($q);
804
805 foreach ($mob_ids as $mob_id) {
806 self::handleQuotaUpdate(new self($mob_id));
807 }
808 }
809
813 public static function _getMobsOfObject(
814 string $a_type,
815 int $a_id,
816 int|false $a_usage_hist_nr = 0,
817 string $a_lang = "-"
818 ): array {
819 global $DIC;
820
821 $ilDB = $DIC->database();
822
823 $lstr = "";
824 if ($a_lang != "") {
825 $lstr = " AND usage_lang = " . $ilDB->quote($a_lang, "text");
826 }
827 $hist_str = "";
828 if ($a_usage_hist_nr !== false) { // see #45933, restore ILIAS 7 behaviour
829 $hist_str = " AND usage_hist_nr = " . $ilDB->quote($a_usage_hist_nr, "integer");
830 }
831
832 $q = "SELECT * FROM mob_usage WHERE " .
833 "usage_type = " . $ilDB->quote($a_type, "text") . " AND " .
834 "usage_id = " . $ilDB->quote($a_id, "integer") .
835 $lstr . $hist_str;
836 $mobs = array();
837 $mob_set = $ilDB->query($q);
838 while ($mob_rec = $ilDB->fetchAssoc($mob_set)) {
839 $mob_id = (int) $mob_rec['id'];
840 if (ilObject::_lookupType($mob_id) === "mob") {
841 $mobs[$mob_id] = $mob_id;
842 }
843 }
844
845 return $mobs;
846 }
847
851 public static function _saveUsage(
852 int $a_mob_id,
853 string $a_type,
854 int $a_id,
855 int $a_usage_hist_nr = 0,
856 string $a_lang = "-"
857 ): void {
858 global $DIC;
859
860 $ilDB = $DIC->database();
861
862 $ilDB->replace(
863 "mob_usage",
864 array(
865 "id" => array("integer", $a_mob_id),
866 "usage_type" => array("text", $a_type),
867 "usage_id" => array("integer", $a_id),
868 "usage_lang" => array("text", $a_lang),
869 "usage_hist_nr" => array("integer", $a_usage_hist_nr)
870 ),
871 array()
872 );
873
874 self::handleQuotaUpdate(new self($a_mob_id));
875 }
876
880 public static function _removeUsage(
881 int $a_mob_id,
882 string $a_type,
883 int $a_id,
884 int $a_usage_hist_nr = 0,
885 string $a_lang = "-"
886 ): void {
887 global $DIC;
888
889 $ilDB = $DIC->database();
890
891 $q = "DELETE FROM mob_usage WHERE " .
892 " id = " . $ilDB->quote($a_mob_id, "integer") . " AND " .
893 " usage_type = " . $ilDB->quote($a_type, "text") . " AND " .
894 " usage_id = " . $ilDB->quote($a_id, "integer") . " AND " .
895 " usage_lang = " . $ilDB->quote($a_lang, "text") . " AND " .
896 " usage_hist_nr = " . $ilDB->quote($a_usage_hist_nr, "integer");
897 $ilDB->manipulate($q);
898
899 self::handleQuotaUpdate(new self($a_mob_id));
900 }
901
905 public function getUsages(
906 bool $a_include_history = true
907 ): array {
908 return self::lookupUsages($this->getId(), $a_include_history);
909 }
910
916 public static function lookupUsages(
917 int $a_id,
918 bool $a_include_history = true
919 ): array {
920 global $DIC;
921
922 $ilDB = $DIC->database();
923
924 $hist_str = "";
925 if ($a_include_history) {
926 $hist_str = ", usage_hist_nr";
927 }
928
929 // get usages in pages
930 $q = "SELECT DISTINCT usage_type, usage_id, usage_lang" . $hist_str . " FROM mob_usage WHERE id = " .
931 $ilDB->quote($a_id, "integer");
932
933 if (!$a_include_history) {
934 $q .= " AND usage_hist_nr = " . $ilDB->quote(0, "integer");
935 }
936
937 $us_set = $ilDB->query($q);
938 $ret = array();
939 while ($us_rec = $ilDB->fetchAssoc($us_set)) {
940 $ut = "";
941 $ct = 0;
942 if (is_int(strpos($us_rec["usage_type"], ":"))) {
943 $us_arr = explode(":", $us_rec["usage_type"]);
944 $ut = $us_arr[1];
945 $ct = $us_arr[0];
946 }
947
948 // check whether page exists
949 $skip = false;
950 if ($ut == "pg") {
951 if (!ilPageObject::_exists($ct, $us_rec["usage_id"])) {
952 $skip = true;
953 }
954 }
955
956 if (!$skip) {
957 $ret[] = array(
958 "type" => $us_rec["usage_type"],
959 "id" => $us_rec["usage_id"],
960 "lang" => $us_rec["usage_lang"],
961 "hist_nr" => ($us_rec["usage_hist_nr"] ?? 0)
962 );
963 }
964 }
965
966 // get usages in media pools
967 $q = "SELECT DISTINCT mep_id FROM mep_tree JOIN mep_item ON (child = obj_id) WHERE mep_item.foreign_id = " .
968 $ilDB->quote($a_id, "integer") . " AND mep_item.type = " . $ilDB->quote("mob", "text");
969 $us_set = $ilDB->query($q);
970 while ($us_rec = $ilDB->fetchAssoc($us_set)) {
971 $ret[] = array("type" => "mep",
972 "id" => $us_rec["mep_id"]);
973 }
974
975 // get usages in news items (media casts)
976 $news_usages = ilNewsItem::_lookupMediaObjectUsages($a_id);
977 foreach ($news_usages as $nu) {
978 $ret[] = $nu;
979 }
980
981
982 // get usages in map areas
983 $q = "SELECT DISTINCT mob_id FROM media_item it, map_area area " .
984 " WHERE area.item_id = it.id " .
985 " AND area.link_type = " . $ilDB->quote("int", "text") . " " .
986 " AND area.target = " . $ilDB->quote("il__mob_" . $a_id, "text");
987 $us_set = $ilDB->query($q);
988 while ($us_rec = $ilDB->fetchAssoc($us_set)) {
989 $ret[] = array("type" => "map",
990 "id" => $us_rec["mob_id"]);
991 }
992
993 // get usages in personal clipboards
994 $users = ilObjUser::_getUsersForClipboadObject("mob", $a_id);
995 foreach ($users as $user) {
996 $ret[] = array("type" => "clip",
997 "id" => $user);
998 }
999
1000 return $ret;
1001 }
1002
1007 public static function getParentObjectIdForUsage(
1008 array $a_usage,
1009 bool $a_include_all_access_obj_ids = false
1010 ): ?int {
1011 $cont_type = "";
1012 if (is_int(strpos($a_usage["type"], ":"))) {
1013 $us_arr = explode(":", $a_usage["type"]);
1014 $type = $us_arr[1];
1015 $cont_type = $us_arr[0];
1016 } else {
1017 $type = $a_usage["type"];
1018 }
1019
1020 $id = $a_usage["id"];
1021 $obj_id = null;
1022
1023 switch ($type) {
1024 // RTE / tiny mce
1025 case "html":
1026
1027 switch ($cont_type) {
1028 case "qpl":
1029 // Question Pool *Question* Text (Test)
1030 global $DIC;
1031 $qinfo = $DIC->testQuestion()->getGeneralQuestionProperties($id);
1032 if ($qinfo->getOriginalId() > 0) {
1033 $obj_id = ilObjTest::_lookupTestObjIdForQuestionId($id); // usage in test
1034 } else {
1035 $obj_id = (int) ($qinfo["obj_fi"] ?? 0); // usage in pool
1036 }
1037 break;
1038
1039 case "spl":
1040 // Question Pool *Question* Text (Survey)
1042 if ($quest) {
1043 $parent_id = $quest->getObjId();
1044
1045 // pool question copy - find survey, do not use pool itself
1046 if ($quest->getOriginalId() &&
1047 ilObject::_lookupType($parent_id) == "spl") {
1049 }
1050 // original question (in pool or survey)
1051 else {
1052 $obj_id = (int) $parent_id;
1053 }
1054
1055 unset($quest);
1056 }
1057 break;
1058
1059 case "exca":
1060 // Exercise assignment
1061 $returned_pk = $a_usage['id'];
1062 // #15995 - we are just checking against exercise object
1063 $obj_id = ilExSubmission::lookupExerciseIdForReturnedId($returned_pk);
1064 break;
1065
1066 case "frm":
1067 // Forum
1068 $post_pk = $a_usage['id'];
1069 $oPost = new ilForumPost($post_pk);
1070 $frm_pk = $oPost->getForumId();
1071 $obj_id = ilForum::_lookupObjIdForForumId($frm_pk);
1072 break;
1073
1074
1075 case "frm~d":
1076 $draft_id = $a_usage['id'];
1077 $oDraft = ilForumPostDraft::newInstanceByDraftId($draft_id);
1078
1079 $frm_pk = $oDraft->getForumId();
1080 $obj_id = ilForum::_lookupObjIdForForumId($frm_pk);
1081 break;
1082 case "frm~h":
1083 $history_id = $a_usage['id'];
1084 $oHistoryDraft = new ilForumDraftsHistory($history_id);
1085 $oDraft = ilForumPostDraft::newInstanceByDraftId($oHistoryDraft->getDraftId());
1086
1087 $frm_pk = $oDraft->getForumId();
1088 $obj_id = ilForum::_lookupObjIdForForumId($frm_pk);
1089 break;
1090 // temporary items (per user)
1091 case "frm~":
1092 case "exca~":
1093 $obj_id = (int) $a_usage['id'];
1094 break;
1095
1096 // "old" category pages
1097 case "cat":
1098 // InfoScreen Text
1099 case "tst":
1100 case "svy":
1101 // data collection
1102 case "dcl":
1103 $obj_id = (int) $id;
1104 break;
1105 }
1106 break;
1107
1108 // page editor
1109 case "pg":
1110
1111 switch ($cont_type) {
1112 // question feedback // parent obj id is q id
1113 case "qfbg":
1114 case "qpl":
1115
1116 if ($cont_type == "qfbg") {
1118 }
1119
1120 // Question Pool Question Pages
1121 global $DIC;
1122 $qinfo = $DIC->testQuestion()->getGeneralQuestionProperties($id);
1123 if ($qinfo->getOriginalId() > 0) {
1124 $obj_id = ilObjTest::_lookupTestObjIdForQuestionId($id); // usage in test
1125 } else {
1126 $obj_id = $qinfo["obj_fi"]; // usage in pool
1127 }
1128 if ($obj_id == 0) { // this is the case, if question is in learning module -> get lm id
1130 if ($pinfo && $pinfo["parent_type"] == "lm") {
1131 $obj_id = ilLMObject::_lookupContObjID($pinfo["page_id"]);
1132 }
1133 }
1134 break;
1135
1136 case "lm":
1137 // learning modules
1139 break;
1140
1141 case "term":
1142 $term_id = $id;
1143 $obj_id = ilGlossaryTerm::_lookGlossaryID($term_id);
1144 break;
1145
1146 case "wpg":
1147 // wiki page
1149 break;
1150
1151 case "sahs":
1152 // sahs page
1153 // can this implementation be used for other content types, too?
1154 $obj_id = ilPageObject::lookupParentId($id, 'sahs');
1155 break;
1156
1157 case "prtf":
1158 // portfolio
1160 break;
1161
1162 case "prtt":
1163 // portfolio template
1165 break;
1166
1167
1168 case "impr":
1169 // imprint page - always id 1
1170 // fallthrough
1171
1172 case "copa":
1173 case "cstr":
1174 $obj_id = $id;
1175 break;
1176
1177 default:
1178 $obj_id = ilPageObject::lookupParentId($id, $cont_type);
1179 break;
1180 }
1181 break;
1182
1183 // Media Pool
1184 case "mep":
1185 $obj_id = $id;
1186 break;
1187
1188 // News Context Object (e.g. MediaCast)
1189 case "news":
1191 break;
1192 }
1193
1194 return $obj_id;
1195 }
1196
1200 public static function _resizeImage(
1201 string $a_file,
1202 int $a_width,
1203 int $a_height,
1204 bool $a_constrain_prop = false
1205 ): string {
1206 global $DIC;
1207 $file_path = pathinfo($a_file);
1208 $location = substr($file_path["basename"], 0, strlen($file_path["basename"]) -
1209 strlen($file_path["extension"]) - 1) . "_" .
1210 $a_width . "_" .
1211 $a_height . "." . $file_path["extension"];
1212 $target_file = $file_path["dirname"] . "/" .
1213 $location;
1214
1215 $returned_target_file = $DIC->fileConverters()
1216 ->legacyImages()
1217 ->resizeToFixedSize(
1218 $a_file,
1219 $target_file,
1220 $a_width,
1221 $a_height,
1222 $a_constrain_prop
1223 );
1224
1225 if ($returned_target_file !== $target_file) {
1226 throw new RuntimeException('Could not resize image');
1227 }
1228
1229 return $location;
1230 }
1231
1235 public static function getMimeType(
1236 string $a_file,
1237 bool $a_external = false
1238 ): string {
1239 $mime = MimeType::lookupMimeType($a_file, MimeType::APPLICATION__OCTET_STREAM, $a_external);
1240 return $mime;
1241 }
1242
1243 public static function _determineWidthHeight(
1244 string $a_format,
1245 string $a_type,
1246 string $a_file,
1247 string $a_reference,
1248 bool $a_constrain_proportions,
1249 bool $a_use_original,
1250 ?int $a_user_width = null,
1251 ?int $a_user_height = null
1252 ): array {
1253 global $DIC;
1254
1255 $lng = $DIC->language();
1256 $size = [];
1257 $wr = 0;
1258 $hr = 0;
1259 $width = 0;
1260 $height = 0;
1261
1262 // determine width and height of known image types
1263 //$width = 640;
1264 //$height = 360;
1265 $info = "";
1266
1267 /*
1268 if ($a_format == "audio/mpeg") {
1269 $width = 300;
1270 $height = 20;
1271 }*/
1272
1273 if (ilUtil::deducibleSize($a_format)) {
1274 if ($a_type == "File") {
1275 $size = ilMediaImageUtil::getImageSize($a_file);
1276 } else {
1277 $size = ilMediaImageUtil::getImageSize($a_reference);
1278 }
1279 }
1280
1281 if (!isset($size[0])) {
1282 $size[0] = 0;
1283 }
1284 if (!isset($size[1])) {
1285 $size[1] = 0;
1286 }
1287
1288 if ($a_use_original) {
1289 if ($size[0] > 0 && $size[1] > 0) {
1290 //$width = $size[0];
1291 //$height = $size[1];
1292 $width = "";
1293 $height = "";
1294 } else {
1295 $info = $lng->txt("cont_could_not_determine_resource_size");
1296 }
1297 } else {
1298 $w = $a_user_width;
1299 $h = $a_user_height;
1300 $width = $w;
1301 $height = $h;
1302 //echo "<br>C-$width-$height-";
1303 if (ilUtil::deducibleSize($a_format) && $a_constrain_proportions) {
1304 if ($size[0] > 0 && $size[1] > 0) {
1305 if ($w > 0) {
1306 $wr = $size[0] / $w;
1307 }
1308 if ($h > 0) {
1309 $hr = $size[1] / $h;
1310 }
1311 //echo "<br>+".$wr."+".$size[0]."+".$w."+";
1312 //echo "<br>+".$hr."+".$size[1]."+".$h."+";
1313 $r = max($wr, $hr);
1314 if ($r > 0) {
1315 $width = (int) round($size[0] / $r);
1316 $height = (int) round($size[1] / $r);
1317 }
1318 }
1319 }
1320 //echo "<br>D-$width-$height-";
1321 }
1322 //echo "<br>E-$width-$height-";
1323
1324 if ($width == 0 && is_null($a_user_width)) {
1325 $width = "";
1326 }
1327 if ($height == 0 && is_null($a_user_height)) {
1328 $height = "";
1329 }
1330 return array("width" => $width, "height" => $height, "info" => $info);
1331 }
1332
1333 public function getDataDirectory(): string
1334 {
1335 return ilFileUtils::getWebspaceDir() . "/mobs/mm_" . $this->getId();
1336 }
1337
1343 public static function _saveTempFileAsMediaObject(
1344 string $name,
1345 string $tmp_name,
1346 bool $upload = true
1347 ): ilObjMediaObject {
1348 // create dummy object in db (we need an id)
1349 $media_object = new ilObjMediaObject();
1350 $media_object->setTitle($name);
1351 $media_object->setDescription("");
1352 $media_object->create();
1353
1354 // determine and create mob directory, move uploaded file to directory
1355 $media_object->createDirectory();
1356 $mob_dir = ilObjMediaObject::_getDirectory($media_object->getId());
1357
1358 $file = $mob_dir . "/" . $name;
1359 if ($upload) {
1360 $media_item = $media_object->addMediaItemFromLegacyUpload(
1361 "Standard",
1362 $tmp_name,
1363 $name,
1364 0,
1365 0,
1366 true,
1367 true
1368 );
1369 } else {
1370 $media_item = $media_object->addMediaItemFromLocalFile(
1371 "Standard",
1372 $tmp_name,
1373 $name
1374 );
1375 /*
1376 $media_item = new ilMediaItem();
1377 $media_object->addMediaItem($media_item);
1378 $media_item->setPurpose("Standard");
1379
1380 copy($tmp_name, $file);
1381 // get mime type
1382 $format = ilObjMediaObject::getMimeType($file);
1383 $media_item->setFormat($format);
1384 $location = $name;
1385 $media_item->setLocation($location);
1386 $media_item->setLocationType("LocalFile");*/
1387 }
1388
1389 // set real meta and object data
1390 $media_object->setTitle($name);
1391 $media_object->setDescription($media_item->getFormat());
1392 $media_item->setHAlign("Left");
1393
1394 /*
1395 self::renameExecutables($mob_dir);
1396 ilMediaSvgSanitizer::sanitizeDir($mob_dir); // see #20339
1397 */
1398
1399 $media_object->update();
1400
1401 return $media_object;
1402 }
1403
1405 string $purpose,
1406 string $tmp_name,
1407 string $name,
1408 int $resize_width = 0,
1409 int $resize_height = 0,
1410 bool $constrain_proportions = true,
1411 bool $deduce_size = false
1412 ): \ilMediaItem {
1413 $media_item = new ilMediaItem();
1414 $this->addMediaItem($media_item);
1415 $media_item->setPurpose($purpose);
1416 //$location = self::fixFilename($_FILES[$upload_name]['name']);
1417 $location = $name;
1418 $this->manager->addFileFromLegacyUpload($this->getId(), $tmp_name);
1419
1420 // get mime type
1421 $format = self::getMimeType($location, true);
1422
1423 // resize standard images
1424 if ($resize_width > 0 && $resize_height > 0 && is_int(strpos($format, "image"))) {
1425 /*
1426 $location = ilObjMediaObject::_resizeImage(
1427 $file,
1428 $resize_width,
1429 $resize_height,
1430 $constrain_proportions
1431 );*/
1432 }
1433
1434 if ($deduce_size) {
1435 /*
1436 if (ilUtil::deducibleSize($format)) {
1437 $size = ilMediaImageUtil::getImageSize($file);
1438 $media_item->setWidth($size[0]);
1439 $media_item->setHeight($size[1]);
1440 }*/
1441 }
1442
1443 // set real meta and object data
1444 $media_item->setFormat($format);
1445 $media_item->setLocation($location);
1446 $media_item->setLocationType("LocalFile");
1447 if ($purpose === "Standard") {
1448 $this->generatePreviewPic(320, 240);
1449 }
1450 return $media_item;
1451 }
1452
1453 public function addMediaItemFromUpload(
1454 string $purpose,
1455 UploadResult $result,
1456 string $upload_hash = "",
1457 ): \ilMediaItem {
1458 $media_item = new ilMediaItem();
1459 $this->addMediaItem($media_item);
1460 $media_item->setPurpose($purpose);
1461 $this->manager->addFileFromUpload($this->getId(), $result);
1462
1463 // get mime type
1464 $format = self::getMimeType($result->getName(), true);
1465
1466 // set real meta and object data
1467 $media_item->setFormat($format);
1468 $media_item->setLocation($result->getName());
1469 $media_item->setLocationType("LocalFile");
1470 if ($upload_hash !== "") {
1471 $media_item->setUploadHash($upload_hash);
1472 }
1473 if ($purpose === "Standard") {
1474 $this->generatePreviewPic(320, 240);
1475 }
1476 return $media_item;
1477 }
1478
1480 string $purpose,
1481 string $tmp_name,
1482 string $name
1483 ): \ilMediaItem {
1484 $media_item = new ilMediaItem();
1485 $this->addMediaItem($media_item);
1486 $media_item->setPurpose($purpose);
1487 $location = $name;
1488 $this->manager->addFileFromLocal($this->getId(), $tmp_name, $name);
1489
1490 // get mime type
1491 $format = self::getMimeType($location, true);
1492
1493 // set real meta and object data
1494 $media_item->setFormat($format);
1495 $media_item->setLocation($location);
1496 $media_item->setLocationType("LocalFile");
1497 if ($purpose === "Standard") {
1498 $this->generatePreviewPic(320, 240);
1499 }
1500 return $media_item;
1501 }
1502
1504 string $purpose,
1505 UploadResult $result,
1506 string $upload_hash = "",
1507 ): \ilMediaItem {
1508 $media_item = $this->getMediaItem($purpose);
1509 $this->manager->removeLocation($this->getId(), $media_item->getLocation());
1510 $this->manager->addFileFromUpload($this->getId(), $result);
1511
1512 // get mime type
1513 $format = self::getMimeType($result->getName(), true);
1514
1515 // set real meta and object data
1516 $media_item->setFormat($format);
1517 $media_item->setLocation($result->getName());
1518 $media_item->setLocationType("LocalFile");
1519 if ($upload_hash !== "") {
1520 $media_item->setUploadHash($upload_hash);
1521 }
1522 if ($purpose === "Standard") {
1523 $this->generatePreviewPic(320, 240);
1524 }
1525 return $media_item;
1526 }
1527
1531 public function uploadAdditionalFile(
1532 string $a_name,
1533 string $tmp_name,
1534 string $a_subdir = "",
1535 string $a_mode = "move_uploaded"
1536 ): void {
1537 $a_subdir = str_replace("..", "", $a_subdir);
1538 if ($a_mode == "rename") {
1539 $this->manager->addFileFromLocal(
1540 $this->getId(),
1541 $tmp_name,
1542 $a_subdir . "/" . $a_name
1543 );
1544 } else {
1545 $this->manager->addFileFromLegacyUpload(
1546 $this->getId(),
1547 $tmp_name,
1548 $a_subdir . "/" . $a_name
1549 );
1550 }
1551 }
1552
1554 UploadResult $result,
1555 string $subdir
1556 ): void {
1557 $this->manager->addFileFromUpload(
1558 $this->getId(),
1559 $result,
1560 $subdir
1561 );
1562 }
1563
1564 public function uploadSrtFile(
1565 string $a_tmp_name,
1566 string $a_language,
1567 string $a_mode = "move_uploaded"
1568 ): bool {
1569 if (is_file($a_tmp_name) && $a_language != "") {
1570 $this->uploadAdditionalFile("subtitle_" . $a_language . ".vtt", $a_tmp_name, "srt", $a_mode);
1571 return true;
1572 }
1573 return false;
1574 }
1575
1576 public function getSrtFiles(bool $vtt_only = false): array
1577 {
1578 return $this->manager->getSrtFiles($this->getId(), $vtt_only);
1579 }
1580
1584 public function makeThumbnail(
1585 string $source,
1586 string $thumbname,
1587 ): void {
1588 $format = self::getMimeType($source, true);
1589 $this->thumbs->createPreview(
1590 $this->getId(),
1591 $source,
1592 true,
1593 $format,
1594 1,
1595 $thumbname
1596 );
1597 }
1598
1599 public function removeAdditionalFile(
1600 string $a_file
1601 ): void {
1602 $this->manager->removeLocation(
1603 $this->getId(),
1604 $a_file
1605 );
1606 }
1607
1608
1613 public function getLinkedMediaObjects(
1614 array $a_ignore = []
1615 ): array {
1616 $linked = array();
1617
1618 // get linked media objects (map areas)
1619 $med_items = $this->getMediaItems();
1620
1621 foreach ($med_items as $med_item) {
1622 $int_links = ilMapArea::_getIntLinks($med_item->getId());
1623 foreach ($int_links as $k => $int_link) {
1624 if ($int_link["Type"] == "MediaObject") {
1625 $l_id = ilInternalLink::_extractObjIdOfTarget($int_link["Target"]);
1626 if (ilObject::_exists($l_id)) {
1627 if (!in_array($l_id, $linked) &&
1628 !in_array($l_id, $a_ignore)) {
1629 $linked[] = $l_id;
1630 }
1631 }
1632 }
1633 }
1634 }
1635 //var_dump($linked);
1636 return $linked;
1637 }
1638
1639 public static function isTypeAllowed(
1640 string $a_type
1641 ): bool {
1642 global $DIC;
1643 return in_array($a_type, iterator_to_array(
1644 $DIC->mediaObjects()->internal()->domain()->mediaType()->getAllowedSuffixes()
1645 ), true);
1646 }
1647
1651 public function duplicate(): ilObjMediaObject
1652 {
1653 $new_obj = new ilObjMediaObject();
1654 $new_obj->setTitle($this->getTitle());
1655 $new_obj->setDescription($this->getDescription());
1656
1657 // media items
1658 foreach ($this->getMediaItems() as $key => $val) {
1659 $new_obj->addMediaItem($val);
1660 }
1661
1662 $new_obj->create(
1663 false,
1664 true,
1665 $this->getId() // "from" id
1666 );
1667
1668 // meta data
1669 $this->domain->metadata()->learningObjectMetadata()
1670 ->derive()
1671 ->fromObject(0, $this->getId(), "mob")
1672 ->forObject(0, $new_obj->getId(), "mob");
1673
1674 return $new_obj;
1675 }
1676
1677 public function uploadVideoPreviewPic(
1678 array $a_prevpic
1679 ): void {
1680 // remove old one
1681 if ($this->getVideoPreviewPic(true) != "") {
1682 $this->removeAdditionalFile($this->getVideoPreviewPic(true));
1683 }
1684
1685 $pi = pathinfo($a_prevpic["name"]);
1686 $ext = $pi["extension"];
1687 if (in_array($ext, array("jpg", "jpeg", "png"))) {
1688 $this->uploadAdditionalFile("mob_vpreview." . $ext, $a_prevpic["tmp_name"]);
1689 }
1690 }
1691
1692 public function generatePreviewPic(
1693 int $a_width,
1694 int $a_height,
1695 int $sec = 1
1696 ): void {
1698 $logger = $GLOBALS['DIC']->logger()->mob();
1699
1700 $item = $this->getMediaItem("Standard");
1701 if ($item->getFormat() === "image/svg+xml") {
1702 return;
1703 }
1704
1705 $logger->debug("Generate preview pic...");
1706 $logger->debug("..." . $item->getFormat());
1707
1708 $this->thumbs->createPreview(
1709 $this->getId(),
1710 $item->getLocation(),
1711 $item->getLocationType() === "LocalFile",
1712 $item->getFormat(),
1713 $sec
1714 );
1715 }
1716
1717 public function getVideoPreviewPic(
1718 bool $a_filename_only = false
1719 ): string {
1720
1721 if (!$a_filename_only) {
1722 $src = $this->thumbs->getPreviewSrc($this->getId());
1723 if ($src !== "") {
1724 return $src;
1725 }
1726 }
1727
1728 $dir = ilObjMediaObject::_getDirectory($this->getId());
1729 $ppics = array("mob_vpreview.jpg",
1730 "mob_vpreview.jpeg",
1731 "mob_vpreview.png");
1732 $med = $this->getMediaItem("Standard");
1733 if ($med && $med->getFormat() === "image/svg+xml" && $med->getLocationType() === "LocalFile") {
1734 $ppics[] = $med->getLocation();
1735 }
1736 foreach ($ppics as $p) {
1737 if (is_file($dir . "/" . $p)) {
1738 if ($a_filename_only) {
1739 return $p;
1740 } else {
1741 return $dir . "/" . $p;
1742 }
1743 }
1744 }
1745 return "";
1746 }
1747
1751 public static function fixFilename(
1752 string $a_name
1753 ): string {
1754 $a_name = ilFileUtils::getASCIIFilename($a_name);
1755
1756 $rchars = array("`", "=", "$", "{", "}", "'", ";", " ", "(", ")");
1757 $a_name = str_replace($rchars, "_", $a_name);
1758 $a_name = str_replace("__", "_", $a_name);
1759 return $a_name;
1760 }
1761
1762
1766 public function getMultiSrtUploadDir(): string
1767 {
1768 return ilObjMediaObject::_getDirectory($this->getId()) . "/srt/tmp";
1769 }
1770
1771
1776 array $a_file
1777 ): void {
1778 $lng = $this->lng;
1779
1780 if (!is_file($a_file["tmp_name"])) {
1781 throw new ilMediaObjectsException($lng->txt("mob_file_could_not_be_uploaded"));
1782 }
1783
1784 $dir = $this->getMultiSrtUploadDir();
1785 ilFileUtils::delDir($dir, true);
1787 ilFileUtils::moveUploadedFile($a_file["tmp_name"], "multi_vtt.zip", $dir . "/" . "multi_vtt.zip");
1788 $this->domain->resources()->zip()->unzipFile($dir . "/multi_vtt.zip");
1789 }
1790
1794 public function clearMultiSrtDirectory(): void
1795 {
1796 ilFileUtils::delDir($this->getMultiSrtUploadDir());
1797 }
1798
1802 public function getMultiSrtFiles(): array
1803 {
1804 $items = array();
1805
1806 $lang_codes = $this->domain->metadata()->getLOMLanguageCodes();
1807
1808 $dir = $this->getMultiSrtUploadDir();
1809 $files = ilFileUtils::getDir($dir);
1810 foreach ($files as $k => $i) {
1811 // check directory
1812 if ($i["type"] == "file" && !in_array($k, array(".", ".."))) {
1813 if (pathinfo($k, PATHINFO_EXTENSION) == "vtt") {
1814 $lang = "";
1815 if (substr($k, strlen($k) - 7, 1) == "_") {
1816 $lang = substr($k, strlen($k) - 6, 2);
1817 if (!in_array($lang, $lang_codes)) {
1818 $lang = "";
1819 }
1820 }
1821 $items[] = array("filename" => $k, "lang" => $lang);
1822 }
1823 }
1824 }
1825 return $items;
1826 }
1827
1828 public static function renameExecutables(
1829 string $a_dir
1830 ): void {
1831 ilFileUtils::renameExecutables($a_dir);
1832 if (!self::isTypeAllowed("html")) {
1833 ilFileUtils::rRenameSuffix($a_dir, "html", "sec"); // see #20187
1834 }
1835 }
1836
1837 public function getExternalMetadata(): void
1838 {
1839 // see https://oembed.com/
1840 $st_item = $this->getMediaItem("Standard");
1841 if ($st_item->getLocationType() == "Reference") {
1842 if (ilExternalMediaAnalyzer::isVimeo($st_item->getLocation())) {
1843 $st_item->setFormat("video/vimeo");
1844 $par = ilExternalMediaAnalyzer::extractVimeoParameters($st_item->getLocation());
1846 $this->setTitle($meta["title"] ?? "");
1847 $description = str_replace("\n", "", $meta["description"] ?? "");
1848 $description = str_replace(["<br>", "<br />"], ["\n", "\n"], $description);
1849 $description = strip_tags($description);
1850 $this->setDescription($description);
1851 $st_item->setDuration((int) ($meta["duration"] ?? 0));
1852 $url = parse_url($meta["thumbnail_url"] ?? "");
1853 $file = basename($url["path"]);
1854 $ext = pathinfo($file, PATHINFO_EXTENSION);
1855 if ($ext == "") {
1856 $ext = "jpg";
1857 }
1858 $this->manager->addPreviewFromUrl(
1859 $this->getId(),
1860 $meta["thumbnail_url"],
1861 "/mob_vpreview." . $ext
1862 );
1863 }
1864 if (ilExternalMediaAnalyzer::isYoutube($st_item->getLocation())) {
1865 $st_item->setFormat("video/youtube");
1866 $par = ilExternalMediaAnalyzer::extractYoutubeParameters($st_item->getLocation());
1867 try {
1869 $this->setTitle($meta["title"] ?? "");
1870 $description = str_replace("\n", "", $meta["description"] ?? "");
1871 } catch (Exception $e) {
1872 $this->setTitle($st_item->getLocation());
1873 $description = "";
1874 }
1875 $description = str_replace(["<br>", "<br />"], ["\n", "\n"], $description);
1876 $description = strip_tags($description);
1877 $this->setDescription($description);
1878 $st_item->setDuration((int) ($meta["duration"] ?? 0));
1879 $thumbnail_url = $meta["thumbnail_url"] ?? "";
1880 $url = parse_url($thumbnail_url);
1881 if ($thumbnail_url !== "") {
1882 $mob_logger = ilLoggerFactory::getLogger('mob');
1883 $file = basename($url["path"]);
1884 $this->manager->addPreviewFromUrl(
1885 $this->getId(),
1886 $meta["thumbnail_url"],
1887 "/mob_vpreview." .
1888 pathinfo($file, PATHINFO_EXTENSION)
1889 );
1890 }
1891 }
1892 }
1893 }
1894
1895 public function getStandardSrc(): string
1896 {
1897 return $this->getLocationSrc("Standard");
1898 }
1899
1900 public function getFullscreenSrc(): string
1901 {
1902 return $this->getLocationSrc("Fullscreen");
1903 }
1904
1905 protected function getLocationSrc(string $purpose): string
1906 {
1907 return (string) $this->getMediaItem($purpose)?->getLocationSrc();
1908 }
1909}
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins
Definition: plugin.php:23
$location
Definition: buildRTE.php:22
Mime type determination.
Definition: MimeType.php:30
static _lookupSurveyObjId(int $a_question_id)
static _instanciateQuestion(int $question_id)
Get question object.
return true
const IL_MODE_ALIAS
const IL_MODE_OUTPUT
const IL_MODE_FULL
static lookupExerciseIdForReturnedId(int $a_returned_id)
Get exercise from submission id (used in ilObjMediaObject)
static isVimeo(string $a_location)
Identify Vimeo links.
static extractVimeoParameters(string $a_location)
Extract Vimeo Parameter.
Class ilFileUtils.
static makeDirParents(string $a_dir)
Create a new directory and all parent directories.
static getWebspaceDir(string $mode="filesystem")
get webspace directory
static getDir(string $a_dir, bool $a_rec=false, ?string $a_sub_dir="")
get directory
static makeDir(string $a_dir)
creates a new directory and inherits all filesystem permissions of the parent directory You may pass ...
static delDir(string $a_dir, bool $a_clean_only=false)
removes a dir and all its content (subdirs and files) recursively
static rRenameSuffix(string $a_dir, string $a_old_suffix, string $a_new_suffix)
Renames all files with certain suffix and gives them a new suffix.
static moveUploadedFile(string $a_file, string $a_name, string $a_target, bool $a_raise_errors=true, string $a_mode="move_uploaded")
move uploaded file
static rCopy(string $a_sdir, string $a_tdir, bool $preserveTimeAttributes=false)
Copies content of a directory $a_sdir recursively to a directory $a_tdir.
Class ilForumDraftHistory.
static newInstanceByDraftId(int $draft_id)
static _lookupObjIdForForumId(int $a_for_id)
static _lookGlossaryID(int $term_id)
get glossary id form term id
static _lookupContObjID(int $a_id)
get learning module id for lm object
static getLogger(string $a_component_id)
Get component logger.
static _getIntLinks(int $a_item_id)
get all internal links of a media items map areas
static getImageSize(string $a_location)
Get image size from location.
Class ilMediaItem Media Item, component of a media object (file or reference)
static _getMediaItemsOfMOb(ilObjMediaObject $a_mob)
Read media items into(!) media object (static)
static deleteAllItemsOfMob(int $a_mob_id)
static _lookupLocationForMobId(int $a_mob_id, string $a_purpose)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static _lookupMediaObjectUsages(int $a_mob_id)
Lookup media object usage(s)
static _lookupContextObjId(int $a_news_id)
Context Object ID.
replaceMediaItemFromUpload(string $purpose, UploadResult $result, string $upload_hash="",)
static getParentObjectIdForUsage(array $a_usage, bool $a_include_all_access_obj_ids=false)
Get's the repository object ID of a parent object, if possible see ilWebAccessChecker.
getSrtFiles(bool $vtt_only=false)
escapeProperty(string $a_value)
Escape property (e.g.
static _exists(int $id, bool $reference=false, ?string $type=null)
checks if an object exists in object_data
getMultiSrtFiles()
Get all srt files of srt multi upload.
MediaObjectManager $manager
exportFiles(string $a_target_dir)
export all media files of object to target directory note: target directory must be the export target...
makeThumbnail(string $source, string $thumbname,)
Make thumbnail.
modifyExportIdentifier(string $a_tag, string $a_param, string $a_value)
static _resizeImage(string $a_file, int $a_width, int $a_height, bool $a_constrain_prop=false)
Resize image and return new image file ("_width_height" string appended)
static isTypeAllowed(string $a_type)
getMultiSrtUploadDir()
Get directory for multi srt upload.
static _getURL(int $a_mob_id)
get directory for files of media object
getVideoPreviewPic(bool $a_filename_only=false)
getLocationSrc(string $purpose)
static handleQuotaUpdate(ilObjMediaObject $a_mob)
containsIntLink()
returns true, if mob was marked as containing an intern link (via setContainsIntLink) (this method sh...
static _determineWidthHeight(string $a_format, string $a_type, string $a_file, string $a_reference, bool $a_constrain_proportions, bool $a_use_original, ?int $a_user_width=null, ?int $a_user_height=null)
static _saveTempFileAsMediaObject(string $name, string $tmp_name, bool $upload=true)
getXML(int $a_mode=IL_MODE_FULL, int $a_inst=0, bool $a_sign_locals=false, bool $offline=false)
get MediaObject XLM Tag
getMediaItem(string $a_purpose)
get item for media purpose
static lookupUsages(int $a_id, bool $a_include_history=true)
Lookup usages of media object.
addAdditionalFileFromUpload(UploadResult $result, string $subdir)
static _removeUsage(int $a_mob_id, string $a_type, int $a_id, int $a_usage_hist_nr=0, string $a_lang="-")
Remove usage of mob in another container.
uploadAdditionalFile(string $a_name, string $tmp_name, string $a_subdir="", string $a_mode="move_uploaded")
Create new media object and update page in db and return new media object.
clearMultiSrtDirectory()
Clear multi srt directory.
duplicate()
Duplicate media object, return new media object.
static fixFilename(string $a_name)
Fix filename of uploaded file.
static getMimeType(string $a_file, bool $a_external=false)
get mime type for file
handleAmps(string $a_str)
Replace "&" (if not an "&") with "&".
static _lookupItemPath(int $a_mob_id, bool $a_url_encode=false, bool $a_web=true, string $a_purpose="")
Get path for item with specific purpose.
uploadSrtFile(string $a_tmp_name, string $a_language, string $a_mode="move_uploaded")
createDirectory()
Create file directory of media object.
beforeMDUpdateListener(string $a_element)
static renameExecutables(string $a_dir)
setAlias(bool $a_is_alias)
addMediaItem(ilMediaItem $a_item)
addMediaItemFromUpload(string $purpose, UploadResult $result, string $upload_hash="",)
exportXML(ilXmlWriter $a_xml_writer, int $a_inst=0)
hasPurposeItem(string $purpose)
returns whether object has media item with specific purpose
uploadVideoPreviewPic(array $a_prevpic)
addMediaItemFromLegacyUpload(string $purpose, string $tmp_name, string $name, int $resize_width=0, int $resize_height=0, bool $constrain_proportions=true, bool $deduce_size=false)
removeMediaItem(string $a_purpose)
static _getRelativeDirectory(int $a_mob_id)
Get relative (to webspace dir) directory.
create(bool $a_create_meta_data=false, bool $a_save_media_items=true, int $from_mob_id=0)
removeAdditionalFile(string $a_file)
uploadMultipleSubtitleFile(array $a_file)
Upload multi srt file.
static _getDirectory(int $a_mob_id)
Get absolute directory.
getFilesOfDirectory(string $dir_path="")
getLinkedMediaObjects(array $a_ignore=[])
Get all media objects linked in map areas of this media object.
getUsages(bool $a_include_history=true)
get all usages of current media object
addMediaItemFromLocalFile(string $purpose, string $tmp_name, string $name)
static _deleteAllUsages(string $a_type, int $a_id, ?int $a_usage_hist_nr=0, string $a_lang="-")
setContainsIntLink(bool $a_contains_link)
content parser set this flag to true, if the media object contains internal links (this method should...
static _saveUsage(int $a_mob_id, string $a_type, int $a_id, int $a_usage_hist_nr=0, string $a_lang="-")
Save usage of mob within another container (e.g.
InternalDomainService $domain
update(bool $a_upload=false)
static _getMobsOfObject(string $a_type, int $a_id, int|false $a_usage_hist_nr=0, string $a_lang="-")
static _lookupTestObjIdForQuestionId(int $q_id)
Get test Object ID for question ID.
User class.
static _getUsersForClipboadObject(string $a_type, int $a_id)
Class ilObject Basic functions for all objects.
static _lookupType(int $id, bool $reference=false)
static _writeDescription(int $obj_id, string $desc)
write description to db (static)
static _writeTitle(int $obj_id, string $title)
write title to db (static)
setTitle(string $title)
static _exists(int $id, bool $reference=false, ?string $type=null)
checks if an object exists in object_data
string $type
static _getPageForQuestionId(int $a_q_id, string $a_parent_type="")
static _exists(string $a_parent_type, int $a_id, string $a_lang="", bool $a_no_cache=false)
Checks whether page exists.
static lookupParentId(int $a_id, string $a_type)
static findPortfolioForPage(int $a_page_id)
Get portfolio id of page id.
Util class various functions, usage as namespace.
static deducibleSize(string $a_mime)
checks if mime type is provided by getimagesize()
static secureUrl(string $url)
static insertInstIntoID(string $a_value)
inserts installation id into ILIAS id
static signFile(string $path_to_file)
static lookupObjIdByPage(int $a_page_id)
returns the wiki/object id to a given page id
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
const CLIENT_ID
Definition: constants.php:41
const IL_INST_ID
Definition: constants.php:40
return['delivery_method'=> 'php',]
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
$info
Definition: entry_point.php:21
Interface Location.
Definition: Location.php:33
$path
Definition: ltiservices.php:30
__construct(Container $dic, ilPlugin $plugin)
@inheritDoc
global $lng
Definition: privfeed.php:31
if(!file_exists('../ilias.ini.php'))
global $DIC
Definition: shib_login.php:26
$q
Definition: shib_logout.php:23
$url
Definition: shib_logout.php:68
$GLOBALS["DIC"]
Definition: wac.php:54