ILIAS  trunk Revision v11.0_alpha-2638-g80c1d007f79
class.ilMailSearchObjectGUI.php
Go to the documentation of this file.
1 <?php
2 
19 declare(strict_types=1);
20 
23 
24 abstract class ilMailSearchObjectGUI
25 {
27  protected Refinery $refinery;
28  protected ?string $view = null;
31  protected ilLanguage $lng;
32  protected ilObjUser $user;
36  protected ilTree $tree;
38  protected ilFormatMail $umail;
39  protected bool $mailing_allowed;
40  protected \ILIAS\UI\Factory $ui_factory;
41  protected \ILIAS\UI\Renderer $ui_renderer;
42 
47  public function __construct(protected $wsp_access_handler = null, protected ?int $wsp_node_id = null)
48  {
49  global $DIC;
50 
51  $this->tpl = $DIC['tpl'];
52  $this->ctrl = $DIC['ilCtrl'];
53  $this->lng = $DIC['lng'];
54  $this->user = $DIC['ilUser'];
55  $this->error = $DIC['ilErr'];
56  $this->rbacsystem = $DIC['rbacsystem'];
57  $this->rbacreview = $DIC['rbacreview'];
58  $this->tree = $DIC['tree'];
59  $this->cache = $DIC['ilObjDataCache'];
60  $this->http = $DIC->http();
61  $this->refinery = $DIC->refinery();
62  $this->ui_factory = $DIC->ui()->factory();
63  $this->ui_renderer = $DIC->ui()->renderer();
64 
65  $this->ctrl->saveParameter($this, 'mobj_id');
66  $this->ctrl->saveParameter($this, 'ref');
67 
68  $mail = new ilMail($this->user->getId());
69  $this->mailing_allowed = $this->rbacsystem->checkAccess('internal_mail', $mail->getMailObjectReferenceId());
70 
71  $this->umail = new ilFormatMail($this->user->getId());
72 
73  $this->lng->loadLanguageModule('mail');
74  }
75 
76  private function isDefaultRequestContext(): bool
77  {
78  return (
79  !$this->http->wrapper()->query()->has('ref') ||
80  $this->http->wrapper()->query()->retrieve('ref', $this->refinery->kindlyTo()->string()) !== 'wsp'
81  );
82  }
83 
84  private function getContext(): string
85  {
86  $context = 'mail';
87  if ($this->http->wrapper()->query()->has('ref')) {
88  $context = $this->http->wrapper()->query()->retrieve('ref', $this->refinery->kindlyTo()->string());
89  }
90 
91  return $context;
92  }
93 
94  private function isLocalRoleTitle(string $title): bool
95  {
96  foreach ($this->getLocalDefaultRolePrefixes() as $local_role_prefix) {
97  if (str_starts_with($title, $local_role_prefix)) {
98  return true;
99  }
100  }
101 
102  return false;
103  }
104 
105  abstract protected function getObjectType(): string;
106 
110  abstract protected function getLocalDefaultRolePrefixes(): array;
111 
112  protected function getRequestValue(string $key, \ILIAS\Refinery\Transformation $trafo, $default = null)
113  {
114  $value = $default;
115  if ($this->http->wrapper()->query()->has($key)) {
116  $value = $this->http->wrapper()->query()->retrieve($key, $trafo);
117  }
118 
119  if ($this->http->wrapper()->post()->has($key)) {
120  $value = $this->http->wrapper()->post()->retrieve($key, $trafo);
121  }
122 
123  return $value;
124  }
125 
129  protected function addPermission(array $a_obj_ids): void
130  {
131  $added = $this->wsp_access_handler->addMissingPermissionForObjects($this->wsp_node_id, $a_obj_ids);
132 
133  if ($added) {
134  $this->tpl->setOnScreenMessage('success', $this->lng->txt('wsp_share_success'), true);
135  }
136  $this->ctrl->redirectByClass(ilWorkspaceAccessGUI::class, 'share');
137  }
138 
139  protected function share(): void
140  {
141  $view = '';
142  if ($this->http->wrapper()->query()->has('view')) {
143  $view = $this->http->wrapper()->query()->retrieve('view', $this->refinery->kindlyTo()->string());
144  }
145 
146  if ($view === 'myobjects') {
147  $obj_ids = [];
148  if ($this->http->wrapper()->query()->has('search_' . $this->getObjectType())) {
149  $obj_ids = [
150  $this->http->wrapper()->query()->retrieve(
151  'search_' . $this->getObjectType(),
152  $this->refinery->kindlyTo()->int()
153  )
154  ];
155  } elseif ($this->http->wrapper()->post()->has('search_' . $this->getObjectType())) {
156  $obj_ids = $this->http->wrapper()->post()->retrieve(
157  'search_' . $this->getObjectType(),
158  $this->refinery->kindlyTo()->listOf($this->refinery->kindlyTo()->int())
159  );
160  }
161 
162  if ($obj_ids !== []) {
163  $this->addPermission($obj_ids);
164  } else {
165  $this->tpl->setOnScreenMessage('info', $this->lng->txt('mail_select_' . $this->getObjectType()));
166  $this->showMyObjects();
167  }
168  } elseif ($view === $this->getObjectType() . '_members') {
169  $usr_ids = [];
170  if ($this->http->wrapper()->query()->has('search_members')) {
171  $usr_ids = [
172  $this->http->wrapper()->query()->retrieve(
173  'search_members',
174  $this->refinery->kindlyTo()->int()
175  )
176  ];
177  } elseif ($this->http->wrapper()->post()->has('search_members')) {
178  $usr_ids = $this->http->wrapper()->post()->retrieve(
179  'search_members',
180  $this->refinery->kindlyTo()->listOf($this->refinery->kindlyTo()->int())
181  );
182  }
183 
184  if ($usr_ids !== []) {
185  $this->addPermission($usr_ids);
186  } else {
187  $this->tpl->setOnScreenMessage('info', $this->lng->txt('mail_select_one_entry'));
188  $this->showMembers();
189  }
190  } else {
191  $this->showMyObjects();
192  }
193  }
194 
195  protected function mail(): void
196  {
197  $view = '';
198  if ($this->http->wrapper()->query()->has('view')) {
199  $view = $this->http->wrapper()->query()->retrieve('view', $this->refinery->kindlyTo()->string());
200  }
201 
202  if ($view === 'myobjects') {
203  $obj_ids = [];
204  if ($this->http->wrapper()->query()->has('search_' . $this->getObjectType())) {
205  $obj_ids = [
206  $this->http->wrapper()->query()->retrieve(
207  'search_' . $this->getObjectType(),
208  $this->refinery->kindlyTo()->int()
209  )
210  ];
211  } elseif ($this->http->wrapper()->post()->has('search_' . $this->getObjectType())) {
212  $obj_ids = $this->http->wrapper()->post()->retrieve(
213  'search_' . $this->getObjectType(),
214  $this->refinery->kindlyTo()->listOf($this->refinery->kindlyTo()->int())
215  );
216  }
217 
218  if ($obj_ids !== []) {
219  $this->mailObjects();
220  } else {
221  $this->tpl->setOnScreenMessage('info', $this->lng->txt('mail_select_' . $this->getObjectType()));
222  $this->showMyObjects();
223  }
224  } elseif ($view === $this->getObjectType() . '_members') {
225  $usr_ids = [];
226  if ($this->http->wrapper()->query()->has('search_members')) {
227  $usr_ids = [
228  $this->http->wrapper()->query()->retrieve(
229  'search_members',
230  $this->refinery->kindlyTo()->int()
231  )
232  ];
233  } elseif ($this->http->wrapper()->post()->has('search_members')) {
234  $usr_ids = $this->http->wrapper()->post()->retrieve(
235  'search_members',
236  $this->refinery->kindlyTo()->listOf($this->refinery->kindlyTo()->int())
237  );
238  }
239 
240  if ($usr_ids !== []) {
241  $this->mailMembers();
242  } else {
243  $this->tpl->setOnScreenMessage('info', $this->lng->txt('mail_select_one_entry'));
244  $this->showMembers();
245  }
246  } else {
247  $this->showMyObjects();
248  }
249  }
250 
251  protected function mailObjects(): void
252  {
253  $members = [];
254  $mail_data = $this->umail->retrieveFromStage();
255 
256  $obj_ids = [];
257  if ($this->http->wrapper()->query()->has('search_' . $this->getObjectType())) {
258  $obj_ids = [
259  $this->http->wrapper()->query()->retrieve(
260  'search_' . $this->getObjectType(),
261  $this->refinery->kindlyTo()->int()
262  )
263  ];
264  } elseif ($this->http->wrapper()->post()->has('search_' . $this->getObjectType())) {
265  $obj_ids = $this->http->wrapper()->post()->retrieve(
266  'search_' . $this->getObjectType(),
267  $this->refinery->kindlyTo()->listOf($this->refinery->kindlyTo()->int())
268  );
269  }
270 
271  foreach ($obj_ids as $obj_id) {
272  $ref_ids = ilObject::_getAllReferences($obj_id);
273  foreach ($ref_ids as $ref_id) {
274  $can_send_mails = ilParticipants::canSendMailToMembers(
275  $ref_id,
276  $this->user->getId(),
278  );
279  if (!$can_send_mails) {
280  continue;
281  }
282 
283  $roles = $this->rbacreview->getAssignableChildRoles($ref_id);
284  foreach ($roles as $role) {
285  if ($this->isLocalRoleTitle($role['title'])) {
286  $recipient = (new ilRoleMailboxAddress($role['obj_id']))->value();
287  if (!$this->umail->existsRecipient($recipient, (string) $mail_data['rcp_to'])) {
288  $members[] = $recipient;
289  }
290  }
291  }
292  }
293  }
294 
295  $mail_data = $members !== [] ? $this->umail->appendSearchResult(array_unique($members), 'to') : $this->umail->retrieveFromStage();
296 
297  $this->umail->persistToStage(
298  (int) $mail_data['user_id'],
299  $mail_data['attachments'],
300  $mail_data['rcp_to'],
301  $mail_data['rcp_cc'],
302  $mail_data['rcp_bcc'],
303  $mail_data['m_subject'],
304  $mail_data['m_message'],
305  $mail_data['use_placeholders'],
306  $mail_data['tpl_ctx_id'],
307  $mail_data['tpl_ctx_params']
308  );
309 
310  $this->ctrl->redirectToURL('ilias.php?baseClass=ilMailGUI&type=search_res');
311  }
312 
313  public function mailMembers(): void
314  {
315  $members = [];
316  $usr_ids = [];
317  if ($this->http->wrapper()->query()->has('search_members')) {
318  $usr_ids = [
319  $this->http->wrapper()->query()->retrieve(
320  'search_members',
321  $this->refinery->kindlyTo()->int()
322  )
323  ];
324  } elseif ($this->http->wrapper()->post()->has('search_members')) {
325  $usr_ids = $this->http->wrapper()->post()->retrieve(
326  'search_members',
327  $this->refinery->kindlyTo()->listOf($this->refinery->kindlyTo()->int())
328  );
329  }
330 
331  $mail_data = $this->umail->retrieveFromStage();
332  foreach ($usr_ids as $usr_id) {
333  $login = ilObjUser::_lookupLogin($usr_id);
334  if (!$this->umail->existsRecipient($login, (string) $mail_data['rcp_to'])) {
335  $members[] = $login;
336  }
337  }
338  $mail_data = $this->umail->appendSearchResult(array_unique($members), 'to');
339 
340  $this->umail->persistToStage(
341  (int) $mail_data['user_id'],
342  $mail_data['attachments'],
343  $mail_data['rcp_to'],
344  $mail_data['rcp_cc'],
345  $mail_data['rcp_bcc'],
346  $mail_data['m_subject'],
347  $mail_data['m_message'],
348  $mail_data['use_placeholders'],
349  $mail_data['tpl_ctx_id'],
350  $mail_data['tpl_ctx_params']
351  );
352 
353  $this->ctrl->redirectToURL('ilias.php?baseClass=ilMailGUI&type=search_res');
354  }
355 
356  public function cancel(): void
357  {
358  $view = '';
359  if ($this->http->wrapper()->query()->has('view')) {
360  $view = $this->http->wrapper()->query()->retrieve('view', $this->refinery->kindlyTo()->string());
361  }
362 
363  if ($view === 'myobjects' && $this->isDefaultRequestContext()) {
364  $this->ctrl->returnToParent($this);
365  } else {
366  $this->showMyObjects();
367  }
368  }
369 
370  public function showMembers(): void
371  {
372  $obj_ids = [];
373  if ($this->http->wrapper()->query()->has('search_' . $this->getObjectType())) {
374  $obj_ids = $this->refinery->kindlyTo()->listOf(
375  $this->refinery->kindlyTo()->int()
376  )->transform(explode(',', (string) $this->http->wrapper()->query()->retrieve(
377  'search_' . $this->getObjectType(),
378  $this->refinery->kindlyTo()->string()
379  )));
380  } elseif ($this->http->wrapper()->post()->has('search_' . $this->getObjectType())) {
381  $obj_ids = $this->http->wrapper()->post()->retrieve(
382  'search_' . $this->getObjectType(),
383  $this->refinery->kindlyTo()->listOf(
384  $this->refinery->kindlyTo()->int()
385  )
386  );
387  } elseif (ilSession::get('search_' . $this->getObjectType())) {
388  $obj_ids = $this->refinery->kindlyTo()->listOf(
389  $this->refinery->kindlyTo()->int()
390  )->transform(explode(',', (string) ilSession::get('search_' . $this->getObjectType())));
391  ilSession::set('search_' . $this->getObjectType(), '');
392  }
393 
394  if ($obj_ids === []) {
395  $this->tpl->setOnScreenMessage('info', $this->lng->txt('mail_select_' . $this->getObjectType()));
396  $this->showMyObjects();
397  return;
398  }
399 
400  foreach ($obj_ids as $obj_id) {
402  $object = ilObjectFactory::getInstanceByObjId($obj_id);
403 
404  $ref_ids = array_keys(ilObject::_getAllReferences($object->getId()));
405  $ref_id = $ref_ids[0];
406  $object->setRefId($ref_id);
407 
408  if (!$this->doesExposeMembers($object)) {
409  $this->tpl->setOnScreenMessage('info', $this->lng->txt('mail_crs_list_members_not_available_for_at_least_one_crs'));
410  $this->showMyObjects();
411  return;
412  }
413  }
414 
415  $this->tpl->setTitle($this->lng->txt('mail_addressbook'));
416 
417  $this->ctrl->setParameter($this, 'view', $this->getObjectType() . '_members');
418  if ($obj_ids !== []) {
419  $this->ctrl->setParameter($this, 'search_' . $this->getObjectType(), implode(',', $obj_ids));
420  }
421  $this->tpl->setVariable('ACTION', $this->ctrl->getFormAction($this));
422  $this->ctrl->clearParameters($this);
423 
424  $this->lng->loadLanguageModule($this->getObjectType());
425 
426  $context = $this->getContext();
427 
429  $this,
430  $this->getObjectType(),
431  $context,
432  $obj_ids
433  );
434  $tableData = [];
435 
436  $searchTpl = new ilTemplate('tpl.mail_search_template.html', true, true, 'components/ILIAS/Contact');
437  foreach ($obj_ids as $obj_id) {
438  $members_obj = ilParticipants::getInstanceByObjId($obj_id);
439  $usr_ids = array_map('intval', ilUtil::_sortIds($members_obj->getParticipants(), 'usr_data', 'lastname', 'usr_id'));
440  foreach ($usr_ids as $usr_id) {
441  $user = new ilObjUser($usr_id);
442  if (!$user->getActive()) {
443  continue;
444  }
445 
446  $fullname = '';
447  if (in_array(ilObjUser::_lookupPref($user->getId(), 'public_profile'), ['g', 'y'])) {
448  $fullname = $user->getLastname() . ', ' . $user->getFirstname();
449  }
450 
451  $rowData = [
452  'members_id' => $user->getId(),
453  'members_login' => $user->getLogin(),
454  'members_name' => $fullname,
455  'members_crs_grp' => $this->cache->lookupTitle((int) $obj_id),
456  'search_' . $this->getObjectType() => $obj_id
457  ];
458 
459  if ('mail' === $context && ilBuddySystem::getInstance()->isEnabled()) {
460  $relation = ilBuddyList::getInstanceByGlobalUser()->getRelationByUserId($user->getId());
461  $state_name = ilStr::convertUpperCamelCaseToUnderscoreCase($relation->getState()->getName());
462  $rowData['status'] = '';
463  if ($user->getId() !== $this->user->getId()) {
464  if ($relation->isOwnedByActor()) {
465  $rowData['status'] = $this->lng->txt('buddy_bs_state_' . $state_name . '_a');
466  } else {
467  $rowData['status'] = $this->lng->txt('buddy_bs_state_' . $state_name . '_p');
468  }
469  }
470  }
471 
472  $tableData[] = $rowData;
473  }
474  }
475  $table->setData($tableData);
476 
477  if ($tableData !== []) {
478  $searchTpl->setVariable('TXT_MARKED_ENTRIES', $this->lng->txt('marked_entries'));
479  }
480 
481  $searchTpl->setVariable('TABLE', $table->getHTML());
482  $this->tpl->setContent($searchTpl->get());
483 
484  if ($this->isDefaultRequestContext()) {
485  $this->tpl->printToStdout();
486  }
487  }
488 
489  abstract protected function doesExposeMembers(ilObject $object): bool;
490 
491  public function showMyObjects(): void
492  {
493  $this->tpl->setTitle($this->lng->txt('mail_addressbook'));
494 
495  $searchTpl = new ilTemplate('tpl.mail_search_template.html', true, true, 'components/ILIAS/Contact');
496 
497  $this->lng->loadLanguageModule('crs');
498 
499  $table = new ilMailSearchObjectsTableGUI(
500  $this,
501  $this->getObjectType(),
502  $this->getContext()
503  );
504  $table->setId('search_' . $this->getObjectType() . '_tbl');
505 
506  $objs_ids = ilParticipants::_getMembershipByType($this->user->getId(), [$this->getObjectType()]);
507  $counter = 0;
508  $tableData = [];
509  if ($objs_ids !== []) {
510  $num_courses_hidden_members = 0;
511  foreach ($objs_ids as $obj_id) {
513  $object = ilObjectFactory::getInstanceByObjId($obj_id);
514 
515  $ref_ids = array_keys(ilObject::_getAllReferences($object->getId()));
516  $ref_id = $ref_ids[0];
517  $object->setRefId($ref_id);
518 
519  $has_untrashed_references = ilObject::_hasUntrashedReference($object->getId());
520  $can_send_mails = ilParticipants::canSendMailToMembers(
521  $object->getRefId(),
522  $this->user->getId(),
524  );
525 
526  $exposes_members = $this->doesExposeMembers($object);
527  ;
528  if ($has_untrashed_references && ($can_send_mails || $exposes_members)) {
529  $participants = ilParticipants::getInstanceByObjId($object->getId());
530  $usr_ids = $participants->getParticipants();
531 
532  foreach ($usr_ids as $key => $usr_id) {
533  $is_active = ilObjUser::_lookupActive($usr_id);
534  if (!$is_active) {
535  unset($usr_ids[$key]);
536  }
537  }
538  $usr_ids = array_values($usr_ids);
539 
540  if (!$exposes_members) {
541  ++$num_courses_hidden_members;
542  }
543 
544  $path_arr = $this->tree->getPathFull($object->getRefId(), $this->tree->getRootId());
545  $path = '';
546  foreach ($path_arr as $data) {
547  if ($path !== '') {
548  $path .= ' -> ';
549  }
550  $path .= $data['title'];
551  }
552 
553  $this->ctrl->setParameter($this, 'search_' . $this->getObjectType(), $object->getId());
554  $this->ctrl->setParameter($this, 'view', 'myobjects');
555  $buttons = [];
556 
557  if ($this->isDefaultRequestContext()) {
558  if ($this->mailing_allowed && $can_send_mails) {
559  $buttons[] = $this->ui_factory
560  ->button()
561  ->shy(
562  $this->lng->txt('mail_members'),
563  $this->ctrl->getLinkTarget($this, 'mail')
564  );
565  }
566  } else {
567  $buttons[] = $this->ui_factory
568  ->button()
569  ->shy(
570  $this->lng->txt('wsp_share_with_members'),
571  $this->ctrl->getLinkTarget($this, 'share')
572  );
573  }
574 
575  if ($exposes_members) {
576  $buttons[] = $this->ui_factory
577  ->button()
578  ->shy(
579  $this->lng->txt('mail_list_members'),
580  $this->ctrl->getLinkTarget($this, 'showMembers')
581  );
582  }
583 
584  $this->ctrl->clearParameters($this);
585 
586  $drop_down = null;
587  if ($buttons !== []) {
588  $drop_down = $this->ui_factory
589  ->dropdown()
590  ->standard($buttons)
591  ->withLabel($this->lng->txt('actions'));
592  }
593 
594  $rowData = [
595  'OBJECT_ID' => $object->getId(),
596  'OBJECT_NAME' => $object->getTitle(),
597  'OBJECT_NO_MEMBERS' => count($usr_ids),
598  'OBJECT_PATH' => $path,
599  'COMMAND_SELECTION_LIST' => $drop_down ? $this->ui_renderer->render($drop_down) : '',
600  'hidden_members' => !$exposes_members,
601  ];
602  $counter++;
603  $tableData[] = $rowData;
604  }
605  }
606 
607  if ($num_courses_hidden_members > 0) {
608  $searchTpl->setCurrentBlock('caption_block');
609  $searchTpl->setVariable('TXT_LIST_MEMBERS_NOT_AVAILABLE', $this->lng->txt('mail_crs_list_members_not_available'));
610  $searchTpl->parseCurrentBlock();
611  }
612  }
613 
614  $searchTpl->setVariable('TXT_MARKED_ENTRIES', $this->lng->txt('marked_entries'));
615 
616  $table->setData($tableData);
617  $searchTpl->setVariable('TABLE', $table->getHTML());
618  $this->tpl->setContent($searchTpl->get());
619 
620  if ($this->isDefaultRequestContext()) {
621  $this->tpl->printToStdout();
622  }
623  }
624 
625  public function executeCommand(): bool
626  {
627  $forward_class = $this->ctrl->getNextClass($this) ?? '';
628  switch (strtolower($forward_class)) {
629  case strtolower(ilBuddySystemGUI::class):
630  if (!ilBuddySystem::getInstance()->isEnabled()) {
631  $this->error->raiseError($this->lng->txt('msg_no_perm_read'), $this->error->MESSAGE);
632  }
633 
634  $this->ctrl->saveParameter($this, 'search_' . $this->getObjectType());
635 
636  $this->ctrl->setReturn($this, 'showMembers');
637  $this->ctrl->forwardCommand(new ilBuddySystemGUI());
638  break;
639 
640  default:
641  if (!($cmd = $this->ctrl->getCmd())) {
642  $cmd = 'showMyObjects';
643  }
644 
645  $this->$cmd();
646  break;
647  }
648 
649  return true;
650  }
651 }
static get(string $a_var)
Class ilBuddySystemGUI.
$context
Definition: webdav.php:31
$relation
static convertUpperCamelCaseToUnderscoreCase(string $value)
Convert a value given in camel case conversion to underscore case conversion (e.g.
Interface Observer Contains several chained tasks and infos about them.
static _getAllReferences(int $id)
get all reference ids for object ID
static getInstanceByObjId(int $a_obj_id)
Get instance by obj type.
static _hasUntrashedReference(int $obj_id)
checks whether an object has at least one reference that is not in trash
static _lookupPref(int $a_usr_id, string $a_keyword)
doesExposeMembers(ilObject $object)
__construct(protected $wsp_access_handler=null, protected ?int $wsp_node_id=null)
setRefId(int $ref_id)
$path
Definition: ltiservices.php:29
ilGlobalTemplateInterface $tpl
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
$ref_id
Definition: ltiauth.php:65
static http()
Fetches the global http state from ILIAS.
global $DIC
Definition: shib_login.php:26
static _sortIds(array $a_ids, string $a_table, string $a_field, string $a_id_name)
Function that sorts ids by a given table field using WHERE IN E.g: __sort(array(6,7),&#39;usr_data&#39;,&#39;lastname&#39;,&#39;usr_id&#39;) => sorts by lastname.
static getInstanceByObjId(?int $obj_id, bool $stop_on_error=true)
get an instance of an Ilias object by object id
static _getMembershipByType(int $a_usr_id, array $a_type, bool $a_only_member_role=false)
get membership by type Get course or group membership
static canSendMailToMembers(int|ilObject $ref_id_or_instance, ?int $usr_id=null, ?int $mail_obj_ref_id=null)
This method was introduced as a band-aid fix for #22764.
static set(string $a_var, $a_val)
Set a value.
static _lookupActive(int $a_usr_id)
getRequestValue(string $key, \ILIAS\Refinery\Transformation $trafo, $default=null)
static getInstanceByGlobalUser(?ilObjUser $user=null)
static _lookupLogin(int $a_user_id)