ILIAS  release_8 Revision v8.19
All Data Structures Namespaces Files Functions Variables Modules Pages
class.ilObjMediaObject.php
Go to the documentation of this file.
1 <?php
2 
20 
21 define("IL_MODE_ALIAS", 1);
22 define("IL_MODE_OUTPUT", 2);
23 define("IL_MODE_FULL", 3);
24 
29 {
30  protected ilObjUser $user;
31  public bool $is_alias;
32  public string $origin_id;
33  public array $media_items;
34  public bool $contains_int_link;
35 
36  public function __construct(
37  int $a_id = 0
38  ) {
39  global $DIC;
40 
41  $this->user = $DIC->user();
42  $this->app_event_handler = $DIC["ilAppEventHandler"];
43  $this->lng = $DIC->language();
44  $this->is_alias = false;
45  $this->media_items = array();
46  $this->contains_int_link = false;
47  $this->type = "mob";
48  parent::__construct($a_id, false);
49  }
50 
51  public static function _exists(
52  int $id,
53  bool $reference = false,
54  ?string $type = null
55  ): bool {
56  if (is_int(strpos($id, "_"))) {
58  }
59 
60  if (parent::_exists($id) && ilObject::_lookupType($id) === "mob") {
61  return true;
62  }
63  return false;
64  }
65 
66  public function delete(): bool
67  {
68  $mob_logger = ilLoggerFactory::getLogger('mob');
69  $mob_logger->debug("ilObjMediaObject: Delete called for media object ID '" . $this->getId() . "'.");
70 
71  if (!($this->getId() > 0)) {
72  return false;
73  }
74 
75  $usages = $this->getUsages();
76 
77  $mob_logger->debug("ilObjMediaObject: ... Found " . count($usages) . " usages.");
78 
79  if (count($usages) == 0) {
80  // remove directory
82 
83  // remove thumbnail directory
85 
86  // delete meta data of mob
87  $this->deleteMetaData();
88 
89  // delete media items
91 
92  // this is just to make sure, there should be no entries left at
93  // this point as they depend on the usage
94  self::handleQuotaUpdate($this);
95 
96  // delete object
97  parent::delete();
98 
99  $mob_logger->debug("ilObjMediaObject: ... deleted.");
100  } else {
101  foreach ($usages as $u) {
102  $mob_logger->debug("ilObjMediaObject: ... usage type:" . $u["type"] .
103  ", id:" . $u["id"] .
104  ", lang:" . ($u["lang"] ?? "") .
105  ", hist_nr:" . ($u["hist_nr"] ?? "") . ".");
106  }
107  $mob_logger->debug("ilObjMediaObject: ... not deleted.");
108  }
109  return true;
110  }
111 
112  protected function beforeMDUpdateListener(string $a_element): bool
113  {
114  switch ($a_element) {
115  case 'General':
116 
117  // Update Title and description
118  $md = new ilMD(0, $this->getId(), $this->getType());
119  $md_gen = $md->getGeneral();
120 
121  if (is_object($md_gen)) {
122  ilObject::_writeTitle($this->getId(), $md_gen->getTitle());
123  $this->setTitle($md_gen->getTitle());
124 
125  foreach ($md_gen->getDescriptionIds() as $id) {
126  $md_des = $md_gen->getDescription($id);
127  ilObject::_writeDescription($this->getId(), $md_des->getDescription());
128  $this->setDescription($md_des->getDescription());
129  break;
130  }
131  }
132 
133  break;
134  }
135  return false; // prevent parent from creating ilMD
136  }
137 
138  protected function beforeCreateMetaData(): bool
139  {
141 
142  $md_creator = new ilMDCreator(0, $this->getId(), $this->getType());
143  $md_creator->setTitle($this->getTitle());
144  $md_creator->setTitleLanguage($ilUser->getPref('language'));
145  $md_creator->setDescription($this->getDescription());
146  $md_creator->setDescriptionLanguage($ilUser->getPref('language'));
147  $md_creator->setKeywordLanguage($ilUser->getPref('language'));
148  $md_creator->setLanguage($ilUser->getPref('language'));
149  $md_creator->create();
150 
151  return false; // avoid parent to create md
152  }
153 
154  protected function beforeUpdateMetaData(): bool
155  {
156  $md = new ilMD(0, $this->getId(), $this->getType());
157  $md_gen = $md->getGeneral();
158  $md_gen->setTitle($this->getTitle());
159 
160  // sets first description (maybe not appropriate)
161  $md_des_ids = $md_gen->getDescriptionIds();
162  if (count($md_des_ids) > 0) {
163  $md_des = $md_gen->getDescription($md_des_ids[0]);
164  $md_des->setDescription($this->getDescription());
165  $md_des->update();
166  }
167  $md_gen->update();
168  return false;
169  }
170 
171  protected function beforeDeleteMetaData(): bool
172  {
173  // Delete meta data
174  $md = new ilMD(0, $this->getId(), $this->getType());
175  $md->deleteAll();
176 
177  return false;
178  }
179 
180 
181  public function addMediaItem(
182  ilMediaItem $a_item
183  ): void {
184  $this->media_items[] = $a_item;
185  }
186 
187  public function &getMediaItems(): array
188  {
189  return $this->media_items;
190  }
191 
195  public function getMediaItem(
196  string $a_purpose
197  ): ?ilMediaItem {
198  foreach ($this->media_items as $media_item) {
199  if ($media_item->getPurpose() == $a_purpose) {
200  return $media_item;
201  }
202  }
203  return null;
204  }
205 
206  public function removeMediaItem(
207  string $a_purpose
208  ): void {
209  foreach ($this->media_items as $key => $media_item) {
210  if ($media_item->getPurpose() == $a_purpose) {
211  unset($this->media_items[$key]);
212  }
213  }
214  // update numbers and keys
215  $i = 1;
216  $media_items = array();
217  foreach ($this->media_items as $media_item) {
218  $media_items [$i] = $media_item;
219  $media_item->setMobId($this->getId());
220  $media_item->setNr($i);
221  $i++;
222  }
223  $this->media_items = $media_items;
224  }
225 
226  public function removeAllMediaItems(): void
227  {
228  $this->media_items = array();
229  }
230 
231  public function hasFullscreenItem(): bool
232  {
233  return $this->hasPurposeItem("Fullscreen");
234  }
235 
239  public function hasPurposeItem(string $purpose): bool
240  {
241  if (is_object($this->getMediaItem($purpose))) {
242  return true;
243  } else {
244  return false;
245  }
246  }
247 
252  public function read(): void
253  {
254  parent::read();
256  }
257 
258  public function setAlias(bool $a_is_alias): void
259  {
260  $this->is_alias = $a_is_alias;
261  }
262 
263  public function isAlias(): bool
264  {
265  return $this->is_alias;
266  }
267 
271  public function setOriginID(string $a_id): void
272  {
273  $this->origin_id = $a_id;
274  }
275 
276  public function getOriginID(): string
277  {
278  return $this->origin_id;
279  }
280 
281  public function create(bool $a_create_meta_data = false, bool $a_save_media_items = true): int
282  {
283  $id = parent::create();
284 
285  if (!$a_create_meta_data) {
286  $this->createMetaData();
287  }
288 
289  if ($a_save_media_items) {
290  $media_items = $this->getMediaItems();
291  for ($i = 0; $i < count($media_items); $i++) {
292  $item = $media_items[$i];
293  $item->setMobId($this->getId());
294  $item->setNr($i + 1);
295  $item->create();
296  }
297  }
298 
299  self::handleQuotaUpdate($this);
300 
301  $ilAppEventHandler = $this->app_event_handler;
302  $ilAppEventHandler->raise(
303  'Services/MediaObjects',
304  'create',
305  array('object' => $this,
306  'obj_type' => 'mob',
307  'obj_id' => $this->getId())
308  );
309 
310  return $id;
311  }
312 
313  public function update(bool $a_upload = false): bool
314  {
315  parent::update();
316 
317  if (!$a_upload) {
318  $this->updateMetaData();
319  }
320 
321  // iterate all items
322  $media_items = $this->getMediaItems();
324 
325  $j = 1;
326  foreach ($media_items as $key => $val) {
327  $item = $val;
328  if (is_object($item)) {
329  $item->setMobId($this->getId());
330  $item->setNr($j);
331  if ($item->getLocationType() == "Reference") {
332  $item->extractUrlParameters();
333  }
334  $item->create();
335  $j++;
336  }
337  }
338 
339  self::handleQuotaUpdate($this);
340  $ilAppEventHandler = $this->app_event_handler;
341  $ilAppEventHandler->raise(
342  'Services/MediaObjects',
343  'update',
344  array('object' => $this,
345  'obj_type' => 'mob',
346  'obj_id' => $this->getId())
347  );
348 
349  return true;
350  }
351 
355  protected static function handleQuotaUpdate(
356  ilObjMediaObject $a_mob
357  ): void {
358  }
359 
363  public static function _getDirectory(
364  int $a_mob_id
365  ): string {
366  return ilFileUtils::getWebspaceDir() . "/" . self::_getRelativeDirectory($a_mob_id);
367  }
368 
372  public static function _getRelativeDirectory(int $a_mob_id): string
373  {
374  return "mobs/mm_" . $a_mob_id;
375  }
376 
380  public static function _getURL(
381  int $a_mob_id
382  ): string {
383  return ilUtil::getHtmlPath(ilFileUtils::getWebspaceDir() . "/mobs/mm_" . $a_mob_id);
384  }
385 
389  public static function _getThumbnailDirectory(
390  int $a_mob_id,
391  string $a_mode = "filesystem"
392  ): string {
393  return ilFileUtils::getWebspaceDir($a_mode) . "/thumbs/mm_" . $a_mob_id;
394  }
395 
399  public static function _lookupStandardItemPath(
400  int $a_mob_id,
401  bool $a_url_encode = false,
402  bool $a_web = true
403  ): string {
404  return ilObjMediaObject::_lookupItemPath($a_mob_id, $a_url_encode, $a_web, "Standard");
405  }
406 
410  public static function _lookupItemPath(
411  int $a_mob_id,
412  bool $a_url_encode = false,
413  bool $a_web = true,
414  string $a_purpose = ""
415  ): string {
416  if ($a_purpose == "") {
417  $a_purpose = "Standard";
418  }
419  $location = ilMediaItem::_lookupLocationForMobId($a_mob_id, $a_purpose);
420  if (preg_match("/https?\:/i", $location)) {
421  return $location;
422  }
423 
424  if ($a_url_encode) {
425  $location = rawurlencode($location);
426  }
427 
428  $path = ($a_web)
429  ? ILIAS_HTTP_PATH
430  : ".";
431 
432  return $path . "/data/" . CLIENT_ID . "/mobs/mm_" . $a_mob_id . "/" . $location;
433  }
434 
439  public function createDirectory(): void
440  {
443  if (!is_dir($path)) {
444  throw new ilMediaObjectsException("Failed to create directory $path.");
445  }
446  }
447 
451  public static function _createThumbnailDirectory(
452  int $a_obj_id
453  ): void {
455  ilFileUtils::createDirectory(ilFileUtils::getWebspaceDir() . "/thumbs/mm_" . $a_obj_id);
456  }
457 
461  public function getFilesOfDirectory(
462  string $a_subdir = ""
463  ): array {
464  $a_subdir = str_replace("..", "", $a_subdir);
465  $dir = ilObjMediaObject::_getDirectory($this->getId());
466  if ($a_subdir != "") {
467  $dir .= "/" . $a_subdir;
468  }
469 
470  $files = array();
471  if (is_dir($dir)) {
472  $entries = ilFileUtils::getDir($dir);
473  foreach ($entries as $e) {
474  if (is_file($dir . "/" . $e["entry"]) && $e["entry"] != "." && $e["entry"] != "..") {
475  $files[] = $e["entry"];
476  }
477  }
478  }
479  return $files;
480  }
481 
482 
491  public function getXML(
492  int $a_mode = IL_MODE_FULL,
493  int $a_inst = 0,
494  bool $a_sign_locals = false
495  ): string {
497  $xml = "";
498  // TODO: full implementation of all parameters
499  //echo "-".$a_mode."-";
500  switch ($a_mode) {
501  case IL_MODE_ALIAS:
502  $xml = "<MediaObject>";
503  $xml .= "<MediaAlias OriginId=\"il__mob_" . $this->getId() . "\"/>";
504  $media_items = $this->getMediaItems();
505  for ($i = 0; $i < count($media_items); $i++) {
506  $item = $media_items[$i];
507  $xml .= "<MediaAliasItem Purpose=\"" . $item->getPurpose() . "\">";
508 
509  // Layout
510  $width = ($item->getWidth() != "")
511  ? "Width=\"" . $item->getWidth() . "\""
512  : "";
513  $height = ($item->getHeight() != "")
514  ? "Height=\"" . $item->getHeight() . "\""
515  : "";
516  $halign = ($item->getHAlign() != "")
517  ? "HorizontalAlign=\"" . $item->getHAlign() . "\""
518  : "";
519  $xml .= "<Layout $width $height $halign />";
520 
521  // Caption
522  if ($item->getCaption() != "") {
523  $xml .= "<Caption Align=\"bottom\">" .
524  $this->escapeProperty($item->getCaption()) . "</Caption>";
525  }
526 
527  // Text Representation
528  if ($item->getTextRepresentation() != "") {
529  $xml .= "<TextRepresentation>" .
530  $this->escapeProperty($item->getTextRepresentation()) . "</TextRepresentation>";
531  }
532 
533  // Parameter
534  $parameters = $item->getParameters();
535  foreach ($parameters as $name => $value) {
536  $xml .= "<Parameter Name=\"$name\" Value=\"" . $this->escapeProperty($value) . "\"/>";
537  }
538  $xml .= $item->getMapAreasXML();
539  $xml .= "</MediaAliasItem>";
540  }
541  break;
542 
543  // for output we need technical sections of meta data
544  case IL_MODE_OUTPUT:
545 
546  // get first technical section
547  // $meta = $this->getMetaData();
548  $xml = "<MediaObject Id=\"il__mob_" . $this->getId() . "\">";
549 
550  $media_items = $this->getMediaItems();
551  for ($i = 0; $i < count($media_items); $i++) {
552  $item = $media_items[$i];
553 
554  $xml .= "<MediaItem Purpose=\"" . $item->getPurpose() . "\">";
555 
556  if ($a_sign_locals && $item->getLocationType() == "LocalFile") {
557  $location = ilWACSignedPath::signFile($this->getDataDirectory() . "/" . $item->getLocation());
558  $location = substr($location, strrpos($location, "/") + 1);
559  } else {
560  $location = $item->getLocation();
561  if ($item->getLocationType() != "LocalFile") { //#25941
563  }
564  }
565 
566  $xml .= "<Location Type=\"" . $item->getLocationType() . "\">" .
567  $this->handleAmps($location) . "</Location>";
568 
569  // Format
570  $xml .= "<Format>" . $item->getFormat() . "</Format>";
571 
572  // Layout
573  $width = ($item->getWidth() != "")
574  ? "Width=\"" . $item->getWidth() . "\""
575  : "";
576  $height = ($item->getHeight() != "")
577  ? "Height=\"" . $item->getHeight() . "\""
578  : "";
579  $halign = ($item->getHAlign() != "")
580  ? "HorizontalAlign=\"" . $item->getHAlign() . "\""
581  : "";
582  $xml .= "<Layout $width $height $halign />";
583 
584  // Caption
585  if ($item->getCaption() != "") {
586  $xml .= "<Caption Align=\"bottom\">" .
587  $this->escapeProperty($item->getCaption()) . "</Caption>";
588  }
589 
590  // Text Representation
591  if ($item->getTextRepresentation() != "") {
592  $xml .= "<TextRepresentation>" .
593  $this->escapeProperty($item->getTextRepresentation()) . "</TextRepresentation>";
594  }
595 
596  // Title
597  if ($this->getTitle() != "") {
598  $xml .= "<Title>" .
599  $this->escapeProperty($this->getTitle()) . "</Title>";
600  }
601 
602  // Parameter
603  $parameters = $item->getParameters();
604  foreach ($parameters as $name => $value) {
605  $xml .= "<Parameter Name=\"$name\" Value=\"" . $this->escapeProperty($value) . "\"/>";
606  }
607  $xml .= $item->getMapAreasXML();
608 
609  // Subtitles
610  if ($item->getPurpose() == "Standard") {
611  $srts = $this->getSrtFiles();
612  foreach ($srts as $srt) {
613  $def = "";
614  $meta_lang = "";
615  if ($ilUser->getLanguage() != $meta_lang &&
616  $ilUser->getLanguage() == $srt["language"]) {
617  $def = ' Default="true" ';
618  }
619  $xml .= "<Subtitle File=\"" . $srt["full_path"] .
620  "\" Language=\"" . $srt["language"] . "\" " . $def . "/>";
621  }
622  }
623  $xml .= "</MediaItem>";
624  }
625  break;
626 
627  // full xml for export
628  case IL_MODE_FULL:
629 
630  // $meta = $this->getMetaData();
631  $xml = "<MediaObject>";
632 
633  // meta data
634  $md2xml = new ilMD2XML(0, $this->getId(), $this->getType());
635  $md2xml->setExportMode(true);
636  $md2xml->startExport();
637  $xml .= $md2xml->getXML();
638 
639  $media_items = $this->getMediaItems();
640  for ($i = 0; $i < count($media_items); $i++) {
641  $item = $media_items[$i];
642 
643  // highlight mode
644  $xml .= "<MediaItem Purpose=\"" . $item->getPurpose() . "\">";
645 
646  // Location
647  $xml .= "<Location Type=\"" . $item->getLocationType() . "\">" .
648  $this->handleAmps($item->getLocation()) . "</Location>";
649 
650  // Format
651  $xml .= "<Format>" . $item->getFormat() . "</Format>";
652 
653  // Layout
654  $width = ($item->getWidth() != "")
655  ? "Width=\"" . $item->getWidth() . "\""
656  : "";
657  $height = ($item->getHeight() != "")
658  ? "Height=\"" . $item->getHeight() . "\""
659  : "";
660  $halign = ($item->getHAlign() != "")
661  ? "HorizontalAlign=\"" . $item->getHAlign() . "\""
662  : "";
663  $xml .= "<Layout $width $height $halign />";
664 
665  // Caption
666  if ($item->getCaption() != "") {
667  $xml .= "<Caption Align=\"bottom\">" .
668  str_replace("&", "&amp;", $item->getCaption()) . "</Caption>";
669  }
670 
671  // Text Representation
672  if ($item->getTextRepresentation() != "") {
673  $xml .= "<TextRepresentation>" .
674  str_replace("&", "&amp;", $item->getTextRepresentation()) . "</TextRepresentation>";
675  }
676 
677  // Parameter
678  $parameters = $item->getParameters();
679  foreach ($parameters as $name => $value) {
680  $xml .= "<Parameter Name=\"$name\" Value=\"$value\"/>";
681  }
682  $xml .= $item->getMapAreasXML(true, $a_inst);
683  $xml .= "</MediaItem>";
684  }
685  break;
686  }
687  $xml .= "</MediaObject>";
688  return $xml;
689  }
690 
694  protected function escapeProperty(
695  string $a_value
696  ): string {
697  return htmlspecialchars($a_value);
698  }
699 
700 
704  public function handleAmps(
705  string $a_str
706  ): string {
707  $a_str = str_replace("&amp;", "&", $a_str);
708  $a_str = str_replace("&", "&amp;", $a_str);
709  return $a_str;
710  }
711 
712  public function exportXML(
713  ilXmlWriter $a_xml_writer,
714  int $a_inst = 0
715  ): void {
716  $a_xml_writer->appendXML($this->getXML(IL_MODE_FULL, $a_inst));
717  }
718 
719 
728  public function exportFiles(
729  string $a_target_dir
730  ): void {
731  $subdir = "il_" . IL_INST_ID . "_mob_" . $this->getId();
732  ilFileUtils::makeDir($a_target_dir . "/objects/" . $subdir);
733 
734  $mobdir = ilFileUtils::getWebspaceDir() . "/mobs/mm_" . $this->getId();
735  ilFileUtils::rCopy($mobdir, $a_target_dir . "/objects/" . $subdir);
736  }
737 
738  public function modifyExportIdentifier(
739  string $a_tag,
740  string $a_param,
741  string $a_value
742  ): string {
743  if ($a_tag == "Identifier" && $a_param == "Entry") {
744  $a_value = ilUtil::insertInstIntoID($a_value);
745  }
746 
747  return $a_value;
748  }
749 
750 
752  // EDIT METHODS: these methods act on the media alias in the dom
754 
759  public function setContainsIntLink(
760  bool $a_contains_link
761  ): void {
762  $this->contains_int_link = $a_contains_link;
763  }
764 
769  public function containsIntLink(): bool
770  {
772  }
773 
774  public static function _deleteAllUsages(
775  string $a_type,
776  int $a_id,
777  ?int $a_usage_hist_nr = 0,
778  string $a_lang = "-"
779  ): void {
780  global $DIC;
781 
782  $ilDB = $DIC->database();
783 
784  $and_hist = "";
785  if (!is_null($a_usage_hist_nr)) {
786  $and_hist = " AND usage_hist_nr = " . $ilDB->quote($a_usage_hist_nr, "integer");
787  }
788 
789  $mob_ids = array();
790  $set = $ilDB->query("SELECT id FROM mob_usage" .
791  " WHERE usage_type = " . $ilDB->quote($a_type, "text") .
792  " AND usage_id = " . $ilDB->quote($a_id, "integer") .
793  " AND usage_lang = " . $ilDB->quote($a_lang, "text") .
794  $and_hist);
795  while ($row = $ilDB->fetchAssoc($set)) {
796  $mob_ids[] = $row["id"];
797  }
798 
799  $q = "DELETE FROM mob_usage WHERE usage_type = " .
800  $ilDB->quote($a_type, "text") .
801  " AND usage_id= " . $ilDB->quote($a_id, "integer") .
802  " AND usage_lang = " . $ilDB->quote($a_lang, "text") .
803  $and_hist;
804  $ilDB->manipulate($q);
805 
806  foreach ($mob_ids as $mob_id) {
807  self::handleQuotaUpdate(new self($mob_id));
808  }
809  }
810 
814  public static function _getMobsOfObject(
815  string $a_type,
816  int $a_id,
817  int $a_usage_hist_nr = 0,
818  string $a_lang = "-"
819  ): array {
820  global $DIC;
821 
822  $ilDB = $DIC->database();
823 
824  $lstr = "";
825  if ($a_lang != "") {
826  $lstr = " AND usage_lang = " . $ilDB->quote($a_lang, "text");
827  }
828  $hist_str = "";
829  if ($a_usage_hist_nr > 0) {
830  $hist_str = " AND usage_hist_nr = " . $ilDB->quote($a_usage_hist_nr, "integer");
831  }
832 
833  $q = "SELECT * FROM mob_usage WHERE " .
834  "usage_type = " . $ilDB->quote($a_type, "text") . " AND " .
835  "usage_id = " . $ilDB->quote($a_id, "integer") .
836  $lstr . $hist_str;
837  $mobs = array();
838  $mob_set = $ilDB->query($q);
839  while ($mob_rec = $ilDB->fetchAssoc($mob_set)) {
840  $mob_id = (int) $mob_rec['id'];
841  if (ilObject::_lookupType($mob_id) === "mob") {
842  $mobs[$mob_id] = $mob_id;
843  }
844  }
845 
846  return $mobs;
847  }
848 
852  public static function _saveUsage(
853  int $a_mob_id,
854  string $a_type,
855  int $a_id,
856  int $a_usage_hist_nr = 0,
857  string $a_lang = "-"
858  ): void {
859  global $DIC;
860 
861  $ilDB = $DIC->database();
863  $log->debug("save usage mob: " . $a_mob_id . ", type " . $a_type . " id: " . $a_id . ", hist: " . $a_usage_hist_nr . ", lang: " . $a_lang);
864  $ilDB->replace(
865  "mob_usage",
866  array(
867  "id" => array("integer", $a_mob_id),
868  "usage_type" => array("text", $a_type),
869  "usage_id" => array("integer", $a_id),
870  "usage_lang" => array("text", $a_lang),
871  "usage_hist_nr" => array("integer", $a_usage_hist_nr)
872  ),
873  array()
874  );
875 
876  self::handleQuotaUpdate(new self($a_mob_id));
877  }
878 
882  public static function _removeUsage(
883  int $a_mob_id,
884  string $a_type,
885  int $a_id,
886  int $a_usage_hist_nr = 0,
887  string $a_lang = "-"
888  ): void {
889  global $DIC;
890 
891  $ilDB = $DIC->database();
892 
893  $q = "DELETE FROM mob_usage WHERE " .
894  " id = " . $ilDB->quote($a_mob_id, "integer") . " AND " .
895  " usage_type = " . $ilDB->quote($a_type, "text") . " AND " .
896  " usage_id = " . $ilDB->quote($a_id, "integer") . " AND " .
897  " usage_lang = " . $ilDB->quote($a_lang, "text") . " AND " .
898  " usage_hist_nr = " . $ilDB->quote($a_usage_hist_nr, "integer");
899  $ilDB->manipulate($q);
900 
901  self::handleQuotaUpdate(new self($a_mob_id));
902  }
903 
907  public function getUsages(
908  bool $a_include_history = true
909  ): array {
910  return self::lookupUsages($this->getId(), $a_include_history);
911  }
912 
918  public static function lookupUsages(
919  int $a_id,
920  bool $a_include_history = true
921  ): array {
922  global $DIC;
923 
924  $ilDB = $DIC->database();
925 
926  $hist_str = "";
927  if ($a_include_history) {
928  $hist_str = ", usage_hist_nr";
929  }
930  // get usages in pages
931  $q = "SELECT DISTINCT usage_type, usage_id, usage_lang" . $hist_str . " FROM mob_usage WHERE id = " .
932  $ilDB->quote($a_id, "integer");
933 
934  if (!$a_include_history) {
935  $q .= " AND usage_hist_nr = " . $ilDB->quote(0, "integer");
936  }
937 
938  $us_set = $ilDB->query($q);
939  $ret = array();
940  while ($us_rec = $ilDB->fetchAssoc($us_set)) {
941  $ut = "";
942  $ct = 0;
943  if (is_int(strpos($us_rec["usage_type"], ":"))) {
944  $us_arr = explode(":", $us_rec["usage_type"]);
945  $ut = $us_arr[1];
946  $ct = $us_arr[0];
947  }
948 
949  // check whether page exists
950  $skip = false;
951  if ($ut == "pg") {
952  if (!ilPageObject::_exists($ct, $us_rec["usage_id"])) {
953  $skip = true;
954  }
955  }
956 
957  if (!$skip) {
958  $ret[] = array(
959  "type" => $us_rec["usage_type"],
960  "id" => $us_rec["usage_id"],
961  "lang" => $us_rec["usage_lang"],
962  "hist_nr" => ($us_rec["usage_hist_nr"] ?? 0)
963  );
964  }
965  }
966 
967  // get usages in media pools
968  $q = "SELECT DISTINCT mep_id FROM mep_tree JOIN mep_item ON (child = obj_id) WHERE mep_item.foreign_id = " .
969  $ilDB->quote($a_id, "integer") . " AND mep_item.type = " . $ilDB->quote("mob", "text");
970  $us_set = $ilDB->query($q);
971  while ($us_rec = $ilDB->fetchAssoc($us_set)) {
972  $ret[] = array("type" => "mep",
973  "id" => $us_rec["mep_id"]);
974  }
975 
976  // get usages in news items (media casts)
977  $news_usages = ilNewsItem::_lookupMediaObjectUsages($a_id);
978  foreach ($news_usages as $nu) {
979  $ret[] = $nu;
980  }
981 
982 
983  // get usages in map areas
984  $q = "SELECT DISTINCT mob_id FROM media_item it, map_area area " .
985  " WHERE area.item_id = it.id " .
986  " AND area.link_type = " . $ilDB->quote("int", "text") . " " .
987  " AND area.target = " . $ilDB->quote("il__mob_" . $a_id, "text");
988  $us_set = $ilDB->query($q);
989  while ($us_rec = $ilDB->fetchAssoc($us_set)) {
990  $ret[] = array("type" => "map",
991  "id" => $us_rec["mob_id"]);
992  }
993 
994  // get usages in personal clipboards
995  $users = ilObjUser::_getUsersForClipboadObject("mob", $a_id);
996  foreach ($users as $user) {
997  $ret[] = array("type" => "clip",
998  "id" => $user);
999  }
1000 
1001  return $ret;
1002  }
1003 
1008  public static function getParentObjectIdForUsage(
1009  array $a_usage,
1010  bool $a_include_all_access_obj_ids = false
1011  ): ?int {
1012  $cont_type = "";
1013  if (is_int(strpos($a_usage["type"], ":"))) {
1014  $us_arr = explode(":", $a_usage["type"]);
1015  $type = $us_arr[1];
1016  $cont_type = $us_arr[0];
1017  } else {
1018  $type = $a_usage["type"];
1019  }
1020 
1021  $id = $a_usage["id"];
1022  $obj_id = null;
1023 
1024  switch ($type) {
1025  // RTE / tiny mce
1026  case "html":
1027 
1028  switch ($cont_type) {
1029  case "qpl":
1030  // Question Pool *Question* Text (Test)
1032  if (isset($qinfo["original_id"]) && $qinfo["original_id"] > 0) {
1033  $obj_id = ilObjTest::_lookupTestObjIdForQuestionId($id); // usage in test
1034  } else {
1035  $obj_id = (int) ($qinfo["obj_fi"] ?? 0); // usage in pool
1036  }
1037  break;
1038 
1039  case "spl":
1040  // Question Pool *Question* Text (Survey)
1042  if ($quest) {
1043  $parent_id = $quest->getObjId();
1044 
1045  // pool question copy - find survey, do not use pool itself
1046  if ($quest->getOriginalId() &&
1047  ilObject::_lookupType($parent_id) == "spl") {
1049  }
1050  // original question (in pool or survey)
1051  else {
1052  $obj_id = (int) $parent_id;
1053  }
1054 
1055  unset($quest);
1056  }
1057  break;
1058 
1059  case "exca":
1060  // Exercise assignment
1061  $returned_pk = $a_usage['id'];
1062  // #15995 - we are just checking against exercise object
1063  $obj_id = ilExSubmission::lookupExerciseIdForReturnedId($returned_pk);
1064  break;
1065 
1066  case "frm":
1067  // Forum
1068  $post_pk = $a_usage['id'];
1069  $oPost = new ilForumPost($post_pk);
1070  $frm_pk = $oPost->getForumId();
1071  $obj_id = ilForum::_lookupObjIdForForumId($frm_pk);
1072  break;
1073 
1074 
1075  case "frm~d":
1076  $draft_id = $a_usage['id'];
1077  $oDraft = ilForumPostDraft::newInstanceByDraftId($draft_id);
1078 
1079  $frm_pk = $oDraft->getForumId();
1080  $obj_id = ilForum::_lookupObjIdForForumId($frm_pk);
1081  break;
1082  case "frm~h":
1083  $history_id = $a_usage['id'];
1084  $oHistoryDraft = new ilForumDraftsHistory($history_id);
1085  $oDraft = ilForumPostDraft::newInstanceByDraftId($oHistoryDraft->getDraftId());
1086 
1087  $frm_pk = $oDraft->getForumId();
1088  $obj_id = ilForum::_lookupObjIdForForumId($frm_pk);
1089  break;
1090  // temporary items (per user)
1091  case "frm~":
1092  case "exca~":
1093  $obj_id = (int) $a_usage['id'];
1094  break;
1095 
1096  // "old" category pages
1097  case "cat":
1098  // InfoScreen Text
1099  case "tst":
1100  case "svy":
1101  // data collection
1102  case "dcl":
1103  $obj_id = (int) $id;
1104  break;
1105  }
1106  break;
1107 
1108  // page editor
1109  case "pg":
1110 
1111  switch ($cont_type) {
1112  // question feedback // parent obj id is q id
1113  case "qfbg":
1114  case "qpl":
1115 
1116  if ($cont_type == "qfbg") {
1118  }
1119 
1120  // Question Pool Question Pages
1122  if ($qinfo["original_id"] > 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  $pinfo = ilPCQuestion::_getPageForQuestionId($id, "sahs");
1133  if ($pinfo && $pinfo["parent_type"] == "sahs") {
1134  $obj_id = (int) ilSCORM2004Node::_lookupSLMID($pinfo["page_id"]);
1135  }
1136  }
1137  break;
1138 
1139  case "lm":
1140  // learning modules
1141  $obj_id = ilLMObject::_lookupContObjID($id);
1142  break;
1143 
1144  case "gdf":
1145  // glossary definition
1147  $obj_id = (int) ilGlossaryTerm::_lookGlossaryID($term_id);
1148  break;
1149 
1150  case "wpg":
1151  // wiki page
1152  $obj_id = (int) ilWikiPage::lookupObjIdByPage($id);
1153  break;
1154 
1155  case "sahs":
1156  // sahs page
1157  // can this implementation be used for other content types, too?
1158  $obj_id = ilPageObject::lookupParentId($id, 'sahs');
1159  break;
1160 
1161  case "prtf":
1162  // portfolio
1164  break;
1165 
1166  case "prtt":
1167  // portfolio template
1169  break;
1170 
1171  case "blp":
1172  // blog
1173  $obj_id = ilPageObject::lookupParentId($id, 'blp');
1174  break;
1175 
1176  case "impr":
1177  // imprint page - always id 1
1178  // fallthrough
1179 
1180  case "crs":
1181  case "grp":
1182  case "cat":
1183  case "fold":
1184  case "root":
1185  case "cont":
1186  case "copa":
1187  case "cstr":
1188  // repository pages
1189  $obj_id = $id;
1190  break;
1191  }
1192  break;
1193 
1194  // Media Pool
1195  case "mep":
1196  $obj_id = $id;
1197  break;
1198 
1199  // News Context Object (e.g. MediaCast)
1200  case "news":
1202  break;
1203  }
1204 
1205  return $obj_id;
1206  }
1207 
1211  public static function _resizeImage(
1212  string $a_file,
1213  int $a_width,
1214  int $a_height,
1215  bool $a_constrain_prop = false
1216  ): string {
1217  $file_path = pathinfo($a_file);
1218  $location = substr($file_path["basename"], 0, strlen($file_path["basename"]) -
1219  strlen($file_path["extension"]) - 1) . "_" .
1220  $a_width . "_" .
1221  $a_height . "." . $file_path["extension"];
1222  $target_file = $file_path["dirname"] . "/" .
1223  $location;
1225  $a_file,
1226  $target_file,
1227  $a_width,
1228  $a_height,
1229  $a_constrain_prop
1230  );
1231 
1232  return $location;
1233  }
1234 
1238  public static function getMimeType(
1239  string $a_file,
1240  bool $a_external = false
1241  ): string {
1242  $mime = MimeType::lookupMimeType($a_file, MimeType::APPLICATION__OCTET_STREAM, $a_external);
1243  return $mime;
1244  }
1245 
1246  public static function _determineWidthHeight(
1247  string $a_format,
1248  string $a_type,
1249  string $a_file,
1250  string $a_reference,
1251  bool $a_constrain_proportions,
1252  bool $a_use_original,
1253  ?int $a_user_width = null,
1254  ?int $a_user_height = null
1255  ): array {
1256  global $DIC;
1257 
1258  $lng = $DIC->language();
1259  $size = [];
1260  $wr = 0;
1261  $hr = 0;
1262  $width = 0;
1263  $height = 0;
1264 
1265  // determine width and height of known image types
1266  //$width = 640;
1267  //$height = 360;
1268  $info = "";
1269 
1270  /*
1271  if ($a_format == "audio/mpeg") {
1272  $width = 300;
1273  $height = 20;
1274  }*/
1275 
1276  if (ilUtil::deducibleSize($a_format)) {
1277  if ($a_type == "File") {
1278  $size = ilMediaImageUtil::getImageSize($a_file);
1279  } else {
1280  $size = ilMediaImageUtil::getImageSize($a_reference);
1281  }
1282  }
1283 
1284  if (!isset($size[0])) {
1285  $size[0] = 0;
1286  }
1287  if (!isset($size[1])) {
1288  $size[1] = 0;
1289  }
1290 
1291  if ($a_use_original) {
1292  if ($size[0] > 0 && $size[1] > 0) {
1293  //$width = $size[0];
1294  //$height = $size[1];
1295  $width = "";
1296  $height = "";
1297  } else {
1298  $info = $lng->txt("cont_could_not_determine_resource_size");
1299  }
1300  } else {
1301  $w = $a_user_width;
1302  $h = $a_user_height;
1303  $width = $w;
1304  $height = $h;
1305  //echo "<br>C-$width-$height-";
1306  if (ilUtil::deducibleSize($a_format) && $a_constrain_proportions) {
1307  if ($size[0] > 0 && $size[1] > 0) {
1308  if ($w > 0) {
1309  $wr = $size[0] / $w;
1310  }
1311  if ($h > 0) {
1312  $hr = $size[1] / $h;
1313  }
1314  //echo "<br>+".$wr."+".$size[0]."+".$w."+";
1315  //echo "<br>+".$hr."+".$size[1]."+".$h."+";
1316  $r = max($wr, $hr);
1317  if ($r > 0) {
1318  $width = (int) round($size[0] / $r);
1319  $height = (int) round($size[1] / $r);
1320  }
1321  }
1322  }
1323  //echo "<br>D-$width-$height-";
1324  }
1325  //echo "<br>E-$width-$height-";
1326 
1327  if ($width == 0 && is_null($a_user_width)) {
1328  $width = "";
1329  }
1330  if ($height == 0 && is_null($a_user_height)) {
1331  $height = "";
1332  }
1333  return array("width" => $width, "height" => $height, "info" => $info);
1334  }
1335 
1336  public function getDataDirectory(): string
1337  {
1338  return ilFileUtils::getWebspaceDir() . "/mobs/mm_" . $this->getId();
1339  }
1340 
1344  public static function _saveTempFileAsMediaObject(
1345  string $name,
1346  string $tmp_name,
1347  bool $upload = true
1348  ): ilObjMediaObject {
1349  // create dummy object in db (we need an id)
1350  $media_object = new ilObjMediaObject();
1351  $media_object->setTitle($name);
1352  $media_object->setDescription("");
1353  $media_object->create();
1354 
1355  // determine and create mob directory, move uploaded file to directory
1356  $media_object->createDirectory();
1357  $mob_dir = ilObjMediaObject::_getDirectory($media_object->getId());
1358 
1359  $media_item = new ilMediaItem();
1360  $media_object->addMediaItem($media_item);
1361  $media_item->setPurpose("Standard");
1362 
1363  $file = $mob_dir . "/" . $name;
1364  if ($upload) {
1365  ilFileUtils::moveUploadedFile($tmp_name, $name, $file);
1366  } else {
1367  copy($tmp_name, $file);
1368  }
1369  // get mime type
1371  $location = $name;
1372  // set real meta and object data
1373  $media_item->setFormat($format);
1374  $media_item->setLocation($location);
1375  $media_item->setLocationType("LocalFile");
1376  $media_object->setTitle($name);
1377  $media_object->setDescription($format);
1378 
1380  $size = ilMediaImageUtil::getImageSize($file);
1381  $media_item->setWidth($size[0]);
1382  $media_item->setHeight($size[1]);
1383  }
1384  $media_item->setHAlign("Left");
1385 
1386  self::renameExecutables($mob_dir);
1387  ilMediaSvgSanitizer::sanitizeDir($mob_dir); // see #20339
1388 
1389  $media_object->update();
1390 
1391  return $media_object;
1392  }
1393 
1397  public function uploadAdditionalFile(
1398  string $a_name,
1399  string $tmp_name,
1400  string $a_subdir = "",
1401  string $a_mode = "move_uploaded"
1402  ): void {
1403  $a_subdir = str_replace("..", "", $a_subdir);
1404  $dir = $mob_dir = ilObjMediaObject::_getDirectory($this->getId());
1405  if ($a_subdir != "") {
1406  $dir .= "/" . $a_subdir;
1407  }
1409  if ($a_mode == "rename") {
1410  ilFileUtils::rename($tmp_name, $dir . "/" . $a_name);
1411  } else {
1412  ilFileUtils::moveUploadedFile($tmp_name, $a_name, $dir . "/" . $a_name, true, $a_mode);
1413  }
1414  self::renameExecutables($mob_dir);
1415  ilMediaSvgSanitizer::sanitizeDir($mob_dir); // see #20339
1416  }
1417 
1418  public function uploadSrtFile(
1419  string $a_tmp_name,
1420  string $a_language,
1421  string $a_mode = "move_uploaded"
1422  ): bool {
1423  if (is_file($a_tmp_name) && $a_language != "") {
1424  $this->uploadAdditionalFile("subtitle_" . $a_language . ".srt", $a_tmp_name, "srt", $a_mode);
1425  return true;
1426  }
1427  return false;
1428  }
1429 
1430  public function getSrtFiles(): array
1431  {
1432  $srt_dir = ilObjMediaObject::_getDirectory($this->getId()) . "/srt";
1433 
1434  if (!is_dir($srt_dir)) {
1435  return array();
1436  }
1437 
1438  $items = ilFileUtils::getDir($srt_dir);
1439 
1440  $srt_files = array();
1441  foreach ($items as $i) {
1442  if (!in_array($i["entry"], array(".", "..")) && $i["type"] == "file") {
1443  $name = explode(".", $i["entry"]);
1444  if ($name[1] == "srt" && substr($name[0], 0, 9) == "subtitle_") {
1445  $srt_files[] = array("file" => $i["entry"],
1446  "full_path" => "srt/" . $i["entry"], "language" => substr($name[0], 9, 2));
1447  }
1448  }
1449  }
1450 
1451  return $srt_files;
1452  }
1453 
1457  public function makeThumbnail(
1458  string $a_file,
1459  string $a_thumbname,
1460  string $a_format = "png",
1461  int $a_size = 80
1462  ): void {
1463  $size = (int) $a_size;
1464  $m_dir = ilObjMediaObject::_getDirectory($this->getId());
1466  $file = $m_dir . "/" . $a_file;
1467 
1468  $mime = ilObjMediaObject::getMimeType($file);
1469  $wh = ilMediaImageUtil::getImageSize($file);
1470 
1471  // see #8602
1472  if ($size > (int) $wh[0] && $size > $wh[1]) {
1473  $a_size = "";
1474  }
1475 
1476  $m_dir = ilObjMediaObject::_getDirectory($this->getId());
1478  self::_createThumbnailDirectory($this->getId());
1480  $m_dir . "/" . $a_file,
1481  $t_dir . "/" . $a_thumbname,
1482  $a_format,
1483  (string) $a_size
1484  );
1485  }
1486 
1487  public static function getThumbnailPath(
1488  int $a_mob_id,
1489  string $a_thumbname
1490  ): string {
1491  $t_dir = ilObjMediaObject::_getThumbnailDirectory($a_mob_id);
1492  return $t_dir . "/" . $a_thumbname;
1493  }
1494 
1495  public function removeAdditionalFile(
1496  string $a_file
1497  ): void {
1498  $file = str_replace("..", "", $a_file);
1499  $file = ilObjMediaObject::_getDirectory($this->getId()) . "/" . $file;
1500  if (is_file($file)) {
1501  unlink($file);
1502  }
1503  }
1504 
1505 
1510  public function getLinkedMediaObjects(
1511  array $a_ignore = []
1512  ): array {
1513  $linked = array();
1514 
1515  // get linked media objects (map areas)
1516  $med_items = $this->getMediaItems();
1517 
1518  foreach ($med_items as $med_item) {
1519  $int_links = ilMapArea::_getIntLinks($med_item->getId());
1520  foreach ($int_links as $k => $int_link) {
1521  if ($int_link["Type"] == "MediaObject") {
1522  $l_id = ilInternalLink::_extractObjIdOfTarget($int_link["Target"]);
1523  if (ilObject::_exists($l_id)) {
1524  if (!in_array($l_id, $linked) &&
1525  !in_array($l_id, $a_ignore)) {
1526  $linked[] = $l_id;
1527  }
1528  }
1529  }
1530  }
1531  }
1532  //var_dump($linked);
1533  return $linked;
1534  }
1535 
1540  public static function getRestrictedFileTypes(): array
1541  {
1542  return array_filter(self::getAllowedFileTypes(), function ($v) {
1543  return !in_array($v, self::getForbiddenFileTypes());
1544  });
1545  }
1546 
1550  public static function getForbiddenFileTypes(): array
1551  {
1552  $mset = new ilSetting("mobs");
1553  if (trim((string) $mset->get("black_list_file_types")) === "") {
1554  return array();
1555  }
1556  return array_map(
1557  function ($v) {
1558  return strtolower(trim($v));
1559  },
1560  explode(",", $mset->get("black_list_file_types"))
1561  );
1562  }
1563 
1567  public static function getAllowedFileTypes(): array
1568  {
1569  $mset = new ilSetting("mobs");
1570  if (trim((string) $mset->get("restricted_file_types")) === "") {
1571  return array();
1572  }
1573  return array_map(
1574  function ($v) {
1575  return strtolower(trim($v));
1576  },
1577  explode(",", $mset->get("restricted_file_types"))
1578  );
1579  }
1580 
1581  public static function isTypeAllowed(
1582  string $a_type
1583  ): bool {
1584  if (in_array($a_type, self::getForbiddenFileTypes())) {
1585  return false;
1586  }
1587  if (count(self::getAllowedFileTypes()) == 0 || in_array($a_type, self::getAllowedFileTypes())) {
1588  return true;
1589  }
1590  return false;
1591  }
1592 
1596  public function duplicate(): ilObjMediaObject
1597  {
1598  $new_obj = new ilObjMediaObject();
1599  $new_obj->setTitle($this->getTitle());
1600  $new_obj->setDescription($this->getDescription());
1601 
1602  // media items
1603  foreach ($this->getMediaItems() as $key => $val) {
1604  $new_obj->addMediaItem($val);
1605  }
1606 
1607  $new_obj->create(false, true);
1608 
1609  // files
1610  $new_obj->createDirectory();
1611  self::_createThumbnailDirectory($new_obj->getId());
1614  ilObjMediaObject::_getDirectory($new_obj->getId())
1615  );
1618  ilObjMediaObject::_getThumbnailDirectory($new_obj->getId())
1619  );
1620 
1621  // meta data
1622  $md = new ilMD(0, $this->getId(), "mob");
1623  $new_md = $md->cloneMD(0, $new_obj->getId(), "mob");
1624 
1625  return $new_obj;
1626  }
1627 
1628  public function uploadVideoPreviewPic(
1629  array $a_prevpic
1630  ): void {
1631  // remove old one
1632  if ($this->getVideoPreviewPic(true) != "") {
1633  $this->removeAdditionalFile($this->getVideoPreviewPic(true));
1634  }
1635 
1636  $pi = pathinfo($a_prevpic["name"]);
1637  $ext = $pi["extension"];
1638  if (in_array($ext, array("jpg", "jpeg", "png"))) {
1639  $this->uploadAdditionalFile("mob_vpreview." . $ext, $a_prevpic["tmp_name"]);
1640  }
1641  }
1642 
1643  public function generatePreviewPic(
1644  int $a_width,
1645  int $a_height,
1646  int $sec = 1
1647  ): void {
1649  $logger = $GLOBALS['DIC']->logger()->mob();
1650 
1651  $item = $this->getMediaItem("Standard");
1652  if ($item->getFormat() === "image/svg+xml") {
1653  return;
1654  }
1655 
1656  if ($item->getLocationType() == "LocalFile") {
1657  if (is_int(strpos($item->getFormat(), "image/"))) {
1658  $a_width = $a_height = 400;
1659 
1660 
1661  $dir = ilObjMediaObject::_getDirectory($this->getId());
1662  $file = $dir . "/" .
1663  $item->getLocation();
1664  if (is_file($file)) {
1665  if (ilShellUtil::isConvertVersionAtLeast("6.3.8-3")) {
1668  $file
1669  ) . "[0] -geometry " . $a_width . "x" . $a_height . "^ -gravity center -extent " . $a_width . "x" . $a_height . " PNG:" . $dir . "/mob_vpreview.png"
1670  );
1671  } else {
1672  ilShellUtil::convertImage($file, $dir . "/mob_vpreview.png", "PNG", $a_width . "x" . $a_height);
1673  }
1674  }
1675  }
1676  }
1677 
1678  $logger->debug("Generate preview pic...");
1679  $logger->debug("..." . $item->getFormat());
1680  if (is_int(strpos($item->getFormat(), "video/mp4"))) {
1681  try {
1682  if ($sec < 0) {
1683  $sec = 0;
1684  }
1685  if ($this->getVideoPreviewPic() != "") {
1686  $this->removeAdditionalFile($this->getVideoPreviewPic(true));
1687  }
1688  $med = $this->getMediaItem("Standard");
1689  if ($med->getLocationType() == "LocalFile") {
1690  $mob_file = ilObjMediaObject::_getDirectory($this->getId()) . "/" . $med->getLocation();
1691  } else {
1692  $mob_file = $med->getLocation();
1693  }
1694  $logger->debug(
1695  "...extract " . $mob_file . " in " .
1697  );
1699  $mob_file,
1700  "mob_vpreview.png",
1702  $sec
1703  );
1704  } catch (ilException $e) {
1706 
1707  $message = '';
1708  if (is_array($ret) && count($ret) > 0) {
1709  $message = "\n" . implode("\n", $ret);
1710  }
1711 
1712  $logger->warning($e->getMessage() . $message);
1713  $logger->logStack(ilLogLevel::WARNING);
1714  }
1715  }
1716  }
1717 
1718  public function getVideoPreviewPic(
1719  bool $a_filename_only = false
1720  ): string {
1721  $dir = ilObjMediaObject::_getDirectory($this->getId());
1722  $ppics = array("mob_vpreview.jpg",
1723  "mob_vpreview.jpeg",
1724  "mob_vpreview.png");
1725  foreach ($ppics as $p) {
1726  if (is_file($dir . "/" . $p)) {
1727  if ($a_filename_only) {
1728  return $p;
1729  } else {
1730  return $dir . "/" . $p;
1731  }
1732  }
1733  }
1734  return "";
1735  }
1736 
1740  public static function fixFilename(
1741  string $a_name
1742  ): string {
1743  $a_name = ilFileUtils::getASCIIFilename($a_name);
1744 
1745  $rchars = array("`", "=", "$", "{", "}", "'", ";", " ", "(", ")");
1746  $a_name = str_replace($rchars, "_", $a_name);
1747  $a_name = str_replace("__", "_", $a_name);
1748  return $a_name;
1749  }
1750 
1751 
1755  public function getMultiSrtUploadDir(): string
1756  {
1757  return ilObjMediaObject::_getDirectory($this->getId()) . "/srt/tmp";
1758  }
1759 
1760 
1765  array $a_file
1766  ): void {
1767  $lng = $this->lng;
1768 
1769  if (!is_file($a_file["tmp_name"])) {
1770  throw new ilMediaObjectsException($lng->txt("mob_file_could_not_be_uploaded"));
1771  }
1772 
1773  $dir = $this->getMultiSrtUploadDir();
1774  ilFileUtils::delDir($dir, true);
1776  ilFileUtils::moveUploadedFile($a_file["tmp_name"], "multi_srt.zip", $dir . "/" . "multi_srt.zip");
1777  ilFileUtils::unzip($dir . "/multi_srt.zip", true);
1778  }
1779 
1783  public function clearMultiSrtDirectory(): void
1784  {
1786  }
1787 
1791  public function getMultiSrtFiles(): array
1792  {
1793  $items = array();
1794 
1796 
1797  $dir = $this->getMultiSrtUploadDir();
1798  $files = ilFileUtils::getDir($dir);
1799  foreach ($files as $k => $i) {
1800  // check directory
1801  if ($i["type"] == "file" && !in_array($k, array(".", ".."))) {
1802  if (pathinfo($k, PATHINFO_EXTENSION) == "srt") {
1803  $lang = "";
1804  if (substr($k, strlen($k) - 7, 1) == "_") {
1805  $lang = substr($k, strlen($k) - 6, 2);
1806  if (!in_array($lang, $lang_codes)) {
1807  $lang = "";
1808  }
1809  }
1810  $items[] = array("filename" => $k, "lang" => $lang);
1811  }
1812  }
1813  }
1814  return $items;
1815  }
1816 
1817  public static function renameExecutables(
1818  string $a_dir
1819  ): void {
1821  if (!self::isTypeAllowed("html")) {
1822  ilFileUtils::rRenameSuffix($a_dir, "html", "sec"); // see #20187
1823  }
1824  }
1825 
1826  public function getExternalMetadata(): void
1827  {
1828  // see https://oembed.com/
1829  $st_item = $this->getMediaItem("Standard");
1830  if ($st_item->getLocationType() == "Reference") {
1831  if (ilExternalMediaAnalyzer::isVimeo($st_item->getLocation())) {
1832  $st_item->setFormat("video/vimeo");
1833  $par = ilExternalMediaAnalyzer::extractVimeoParameters($st_item->getLocation());
1834  $meta = ilExternalMediaAnalyzer::getVimeoMetadata($par["id"]);
1835  $this->setTitle($meta["title"] ?? "");
1836  $description = str_replace("\n", "", $meta["description"] ?? "");
1837  $description = str_replace(["<br>", "<br />"], ["\n", "\n"], $description);
1838  $description = strip_tags($description);
1839  $this->setDescription($description);
1840  $st_item->setDuration((int) ($meta["duration"] ?? 0));
1841  $url = parse_url($meta["thumbnail_url"] ?? "");
1842  $file = basename($url["path"]);
1843  $ext = pathinfo($file, PATHINFO_EXTENSION);
1844  if ($ext == "") {
1845  $ext = "jpg";
1846  }
1847  copy(
1848  $meta["thumbnail_url"],
1849  ilObjMediaObject::_getDirectory($this->getId()) . "/mob_vpreview." .
1850  $ext
1851  );
1852  }
1853  if (ilExternalMediaAnalyzer::isYoutube($st_item->getLocation())) {
1854  $st_item->setFormat("video/youtube");
1855  $par = ilExternalMediaAnalyzer::extractYoutubeParameters($st_item->getLocation());
1856  try {
1858  $this->setTitle($meta["title"] ?? "");
1859  $description = str_replace("\n", "", $meta["description"] ?? "");
1860  } catch (Exception $e) {
1861  $this->setTitle($st_item->getLocation());
1862  $description = "";
1863  }
1864  $description = str_replace(["<br>", "<br />"], ["\n", "\n"], $description);
1865  $description = strip_tags($description);
1866  $this->setDescription($description);
1867  $st_item->setDuration((int) ($meta["duration"] ?? 0));
1868  $thumbnail_url = $meta["thumbnail_url"] ?? "";
1869  $url = parse_url($thumbnail_url);
1870  if ($thumbnail_url !== "") {
1871  $file = basename($url["path"]);
1872  copy(
1873  $meta["thumbnail_url"],
1874  ilObjMediaObject::_getDirectory($this->getId()) . "/mob_vpreview." .
1875  pathinfo($file, PATHINFO_EXTENSION)
1876  );
1877  }
1878  }
1879  }
1880  }
1881 }
static getWebspaceDir(string $mode="filesystem")
get webspace directory
static _getThumbnailDirectory(int $a_mob_id, string $a_mode="filesystem")
get directory for files of media object
static getLastReturnValues()
Get last return values.
static _lookupStandardItemPath(int $a_mob_id, bool $a_url_encode=false, bool $a_web=true)
Get path for standard item.
static sanitizeDir(string $a_path)
Sanitize directory recursively.
string $type
static _writeTitle(int $obj_id, string $title)
write title to db (static)
getLinkedMediaObjects(array $a_ignore=[])
Get all media objects linked in map areas of this media object.
const IL_INST_ID
Definition: constants.php:40
static getLogger(string $a_component_id)
Get component logger.
static _lookupLocationForMobId(int $a_mob_id, string $a_purpose)
static _lookupTestObjIdForQuestionId($a_q_id)
Get test Object ID for question ID.
$mobs
Definition: imgupload.php:70
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...
makeThumbnail(string $a_file, string $a_thumbname, string $a_format="png", int $a_size=80)
Make thumbnail.
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)
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.
static isConvertVersionAtLeast(string $a_version)
Compare convert version numbers.
addMediaItem(ilMediaItem $a_item)
getMultiSrtFiles()
Get all srt files of srt multi upload.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static _getIntLinks(int $a_item_id)
get all internal links of a media items map areas
debug(string $a_message, array $a_context=array())
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 _createThumbnailDirectory(int $a_obj_id)
Create thumbnail directory.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
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 escapeShellArg(string $a_arg)
static _resizeImage(string $a_file, int $a_width, int $a_height, bool $a_constrain_prop=false)
Resize image and return new image file ("_width_height" string appended)
static _getMediaItemsOfMOb(ilObjMediaObject $a_mob)
Read media items into(!) media object (static)
static isVimeo(string $a_location)
Identify Vimeo links.
static extractImage(string $a_file, string $a_target_filename, string $a_target_dir="", int $a_sec=1)
Extract image from video file.
static makeDirParents(string $a_dir)
Create a new directory and all parent directories.
static secureUrl(string $url)
$path
Definition: ltiservices.php:32
static renameExecutables(string $a_dir)
static unzip(string $path_to_zip_file, bool $overwrite_existing=false, bool $unpack_flat=false)
Class ilForumDraftHistory.
static getASCIIFilename(string $a_filename)
static deleteAllItemsOfMob(int $a_mob_id)
setAlias(bool $a_is_alias)
static handleQuotaUpdate(ilObjMediaObject $a_mob)
global $DIC
Definition: feed.php:28
static renameExecutables(string $a_dir)
clearMultiSrtDirectory()
Clear multi srt directory.
if($format !==null) $name
Definition: metadata.php:247
setDescription(string $desc)
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
escapeProperty(string $a_value)
Escape property (e.g.
uploadSrtFile(string $a_tmp_name, string $a_language, string $a_mode="move_uploaded")
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)
getVideoPreviewPic(bool $a_filename_only=false)
exportXML(ilXmlWriter $a_xml_writer, int $a_inst=0)
const CLIENT_ID
Definition: constants.php:41
getMediaItem(string $a_purpose)
get item for media purpose
static createDirectory(string $a_dir, int $a_mod=0755)
create directory
if(!defined('PATH_SEPARATOR')) $GLOBALS['_PEAR_default_error_mode']
Definition: PEAR.php:64
hasPurposeItem(string $purpose)
returns whether object has media item with specific purpose
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
string $key
Consumer key/client ID value.
Definition: System.php:193
$format
Definition: metadata.php:235
static _getQuestionInfo(int $question_id)
static lookupExerciseIdForReturnedId(int $a_returned_id)
Get exercise from submission id (used in ilObjMediaObject)
$xml
Definition: metadata.php:351
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
static convertImage(string $a_from, string $a_to, string $a_target_format="", string $a_geometry="", string $a_background_color="")
convert image
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.
static getForbiddenFileTypes()
Get forbidden file types.
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...
$lang
Definition: xapiexit.php:26
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)
Create new media object and update page in db and return new media object.
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.
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="-")
create(bool $a_create_meta_data=false, bool $a_save_media_items=true)
static getRestrictedFileTypes()
Get restricted file types (this is for the input form, this list will be empty, if "allowed list" is ...
static _lookupTermId(int $a_def_id)
Looks up term id for a definition id.
static getAllowedFileTypes()
Get allowed file types.
__construct(Container $dic, ilPlugin $plugin)
static lookupObjIdByPage(int $a_page_id)
returns the wiki/object id to a given page id
$ilUser
Definition: imgupload.php:34
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
static signFile(string $path_to_file)
const IL_MODE_OUTPUT
static getThumbnailPath(int $a_mob_id, string $a_thumbname)
ilLogger $log
duplicate()
Duplicate media object, return new media object.
$message
Definition: xapiexit.php:32
$url
static rename(string $a_source, string $a_target)
static _getURL(int $a_mob_id)
get directory for files of media object
static _lookupMediaObjectUsages(int $a_mob_id)
Lookup media object usage(s)
getXML(int $a_mode=IL_MODE_FULL, int $a_inst=0, bool $a_sign_locals=false)
get MediaObject XLM Tag
static newInstanceByDraftId(int $draft_id)
getFilesOfDirectory(string $a_subdir="")
Get files of directory.
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
static execConvert(string $args)
execute convert command
raise(string $a_component, string $a_event, array $a_parameter=[])
Raise an event.
static resizeImage(string $a_from, string $a_to, int $a_width, int $a_height, bool $a_constrain_prop=false)
resize image
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)
$i
Definition: metadata.php:41
removeMediaItem(string $a_purpose)
static _lookGlossaryID(int $term_id)
get glossary id form term id