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