ILIAS  trunk Revision v11.0_alpha-2638-g80c1d007f79
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  $options = [];
415  foreach ($this->filter["hide"] as $obj_id) {
416  $options[$obj_id] = $this->ilObjDataCache->lookupTitle(
417  (int) $obj_id
418  );
419  }
420  $msi->setOptions($options);
421  }
422 
423  // title/description
424  $ti = new ilTextInputGUI(
425  $this->lng->txt("trac_title_description"),
426  "query"
427  );
428  $ti->setMaxLength(64);
429  $ti->setSize(20);
430  $this->addFilterItem($ti);
431  $ti->readFromSession();
432  $this->filter["query"] = $ti->getValue();
433 
434  // repository area selection
436  $this->lng->txt("trac_filter_area"),
437  "area"
438  );
439  $rs->setSelectText($this->lng->txt("trac_select_area"));
440  $this->addFilterItem($rs);
441  $rs->readFromSession();
442  $this->filter["area"] = $rs->getValue();
443 
444  // hide "not started yet"
445  if ($a_include_no_status_filter) {
446  $cb = new ilCheckboxInputGUI(
447  $this->lng->txt("trac_filter_has_status"),
448  "status"
449  );
450  $this->addFilterItem($cb);
451  $cb->readFromSession();
452  $this->filter["status"] = $cb->getChecked();
453  }
454  }
455 
458  protected function buildPath(array $ref_ids): array
459  {
460  if (!count($ref_ids)) {
461  return [];
462  }
463  $result = [];
464  foreach ($ref_ids as $ref_id) {
465  $path = "...";
466  $counter = 0;
467  $path_full = $this->tree->getPathFull($ref_id);
468  foreach ($path_full as $data) {
469  if (++$counter < (count($path_full) - 1)) {
470  continue;
471  }
472  $path .= " &raquo; ";
473  if ($ref_id != $data['ref_id']) {
474  $path .= $data['title'];
475  } else {
476  $path .= ('<a target="_top" href="' .
477  ilLink::_getLink(
478  $data['ref_id'],
479  $data['type']
480  ) . '">' .
481  $data['title'] . '</a>');
482  }
483  }
484 
485  $result[$ref_id] = $path;
486  }
487  return $result;
488  }
489 
490  protected function getPossibleTypes(
491  bool $a_split_learning_resources = false,
492  bool $a_include_digilib = false,
493  bool $a_allow_undefined_lp = false
494  ): array {
495  global $DIC;
496 
497  $component_repository = $DIC['component.repository'];
498 
499  $options = array();
500 
501  if ($a_split_learning_resources) {
502  $options['lm'] = $this->lng->txt('objs_lm');
503  $options['sahs'] = $this->lng->txt('objs_sahs');
504  $options['htlm'] = $this->lng->txt('objs_htlm');
505  } else {
506  $options['lres'] = $this->lng->txt('obj_lrss');
507  }
508 
509  $options['crs'] = $this->lng->txt('objs_crs');
510  $options['grp'] = $this->lng->txt('objs_grp');
511  $options['exc'] = $this->lng->txt('objs_exc');
512  $options['file'] = $this->lng->txt('objs_file');
513  $options['mcst'] = $this->lng->txt('objs_mcst');
514  $options['svy'] = $this->lng->txt('objs_svy');
515  $options['tst'] = $this->lng->txt('objs_tst');
516  $options['prg'] = $this->lng->txt('objs_prg');
517  $options['iass'] = $this->lng->txt('objs_iass');
518  $options['copa'] = $this->lng->txt('objs_copa');
519  $options['frm'] = $this->lng->txt('objs_frm');
520  $options['cmix'] = $this->lng->txt('objs_cmix');
521  $options['lti'] = $this->lng->txt('objs_lti');
522  $options['lso'] = $this->lng->txt('objs_lso');
523  $options['dcl'] = $this->lng->txt('objs_dcl');
524 
525  if ($a_allow_undefined_lp) {
526  $options['root'] = $this->lng->txt('obj_reps');
527  $options['cat'] = $this->lng->txt('objs_cat');
528  $options["webr"] = $this->lng->txt("objs_webr");
529  $options["wiki"] = $this->lng->txt("objs_wiki");
530  $options["blog"] = $this->lng->txt("objs_blog");
531  $options["prtf"] = $this->lng->txt("objs_prtf");
532  $options["prtt"] = $this->lng->txt("objs_prtt");
533  }
534 
535  // repository plugins (currently only active)
536  $plugins = $component_repository->getPluginSlotById(
537  "robj"
538  )->getActivePlugins();
539  foreach ($plugins as $pl) {
540  $pl_id = $pl->getId();
542  $options[$pl_id] = ilObjectPlugin::lookupTxtById(
543  $pl_id,
544  "objs_" . $pl_id
545  );
546  }
547  }
548 
549  asort($options);
550  return $options;
551  }
552 
553  protected function parseValue(
554  string $id,
555  ?string $value,
556  string $type
557  ): string {
558  // get rid of aggregation
559  $pos = strrpos($id, "_");
560  if ($pos !== false) {
561  $function = strtoupper(substr($id, $pos + 1));
562  if (in_array(
563  $function,
564  array("MIN", "MAX", "SUM", "AVG", "COUNT")
565  )) {
566  $id = substr($id, 0, $pos);
567  }
568  }
569 
570  if ((trim((string) $value) == "") && $id != "status") {
571  if ($id == "title" &&
572  get_class($this) != "ilTrObjectUsersPropsTableGUI" &&
573  get_class($this) != "ilTrMatrixTableGUI") {
574  return "--" . $this->lng->txt("none") . "--";
575  }
576  return " ";
577  }
578 
579  switch ($id) {
580  case "first_access":
581  case "create_date":
582  case 'status_changed':
584  new ilDateTime($value, IL_CAL_DATETIME)
585  );
586  break;
587 
588  case "last_access":
590  new ilDateTime($value, IL_CAL_UNIX)
591  );
592  break;
593 
594  case "birthday":
596  new ilDate($value, IL_CAL_DATE)
597  );
598  break;
599 
600  case "spent_seconds":
601  if (!ilObjectLP::supportsSpentSeconds($type)) {
602  $value = "-";
603  } else {
605  (int) $value,
606  ((int) $value < 3600 ? true : false)
607  ); // #14858
608  }
609  break;
610 
611  case "percentage":
612  if (false /* $this->isPercentageAvailable() */) {
613  $value = "-";
614  } else {
615  $value = $value . "%";
616  }
617  break;
618 
619  case "mark":
620  if (!ilObjectLP::supportsMark($type)) {
621  $value = "-";
622  }
623  break;
624 
625  case "gender":
626  $value = $this->lng->txt("gender_" . $value);
627  break;
628 
629  case "status":
630  $icons = ilLPStatusIcons::getInstance($this->getIconVariant());
631  $value = $icons->renderIconForStatus((int) $value);
632  break;
633 
634  case "language":
635  $this->lng->loadLanguageModule("meta");
636  $value = $this->lng->txt("meta_l_" . $value);
637  break;
638 
639  case "sel_country":
640  $value = $this->lng->txt("meta_c_" . $value);
641  break;
642  }
643 
644  return $value ?? '';
645  }
646 
647  public function getCurrentFilter(bool $as_query = false): array
648  {
649  $result = array();
650  foreach ($this->filter as $id => $value) {
651  $item = $this->getFilterItemByPostVar($id);
652  switch ($id) {
653  case "title":
654  case "country":
655  case "gender":
656  case "city":
657  case "language":
658  case "login":
659  case "firstname":
660  case "lastname":
661  case "mark":
662  case "u_comment":
663  case "institution":
664  case "department":
665  case "street":
666  case "zipcode":
667  case "email":
668  case "matriculation":
669  case "sel_country":
670  case "query":
671  case "type":
672  case "area":
673  if ($value) {
674  $result[$id] = $value;
675  }
676  break;
677 
678  case "status":
679  if (!is_null($value) && $value !== "") {
680  $result[$id] = $value;
681  }
682  break;
683 
684  case "user_total":
685  case "read_count":
686  case "percentage":
687  case "hide":
688  case "spent_seconds":
689  if (is_array($value) && implode("", $value)) {
690  $result[$id] = $value;
691  }
692  break;
693 
694  case "registration":
695  case "create_date":
696  case "first_access":
697  case "last_access":
698  case 'status_changed':
699  if ($value) {
700  if ($value["from"]) {
701  $result[$id]["from"] = $value["from"]->get(
703  );
704  }
705  if ($value["to"]) {
706  $result[$id]["to"] = $value["to"]->get(
708  );
709  }
710  }
711  break;
712 
713  case "birthday":
714  if ($value) {
715  if ($value["from"]) {
716  $result[$id]["from"] = $value["from"]->get(
718  );
719  $result[$id]["from"] = substr(
720  $result[$id]["from"],
721  0,
722  -8
723  ) . "00:00:00";
724  }
725  if ($value["to"]) {
726  $result[$id]["to"] = $value["to"]->get(
728  );
729  $result[$id]["to"] = substr(
730  $result[$id]["to"],
731  0,
732  -8
733  ) . "23:59:59";
734  }
735  }
736  break;
737  }
738  }
739  return $result;
740  }
741 
742  protected function isPercentageAvailable(int $a_obj_id): bool
743  {
744  if ($a_obj_id === 0) {
745  return false;
746  }
747  $olp = ilObjectLP::getInstance($a_obj_id);
748  $mode = $olp->getCurrentMode();
749  if (in_array(
750  $mode,
751  [
765  ]
766  )) {
767  return true;
768  }
769  return false;
770  }
771 
772  protected function parseTitle(
773  int $a_obj_id,
774  string $action,
775  int $a_user_id = 0
776  ) {
777  global $DIC;
778 
779  $user = "";
780  if ($a_user_id) {
781  if ($a_user_id != $this->user->getId()) {
782  $a_user = ilObjectFactory::getInstanceByObjId($a_user_id);
783  } else {
784  $a_user = $this->user;
785  }
786  $user .= ", " . $a_user->getFullName(
787  ); // " [".$a_user->getLogin()."]";
788  }
789 
790  if ($a_obj_id != ROOT_FOLDER_ID) {
791  $this->setTitle(
792  $this->lng->txt(
793  $action
794  ) . ": " . $this->ilObjDataCache->lookupTitle($a_obj_id) . $user
795  );
796 
797  $olp = ilObjectLP::getInstance($a_obj_id);
798  $this->setDescription(
799  $this->lng->txt('trac_mode') . ": " . $olp->getModeText(
800  $olp->getCurrentMode()
801  )
802  );
803  } else {
804  $this->setTitle($this->lng->txt($action));
805  }
806  }
807 
811  protected function getExportMeta(): array
812  {
813  global $DIC;
814 
815  $ilClientIniFile = $DIC['ilClientIniFile'];
816 
817  /* see spec
818  Name of installation
819  Name of the course
820  Permalink to course
821  Owner of course object
822  Date of report generation
823  Reporting period
824  Name of person who generated the report.
825  */
826 
828 
829  $data = array();
830  $data[$this->lng->txt(
831  "trac_name_of_installation"
832  )] = $ilClientIniFile->readVariable('client', 'name');
833 
834  if ($this->obj_id) {
835  $data[$this->lng->txt(
836  "trac_object_name"
837  )] = $this->ilObjDataCache->lookupTitle((int) $this->obj_id);
838  if ($this->ref_id) {
839  $data[$this->lng->txt("trac_object_link")] = ilLink::_getLink(
840  $this->ref_id,
841  ilObject::_lookupType($this->obj_id)
842  );
843  }
844  $data[$this->lng->txt(
845  "trac_object_owner"
847  ilObject::_lookupOwner($this->obj_id)
848  );
849  }
850 
851  $data[$this->lng->txt(
852  "trac_report_date"
854  new ilDateTime(
855  time(),
857  )
858  );
859  $data[$this->lng->txt("trac_report_owner")] = $this->user->getFullName(
860  );
861 
862  return $data;
863  }
864 
865  protected function fillMetaExcel(ilExcel $a_excel, int &$a_row): void
866  {
867  foreach ($this->getExportMeta() as $caption => $value) {
868  $a_excel->setCell($a_row, 0, $caption);
869  $a_excel->setCell($a_row, 1, $value);
870  $a_row++;
871  }
872  $a_row++;
873  }
874 
875  protected function fillMetaCSV(ilCSVWriter $a_csv): void
876  {
877  foreach ($this->getExportMeta() as $caption => $value) {
878  $a_csv->addColumn(strip_tags($caption));
879  $a_csv->addColumn(strip_tags($value));
880  $a_csv->addRow();
881  }
882  $a_csv->addRow();
883  }
884 
890  protected function showTimingsWarning(int $a_ref_id, int $a_user_id)
891  {
892  $timing_cache = ilTimingCache::getInstanceByRefId($a_ref_id);
893  if ($timing_cache->isWarningRequired($a_user_id)) {
894  $timings = ilTimingCache::_getTimings($a_ref_id);
895  if (
896  $timings['item']['changeable'] &&
897  ($timings['user'][$a_user_id] ?? false) &&
898  $timings['user'][$a_user_id]['end']
899  ) {
900  $end = $timings['user'][$a_user_id]['end'];
901  } elseif ($timings['item']['suggestion_end']) {
902  $end = $timings['item']['suggestion_end'];
903  } else {
904  $end = true;
905  }
906  return $end;
907  }
908  return false;
909  }
910 
911  protected function formatSeconds(
912  int $seconds,
913  bool $a_shorten_zero = false
914  ): string {
915  $seconds = ($seconds > 0) ? $seconds : 0;
916  if ($a_shorten_zero && !$seconds) {
917  return "-";
918  }
919 
920  $hours = floor($seconds / 3600);
921  $rest = $seconds % 3600;
922 
923  $minutes = floor($rest / 60);
924  $rest = $rest % 60;
925 
926  if ($rest) {
927  $minutes++;
928  }
929 
930  return sprintf("%dh%02dm", $hours, $minutes);
931  }
932 
938  protected function anonymizeValue($a_value, bool $a_force_number = false)
939  {
940  // currently inactive
941  return $a_value;
942  }
943 
944  protected function buildValueScale(
945  int $a_max_value,
946  bool $a_anonymize = false,
947  bool $a_format_seconds = false
948  ): array {
949  $step = 0;
950  if ($a_max_value) {
951  $step = $a_max_value / 10;
952  $base = ceil(log($step, 10));
953  $fac = ceil($step / pow(10, ($base - 1)));
954  $step = pow(10, $base - 1) * $fac;
955  }
956  if ($step <= 1) {
957  $step = 1;
958  }
959  $ticks = range(0, $a_max_value + $step, $step);
960 
961  $value_ticks = array(0 => 0);
962  foreach ($ticks as $tick) {
963  $value = $tvalue = $tick;
964  if ($a_anonymize) {
965  $value = $this->anonymizeValue($value, true);
966  $tvalue = $this->anonymizeValue($tvalue);
967  }
968  if ($a_format_seconds) {
969  $tvalue = $this->formatSeconds($value);
970  }
971  $value_ticks[$value] = $tvalue;
972  }
973 
974  return $value_ticks;
975  }
976 
977  protected function getMonthsFilter($a_short = false): array
978  {
979  $options = array();
980  for ($loop = 0; $loop < 10; $loop++) {
981  $year = date("Y") - $loop;
982  $options[$year] = $year;
983  for ($loop2 = 12; $loop2 > 0; $loop2--) {
984  $month = str_pad($loop2, 2, "0", STR_PAD_LEFT);
985  if ($year . $month <= date("Ym")) {
986  if (!$a_short) {
987  $caption = $year . " / " . $this->lng->txt(
988  "month_" . $month . "_long"
989  );
990  } else {
991  $caption = $year . "/" . $month;
992  }
993  $options[$year . "-" . $month] = $caption;
994  }
995  }
996  }
997  return $options;
998  }
999 
1000  protected function getMonthsYear($a_year = null, $a_short = false): array
1001  {
1002  if (!$a_year) {
1003  $a_year = date("Y");
1004  }
1005 
1006  $all = array();
1007  for ($loop = 1; $loop < 13; $loop++) {
1008  $month = str_pad($loop, 2, "0", STR_PAD_LEFT);
1009  if ($a_year . "-" . $month <= date("Y-m")) {
1010  if (!$a_short) {
1011  $caption = $this->lng->txt("month_" . $month . "_long");
1012  } else {
1013  $caption = $this->lng->txt("month_" . $month . "_short");
1014  }
1015  $all[$a_year . "-" . $month] = $caption;
1016  }
1017  }
1018  return $all;
1019  }
1020 
1021  protected function getSelectableUserColumns(
1022  int $a_in_course = 0,
1023  int $a_in_group = 0
1024  ): array {
1025  $cols = $privacy_fields = array();
1026 
1027  $up = new ilUserProfile();
1028  $up->skipGroup("preferences");
1029  $up->skipGroup("settings");
1030  $up->skipGroup("interests");
1031  $ufs = $up->getStandardFields();
1032 
1033  // default fields
1034  $cols["login"] = array(
1035  "txt" => $this->lng->txt("login"),
1036  "default" => true
1037  );
1038 
1039  if (!$this->anonymized) {
1040  $cols["firstname"] = array(
1041  "txt" => $this->lng->txt("firstname"),
1042  "default" => true
1043  );
1044  $cols["lastname"] = array(
1045  "txt" => $this->lng->txt("lastname"),
1046  "default" => true
1047  );
1048  }
1049 
1050  // show only if extended data was activated in lp settings
1051  $tracking = new ilObjUserTracking();
1052  if ($tracking->hasExtendedData(
1054  )) {
1055  $cols["first_access"] = array(
1056  "txt" => $this->lng->txt("trac_first_access"),
1057  "default" => true
1058  );
1059  $cols["last_access"] = array(
1060  "txt" => $this->lng->txt("trac_last_access"),
1061  "default" => true
1062  );
1063  }
1064  if ($tracking->hasExtendedData(
1066  )) {
1067  $cols["read_count"] = array(
1068  "txt" => $this->lng->txt("trac_read_count"),
1069  "default" => true
1070  );
1071  }
1072  if ($tracking->hasExtendedData(
1074  ) &&
1075  ilObjectLP::supportsSpentSeconds($this->type)) {
1076  $cols["spent_seconds"] = array(
1077  "txt" => $this->lng->txt("trac_spent_seconds"),
1078  "default" => true
1079  );
1080  }
1081 
1082  if ($this->isPercentageAvailable($this->obj_id)) {
1083  $cols["percentage"] = array(
1084  "txt" => $this->lng->txt("trac_percentage"),
1085  "default" => true
1086  );
1087  }
1088 
1089  // do not show status if learning progress is deactivated
1090  $olp = ilObjectLP::getInstance($this->obj_id);
1091  if ($olp->isActive()) {
1092  $cols["status"] = array(
1093  "txt" => $this->lng->txt("trac_status"),
1094  "default" => true
1095  );
1096 
1097  $cols['status_changed'] = array(
1098  'txt' => $this->lng->txt('trac_status_changed'),
1099  'default' => false
1100  );
1101  }
1102 
1103  if (ilObjectLP::supportsMark($this->type)) {
1104  $cols["mark"] = array(
1105  "txt" => $this->lng->txt("trac_mark"),
1106  "default" => true
1107  );
1108  }
1109 
1110  $cols["u_comment"] = array(
1111  "txt" => $this->lng->txt("trac_comment"),
1112  "default" => false
1113  );
1114 
1115  $cols["create_date"] = array(
1116  "txt" => $this->lng->txt("create_date"),
1117  "default" => false
1118  );
1119  $cols["language"] = array(
1120  "txt" => $this->lng->txt("language"),
1121  "default" => false
1122  );
1123 
1124  // add user data only if object is [part of] course
1125  if (!$this->anonymized &&
1126  ($a_in_course || $a_in_group)) {
1127  // only show if export permission is granted
1128  if (ilPrivacySettings::getInstance()->checkExportAccess(
1129  $a_in_group === 0 ? $a_in_course : $a_in_group
1130  )) {
1131  // other user profile fields
1132  foreach ($ufs as $f => $fd) {
1133  if (!isset($cols[$f]) && $f != "username" && !($fd["lists_hide"] ?? false)) {
1134  if ($a_in_course &&
1135  !(($fd["course_export_fix_value"] ?? false) || $this->setting->get(
1136  "usr_settings_course_export_" . $f
1137  ))) {
1138  continue;
1139  }
1140  if ($a_in_group &&
1141  !(($fd["group_export_fix_value"] ?? false) || $this->setting->get(
1142  "usr_settings_group_export_" . $f
1143  ))) {
1144  continue;
1145  }
1146 
1147  $cols[$f] = array(
1148  "txt" => $this->lng->txt($f),
1149  "default" => false
1150  );
1151  $privacy_fields[] = $f;
1152  }
1153  }
1154 
1155  // additional defined user data fields
1156  $user_defined_fields = ilUserDefinedFields::_getInstance();
1157  if ($a_in_course) {
1158  $user_defined_fields = $user_defined_fields->getCourseExportableFields(
1159  );
1160  } else {
1161  $user_defined_fields = $user_defined_fields->getGroupExportableFields(
1162  );
1163  }
1164  foreach ($user_defined_fields as $definition) {
1165  if ($definition["field_type"] != UDF_TYPE_WYSIWYG) {
1166  $f = "udf_" . $definition["field_id"];
1167  $cols[$f] = array(
1168  "txt" => $definition["field_name"],
1169  "default" => false
1170  );
1171 
1172  $privacy_fields[] = $f;
1173  }
1174  }
1175  }
1176  }
1177  return array($cols, $privacy_fields);
1178  }
1179 
1183  protected function addToClipboard(): void
1184  {
1185  $users = $this->initUidFromPost();
1186  $clip = ilUserClipboard::getInstance($this->user->getId());
1187  $clip->add($users);
1188  $clip->save();
1189  $this->lng->loadLanguageModule('user');
1190  $this->main_tpl->setOnScreenMessage(
1191  'success',
1192  $this->lng->txt(
1193  'clipboard_user_added'
1194  ),
1195  true
1196  );
1197  }
1198 
1202  public function getIconVariant(): int
1203  {
1204  return $this->icon_variant;
1205  }
1206 
1210  public function setIconVariant(int $variant): void
1211  {
1212  $this->icon_variant = $variant;
1213  }
1214 }
buildValueScale(int $a_max_value, bool $a_anonymize=false, bool $a_format_seconds=false)
static array static setUseRelativeDates(bool $a_status)
set use relative dates
addColumn(string $a_col)
$res
Definition: ltiservices.php:66
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)
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.
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.
sort()
description: > Example for rendering a Sort Glyph.
Definition: sort.php:41
$path
Definition: ltiservices.php:29
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)
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
resetOffset(bool $a_in_determination=false)
initBaseFilter(bool $a_split_learning_resources=false, bool $a_include_no_status_filter=true)
Init filter.
This class represents a multi selection list property in a property form.
anonymizeValue($a_value, bool $a_force_number=false)
setCell(int $a_row, int $col, $value, ?string $datatype=null, bool $disable_strip_tags_for_strings=false)
Set cell value.
$ref_id
Definition: ltiauth.php:65
static http()
Fetches the global http state from ILIAS.
TableGUI class for learning progress.
getExportMeta()
Build export meta data.
isPercentageAvailable(int $a_obj_id)
This class represents a repository selector in a property form.
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)
global $DIC
Definition: shib_login.php:26
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
final const string CONTEXT_KEY
ilGlobalTemplateInterface $main_tpl
getMonthsFilter($a_short=false)
__construct(Container $dic, ilPlugin $plugin)
const LP_MODE_CMIX_COMPL_OR_PASSED_WITH_FAILED
static formatDate(ilDateTime $date, bool $a_skip_day=false, bool $a_include_wd=false, bool $include_seconds=false, ?ilObjUser $user=null,)
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)
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)