ILIAS  release_9 Revision v9.13-25-g2c18ec4c24f
class.ilLPTableBaseGUI.php
Go to the documentation of this file.
1 <?php
2 
19 declare(strict_types=0);
20 
23 
31 {
32  public const HIT_LIMIT = 5000;
34  protected HttpService $http;
35 
36  protected array $filter = [];
37  protected bool $anonymized = true;
39  private ilObjUser $user;
40  protected ilSetting $setting;
43  protected ilTree $tree;
44  protected \ilGlobalTemplateInterface $main_tpl;
45 
46  public function __construct(
47  ?object $a_parent_obj,
48  string $a_parent_cmd = "",
49  string $a_template_context = ""
50  ) {
51  global $DIC;
52  $this->main_tpl = $DIC->ui()->mainTemplate();
53 
54  $this->objDefinition = $DIC['objDefinition'];
55  $this->ilObjDataCache = $DIC['ilObjDataCache'];
56  $this->tree = $DIC->repositoryTree();
57  $this->user = $DIC->user();
58  $this->setting = $DIC->settings();
59  $this->http = $DIC->http();
60  $this->refinery = $DIC->refinery();
61 
62  $this->anonymized = !ilObjUserTracking::_enabledUserRelatedData();
63  if (!$this->anonymized && isset($this->obj_id) && $this->obj_id > 0) {
64  $olp = ilObjectLP::getInstance($this->obj_id);
65  $this->anonymized = $olp->isAnonymized();
66  }
67 
68  /*
69  * BT 35453: parent constructor needs to be called after $this->anonymized
70  * is set, in order for getSelectableUserColumns to also properly return
71  * user defined fields (e.g. firstname, lastname, and other user data).
72  */
73  parent::__construct($a_parent_obj, $a_parent_cmd, $a_template_context);
74 
75  // country names
76  $this->lng->loadLanguageModule("meta");
77  }
78 
79  protected function initItemIdFromPost(): array
80  {
81  if ($this->http->wrapper()->post()->has('item_id')) {
82  return $this->http->wrapper()->post()->retrieve(
83  'item_id',
84  $this->refinery->kindlyTo()->listOf(
85  $this->refinery->kindlyTo()->int()
86  )
87  );
88  }
89  return [];
90  }
91 
92  protected function initUidFromPost(): array
93  {
94  if ($this->http->wrapper()->post()->has('uid')) {
95  return $this->http->wrapper()->post()->retrieve(
96  'uid',
97  $this->refinery->kindlyTo()->listOf(
98  $this->refinery->kindlyTo()->int()
99  )
100  );
101  }
102  return [];
103  }
104 
105  public function executeCommand(): bool
106  {
107  $this->determineSelectedFilters();
108  if (!$this->ctrl->getNextClass($this)) {
109  $to_hide = false;
110 
111  switch ($this->ctrl->getCmd()) {
112  case "applyFilter":
113  $this->resetOffset();
114  $this->writeFilterToSession();
115  $this->storeProperty("offset", "0");
116  break;
117 
118  case "resetFilter":
119  $this->resetOffset();
120  $this->resetFilter();
121  $this->storeProperty("offset", "0");
122  break;
123 
124  case "hideSelected":
125  $to_hide = $this->initItemIdFromPost();
126  break;
127 
128  case "hide":
129  $hide = 0;
130  if ($this->http->wrapper()->query()->has('hide')) {
131  $hide = $this->http->wrapper()->query()->retrieve(
132  'hide',
133  $this->refinery->kindlyTo()->int()
134  );
135  }
136  $to_hide = [$hide];
137  break;
138 
139  case "mailselectedusers":
140  if (!$this->initUidFromPost()) {
141  $this->main_tpl->setOnScreenMessage(
142  'failure',
143  $this->lng->txt(
144  "no_checkbox"
145  ),
146  true
147  );
148  } else {
149  $this->sendMail(
150  $this->initUidFromPost(),
151  $this->parent_obj,
152  $this->parent_cmd
153  );
154  }
155  break;
156 
157  case 'addToClipboard':
158  if (!$this->initUidFromPost()) {
159  $this->main_tpl->setOnScreenMessage(
160  'failure',
161  $this->lng->txt(
162  'no_checkbox'
163  ),
164  true
165  );
166  } else {
167  $this->addToClipboard();
168  }
169  break;
170 
171  // page selector
172  default:
173  $this->determineOffsetAndOrder();
174  $this->storeNavParameter();
175  $this->storeProperty("offset", (string) $this->getOffset());
176  break;
177  }
178 
179  if ($to_hide) {
180  $obj = $this->getFilterItemByPostVar("hide");
181  $value = array_unique(
182  array_merge((array) $obj->getValue(), $to_hide)
183  );
184  $obj->setValue($value);
185  $obj->writeToSession();
186  }
187 
188  if ($this->requested_tmpl_create !== "") {
189  $this->ctrl->setParameter(
190  $this->parent_obj,
191  "tbltplcrt",
192  $this->requested_tmpl_create
193  );
194  }
195  if ($this->requested_tmpl_delete !== "") {
196  $this->ctrl->setParameter(
197  $this->parent_obj,
198  "tbltpldel",
199  $this->requested_tmpl_delete
200  );
201  }
202  $this->ctrl->redirect($this->parent_obj, $this->parent_cmd);
203  } else {
204  // e.g. repository selector
205  return parent::executeCommand();
206  }
207  return true;
208  }
209 
213  protected function findReferencesForObjId(int $a_obj_id): array
214  {
215  $ref_ids = array_keys(ilObject::_getAllReferences($a_obj_id));
216  sort($ref_ids, SORT_NUMERIC);
217  return $ref_ids;
218  }
219 
220 
221 
222  protected function sendMail(
223  array $a_user_ids,
224  $a_parent_obj,
225  string $a_parent_cmd
226  ): void {
227  // see ilObjCourseGUI::sendMailToSelectedUsersObject()
228 
229  $rcps = array();
230  foreach ($a_user_ids as $usr_id) {
231  $rcps[] = ilObjUser::_lookupLogin($usr_id);
232  }
233 
234  $template = array();
235  $sig = null;
236 
237  $ref_id = 0;
238  if ($this->http->wrapper()->query()->has('ref_id')) {
239  $ref_id = $this->http->wrapper()->query()->retrieve(
240  'ref_id',
241  $this->refinery->kindlyTo()->int()
242  );
243  }
244  // repository-object-specific
245  if ($ref_id) {
246  $obj_lp = ilObjectLP::getInstance(
248  );
249  $tmpl_id = $obj_lp->getMailTemplateId();
250 
251  if ($tmpl_id) {
252  $template = array(
253  ilMailFormCall::CONTEXT_KEY => $tmpl_id,
254  'ref_id' => $ref_id,
255  'ts' => time()
256  );
257  } else {
258  $sig = ilLink::_getLink($ref_id);
259  $sig = rawurlencode(base64_encode($sig));
260  }
261  }
262 
265  $a_parent_obj,
266  $a_parent_cmd,
267  array(),
268  array(
269  'type' => 'new',
270  'rcp_to' => implode(',', $rcps),
271  'sig' => $sig
272  ),
273  $template
274  )
275  );
276  }
277 
281  protected function searchObjects(
282  array $filter,
283  string $permission,
284  ?array $preset_obj_ids = null,
285  bool $a_check_lp_activation = true
286  ): array {
287  $query_parser = new ilQueryParser($filter["query"] ?? '');
288  $query_parser->setMinWordLength(0);
289  $query_parser->setCombination(ilQueryParser::QP_COMBINATION_AND);
290  $query_parser->parse();
291  if (!$query_parser->validate()) {
292  ilLoggerFactory::getLogger('trac')->notice(
293  $query_parser->getMessage()
294  );
295  // echo $query_parser->getMessage();
296  return [];
297  }
298 
299  if ($filter["type"] == "lres") {
300  $filter["type"] = array('lm', 'sahs', 'htlm');
301  } else {
302  $filter["type"] = array($filter["type"]);
303  }
304 
305  $object_search = new ilLikeObjectSearch($query_parser);
306  $object_search->setFilter($filter["type"]);
307  if ($preset_obj_ids) {
308  $object_search->setIdFilter($preset_obj_ids);
309  }
310  $res = $object_search->performSearch();
311 
312  if ($permission) {
313  $res->setRequiredPermission($permission);
314  }
315 
316  $res->setMaxHits(self::HIT_LIMIT);
317 
318  if ($a_check_lp_activation) {
319  $res->addObserver($this, "searchFilterListener");
320  }
321 
322  if (!$this->filter["area"]) {
323  $res->filter(ROOT_FOLDER_ID, true);
324  } else {
325  $res->filter($this->filter["area"], true);
326  }
327 
328  $objects = array();
329  foreach ($res->getResults() as $obj_data) {
330  $objects[$obj_data['obj_id']][] = $obj_data['ref_id'];
331  }
332  return $objects ?: array();
333  }
334 
340  public function searchFilterListener(int $a_ref_id, array $a_data): bool
341  {
342  if (is_array($this->filter["hide"]) && in_array(
343  $a_data["obj_id"],
344  $this->filter["hide"]
345  )) {
346  return false;
347  }
348  $olp = ilObjectLP::getInstance($a_data["obj_id"]);
349  if (get_class(
350  $olp
351  ) != "ilObjectLP" && // #13654 - LP could be unsupported
352  !$olp->isActive()) {
353  return false;
354  }
355  return true;
356  }
357 
358  protected function isForwardingToFormDispatcher(): bool
359  {
360  return false;
361  }
362 
363  protected function initRepositoryFilter(array $filter): array
364  {
365  $repo = new ilRepositorySelector2InputGUI(
366  $this->lng->txt('trac_filter_area'),
367  'effective_from',
368  false,
369  ($this->isForwardingToFormDispatcher()) ? $this : null
370  );
371  $white_list = [];
372  foreach ($this->objDefinition->getAllRepositoryTypes() as $type) {
373  if ($this->objDefinition->isContainer($type)) {
374  $white_list[] = $type;
375  }
376  }
377  $repo->getExplorerGUI()->setTypeWhiteList($white_list);
378  $this->addFilterItem($repo);
379  $repo->readFromSession();
380  $filter['area'] = (int) $repo->getValue();
381  return $filter;
382  }
383 
387  public function initBaseFilter(
388  bool $a_split_learning_resources = false,
389  bool $a_include_no_status_filter = true
390  ) {
391  $this->setDisableFilterHiding(true);
392 
393  // object type selection
394  $si = new ilSelectInputGUI($this->lng->txt("obj_type"), "type");
395  $si->setOptions($this->getPossibleTypes($a_split_learning_resources));
396  $this->addFilterItem($si);
397  $si->readFromSession();
398  if (!$si->getValue()) {
399  $si->setValue("crs");
400  }
401  $this->filter["type"] = $si->getValue();
402 
403  // hidden items
404  $msi = new ilMultiSelectInputGUI(
405  $this->lng->txt("trac_filter_hidden"),
406  "hide"
407  );
408  $this->addFilterItem($msi);
409  $msi->readFromSession();
410  $this->filter["hide"] = $msi->getValue();
411  if ($this->filter["hide"]) {
412  // create options from current value
413  $types = $this->getCurrentFilter(true);
414  $type = $types["type"];
415  $options = array();
416  if ($type == 'lres') {
417  $type = array('lm', 'sahs', 'htlm');
418  } else {
419  $type = array($type);
420  }
421  foreach ($this->filter["hide"] as $obj_id) {
422  if (in_array(
423  $this->ilObjDataCache->lookupType((int) $obj_id),
424  $type
425  )) {
426  $options[$obj_id] = $this->ilObjDataCache->lookupTitle(
427  (int) $obj_id
428  );
429  }
430  }
431  $msi->setOptions($options);
432  }
433 
434  // title/description
435  $ti = new ilTextInputGUI(
436  $this->lng->txt("trac_title_description"),
437  "query"
438  );
439  $ti->setMaxLength(64);
440  $ti->setSize(20);
441  $this->addFilterItem($ti);
442  $ti->readFromSession();
443  $this->filter["query"] = $ti->getValue();
444 
445  // repository area selection
447  $this->lng->txt("trac_filter_area"),
448  "area"
449  );
450  $rs->setSelectText($this->lng->txt("trac_select_area"));
451  $this->addFilterItem($rs);
452  $rs->readFromSession();
453  $this->filter["area"] = $rs->getValue();
454 
455  // hide "not started yet"
456  if ($a_include_no_status_filter) {
457  $cb = new ilCheckboxInputGUI(
458  $this->lng->txt("trac_filter_has_status"),
459  "status"
460  );
461  $this->addFilterItem($cb);
462  $cb->readFromSession();
463  $this->filter["status"] = $cb->getChecked();
464  }
465  }
466 
469  protected function buildPath(array $ref_ids): array
470  {
471  if (!count($ref_ids)) {
472  return [];
473  }
474  $result = [];
475  foreach ($ref_ids as $ref_id) {
476  $path = "...";
477  $counter = 0;
478  $path_full = $this->tree->getPathFull($ref_id);
479  foreach ($path_full as $data) {
480  if (++$counter < (count($path_full) - 1)) {
481  continue;
482  }
483  $path .= " &raquo; ";
484  if ($ref_id != $data['ref_id']) {
485  $path .= $data['title'];
486  } else {
487  $path .= ('<a target="_top" href="' .
488  ilLink::_getLink(
489  $data['ref_id'],
490  $data['type']
491  ) . '">' .
492  $data['title'] . '</a>');
493  }
494  }
495 
496  $result[$ref_id] = $path;
497  }
498  return $result;
499  }
500 
501  protected function getPossibleTypes(
502  bool $a_split_learning_resources = false,
503  bool $a_include_digilib = false,
504  bool $a_allow_undefined_lp = false
505  ): array {
506  global $DIC;
507 
508  $component_repository = $DIC['component.repository'];
509 
510  $options = array();
511 
512  if ($a_split_learning_resources) {
513  $options['lm'] = $this->lng->txt('objs_lm');
514  $options['sahs'] = $this->lng->txt('objs_sahs');
515  $options['htlm'] = $this->lng->txt('objs_htlm');
516  } else {
517  $options['lres'] = $this->lng->txt('obj_lrss');
518  }
519 
520  $options['crs'] = $this->lng->txt('objs_crs');
521  $options['grp'] = $this->lng->txt('objs_grp');
522  $options['exc'] = $this->lng->txt('objs_exc');
523  $options['file'] = $this->lng->txt('objs_file');
524  $options['mcst'] = $this->lng->txt('objs_mcst');
525  $options['svy'] = $this->lng->txt('objs_svy');
526  $options['tst'] = $this->lng->txt('objs_tst');
527  $options['prg'] = $this->lng->txt('objs_prg');
528  $options['iass'] = $this->lng->txt('objs_iass');
529  $options['copa'] = $this->lng->txt('objs_copa');
530  $options['frm'] = $this->lng->txt('objs_frm');
531  $options['cmix'] = $this->lng->txt('objs_cmix');
532  $options['lti'] = $this->lng->txt('objs_lti');
533  $options['lso'] = $this->lng->txt('objs_lso');
534  $options['dcl'] = $this->lng->txt('objs_dcl');
535 
536  if ($a_allow_undefined_lp) {
537  $options['root'] = $this->lng->txt('obj_reps');
538  $options['cat'] = $this->lng->txt('objs_cat');
539  $options["webr"] = $this->lng->txt("objs_webr");
540  $options["wiki"] = $this->lng->txt("objs_wiki");
541  $options["blog"] = $this->lng->txt("objs_blog");
542  $options["prtf"] = $this->lng->txt("objs_prtf");
543  $options["prtt"] = $this->lng->txt("objs_prtt");
544  }
545 
546  // repository plugins (currently only active)
547  $plugins = $component_repository->getPluginSlotById(
548  "robj"
549  )->getActivePlugins();
550  foreach ($plugins as $pl) {
551  $pl_id = $pl->getId();
553  $options[$pl_id] = ilObjectPlugin::lookupTxtById(
554  $pl_id,
555  "objs_" . $pl_id
556  );
557  }
558  }
559 
560  asort($options);
561  return $options;
562  }
563 
564  protected function parseValue(
565  string $id,
566  ?string $value,
567  string $type
568  ): string {
569  // get rid of aggregation
570  $pos = strrpos($id, "_");
571  if ($pos !== false) {
572  $function = strtoupper(substr($id, $pos + 1));
573  if (in_array(
574  $function,
575  array("MIN", "MAX", "SUM", "AVG", "COUNT")
576  )) {
577  $id = substr($id, 0, $pos);
578  }
579  }
580 
581  if ((trim((string) $value) == "") && $id != "status") {
582  if ($id == "title" &&
583  get_class($this) != "ilTrObjectUsersPropsTableGUI" &&
584  get_class($this) != "ilTrMatrixTableGUI") {
585  return "--" . $this->lng->txt("none") . "--";
586  }
587  return " ";
588  }
589 
590  switch ($id) {
591  case "first_access":
592  case "create_date":
593  case 'status_changed':
595  new ilDateTime($value, IL_CAL_DATETIME)
596  );
597  break;
598 
599  case "last_access":
601  new ilDateTime($value, IL_CAL_UNIX)
602  );
603  break;
604 
605  case "birthday":
607  new ilDate($value, IL_CAL_DATE)
608  );
609  break;
610 
611  case "spent_seconds":
612  if (!ilObjectLP::supportsSpentSeconds($type)) {
613  $value = "-";
614  } else {
616  (int) $value,
617  ((int) $value < 3600 ? true : false)
618  ); // #14858
619  }
620  break;
621 
622  case "percentage":
623  if (false /* $this->isPercentageAvailable() */) {
624  $value = "-";
625  } else {
626  $value = $value . "%";
627  }
628  break;
629 
630  case "mark":
631  if (!ilObjectLP::supportsMark($type)) {
632  $value = "-";
633  }
634  break;
635 
636  case "gender":
637  $value = $this->lng->txt("gender_" . $value);
638  break;
639 
640  case "status":
641  $icons = ilLPStatusIcons::getInstance($this->getIconVariant());
642  $value = $icons->renderIconForStatus((int) $value);
643  break;
644 
645  case "language":
646  $this->lng->loadLanguageModule("meta");
647  $value = $this->lng->txt("meta_l_" . $value);
648  break;
649 
650  case "sel_country":
651  $value = $this->lng->txt("meta_c_" . $value);
652  break;
653  }
654 
655  return $value ?? '';
656  }
657 
658  public function getCurrentFilter(bool $as_query = false): array
659  {
660  $result = array();
661  foreach ($this->filter as $id => $value) {
662  $item = $this->getFilterItemByPostVar($id);
663  switch ($id) {
664  case "title":
665  case "country":
666  case "gender":
667  case "city":
668  case "language":
669  case "login":
670  case "firstname":
671  case "lastname":
672  case "mark":
673  case "u_comment":
674  case "institution":
675  case "department":
676  case "street":
677  case "zipcode":
678  case "email":
679  case "matriculation":
680  case "sel_country":
681  case "query":
682  case "type":
683  case "area":
684  if ($value) {
685  $result[$id] = $value;
686  }
687  break;
688 
689  case "status":
690  if (!is_null($value) && $value !== "") {
691  $result[$id] = $value;
692  }
693  break;
694 
695  case "user_total":
696  case "read_count":
697  case "percentage":
698  case "hide":
699  case "spent_seconds":
700  if (is_array($value) && implode("", $value)) {
701  $result[$id] = $value;
702  }
703  break;
704 
705  case "registration":
706  case "create_date":
707  case "first_access":
708  case "last_access":
709  case 'status_changed':
710  if ($value) {
711  if ($value["from"]) {
712  $result[$id]["from"] = $value["from"]->get(
714  );
715  }
716  if ($value["to"]) {
717  $result[$id]["to"] = $value["to"]->get(
719  );
720  }
721  }
722  break;
723 
724  case "birthday":
725  if ($value) {
726  if ($value["from"]) {
727  $result[$id]["from"] = $value["from"]->get(
729  );
730  $result[$id]["from"] = substr(
731  $result[$id]["from"],
732  0,
733  -8
734  ) . "00:00:00";
735  }
736  if ($value["to"]) {
737  $result[$id]["to"] = $value["to"]->get(
739  );
740  $result[$id]["to"] = substr(
741  $result[$id]["to"],
742  0,
743  -8
744  ) . "23:59:59";
745  }
746  }
747  break;
748  }
749  }
750  return $result;
751  }
752 
753  protected function isPercentageAvailable(int $a_obj_id): bool
754  {
755  if ($a_obj_id === 0) {
756  return false;
757  }
758  $olp = ilObjectLP::getInstance($a_obj_id);
759  $mode = $olp->getCurrentMode();
760  if (in_array(
761  $mode,
774  )
775  )) {
776  return true;
777  }
778  return false;
779  }
780 
781  protected function parseTitle(
782  int $a_obj_id,
783  string $action,
784  int $a_user_id = 0
785  ) {
786  global $DIC;
787 
788  $user = "";
789  if ($a_user_id) {
790  if ($a_user_id != $this->user->getId()) {
791  $a_user = ilObjectFactory::getInstanceByObjId($a_user_id);
792  } else {
793  $a_user = $this->user;
794  }
795  $user .= ", " . $a_user->getFullName(
796  ); // " [".$a_user->getLogin()."]";
797  }
798 
799  if ($a_obj_id != ROOT_FOLDER_ID) {
800  $this->setTitle(
801  $this->lng->txt(
802  $action
803  ) . ": " . $this->ilObjDataCache->lookupTitle($a_obj_id) . $user
804  );
805 
806  $olp = ilObjectLP::getInstance($a_obj_id);
807  $this->setDescription(
808  $this->lng->txt('trac_mode') . ": " . $olp->getModeText(
809  $olp->getCurrentMode()
810  )
811  );
812  } else {
813  $this->setTitle($this->lng->txt($action));
814  }
815  }
816 
820  protected function getExportMeta(): array
821  {
822  global $DIC;
823 
824  $ilClientIniFile = $DIC['ilClientIniFile'];
825 
826  /* see spec
827  Name of installation
828  Name of the course
829  Permalink to course
830  Owner of course object
831  Date of report generation
832  Reporting period
833  Name of person who generated the report.
834  */
835 
837 
838  $data = array();
839  $data[$this->lng->txt(
840  "trac_name_of_installation"
841  )] = $ilClientIniFile->readVariable('client', 'name');
842 
843  if ($this->obj_id) {
844  $data[$this->lng->txt(
845  "trac_object_name"
846  )] = $this->ilObjDataCache->lookupTitle((int) $this->obj_id);
847  if ($this->ref_id) {
848  $data[$this->lng->txt("trac_object_link")] = ilLink::_getLink(
849  $this->ref_id,
850  ilObject::_lookupType($this->obj_id)
851  );
852  }
853  $data[$this->lng->txt(
854  "trac_object_owner"
856  ilObject::_lookupOwner($this->obj_id)
857  );
858  }
859 
860  $data[$this->lng->txt(
861  "trac_report_date"
863  new ilDateTime(
864  time(),
866  )
867  );
868  $data[$this->lng->txt("trac_report_owner")] = $this->user->getFullName(
869  );
870 
871  return $data;
872  }
873 
874  protected function fillMetaExcel(ilExcel $a_excel, int &$a_row): void
875  {
876  foreach ($this->getExportMeta() as $caption => $value) {
877  $a_excel->setCell($a_row, 0, $caption);
878  $a_excel->setCell($a_row, 1, $value);
879  $a_row++;
880  }
881  $a_row++;
882  }
883 
884  protected function fillMetaCSV(ilCSVWriter $a_csv): void
885  {
886  foreach ($this->getExportMeta() as $caption => $value) {
887  $a_csv->addColumn(strip_tags($caption));
888  $a_csv->addColumn(strip_tags($value));
889  $a_csv->addRow();
890  }
891  $a_csv->addRow();
892  }
893 
899  protected function showTimingsWarning(int $a_ref_id, int $a_user_id)
900  {
901  $timing_cache = ilTimingCache::getInstanceByRefId($a_ref_id);
902  if ($timing_cache->isWarningRequired($a_user_id)) {
903  $timings = ilTimingCache::_getTimings($a_ref_id);
904  if (
905  $timings['item']['changeable'] &&
906  ($timings['user'][$a_user_id] ?? false) &&
907  $timings['user'][$a_user_id]['end']
908  ) {
909  $end = $timings['user'][$a_user_id]['end'];
910  } elseif ($timings['item']['suggestion_end']) {
911  $end = $timings['item']['suggestion_end'];
912  } else {
913  $end = true;
914  }
915  return $end;
916  }
917  return false;
918  }
919 
920  protected function formatSeconds(
921  int $seconds,
922  bool $a_shorten_zero = false
923  ): string {
924  $seconds = ($seconds > 0) ? $seconds : 0;
925  if ($a_shorten_zero && !$seconds) {
926  return "-";
927  }
928 
929  $hours = floor($seconds / 3600);
930  $rest = $seconds % 3600;
931 
932  $minutes = floor($rest / 60);
933  $rest = $rest % 60;
934 
935  if ($rest) {
936  $minutes++;
937  }
938 
939  return sprintf("%dh%02dm", $hours, $minutes);
940  }
941 
947  protected function anonymizeValue($a_value, bool $a_force_number = false)
948  {
949  // currently inactive
950  return $a_value;
951  }
952 
953  protected function buildValueScale(
954  int $a_max_value,
955  bool $a_anonymize = false,
956  bool $a_format_seconds = false
957  ): array {
958  $step = 0;
959  if ($a_max_value) {
960  $step = $a_max_value / 10;
961  $base = ceil(log($step, 10));
962  $fac = ceil($step / pow(10, ($base - 1)));
963  $step = pow(10, $base - 1) * $fac;
964  }
965  if ($step <= 1) {
966  $step = 1;
967  }
968  $ticks = range(0, $a_max_value + $step, $step);
969 
970  $value_ticks = array(0 => 0);
971  foreach ($ticks as $tick) {
972  $value = $tvalue = $tick;
973  if ($a_anonymize) {
974  $value = $this->anonymizeValue($value, true);
975  $tvalue = $this->anonymizeValue($tvalue);
976  }
977  if ($a_format_seconds) {
978  $tvalue = $this->formatSeconds($value);
979  }
980  $value_ticks[$value] = $tvalue;
981  }
982 
983  return $value_ticks;
984  }
985 
986  protected function getMonthsFilter($a_short = false): array
987  {
988  $options = array();
989  for ($loop = 0; $loop < 10; $loop++) {
990  $year = date("Y") - $loop;
991  $options[$year] = $year;
992  for ($loop2 = 12; $loop2 > 0; $loop2--) {
993  $month = str_pad($loop2, 2, "0", STR_PAD_LEFT);
994  if ($year . $month <= date("Ym")) {
995  if (!$a_short) {
996  $caption = $year . " / " . $this->lng->txt(
997  "month_" . $month . "_long"
998  );
999  } else {
1000  $caption = $year . "/" . $month;
1001  }
1002  $options[$year . "-" . $month] = $caption;
1003  }
1004  }
1005  }
1006  return $options;
1007  }
1008 
1009  protected function getMonthsYear($a_year = null, $a_short = false): array
1010  {
1011  if (!$a_year) {
1012  $a_year = date("Y");
1013  }
1014 
1015  $all = array();
1016  for ($loop = 1; $loop < 13; $loop++) {
1017  $month = str_pad($loop, 2, "0", STR_PAD_LEFT);
1018  if ($a_year . "-" . $month <= date("Y-m")) {
1019  if (!$a_short) {
1020  $caption = $this->lng->txt("month_" . $month . "_long");
1021  } else {
1022  $caption = $this->lng->txt("month_" . $month . "_short");
1023  }
1024  $all[$a_year . "-" . $month] = $caption;
1025  }
1026  }
1027  return $all;
1028  }
1029 
1030  protected function getSelectableUserColumns(
1031  int $a_in_course = 0,
1032  int $a_in_group = 0
1033  ): array {
1034  $cols = $privacy_fields = array();
1035 
1036  $up = new ilUserProfile();
1037  $up->skipGroup("preferences");
1038  $up->skipGroup("settings");
1039  $up->skipGroup("interests");
1040  $ufs = $up->getStandardFields();
1041 
1042  // default fields
1043  $cols["login"] = array(
1044  "txt" => $this->lng->txt("login"),
1045  "default" => true
1046  );
1047 
1048  if (!$this->anonymized) {
1049  $cols["firstname"] = array(
1050  "txt" => $this->lng->txt("firstname"),
1051  "default" => true
1052  );
1053  $cols["lastname"] = array(
1054  "txt" => $this->lng->txt("lastname"),
1055  "default" => true
1056  );
1057  }
1058 
1059  // show only if extended data was activated in lp settings
1060  $tracking = new ilObjUserTracking();
1061  if ($tracking->hasExtendedData(
1063  )) {
1064  $cols["first_access"] = array(
1065  "txt" => $this->lng->txt("trac_first_access"),
1066  "default" => true
1067  );
1068  $cols["last_access"] = array(
1069  "txt" => $this->lng->txt("trac_last_access"),
1070  "default" => true
1071  );
1072  }
1073  if ($tracking->hasExtendedData(
1075  )) {
1076  $cols["read_count"] = array(
1077  "txt" => $this->lng->txt("trac_read_count"),
1078  "default" => true
1079  );
1080  }
1081  if ($tracking->hasExtendedData(
1083  ) &&
1084  ilObjectLP::supportsSpentSeconds($this->type)) {
1085  $cols["spent_seconds"] = array(
1086  "txt" => $this->lng->txt("trac_spent_seconds"),
1087  "default" => true
1088  );
1089  }
1090 
1091  if ($this->isPercentageAvailable($this->obj_id)) {
1092  $cols["percentage"] = array(
1093  "txt" => $this->lng->txt("trac_percentage"),
1094  "default" => true
1095  );
1096  }
1097 
1098  // do not show status if learning progress is deactivated
1099  $olp = ilObjectLP::getInstance($this->obj_id);
1100  if ($olp->isActive()) {
1101  $cols["status"] = array(
1102  "txt" => $this->lng->txt("trac_status"),
1103  "default" => true
1104  );
1105 
1106  $cols['status_changed'] = array(
1107  'txt' => $this->lng->txt('trac_status_changed'),
1108  'default' => false
1109  );
1110  }
1111 
1112  if (ilObjectLP::supportsMark($this->type)) {
1113  $cols["mark"] = array(
1114  "txt" => $this->lng->txt("trac_mark"),
1115  "default" => true
1116  );
1117  }
1118 
1119  $cols["u_comment"] = array(
1120  "txt" => $this->lng->txt("trac_comment"),
1121  "default" => false
1122  );
1123 
1124  $cols["create_date"] = array(
1125  "txt" => $this->lng->txt("create_date"),
1126  "default" => false
1127  );
1128  $cols["language"] = array(
1129  "txt" => $this->lng->txt("language"),
1130  "default" => false
1131  );
1132 
1133  // add user data only if object is [part of] course
1134  if (!$this->anonymized &&
1135  ($a_in_course || $a_in_group)) {
1136  // only show if export permission is granted
1137  if (ilPrivacySettings::getInstance()->checkExportAccess(
1138  $a_in_group === 0 ? $a_in_course : $a_in_group
1139  )) {
1140  // other user profile fields
1141  foreach ($ufs as $f => $fd) {
1142  if (!isset($cols[$f]) && $f != "username" && !($fd["lists_hide"] ?? false)) {
1143  if ($a_in_course &&
1144  !(($fd["course_export_fix_value"] ?? false) || $this->setting->get(
1145  "usr_settings_course_export_" . $f
1146  ))) {
1147  continue;
1148  }
1149  if ($a_in_group &&
1150  !(($fd["group_export_fix_value"] ?? false) || $this->setting->get(
1151  "usr_settings_group_export_" . $f
1152  ))) {
1153  continue;
1154  }
1155 
1156  $cols[$f] = array(
1157  "txt" => $this->lng->txt($f),
1158  "default" => false
1159  );
1160  $privacy_fields[] = $f;
1161  }
1162  }
1163 
1164  // additional defined user data fields
1165  $user_defined_fields = ilUserDefinedFields::_getInstance();
1166  if ($a_in_course) {
1167  $user_defined_fields = $user_defined_fields->getCourseExportableFields(
1168  );
1169  } else {
1170  $user_defined_fields = $user_defined_fields->getGroupExportableFields(
1171  );
1172  }
1173  foreach ($user_defined_fields as $definition) {
1174  if ($definition["field_type"] != UDF_TYPE_WYSIWYG) {
1175  $f = "udf_" . $definition["field_id"];
1176  $cols[$f] = array(
1177  "txt" => $definition["field_name"],
1178  "default" => false
1179  );
1180 
1181  $privacy_fields[] = $f;
1182  }
1183  }
1184  }
1185  }
1186  return array($cols, $privacy_fields);
1187  }
1188 
1192  protected function addToClipboard(): void
1193  {
1194  $users = $this->initUidFromPost();
1195  $clip = ilUserClipboard::getInstance($this->user->getId());
1196  $clip->add($users);
1197  $clip->save();
1198  $this->lng->loadLanguageModule('user');
1199  $this->main_tpl->setOnScreenMessage(
1200  'success',
1201  $this->lng->txt(
1202  'clipboard_user_added'
1203  ),
1204  true
1205  );
1206  }
1207 
1211  public function getIconVariant(): int
1212  {
1213  return $this->icon_variant;
1214  }
1215 
1219  public function setIconVariant(int $variant): void
1220  {
1221  $this->icon_variant = $variant;
1222  }
1223 }
buildValueScale(int $a_max_value, bool $a_anonymize=false, bool $a_format_seconds=false)
addColumn(string $a_col)
$res
Definition: ltiservices.php:69
getPossibleTypes(bool $a_split_learning_resources=false, bool $a_include_digilib=false, bool $a_allow_undefined_lp=false)
getCurrentFilter(bool $as_query=false)
const IL_CAL_DATETIME
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static getLogger(string $a_component_id)
Get component logger.
This class represents a selection list property in a property form.
addFilterItem(ilTableFilterItem $a_input_item, bool $a_optional=false)
const ROOT_FOLDER_ID
Definition: constants.php:32
static _lookupFullname(int $a_user_id)
getSelectableUserColumns(int $a_in_course=0, int $a_in_group=0)
findReferencesForObjId(int $a_obj_id)
getMonthsYear($a_year=null, $a_short=false)
searchObjects(array $filter, string $permission, ?array $preset_obj_ids=null, bool $a_check_lp_activation=true)
Search objects that match current filters.
static _getAllReferences(int $id)
get all reference ids for object ID
fillMetaExcel(ilExcel $a_excel, int &$a_row)
sendMail(array $a_user_ids, $a_parent_obj, string $a_parent_cmd)
static formatDate(ilDateTime $date, bool $a_skip_day=false, bool $a_include_wd=false, bool $include_seconds=false)
setDescription(string $a_val)
static getInstance(int $variant=ilLPStatusIcons::ICON_VARIANT_DEFAULT, ?\ILIAS\UI\Renderer $renderer=null, ?\ILIAS\UI\Factory $factory=null)
setDisableFilterHiding(bool $a_val=true)
Class ilUserProfile.
__construct(?object $a_parent_obj, string $a_parent_cmd="", string $a_template_context="")
fillMetaCSV(ilCSVWriter $a_csv)
static _lookupOwner(int $obj_id)
Lookup owner user ID for object ID.
setCell(int $a_row, int $a_col, $a_value, ?string $a_datatype=null)
Set cell value.
setOptions(array $a_options)
const IL_CAL_UNIX
static secondsToString(int $seconds, bool $force_with_seconds=false, ?ilLanguage $a_lng=null)
converts seconds to string: Long: 7 days 4 hour(s) ...
addToClipboard()
Add selected users to clipboard.
$path
Definition: ltiservices.php:32
searchFilterListener(int $a_ref_id, array $a_data)
Listener for SearchResultFilter Checks wheather the object is hidden and mode is not LP_MODE_DEACTIVA...
getFilterItemByPostVar(string $a_post_var)
global $DIC
Definition: feed.php:28
parses the objects.xml it handles the xml-description of all ilias objects
resetOffset(bool $a_in_determination=false)
initBaseFilter(bool $a_split_learning_resources=false, bool $a_include_no_status_filter=true)
Init filter.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
anonymizeValue($a_value, bool $a_force_number=false)
$ref_id
Definition: ltiauth.php:67
static http()
Fetches the global http state from ILIAS.
__construct(VocabulariesInterface $vocabularies)
TableGUI class for learning progress.
getExportMeta()
Build export meta data.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
isPercentageAvailable(int $a_obj_id)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
setIconVariant(int $variant)
Sets the variant of LP icons that is shown in the table.
getIconVariant()
Gets the variant of LP icons that is shown in the table.
parseValue(string $id, ?string $value, string $type)
ilObjectDataCache $ilObjDataCache
ilObjectDefinition $objDefinition
static _lookupObjectId(int $ref_id)
formatSeconds(int $seconds, bool $a_shorten_zero=false)
const UDF_TYPE_WYSIWYG
setTitle(string $a_title, string $a_icon="", string $a_icon_alt="")
static lookupTxtById(string $plugin_id, string $lang_var)
static redirect(string $a_script)
static isTypePluginWithLP(string $a_type, bool $a_active_status=true)
initRepositoryFilter(array $filter)
static getInstanceByObjId(?int $obj_id, bool $stop_on_error=true)
get an instance of an Ilias object by object id
static supportsSpentSeconds(string $obj_type)
const IL_CAL_DATE
ilGlobalTemplateInterface $main_tpl
getMonthsFilter($a_short=false)
const LP_MODE_CMIX_COMPL_OR_PASSED_WITH_FAILED
static getRedirectTarget( $gui, string $cmd, array $gui_params=[], array $mail_params=[], array $context_params=[])
filter(string $filter_id, $class_path, string $cmd, bool $activated=true, bool $expanded=true)
static _getTimings(int $a_ref_id)
static supportsMark(string $obj_type)
static _lookupType(int $id, bool $reference=false)
static setUseRelativeDates(bool $a_status)
set use relative dates
parseTitle(int $a_obj_id, string $action, int $a_user_id=0)
showTimingsWarning(int $a_ref_id, int $a_user_id)
static getInstance(int $obj_id)
determineOffsetAndOrder(bool $a_omit_offset=false)
storeProperty(string $type, string $value)
static getInstance(int $a_usr_id)
static getInstanceByRefId(int $ref_id)
RefineryFactory $refinery
static _lookupLogin(int $a_user_id)