ILIAS  release_9 Revision v9.13-25-g2c18ec4c24f
class.ilObjMediaObject.php
Go to the documentation of this file.
1 <?php
2 
26 
27 define("IL_MODE_ALIAS", 1);
28 define("IL_MODE_OUTPUT", 2);
29 define("IL_MODE_FULL", 3);
30 
35 {
36  private const DEFAULT_PREVIEW_SIZE = 80;
38  protected ilObjUser $user;
39  public bool $is_alias;
40  public string $origin_id;
41  public array $media_items;
42  public bool $contains_int_link;
44 
45  public function __construct(
46  int $a_id = 0
47  ) {
48  global $DIC;
49 
50  $this->user = $DIC->user();
51  $this->app_event_handler = $DIC["ilAppEventHandler"];
52  $this->lng = $DIC->language();
53  $this->is_alias = false;
54  $this->media_items = array();
55  $this->contains_int_link = false;
56  $this->type = "mob";
57  parent::__construct($a_id, false);
58  $this->image_converter = $DIC->fileConverters()->legacyImages();
59  $this->domain = $DIC->mediaObjects()->internal()->domain();
60  }
61 
62  public static function _exists(
63  int $id,
64  bool $reference = false,
65  ?string $type = null
66  ): bool {
67  if (is_int(strpos($id, "_"))) {
69  }
70 
71  if (parent::_exists($id) && ilObject::_lookupType($id) === "mob") {
72  return true;
73  }
74  return false;
75  }
76 
77  public function delete(): bool
78  {
79  $mob_logger = ilLoggerFactory::getLogger('mob');
80  $mob_logger->debug("ilObjMediaObject: Delete called for media object ID '" . $this->getId() . "'.");
81 
82  if (!($this->getId() > 0)) {
83  return false;
84  }
85 
86  $usages = $this->getUsages();
87 
88  $mob_logger->debug("ilObjMediaObject: ... Found " . count($usages) . " usages.");
89 
90  if (count($usages) == 0) {
91  // remove directory
93 
94  // remove thumbnail directory
96 
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 
128  // Update Title and description
129  $md = new ilMD(0, $this->getId(), $this->getType());
130  $md_gen = $md->getGeneral();
131 
132  if (is_object($md_gen)) {
133  ilObject::_writeTitle($this->getId(), $md_gen->getTitle());
134  $this->setTitle($md_gen->getTitle());
135 
136  foreach ($md_gen->getDescriptionIds() as $id) {
137  $md_des = $md_gen->getDescription($id);
138  ilObject::_writeDescription($this->getId(), $md_des->getDescription());
139  $this->setDescription($md_des->getDescription());
140  break;
141  }
142  }
143 
144  break;
145  }
146  return false; // prevent parent from creating ilMD
147  }
148 
149  protected function beforeCreateMetaData(): bool
150  {
151  $ilUser = $this->user;
152 
153  $md_creator = new ilMDCreator(0, $this->getId(), $this->getType());
154  $md_creator->setTitle($this->getTitle());
155  $md_creator->setTitleLanguage($ilUser->getPref('language'));
156  $md_creator->setDescription($this->getDescription());
157  $md_creator->setDescriptionLanguage($ilUser->getPref('language'));
158  $md_creator->setKeywordLanguage($ilUser->getPref('language'));
159  $md_creator->setLanguage($ilUser->getPref('language'));
160  $md_creator->create();
161 
162  return false; // avoid parent to create md
163  }
164 
165  protected function beforeUpdateMetaData(): bool
166  {
167  $md = new ilMD(0, $this->getId(), $this->getType());
168  $md_gen = $md->getGeneral();
169  $md_gen->setTitle($this->getTitle());
170 
171  // sets first description (maybe not appropriate)
172  $md_des_ids = $md_gen->getDescriptionIds();
173  if (count($md_des_ids) > 0) {
174  $md_des = $md_gen->getDescription($md_des_ids[0]);
175  $md_des->setDescription($this->getDescription());
176  $md_des->update();
177  }
178  $md_gen->update();
179  return false;
180  }
181 
182  protected function beforeDeleteMetaData(): bool
183  {
184  // Delete meta data
185  $md = new ilMD(0, $this->getId(), $this->getType());
186  $md->deleteAll();
187 
188  return false;
189  }
190 
191 
192  public function addMediaItem(
193  ilMediaItem $a_item
194  ): void {
195  $this->media_items[] = $a_item;
196  }
197 
198  public function &getMediaItems(): array
199  {
200  return $this->media_items;
201  }
202 
206  public function getMediaItem(
207  string $a_purpose
208  ): ?ilMediaItem {
209  foreach ($this->media_items as $media_item) {
210  if ($media_item->getPurpose() == $a_purpose) {
211  return $media_item;
212  }
213  }
214  return null;
215  }
216 
217  public function removeMediaItem(
218  string $a_purpose
219  ): void {
220  foreach ($this->media_items as $key => $media_item) {
221  if ($media_item->getPurpose() == $a_purpose) {
222  unset($this->media_items[$key]);
223  }
224  }
225  // update numbers and keys
226  $i = 1;
227  $media_items = array();
228  foreach ($this->media_items as $media_item) {
229  $media_items [$i] = $media_item;
230  $media_item->setMobId($this->getId());
231  $media_item->setNr($i);
232  $i++;
233  }
234  $this->media_items = $media_items;
235  }
236 
237  public function removeAllMediaItems(): void
238  {
239  $this->media_items = array();
240  }
241 
242  public function hasFullscreenItem(): bool
243  {
244  return $this->hasPurposeItem("Fullscreen");
245  }
246 
250  public function hasPurposeItem(string $purpose): bool
251  {
252  if (is_object($this->getMediaItem($purpose))) {
253  return true;
254  } else {
255  return false;
256  }
257  }
258 
263  public function read(): void
264  {
265  parent::read();
267  }
268 
269  public function setAlias(bool $a_is_alias): void
270  {
271  $this->is_alias = $a_is_alias;
272  }
273 
274  public function isAlias(): bool
275  {
276  return $this->is_alias;
277  }
278 
282  public function setOriginID(string $a_id): void
283  {
284  $this->origin_id = $a_id;
285  }
286 
287  public function getOriginID(): string
288  {
289  return $this->origin_id;
290  }
291 
292  public function create(bool $a_create_meta_data = false, bool $a_save_media_items = true): int
293  {
294  $id = parent::create();
295 
296  if (!$a_create_meta_data) {
297  $this->createMetaData();
298  }
299 
300  if ($a_save_media_items) {
301  $media_items = $this->getMediaItems();
302  for ($i = 0; $i < count($media_items); $i++) {
303  $item = $media_items[$i];
304  $item->setMobId($this->getId());
305  $item->setNr($i + 1);
306  $item->create();
307  }
308  }
309 
310  self::handleQuotaUpdate($this);
311 
312  $ilAppEventHandler = $this->app_event_handler;
313  $ilAppEventHandler->raise(
314  'Services/MediaObjects',
315  'create',
316  array('object' => $this,
317  'obj_type' => 'mob',
318  'obj_id' => $this->getId())
319  );
320 
321  return $id;
322  }
323 
324  public function update(bool $a_upload = false): bool
325  {
326  parent::update();
327 
328  if (!$a_upload) {
329  $this->updateMetaData();
330  }
331 
332  // iterate all items
333  $media_items = $this->getMediaItems();
335 
336  $j = 1;
337  foreach ($media_items as $key => $val) {
338  $item = $val;
339  if (is_object($item)) {
340  $item->setMobId($this->getId());
341  $item->setNr($j);
342  if ($item->getLocationType() == "Reference") {
343  $item->extractUrlParameters();
344  }
345  $item->create();
346  $j++;
347  }
348  }
349 
350  self::handleQuotaUpdate($this);
351  $ilAppEventHandler = $this->app_event_handler;
352  $ilAppEventHandler->raise(
353  'Services/MediaObjects',
354  'update',
355  array('object' => $this,
356  'obj_type' => 'mob',
357  'obj_id' => $this->getId())
358  );
359 
360  return true;
361  }
362 
366  protected static function handleQuotaUpdate(
367  ilObjMediaObject $a_mob
368  ): void {
369  }
370 
374  public static function _getDirectory(
375  int $a_mob_id
376  ): string {
377  return ilFileUtils::getWebspaceDir() . "/" . self::_getRelativeDirectory($a_mob_id);
378  }
379 
383  public static function _getRelativeDirectory(int $a_mob_id): string
384  {
385  return "mobs/mm_" . $a_mob_id;
386  }
387 
391  public static function _getURL(
392  int $a_mob_id
393  ): string {
394  return ilUtil::getHtmlPath(ilFileUtils::getWebspaceDir() . "/mobs/mm_" . $a_mob_id);
395  }
396 
400  public static function _getThumbnailDirectory(
401  int $a_mob_id,
402  string $a_mode = "filesystem"
403  ): string {
404  return ilFileUtils::getWebspaceDir($a_mode) . "/thumbs/mm_" . $a_mob_id;
405  }
406 
410  public static function _lookupStandardItemPath(
411  int $a_mob_id,
412  bool $a_url_encode = false,
413  bool $a_web = true
414  ): string {
415  return ilObjMediaObject::_lookupItemPath($a_mob_id, $a_url_encode, $a_web, "Standard");
416  }
417 
421  public static function _lookupItemPath(
422  int $a_mob_id,
423  bool $a_url_encode = false,
424  bool $a_web = true,
425  string $a_purpose = ""
426  ): string {
427  if ($a_purpose == "") {
428  $a_purpose = "Standard";
429  }
430  $location = ilMediaItem::_lookupLocationForMobId($a_mob_id, $a_purpose);
431  if (preg_match("/https?\:/i", $location)) {
432  return $location;
433  }
434 
435  if ($a_url_encode) {
436  $location = rawurlencode($location);
437  }
438 
439  $path = ($a_web)
440  ? ILIAS_HTTP_PATH
441  : ".";
442 
443  return $path . "/data/" . CLIENT_ID . "/mobs/mm_" . $a_mob_id . "/" . $location;
444  }
445 
450  public function createDirectory(): void
451  {
454  if (!is_dir($path)) {
455  throw new ilMediaObjectsException("Failed to create directory $path.");
456  }
457  }
458 
462  public static function _createThumbnailDirectory(
463  int $a_obj_id
464  ): void {
466  ilFileUtils::createDirectory(ilFileUtils::getWebspaceDir() . "/thumbs/mm_" . $a_obj_id);
467  }
468 
472  public function getFilesOfDirectory(
473  string $a_subdir = ""
474  ): array {
475  $a_subdir = str_replace("..", "", $a_subdir);
476  $dir = ilObjMediaObject::_getDirectory($this->getId());
477  if ($a_subdir != "") {
478  $dir .= "/" . $a_subdir;
479  }
480 
481  $files = array();
482  if (is_dir($dir)) {
483  $entries = ilFileUtils::getDir($dir);
484  foreach ($entries as $e) {
485  if (is_file($dir . "/" . $e["entry"]) && $e["entry"] != "." && $e["entry"] != "..") {
486  $files[] = $e["entry"];
487  }
488  }
489  }
490  return $files;
491  }
492 
493 
502  public function getXML(
503  int $a_mode = IL_MODE_FULL,
504  int $a_inst = 0,
505  bool $a_sign_locals = false
506  ): string {
507  $ilUser = $this->user;
508  $xml = "";
509  // TODO: full implementation of all parameters
510  //echo "-".$a_mode."-";
511  switch ($a_mode) {
512  case IL_MODE_ALIAS:
513  $xml = "<MediaObject>";
514  $xml .= "<MediaAlias OriginId=\"il__mob_" . $this->getId() . "\"/>";
515  $media_items = $this->getMediaItems();
516  for ($i = 0; $i < count($media_items); $i++) {
517  $item = $media_items[$i];
518  $xml .= "<MediaAliasItem Purpose=\"" . $item->getPurpose() . "\">";
519 
520  // Layout
521  $width = ($item->getWidth() != "")
522  ? "Width=\"" . $item->getWidth() . "\""
523  : "";
524  $height = ($item->getHeight() != "")
525  ? "Height=\"" . $item->getHeight() . "\""
526  : "";
527  $halign = ($item->getHAlign() != "")
528  ? "HorizontalAlign=\"" . $item->getHAlign() . "\""
529  : "";
530  $xml .= "<Layout $width $height $halign />";
531 
532  // Caption
533  if ($item->getCaption() != "") {
534  $xml .= "<Caption Align=\"bottom\">" .
535  $this->escapeProperty($item->getCaption()) . "</Caption>";
536  }
537 
538  // Text Representation
539  if ($item->getTextRepresentation() != "") {
540  $xml .= "<TextRepresentation>" .
541  $this->escapeProperty($item->getTextRepresentation()) . "</TextRepresentation>";
542  }
543 
544  // Parameter
545  $parameters = $item->getParameters();
546  foreach ($parameters as $name => $value) {
547  $xml .= "<Parameter Name=\"$name\" Value=\"" . $this->escapeProperty($value) . "\"/>";
548  }
549  $xml .= $item->getMapAreasXML();
550  $xml .= "</MediaAliasItem>";
551  }
552  break;
553 
554  // for output we need technical sections of meta data
555  case IL_MODE_OUTPUT:
556 
557  // get first technical section
558  // $meta = $this->getMetaData();
559  $xml = "<MediaObject Id=\"il__mob_" . $this->getId() . "\">";
560 
561  $media_items = $this->getMediaItems();
562  for ($i = 0; $i < count($media_items); $i++) {
563  $item = $media_items[$i];
564 
565  $xml .= "<MediaItem Purpose=\"" . $item->getPurpose() . "\">";
566 
567  if ($a_sign_locals && $item->getLocationType() == "LocalFile") {
568  $location = ilWACSignedPath::signFile($this->getDataDirectory() . "/" . $item->getLocation());
569  $location = substr($location, strrpos($location, "/") + 1);
570  } else {
571  $location = $item->getLocation();
572  if ($item->getLocationType() != "LocalFile") { //#25941
574  }
575  }
576 
577  $xml .= "<Location Type=\"" . $item->getLocationType() . "\">" .
578  $this->handleAmps($location) . "</Location>";
579 
580  // Format
581  $xml .= "<Format>" . $item->getFormat() . "</Format>";
582 
583  // Layout
584  $width = ($item->getWidth() != "")
585  ? "Width=\"" . $item->getWidth() . "\""
586  : "";
587  $height = ($item->getHeight() != "")
588  ? "Height=\"" . $item->getHeight() . "\""
589  : "";
590  $halign = ($item->getHAlign() != "")
591  ? "HorizontalAlign=\"" . $item->getHAlign() . "\""
592  : "";
593  $xml .= "<Layout $width $height $halign />";
594 
595  // Caption
596  if ($item->getCaption() != "") {
597  $xml .= "<Caption Align=\"bottom\">" .
598  $this->escapeProperty($item->getCaption()) . "</Caption>";
599  }
600 
601  // Text Representation
602  if ($item->getTextRepresentation() != "") {
603  $xml .= "<TextRepresentation>" .
604  $this->escapeProperty($item->getTextRepresentation()) . "</TextRepresentation>";
605  }
606 
607  // Title
608  if ($this->getTitle() != "") {
609  $xml .= "<Title>" .
610  $this->escapeProperty($this->getTitle()) . "</Title>";
611  }
612 
613  // Parameter
614  $parameters = $item->getParameters();
615  foreach ($parameters as $name => $value) {
616  $xml .= "<Parameter Name=\"$name\" Value=\"" . $this->escapeProperty($value) . "\"/>";
617  }
618  $xml .= $item->getMapAreasXML();
619 
620  // Subtitles
621  if ($item->getPurpose() == "Standard") {
622  $srts = $this->getSrtFiles();
623  foreach ($srts as $srt) {
624  $def = "";
625  $meta_lang = "";
626  if ($ilUser->getLanguage() != $meta_lang &&
627  $ilUser->getLanguage() == $srt["language"]) {
628  $def = ' Default="true" ';
629  }
630  $xml .= "<Subtitle File=\"" . $srt["full_path"] .
631  "\" Language=\"" . $srt["language"] . "\" " . $def . "/>";
632  }
633  }
634  if ($this->getVideoPreviewPic(true)) {
635  $xml .= "<PreviewPic File=\"" . $this->getVideoPreviewPic(true) .
636  "\" />";
637  }
638  $xml .= "</MediaItem>";
639  }
640  break;
641 
642  // full xml for export
643  case IL_MODE_FULL:
644 
645  // $meta = $this->getMetaData();
646  $xml = "<MediaObject>";
647 
648  // meta data
649  $md2xml = new ilMD2XML(0, $this->getId(), $this->getType());
650  $md2xml->setExportMode(true);
651  $md2xml->startExport();
652  $xml .= $md2xml->getXML();
653 
654  $media_items = $this->getMediaItems();
655  for ($i = 0; $i < count($media_items); $i++) {
656  $item = $media_items[$i];
657 
658  // highlight mode
659  $xml .= "<MediaItem Purpose=\"" . $item->getPurpose() . "\">";
660 
661  // Location
662  $xml .= "<Location Type=\"" . $item->getLocationType() . "\">" .
663  $this->handleAmps($item->getLocation()) . "</Location>";
664 
665  // Format
666  $xml .= "<Format>" . $item->getFormat() . "</Format>";
667 
668  // Layout
669  $width = ($item->getWidth() != "")
670  ? "Width=\"" . $item->getWidth() . "\""
671  : "";
672  $height = ($item->getHeight() != "")
673  ? "Height=\"" . $item->getHeight() . "\""
674  : "";
675  $halign = ($item->getHAlign() != "")
676  ? "HorizontalAlign=\"" . $item->getHAlign() . "\""
677  : "";
678  $xml .= "<Layout $width $height $halign />";
679 
680  // Caption
681  if ($item->getCaption() != "") {
682  $xml .= "<Caption Align=\"bottom\">" .
683  str_replace("&", "&amp;", $item->getCaption()) . "</Caption>";
684  }
685 
686  // Text Representation
687  if ($item->getTextRepresentation() != "") {
688  $xml .= "<TextRepresentation>" .
689  str_replace("&", "&amp;", $item->getTextRepresentation()) . "</TextRepresentation>";
690  }
691 
692  // Parameter
693  $parameters = $item->getParameters();
694  foreach ($parameters as $name => $value) {
695  $xml .= "<Parameter Name=\"$name\" Value=\"$value\"/>";
696  }
697  $xml .= $item->getMapAreasXML(true, $a_inst);
698  $xml .= "</MediaItem>";
699  }
700  break;
701  }
702  $xml .= "</MediaObject>";
703  return $xml;
704  }
705 
709  protected function escapeProperty(
710  string $a_value
711  ): string {
712  return htmlspecialchars($a_value);
713  }
714 
715 
719  public function handleAmps(
720  string $a_str
721  ): string {
722  $a_str = str_replace("&amp;", "&", $a_str);
723  $a_str = str_replace("&", "&amp;", $a_str);
724  return $a_str;
725  }
726 
727  public function exportXML(
728  ilXmlWriter $a_xml_writer,
729  int $a_inst = 0
730  ): void {
731  $a_xml_writer->appendXML($this->getXML(IL_MODE_FULL, $a_inst));
732  }
733 
734 
743  public function exportFiles(
744  string $a_target_dir
745  ): void {
746  $subdir = "il_" . IL_INST_ID . "_mob_" . $this->getId();
747  ilFileUtils::makeDir($a_target_dir . "/objects/" . $subdir);
748 
749  $mobdir = ilFileUtils::getWebspaceDir() . "/mobs/mm_" . $this->getId();
750  ilFileUtils::rCopy($mobdir, $a_target_dir . "/objects/" . $subdir);
751  }
752 
753  public function modifyExportIdentifier(
754  string $a_tag,
755  string $a_param,
756  string $a_value
757  ): string {
758  if ($a_tag == "Identifier" && $a_param == "Entry") {
759  $a_value = ilUtil::insertInstIntoID($a_value);
760  }
761 
762  return $a_value;
763  }
764 
765 
767  // EDIT METHODS: these methods act on the media alias in the dom
769 
774  public function setContainsIntLink(
775  bool $a_contains_link
776  ): void {
777  $this->contains_int_link = $a_contains_link;
778  }
779 
784  public function containsIntLink(): bool
785  {
787  }
788 
789  public static function _deleteAllUsages(
790  string $a_type,
791  int $a_id,
792  ?int $a_usage_hist_nr = 0,
793  string $a_lang = "-"
794  ): void {
795  global $DIC;
796 
797  $ilDB = $DIC->database();
798 
799  $and_hist = "";
800  if (!is_null($a_usage_hist_nr)) {
801  $and_hist = " AND usage_hist_nr = " . $ilDB->quote($a_usage_hist_nr, "integer");
802  }
803 
804  $mob_ids = array();
805  $set = $ilDB->query("SELECT id FROM mob_usage" .
806  " WHERE usage_type = " . $ilDB->quote($a_type, "text") .
807  " AND usage_id = " . $ilDB->quote($a_id, "integer") .
808  " AND usage_lang = " . $ilDB->quote($a_lang, "text") .
809  $and_hist);
810  while ($row = $ilDB->fetchAssoc($set)) {
811  $mob_ids[] = $row["id"];
812  }
813 
814  $q = "DELETE FROM mob_usage WHERE usage_type = " .
815  $ilDB->quote($a_type, "text") .
816  " AND usage_id= " . $ilDB->quote($a_id, "integer") .
817  " AND usage_lang = " . $ilDB->quote($a_lang, "text") .
818  $and_hist;
819  $ilDB->manipulate($q);
820 
821  foreach ($mob_ids as $mob_id) {
822  self::handleQuotaUpdate(new self($mob_id));
823  }
824  }
825 
829  public static function _getMobsOfObject(
830  string $a_type,
831  int $a_id,
832  int $a_usage_hist_nr = 0,
833  string $a_lang = "-"
834  ): array {
835  global $DIC;
836 
837  $ilDB = $DIC->database();
838 
839  $lstr = "";
840  if ($a_lang != "") {
841  $lstr = " AND usage_lang = " . $ilDB->quote($a_lang, "text");
842  }
843  $hist_str = "";
844  if ($a_usage_hist_nr > 0) {
845  $hist_str = " AND usage_hist_nr = " . $ilDB->quote($a_usage_hist_nr, "integer");
846  }
847 
848  $q = "SELECT * FROM mob_usage WHERE " .
849  "usage_type = " . $ilDB->quote($a_type, "text") . " AND " .
850  "usage_id = " . $ilDB->quote($a_id, "integer") .
851  $lstr . $hist_str;
852  $mobs = array();
853  $mob_set = $ilDB->query($q);
854  while ($mob_rec = $ilDB->fetchAssoc($mob_set)) {
855  $mob_id = (int) $mob_rec['id'];
856  if (ilObject::_lookupType($mob_id) === "mob") {
857  $mobs[$mob_id] = $mob_id;
858  }
859  }
860 
861  return $mobs;
862  }
863 
867  public static function _saveUsage(
868  int $a_mob_id,
869  string $a_type,
870  int $a_id,
871  int $a_usage_hist_nr = 0,
872  string $a_lang = "-"
873  ): void {
874  global $DIC;
875 
876  $ilDB = $DIC->database();
877 
878  $ilDB->replace(
879  "mob_usage",
880  array(
881  "id" => array("integer", $a_mob_id),
882  "usage_type" => array("text", $a_type),
883  "usage_id" => array("integer", $a_id),
884  "usage_lang" => array("text", $a_lang),
885  "usage_hist_nr" => array("integer", $a_usage_hist_nr)
886  ),
887  array()
888  );
889 
890  self::handleQuotaUpdate(new self($a_mob_id));
891  }
892 
896  public static function _removeUsage(
897  int $a_mob_id,
898  string $a_type,
899  int $a_id,
900  int $a_usage_hist_nr = 0,
901  string $a_lang = "-"
902  ): void {
903  global $DIC;
904 
905  $ilDB = $DIC->database();
906 
907  $q = "DELETE FROM mob_usage WHERE " .
908  " id = " . $ilDB->quote($a_mob_id, "integer") . " AND " .
909  " usage_type = " . $ilDB->quote($a_type, "text") . " AND " .
910  " usage_id = " . $ilDB->quote($a_id, "integer") . " AND " .
911  " usage_lang = " . $ilDB->quote($a_lang, "text") . " AND " .
912  " usage_hist_nr = " . $ilDB->quote($a_usage_hist_nr, "integer");
913  $ilDB->manipulate($q);
914 
915  self::handleQuotaUpdate(new self($a_mob_id));
916  }
917 
921  public function getUsages(
922  bool $a_include_history = true
923  ): array {
924  return self::lookupUsages($this->getId(), $a_include_history);
925  }
926 
932  public static function lookupUsages(
933  int $a_id,
934  bool $a_include_history = true
935  ): array {
936  global $DIC;
937 
938  $ilDB = $DIC->database();
939 
940  $hist_str = "";
941  if ($a_include_history) {
942  $hist_str = ", usage_hist_nr";
943  }
944 
945  // get usages in pages
946  $q = "SELECT DISTINCT usage_type, usage_id, usage_lang" . $hist_str . " FROM mob_usage WHERE id = " .
947  $ilDB->quote($a_id, "integer");
948 
949  if (!$a_include_history) {
950  $q .= " AND usage_hist_nr = " . $ilDB->quote(0, "integer");
951  }
952 
953  $us_set = $ilDB->query($q);
954  $ret = array();
955  while ($us_rec = $ilDB->fetchAssoc($us_set)) {
956  $ut = "";
957  $ct = 0;
958  if (is_int(strpos($us_rec["usage_type"], ":"))) {
959  $us_arr = explode(":", $us_rec["usage_type"]);
960  $ut = $us_arr[1];
961  $ct = $us_arr[0];
962  }
963 
964  // check whether page exists
965  $skip = false;
966  if ($ut == "pg") {
967  if (!ilPageObject::_exists($ct, $us_rec["usage_id"])) {
968  $skip = true;
969  }
970  }
971 
972  if (!$skip) {
973  $ret[] = array(
974  "type" => $us_rec["usage_type"],
975  "id" => $us_rec["usage_id"],
976  "lang" => $us_rec["usage_lang"],
977  "hist_nr" => ($us_rec["usage_hist_nr"] ?? 0)
978  );
979  }
980  }
981 
982  // get usages in media pools
983  $q = "SELECT DISTINCT mep_id FROM mep_tree JOIN mep_item ON (child = obj_id) WHERE mep_item.foreign_id = " .
984  $ilDB->quote($a_id, "integer") . " AND mep_item.type = " . $ilDB->quote("mob", "text");
985  $us_set = $ilDB->query($q);
986  while ($us_rec = $ilDB->fetchAssoc($us_set)) {
987  $ret[] = array("type" => "mep",
988  "id" => $us_rec["mep_id"]);
989  }
990 
991  // get usages in news items (media casts)
992  $news_usages = ilNewsItem::_lookupMediaObjectUsages($a_id);
993  foreach ($news_usages as $nu) {
994  $ret[] = $nu;
995  }
996 
997 
998  // get usages in map areas
999  $q = "SELECT DISTINCT mob_id FROM media_item it, map_area area " .
1000  " WHERE area.item_id = it.id " .
1001  " AND area.link_type = " . $ilDB->quote("int", "text") . " " .
1002  " AND area.target = " . $ilDB->quote("il__mob_" . $a_id, "text");
1003  $us_set = $ilDB->query($q);
1004  while ($us_rec = $ilDB->fetchAssoc($us_set)) {
1005  $ret[] = array("type" => "map",
1006  "id" => $us_rec["mob_id"]);
1007  }
1008 
1009  // get usages in personal clipboards
1010  $users = ilObjUser::_getUsersForClipboadObject("mob", $a_id);
1011  foreach ($users as $user) {
1012  $ret[] = array("type" => "clip",
1013  "id" => $user);
1014  }
1015 
1016  return $ret;
1017  }
1018 
1023  public static function getParentObjectIdForUsage(
1024  array $a_usage,
1025  bool $a_include_all_access_obj_ids = false
1026  ): ?int {
1027  $cont_type = "";
1028  if (is_int(strpos($a_usage["type"], ":"))) {
1029  $us_arr = explode(":", $a_usage["type"]);
1030  $type = $us_arr[1];
1031  $cont_type = $us_arr[0];
1032  } else {
1033  $type = $a_usage["type"];
1034  }
1035 
1036  $id = $a_usage["id"];
1037  $obj_id = null;
1038 
1039  switch ($type) {
1040  // RTE / tiny mce
1041  case "html":
1042 
1043  switch ($cont_type) {
1044  case "qpl":
1045  // Question Pool *Question* Text (Test)
1046  global $DIC;
1047  $qinfo = $DIC->testQuestionPool()->questionInfo()->getQuestionInfo($id);
1048  if (isset($qinfo["original_id"]) && $qinfo["original_id"] > 0) {
1049  $obj_id = ilObjTest::_lookupTestObjIdForQuestionId($id); // usage in test
1050  } else {
1051  $obj_id = (int) ($qinfo["obj_fi"] ?? 0); // usage in pool
1052  }
1053  break;
1054 
1055  case "spl":
1056  // Question Pool *Question* Text (Survey)
1058  if ($quest) {
1059  $parent_id = $quest->getObjId();
1060 
1061  // pool question copy - find survey, do not use pool itself
1062  if ($quest->getOriginalId() &&
1063  ilObject::_lookupType($parent_id) == "spl") {
1065  }
1066  // original question (in pool or survey)
1067  else {
1068  $obj_id = (int) $parent_id;
1069  }
1070 
1071  unset($quest);
1072  }
1073  break;
1074 
1075  case "exca":
1076  // Exercise assignment
1077  $returned_pk = $a_usage['id'];
1078  // #15995 - we are just checking against exercise object
1079  $obj_id = ilExSubmission::lookupExerciseIdForReturnedId($returned_pk);
1080  break;
1081 
1082  case "frm":
1083  // Forum
1084  $post_pk = $a_usage['id'];
1085  $oPost = new ilForumPost($post_pk);
1086  $frm_pk = $oPost->getForumId();
1087  $obj_id = ilForum::_lookupObjIdForForumId($frm_pk);
1088  break;
1089 
1090 
1091  case "frm~d":
1092  $draft_id = $a_usage['id'];
1093  $oDraft = ilForumPostDraft::newInstanceByDraftId($draft_id);
1094 
1095  $frm_pk = $oDraft->getForumId();
1096  $obj_id = ilForum::_lookupObjIdForForumId($frm_pk);
1097  break;
1098  case "frm~h":
1099  $history_id = $a_usage['id'];
1100  $oHistoryDraft = new ilForumDraftsHistory($history_id);
1101  $oDraft = ilForumPostDraft::newInstanceByDraftId($oHistoryDraft->getDraftId());
1102 
1103  $frm_pk = $oDraft->getForumId();
1104  $obj_id = ilForum::_lookupObjIdForForumId($frm_pk);
1105  break;
1106  // temporary items (per user)
1107  case "frm~":
1108  case "exca~":
1109  $obj_id = (int) $a_usage['id'];
1110  break;
1111 
1112  // "old" category pages
1113  case "cat":
1114  // InfoScreen Text
1115  case "tst":
1116  case "svy":
1117  // data collection
1118  case "dcl":
1119  $obj_id = (int) $id;
1120  break;
1121  }
1122  break;
1123 
1124  // page editor
1125  case "pg":
1126 
1127  switch ($cont_type) {
1128  // question feedback // parent obj id is q id
1129  case "qfbg":
1130  case "qpl":
1131 
1132  if ($cont_type == "qfbg") {
1134  }
1135 
1136  // Question Pool Question Pages
1137  global $DIC;
1138  $qinfo = $DIC->testQuestionPool()->questionInfo()->getQuestionInfo($id);
1139  if ($qinfo["original_id"] > 0) {
1140  $obj_id = ilObjTest::_lookupTestObjIdForQuestionId($id); // usage in test
1141  } else {
1142  $obj_id = $qinfo["obj_fi"]; // usage in pool
1143  }
1144  if ($obj_id == 0) { // this is the case, if question is in learning module -> get lm id
1145  $pinfo = ilPCQuestion::_getPageForQuestionId($id, "lm");
1146  if ($pinfo && $pinfo["parent_type"] == "lm") {
1147  $obj_id = ilLMObject::_lookupContObjID($pinfo["page_id"]);
1148  }
1149  }
1150  break;
1151 
1152  case "lm":
1153  // learning modules
1154  $obj_id = ilLMObject::_lookupContObjID($id);
1155  break;
1156 
1157  case "term":
1158  $term_id = $id;
1159  $obj_id = ilGlossaryTerm::_lookGlossaryID($term_id);
1160  break;
1161 
1162  case "wpg":
1163  // wiki page
1164  $obj_id = (int) ilWikiPage::lookupObjIdByPage($id);
1165  break;
1166 
1167  case "sahs":
1168  // sahs page
1169  // can this implementation be used for other content types, too?
1170  $obj_id = ilPageObject::lookupParentId($id, 'sahs');
1171  break;
1172 
1173  case "prtf":
1174  // portfolio
1176  break;
1177 
1178  case "prtt":
1179  // portfolio template
1181  break;
1182 
1183 
1184  case "impr":
1185  // imprint page - always id 1
1186  // fallthrough
1187 
1188  case "copa":
1189  case "cstr":
1190  $obj_id = $id;
1191  break;
1192 
1193  default:
1194  $obj_id = ilPageObject::lookupParentId($id, $cont_type);
1195  break;
1196  }
1197  break;
1198 
1199  // Media Pool
1200  case "mep":
1201  $obj_id = $id;
1202  break;
1203 
1204  // News Context Object (e.g. MediaCast)
1205  case "news":
1207  break;
1208  }
1209 
1210  return $obj_id;
1211  }
1212 
1216  public static function _resizeImage(
1217  string $a_file,
1218  int $a_width,
1219  int $a_height,
1220  bool $a_constrain_prop = false
1221  ): string {
1222  global $DIC;
1223  $file_path = pathinfo($a_file);
1224  $location = substr($file_path["basename"], 0, strlen($file_path["basename"]) -
1225  strlen($file_path["extension"]) - 1) . "_" .
1226  $a_width . "_" .
1227  $a_height . "." . $file_path["extension"];
1228  $target_file = $file_path["dirname"] . "/" .
1229  $location;
1230 
1231  $returned_target_file = $DIC->fileConverters()
1232  ->legacyImages()
1233  ->resizeToFixedSize(
1234  $a_file,
1235  $target_file,
1236  $a_width,
1237  $a_height,
1238  $a_constrain_prop
1239  );
1240 
1241  if ($returned_target_file !== $target_file) {
1242  throw new RuntimeException('Could not resize image');
1243  }
1244 
1245  return $location;
1246  }
1247 
1251  public static function getMimeType(
1252  string $a_file,
1253  bool $a_external = false
1254  ): string {
1255  $mime = MimeType::lookupMimeType($a_file, MimeType::APPLICATION__OCTET_STREAM, $a_external);
1256  return $mime;
1257  }
1258 
1259  public static function _determineWidthHeight(
1260  string $a_format,
1261  string $a_type,
1262  string $a_file,
1263  string $a_reference,
1264  bool $a_constrain_proportions,
1265  bool $a_use_original,
1266  ?int $a_user_width = null,
1267  ?int $a_user_height = null
1268  ): array {
1269  global $DIC;
1270 
1271  $lng = $DIC->language();
1272  $size = [];
1273  $wr = 0;
1274  $hr = 0;
1275  $width = 0;
1276  $height = 0;
1277 
1278  // determine width and height of known image types
1279  //$width = 640;
1280  //$height = 360;
1281  $info = "";
1282 
1283  /*
1284  if ($a_format == "audio/mpeg") {
1285  $width = 300;
1286  $height = 20;
1287  }*/
1288 
1289  if (ilUtil::deducibleSize($a_format)) {
1290  if ($a_type == "File") {
1291  $size = ilMediaImageUtil::getImageSize($a_file);
1292  } else {
1293  $size = ilMediaImageUtil::getImageSize($a_reference);
1294  }
1295  }
1296 
1297  if (!isset($size[0])) {
1298  $size[0] = 0;
1299  }
1300  if (!isset($size[1])) {
1301  $size[1] = 0;
1302  }
1303 
1304  if ($a_use_original) {
1305  if ($size[0] > 0 && $size[1] > 0) {
1306  //$width = $size[0];
1307  //$height = $size[1];
1308  $width = "";
1309  $height = "";
1310  } else {
1311  $info = $lng->txt("cont_could_not_determine_resource_size");
1312  }
1313  } else {
1314  $w = $a_user_width;
1315  $h = $a_user_height;
1316  $width = $w;
1317  $height = $h;
1318  //echo "<br>C-$width-$height-";
1319  if (ilUtil::deducibleSize($a_format) && $a_constrain_proportions) {
1320  if ($size[0] > 0 && $size[1] > 0) {
1321  if ($w > 0) {
1322  $wr = $size[0] / $w;
1323  }
1324  if ($h > 0) {
1325  $hr = $size[1] / $h;
1326  }
1327  //echo "<br>+".$wr."+".$size[0]."+".$w."+";
1328  //echo "<br>+".$hr."+".$size[1]."+".$h."+";
1329  $r = max($wr, $hr);
1330  if ($r > 0) {
1331  $width = (int) round($size[0] / $r);
1332  $height = (int) round($size[1] / $r);
1333  }
1334  }
1335  }
1336  //echo "<br>D-$width-$height-";
1337  }
1338  //echo "<br>E-$width-$height-";
1339 
1340  if ($width == 0 && is_null($a_user_width)) {
1341  $width = "";
1342  }
1343  if ($height == 0 && is_null($a_user_height)) {
1344  $height = "";
1345  }
1346  return array("width" => $width, "height" => $height, "info" => $info);
1347  }
1348 
1349  public function getDataDirectory(): string
1350  {
1351  return ilFileUtils::getWebspaceDir() . "/mobs/mm_" . $this->getId();
1352  }
1353 
1357  public static function _saveTempFileAsMediaObject(
1358  string $name,
1359  string $tmp_name,
1360  bool $upload = true
1361  ): ilObjMediaObject {
1362  // create dummy object in db (we need an id)
1363  $media_object = new ilObjMediaObject();
1364  $media_object->setTitle($name);
1365  $media_object->setDescription("");
1366  $media_object->create();
1367 
1368  // determine and create mob directory, move uploaded file to directory
1369  $media_object->createDirectory();
1370  $mob_dir = ilObjMediaObject::_getDirectory($media_object->getId());
1371 
1372  $media_item = new ilMediaItem();
1373  $media_object->addMediaItem($media_item);
1374  $media_item->setPurpose("Standard");
1375 
1376  $file = $mob_dir . "/" . $name;
1377  if ($upload) {
1378  ilFileUtils::moveUploadedFile($tmp_name, $name, $file);
1379  } else {
1380  copy($tmp_name, $file);
1381  }
1382  // get mime type
1383  $format = ilObjMediaObject::getMimeType($file);
1384  $location = $name;
1385  // set real meta and object data
1386  $media_item->setFormat($format);
1387  $media_item->setLocation($location);
1388  $media_item->setLocationType("LocalFile");
1389  $media_object->setTitle($name);
1390  $media_object->setDescription($format);
1391 
1392  if (ilUtil::deducibleSize($format)) {
1393  $size = ilMediaImageUtil::getImageSize($file);
1394  $media_item->setWidth($size[0]);
1395  $media_item->setHeight($size[1]);
1396  }
1397  $media_item->setHAlign("Left");
1398 
1399  self::renameExecutables($mob_dir);
1400  ilMediaSvgSanitizer::sanitizeDir($mob_dir); // see #20339
1401 
1402  $media_object->update();
1403 
1404  return $media_object;
1405  }
1406 
1410  public function uploadAdditionalFile(
1411  string $a_name,
1412  string $tmp_name,
1413  string $a_subdir = "",
1414  string $a_mode = "move_uploaded"
1415  ): void {
1416  $a_subdir = str_replace("..", "", $a_subdir);
1417  $dir = $mob_dir = ilObjMediaObject::_getDirectory($this->getId());
1418  if ($a_subdir != "") {
1419  $dir .= "/" . $a_subdir;
1420  }
1422  if ($a_mode == "rename") {
1423  ilFileUtils::rename($tmp_name, $dir . "/" . $a_name);
1424  } else {
1425  ilFileUtils::moveUploadedFile($tmp_name, $a_name, $dir . "/" . $a_name, true, $a_mode);
1426  }
1427  self::renameExecutables($mob_dir);
1428  ilMediaSvgSanitizer::sanitizeDir($mob_dir); // see #20339
1429  }
1430 
1432  FileUpload $upload,
1433  UploadResult $result,
1434  string $subdir
1435  ): void {
1436  $mob_dir = self::_getRelativeDirectory($this->getId());
1437  $mob_dir .= "/" . $subdir;
1438  $upload->moveOneFileTo(
1439  $result,
1440  $mob_dir,
1441  Location::WEB,
1442  $result->getName(),
1443  true
1444  );
1445  }
1446 
1447  public function uploadSrtFile(
1448  string $a_tmp_name,
1449  string $a_language,
1450  string $a_mode = "move_uploaded"
1451  ): bool {
1452  if (is_file($a_tmp_name) && $a_language != "") {
1453  $this->uploadAdditionalFile("subtitle_" . $a_language . ".srt", $a_tmp_name, "srt", $a_mode);
1454  return true;
1455  }
1456  return false;
1457  }
1458 
1459  public function getSrtFiles(): array
1460  {
1461  $srt_dir = ilObjMediaObject::_getDirectory($this->getId()) . "/srt";
1462 
1463  if (!is_dir($srt_dir)) {
1464  return array();
1465  }
1466 
1467  $items = ilFileUtils::getDir($srt_dir);
1468 
1469  $srt_files = array();
1470  foreach ($items as $i) {
1471  if (!in_array($i["entry"], array(".", "..")) && $i["type"] == "file") {
1472  $name = explode(".", $i["entry"]);
1473  if ($name[1] == "srt" && substr($name[0], 0, 9) == "subtitle_") {
1474  $srt_files[] = array("file" => $i["entry"],
1475  "full_path" => "srt/" . $i["entry"], "language" => substr($name[0], 9, 2));
1476  }
1477  }
1478  }
1479 
1480  return $srt_files;
1481  }
1482 
1486  public function makeThumbnail(
1487  string $a_file,
1488  string $a_thumbname,
1489  ): void {
1490  $size = self::DEFAULT_PREVIEW_SIZE;
1491  $m_dir = ilObjMediaObject::_getDirectory($this->getId());
1493  $file = $m_dir . "/" . $a_file;
1494 
1495  $mime = ilObjMediaObject::getMimeType($file);
1496  $wh = ilMediaImageUtil::getImageSize($file);
1497 
1498  // see #8602
1499  if ($size > (int) $wh[0] && $size > $wh[1]) {
1500  $size = min($wh[0], $wh[1]);
1501  }
1502 
1503  $m_dir = ilObjMediaObject::_getDirectory($this->getId());
1505  self::_createThumbnailDirectory($this->getId());
1506  $this->image_converter->croppedSquare(
1507  $m_dir . "/" . $a_file,
1508  $t_dir . "/" . $a_thumbname,
1509  $size
1510  );
1511  }
1512 
1513  public static function getThumbnailPath(
1514  int $a_mob_id,
1515  string $a_thumbname
1516  ): string {
1517  $t_dir = ilObjMediaObject::_getThumbnailDirectory($a_mob_id);
1518  return $t_dir . "/" . $a_thumbname;
1519  }
1520 
1521  public function removeAdditionalFile(
1522  string $a_file
1523  ): void {
1524  $file = str_replace("..", "", $a_file);
1525  $file = ilObjMediaObject::_getDirectory($this->getId()) . "/" . $file;
1526  if (is_file($file)) {
1527  unlink($file);
1528  }
1529  }
1530 
1531 
1536  public function getLinkedMediaObjects(
1537  array $a_ignore = []
1538  ): array {
1539  $linked = array();
1540 
1541  // get linked media objects (map areas)
1542  $med_items = $this->getMediaItems();
1543 
1544  foreach ($med_items as $med_item) {
1545  $int_links = ilMapArea::_getIntLinks($med_item->getId());
1546  foreach ($int_links as $k => $int_link) {
1547  if ($int_link["Type"] == "MediaObject") {
1548  $l_id = ilInternalLink::_extractObjIdOfTarget($int_link["Target"]);
1549  if (ilObject::_exists($l_id)) {
1550  if (!in_array($l_id, $linked) &&
1551  !in_array($l_id, $a_ignore)) {
1552  $linked[] = $l_id;
1553  }
1554  }
1555  }
1556  }
1557  }
1558  //var_dump($linked);
1559  return $linked;
1560  }
1561 
1562  public static function isTypeAllowed(
1563  string $a_type
1564  ): bool {
1565  global $DIC;
1566  return in_array($a_type, iterator_to_array(
1567  $DIC->mediaObjects()->internal()->domain()->mediaType()->getAllowedSuffixes()
1568  ), true);
1569  }
1570 
1574  public function duplicate(): ilObjMediaObject
1575  {
1576  $new_obj = new ilObjMediaObject();
1577  $new_obj->setTitle($this->getTitle());
1578  $new_obj->setDescription($this->getDescription());
1579 
1580  // media items
1581  foreach ($this->getMediaItems() as $key => $val) {
1582  $new_obj->addMediaItem($val);
1583  }
1584 
1585  $new_obj->create(false, true);
1586 
1587  // files
1588  $new_obj->createDirectory();
1589  self::_createThumbnailDirectory($new_obj->getId());
1592  ilObjMediaObject::_getDirectory($new_obj->getId())
1593  );
1596  ilObjMediaObject::_getThumbnailDirectory($new_obj->getId())
1597  );
1598 
1599  // meta data
1600  $md = new ilMD(0, $this->getId(), "mob");
1601  $new_md = $md->cloneMD(0, $new_obj->getId(), "mob");
1602 
1603  return $new_obj;
1604  }
1605 
1606  public function uploadVideoPreviewPic(
1607  array $a_prevpic
1608  ): void {
1609  // remove old one
1610  if ($this->getVideoPreviewPic(true) != "") {
1611  $this->removeAdditionalFile($this->getVideoPreviewPic(true));
1612  }
1613 
1614  $pi = pathinfo($a_prevpic["name"]);
1615  $ext = $pi["extension"];
1616  if (in_array($ext, array("jpg", "jpeg", "png"))) {
1617  $this->uploadAdditionalFile("mob_vpreview." . $ext, $a_prevpic["tmp_name"]);
1618  }
1619  }
1620 
1621  public function generatePreviewPic(
1622  int $a_width,
1623  int $a_height,
1624  int $sec = 1
1625  ): void {
1627  $logger = $GLOBALS['DIC']->logger()->mob();
1628 
1629  $item = $this->getMediaItem("Standard");
1630  if ($item->getFormat() === "image/svg+xml") {
1631  return;
1632  }
1633 
1634  $logger->debug("Generate preview pic...");
1635  $logger->debug("..." . $item->getFormat());
1636 
1637  if ($item->getLocationType() == "LocalFile") {
1638  if (is_int(strpos($item->getFormat(), "image/"))) {
1639  $a_width = $a_height = self::DEFAULT_PREVIEW_SIZE;
1640 
1641  $dir = ilObjMediaObject::_getDirectory($this->getId());
1642  $file = $dir . "/" .
1643  $item->getLocation();
1644  if (is_file($file)) {
1645  $logger->debug("Calling image converter.");
1646  $this->image_converter->resizeToFixedSize(
1647  $file,
1648  $dir . "/mob_vpreview.png",
1649  $a_width,
1650  $a_height,
1651  true,
1652  ImageOutputOptions::FORMAT_PNG
1653  );
1654  }
1655  }
1656  }
1657 
1658  if (in_array($item->getFormat(), ["video/mp4", "video/webm"])) {
1659  try {
1660  if ($sec < 0) {
1661  $sec = 0;
1662  }
1663  if ($this->getVideoPreviewPic() != "") {
1664  $this->removeAdditionalFile($this->getVideoPreviewPic(true));
1665  }
1666  $med = $this->getMediaItem("Standard");
1667  if ($med->getLocationType() == "LocalFile") {
1668  $mob_file = ilObjMediaObject::_getDirectory($this->getId()) . "/" . $med->getLocation();
1669  } else {
1670  $mob_file = $med->getLocation();
1671  }
1672  $logger->debug(
1673  "...extract " . $mob_file . " in " .
1675  );
1676  $logger->debug("Call ffmpeg.");
1678  $mob_file,
1679  "mob_vpreview.png",
1681  $sec
1682  );
1683  } catch (ilException $e) {
1685 
1686  $message = '';
1687  if (is_array($ret) && count($ret) > 0) {
1688  $message = "\n" . implode("\n", $ret);
1689  }
1690 
1691  $logger->warning($e->getMessage() . $message);
1692  $logger->logStack(ilLogLevel::WARNING);
1693  }
1694  }
1695  }
1696 
1697  public function getVideoPreviewPic(
1698  bool $a_filename_only = false
1699  ): string {
1700  $dir = ilObjMediaObject::_getDirectory($this->getId());
1701  $ppics = array("mob_vpreview.jpg",
1702  "mob_vpreview.jpeg",
1703  "mob_vpreview.png");
1704  $med = $this->getMediaItem("Standard");
1705  if ($med && $med->getFormat() === "image/svg+xml" && $med->getLocationType() === "LocalFile") {
1706  $ppics[] = $med->getLocation();
1707  }
1708  foreach ($ppics as $p) {
1709  if (is_file($dir . "/" . $p)) {
1710  if ($a_filename_only) {
1711  return $p;
1712  } else {
1713  return $dir . "/" . $p;
1714  }
1715  }
1716  }
1717  return "";
1718  }
1719 
1723  public static function fixFilename(
1724  string $a_name
1725  ): string {
1726  $a_name = ilFileUtils::getASCIIFilename($a_name);
1727 
1728  $rchars = array("`", "=", "$", "{", "}", "'", ";", " ", "(", ")");
1729  $a_name = str_replace($rchars, "_", $a_name);
1730  $a_name = str_replace("__", "_", $a_name);
1731  return $a_name;
1732  }
1733 
1734 
1738  public function getMultiSrtUploadDir(): string
1739  {
1740  return ilObjMediaObject::_getDirectory($this->getId()) . "/srt/tmp";
1741  }
1742 
1743 
1748  array $a_file
1749  ): void {
1750  $lng = $this->lng;
1751 
1752  if (!is_file($a_file["tmp_name"])) {
1753  throw new ilMediaObjectsException($lng->txt("mob_file_could_not_be_uploaded"));
1754  }
1755 
1756  $dir = $this->getMultiSrtUploadDir();
1757  ilFileUtils::delDir($dir, true);
1759  ilFileUtils::moveUploadedFile($a_file["tmp_name"], "multi_srt.zip", $dir . "/" . "multi_srt.zip");
1760  $this->domain->resources()->zip()->unzipFile($dir . "/multi_srt.zip");
1761  }
1762 
1766  public function clearMultiSrtDirectory(): void
1767  {
1769  }
1770 
1774  public function getMultiSrtFiles(): array
1775  {
1776  $items = array();
1777 
1779 
1780  $dir = $this->getMultiSrtUploadDir();
1781  $files = ilFileUtils::getDir($dir);
1782  foreach ($files as $k => $i) {
1783  // check directory
1784  if ($i["type"] == "file" && !in_array($k, array(".", ".."))) {
1785  if (pathinfo($k, PATHINFO_EXTENSION) == "srt") {
1786  $lang = "";
1787  if (substr($k, strlen($k) - 7, 1) == "_") {
1788  $lang = substr($k, strlen($k) - 6, 2);
1789  if (!in_array($lang, $lang_codes)) {
1790  $lang = "";
1791  }
1792  }
1793  $items[] = array("filename" => $k, "lang" => $lang);
1794  }
1795  }
1796  }
1797  return $items;
1798  }
1799 
1800  public static function renameExecutables(
1801  string $a_dir
1802  ): void {
1804  if (!self::isTypeAllowed("html")) {
1805  ilFileUtils::rRenameSuffix($a_dir, "html", "sec"); // see #20187
1806  }
1807  }
1808 
1809  public function getExternalMetadata(): void
1810  {
1811  // see https://oembed.com/
1812  $st_item = $this->getMediaItem("Standard");
1813  if ($st_item->getLocationType() == "Reference") {
1814  if (ilExternalMediaAnalyzer::isVimeo($st_item->getLocation())) {
1815  $st_item->setFormat("video/vimeo");
1816  $par = ilExternalMediaAnalyzer::extractVimeoParameters($st_item->getLocation());
1817  $meta = ilExternalMediaAnalyzer::getVimeoMetadata($par["id"]);
1818  $this->setTitle($meta["title"] ?? "");
1819  $description = str_replace("\n", "", $meta["description"] ?? "");
1820  $description = str_replace(["<br>", "<br />"], ["\n", "\n"], $description);
1821  $description = strip_tags($description);
1822  $this->setDescription($description);
1823  $st_item->setDuration((int) ($meta["duration"] ?? 0));
1824  $url = parse_url($meta["thumbnail_url"] ?? "");
1825  $file = basename($url["path"]);
1826  $ext = pathinfo($file, PATHINFO_EXTENSION);
1827  if ($ext == "") {
1828  $ext = "jpg";
1829  }
1830  copy(
1831  $meta["thumbnail_url"],
1832  ilObjMediaObject::_getDirectory($this->getId()) . "/mob_vpreview." .
1833  $ext
1834  );
1835  }
1836  if (ilExternalMediaAnalyzer::isYoutube($st_item->getLocation())) {
1837  $st_item->setFormat("video/youtube");
1838  $par = ilExternalMediaAnalyzer::extractYoutubeParameters($st_item->getLocation());
1839  try {
1841  $this->setTitle($meta["title"] ?? "");
1842  $description = str_replace("\n", "", $meta["description"] ?? "");
1843  } catch (Exception $e) {
1844  $this->setTitle($st_item->getLocation());
1845  $description = "";
1846  }
1847  $description = str_replace(["<br>", "<br />"], ["\n", "\n"], $description);
1848  $description = strip_tags($description);
1849  $this->setDescription($description);
1850  $st_item->setDuration((int) ($meta["duration"] ?? 0));
1851  $thumbnail_url = $meta["thumbnail_url"] ?? "";
1852  $url = parse_url($thumbnail_url);
1853  if ($thumbnail_url !== "") {
1854  $file = basename($url["path"]);
1855  copy(
1856  $meta["thumbnail_url"],
1857  ilObjMediaObject::_getDirectory($this->getId()) . "/mob_vpreview." .
1858  pathinfo($file, PATHINFO_EXTENSION)
1859  );
1860  }
1861  }
1862  }
1863  }
1864 }
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 _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)
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 _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 _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)
static _lookupTestObjIdForQuestionId(int $q_id)
Get test Object ID for question ID.
addAdditionalFileFromUpload(FileUpload $upload, UploadResult $result, string $subdir)
$path
Definition: ltiservices.php:32
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)
global $DIC
Definition: feed.php:28
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.
__construct(VocabulariesInterface $vocabularies)
static getMimeType(string $a_file, bool $a_external=false)
get mime type for file
$GLOBALS["DIC"]
Definition: wac.php:31
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
moveOneFileTo(UploadResult $uploadResult, string $destination, int $location=Location::STORAGE, string $file_name='', bool $override_existing=false)
Moves a single File (the attributes, metadata and upload-status of which are contained in UploadResul...
getMediaItem(string $a_purpose)
get item for media purpose
static createDirectory(string $a_dir, int $a_mod=0755)
create directory
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
static lookupExerciseIdForReturnedId(int $a_returned_id)
Get exercise from submission id (used in ilObjMediaObject)
$url
Definition: ltiregstart.php:35
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
Class FileUpload.
Definition: FileUpload.php:34
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.
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)
InternalDomainService $domain
static lookupObjIdByPage(int $a_page_id)
returns the wiki/object id to a given page id
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins
Definition: plugin.php:23
$q
Definition: shib_logout.php:21
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)
makeThumbnail(string $a_file, string $a_thumbname,)
Make thumbnail.
const IL_MODE_OUTPUT
static getThumbnailPath(int $a_mob_id, string $a_thumbname)
duplicate()
Duplicate media object, return new media object.
$message
Definition: xapiexit.php:32
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
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