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