ILIAS  trunk Revision v12.0_alpha-1221-g4e438232683
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 $src = $offline
610 ? "mobs/mm_" . $this->getId() . $srt["full_path"]
611 : $srt["src"];
612 $xml .= "<Subtitle File=\"" . $src .
613 "\" Language=\"" . $srt["language"] . "\" " . $def . "/>";
614 }
615 }
616 if ($this->getVideoPreviewPic(false)) {
617 $xml .= "<PreviewPic File=\"" . $this->handleAmps($this->getVideoPreviewPic(false)) .
618 "\" />";
619 }
620 if ($item->getLocationType() == "LocalFile") {
621 $lpos = strrpos($location, "/");
622 $base_url = substr($location, 0, $lpos);
623 $xml .= "<Url Base=\"" . $base_url .
624 "\" />";
625 }
626 $xml .= "</MediaItem>";
627 }
628 break;
629
630 // full xml for export
631 case IL_MODE_FULL:
632 $xml = "<MediaObject>";
633
634 // Title and Identifier
635 $xml .= "<Identifier Entry=\"il_" . IL_INST_ID . "_mob_" . $this->getId() . "\"/>";
636 if ($this->getTitle() != "") {
637 $xml .= "<Title>" .
638 $this->escapeProperty($this->getTitle()) . "</Title>";
639 }
640
641 $media_items = $this->getMediaItems();
642 for ($i = 0; $i < count($media_items); $i++) {
643 $item = $media_items[$i];
644
645 // highlight mode
646 $xml .= "<MediaItem Purpose=\"" . $item->getPurpose() . "\">";
647
648 // Location
649 $xml .= "<Location Type=\"" . $item->getLocationType() . "\">" .
650 $this->handleAmps($item->getLocation()) . "</Location>";
651
652 // Format
653 $xml .= "<Format>" . $item->getFormat() . "</Format>";
654
655 // Layout
656 $width = ($item->getWidth() != "")
657 ? "Width=\"" . $item->getWidth() . "\""
658 : "";
659 $height = ($item->getHeight() != "")
660 ? "Height=\"" . $item->getHeight() . "\""
661 : "";
662 $halign = ($item->getHAlign() != "")
663 ? "HorizontalAlign=\"" . $item->getHAlign() . "\""
664 : "";
665 $xml .= "<Layout $width $height $halign />";
666
667 // Caption
668 if ($item->getCaption() != "") {
669 $xml .= "<Caption Align=\"bottom\">" .
670 str_replace("&", "&amp;", $item->getCaption()) . "</Caption>";
671 }
672
673 // Text Representation
674 if ($item->getTextRepresentation() != "") {
675 $xml .= "<TextRepresentation>" .
676 str_replace("&", "&amp;", $item->getTextRepresentation()) . "</TextRepresentation>";
677 }
678
679 // Parameter
680 $parameters = $item->getParameters();
681 foreach ($parameters as $name => $value) {
682 $xml .= "<Parameter Name=\"$name\" Value=\"$value\"/>";
683 }
684 $xml .= $item->getMapAreasXML(true, $a_inst);
685 $xml .= "</MediaItem>";
686 }
687 break;
688 }
689 $xml .= "</MediaObject>";
690 return $xml;
691 }
692
696 protected function escapeProperty(
697 string $a_value
698 ): string {
699 return htmlspecialchars($a_value);
700 }
701
702
706 public function handleAmps(
707 string $a_str
708 ): string {
709 $a_str = str_replace("&amp;", "&", $a_str);
710 $a_str = str_replace("&", "&amp;", $a_str);
711 return $a_str;
712 }
713
714 public function exportXML(
715 ilXmlWriter $a_xml_writer,
716 int $a_inst = 0
717 ): void {
718 $a_xml_writer->appendXML($this->getXML(IL_MODE_FULL, $a_inst));
719 }
720
721
730 public function exportFiles(
731 string $a_target_dir
732 ): void {
733 $subdir = "il_" . IL_INST_ID . "_mob_" . $this->getId();
734 ilFileUtils::makeDir($a_target_dir . "/objects/" . $subdir);
735
736 $mobdir = ilFileUtils::getWebspaceDir() . "/mobs/mm_" . $this->getId();
737 ilFileUtils::rCopy($mobdir, $a_target_dir . "/objects/" . $subdir);
738 }
739
740 public function modifyExportIdentifier(
741 string $a_tag,
742 string $a_param,
743 string $a_value
744 ): string {
745 if ($a_tag == "Identifier" && $a_param == "Entry") {
746 $a_value = ilUtil::insertInstIntoID($a_value);
747 }
748
749 return $a_value;
750 }
751
752
754 // EDIT METHODS: these methods act on the media alias in the dom
756
761 public function setContainsIntLink(
762 bool $a_contains_link
763 ): void {
764 $this->contains_int_link = $a_contains_link;
765 }
766
771 public function containsIntLink(): bool
772 {
773 return $this->contains_int_link;
774 }
775
776 public static function _deleteAllUsages(
777 string $a_type,
778 int $a_id,
779 ?int $a_usage_hist_nr = 0,
780 string $a_lang = "-"
781 ): void {
782 global $DIC;
783
784 $ilDB = $DIC->database();
785
786 $and_hist = "";
787 if (!is_null($a_usage_hist_nr)) {
788 $and_hist = " AND usage_hist_nr = " . $ilDB->quote($a_usage_hist_nr, "integer");
789 }
790
791 $mob_ids = array();
792 $set = $ilDB->query("SELECT id FROM mob_usage" .
793 " WHERE usage_type = " . $ilDB->quote($a_type, "text") .
794 " AND usage_id = " . $ilDB->quote($a_id, "integer") .
795 " AND usage_lang = " . $ilDB->quote($a_lang, "text") .
796 $and_hist);
797 while ($row = $ilDB->fetchAssoc($set)) {
798 $mob_ids[] = $row["id"];
799 }
800
801 $q = "DELETE FROM mob_usage WHERE usage_type = " .
802 $ilDB->quote($a_type, "text") .
803 " AND usage_id= " . $ilDB->quote($a_id, "integer") .
804 " AND usage_lang = " . $ilDB->quote($a_lang, "text") .
805 $and_hist;
806 $ilDB->manipulate($q);
807
808 foreach ($mob_ids as $mob_id) {
809 self::handleQuotaUpdate(new self($mob_id));
810 }
811 }
812
816 public static function _getMobsOfObject(
817 string $a_type,
818 int $a_id,
819 int|false $a_usage_hist_nr = 0,
820 string $a_lang = "-"
821 ): array {
822 global $DIC;
823
824 $ilDB = $DIC->database();
825
826 $lstr = "";
827 if ($a_lang != "") {
828 $lstr = " AND usage_lang = " . $ilDB->quote($a_lang, "text");
829 }
830 $hist_str = "";
831 if ($a_usage_hist_nr !== false) { // see #45933, restore ILIAS 7 behaviour
832 $hist_str = " AND usage_hist_nr = " . $ilDB->quote($a_usage_hist_nr, "integer");
833 }
834
835 $q = "SELECT * FROM mob_usage WHERE " .
836 "usage_type = " . $ilDB->quote($a_type, "text") . " AND " .
837 "usage_id = " . $ilDB->quote($a_id, "integer") .
838 $lstr . $hist_str;
839 $mobs = array();
840 $mob_set = $ilDB->query($q);
841 while ($mob_rec = $ilDB->fetchAssoc($mob_set)) {
842 $mob_id = (int) $mob_rec['id'];
843 if (ilObject::_lookupType($mob_id) === "mob") {
844 $mobs[$mob_id] = $mob_id;
845 }
846 }
847
848 return $mobs;
849 }
850
854 public static function _saveUsage(
855 int $a_mob_id,
856 string $a_type,
857 int $a_id,
858 int $a_usage_hist_nr = 0,
859 string $a_lang = "-"
860 ): void {
861 global $DIC;
862
863 $ilDB = $DIC->database();
864
865 $ilDB->replace(
866 "mob_usage",
867 array(
868 "id" => array("integer", $a_mob_id),
869 "usage_type" => array("text", $a_type),
870 "usage_id" => array("integer", $a_id),
871 "usage_lang" => array("text", $a_lang),
872 "usage_hist_nr" => array("integer", $a_usage_hist_nr)
873 ),
874 array()
875 );
876
877 self::handleQuotaUpdate(new self($a_mob_id));
878 }
879
883 public static function _removeUsage(
884 int $a_mob_id,
885 string $a_type,
886 int $a_id,
887 int $a_usage_hist_nr = 0,
888 string $a_lang = "-"
889 ): void {
890 global $DIC;
891
892 $ilDB = $DIC->database();
893
894 $q = "DELETE FROM mob_usage WHERE " .
895 " id = " . $ilDB->quote($a_mob_id, "integer") . " AND " .
896 " usage_type = " . $ilDB->quote($a_type, "text") . " AND " .
897 " usage_id = " . $ilDB->quote($a_id, "integer") . " AND " .
898 " usage_lang = " . $ilDB->quote($a_lang, "text") . " AND " .
899 " usage_hist_nr = " . $ilDB->quote($a_usage_hist_nr, "integer");
900 $ilDB->manipulate($q);
901
902 self::handleQuotaUpdate(new self($a_mob_id));
903 }
904
908 public function getUsages(
909 bool $a_include_history = true
910 ): array {
911 return self::lookupUsages($this->getId(), $a_include_history);
912 }
913
919 public static function lookupUsages(
920 int $a_id,
921 bool $a_include_history = true
922 ): array {
923 global $DIC;
924
925 $ilDB = $DIC->database();
926
927 $hist_str = "";
928 if ($a_include_history) {
929 $hist_str = ", usage_hist_nr";
930 }
931
932 // get usages in pages
933 $q = "SELECT DISTINCT usage_type, usage_id, usage_lang" . $hist_str . " FROM mob_usage WHERE id = " .
934 $ilDB->quote($a_id, "integer");
935
936 if (!$a_include_history) {
937 $q .= " AND usage_hist_nr = " . $ilDB->quote(0, "integer");
938 }
939
940 $us_set = $ilDB->query($q);
941 $ret = array();
942 while ($us_rec = $ilDB->fetchAssoc($us_set)) {
943 $ut = "";
944 $ct = 0;
945 if (is_int(strpos($us_rec["usage_type"], ":"))) {
946 $us_arr = explode(":", $us_rec["usage_type"]);
947 $ut = $us_arr[1];
948 $ct = $us_arr[0];
949 }
950
951 // check whether page exists
952 $skip = false;
953 if ($ut == "pg") {
954 if (!ilPageObject::_exists($ct, $us_rec["usage_id"])) {
955 $skip = true;
956 }
957 }
958
959 if (!$skip) {
960 $ret[] = array(
961 "type" => $us_rec["usage_type"],
962 "id" => $us_rec["usage_id"],
963 "lang" => $us_rec["usage_lang"],
964 "hist_nr" => ($us_rec["usage_hist_nr"] ?? 0)
965 );
966 }
967 }
968
969 // get usages in media pools
970 $q = "SELECT DISTINCT mep_id FROM mep_tree JOIN mep_item ON (child = obj_id) WHERE mep_item.foreign_id = " .
971 $ilDB->quote($a_id, "integer") . " AND mep_item.type = " . $ilDB->quote("mob", "text");
972 $us_set = $ilDB->query($q);
973 while ($us_rec = $ilDB->fetchAssoc($us_set)) {
974 $ret[] = array("type" => "mep",
975 "id" => $us_rec["mep_id"]);
976 }
977
978 // get usages in news items (media casts)
979 $news_usages = ilNewsItem::_lookupMediaObjectUsages($a_id);
980 foreach ($news_usages as $nu) {
981 $ret[] = $nu;
982 }
983
984
985 // get usages in map areas
986 $q = "SELECT DISTINCT mob_id FROM media_item it, map_area area " .
987 " WHERE area.item_id = it.id " .
988 " AND area.link_type = " . $ilDB->quote("int", "text") . " " .
989 " AND area.target = " . $ilDB->quote("il__mob_" . $a_id, "text");
990 $us_set = $ilDB->query($q);
991 while ($us_rec = $ilDB->fetchAssoc($us_set)) {
992 $ret[] = array("type" => "map",
993 "id" => $us_rec["mob_id"]);
994 }
995
996 // get usages in personal clipboards
997 $users = ilObjUser::_getUsersForClipboadObject("mob", $a_id);
998 foreach ($users as $user) {
999 $ret[] = array("type" => "clip",
1000 "id" => $user);
1001 }
1002
1003 return $ret;
1004 }
1005
1010 public static function getParentObjectIdForUsage(
1011 array $a_usage,
1012 bool $a_include_all_access_obj_ids = false
1013 ): ?int {
1014 $cont_type = "";
1015 if (is_int(strpos($a_usage["type"], ":"))) {
1016 $us_arr = explode(":", $a_usage["type"]);
1017 $type = $us_arr[1];
1018 $cont_type = $us_arr[0];
1019 } else {
1020 $type = $a_usage["type"];
1021 }
1022
1023 $id = $a_usage["id"];
1024 $obj_id = null;
1025
1026 switch ($type) {
1027 // RTE / tiny mce
1028 case "html":
1029
1030 switch ($cont_type) {
1031 case "qpl":
1032 // Question Pool *Question* Text (Test)
1033 global $DIC;
1034 $qinfo = $DIC->testQuestion()->getGeneralQuestionProperties($id);
1035 if ($qinfo->getOriginalId() > 0) {
1036 $obj_id = ilObjTest::_lookupTestObjIdForQuestionId($id); // usage in test
1037 } else {
1038 $obj_id = (int) ($qinfo["obj_fi"] ?? 0); // usage in pool
1039 }
1040 break;
1041
1042 case "spl":
1043 // Question Pool *Question* Text (Survey)
1045 if ($quest) {
1046 $parent_id = $quest->getObjId();
1047
1048 // pool question copy - find survey, do not use pool itself
1049 if ($quest->getOriginalId() &&
1050 ilObject::_lookupType($parent_id) == "spl") {
1052 }
1053 // original question (in pool or survey)
1054 else {
1055 $obj_id = (int) $parent_id;
1056 }
1057
1058 unset($quest);
1059 }
1060 break;
1061
1062 case "exca":
1063 // Exercise assignment
1064 $returned_pk = $a_usage['id'];
1065 // #15995 - we are just checking against exercise object
1066 $obj_id = ilExSubmission::lookupExerciseIdForReturnedId($returned_pk);
1067 break;
1068
1069 case "frm":
1070 // Forum
1071 $post_pk = $a_usage['id'];
1072 $oPost = new ilForumPost($post_pk);
1073 $frm_pk = $oPost->getForumId();
1074 $obj_id = ilForum::_lookupObjIdForForumId($frm_pk);
1075 break;
1076
1077
1078 case "frm~d":
1079 $draft_id = $a_usage['id'];
1080 $oDraft = ilForumPostDraft::newInstanceByDraftId($draft_id);
1081
1082 $frm_pk = $oDraft->getForumId();
1083 $obj_id = ilForum::_lookupObjIdForForumId($frm_pk);
1084 break;
1085 case "frm~h":
1086 $history_id = $a_usage['id'];
1087 $oHistoryDraft = new ilForumDraftsHistory($history_id);
1088 $oDraft = ilForumPostDraft::newInstanceByDraftId($oHistoryDraft->getDraftId());
1089
1090 $frm_pk = $oDraft->getForumId();
1091 $obj_id = ilForum::_lookupObjIdForForumId($frm_pk);
1092 break;
1093 // temporary items (per user)
1094 case "frm~":
1095 case "exca~":
1096 $obj_id = (int) $a_usage['id'];
1097 break;
1098
1099 // "old" category pages
1100 case "cat":
1101 // InfoScreen Text
1102 case "tst":
1103 case "svy":
1104 // data collection
1105 case "dcl":
1106 $obj_id = (int) $id;
1107 break;
1108 }
1109 break;
1110
1111 // page editor
1112 case "pg":
1113
1114 switch ($cont_type) {
1115 // question feedback // parent obj id is q id
1116 case "qfbg":
1117 case "qpl":
1118
1119 if ($cont_type == "qfbg") {
1121 }
1122
1123 // Question Pool Question Pages
1124 global $DIC;
1125 $qinfo = $DIC->testQuestion()->getGeneralQuestionProperties($id);
1126 if ($qinfo->getOriginalId() > 0) {
1127 $obj_id = ilObjTest::_lookupTestObjIdForQuestionId($id); // usage in test
1128 } else {
1129 $obj_id = $qinfo["obj_fi"]; // usage in pool
1130 }
1131 if ($obj_id == 0) { // this is the case, if question is in learning module -> get lm id
1133 if ($pinfo && $pinfo["parent_type"] == "lm") {
1134 $obj_id = ilLMObject::_lookupContObjID($pinfo["page_id"]);
1135 }
1136 }
1137 break;
1138
1139 case "lm":
1140 // learning modules
1142 break;
1143
1144 case "term":
1145 $term_id = $id;
1146 $obj_id = ilGlossaryTerm::_lookGlossaryID($term_id);
1147 break;
1148
1149 case "wpg":
1150 // wiki page
1152 break;
1153
1154 case "sahs":
1155 // sahs page
1156 // can this implementation be used for other content types, too?
1157 $obj_id = ilPageObject::lookupParentId($id, 'sahs');
1158 break;
1159
1160 case "prtf":
1161 // portfolio
1163 break;
1164
1165 case "prtt":
1166 // portfolio template
1168 break;
1169
1170
1171 case "impr":
1172 // imprint page - always id 1
1173 // fallthrough
1174
1175 case "copa":
1176 case "cstr":
1177 $obj_id = $id;
1178 break;
1179
1180 default:
1181 $obj_id = ilPageObject::lookupParentId($id, $cont_type);
1182 break;
1183 }
1184 break;
1185
1186 // Media Pool
1187 case "mep":
1188 $obj_id = $id;
1189 break;
1190
1191 // News Context Object (e.g. MediaCast)
1192 case "news":
1194 break;
1195 }
1196
1197 return $obj_id;
1198 }
1199
1203 public static function getMimeType(
1204 string $a_file,
1205 bool $a_external = false
1206 ): string {
1207 $mime = MimeType::lookupMimeType($a_file, MimeType::APPLICATION__OCTET_STREAM, $a_external);
1208 return $mime;
1209 }
1210
1211 public static function _determineWidthHeight(
1212 string $a_format,
1213 string $a_type,
1214 string $a_file,
1215 string $a_reference,
1216 bool $a_constrain_proportions,
1217 bool $a_use_original,
1218 ?int $a_user_width = null,
1219 ?int $a_user_height = null
1220 ): array {
1221 global $DIC;
1222
1223 $lng = $DIC->language();
1224 $size = [];
1225 $wr = 0;
1226 $hr = 0;
1227 $width = 0;
1228 $height = 0;
1229
1230 // determine width and height of known image types
1231 //$width = 640;
1232 //$height = 360;
1233 $info = "";
1234
1235 /*
1236 if ($a_format == "audio/mpeg") {
1237 $width = 300;
1238 $height = 20;
1239 }*/
1240
1241 if (ilUtil::deducibleSize($a_format)) {
1242 if ($a_type == "File") {
1243 $size = ilMediaImageUtil::getImageSize($a_file);
1244 } else {
1245 $size = ilMediaImageUtil::getImageSize($a_reference);
1246 }
1247 }
1248
1249 if (!isset($size[0])) {
1250 $size[0] = 0;
1251 }
1252 if (!isset($size[1])) {
1253 $size[1] = 0;
1254 }
1255
1256 if ($a_use_original) {
1257 if ($size[0] > 0 && $size[1] > 0) {
1258 //$width = $size[0];
1259 //$height = $size[1];
1260 $width = "";
1261 $height = "";
1262 } else {
1263 $info = $lng->txt("cont_could_not_determine_resource_size");
1264 }
1265 } else {
1266 $w = $a_user_width;
1267 $h = $a_user_height;
1268 $width = $w;
1269 $height = $h;
1270 //echo "<br>C-$width-$height-";
1271 if (ilUtil::deducibleSize($a_format) && $a_constrain_proportions) {
1272 if ($size[0] > 0 && $size[1] > 0) {
1273 if ($w > 0) {
1274 $wr = $size[0] / $w;
1275 }
1276 if ($h > 0) {
1277 $hr = $size[1] / $h;
1278 }
1279 //echo "<br>+".$wr."+".$size[0]."+".$w."+";
1280 //echo "<br>+".$hr."+".$size[1]."+".$h."+";
1281 $r = max($wr, $hr);
1282 if ($r > 0) {
1283 $width = (int) round($size[0] / $r);
1284 $height = (int) round($size[1] / $r);
1285 }
1286 }
1287 }
1288 //echo "<br>D-$width-$height-";
1289 }
1290 //echo "<br>E-$width-$height-";
1291
1292 if ($width == 0 && is_null($a_user_width)) {
1293 $width = "";
1294 }
1295 if ($height == 0 && is_null($a_user_height)) {
1296 $height = "";
1297 }
1298 return array("width" => $width, "height" => $height, "info" => $info);
1299 }
1300
1301 public function getDataDirectory(): string
1302 {
1303 return ilFileUtils::getWebspaceDir() . "/mobs/mm_" . $this->getId();
1304 }
1305
1311 public static function _saveTempFileAsMediaObject(
1312 string $name,
1313 string $tmp_name,
1314 bool $upload = true
1315 ): ilObjMediaObject {
1316 // create dummy object in db (we need an id)
1317 $media_object = new ilObjMediaObject();
1318 $media_object->setTitle($name);
1319 $media_object->setDescription("");
1320 $media_object->create();
1321
1322 // determine and create mob directory, move uploaded file to directory
1323 $media_object->createDirectory();
1324 $mob_dir = ilObjMediaObject::_getDirectory($media_object->getId());
1325
1326 $file = $mob_dir . "/" . $name;
1327 if ($upload) {
1328 $media_item = $media_object->addMediaItemFromLegacyUpload(
1329 "Standard",
1330 $tmp_name,
1331 $name,
1332 0,
1333 0,
1334 true,
1335 true
1336 );
1337 } else {
1338 $media_item = $media_object->addMediaItemFromLocalFile(
1339 "Standard",
1340 $tmp_name,
1341 $name
1342 );
1343 /*
1344 $media_item = new ilMediaItem();
1345 $media_object->addMediaItem($media_item);
1346 $media_item->setPurpose("Standard");
1347
1348 copy($tmp_name, $file);
1349 // get mime type
1350 $format = ilObjMediaObject::getMimeType($file);
1351 $media_item->setFormat($format);
1352 $location = $name;
1353 $media_item->setLocation($location);
1354 $media_item->setLocationType("LocalFile");*/
1355 }
1356
1357 // set real meta and object data
1358 $media_object->setTitle($name);
1359 $media_object->setDescription($media_item->getFormat());
1360 $media_item->setHAlign("Left");
1361
1362 /*
1363 self::renameExecutables($mob_dir);
1364 ilMediaSvgSanitizer::sanitizeDir($mob_dir); // see #20339
1365 */
1366
1367 $media_object->update();
1368
1369 return $media_object;
1370 }
1371
1373 string $purpose,
1374 string $tmp_name,
1375 string $name,
1376 int $resize_width = 0,
1377 int $resize_height = 0,
1378 bool $constrain_proportions = true,
1379 bool $deduce_size = false
1380 ): \ilMediaItem {
1381 $media_item = new ilMediaItem();
1382 $this->addMediaItem($media_item);
1383 $media_item->setPurpose($purpose);
1384 //$location = self::fixFilename($_FILES[$upload_name]['name']);
1385 $location = $name;
1386 $this->manager->addFileFromLegacyUpload($this->getId(), $tmp_name);
1387
1388 // get mime type
1389 $format = self::getMimeType($location, true);
1390
1391 // resize standard images
1392 if ($resize_width > 0 && $resize_height > 0 && is_int(strpos($format, "image"))) {
1393 /*
1394 $location = ilObjMediaObject::_resizeImage(
1395 $file,
1396 $resize_width,
1397 $resize_height,
1398 $constrain_proportions
1399 );*/
1400 }
1401
1402 if ($deduce_size) {
1403 /*
1404 if (ilUtil::deducibleSize($format)) {
1405 $size = ilMediaImageUtil::getImageSize($file);
1406 $media_item->setWidth($size[0]);
1407 $media_item->setHeight($size[1]);
1408 }*/
1409 }
1410
1411 // set real meta and object data
1412 $media_item->setFormat($format);
1413 $media_item->setLocation($location);
1414 $media_item->setLocationType("LocalFile");
1415 if ($purpose === "Standard") {
1416 $this->generatePreviewPic(320, 240);
1417 }
1418 return $media_item;
1419 }
1420
1421 public function addMediaItemFromUpload(
1422 string $purpose,
1423 UploadResult $result,
1424 string $upload_hash = "",
1425 ): \ilMediaItem {
1426 $media_item = new ilMediaItem();
1427 $this->addMediaItem($media_item);
1428 $media_item->setPurpose($purpose);
1429 $this->manager->addFileFromUpload($this->getId(), $result);
1430
1431 // get mime type
1432 $format = self::getMimeType($result->getName(), true);
1433
1434 // set real meta and object data
1435 $media_item->setFormat($format);
1436 $media_item->setLocation($result->getName());
1437 $media_item->setLocationType("LocalFile");
1438 if ($upload_hash !== "") {
1439 $media_item->setUploadHash($upload_hash);
1440 }
1441 if ($purpose === "Standard") {
1442 $this->generatePreviewPic(320, 240);
1443 }
1444 return $media_item;
1445 }
1446
1448 string $purpose,
1449 string $tmp_name,
1450 string $name
1451 ): \ilMediaItem {
1452 $media_item = new ilMediaItem();
1453 $this->addMediaItem($media_item);
1454 $media_item->setPurpose($purpose);
1455 $location = $name;
1456 $this->manager->addFileFromLocal($this->getId(), $tmp_name, $name);
1457
1458 // get mime type
1459 $format = self::getMimeType($location, true);
1460
1461 // set real meta and object data
1462 $media_item->setFormat($format);
1463 $media_item->setLocation($location);
1464 $media_item->setLocationType("LocalFile");
1465 if ($purpose === "Standard") {
1466 $this->generatePreviewPic(320, 240);
1467 }
1468 return $media_item;
1469 }
1470
1472 string $purpose,
1473 UploadResult $result,
1474 string $upload_hash = "",
1475 ): \ilMediaItem {
1476 $media_item = $this->getMediaItem($purpose);
1477 $this->manager->removeLocation($this->getId(), $media_item->getLocation());
1478 $this->manager->addFileFromUpload($this->getId(), $result);
1479
1480 // get mime type
1481 $format = self::getMimeType($result->getName(), true);
1482
1483 // set real meta and object data
1484 $media_item->setFormat($format);
1485 $media_item->setLocation($result->getName());
1486 $media_item->setLocationType("LocalFile");
1487 if ($upload_hash !== "") {
1488 $media_item->setUploadHash($upload_hash);
1489 }
1490 if ($purpose === "Standard") {
1491 $this->generatePreviewPic(320, 240);
1492 }
1493 return $media_item;
1494 }
1495
1499 public function uploadAdditionalFile(
1500 string $a_name,
1501 string $tmp_name,
1502 string $a_subdir = "",
1503 string $a_mode = "move_uploaded"
1504 ): void {
1505 $a_subdir = str_replace("..", "", $a_subdir);
1506 if ($a_mode == "rename") {
1507 $this->manager->addFileFromLocal(
1508 $this->getId(),
1509 $tmp_name,
1510 $a_subdir . "/" . $a_name
1511 );
1512 } else {
1513 $this->manager->addFileFromLegacyUpload(
1514 $this->getId(),
1515 $tmp_name,
1516 $a_subdir . "/" . $a_name
1517 );
1518 }
1519 }
1520
1522 UploadResult $result,
1523 string $subdir
1524 ): void {
1525 $this->manager->addFileFromUpload(
1526 $this->getId(),
1527 $result,
1528 $subdir
1529 );
1530 }
1531
1532 public function uploadSrtFile(
1533 string $a_tmp_name,
1534 string $a_language,
1535 string $a_mode = "move_uploaded"
1536 ): bool {
1537 if (is_file($a_tmp_name) && $a_language != "") {
1538 $this->uploadAdditionalFile("subtitle_" . $a_language . ".vtt", $a_tmp_name, "srt", $a_mode);
1539 return true;
1540 }
1541 return false;
1542 }
1543
1544 public function getSrtFiles(bool $vtt_only = false): array
1545 {
1546 return $this->manager->getSrtFiles($this->getId(), $vtt_only);
1547 }
1548
1552 public function makeThumbnail(
1553 string $source,
1554 string $thumbname,
1555 ): void {
1556 $format = self::getMimeType($source, true);
1557 $this->thumbs->createPreview(
1558 $this->getId(),
1559 $source,
1560 true,
1561 $format,
1562 1,
1563 $thumbname
1564 );
1565 }
1566
1567 public function removeAdditionalFile(
1568 string $a_file
1569 ): void {
1570 $this->manager->removeLocation(
1571 $this->getId(),
1572 $a_file
1573 );
1574 }
1575
1576
1581 public function getLinkedMediaObjects(
1582 array $a_ignore = []
1583 ): array {
1584 $linked = array();
1585
1586 // get linked media objects (map areas)
1587 $med_items = $this->getMediaItems();
1588
1589 foreach ($med_items as $med_item) {
1590 $int_links = ilMapArea::_getIntLinks($med_item->getId());
1591 foreach ($int_links as $k => $int_link) {
1592 if ($int_link["Type"] == "MediaObject") {
1593 $l_id = ilInternalLink::_extractObjIdOfTarget($int_link["Target"]);
1594 if (ilObject::_exists($l_id)) {
1595 if (!in_array($l_id, $linked) &&
1596 !in_array($l_id, $a_ignore)) {
1597 $linked[] = $l_id;
1598 }
1599 }
1600 }
1601 }
1602 }
1603 //var_dump($linked);
1604 return $linked;
1605 }
1606
1607 public static function isTypeAllowed(
1608 string $a_type
1609 ): bool {
1610 global $DIC;
1611 return in_array($a_type, iterator_to_array(
1612 $DIC->mediaObjects()->internal()->domain()->mediaType()->getAllowedSuffixes()
1613 ), true);
1614 }
1615
1619 public function duplicate(): ilObjMediaObject
1620 {
1621 $new_obj = new ilObjMediaObject();
1622 $new_obj->setTitle($this->getTitle());
1623 $new_obj->setDescription($this->getDescription());
1624
1625 // media items
1626 foreach ($this->getMediaItems() as $key => $val) {
1627 $new_obj->addMediaItem($val);
1628 }
1629
1630 $new_obj->create(
1631 false,
1632 true,
1633 $this->getId() // "from" id
1634 );
1635
1636 // meta data
1637 $this->domain->metadata()->learningObjectMetadata()
1638 ->derive()
1639 ->fromObject(0, $this->getId(), "mob")
1640 ->forObject(0, $new_obj->getId(), "mob");
1641
1642 return $new_obj;
1643 }
1644
1645 public function uploadVideoPreviewPic(
1646 array $a_prevpic
1647 ): void {
1648 // remove old one
1649 if ($this->getVideoPreviewPic(true) != "") {
1650 $this->removeAdditionalFile($this->getVideoPreviewPic(true));
1651 }
1652
1653 $pi = pathinfo($a_prevpic["name"]);
1654 $ext = $pi["extension"];
1655 if (in_array($ext, array("jpg", "jpeg", "png"))) {
1656 $this->uploadAdditionalFile("mob_vpreview." . $ext, $a_prevpic["tmp_name"]);
1657 }
1658 }
1659
1660 public function generatePreviewPic(
1661 int $a_width,
1662 int $a_height,
1663 int $sec = 1
1664 ): void {
1666 $logger = $GLOBALS['DIC']->logger()->mob();
1667
1668 $item = $this->getMediaItem("Standard");
1669 if ($item->getFormat() === "image/svg+xml") {
1670 return;
1671 }
1672
1673 $logger->debug("Generate preview pic...");
1674 $logger->debug("..." . $item->getFormat());
1675 $this->thumbs->createPreview(
1676 $this->getId(),
1677 $item->getLocation(),
1678 $item->getLocationType() === "LocalFile",
1679 $item->getFormat(),
1680 $sec
1681 );
1682 }
1683
1684 public function getVideoPreviewPic(
1685 bool $a_filename_only = false
1686 ): string {
1687
1688 if (!$a_filename_only) {
1689 $src = $this->thumbs->getPreviewSrc($this->getId());
1690 if ($src !== "") {
1691 return $src;
1692 }
1693 }
1694
1695 $dir = ilObjMediaObject::_getDirectory($this->getId());
1696 $ppics = array("mob_vpreview.jpg",
1697 "mob_vpreview.jpeg",
1698 "mob_vpreview.png");
1699 $med = $this->getMediaItem("Standard");
1700 if ($med && $med->getFormat() === "image/svg+xml" && $med->getLocationType() === "LocalFile") {
1701 $ppics[] = $med->getLocation();
1702 }
1703 foreach ($ppics as $p) {
1704 if (is_file($dir . "/" . $p)) {
1705 if ($a_filename_only) {
1706 return $p;
1707 } else {
1708 return $dir . "/" . $p;
1709 }
1710 }
1711 }
1712 return "";
1713 }
1714
1718 public static function fixFilename(
1719 string $a_name
1720 ): string {
1721 $a_name = ilFileUtils::getASCIIFilename($a_name);
1722
1723 $rchars = array("`", "=", "$", "{", "}", "'", ";", " ", "(", ")");
1724 $a_name = str_replace($rchars, "_", $a_name);
1725 $a_name = str_replace("__", "_", $a_name);
1726 return $a_name;
1727 }
1728
1729
1733 public function getMultiSrtUploadDir(): string
1734 {
1735 return ilObjMediaObject::_getDirectory($this->getId()) . "/srt/tmp";
1736 }
1737
1738
1743 array $a_file
1744 ): void {
1745 $lng = $this->lng;
1746
1747 if (!is_file($a_file["tmp_name"])) {
1748 throw new ilMediaObjectsException($lng->txt("mob_file_could_not_be_uploaded"));
1749 }
1750
1751 $dir = $this->getMultiSrtUploadDir();
1752 ilFileUtils::delDir($dir, true);
1754 ilFileUtils::moveUploadedFile($a_file["tmp_name"], "multi_vtt.zip", $dir . "/" . "multi_vtt.zip");
1755 $this->domain->resources()->zip()->unzipFile($dir . "/multi_vtt.zip");
1756 }
1757
1761 public function clearMultiSrtDirectory(): void
1762 {
1763 ilFileUtils::delDir($this->getMultiSrtUploadDir());
1764 }
1765
1769 public function getMultiSrtFiles(): array
1770 {
1771 $items = array();
1772
1773 $lang_codes = $this->domain->metadata()->getLOMLanguageCodes();
1774
1775 $dir = $this->getMultiSrtUploadDir();
1776 $files = ilFileUtils::getDir($dir);
1777 foreach ($files as $k => $i) {
1778 // check directory
1779 if ($i["type"] == "file" && !in_array($k, array(".", ".."))) {
1780 if (pathinfo($k, PATHINFO_EXTENSION) == "vtt") {
1781 $lang = "";
1782 if (substr($k, strlen($k) - 7, 1) == "_") {
1783 $lang = substr($k, strlen($k) - 6, 2);
1784 if (!in_array($lang, $lang_codes)) {
1785 $lang = "";
1786 }
1787 }
1788 $items[] = array("filename" => $k, "lang" => $lang);
1789 }
1790 }
1791 }
1792 return $items;
1793 }
1794
1795 public static function renameExecutables(
1796 string $a_dir
1797 ): void {
1798 ilFileUtils::renameExecutables($a_dir);
1799 if (!self::isTypeAllowed("html")) {
1800 ilFileUtils::rRenameSuffix($a_dir, "html", "sec"); // see #20187
1801 }
1802 }
1803
1804 public function getExternalMetadata(): void
1805 {
1806 // see https://oembed.com/
1807 $st_item = $this->getMediaItem("Standard");
1808 if ($st_item->getLocationType() == "Reference") {
1809 if (ilExternalMediaAnalyzer::isVimeo($st_item->getLocation())) {
1810 $st_item->setFormat("video/vimeo");
1811 $par = ilExternalMediaAnalyzer::extractVimeoParameters($st_item->getLocation());
1813 $this->setTitle($meta["title"] ?? "");
1814 $description = str_replace("\n", "", $meta["description"] ?? "");
1815 $description = str_replace(["<br>", "<br />"], ["\n", "\n"], $description);
1816 $description = strip_tags($description);
1817 $this->setDescription($description);
1818 $st_item->setDuration((int) ($meta["duration"] ?? 0));
1819 $url = parse_url($meta["thumbnail_url"] ?? "");
1820 $file = basename($url["path"]);
1821 $ext = pathinfo($file, PATHINFO_EXTENSION);
1822 if ($ext == "") {
1823 $ext = "jpg";
1824 }
1825 $this->manager->addPreviewFromUrl(
1826 $this->getId(),
1827 $meta["thumbnail_url"],
1828 "/mob_vpreview." . $ext
1829 );
1830 }
1831 if (ilExternalMediaAnalyzer::isYoutube($st_item->getLocation())) {
1832 $st_item->setFormat("video/youtube");
1833 $par = ilExternalMediaAnalyzer::extractYoutubeParameters($st_item->getLocation());
1834 try {
1836 $this->setTitle($meta["title"] ?? "");
1837 $description = str_replace("\n", "", $meta["description"] ?? "");
1838 } catch (Exception $e) {
1839 $this->setTitle($st_item->getLocation());
1840 $description = "";
1841 }
1842 $description = str_replace(["<br>", "<br />"], ["\n", "\n"], $description);
1843 $description = strip_tags($description);
1844 $this->setDescription($description);
1845 $st_item->setDuration((int) ($meta["duration"] ?? 0));
1846 $thumbnail_url = $meta["thumbnail_url"] ?? "";
1847 $url = parse_url($thumbnail_url);
1848 if ($thumbnail_url !== "") {
1849 $mob_logger = ilLoggerFactory::getLogger('mob');
1850 $file = basename($url["path"]);
1851 $this->manager->addPreviewFromUrl(
1852 $this->getId(),
1853 $meta["thumbnail_url"],
1854 "/mob_vpreview." .
1855 pathinfo($file, PATHINFO_EXTENSION)
1856 );
1857 }
1858 }
1859 }
1860 }
1861
1862 public function getStandardSrc(): string
1863 {
1864 return $this->getLocationSrc("Standard");
1865 }
1866
1867 public function getFullscreenSrc(): string
1868 {
1869 return $this->getLocationSrc("Fullscreen");
1870 }
1871
1872 protected function getLocationSrc(string $purpose): string
1873 {
1874 return (string) $this->getMediaItem($purpose)?->getLocationSrc();
1875 }
1876}
$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 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:25
$url
Definition: shib_logout.php:70
$GLOBALS["DIC"]
Definition: wac.php:54