ILIAS  trunk Revision v11.0_alpha-2638-g80c1d007f79
class.ilObjUserFolderGUI.php
Go to the documentation of this file.
1 <?php
2 
19 declare(strict_types=1);
20 
23 use ILIAS\User\Profile\Prompt\Repository as PromptRepository;
31 
41 {
43 
45  'visible' => 'user_visible_in_profile',
46  'changeable' => 'changeable',
47  'searchable' => 'header_searchable',
48  'required' => 'required_field',
49  'export' => 'export',
50  'course_export' => 'course_export',
51  'group_export' => 'group_export',
52  'prg_export' => 'prg_export',
53  'visib_reg' => 'header_visible_registration',
54  'visib_lua' => 'usr_settings_visib_lua',
55  'changeable_lua' => 'usr_settings_changeable_lua'
56  ];
57 
58  private ilPropertyFormGUI $form;
59  private array $requested_ids; // Missing array type.
60  private string $selected_action;
62  private int $user_owner_id = 0;
63  private int $confirm_change = 0;
64  private ilDBInterface $db;
65  private ilLogger $log;
67  private bool $usrFieldChangeListenersAccepted = false;
68 
73  private DIContainer $dic;
74 
78 
79  public function __construct(
80  $a_data,
81  int $a_id,
82  bool $a_call_by_reference
83  ) {
84  global $DIC;
85  $this->dic = $DIC;
86 
87  $this->event = $DIC['ilAppEventHandler'];
88  $this->filesystem = $DIC->filesystem()->storage();
89  $this->upload = $DIC['upload'];
90  $this->db = $DIC['ilDB'];
91  $this->dic->upload();
92 
93  $this->type = 'usrf';
95  $a_data,
96  $a_id,
97  $a_call_by_reference,
98  false
99  );
100 
101  $this->lng->loadLanguageModule('search');
102  $this->lng->loadLanguageModule('user');
103  $this->lng->loadLanguageModule('tos');
104  $this->ctrl->saveParameter(
105  $this,
106  'letter'
107  );
108 
109  $this->user_request = new UserGUIRequest(
110  $DIC->http(),
111  $DIC->refinery()
112  );
113 
114  $this->selected_action = $this->user_request->getSelectedAction();
115  $this->user_settings_config = new ilUserSettingsConfig();
116 
117  $this->log = ilLoggerFactory::getLogger('user');
118  $this->requested_ids = $this->user_request->getIds();
119  }
120 
121  private function getTranslationForField(
122  string $field_name,
123  array $properties
124  ): string {
125  $translation = (!isset($properties['lang_var']) || $properties['lang_var'] === '')
126  ? $field_name
127  : $properties['lang_var'];
128 
129  if ($field_name === 'country') {
130  $translation = 'country_free_text';
131  }
132  if ($field_name === 'sel_country') {
133  $translation = 'country_selection';
134  }
135 
136  return $this->lng->txt($translation);
137  }
138 
139  public function setUserOwnerId(int $a_id): void
140  {
141  $this->user_owner_id = $a_id;
142  }
143 
144  public function getUserOwnerId(): int
145  {
146  return $this->user_owner_id ?: USER_FOLDER_ID;
147  }
148 
149  public function executeCommand(): void
150  {
151  $next_class = $this->ctrl->getNextClass($this);
152  $cmd = $this->ctrl->getCmd();
153  $this->prepareOutput();
154 
155  switch ($next_class) {
156  case 'ilusertablegui':
157  $u_table = new ilUserTableGUI(
158  $this,
159  'view'
160  );
161  $u_table->initFilter();
162  $this->ctrl->setReturn(
163  $this,
164  'view'
165  );
166  $this->ctrl->forwardCommand($u_table);
167  break;
168 
169  case 'ilpermissiongui':
170  $perm_gui = new ilPermissionGUI($this);
171  $this->ctrl->forwardCommand($perm_gui);
172  break;
173 
174  case 'ilrepositorysearchgui':
175  if (!$this->access->checkRbacOrPositionPermissionAccess(
176  'read',
179  )) {
180  $this->ilias->raiseError(
181  $this->lng->txt('permission_denied'),
182  $this->ilias->error_obj->MESSAGE
183  );
184  }
185 
186  $user_search = new ilRepositorySearchGUI();
187  $user_search->setTitle($this->lng->txt('search_user_extended')); // #17502
188  $user_search->enableSearchableCheck(false);
189  $user_search->setUserLimitations(false);
190  $user_search->setCallback(
191  $this,
192  'searchResultHandler',
193  $this->getUserMultiCommands(true)
194  );
195  $user_search->addUserAccessFilterCallable([$this, 'searchUserAccessFilterCallable']);
196  $this->tabs_gui->setTabActive('search_user_extended');
197  $this->ctrl->setReturn(
198  $this,
199  'view'
200  );
201  $this->ctrl->forwardCommand($user_search);
202  break;
203 
204  case 'ilcustomuserfieldsgui':
205  $this->raiseErrorOnMissingWrite();
206  $this->tabs_gui->setTabActive('settings');
207  $this->setSubTabs('settings');
208  $this->tabs_gui->activateSubTab('user_defined_fields');
209  $cf = new ilCustomUserFieldsGUI(
210  $this->requested_ref_id,
211  $this->user_request->getFieldId()
212  );
213  $this->ctrl->forwardCommand($cf);
214  break;
215 
216  case 'iluserstartingpointgui':
217  $this->raiseErrorOnMissingWrite();
218  $this->tabs_gui->setTabActive('settings');
219  $this->setSubTabs('settings');
220  $this->tabs_gui->activateSubTab('starting_points');
221  $cf = new ilUserStartingPointGUI($this->ref_id);
222  $this->ctrl->forwardCommand($cf);
223  break;
224 
225  case strtolower(SettingsGUI::class):
226  $this->raiseErrorOnMissingWrite();
227  $this->tabs_gui->setTabActive('settings');
228  $this->setSubTabs('settings');
229  $this->tabs_gui->activateSubTab('user_profile_info');
230  $this->ctrl->forwardCommand(
231  new SettingsGUI(
232  $this->ctrl,
233  $this->lng,
234  $this->ui_factory,
235  $this->ui_renderer,
236  $this->tpl,
237  $this->request,
238  $this->refinery,
239  new PromptRepository(
240  $this->db,
241  $this->lng,
242  new ilSetting('user')
243  )
244  )
245  );
246  break;
247 
248  default:
249  if (!$cmd) {
250  $cmd = 'view';
251  }
252  $cmd .= 'Object';
253  $this->$cmd();
254  break;
255  }
256  }
257 
258  public function resetFilterObject(): void
259  {
260  $utab = new ilUserTableGUI(
261  $this,
262  'view'
263  );
264  $utab->resetOffset();
265  $utab->resetFilter();
266  $this->viewObject();
267  }
268 
272  public function addUserObject(): void
273  {
274  $this->ctrl->setParameterByClass(
275  'ilobjusergui',
276  'new_type',
277  'usr'
278  );
279  $this->ctrl->redirectByClass(
280  ['iladministrationgui', 'ilobjusergui'],
281  'create'
282  );
283  }
284 
285  public function applyFilterObject(): void
286  {
287  $utab = new ilUserTableGUI(
288  $this,
289  'view'
290  );
291  $utab->resetOffset();
292  $utab->writeFilterToSession();
293  $this->viewObject();
294  $this->tabs_gui->activateTab('usrf');
295  }
296 
300  public function viewObject(
301  ): void {
302  if ($this->rbac_system->checkAccess('create_usr', $this->object->getRefId())
303  || $this->rbac_system->checkAccess('cat_administrate_users', $this->object->getRefId())) {
304  $this->toolbar->addComponent(
305  $this->ui_factory->link()->standard(
306  $this->lng->txt('usr_add'),
307  $this->ctrl->getLinkTarget($this, 'addUser')
308  )
309  );
310 
311  $this->toolbar->addComponent(
312  $this->ui_factory->link()->standard(
313  $this->lng->txt('import_users'),
314  $this->ctrl->getLinkTarget($this, 'importUserForm')
315  )
316  );
317  }
318 
319  $list_of_users = null;
320  if (!$this->access->checkAccess('read_users', '', USER_FOLDER_ID)
321  && $this->access->checkRbacOrPositionPermissionAccess(
322  'read_users',
325  )) {
326  $list_of_users = $this->access->filterUserIdsByRbacOrPositionOfCurrentUser(
327  'read_users',
331  );
332  }
333 
334  $utab = new ilUserTableGUI(
335  $this,
336  'view',
338  false
339  );
340  $utab->addFilterItemValue(
341  'user_ids',
342  $list_of_users
343  );
344  $utab->getItems();
345 
346  $this->tpl->setContent($utab->getHTML());
347  }
348 
349  protected function addUserAutoCompleteObject(): void
350  {
351  $auto = new ilUserAutoComplete();
352  $auto->addUserAccessFilterCallable(\Closure::fromCallable([$this, 'filterUserIdsByRbacOrPositionOfCurrentUser']));
353  $auto->setSearchFields(['login', 'firstname', 'lastname', 'email', 'second_email']);
354  $auto->enableFieldSearchableCheck(false);
355  $auto->setMoreLinkAvailable(true);
356 
357  if ($this->user_request->getFetchAll()) {
358  $auto->setLimit(ilUserAutoComplete::MAX_ENTRIES);
359  }
360 
361  echo $auto->getList($this->user_request->getTerm());
362  exit();
363  }
364 
368  public function filterUserIdsByRbacOrPositionOfCurrentUser(array $user_ids): array
369  {
370  return $this->access->filterUserIdsByRbacOrPositionOfCurrentUser(
371  'read_users',
374  $user_ids
375  );
376  }
377 
378  public function chooseLetterObject(): void
379  {
380  $this->ctrl->redirect(
381  $this,
382  'view'
383  );
384  }
385 
390  protected function showPossibleSubObjects(): void
391  {
392  $subobj = null;
393 
394  $d = $this->obj_definition->getCreatableSubObjects($this->object->getType());
395 
396  if (!$this->rbac_system->checkAccess(
397  'create_usr',
398  $this->object->getRefId()
399  )) {
400  unset($d['usr']);
401  }
402 
403  if (count($d) > 0) {
404  foreach ($d as $row) {
405  $count = 0;
406  if ($row['max'] > 0) {
407  //how many elements are present?
408  for ($i = 0, $iMax = count($this->data['ctrl']); $i < $iMax; $i++) {
409  if ($this->data['ctrl'][$i]['type'] == $row['name']) {
410  $count++;
411  }
412  }
413  }
414  if ($row['max'] == '' || $count < $row['max']) {
415  $subobj[] = $row['name'];
416  }
417  }
418  }
419 
420  if (is_array($subobj)) {
421  //build form
423  12,
424  'new_type',
425  $subobj
426  );
427  $this->tpl->setCurrentBlock('add_object');
428  $this->tpl->setVariable(
429  'SELECT_OBJTYPE',
430  $opts
431  );
432  $this->tpl->setVariable(
433  'BTN_NAME',
434  'create'
435  );
436  $this->tpl->setVariable(
437  'TXT_ADD',
438  $this->lng->txt('add')
439  );
440  $this->tpl->parseCurrentBlock();
441  }
442  }
443 
444  public function cancelUserFolderActionObject(): void
445  {
446  $this->ctrl->redirect(
447  $this,
448  'view'
449  );
450  }
451 
452  public function cancelSearchActionObject(): void
453  {
454  $this->ctrl->redirectByClass(
455  'ilrepositorysearchgui',
456  'showSearchResults'
457  );
458  }
459 
460  public function confirmactivateObject(): void
461  {
462  if (!$this->checkUserManipulationAccessBool()) {
463  $this->ilias->raiseError(
464  $this->lng->txt('msg_no_perm_write'),
465  $this->ilias->error_obj->WARNING
466  );
467  }
468 
469  // FOR ALL SELECTED OBJECTS
470  foreach ($this->getActionUserIds() as $id) {
472  $id,
473  false
474  );
475  if ($obj instanceof \ilObjUser) {
476  if (!$obj->getActive()) {
477  $obj->setLoginAttempts(0);
478  }
479  $obj->setActive(
480  true,
481  $this->user->getId()
482  );
483  $obj->update();
484  }
485  }
486 
487  $this->tpl->setOnScreenMessage('success', $this->lng->txt('user_activated'), true);
488 
489  if ($this->user_request->getFrSearch()) {
490  $this->ctrl->redirectByClass(
491  'ilRepositorySearchGUI',
492  'show'
493  );
494  } else {
495  $this->ctrl->redirect(
496  $this,
497  'view'
498  );
499  }
500  }
501 
502  public function confirmdeactivateObject(): void
503  {
504  if (!$this->checkUserManipulationAccessBool()) {
505  $this->ilias->raiseError(
506  $this->lng->txt('msg_no_perm_write'),
507  $this->ilias->error_obj->WARNING
508  );
509  }
510  // FOR ALL SELECTED OBJECTS
511  foreach ($this->getActionUserIds() as $id) {
513  $id,
514  false
515  );
516  if ($obj instanceof \ilObjUser) {
517  $obj->setActive(
518  false,
519  $this->user->getId()
520  );
521  $obj->update();
522  }
523  }
524 
525  // Feedback
526  $this->tpl->setOnScreenMessage('success', $this->lng->txt('user_deactivated'), true);
527 
528  if ($this->user_request->getFrSearch()) {
529  $this->ctrl->redirectByClass(
530  'ilRepositorySearchGUI',
531  'show'
532  );
533  } else {
534  $this->ctrl->redirect(
535  $this,
536  'view'
537  );
538  }
539  }
540 
541  protected function confirmaccessFreeObject(): void
542  {
543  if (!$this->checkUserManipulationAccessBool()) {
544  $this->ilias->raiseError(
545  $this->lng->txt('msg_no_perm_write'),
546  $this->ilias->error_obj->WARNING
547  );
548  }
549 
550  foreach ($this->getActionUserIds() as $id) {
552  $id,
553  false
554  );
555  if ($obj instanceof \ilObjUser) {
556  $obj->setTimeLimitUnlimited(true);
557  $obj->setTimeLimitFrom(null);
558  $obj->setTimeLimitUntil(null);
559  $obj->setTimeLimitMessage('');
560  $obj->update();
561  }
562  }
563 
564  // Feedback
565  $this->tpl->setOnScreenMessage('success', $this->lng->txt('access_free_granted'), true);
566 
567  if ($this->user_request->getFrSearch()) {
568  $this->ctrl->redirectByClass(
569  'ilRepositorySearchGUI',
570  'show'
571  );
572  } else {
573  $this->ctrl->redirect(
574  $this,
575  'view'
576  );
577  }
578  }
579 
580  public function setAccessRestrictionObject(
581  ?ilPropertyFormGUI $a_form = null,
582  bool $a_from_search = false
583  ): bool {
584  if (!$a_form) {
585  $a_form = $this->initAccessRestrictionForm($a_from_search);
586  }
587  $this->tpl->setContent($a_form->getHTML());
588 
589  // #10963
590  return true;
591  }
592 
593  protected function initAccessRestrictionForm(
594  bool $a_from_search = false
595  ): ?ilPropertyFormGUI {
596  $user_ids = $this->getActionUserIds();
597  if (!$user_ids) {
598  $this->tpl->setOnScreenMessage('failure', $this->lng->txt('select_one'));
599  $this->viewObject();
600  return null;
601  }
602 
603  $form = new ilPropertyFormGUI();
604  $form->setTitle($this->lng->txt('time_limit_add_time_limit_for_selected'));
605  $form->setFormAction(
606  $this->ctrl->getFormAction(
607  $this,
608  'confirmaccessRestrict'
609  )
610  );
611 
612  $from = new ilDateTimeInputGUI(
613  $this->lng->txt('access_from'),
614  'from'
615  );
616  $from->setShowTime(true);
617  $from->setRequired(true);
618  $form->addItem($from);
619 
620  $to = new ilDateTimeInputGUI(
621  $this->lng->txt('access_until'),
622  'to'
623  );
624  $to->setRequired(true);
625  $to->setShowTime(true);
626  $form->addItem($to);
627 
628  $form->addCommandButton(
629  'confirmaccessRestrict',
630  $this->lng->txt('confirm')
631  );
632  $form->addCommandButton(
633  'view',
634  $this->lng->txt('cancel')
635  );
636 
637  foreach ($user_ids as $user_id) {
638  $ufield = new ilHiddenInputGUI('id[]');
639  $ufield->setValue((string) $user_id);
640  $form->addItem($ufield);
641  }
642 
643  // return to search?
644  if ($a_from_search || $this->user_request->getFrSearch()) {
645  $field = new ilHiddenInputGUI('frsrch');
646  $field->setValue('1');
647  $form->addItem($field);
648  }
649 
650  return $form;
651  }
652 
658  protected function confirmaccessRestrictObject(): bool
659  {
660  $form = $this->initAccessRestrictionForm();
661  if (!$form->checkInput()) {
662  return $this->setAccessRestrictionObject($form);
663  }
664 
665  $timefrom = $form->getItemByPostVar('from')->getDate()->get(IL_CAL_UNIX);
666  $timeuntil = $form->getItemByPostVar('to')->getDate()->get(IL_CAL_UNIX);
667  if ($timeuntil <= $timefrom) {
668  $this->tpl->setOnScreenMessage('failure', $this->lng->txt('time_limit_not_valid'));
669  return $this->setAccessRestrictionObject($form);
670  }
671 
672  if (!$this->checkUserManipulationAccessBool()) {
673  $this->ilias->raiseError(
674  $this->lng->txt('msg_no_perm_write'),
675  $this->ilias->error_obj->WARNING
676  );
677  }
678  foreach ($this->getActionUserIds() as $id) {
680  $id,
681  false
682  );
683  if ($obj instanceof \ilObjUser) {
684  $obj->setTimeLimitUnlimited(false);
685  $obj->setTimeLimitFrom((int) $timefrom);
686  $obj->setTimeLimitUntil((int) $timeuntil);
687  $obj->setTimeLimitMessage('');
688  $obj->update();
689  }
690  }
691  $this->tpl->setOnScreenMessage('success', $this->lng->txt('access_restricted'), true);
692 
693  if ($this->user_request->getFrSearch()) {
694  $this->ctrl->redirectByClass(
695  'ilRepositorySearchGUI',
696  'show'
697  );
698  } else {
699  $this->ctrl->redirect(
700  $this,
701  'view'
702  );
703  }
704  return false;
705  }
706 
707  public function confirmdeleteObject(): void
708  {
709  if (!$this->rbac_system->checkAccess(
710  'delete',
711  $this->object->getRefId()
712  )) {
713  $this->tpl->setOnScreenMessage('failure', $this->lng->txt('msg_no_perm_delete'), true);
714  $this->ctrl->redirect(
715  $this,
716  'view'
717  );
718  }
719 
720  $ids = $this->user_request->getIds();
721  if (in_array(
722  $this->user->getId(),
723  $ids
724  )) {
725  $this->ilias->raiseError(
726  $this->lng->txt('msg_no_delete_yourself'),
727  $this->ilias->error_obj->WARNING
728  );
729  }
730 
731  // FOR ALL SELECTED OBJECTS
732  foreach ($ids as $id) {
733  // instatiate correct object class (usr)
735  $obj->delete();
736  }
737 
738  // Feedback
739  $this->tpl->setOnScreenMessage('success', $this->lng->txt('user_deleted'), true);
740 
741  if ($this->user_request->getFrSearch()) {
742  $this->ctrl->redirectByClass(
743  'ilRepositorySearchGUI',
744  'show'
745  );
746  } else {
747  $this->ctrl->redirect(
748  $this,
749  'view'
750  );
751  }
752  }
753 
758  protected function getActionUserIds(): array
759  {
760  if ($this->getSelectAllPostArray()['select_cmd_all']) {
761  $utab = new ilUserTableGUI(
762  $this,
763  'view',
765  false
766  );
767 
768  if (!$this->access->checkAccess(
769  'read_users',
770  '',
772  ) &&
773  $this->access->checkRbacOrPositionPermissionAccess(
774  'read_users',
777  )) {
779  $filtered_users = $this->access->filterUserIdsByRbacOrPositionOfCurrentUser(
780  'read_users',
783  $users
784  );
785 
786  $utab->addFilterItemValue(
787  'user_ids',
788  $filtered_users
789  );
790  }
791 
792  return $utab->getUserIdsForFilter();
793  } else {
794  return $this->access->filterUserIdsByRbacOrPositionOfCurrentUser(
795  'read_users',
798  $this->requested_ids
799  );
800  }
801  }
802 
803  private function checkUserManipulationAccessBool(): bool
804  {
805  return $this->access->checkRbacOrPositionPermissionAccess(
806  'write',
809  );
810  }
811 
812  public function showActionConfirmation(
813  string $action,
814  bool $a_from_search = false
815  ): bool {
816  $user_ids = $this->getActionUserIds();
817  if (!$user_ids) {
818  $this->tpl->setOnScreenMessage('failure', $this->lng->txt('no_checkbox'));
819  $this->viewObject();
820  return false;
821  }
822 
823  if (!$a_from_search) {
824  $this->tabs_gui->activateTab('obj_usrf');
825  } else {
826  $this->tabs_gui->activateTab('search_user_extended');
827  }
828 
829  if (strcmp(
830  $action,
831  'accessRestrict'
832  ) == 0) {
833  return $this->setAccessRestrictionObject(
834  null,
835  $a_from_search
836  );
837  }
838  if (strcmp(
839  $action,
840  'mail'
841  ) == 0) {
842  $this->mailObject();
843  return false;
844  }
845  if (strcmp($action, 'addToClipboard') === 0) {
846  $this->addToClipboardObject();
847  return false;
848  }
849 
850  unset($this->data);
851 
852  if (!$a_from_search) {
853  $cancel = 'cancelUserFolderAction';
854  } else {
855  $cancel = 'cancelSearchAction';
856  }
857 
858  // display confirmation message
859  $cgui = new ilConfirmationGUI();
860  $cgui->setFormAction($this->ctrl->getFormAction($this));
861  $cgui->setHeaderText($this->lng->txt('info_' . $action . '_sure'));
862  $cgui->setCancel(
863  $this->lng->txt('cancel'),
864  $cancel
865  );
866  $cgui->setConfirm(
867  $this->lng->txt('confirm'),
868  'confirm' . $action
869  );
870 
871  if ($a_from_search) {
872  $cgui->addHiddenItem(
873  'frsrch',
874  '1'
875  );
876  }
877 
878  foreach ($user_ids as $id) {
879  $user = new ilObjUser((int) $id);
880 
881  $login = $user->getLastLogin();
882  if (!$login) {
883  $login = $this->lng->txt('never');
884  } else {
886  new ilDateTime(
887  $login,
889  )
890  );
891  }
892 
893  $caption = $user->getFullname() . ' (' . $user->getLogin() . ')' . ', ' .
894  $user->getEmail() . ' - ' . $this->lng->txt('last_login') . ': ' . $login;
895 
896  $cgui->addItem(
897  'id[]',
898  (string) $id,
899  $caption
900  );
901  }
902 
903  $this->tpl->setContent($cgui->getHTML());
904 
905  return true;
906  }
907 
908  public function deleteUsersObject(): void
909  {
910  if (!$this->access->checkRbacOrPositionPermissionAccess(
911  'delete',
914  )) {
915  $this->ilias->raiseError(
916  $this->lng->txt('permission_denied'),
917  $this->ilias->error_obj->MESSAGE
918  );
919  }
920 
921  if (in_array($this->user->getId(), $this->getActionUserIds())) {
922  $this->tpl->setOnScreenMessage('failure', $this->lng->txt('msg_no_delete_yourself'));
923  $this->viewObject();
924  return;
925  }
926  $this->showActionConfirmation('delete');
927  }
928 
929  public function activateUsersObject(): void
930  {
931  $this->raiseErrorOnMissingWrite();
932  $this->showActionConfirmation('activate');
933  }
934 
935  public function deactivateUsersObject(): void
936  {
937  $this->raiseErrorOnMissingWrite();
938  if (in_array($this->user->getId(), $this->getActionUserIds())) {
939  $this->tpl->setOnScreenMessage('failure', $this->lng->txt('no_deactivate_yourself'));
940  $this->viewObject();
941  return;
942  }
943  $this->showActionConfirmation('deactivate');
944  }
945 
946  public function restrictAccessObject(): void
947  {
948  $this->raiseErrorOnMissingWrite();
949  $this->showActionConfirmation('accessRestrict');
950  }
951 
952  public function freeAccessObject(): void
953  {
954  $this->raiseErrorOnMissingWrite();
955  $this->showActionConfirmation('accessFree');
956  }
957 
958  public function userActionObject(): void
959  {
960  $this->raiseErrorOnMissingWrite();
961  $this->showActionConfirmation($this->user_request->getSelectedAction());
962  }
963 
964  public function importUserFormObject(): void
965  {
966  $this->tabs_gui->clearTargets();
967  $this->tabs_gui->setBackTarget(
968  $this->lng->txt('usrf'),
969  $this->ctrl->getLinkTarget(
970  $this,
971  'view'
972  )
973  );
974  if (
975  !$this->rbac_system->checkAccess('create_usr', $this->object->getRefId())
976  && !$this->access->checkAccess('cat_administrate_users', '', $this->object->getRefId())
977  ) {
978  $this->tpl->setOnScreenMessage('failure', $this->lng->txt('permission_denied'));
979  return;
980  }
981  $this->initUserImportForm();
982  $this->tpl->setContent($this->form->getHTML());
983  }
984 
985  public function initUserImportForm(): void
986  {
987  $this->form = new ilPropertyFormGUI();
988 
989  // Import File
990  $fi = new ilFileInputGUI(
991  $this->lng->txt('import_file'),
992  'importFile'
993  );
994  $fi->setSuffixes(['xml']);
995  $fi->setRequired(true);
996  $this->form->addItem($fi);
997 
998  $this->form->addCommandButton(
999  'importUserRoleAssignment',
1000  $this->lng->txt('import')
1001  );
1002  $this->form->addCommandButton(
1003  'importCancelled',
1004  $this->lng->txt('cancel')
1005  );
1006 
1007  $this->form->setTitle($this->lng->txt('import_users'));
1008  $this->form->setFormAction($this->ctrl->getFormAction($this));
1009  }
1010 
1011  protected function inAdministration(): bool
1012  {
1013  return (strtolower($this->user_request->getBaseClass()) === 'iladministrationgui');
1014  }
1015 
1016  public function importCancelledObject(): void
1017  {
1018  $import_dir = $this->getImportDir();
1019  if ($this->filesystem->hasDir($import_dir)) {
1020  $this->filesystem->deleteDir($import_dir);
1021  }
1022 
1023  if ($this->inAdministration()) {
1024  $this->ctrl->redirect(
1025  $this,
1026  'view'
1027  );
1028  } else {
1029  $this->ctrl->redirectByClass(
1030  'ilobjcategorygui',
1031  'listUsers'
1032  );
1033  }
1034  }
1035 
1036  public function getImportDir(): string
1037  {
1038  // For each user session a different directory must be used to prevent
1039  // that one user session overwrites the import data that another session
1040  // is currently importing.
1041 
1042  $importDir = 'user_import/usr_' . $this->user->getId() . '_' . mb_substr(session_id(), 0, 8);
1043 
1044  return $importDir;
1045  }
1046 
1050  public function importUserRoleAssignmentObject(): void
1051  {
1052  $this->tabs_gui->clearTargets();
1053  $this->tabs_gui->setBackTarget(
1054  $this->lng->txt('usrf'),
1055  $this->ctrl->getLinkTarget(
1056  $this,
1057  'view'
1058  )
1059  );
1060 
1061  $this->initUserImportForm();
1062  if ($this->form->checkInput()) {
1063  $xml_file = $this->handleUploadedFiles();
1064  $xml_file_full_path = ilFileUtils::getDataDir() . '/' . $xml_file;
1065 
1066  list($form, $message) = $this->initUserRoleAssignmentForm($xml_file_full_path);
1067 
1068  $this->tpl->setContent($message . $this->ui_renderer->render($form));
1069  } else {
1070  $this->form->setValuesByPost();
1071  $this->tpl->setContent($this->form->getHTML());
1072  }
1073  }
1074 
1079  private function initUserRoleAssignmentForm(string $xml_file_full_path): array
1080  {
1081  $global_roles_assignment_info = null;
1082  $local_roles_assignment_info = null;
1083 
1084  $import_parser = new ilUserImportParser(
1085  $xml_file_full_path,
1087  );
1088  $import_parser->startParsing();
1089 
1090  $message = $this->verifyXmlData($import_parser);
1091 
1092  $xml_file_name = explode(
1093  '/',
1094  $xml_file_full_path
1095  );
1096  $roles_import_filename = $this->ui_factory->input()->field()
1097  ->text($this->lng->txt('import_file'))
1098  ->withDisabled(true)
1099  ->withValue(end($xml_file_name));
1100 
1101  $roles_import_count = $this->ui_factory->input()->field()
1102  ->numeric($this->lng->txt('num_users'))
1103  ->withDisabled(true)
1104  ->withValue($import_parser->getUserCount());
1105 
1106  $import_parser = new ilUserImportParser(
1107  $xml_file_full_path,
1109  );
1110  $import_parser->startParsing();
1111 
1112  $roles = $import_parser->getCollectedRoles();
1113  $all_gl_roles = $this->rbac_review->getRoleListByObject(ROLE_FOLDER_ID);
1114  $gl_roles = [];
1115  $roles_of_user = $this->rbac_review->assignedRoles($this->user->getId());
1116  foreach ($all_gl_roles as $obj_data) {
1117  // check assignment permission if called from local admin
1118  if ($this->object->getRefId() != USER_FOLDER_ID
1119  && !in_array(SYSTEM_ROLE_ID, $roles_of_user)
1120  && !ilObjRole::_getAssignUsersStatus($obj_data['obj_id'])
1121  ) {
1122  continue;
1123  }
1124  // exclude anonymous role from list
1125  if ($obj_data['obj_id'] != ANONYMOUS_ROLE_ID
1126  && ($obj_data['obj_id'] != SYSTEM_ROLE_ID
1127  || in_array(SYSTEM_ROLE_ID, $roles_of_user))
1128  ) {
1129  $gl_roles[$obj_data['obj_id']] = $obj_data['title'];
1130  }
1131  }
1132 
1133  // global roles
1134  $got_globals = false;
1135  $global_selects = [];
1136  foreach ($roles as $role_id => $role) {
1137  if ($role['type'] === 'Global') {
1138  $select_options = [];
1139  if (!$got_globals) {
1140  $global_roles_assignment_info = $this->ui_factory->input()->field()
1141  ->text($this->lng->txt('roles_of_import_global'))
1142  ->withDisabled(true)
1143  ->withValue($this->lng->txt('assign_global_role'));
1144  } else {
1145  $select_options[] = $this->lng->txt('usrimport_ignore_role');
1146  }
1147 
1148  foreach ($gl_roles as $key => $value) {
1149  $select_options[$role_id . '-' . $key] = $value;
1150  }
1151 
1152  // pre selection for role
1153  $pre_select = array_search(
1154  $role['name'],
1155  $select_options
1156  );
1157  if (!$pre_select) {
1158  switch ($role['name']) {
1159  case 'Administrator': // ILIAS 2/3 Administrator
1160  $pre_select = array_search(
1161  'Administrator',
1162  $select_options
1163  );
1164  break;
1165 
1166  case 'Autor': // ILIAS 2 Author
1167  $pre_select = array_search(
1168  'User',
1169  $select_options
1170  );
1171  break;
1172 
1173  case 'Lerner': // ILIAS 2 Learner
1174  $pre_select = array_search(
1175  'User',
1176  $select_options
1177  );
1178  break;
1179 
1180  case 'Gast': // ILIAS 2 Guest
1181  $pre_select = array_search(
1182  'Guest',
1183  $select_options
1184  );
1185  break;
1186 
1187  case 'User':
1188  $pre_select = array_search(
1189  'User',
1190  $select_options
1191  );
1192  break;
1193  }
1194  }
1195 
1196  $select = $this->ui_factory->input()->field()
1197  ->select(
1198  $role['name'],
1199  $select_options
1200  )
1201  ->withValue($pre_select);
1202 
1203  if (!$got_globals) {
1204  $got_globals = true;
1205  $global_selects[] = $select->withRequired(true);
1206  } else {
1207  $global_selects[] = $select;
1208  }
1209  }
1210  }
1211 
1212  // Check if local roles need to be assigned
1213  $got_locals = false;
1214  foreach ($roles as $role_id => $role) {
1215  if ($role['type'] == 'Local') {
1216  $got_locals = true;
1217  break;
1218  }
1219  }
1220 
1221  if ($got_locals) {
1222  $local_roles_assignment_info = $this->ui_factory->input()->field()
1223  ->text($this->lng->txt('roles_of_import_local'))
1224  ->withDisabled(true)
1225  ->withValue($this->lng->txt('assign_local_role'));
1226 
1227  // get local roles
1228  if ($this->object->getRefId() == USER_FOLDER_ID) {
1229  // The import function has been invoked from the user folder
1230  // object. In this case, we show only matching roles,
1231  // because the user folder object is considered the parent of all
1232  // local roles and may contains thousands of roles on large ILIAS
1233  // installations.
1234  $loc_roles = [];
1235 
1236  $roleMailboxSearch = new ilRoleMailboxSearch(new ilMailRfc822AddressParserFactory());
1237  foreach ($roles as $role_id => $role) {
1238  if ($role['type'] == 'Local') {
1239  $searchName = (strpos($role['name'], '#') === 0) ? $role['name'] : '#' . $role['name'];
1240  $matching_role_ids = $roleMailboxSearch->searchRoleIdsByAddressString($searchName);
1241  foreach ($matching_role_ids as $mid) {
1242  if (!in_array(
1243  $mid,
1244  $loc_roles
1245  )) {
1246  $loc_roles[] = $mid;
1247  }
1248  }
1249  }
1250  }
1251  } else {
1252  // The import function has been invoked from a locally
1253  // administrated category. In this case, we show all roles
1254  // contained in the subtree of the category.
1255  $loc_roles = $this->rbac_review->getAssignableRolesInSubtree($this->object->getRefId());
1256  }
1257  $l_roles = [];
1258 
1259  // create a search array with .
1260  foreach ($loc_roles as $key => $loc_role) {
1261  // fetch context path of role
1262  $rolf = $this->rbac_review->getFoldersAssignedToRole(
1263  $loc_role,
1264  true
1265  );
1266 
1267  // only process role folders that are not set to status 'deleted'
1268  // and for which the user has write permissions.
1269  // We also don't show the roles which are in the ROLE_FOLDER_ID folder.
1270  // (The ROLE_FOLDER_ID folder contains the global roles).
1271  if (
1272  !$this->rbac_review->isDeleted($rolf[0]) &&
1273  $this->rbac_system->checkAccess(
1274  'write',
1275  $rolf[0]
1276  ) &&
1277  $rolf[0] != ROLE_FOLDER_ID
1278  ) {
1279  // A local role is only displayed, if it is contained in the subtree of
1280  // the localy administrated category. If the import function has been
1281  // invoked from the user folder object, we show all local roles, because
1282  // the user folder object is considered the parent of all local roles.
1283  // Thus, if we start from the user folder object, we initialize the
1284  // isInSubtree variable with true. In all other cases it is initialized
1285  // with false, and only set to true if we find the object id of the
1286  // locally administrated category in the tree path to the local role.
1287  $is_in_subtree = $this->object->getRefId() == USER_FOLDER_ID;
1288 
1289  $path_array = [];
1290  if ($this->tree->isInTree($rolf[0])) {
1291  // Create path. Paths which have more than 4 segments
1292  // are truncated in the middle.
1293  $tmpPath = $this->tree->getPathFull($rolf[0]);
1294  $tmpPath[] = $rolf[0];//adds target item to list
1295 
1296  for ($i = 1, $n = count($tmpPath) - 1; $i < $n; $i++) {
1297  if ($i < 3 || $i > $n - 3) {
1298  $path_array[] = $tmpPath[$i]['title'];
1299  } elseif ($i == 3 || $i == $n - 3) {
1300  $path_array[] = '...';
1301  }
1302 
1303  $is_in_subtree |= $tmpPath[$i]['obj_id'] == $this->object->getId();
1304  }
1305  //revert this path for a better readability in dropdowns #18306
1306  $path = implode(
1307  ' < ',
1308  array_reverse($path_array)
1309  );
1310  } else {
1311  $path = '<b>Rolefolder ' . $rolf[0] . ' not found in tree! (Role ' . $loc_role . ')</b>';
1312  }
1313  $roleMailboxAddress = (new \ilRoleMailboxAddress($loc_role))->value();
1314  $l_roles[$loc_role] = $roleMailboxAddress . ', ' . $path;
1315  }
1316  }
1317 
1318  natcasesort($l_roles);
1319  $l_roles['ignore'] = $this->lng->txt('usrimport_ignore_role');
1320 
1321  $roleMailboxSearch = new ilRoleMailboxSearch(new ilMailRfc822AddressParserFactory());
1322  $local_selects = [];
1323  foreach ($roles as $role_id => $role) {
1324  if ($role['type'] == 'Local') {
1325  $searchName = (strpos($role['name'], '#') === 0) ? $role['name'] : '#' . $role['name'];
1326  $matching_role_ids = $roleMailboxSearch->searchRoleIdsByAddressString($searchName);
1327  $pre_select = count($matching_role_ids) == 1 ? $role_id . '-' . $matching_role_ids[0] : 'ignore';
1328 
1329  $selectable_roles = [];
1330  if ($this->object->getRefId() == USER_FOLDER_ID) {
1331  // There are too many roles in a large ILIAS installation
1332  // that's why whe show only a choice with the the option 'ignore',
1333  // and the matching roles.
1334  $selectable_roles['ignore'] = $this->lng->txt('usrimport_ignore_role');
1335  foreach ($matching_role_ids as $id) {
1336  $selectable_roles[$role_id . '-' . $id] = $l_roles[$id];
1337  }
1338  } else {
1339  foreach ($l_roles as $local_role_id => $value) {
1340  if ($local_role_id !== 'ignore') {
1341  $selectable_roles[$role_id . '-' . $local_role_id] = $value;
1342  }
1343  }
1344  }
1345 
1346  if (count($selectable_roles) > 0) {
1347  $select = $this->ui_factory->input()->field()
1348  ->select($role['name'], $selectable_roles)
1349  ->withRequired(true);
1350  if (array_key_exists($pre_select, $selectable_roles)) {
1351  $select = $select->withValue($pre_select);
1352  }
1353  $local_selects[] = $select;
1354  }
1355  }
1356  }
1357  }
1358 
1359  $handlers = [
1360  ilUserImportParser::IL_IGNORE_ON_CONFLICT => $this->lng->txt('ignore_on_conflict'),
1361  ilUserImportParser::IL_UPDATE_ON_CONFLICT => $this->lng->txt('update_on_conflict')
1362  ];
1363 
1364  $conflict_action_select = $this->ui_factory->input()->field()
1365  ->select(
1366  $this->lng->txt('conflict_handling'),
1367  $handlers,
1368  str_replace(
1369  '\n',
1370  '<br>',
1371  $this->lng->txt('usrimport_conflict_handling_info')
1372  )
1373  )
1375  ->withRequired(true);
1376 
1377  // new account mail
1378  $this->lng->loadLanguageModule('mail');
1379  $amail = ilObjUserFolder::_lookupNewAccountMail($this->lng->getDefaultLanguage());
1380  $mail_section = null;
1381  if (trim($amail['body'] ?? '') != '' && trim($amail['subject'] ?? '') != '') {
1382  $send_checkbox = $this->ui_factory->input()->field()->checkbox($this->lng->txt('user_send_new_account_mail'))
1383  ->withValue(true);
1384 
1385  $mail_section = $this->ui_factory->input()->field()->section(
1386  [$send_checkbox],
1387  $this->lng->txt('mail_account_mail')
1388  );
1389  }
1390 
1391  $file_info_section = $this->ui_factory->input()->field()->section(
1392  [
1393  'filename' => $roles_import_filename,
1394  'import_count' => $roles_import_count,
1395  ],
1396  $this->lng->txt('file_info')
1397  );
1398 
1399  $form_action = $this->ctrl->getFormActionByClass(self::class, 'importUsers');
1400 
1401  $form_elements = [
1402  'file_info' => $file_info_section
1403  ];
1404 
1405  if (!empty($global_selects)) {
1406  $global_role_info_section = $this->ui_factory->input()
1407  ->field()
1408  ->section([$global_roles_assignment_info], $this->lng->txt('global_role_assignment'));
1409  $global_role_selection_section = $this->ui_factory->input()->field()->section($global_selects, '');
1410  $form_elements['global_role_info'] = $global_role_info_section;
1411  $form_elements['global_role_selection'] = $global_role_selection_section;
1412  }
1413 
1414  if (!empty($local_selects)) {
1415  $local_role_info_section = $this->ui_factory->input()->field()->section(
1416  [$local_roles_assignment_info],
1417  $this->lng->txt('local_role_assignment')
1418  );
1419  $local_role_selection_section = $this->ui_factory->input()->field()->section(
1420  $local_selects,
1421  ''
1422  );
1423 
1424  $form_elements['local_role_info'] = $local_role_info_section;
1425  $form_elements['local_role_selection'] = $local_role_selection_section;
1426  }
1427 
1428  $form_elements['conflict_action'] = $this->ui_factory->input()->field()->section([$conflict_action_select], '');
1429 
1430  if ($mail_section !== null) {
1431  $form_elements['send_mail'] = $mail_section;
1432  }
1433 
1434  return [$this->ui_factory->input()->container()->form()->standard(
1435  $form_action,
1436  $form_elements
1437  ), $message];
1438  }
1439 
1440  private function handleUploadedFiles(): string
1441  {
1442  $subdir = '';
1443  $xml_file = '';
1444 
1445  $import_dir = $this->getImportDir();
1446 
1447  if (!$this->upload->hasBeenProcessed()) {
1448  $this->upload->process();
1449  }
1450 
1451  // recreate user import directory
1452  if ($this->filesystem->hasDir($import_dir)) {
1453  $this->filesystem->deleteDir($import_dir);
1454  }
1455  $this->filesystem->createDir($import_dir);
1456 
1457  foreach ($this->upload->getResults() as $single_file_upload) {
1458  $file_name = $single_file_upload->getName();
1459  $parts = pathinfo($file_name);
1460 
1461  //check if upload status is ok
1462  if (!$single_file_upload->isOK()) {
1463  $this->filesystem->deleteDir($import_dir);
1464  $this->ilias->raiseError(
1465  $this->lng->txt('no_import_file_found'),
1466  $this->ilias->error_obj->MESSAGE
1467  );
1468  }
1469 
1470  // move uploaded file to user import directory
1471  $this->upload->moveFilesTo(
1472  $import_dir,
1473  \ILIAS\FileUpload\Location::STORAGE
1474  );
1475 
1476  // handle zip file
1477  if ($single_file_upload->getMimeType() == 'application/zip') {
1478  // Workaround: unzip function needs full path to file. Should be replaced once Filesystem has own unzip implementation
1479  $full_path = ilFileUtils::getDataDir() . '/user_import/usr_'
1480  . $this->user->getId() . '_' . session_id() . '/' . $file_name;
1481  $this->dic->legacyArchives()->unzip($full_path);
1482 
1483  $xml_file = null;
1484  $file_list = $this->filesystem->listContents($import_dir);
1485 
1486  foreach ($file_list as $key => $a_file) {
1487  if (substr(
1488  $a_file->getPath(),
1489  -4
1490  ) == '.xml') {
1491  unset($file_list[$key]);
1492  $xml_file = $a_file->getPath();
1493  break;
1494  }
1495  }
1496 
1497  //Removing all files except the one to be imported, to make sure to get the right one in import-function
1498  foreach ($file_list as $a_file) {
1499  $this->filesystem->delete($a_file->getPath());
1500  }
1501 
1502  if (is_null($xml_file)) {
1503  $subdir = basename(
1504  $parts['basename'],
1505  '.' . $parts['extension']
1506  );
1507  $xml_file = $import_dir . '/' . $subdir . '/' . $subdir . '.xml';
1508  }
1509  } // handle xml file
1510  else {
1511  $a = $this->filesystem->listContents($import_dir);
1512  $file = end($a);
1513  $xml_file = $file->getPath();
1514  }
1515 
1516  // check xml file
1517  if (!$this->filesystem->has($xml_file)) {
1518  $this->filesystem->deleteDir($import_dir);
1519  $this->ilias->raiseError(
1520  $this->lng->txt('no_xml_file_found_in_zip')
1521  . ' ' . $subdir . '/' . $subdir . '.xml',
1522  $this->ilias->error_obj->MESSAGE
1523  );
1524  }
1525  }
1526 
1527  return $xml_file;
1528  }
1529 
1530  public function verifyXmlData(ilUserImportParser $import_parser): string
1531  {
1532  $import_dir = $this->getImportDir();
1533  switch ($import_parser->getErrorLevel()) {
1535  return '';
1537  return $import_parser->getProtocolAsHTML($this->lng->txt("verification_warning_log"));
1539  $this->filesystem->deleteDir($import_dir);
1540  $this->tpl->setOnScreenMessage(
1541  'failure',
1542  $this->lng->txt('verification_failed') . $import_parser->getProtocolAsHTML(
1543  $this->lng->txt('verification_failure_log')
1544  ),
1545  true
1546  );
1547  $this->ctrl->redirectByClass(self::class, 'importUserForm');
1548  }
1549  }
1550 
1554  public function importUsersObject(): void
1555  {
1556  $result = [];
1557  $xml_file = '';
1558  $import_dir = $this->getImportDir();
1559 
1560  $file_list = $this->filesystem->listContents($import_dir);
1561 
1562  if (count($file_list) > 1) {
1563  $this->filesystem->deleteDir($import_dir);
1564  $this->tpl->setOnScreenMessage($this->lng->txt('usrimport_wrong_file_count'), true);
1565  $this->redirectAfterImport();
1566  }
1567  $xml_file = $file_list[0]->getPath();
1568 
1569  //Need full path to xml file to initialise form
1570  $xml_path = ilFileUtils::getDataDir() . '/' . $xml_file;
1571 
1572  if (!$this->user_request->isPost()) {
1573  $this->tpl->setOnScreenMessage('failure', $this->lng->txt('usrimport_form_not_evaluabe'), true);
1574  $this->redirectAfterImport();
1575  }
1576 
1577  $form = $this->initUserRoleAssignmentForm($xml_path)[0]->withRequest($this->user_request->getRequest());
1578  $result = $form->getData();
1579 
1580  if ($result === null) {
1581  $this->tpl->setContent($this->ui_renderer->render($form));
1582  return;
1583  }
1584 
1585  $rule = $result['conflict_action'][0] ?? 1;
1586 
1587  //If local roles exist, merge the roles that are to be assigned, otherwise just take the array that has global roles
1588  $local_role_selection = (array) ($result['local_role_selection'] ?? []);
1589  $global_role_selection = (array) ($result['global_role_selection'] ?? []);
1590  $roles = array_merge(
1591  $local_role_selection,
1592  $global_role_selection
1593  );
1594 
1595  $role_assignment = [];
1596  foreach ($roles as $value) {
1597  $keys = explode(
1598  '-',
1599  $value
1600  );
1601  if (count($keys) === 2) {
1602  $role_assignment[$keys[0]] = $keys[1];
1603  }
1604  }
1605 
1606  $import_parser = new ilUserImportParser(
1607  $xml_path,
1609  (int) $rule
1610  );
1611  $import_parser->setFolderId($this->getUserOwnerId());
1612 
1613  // Catch hack attempts
1614  // We check here again, if the role folders are in the tree, and if the
1615  // user has permission on the roles.
1616  if (!empty($role_assignment)) {
1617  $global_roles = $this->rbac_review->getGlobalRoles();
1618  $roles_of_user = $this->rbac_review->assignedRoles($this->user->getId());
1619  foreach ($role_assignment as $role_id_string) {
1620  $role_id = $this->refinery->byTrying([
1621  $this->refinery->kindlyTo()->int(),
1622  $this->refinery->always(null)
1623  ])->transform($role_id_string);
1624  if ($role_id === null) {
1625  continue;
1626  }
1628  $role_id,
1629  $roles_of_user,
1630  $global_roles,
1631  $xml_path
1632  );
1633  }
1634  }
1635 
1636  if (isset($result['send_mail'])) {
1637  $import_parser->setSendMail($result['send_mail'][0]);
1638  }
1639 
1640  $import_parser->setRoleAssignment($role_assignment);
1641  $import_parser->startParsing();
1642 
1643  // purge user import directory
1644  $this->filesystem->deleteDir($import_dir);
1645 
1646  switch ($import_parser->getErrorLevel()) {
1648  $this->tpl->setOnScreenMessage(
1649  'success',
1650  $this->lng->txt('user_imported'),
1651  true
1652  );
1653  break;
1655  $this->tpl->setOnScreenMessage(
1656  'success',
1657  $this->lng->txt('user_imported_with_warnings')
1658  . $import_parser->getProtocolAsHTML(
1659  $this->lng->txt('import_warning_log')
1660  ),
1661  true
1662  );
1663  break;
1665  $this->tpl->setOnScreenMessage('failure', $this->lng->txt('user_import_failed'), true);
1666  $this->redirectAfterImport();
1667  break;
1668  }
1669 
1670  if ($this->inAdministration()) {
1671  $this->ctrl->redirect(
1672  $this,
1673  'view'
1674  );
1675  } else {
1676  $this->ctrl->redirectByClass(
1677  'ilobjcategorygui',
1678  'listUsers'
1679  );
1680  }
1681  }
1682 
1684  int $role_id,
1685  array $roles_of_user,
1686  array $global_roles,
1687  string $import_dir
1688  ): void {
1689  if (in_array(
1690  $role_id,
1691  $global_roles
1692  )) {
1693  if (in_array(
1695  $roles_of_user
1696  )) {
1697  return;
1698  }
1699 
1700  if ($role_id === SYSTEM_ROLE_ID
1701  || $this->object->getRefId() !== USER_FOLDER_ID
1702  && !ilObjRole::_getAssignUsersStatus($role_id)
1703  ) {
1704  $this->filesystem->deleteDir($import_dir);
1705  $this->tpl->setOnScreenMessage(
1706  'failure',
1707  $this->lng->txt('usrimport_with_specified_role_not_permitted'),
1708  true
1709  );
1710  $this->redirectAfterImport();
1711  }
1712  return;
1713  }
1714 
1715  $rolf = $this->rbac_review->getFoldersAssignedToRole(
1716  $role_id,
1717  true
1718  );
1719  if ($this->rbac_review->isDeleted($rolf[0])
1720  || !$this->rbac_system->checkAccess(
1721  'write',
1722  $rolf[0]
1723  )
1724  ) {
1725  $this->filesystem->deleteDir($import_dir);
1726  $this->tpl->setOnScreenMessage(
1727  'failure',
1728  $this->lng->txt('usrimport_with_specified_role_not_permitted'),
1729  true
1730  );
1731  $this->redirectAfterImport();
1732  }
1733  }
1734 
1735  protected function generalSettingsObject(): void
1736  {
1737  $this->raiseErrorOnMissingWrite();
1738  $this->initFormGeneralSettings();
1739 
1741 
1742  $show_blocking_time_in_days = $this->settings->get('loginname_change_blocking_time') / 86400;
1743  $show_blocking_time_in_days = (float) $show_blocking_time_in_days;
1744 
1745  $security = ilSecuritySettings::_getInstance();
1746 
1747  $settings = [
1748  'lua' => $aset->isLocalUserAdministrationEnabled(),
1749  'lrua' => $aset->isUserAccessRestricted(),
1750  'allow_change_loginname' => (bool) $this->settings->get('allow_change_loginname'),
1751  'create_history_loginname' => (bool) $this->settings->get('create_history_loginname'),
1752  'reuse_of_loginnames' => (bool) $this->settings->get('reuse_of_loginnames'),
1753  'loginname_change_blocking_time' => $show_blocking_time_in_days,
1754  'user_reactivate_code' => (int) $this->settings->get('user_reactivate_code'),
1755  'user_own_account' => (int) $this->settings->get('user_delete_own_account'),
1756  'user_own_account_email' => $this->settings->get('user_delete_own_account_email'),
1757  'dpro_withdrawal_usr_deletion' => (bool) $this->settings->get('dpro_withdrawal_usr_deletion'),
1758  'tos_withdrawal_usr_deletion' => (bool) $this->settings->get('tos_withdrawal_usr_deletion'),
1759  'login_max_attempts' => $security->getLoginMaxAttempts() > 0 ? $security->getLoginMaxAttempts() : '',
1760  'ps_prevent_simultaneous_logins' => (int) $security->isPreventionOfSimultaneousLoginsEnabled(),
1761  'password_assistance' => (bool) $this->settings->get('password_assistance'),
1762  'letter_avatars' => (int) $this->settings->get('letter_avatars'),
1763  'password_change_on_first_login_enabled' => $security->isPasswordChangeOnFirstLoginEnabled() ? 1 : 0,
1764  'password_max_age' => $security->getPasswordMaxAge()
1765  ];
1766 
1767  $passwordPolicySettings = $this->getPasswordPolicySettingsMap($security);
1768  $this->form->setValuesByArray(
1769  array_merge(
1770  $settings,
1771  $passwordPolicySettings,
1772  ['pw_policy_hash' => md5(
1773  implode(
1774  '',
1775  $passwordPolicySettings
1776  )
1777  )
1778  ]
1779  )
1780  );
1781 
1782  $this->tpl->setContent($this->form->getHTML());
1783  }
1784 
1785  private function getPasswordPolicySettingsMap(\ilSecuritySettings $security): array // Missing array type.
1786  {
1787  return [
1788  'password_must_not_contain_loginame' => $security->getPasswordMustNotContainLoginnameStatus() ? 1 : 0,
1789  'password_chars_and_numbers_enabled' => $security->isPasswordCharsAndNumbersEnabled() ? 1 : 0,
1790  'password_special_chars_enabled' => $security->isPasswordSpecialCharsEnabled() ? 1 : 0,
1791  'password_min_length' => $security->getPasswordMinLength(),
1792  'password_max_length' => $security->getPasswordMaxLength(),
1793  'password_ucase_chars_num' => $security->getPasswordNumberOfUppercaseChars(),
1794  'password_lowercase_chars_num' => $security->getPasswordNumberOfLowercaseChars(),
1795  ];
1796  }
1797 
1801  public function saveGeneralSettingsObject(): void
1802  {
1803  $this->raiseErrorOnMissingWrite();
1804  $this->initFormGeneralSettings();
1805  if ($this->form->checkInput()) {
1806  $valid = true;
1807  if ($this->form->getInput('allow_change_loginname') === '1' &&
1808  !is_numeric($this->form->getInput('loginname_change_blocking_time'))) {
1809  $valid = false;
1810  $this->form->getItemByPostVar('loginname_change_blocking_time')
1811  ->setAlert($this->lng->txt('loginname_change_blocking_time_invalidity_info'));
1812  }
1813 
1814  $security = ilSecuritySettings::_getInstance();
1815 
1816  // account security settings
1817  $security->setPasswordCharsAndNumbersEnabled(
1818  (bool) $this->form->getInput('password_chars_and_numbers_enabled')
1819  );
1820  $security->setPasswordSpecialCharsEnabled(
1821  (bool) $this->form->getInput('password_special_chars_enabled')
1822  );
1823  $security->setPasswordMinLength(
1824  (int) $this->form->getInput('password_min_length')
1825  );
1826  $security->setPasswordMaxLength(
1827  (int) $this->form->getInput('password_max_length')
1828  );
1829  $security->setPasswordNumberOfUppercaseChars(
1830  (int) $this->form->getInput('password_ucase_chars_num')
1831  );
1832  $security->setPasswordNumberOfLowercaseChars(
1833  (int) $this->form->getInput('password_lowercase_chars_num')
1834  );
1835  $security->setPasswordMaxAge(
1836  (int) $this->form->getInput('password_max_age')
1837  );
1838  $security->setLoginMaxAttempts(
1839  (int) $this->form->getInput('login_max_attempts')
1840  );
1841  $security->setPreventionOfSimultaneousLogins(
1842  (bool) $this->form->getInput('ps_prevent_simultaneous_logins')
1843  );
1844  $security->setPasswordChangeOnFirstLoginEnabled(
1845  (bool) $this->form->getInput('password_change_on_first_login_enabled')
1846  );
1847  $security->setPasswordMustNotContainLoginnameStatus(
1848  (bool) $this->form->getInput('password_must_not_contain_loginame')
1849  );
1850 
1851  if ($security->validate($this->form) !== null) {
1852  $valid = false;
1853  }
1854 
1855  if ($valid) {
1856  $security->save();
1857 
1858  ilUserAccountSettings::getInstance()->enableLocalUserAdministration((bool) $this->form->getInput('lua'));
1859  ilUserAccountSettings::getInstance()->restrictUserAccess((bool) $this->form->getInput('lrua'));
1861 
1862  $this->settings->set(
1863  'allow_change_loginname',
1864  $this->form->getInput('allow_change_loginname')
1865  );
1866  $this->settings->set(
1867  'create_history_loginname',
1868  $this->form->getInput('create_history_loginname')
1869  );
1870  $this->settings->set(
1871  'reuse_of_loginnames',
1872  $this->form->getInput('reuse_of_loginnames')
1873  );
1874  $save_blocking_time_in_seconds = (string) ((int) $this->form->getInput(
1875  'loginname_change_blocking_time'
1876  ) * 86400);
1877  $this->settings->set(
1878  'loginname_change_blocking_time',
1879  $save_blocking_time_in_seconds
1880  );
1881  $this->settings->set(
1882  'user_reactivate_code',
1883  $this->form->getInput('user_reactivate_code')
1884  );
1885 
1886  $this->settings->set(
1887  'user_delete_own_account',
1888  $this->form->getInput('user_own_account')
1889  );
1890  $this->settings->set(
1891  'user_delete_own_account_email',
1892  $this->form->getInput('user_own_account_email')
1893  );
1894  $this->settings->set(
1895  'dpro_withdrawal_usr_deletion',
1896  $this->form->getInput('dpro_withdrawal_usr_deletion') === '1' ? '1' : '0'
1897  );
1898  $this->settings->set(
1899  'tos_withdrawal_usr_deletion',
1900  $this->form->getInput('tos_withdrawal_usr_deletion') === '1' ? '1' : '0'
1901  );
1902 
1903  $this->settings->set(
1904  'password_assistance',
1905  $this->form->getInput('password_assistance')
1906  );
1907 
1908  $this->settings->set(
1909  'letter_avatars',
1910  $this->form->getInput('letter_avatars')
1911  );
1912 
1913  $requestPasswordReset = false;
1914  if ($this->form->getInput('pw_policy_hash')) {
1915  $oldSettingsHash = $this->form->getInput('pw_policy_hash');
1916  $currentSettingsHash = md5(
1917  implode(
1918  '',
1919  $this->getPasswordPolicySettingsMap($security)
1920  )
1921  );
1922  $requestPasswordReset = ($oldSettingsHash !== $currentSettingsHash);
1923  }
1924 
1925  if ($requestPasswordReset) {
1926  $this->ctrl->redirect(
1927  $this,
1928  'askForUserPasswordReset'
1929  );
1930  } else {
1931  $this->tpl->setOnScreenMessage('success', $this->lng->txt('saved_successfully'));
1932  }
1933  } else {
1934  $this->tpl->setOnScreenMessage('failure', $this->lng->txt('form_input_not_valid'));
1935  }
1936  } else {
1937  $this->tpl->setOnScreenMessage('failure', $this->lng->txt('form_input_not_valid'));
1938  }
1939  $this->form->setValuesByPost();
1940  $this->tpl->setContent($this->form->getHTML());
1941  }
1942 
1943  protected function forceUserPasswordResetObject(): void
1944  {
1945  LocalUserPasswordManager::getInstance()->resetLastPasswordChangeForLocalUsers();
1946  $this->lng->loadLanguageModule('ps');
1947 
1948  $this->tpl->setOnScreenMessage('success', $this->lng->txt('ps_passwd_policy_change_force_user_reset_succ'), true);
1949  $this->ctrl->redirect(
1950  $this,
1951  'generalSettings'
1952  );
1953  }
1954 
1955  protected function askForUserPasswordResetObject(): void
1956  {
1957  $this->lng->loadLanguageModule('ps');
1958 
1959  $this->tpl->setOnScreenMessage(
1960  'question',
1961  $this->lng->txt('ps_passwd_policy_changed_force_user_reset')
1962  );
1963 
1964  $this->toolbar->addComponent(
1965  $this->ui_factory->button()->standard(
1966  $this->lng->txt('yes'),
1967  $this->ctrl->getLinkTargetByClass(self::class, 'forceUserPasswordReset')
1968  )
1969  );
1970 
1971  $this->toolbar->addComponent(
1972  $this->ui_factory->button()->standard(
1973  $this->lng->txt('no'),
1974  $this->ctrl->getLinkTargetByClass(self::class, 'generalSettings')
1975  )
1976  );
1977  }
1978 
1979  protected function initFormGeneralSettings(): void
1980  {
1981  $this->setSubTabs('settings');
1982  $this->tabs_gui->setTabActive('settings');
1983  $this->tabs_gui->setSubTabActive('general_settings');
1984 
1985  $this->form = new ilPropertyFormGUI();
1986  $this->form->setFormAction(
1987  $this->ctrl->getFormAction(
1988  $this,
1989  'saveGeneralSettings'
1990  )
1991  );
1992 
1993  $this->form->setTitle($this->lng->txt('general_settings'));
1994 
1995  $lua = new ilCheckboxInputGUI(
1996  $this->lng->txt('enable_local_user_administration'),
1997  'lua'
1998  );
1999  $lua->setInfo($this->lng->txt('enable_local_user_administration_info'));
2000  $lua->setValue('1');
2001  $this->form->addItem($lua);
2002 
2003  $lrua = new ilCheckboxInputGUI(
2004  $this->lng->txt('restrict_user_access'),
2005  'lrua'
2006  );
2007  $lrua->setInfo($this->lng->txt('restrict_user_access_info'));
2008  $lrua->setValue('1');
2009  $this->form->addItem($lrua);
2010 
2011  $code = new ilCheckboxInputGUI(
2012  $this->lng->txt('user_account_code_setting'),
2013  'user_reactivate_code'
2014  );
2015  $code->setInfo($this->lng->txt('user_account_code_setting_info'));
2016  $this->form->addItem($code);
2017 
2018  $own = new ilCheckboxInputGUI(
2019  $this->lng->txt('user_allow_delete_own_account'),
2020  'user_own_account'
2021  );
2022  $this->form->addItem($own);
2023  $own_email = new ilEMailInputGUI(
2024  $this->lng->txt('user_delete_own_account_notification_email'),
2025  'user_own_account_email'
2026  );
2027  $own->addSubItem($own_email);
2028 
2029  $this->lng->loadLanguageModule('tos');
2030  $this->lng->loadLanguageModule('dpro');
2031  $this->form->addItem($this->checkbox('tos_withdrawal_usr_deletion'));
2032  $this->form->addItem($this->checkbox('dpro_withdrawal_usr_deletion'));
2033 
2034  $allow_client_maintenance = $this->settings->get(
2035  'session_allow_client_maintenance',
2037  );
2038 
2039  $this->lng->loadLanguageModule('ps');
2040 
2041  $pass = new ilFormSectionHeaderGUI();
2042  $pass->setTitle($this->lng->txt('ps_password_settings'));
2043  $this->form->addItem($pass);
2044 
2045  $check = new ilCheckboxInputGUI(
2046  $this->lng->txt('ps_password_change_on_first_login_enabled'),
2047  'password_change_on_first_login_enabled'
2048  );
2049  $check->setInfo($this->lng->txt('ps_password_change_on_first_login_enabled_info'));
2050  $this->form->addItem($check);
2051 
2052  $check = new ilCheckboxInputGUI(
2053  $this->lng->txt('ps_password_must_not_contain_loginame'),
2054  'password_must_not_contain_loginame'
2055  );
2056  $check->setInfo($this->lng->txt('ps_password_must_not_contain_loginame_info'));
2057  $this->form->addItem($check);
2058 
2059  $check = new ilCheckboxInputGUI(
2060  $this->lng->txt('ps_password_chars_and_numbers_enabled'),
2061  'password_chars_and_numbers_enabled'
2062  );
2063  //$check->setOptionTitle($this->lng->txt('ps_password_chars_and_numbers_enabled'));
2064  $check->setInfo($this->lng->txt('ps_password_chars_and_numbers_enabled_info'));
2065  $this->form->addItem($check);
2066 
2067  $check = new ilCheckboxInputGUI(
2068  $this->lng->txt('ps_password_special_chars_enabled'),
2069  'password_special_chars_enabled'
2070  );
2071  //$check->setOptionTitle($this->lng->txt('ps_password_special_chars_enabled'));
2072  $check->setInfo($this->lng->txt('ps_password_special_chars_enabled_info'));
2073  $this->form->addItem($check);
2074 
2075  $text = new ilNumberInputGUI(
2076  $this->lng->txt('ps_password_min_length'),
2077  'password_min_length'
2078  );
2079  $text->setInfo($this->lng->txt('ps_password_min_length_info'));
2080  $text->setSize(1);
2081  $text->setMaxLength(2);
2082  $this->form->addItem($text);
2083 
2084  $text = new ilNumberInputGUI(
2085  $this->lng->txt('ps_password_max_length'),
2086  'password_max_length'
2087  );
2088  $text->setInfo($this->lng->txt('ps_password_max_length_info'));
2089  $text->setSize(2);
2090  $text->setMaxLength(3);
2091  $this->form->addItem($text);
2092 
2093  $text = new ilNumberInputGUI(
2094  $this->lng->txt('ps_password_uppercase_chars_num'),
2095  'password_ucase_chars_num'
2096  );
2097  $text->setInfo($this->lng->txt('ps_password_uppercase_chars_num_info'));
2098  $text->setMinValue(0);
2099  $text->setSize(2);
2100  $text->setMaxLength(3);
2101  $this->form->addItem($text);
2102 
2103  $text = new ilNumberInputGUI(
2104  $this->lng->txt('ps_password_lowercase_chars_num'),
2105  'password_lowercase_chars_num'
2106  );
2107  $text->setInfo($this->lng->txt('ps_password_lowercase_chars_num_info'));
2108  $text->setMinValue(0);
2109  $text->setSize(2);
2110  $text->setMaxLength(3);
2111  $this->form->addItem($text);
2112 
2113  $text = new ilNumberInputGUI(
2114  $this->lng->txt('ps_password_max_age'),
2115  'password_max_age'
2116  );
2117  $text->setInfo($this->lng->txt('ps_password_max_age_info'));
2118  $text->setSize(2);
2119  $text->setMaxLength(3);
2120  $this->form->addItem($text);
2121 
2122  // password assistance
2123  $cb = new ilCheckboxInputGUI(
2124  $this->lng->txt('enable_password_assistance'),
2125  'password_assistance'
2126  );
2127  $cb->setInfo($this->lng->txt('password_assistance_info'));
2128  $this->form->addItem($cb);
2129 
2130  $pass = new ilFormSectionHeaderGUI();
2131  $pass->setTitle($this->lng->txt('ps_security_protection'));
2132  $this->form->addItem($pass);
2133 
2134  $text = new ilNumberInputGUI(
2135  $this->lng->txt('ps_login_max_attempts'),
2136  'login_max_attempts'
2137  );
2138  $text->setInfo($this->lng->txt('ps_login_max_attempts_info'));
2139  $text->allowDecimals(false);
2140  $text->setMinValue(1);
2141  $text->setMaxValue(ilSecuritySettings::MAX_LOGIN_ATTEMPTS);
2142  $text->setSize(1);
2143  $text->setMaxLength(2);
2144  $this->form->addItem($text);
2145 
2146  // prevent login from multiple pcs at the same time
2147  $objCb = new ilCheckboxInputGUI(
2148  $this->lng->txt('ps_prevent_simultaneous_logins'),
2149  'ps_prevent_simultaneous_logins'
2150  );
2151  $objCb->setValue('1');
2152  $objCb->setInfo($this->lng->txt('ps_prevent_simultaneous_logins_info'));
2153  $this->form->addItem($objCb);
2154 
2155  $log = new ilFormSectionHeaderGUI();
2156  $log->setTitle($this->lng->txt('loginname_settings'));
2157  $this->form->addItem($log);
2158 
2159  $chbChangeLogin = new ilCheckboxInputGUI(
2160  $this->lng->txt('allow_change_loginname'),
2161  'allow_change_loginname'
2162  );
2163  $chbChangeLogin->setValue('1');
2164  $this->form->addItem($chbChangeLogin);
2165  $chbCreateHistory = new ilCheckboxInputGUI(
2166  $this->lng->txt('history_loginname'),
2167  'create_history_loginname'
2168  );
2169  $chbCreateHistory->setInfo($this->lng->txt('loginname_history_info'));
2170  $chbCreateHistory->setValue('1');
2171 
2172  $chbChangeLogin->addSubItem($chbCreateHistory);
2173  $chbReuseLoginnames = new ilCheckboxInputGUI(
2174  $this->lng->txt('reuse_of_loginnames_contained_in_history'),
2175  'reuse_of_loginnames'
2176  );
2177  $chbReuseLoginnames->setValue('1');
2178  $chbReuseLoginnames->setInfo($this->lng->txt('reuse_of_loginnames_contained_in_history_info'));
2179 
2180  $chbChangeLogin->addSubItem($chbReuseLoginnames);
2181  $chbChangeBlockingTime = new ilNumberInputGUI(
2182  $this->lng->txt('loginname_change_blocking_time'),
2183  'loginname_change_blocking_time'
2184  );
2185  $chbChangeBlockingTime->allowDecimals(true);
2186  $chbChangeBlockingTime->setSuffix($this->lng->txt('days'));
2187  $chbChangeBlockingTime->setInfo($this->lng->txt('loginname_change_blocking_time_info'));
2188  $chbChangeBlockingTime->setSize(10);
2189  $chbChangeBlockingTime->setMaxLength(10);
2190  $chbChangeLogin->addSubItem($chbChangeBlockingTime);
2191 
2192  $la = new ilCheckboxInputGUI(
2193  $this->lng->txt('usr_letter_avatars'),
2194  'letter_avatars'
2195  );
2196  $la->setValue('1');
2197  $la->setInfo($this->lng->txt('usr_letter_avatars_info'));
2198  $this->form->addItem($la);
2199 
2200  $passwordPolicySettingsHash = new \ilHiddenInputGUI('pw_policy_hash');
2201  $this->form->addItem($passwordPolicySettingsHash);
2202 
2203  $this->form->addCommandButton(
2204  'saveGeneralSettings',
2205  $this->lng->txt('save')
2206  );
2207  }
2208 
2217  public function settingsObject(): void
2218  {
2219  $this->raiseErrorOnMissingWrite();
2220 
2221  $this->lng->loadLanguageModule('administration');
2222  $this->lng->loadLanguageModule('mail');
2223  $this->lng->loadLanguageModule('chatroom');
2224  $this->setSubTabs('settings');
2225  $this->tabs_gui->activateTab('settings');
2226  $this->tabs_gui->activateSubTab('standard_fields');
2227 
2228  $tab = new ilUserFieldSettingsTableGUI(
2229  $this,
2230  'settings'
2231  );
2232  if ($this->confirm_change) {
2233  $tab->setConfirmChange();
2234  }
2235  $this->tpl->setContent($tab->getHTML());
2236  }
2237 
2238  public function confirmSavedObject(): void
2239  {
2240  $this->raiseErrorOnMissingWrite();
2241  $this->saveGlobalUserSettingsObject('save');
2242  }
2243 
2244  public function saveGlobalUserSettingsObject(string $action = ''): void
2245  {
2246  $this->raiseErrorOnMissingWrite();
2247 
2248  $checked = $this->user_request->getChecked();
2249  $selected = $this->user_request->getSelect();
2250 
2251  $user_settings_config = $this->user_settings_config;
2252 
2253  // see ilUserFieldSettingsTableGUI
2254  $up = new ilUserProfile();
2255  $up->skipField('username');
2256  $field_properties = $up->getStandardFields();
2257  $profile_fields = array_keys($field_properties);
2258 
2259  $valid = true;
2260  foreach ($profile_fields as $field) {
2261  if (($checked['required_' . $field] ?? false) &&
2262  !(int) ($checked['visib_reg_' . $field] ?? null)
2263  ) {
2264  $valid = false;
2265  break;
2266  }
2267  }
2268 
2269  if (!$valid) {
2270  $this->tpl->setOnScreenMessage('failure', $this->lng->txt('invalid_visible_required_options_selected'));
2271  $this->confirm_change = 1;
2272  $this->settingsObject();
2273  return;
2274  }
2275 
2276  // For the following fields, the required state can not be changed
2277  $fixed_required_fields = [
2278  'firstname' => 1,
2279  'lastname' => 1,
2280  'upload' => 0,
2281  'password' => 0,
2282  'language' => 0,
2283  'skin_style' => 0,
2284  'hide_own_online_status' => 0
2285  ];
2286 
2287  // Reset user confirmation
2288  if ($action == 'save') {
2290  }
2291 
2292  $changed_fields = $this->collectChangedFields();
2293  if ($this->handleChangeListeners($changed_fields, $field_properties)) {
2294  return;
2295  }
2296 
2297  foreach ($profile_fields as $field) {
2298  // Enable disable searchable
2299  if (ilUserSearchOptions::_isSearchable($field)) {
2301  $field,
2302  (bool) ($checked['searchable_' . $field] ?? false)
2303  );
2304  }
2305 
2306  if (!($checked['visible_' . $field] ?? false) && !($field_properties[$field]['visible_hide'] ?? false)) {
2307  $user_settings_config->setVisible(
2308  $field,
2309  false
2310  );
2311  } else {
2312  $user_settings_config->setVisible(
2313  $field,
2314  true
2315  );
2316  }
2317 
2318  if (!($checked['changeable_' . $field] ?? false) &&
2319  !($field_properties[$field]['changeable_hide'] ?? false)) {
2320  $user_settings_config->setChangeable(
2321  $field,
2322  false
2323  );
2324  } else {
2325  $user_settings_config->setChangeable(
2326  $field,
2327  true
2328  );
2329  }
2330 
2331  // registration visible
2332  if (($checked['visib_reg_' . $field] ?? false) && !($field_properties[$field]['visib_reg_hide'] ?? false)) {
2333  $this->settings->set(
2334  'usr_settings_visib_reg_' . $field,
2335  '1'
2336  );
2337  } else {
2338  $this->settings->set(
2339  'usr_settings_visib_reg_' . $field,
2340  '0'
2341  );
2342  }
2343 
2344  if ($checked['visib_lua_' . $field] ?? false) {
2345  $this->settings->set(
2346  'usr_settings_visib_lua_' . $field,
2347  '1'
2348  );
2349  } else {
2350  $this->settings->set(
2351  'usr_settings_visib_lua_' . $field,
2352  '0'
2353  );
2354  }
2355 
2356  if ((int) ($checked['changeable_lua_' . $field] ?? false)) {
2357  $this->settings->set(
2358  'usr_settings_changeable_lua_' . $field,
2359  '1'
2360  );
2361  } else {
2362  $this->settings->set(
2363  'usr_settings_changeable_lua_' . $field,
2364  '0'
2365  );
2366  }
2367 
2368  if (($checked['export_' . $field] ?? false) && !($field_properties[$field]['export_hide'] ?? false)) {
2369  $this->ilias->setSetting(
2370  'usr_settings_export_' . $field,
2371  '1'
2372  );
2373  } else {
2374  $this->ilias->deleteSetting('usr_settings_export_' . $field);
2375  }
2376 
2377  // Course export/visibility
2378  if (($checked['course_export_' . $field] ?? false) && !($field_properties[$field]['course_export_hide'] ?? false)) {
2379  $this->ilias->setSetting(
2380  'usr_settings_course_export_' . $field,
2381  '1'
2382  );
2383  } else {
2384  $this->ilias->deleteSetting('usr_settings_course_export_' . $field);
2385  }
2386 
2387  // Group export/visibility
2388  if (($checked['group_export_' . $field] ?? false) && !($field_properties[$field]['group_export_hide'] ?? false)) {
2389  $this->ilias->setSetting(
2390  'usr_settings_group_export_' . $field,
2391  '1'
2392  );
2393  } else {
2394  $this->ilias->deleteSetting('usr_settings_group_export_' . $field);
2395  }
2396 
2397  if (($checked['prg_export_' . $field] ?? false) && !($field_properties[$field]['prg_export_hide'] ?? false)) {
2398  $this->ilias->setSetting(
2399  'usr_settings_prg_export_' . $field,
2400  '1'
2401  );
2402  } else {
2403  $this->ilias->deleteSetting('usr_settings_prg_export_' . $field);
2404  }
2405 
2406  $is_fixed = array_key_exists(
2407  $field,
2408  $fixed_required_fields
2409  );
2410  if (($is_fixed && $fixed_required_fields[$field]) || (!$is_fixed && ($checked['required_' . $field] ?? false))) {
2411  $this->ilias->setSetting(
2412  'require_' . $field,
2413  '1'
2414  );
2415  } else {
2416  $this->ilias->deleteSetting('require_' . $field);
2417  }
2418  }
2419 
2420  $this->ilias->setSetting(
2421  'session_reminder_lead_time',
2422  $this->user_request->getDefaultSessionReminder()
2423  );
2424 
2425  if (isset($checked['export_preferences']) && $checked['export_preferences'] === 1) {
2426  $this->ilias->setSetting(
2427  'usr_settings_export_preferences',
2428  '1'
2429  );
2430  } else {
2431  $this->ilias->deleteSetting('usr_settings_export_preferences');
2432  }
2433 
2434  $this->ilias->setSetting(
2435  'mail_incoming_mail',
2436  $selected['default_mail_incoming_mail'] ?? '0'
2437  );
2438  $this->ilias->setSetting(
2439  'chat_osc_accept_msg',
2440  $selected['default_chat_osc_accept_msg'] ?? 'n'
2441  );
2442  $this->ilias->setSetting(
2443  'chat_broadcast_typing',
2444  $selected['default_chat_broadcast_typing'] ?? 'n'
2445  );
2446  $this->ilias->setSetting(
2447  'bs_allow_to_contact_me',
2448  $selected['default_bs_allow_to_contact_me'] ?? 'n'
2449  );
2450  $this->ilias->setSetting(
2451  'hide_own_online_status',
2452  $selected['default_hide_own_online_status'] ?? 'n'
2453  );
2454 
2455  if ($this->usrFieldChangeListenersAccepted && count($changed_fields) > 0) {
2456  $this->event->raise(
2457  'components/ILIAS/User',
2458  'onUserFieldAttributesChanged',
2459  $changed_fields
2460  );
2461  }
2462 
2463  $this->tpl->setOnScreenMessage('success', $this->lng->txt('usr_settings_saved'));
2464  $this->settingsObject();
2465  }
2466 
2468  {
2469  $this->usrFieldChangeListenersAccepted = true;
2470  $this->confirmSavedObject();
2471  }
2472 
2477  array $interested_change_listeners
2478  ): void {
2479  $post = $this->user_request->getParsedBody();
2480  $confirmDialog = new ilConfirmationGUI();
2481  $confirmDialog->setHeaderText($this->lng->txt('usr_field_change_components_listening'));
2482  $confirmDialog->setFormAction($this->ctrl->getFormActionByClass(
2483  [self::class],
2484  'settings'
2485  ));
2486  $confirmDialog->setConfirm($this->lng->txt('confirm'), 'confirmUsrFieldChangeListeners');
2487  $confirmDialog->setCancel($this->lng->txt('cancel'), 'settings');
2488 
2489  $tpl = new ilTemplate(
2490  'tpl.usr_field_change_listener_confirm.html',
2491  true,
2492  true,
2493  'components/ILIAS/User'
2494  );
2495 
2496  foreach ($interested_change_listeners as $interested_change_listener) {
2497  $tpl->setVariable('FIELD_NAME', $interested_change_listener->getName());
2498  foreach ($interested_change_listener->getAttributes() as $attribute) {
2499  $tpl->setVariable('ATTRIBUTE_NAME', $attribute->getName());
2500  foreach ($attribute->getComponents() as $component) {
2501  $tpl->setVariable('COMPONENT_NAME', $component->getComponentName());
2502  $tpl->setVariable('DESCRIPTION', $component->getDescription());
2503  $tpl->setCurrentBlock('component');
2504  $tpl->parseCurrentBlock('component');
2505  }
2506  $tpl->setCurrentBlock('attribute');
2507  $tpl->parseCurrentBlock('attribute');
2508  }
2509  $tpl->setCurrentBlock('field');
2510  $tpl->parseCurrentBlock('field');
2511  }
2512 
2513  $confirmDialog->addItem('', '0', $tpl->get());
2514 
2515  foreach ($post['chb'] as $postVar => $value) {
2516  $confirmDialog->addHiddenItem("chb[{$postVar}]", $value);
2517  }
2518  foreach ($post['select'] as $postVar => $value) {
2519  $confirmDialog->addHiddenItem("select[{$postVar}]", $value);
2520  }
2521  foreach ($post['current'] as $postVar => $value) {
2522  $confirmDialog->addHiddenItem("current[{$postVar}]", $value);
2523  }
2524  $this->tpl->setContent($confirmDialog->getHTML());
2525  }
2526 
2532  private function handleChangeListeners(
2533  array $changed_fields,
2534  array $field_properties
2535  ): bool {
2536  if (count($changed_fields) > 0) {
2537  $interested_change_listeners = [];
2538  foreach ($field_properties as $field_name => $properties) {
2539  if (!isset($properties['change_listeners'])) {
2540  continue;
2541  }
2542 
2543  foreach ($properties['change_listeners'] as $change_listener_class_name) {
2547  $listener = new $change_listener_class_name($this->dic);
2548  foreach ($changed_fields as $changed_field) {
2549  $attribute_name = $changed_field->getAttributeName();
2550  $description_for_field = $listener->getDescriptionForField($field_name, $attribute_name);
2551  if ($description_for_field !== null && $description_for_field !== '') {
2552  $interested_change_listener = null;
2553  foreach ($interested_change_listeners as $interested_listener) {
2554  if ($interested_listener->getFieldName() === $field_name) {
2555  $interested_change_listener = $interested_listener;
2556  break;
2557  }
2558  }
2559 
2560  if ($interested_change_listener === null) {
2561  $interested_change_listener = new InterestedUserFieldChangeListener(
2562  $this->lng,
2563  $this->getTranslationForField($field_name, $properties),
2564  $field_name
2565  );
2566  $interested_change_listeners[] = $interested_change_listener;
2567  }
2568 
2569  $interested_attribute = $interested_change_listener->addAttribute($attribute_name);
2570  $interested_attribute->addComponent(
2571  $listener->getComponentName(),
2572  $description_for_field
2573  );
2574  }
2575  }
2576  }
2577  }
2578 
2579  if (!$this->usrFieldChangeListenersAccepted && count($interested_change_listeners) > 0) {
2580  $this->showFieldChangeComponentsListeningConfirmDialog($interested_change_listeners);
2581  return true;
2582  }
2583  }
2584 
2585  return false;
2586  }
2587 
2591  private function collectChangedFields(): array
2592  {
2593  $changed_fields = [];
2594  $post = $this->user_request->getParsedBody();
2595  if (
2596  !isset($post['chb'])
2597  && !is_array($post['chb'])
2598  && !isset($post['current'])
2599  && !is_array($post['current'])
2600  ) {
2601  return $changed_fields;
2602  }
2603 
2604  $old = $post['current'];
2605  $new = $post['chb'];
2606 
2607  foreach ($old as $key => $old_value) {
2608  if (!isset($new[$key])) {
2609  $is_boolean = filter_var($old_value, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE);
2610  $new[$key] = $is_boolean ? '0' : $old_value;
2611  }
2612  }
2613 
2614  $oldToNewDiff = array_diff_assoc($old, $new);
2615 
2616  foreach ($oldToNewDiff as $key => $old_value) {
2617  $changed_fields[$key] = new ChangedUserFieldAttribute($key, $old_value, $new[$key]);
2618  }
2619 
2620  return $changed_fields;
2621  }
2622 
2626  public function __buildUserFilterSelect(): string
2627  {
2628  $action[-1] = $this->lng->txt('all_users');
2629  $action[1] = $this->lng->txt('usr_active_only');
2630  $action[0] = $this->lng->txt('usr_inactive_only');
2631  $action[2] = $this->lng->txt('usr_limited_access_only');
2632  $action[3] = $this->lng->txt('usr_without_courses');
2633  $action[4] = $this->lng->txt('usr_filter_lastlogin');
2634  $action[5] = $this->lng->txt('usr_filter_coursemember');
2635  $action[6] = $this->lng->txt('usr_filter_groupmember');
2636  $action[7] = $this->lng->txt('usr_filter_role');
2637 
2639  ilSession::get('user_filter'),
2640  'user_filter',
2641  $action,
2642  false,
2643  true
2644  );
2645  }
2646 
2651  public function downloadExportFileObject(): void
2652  {
2653  $files = $this->user_request->getFiles();
2654  if (count($files) == 0) {
2655  $this->ilias->raiseError(
2656  $this->lng->txt('no_checkbox'),
2657  $this->ilias->error_obj->MESSAGE
2658  );
2659  }
2660 
2661  if (count($files) > 1) {
2662  $this->ilias->raiseError(
2663  $this->lng->txt('select_max_one_item'),
2664  $this->ilias->error_obj->MESSAGE
2665  );
2666  }
2667 
2668  $file = basename($files[0]);
2669 
2670  $export_dir = $this->object->getExportDirectory();
2672  $export_dir . '/' . $file,
2673  $file
2674  );
2675  }
2676 
2677  public function confirmDeleteExportFileObject(): void
2678  {
2679  $files = $this->user_request->getFiles();
2680  if (count($files) == 0) {
2681  $this->ilias->raiseError(
2682  $this->lng->txt('no_checkbox'),
2683  $this->ilias->error_obj->MESSAGE
2684  );
2685  }
2686 
2687  $cgui = new ilConfirmationGUI();
2688  $cgui->setFormAction($this->ctrl->getFormAction($this));
2689  $cgui->setHeaderText($this->lng->txt('info_delete_sure'));
2690  $cgui->setCancel(
2691  $this->lng->txt('cancel'),
2692  'cancelDeleteExportFile'
2693  );
2694  $cgui->setConfirm(
2695  $this->lng->txt('confirm'),
2696  'deleteExportFile'
2697  );
2698 
2699  // BEGIN TABLE DATA
2700  foreach ($files as $file) {
2701  $cgui->addItem(
2702  'file[]',
2703  $file,
2704  $file,
2705  ilObject::_getIcon($this->object->getId()),
2706  $this->lng->txt('obj_usrf')
2707  );
2708  }
2709 
2710  $this->tpl->setContent($cgui->getHTML());
2711  }
2712 
2713  public function cancelDeleteExportFileObject(): void
2714  {
2715  $this->ctrl->redirectByClass(
2716  'ilobjuserfoldergui',
2717  'export'
2718  );
2719  }
2720 
2721  public function deleteExportFileObject(): void
2722  {
2723  $this->raiseErrorOnMissingWrite();
2724  $files = $this->user_request->getFiles();
2725  $export_dir = $this->object->getExportDirectory();
2726  foreach ($files as $file) {
2727  $file = basename($file);
2728 
2729  $exp_file = $export_dir . '/' . $file;
2730  if (is_file($exp_file)) {
2731  unlink($exp_file);
2732  }
2733  }
2734  $this->ctrl->redirectByClass(
2735  'ilobjuserfoldergui',
2736  'export'
2737  );
2738  }
2739 
2744  protected function performExportObject(): void
2745  {
2746  $this->checkPermission('write,read_users');
2747 
2748  $this->object->buildExportFile($this->user_request->getExportType());
2749  $this->ctrl->redirect(
2750  $this,
2751  'export'
2752  );
2753  }
2754 
2755  public function exportObject(): void
2756  {
2757  $this->checkPermission('write,read_users');
2758 
2759  $export_types = [
2760  'userfolder_export_excel_x86',
2761  'userfolder_export_csv',
2762  'userfolder_export_xml'
2763  ];
2764  $options = [];
2765  foreach ($export_types as $type) {
2766  $this->ctrl->setParameterByClass(self::class, 'export_type', $type);
2767  $options[] = $this->ui_factory->button()->shy(
2768  $this->lng->txt($type),
2769  $this->ctrl->getLinkTargetByClass(self::class, 'performExport')
2770  );
2771  }
2772  $type_selection = $this->ui_factory->dropdown()->standard($options)
2773  ->withLabel($this->lng->txt('create_export_file'));
2774 
2775  $this->toolbar->addComponent(
2776  $type_selection,
2777  true
2778  );
2779 
2780  $table = new \ilUserExportFileTableGUI(
2781  $this,
2782  'export'
2783  );
2784  $table->init();
2785  $table->parse($this->object->getExportFiles());
2786 
2787  $this->tpl->setContent($table->getHTML());
2788  }
2789 
2791  {
2792  $this->lng->loadLanguageModule('meta');
2793  $this->lng->loadLanguageModule('mail');
2794 
2795  $form = new ilPropertyFormGUI();
2796  $form->setFormAction($this->ctrl->getFormAction($this));
2797 
2798  $form->setTitleIcon(ilUtil::getImagePath('standard/icon_mail.svg'));
2799  $form->setTitle($this->lng->txt('user_new_account_mail'));
2800  $form->setDescription($this->lng->txt('user_new_account_mail_desc'));
2801 
2802  $langs = $this->lng->getInstalledLanguages();
2803  foreach ($langs as $lang_key) {
2804  $amail = ilObjUserFolder::_lookupNewAccountMail($lang_key);
2805 
2806  $title = $this->lng->txt('meta_l_' . $lang_key);
2807  if ($lang_key == $this->lng->getDefaultLanguage()) {
2808  $title .= ' (' . $this->lng->txt('default') . ')';
2809  }
2810 
2811  $header = new ilFormSectionHeaderGUI();
2812  $header->setTitle($title);
2813  $form->addItem($header);
2814 
2815  $subj = new ilTextInputGUI(
2816  $this->lng->txt('subject'),
2817  'subject_' . $lang_key
2818  );
2819  $subj->setValue($amail['subject'] ?? '');
2820  $form->addItem($subj);
2821 
2822  $salg = new ilTextInputGUI(
2823  $this->lng->txt('mail_salutation_general'),
2824  'sal_g_' . $lang_key
2825  );
2826  $salg->setValue($amail['sal_g'] ?? '');
2827  $form->addItem($salg);
2828 
2829  $salf = new ilTextInputGUI(
2830  $this->lng->txt('mail_salutation_female'),
2831  'sal_f_' . $lang_key
2832  );
2833  $salf->setValue($amail['sal_f'] ?? '');
2834  $form->addItem($salf);
2835 
2836  $salm = new ilTextInputGUI(
2837  $this->lng->txt('mail_salutation_male'),
2838  'sal_m_' . $lang_key
2839  );
2840  $salm->setValue($amail['sal_m'] ?? '');
2841  $form->addItem($salm);
2842 
2843  $body = new ilTextAreaInputGUI(
2844  $this->lng->txt('message_content'),
2845  'body_' . $lang_key
2846  );
2847  $body->setValue($amail['body'] ?? '');
2848  $body->setRows(10);
2849  $body->setCols(100);
2850  $form->addItem($body);
2851 
2852  $att = new ilFileInputGUI(
2853  $this->lng->txt('attachment'),
2854  'att_' . $lang_key
2855  );
2856  $att->setAllowDeletion(true);
2857  if ($amail['att_file'] ?? false) {
2858  $att->setValue($amail['att_file']);
2859  }
2860  $form->addItem($att);
2861  }
2862 
2863  $form->addCommandButton(
2864  'saveNewAccountMail',
2865  $this->lng->txt('save')
2866  );
2867  $form->addCommandButton(
2868  'cancelNewAccountMail',
2869  $this->lng->txt('cancel')
2870  );
2871 
2872  return $form;
2873  }
2874 
2875  public function newAccountMailObject(?ilPropertyFormGUI $form = null): void
2876  {
2877  $this->raiseErrorOnMissingWrite();
2878  $this->setSubTabs('settings');
2879  $this->tabs_gui->setTabActive('settings');
2880  $this->tabs_gui->setSubTabActive('user_new_account_mail');
2881 
2882  if ($form === null) {
2883  $form = $this->initNewAccountMailForm();
2884  }
2885 
2886  $ftpl = new ilTemplate(
2887  'tpl.usrf_new_account_mail.html',
2888  true,
2889  true,
2890  'components/ILIAS/User'
2891  );
2892  $ftpl->setVariable(
2893  'FORM',
2894  $form->getHTML()
2895  );
2896 
2897  // placeholder help text
2898  $ftpl->setVariable(
2899  'TXT_USE_PLACEHOLDERS',
2900  $this->lng->txt('mail_nacc_use_placeholder')
2901  );
2902  $ftpl->setVariable(
2903  'TXT_MAIL_SALUTATION',
2904  $this->lng->txt('mail_nacc_salutation')
2905  );
2906  $ftpl->setVariable(
2907  'TXT_FIRST_NAME',
2908  $this->lng->txt('firstname')
2909  );
2910  $ftpl->setVariable(
2911  'TXT_LAST_NAME',
2912  $this->lng->txt('lastname')
2913  );
2914  $ftpl->setVariable(
2915  'TXT_EMAIL',
2916  $this->lng->txt('email')
2917  );
2918  $ftpl->setVariable(
2919  'TXT_LOGIN',
2920  $this->lng->txt('mail_nacc_login')
2921  );
2922  $ftpl->setVariable(
2923  'TXT_PASSWORD',
2924  $this->lng->txt('password')
2925  );
2926  $ftpl->setVariable(
2927  'TXT_PASSWORD_BLOCK',
2928  $this->lng->txt('mail_nacc_pw_block')
2929  );
2930  $ftpl->setVariable(
2931  'TXT_NOPASSWORD_BLOCK',
2932  $this->lng->txt('mail_nacc_no_pw_block')
2933  );
2934  $ftpl->setVariable(
2935  'TXT_ADMIN_MAIL',
2936  $this->lng->txt('mail_nacc_admin_mail')
2937  );
2938  $ftpl->setVariable(
2939  'TXT_ILIAS_URL',
2940  $this->lng->txt('mail_nacc_ilias_url')
2941  );
2942  $ftpl->setVariable(
2943  'TXT_INSTALLATION_NAME',
2944  $this->lng->txt('mail_nacc_installation_name')
2945  );
2946  $ftpl->setVariable(
2947  'TXT_TARGET',
2948  $this->lng->txt('mail_nacc_target')
2949  );
2950  $ftpl->setVariable(
2951  'TXT_TARGET_TITLE',
2952  $this->lng->txt('mail_nacc_target_title')
2953  );
2954  $ftpl->setVariable(
2955  'TXT_TARGET_TYPE',
2956  $this->lng->txt('mail_nacc_target_type')
2957  );
2958  $ftpl->setVariable(
2959  'TXT_TARGET_BLOCK',
2960  $this->lng->txt('mail_nacc_target_block')
2961  );
2962  $ftpl->setVariable(
2963  'TXT_IF_TIMELIMIT',
2964  $this->lng->txt('mail_nacc_if_timelimit')
2965  );
2966  $ftpl->setVariable(
2967  'TXT_TIMELIMIT',
2968  $this->lng->txt('mail_nacc_timelimit')
2969  );
2970 
2971  $this->tpl->setContent($ftpl->get());
2972  }
2973 
2974  public function cancelNewAccountMailObject(): void
2975  {
2976  $this->ctrl->redirect(
2977  $this,
2978  'settings'
2979  );
2980  }
2981 
2982  public function saveNewAccountMailObject(): void
2983  {
2984  $this->raiseErrorOnMissingWrite();
2985  $form = $this->initNewAccountMailForm();
2986 
2987  // If all forms in ILIAS use the UI/KS forms (here and in Services/Mail), we should move this to a proper constraint/trafo
2988  $is_valid_template_syntax = $this->dic->refinery()->custom()->constraint(function ($value): bool {
2989  try {
2990  $this->dic->mail()->mustacheFactory()->getBasicEngine()->render((string) $value, []);
2991  return true;
2992  } catch (Exception) {
2993  return false;
2994  }
2995  }, $this->dic->language()->txt('mail_template_invalid_tpl_syntax'));
2996 
2997  $valid_templates = true;
2998  $langs = $this->lng->getInstalledLanguages();
2999  foreach ($langs as $lang_key) {
3000  $subject = $this->user_request->getMailSubject($lang_key);
3001  try {
3002  $is_valid_template_syntax->check($subject);
3003  } catch (Exception) {
3004  $form->getItemByPostVar('subject_' . $lang_key)->setAlert(
3005  $is_valid_template_syntax->problemWith($subject)
3006  );
3007  $valid_templates = false;
3008  }
3009 
3010  $body = $this->user_request->getMailBody($lang_key);
3011  try {
3012  $is_valid_template_syntax->check($body);
3013  } catch (Exception) {
3014  $form->getItemByPostVar('body_' . $lang_key)->setAlert(
3015  $is_valid_template_syntax->problemWith($body)
3016  );
3017  $valid_templates = false;
3018  }
3019  }
3020  if (!$valid_templates) {
3021  $this->tpl->setOnScreenMessage('failure', $this->lng->txt('form_input_not_valid'));
3022  $this->newAccountMailObject($form);
3023  return;
3024  }
3025 
3026  foreach ($langs as $lang_key) {
3028  $lang_key,
3029  $this->user_request->getMailSubject($lang_key),
3030  $this->user_request->getMailSalutation('g', $lang_key),
3031  $this->user_request->getMailSalutation('f', $lang_key),
3032  $this->user_request->getMailSalutation('m', $lang_key),
3033  $this->user_request->getMailBody($lang_key)
3034  );
3035 
3036  if ($_FILES['att_' . $lang_key]['tmp_name']) {
3038  $lang_key,
3039  $_FILES['att_' . $lang_key]['tmp_name'],
3040  $_FILES['att_' . $lang_key]['name']
3041  );
3042  }
3043 
3044  if ($this->user_request->getMailAttDelete($lang_key)) {
3046  }
3047  }
3048 
3049  $this->tpl->setOnScreenMessage('success', $this->lng->txt('msg_obj_modified'), true);
3050  $this->ctrl->redirect(
3051  $this,
3052  'newAccountMail'
3053  );
3054  }
3055 
3056  public function getAdminTabs(): void
3057  {
3058  $this->getTabs();
3059  }
3060 
3061  protected function getTabs(): void
3062  {
3063  if ($this->access->checkRbacOrPositionPermissionAccess(
3064  'visible,read',
3066  $this->object->getRefId()
3067  )) {
3068  $this->tabs_gui->addTarget(
3069  'usrf',
3070  $this->ctrl->getLinkTarget(
3071  $this,
3072  'view'
3073  ),
3074  ['view', 'delete', 'resetFilter', 'userAction', ''],
3075  '',
3076  ''
3077  );
3078  }
3079 
3080  if ($this->access->checkRbacOrPositionPermissionAccess(
3081  'read',
3084  )) {
3085  $this->tabs_gui->addTarget(
3086  'search_user_extended',
3087  $this->ctrl->getLinkTargetByClass(
3088  'ilRepositorySearchGUI',
3089  ''
3090  ),
3091  [],
3092  'ilrepositorysearchgui',
3093  ''
3094  );
3095  }
3096 
3097  if ($this->rbac_system->checkAccess(
3098  'write',
3099  $this->object->getRefId()
3100  )) {
3101  $this->tabs_gui->addTarget(
3102  'settings',
3103  $this->ctrl->getLinkTarget(
3104  $this,
3105  'generalSettings'
3106  ),
3107  [
3108  'askForUserPasswordReset',
3109  'forceUserPasswordReset',
3110  'settings',
3111  'generalSettings',
3112  'listUserDefinedField',
3113  'newAccountMail'
3114  ]
3115  );
3116 
3117  $this->tabs_gui->addTarget(
3118  'export',
3119  $this->ctrl->getLinkTarget(
3120  $this,
3121  'export'
3122  ),
3123  'export',
3124  '',
3125  ''
3126  );
3127  }
3128 
3129  if ($this->rbac_system->checkAccess(
3130  'edit_permission',
3131  $this->object->getRefId()
3132  )) {
3133  $this->tabs_gui->addTarget(
3134  'perm_settings',
3135  $this->ctrl->getLinkTargetByClass(
3136  [get_class($this), 'ilpermissiongui'],
3137  'perm'
3138  ),
3139  ['perm', 'info', 'owner'],
3140  'ilpermissiongui'
3141  );
3142  }
3143  }
3144 
3145  public function setSubTabs(string $a_tab): void
3146  {
3147  switch ($a_tab) {
3148  case 'settings':
3149  $this->tabs_gui->addSubTabTarget(
3150  'general_settings',
3151  $this->ctrl->getLinkTarget(
3152  $this,
3153  'generalSettings'
3154  ),
3155  'generalSettings',
3156  get_class($this)
3157  );
3158  $this->tabs_gui->addSubTabTarget(
3159  'standard_fields',
3160  $this->ctrl->getLinkTarget(
3161  $this,
3162  'settings'
3163  ),
3164  ['settings', 'saveGlobalUserSettings'],
3165  get_class($this)
3166  );
3167  $this->tabs_gui->addSubTabTarget(
3168  'user_defined_fields',
3169  $this->ctrl->getLinkTargetByClass(
3170  'ilcustomuserfieldsgui',
3171  'listUserDefinedFields'
3172  ),
3173  'listUserDefinedFields',
3174  get_class($this)
3175  );
3176  $this->tabs_gui->addSubTabTarget(
3177  'user_new_account_mail',
3178  $this->ctrl->getLinkTarget(
3179  $this,
3180  'newAccountMail'
3181  ),
3182  'newAccountMail',
3183  get_class($this)
3184  );
3185 
3186  $this->tabs_gui->addSubTabTarget(
3187  'starting_points',
3188  $this->ctrl->getLinkTargetByClass(
3189  'iluserstartingpointgui',
3190  'startingPoints'
3191  ),
3192  'startingPoints',
3193  get_class($this)
3194  );
3195 
3196  $this->tabs_gui->addSubTabTarget(
3197  'user_profile_info',
3198  $this->ctrl->getLinkTargetByClass(
3199  SettingsGUI::class,
3200  ''
3201  ),
3202  '',
3203  SettingsGUI::class
3204  );
3205 
3206  break;
3207  }
3208  }
3209 
3210  public static function _goto(string $a_user): void
3211  {
3212  global $DIC;
3213 
3214  $a_user = (int) $a_user;
3215  $main_tpl = $DIC->ui()->mainTemplate();
3216 
3217  $ilAccess = $DIC['ilAccess'];
3218  $ilErr = $DIC['ilErr'];
3219  $lng = $DIC['lng'];
3220  $ctrl = $DIC['ilCtrl'];
3221 
3222  $a_target = USER_FOLDER_ID;
3223 
3224  if ($ilAccess->checkAccess(
3225  'read',
3226  '',
3227  $a_target
3228  )) {
3229  $ctrl->redirectToURL('ilias.php?baseClass=ilAdministrationGUI&ref_id=' . $a_target . '&jmpToUser=' . $a_user);
3230  exit;
3231  } else {
3232  if ($ilAccess->checkAccess(
3233  'read',
3234  '',
3236  )) {
3237  $main_tpl->setOnScreenMessage('failure', sprintf(
3238  $lng->txt('msg_no_perm_read_item'),
3240  ), true);
3242  }
3243  }
3244  $ilErr->raiseError(
3245  $lng->txt('msg_no_perm_read'),
3246  $ilErr->FATAL
3247  );
3248  }
3249 
3253  public function jumpToUserObject(): void
3254  {
3255  $jump_to_user = $this->user_request->getJumpToUser();
3256  if (ilObject::_lookupType($jump_to_user) == 'usr') {
3257  $this->ctrl->setParameterByClass(
3258  'ilobjusergui',
3259  'obj_id',
3260  $jump_to_user
3261  );
3262  $this->ctrl->redirectByClass(
3263  'ilobjusergui',
3264  'view'
3265  );
3266  }
3267  }
3268 
3269  public function searchUserAccessFilterCallable(array $a_user_ids): array // Missing array type.
3270  {
3271  if (!$this->checkPermissionBool('read_users')) {
3272  $a_user_ids = $this->access->filterUserIdsByPositionOfCurrentUser(
3275  $a_user_ids
3276  );
3277  }
3278 
3279  return $a_user_ids;
3280  }
3281 
3285  public function searchResultHandler(
3286  array $a_usr_ids,
3287  string $a_cmd
3288  ): bool {
3289  if (!count($a_usr_ids)) {
3290  $this->tpl->setOnScreenMessage('failure', $this->lng->txt('select_one'));
3291  return false;
3292  }
3293 
3294  $this->requested_ids = $a_usr_ids;
3295 
3296  // no real confirmation here
3297  if (stripos($a_cmd, 'export') !== false) {
3298  $cmd = $a_cmd . 'Object';
3299  return $this->$cmd();
3300  }
3301 
3302  return $this->showActionConfirmation(
3303  $a_cmd,
3304  true
3305  );
3306  }
3307 
3308  public function getUserMultiCommands(bool $a_search_form = false): array // Missing array type.
3309  {
3310  $cmds = [];
3311  // see searchResultHandler()
3312  if ($a_search_form) {
3313  if ($this->rbac_system->checkAccess('write', $this->object->getRefId())) {
3314  $cmds = [
3315  'activate' => $this->lng->txt('activate'),
3316  'deactivate' => $this->lng->txt('deactivate'),
3317  'accessRestrict' => $this->lng->txt('accessRestrict'),
3318  'accessFree' => $this->lng->txt('accessFree')
3319  ];
3320  }
3321 
3322  if ($this->rbac_system->checkAccess('delete', $this->object->getRefId())) {
3323  $cmds['delete'] = $this->lng->txt('delete');
3324  }
3325  } else {
3326  if ($this->rbac_system->checkAccess('write', $this->object->getRefId())) {
3327  $cmds = [
3328  'activateUsers' => $this->lng->txt('activate'),
3329  'deactivateUsers' => $this->lng->txt('deactivate'),
3330  'restrictAccess' => $this->lng->txt('accessRestrict'),
3331  'freeAccess' => $this->lng->txt('accessFree')
3332  ];
3333  }
3334 
3335  if ($this->rbac_system->checkAccess('delete', $this->object->getRefId())) {
3336  $cmds['deleteUsers'] = $this->lng->txt('delete');
3337  }
3338  }
3339 
3340  if ($this->rbac_system->checkAccess('write', $this->object->getRefId())) {
3341  $export_types = [
3342  'userfolder_export_excel_x86',
3343  'userfolder_export_csv',
3344  'userfolder_export_xml'
3345  ];
3346  foreach ($export_types as $type) {
3347  $cmd = explode(
3348  '_',
3349  $type
3350  );
3351  $cmd = array_pop($cmd);
3352  $cmds['usrExport' . ucfirst($cmd)] = $this->lng->txt('export') . ' - ' .
3353  $this->lng->txt($type);
3354  }
3355  }
3356 
3357  // check if current user may send mails
3358  $mail = new ilMail($this->user->getId());
3359  if ($this->rbac_system->checkAccess(
3360  'internal_mail',
3361  $mail->getMailObjectReferenceId()
3362  )) {
3363  $cmds['mail'] = $this->lng->txt('send_mail');
3364  }
3365 
3366  $cmds['addToClipboard'] = $this->lng->txt('clipboard_add_btn');
3367 
3368  return $cmds;
3369  }
3370 
3371  protected function usrExportX86Object(): void
3372  {
3373  $user_ids = $this->getActionUserIds();
3374  if (!$user_ids) {
3375  $this->tpl->setOnScreenMessage('failure', $this->lng->txt('select_one'), true);
3376  $this->ctrl->redirect(
3377  $this,
3378  'view'
3379  );
3380  }
3381 
3382  if ($this->checkPermissionBool('write,read_users')) {
3383  $this->object->buildExportFile(
3385  $user_ids
3386  );
3387  $this->ctrl->redirectByClass(
3388  'ilobjuserfoldergui',
3389  'export'
3390  );
3391  } elseif ($this->checkUserManipulationAccessBool()) {
3392  $fullname = $this->object->buildExportFile(
3394  $user_ids,
3395  true
3396  );
3398  $fullname . '.xlsx',
3399  $this->object->getExportFilename(ilObjUserFolder::FILE_TYPE_EXCEL) . '.xlsx',
3400  '',
3401  false,
3402  true
3403  );
3404  }
3405  }
3406 
3407  protected function usrExportCsvObject(): void
3408  {
3409  $user_ids = $this->getActionUserIds();
3410  if (!$user_ids) {
3411  $this->tpl->setOnScreenMessage('failure', $this->lng->txt('select_one'), true);
3412  $this->ctrl->redirect(
3413  $this,
3414  'view'
3415  );
3416  }
3417 
3418  if ($this->checkPermissionBool('write,read_users')) {
3419  $this->object->buildExportFile(
3421  $user_ids
3422  );
3423  $this->ctrl->redirectByClass(
3424  'ilobjuserfoldergui',
3425  'export'
3426  );
3427  } elseif ($this->checkUserManipulationAccessBool()) {
3428  $fullname = $this->object->buildExportFile(
3430  $user_ids,
3431  true
3432  );
3434  $fullname,
3435  $this->object->getExportFilename(ilObjUserFolder::FILE_TYPE_CSV),
3436  '',
3437  false,
3438  true
3439  );
3440  }
3441  }
3442 
3443  protected function usrExportXmlObject(): void
3444  {
3445  $user_ids = $this->getActionUserIds();
3446  if (!$user_ids) {
3447  $this->tpl->setOnScreenMessage('failure', $this->lng->txt('select_one'), true);
3448  $this->ctrl->redirect(
3449  $this,
3450  'view'
3451  );
3452  }
3453  if ($this->checkPermissionBool('write,read_users')) {
3454  $this->object->buildExportFile(
3456  $user_ids
3457  );
3458  $this->ctrl->redirectByClass(
3459  'ilobjuserfoldergui',
3460  'export'
3461  );
3462  } elseif ($this->checkUserManipulationAccessBool()) {
3463  $fullname = $this->object->buildExportFile(
3465  $user_ids,
3466  true
3467  );
3469  $fullname,
3470  $this->object->getExportFilename(ilObjUserFolder::FILE_TYPE_XML),
3471  '',
3472  false,
3473  true
3474  );
3475  }
3476  }
3477 
3478  protected function mailObject(): void
3479  {
3480  $user_ids = $this->getActionUserIds();
3481  if (!$user_ids) {
3482  $this->tpl->setOnScreenMessage('failure', $this->lng->txt('select_one'), true);
3483  $this->ctrl->redirect(
3484  $this,
3485  'view'
3486  );
3487  return;
3488  }
3489 
3490  // remove existing (temporary) lists
3491  $old_lists = new ilMailingLists($this->user);
3492  $old_lists->deleteTemporaryLists();
3493 
3494  // create (temporary) mailing list
3495  $list = new ilMailingList($this->user);
3496  $list->setMode(ilMailingList::MODE_TEMPORARY);
3497  $list->setTitle('-TEMPORARY SYSTEM LIST-');
3498  $list->setDescription('-USER ACCOUNTS MAIL-');
3499  $list->setCreatedate(date('Y-m-d H:i:s'));
3500  $list->insert();
3501  $list_id = $list->getId();
3502 
3503  // after list has been saved...
3504  foreach ($user_ids as $user_id) {
3505  $list->assignUser((int) $user_id);
3506  }
3507 
3508  $umail = new ilFormatMail($this->user->getId());
3509  $mail_data = $umail->retrieveFromStage();
3510 
3511  $umail->persistToStage(
3512  $mail_data['user_id'],
3513  $mail_data['attachments'],
3514  '#il_ml_' . $list_id,
3515  $mail_data['rcp_cc'],
3516  $mail_data['rcp_bcc'],
3517  $mail_data['m_subject'],
3518  $mail_data['m_message'],
3519  $mail_data['use_placeholders'],
3520  $mail_data['tpl_ctx_id'],
3521  $mail_data['tpl_ctx_params']
3522  );
3523 
3524  $this->ctrl->redirectToURL(
3526  $this,
3527  '',
3528  [],
3529  ['type' => 'search_res']
3530  )
3531  );
3532  }
3533 
3534  public function addToExternalSettingsForm(int $a_form_id): array // Missing array type.
3535  {
3536  switch ($a_form_id) {
3538  $security = ilSecuritySettings::_getInstance();
3539 
3540  $fields = [];
3541 
3542  $subitems = [
3543  'ps_password_change_on_first_login_enabled' => [
3544  $security->isPasswordChangeOnFirstLoginEnabled(),
3546  ],
3547  'ps_password_must_not_contain_loginame' => [
3548  $security->getPasswordMustNotContainLoginnameStatus(),
3550  ],
3551  'ps_password_chars_and_numbers_enabled' => [
3552  $security->isPasswordCharsAndNumbersEnabled(),
3554  ],
3555  'ps_password_special_chars_enabled' => [
3556  $security->isPasswordSpecialCharsEnabled(),
3558  ],
3559  'ps_password_min_length' => $security->getPasswordMinLength(),
3560  'ps_password_max_length' => $security->getPasswordMaxLength(),
3561  'ps_password_uppercase_chars_num' => $security->getPasswordNumberOfUppercaseChars(),
3562  'ps_password_lowercase_chars_num' => $security->getPasswordNumberOfLowercaseChars(),
3563  'ps_password_max_age' => $security->getPasswordMaxAge()
3564  ];
3565  $fields['ps_password_settings'] = [null, null, $subitems];
3566 
3567  $subitems = [
3568  'ps_login_max_attempts' => $security->getLoginMaxAttempts(),
3569  'ps_prevent_simultaneous_logins' => [
3570  $security->isPreventionOfSimultaneousLoginsEnabled(),
3572  ]
3573  ];
3574  $fields['ps_security_protection'] = [null, null, $subitems];
3575 
3576  return [['generalSettings', $fields]];
3577  }
3578  return [];
3579  }
3580 
3581  private function redirectAfterImport(): void
3582  {
3583  if ($this->inAdministration()) {
3584  $this->ctrl->redirect(
3585  $this,
3586  'view'
3587  );
3588  }
3589 
3590  $this->ctrl->redirectByClass(
3591  'ilobjcategorygui',
3592  'listUsers'
3593  );
3594  }
3595 
3596  protected function addToClipboardObject(): void
3597  {
3598  $users = $this->getActionUserIds();
3599  if (!count($users)) {
3600  $this->tpl->setOnScreenMessage('failure', $this->lng->txt('select_one'), true);
3601  $this->ctrl->redirect(
3602  $this,
3603  'view'
3604  );
3605  }
3606  $clip = ilUserClipboard::getInstance($GLOBALS['DIC']['ilUser']->getId());
3607  $clip->add($users);
3608  $clip->save();
3609 
3610  $this->tpl->setOnScreenMessage('success', $this->lng->txt('clipboard_user_added'), true);
3611  $this->ctrl->redirect(
3612  $this,
3613  'view'
3614  );
3615  }
3616 
3617  private function checkbox(string $name): ilCheckboxInputGUI
3618  {
3619  $checkbox = new ilCheckboxInputGUI($this->lng->txt($name), $name);
3620  $checkbox->setInfo($this->lng->txt($name . '_desc'));
3621  $checkbox->setValue('1');
3622 
3623  return $checkbox;
3624  }
3625 
3626  private function raiseErrorOnMissingWrite(): void
3627  {
3628  if (!$this->access->checkRbacOrPositionPermissionAccess(
3629  'write',
3632  )) {
3633  $this->ilias->raiseError(
3634  $this->lng->txt('permission_denied'),
3635  $this->ilias->error_obj->MESSAGE
3636  );
3637  }
3638  }
3639 }
static _getAllUserIds(int $a_filter=0)
showFieldChangeComponentsListeningConfirmDialog(array $interested_change_listeners)
static get(string $a_var)
parseCurrentBlock(string $block_name=self::DEFAULT_BLOCK)
Parses the given block.
Global event handler.
searchUserAccessFilterCallable(array $a_user_ids)
static _writeNewAccountMail(string $a_lang, string $a_subject, string $a_sal_g, string $a_sal_f, string $a_sal_m, string $a_body)
importUsersObject()
Import Users with new form implementation.
__buildUserFilterSelect()
build select form to distinguish between active and non-active users
static _saveStatus(string $a_key, bool $a_enabled)
const IL_CAL_DATETIME
static _getIcon(int $obj_id=0, string $size="big", string $type="", bool $offline=false)
Get icon for repository item.
static getLogger(string $a_component_id)
Get component logger.
const USER_FOLDER_ID
Definition: constants.php:33
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...
setCurrentBlock(string $part=self::DEFAULT_BLOCK)
Sets the template to the given block.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
getItemByPostVar(string $a_post_var)
const ROOT_FOLDER_ID
Definition: constants.php:32
if($clientAssertionType !='urn:ietf:params:oauth:client-assertion-type:jwt-bearer'|| $grantType !='client_credentials') $parts
Definition: ltitoken.php:61
static _isSearchable(string $a_key)
Singleton class that stores all security settings.
prepareOutput(bool $show_sub_objects=true)
This class represents a file property in a property form.
final const int MODE_TEMPORARY
Interface Observer Contains several chained tasks and infos about them.
const SYSTEM_ROLE_ID
Definition: constants.php:29
importUserRoleAssignmentObject()
display form for user import with new FileSystem implementation
$valid
Class ilUserProfile.
isPasswordCharsAndNumbersEnabled()
get boolean if the passwords have to contain characters and numbers
settingsObject()
Global user settings Allows to define global settings for user accounts Note: The Global user setting...
static formSelect( $selected, string $varname, array $options, bool $multiple=false, bool $direct_text=false, int $size=0, string $style_class="", array $attribs=[], bool $disabled=false)
Builds a select form field with options and shows the selected option first.
setShowTime(bool $a_showtime)
getFullname(int $a_max_strlen=0)
getUserMultiCommands(bool $a_search_form=false)
getPasswordPolicySettingsMap(\ilSecuritySettings $security)
setSuffixes(array $a_suffixes)
static _updateAccountMailAttachment(string $a_lang, string $a_tmp_name, string $a_name)
Update account mail attachment.
filterUserIdsByRbacOrPositionOfCurrentUser(array $user_ids)
This class represents a email property in a property form.
const IL_CAL_UNIX
setVariable(string $variable, $value='')
Sets the given variable to the given value.
static _reset()
Reset all.
newAccountMailObject(?ilPropertyFormGUI $form=null)
showActionConfirmation(string $action, bool $a_from_search=false)
$ilErr
Definition: raiseError.php:33
$path
Definition: ltiservices.php:29
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This class represents a date/time property in a property form.
static _lookupObjId(int $ref_id)
getPasswordMaxLength()
get the maximum length for passwords
static deliverFileLegacy(string $a_file, ?string $a_filename=null, ?string $a_mime=null, ?bool $isInline=false, ?bool $removeAfterDelivery=false, ?bool $a_exit_after=true)
retrieveFromStage()
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
getActionUserIds()
Get selected items for table action.
allowDecimals(bool $a_value)
ilLanguage $lng
getPasswordNumberOfLowercaseChars()
Returns number of lowercase characters required.
TableGUI class for user administration.
This class represents a hidden form property in a property form.
initUserRoleAssignmentForm(string $xml_file_full_path)
Class ilCustomUserFieldsGUI.
getPasswordNumberOfUppercaseChars()
Returns number of uppercase characters required.
const int DEFAULT_ALLOW_CLIENT_MAINTENANCE
static _goto(string $a_user)
ilGlobalTemplateInterface $tpl
static _lookupTitle(int $obj_id)
saveGeneralSettingsObject()
Save user account settings.
static _lookupNewAccountMail(string $a_lang)
$GLOBALS["DIC"]
Definition: wac.php:53
searchResultHandler(array $a_usr_ids, string $a_cmd)
Handles multi command from repository search gui.
setFormAction(string $a_formaction)
static _getUserFolderId()
Class ilUserStartingPointGUI.
This class represents a number property in a property form.
setVisible(string $field, bool $visible)
Set a profile field being visible.
saveGlobalUserSettingsObject(string $action='')
getTranslationForField(string $field_name, array $properties)
isPasswordSpecialCharsEnabled()
get boolean if the passwords have to contain special characters
getPasswordMinLength()
get the minimum length for passwords
Class ilObjectGUI Basic methods of all Output classes.
global $DIC
Definition: shib_login.php:26
static getImagePath(string $image_name, string $module_path="", string $mode="output", bool $offline=false)
get image path (for images located in a template directory)
Class ilObjForumAdministration.
static _deleteAccountMailAttachment(string $a_lang)
Delete account mail attachment.
Class FileUpload.
Definition: FileUpload.php:37
static getDataDir()
get data directory (outside webspace)
addToExternalSettingsForm(int $a_form_id)
get(string $part=self::DEFAULT_BLOCK)
Renders the given block and returns the html string.
setRequired(bool $a_required)
setTitleIcon(string $a_titleicon)
withValue($value)
Get an input like this with another value displayed on the client side.
Definition: Group.php:61
jumpToUserObject()
Jump to edit screen for user.
addCommandButton(string $a_cmd, string $a_text, string $a_id="")
const ROLE_FOLDER_ID
Definition: constants.php:34
exit
setChangeable(string $field, bool $changeable)
Set a profile field being changeable.
setAllowDeletion(bool $a_val)
checkPermissionBool(string $perm, string $cmd="", string $type="", ?int $ref_id=null)
downloadExportFileObject()
Download selected export files Sends a selected export file for download.
showPossibleSubObjects()
show possible subobjects (pulldown menu) overwritten to prevent displaying of role templates in local...
static getInstanceByObjId(?int $obj_id, bool $stop_on_error=true)
get an instance of an Ilias object by object id
getProtocolAsHTML(string $a_log_title)
Returns the protocol as a HTML table.
getErrorLevel()
Returns the error level.
const ANONYMOUS_ROLE_ID
Definition: constants.php:28
form( $class_path, string $cmd, string $submit_caption="")
__construct(Container $dic, ilPlugin $plugin)
This class represents a text area property in a property form.
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=[])
verifyXmlData(ilUserImportParser $import_parser)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
$a
thx to https://mlocati.github.io/php-cs-fixer-configurator for the examples
$check
Definition: buildRTE.php:81
__construct( $a_data, int $a_id, bool $a_call_by_reference)
$message
Definition: xapiexit.php:31
const ilPropertyFormGUI $form
redirectToURL(string $target_url)
initAccessRestrictionForm(bool $a_from_search=false)
static _getAssignUsersStatus(int $a_role_id)
static _lookupType(int $id, bool $reference=false)
$post
Definition: ltitoken.php:46
static _getInstance()
Get instance of ilSecuritySettings.
ilSetting $settings
checkPermission(string $perm, string $cmd="", string $type="", ?int $ref_id=null)
getPasswordMustNotContainLoginnameStatus()
Return whether the password must not contain the loginname or not.
static getInstance(int $a_usr_id)
redirectOnRoleWithMissingWrite(int $role_id, array $roles_of_user, array $global_roles, string $import_dir)
setAccessRestrictionObject(?ilPropertyFormGUI $a_form=null, bool $a_from_search=false)
static _gotoRepositoryRoot(bool $raise_error=false)
Goto repository root.
ilUserSettingsConfig $user_settings_config