ILIAS  trunk Revision v11.0_alpha-2638-g80c1d007f79
class.ilUserImportParser.php
Go to the documentation of this file.
1 <?php
2 
19 declare(strict_types=1);
20 
23 
25 {
26  public const IL_EXTRACT_ROLES = 1;
27  public const IL_USER_IMPORT = 2;
28  public const IL_VERIFY = 3;
29 
30  public const IL_FAIL_ON_CONFLICT = 1;
31  public const IL_UPDATE_ON_CONFLICT = 2;
32  public const IL_IGNORE_ON_CONFLICT = 3;
33 
34  public const IL_IMPORT_SUCCESS = 1;
35  public const IL_IMPORT_WARNING = 2;
36  public const IL_IMPORT_FAILURE = 3;
37 
38  private const IL_USER_MAPPING_LOGIN = 1;
39  public const IL_USER_MAPPING_ID = 2;
40 
41  private ILIAS $ilias;
46  private ilAccess $access;
47  private ilObjUser $user;
48 
50 
51  protected ?string $tmp_udf_name = null;
52  protected ?string $tmp_udf_id = null;
53  protected array $multi_values; // Missing array type.
54  protected array $udf_data; // Missing array type.
55  protected bool $auth_mode_set;
56  protected ?string $currentPrefKey = null;
57  protected array $prefs; // Missing array type.
58  protected string $current_role_action;
59  protected string $current_role_type;
60  protected string $current_role_id = '0';
61  protected string $cdata;
62  protected array $role_assign; // Missing array type.
63  protected string $req_send_mail;
65  protected int $mode;
66  public bool $approve_date_set = false;
67  public bool $time_limit_set = false;
68  public bool $time_limit_owner_set = false;
69 
70  public bool $updateLookAndSkin = false;
71  public int $folder_id;
72  public array $roles; // Missing array type.
73  public string $action; // "Insert","Update","Delete"
74  protected array $required_fields = []; // Missing array type.
75  protected array $containedTags = [];
76 
85  public array $protocol;
86 
96  public array $logins;
97 
98  public int $conflict_rule;
99 
100  public bool $send_mail;
101 
163  public int $error_level;
164 
165  public ?string $currPasswordType;
166  public ?string $currPassword;
167  public ?string $currActive = null;
168  public int $userCount;
169  public array $user_mapping = []; // Missing array type.
170  public int $mapping_mode;
171 
179  public array $localRoleCache;
180 
185  public ?array $personalPicture = null; // Missing array type.
186 
194  public array $parentRolesCache;
195 
196  public string $skin = '';
197  public string $style = '';
198 
202  public array $userStyles; // Missing array type.
203 
204  public int $user_id;
205 
207  private string $current_messenger_type;
211 
218  public function __construct(
219  string $a_xml_file = '',
220  int $a_mode = self::IL_USER_IMPORT,
221  int $a_conflict_rule = self::IL_FAIL_ON_CONFLICT
222  ) {
224  global $DIC;
225  $this->ilias = $DIC['ilias'];
226  $this->settings = $DIC['ilSetting'];
227  $this->object_data_cache = $DIC['ilObjDataCache'];
228  $this->rbac_review = $DIC['rbacreview'];
229  $this->rbac_admin = $DIC['rbacadmin'];
230  $this->access = $DIC['ilAccess'];
231  $this->user = $DIC['ilUser'];
232  $this->refinery = $DIC['refinery'];
233 
234  $http = $DIC['http'];
235 
236  $this->user_profile = new ilUserProfile();
237 
238  $this->roles = [];
239  $this->mode = $a_mode;
240  $this->conflict_rule = $a_conflict_rule;
241  $this->error_level = self::IL_IMPORT_SUCCESS;
242  $this->protocol = [];
243  $this->logins = [];
244  $this->userCount = 0;
245  $this->localRoleCache = [];
246  $this->parentRolesCache = [];
247  $this->send_mail = false;
248  $this->mapping_mode = self::IL_USER_MAPPING_LOGIN;
249 
250 
251  $this->user_settings_config = new ilUserSettingsConfig();
252 
253  // get all active style instead of only assigned ones -> cannot transfer all to another otherwise
254  $this->userStyles = [];
255  $skins = ilStyleDefinition::getAllSkins();
256 
257  if (is_array($skins)) {
258  foreach ($skins as $skin) {
259  foreach ($skin->getStyles() as $style) {
260  if (!ilSystemStyleSettings::_lookupActivatedStyle($skin->getId(), $style->getId())) {
261  continue;
262  }
263  $this->userStyles [] = $skin->getId() . ':' . $style->getId();
264  }
265  }
266  }
267 
268  $this->acc_mail = new ilAccountMail();
269  $this->acc_mail->setAttachConfiguredFiles(true);
270  $this->acc_mail->useLangVariablesAsFallback(true);
271 
272  $this->recommended_content_manager = new ilRecommendedContentManager();
273 
274  $request = new UserGUIRequest(
275  $http,
276  $this->refinery
277  );
278  $this->req_send_mail = $request->getSendMail();
279 
280  parent::__construct($a_xml_file);
281  }
282 
287  public function setFolderId(int $a_folder_id): void
288  {
289  $this->folder_id = $a_folder_id;
290  }
291 
292  public function getFolderId(): int
293  {
294  return $this->folder_id;
295  }
296 
304  public function setHandlers($a_xml_parser): void
305  {
306  xml_set_element_handler($a_xml_parser, $this->handlerBeginTag(...), $this->handlerEndTag(...));
307  xml_set_character_data_handler($a_xml_parser, $this->handlerCharacterData(...));
308  }
309 
315  public function setRoleAssignment(array $a_assign): void
316  {
317  $this->role_assign = $a_assign;
318  }
319 
323  public function buildTag(string $type, string $name, ?array $attr = null): string // Missing array type.
324  {
325  $tag = '<';
326 
327  if ($type === 'end') {
328  $tag .= '/';
329  }
330 
331  $tag .= $name;
332 
333  if (is_array($attr)) {
334  foreach ($attr as $k => $v) {
335  $tag .= " {$k}='{$v}'";
336  }
337  }
338 
339  $tag .= '>';
340 
341  return $tag;
342  }
343 
344  public function handlerBeginTag(
345  $a_xml_parser,
346  string $a_name,
347  array $a_attribs
348  ): void {
349  switch ($this->mode) {
350  case self::IL_EXTRACT_ROLES:
351  $this->extractRolesBeginTag($a_xml_parser, $a_name, $a_attribs);
352  break;
353  case self::IL_USER_IMPORT:
354  $this->importBeginTag($a_xml_parser, $a_name, $a_attribs);
355  break;
356  case self::IL_VERIFY:
357  $this->verifyBeginTag($a_xml_parser, $a_name, $a_attribs);
358  break;
359  }
360 
361  $this->cdata = '';
362  }
363 
367  public function extractRolesBeginTag(
368  $a_xml_parser,
369  string $a_name,
370  array $a_attribs
371  ): void {
372  switch ($a_name) {
373  case 'Role':
374  // detect numeric, ilias id (then extract role id) or alphanumeric
375  $current_role_id = $a_attribs['Id'];
376  if (($internal_id = ilUtil::__extractId($current_role_id, (int) IL_INST_ID)) > 0) {
377  $current_role_id = $internal_id;
378  }
379  $this->current_role_id = $this->refinery->kindlyTo()->string()->transform($current_role_id);
380  $this->current_role_type = $a_attribs['Type'];
381  break;
382  }
383  }
384 
388  public function importBeginTag(
389  $a_xml_parser,
390  string $a_name,
391  array $a_attribs
392  ): void {
393  switch ($a_name) {
394  case 'Role':
395  $current_role_id = $a_attribs['Id'];
396  if (($internal_id = ilUtil::__extractId($current_role_id, (int) IL_INST_ID)) > 0) {
397  $current_role_id = $internal_id;
398  }
399  $this->current_role_id = (string) $current_role_id;
400  $this->current_role_type = $a_attribs['Type'];
401  $this->current_role_action = (!isset($a_attribs['Action'])) ? 'Assign' : $a_attribs['Action'];
402  break;
403 
404  case 'PersonalPicture':
405  $this->personalPicture = [
406  'encoding' => $a_attribs['encoding'],
407  'imagetype' => $a_attribs['imagetype'],
408  'content' => ''
409  ];
410  break;
411 
412  case 'Look':
413  $this->skin = $a_attribs['Skin'];
414  $this->style = $a_attribs['Style'];
415  break;
416 
417  case 'User':
418  $this->containedTags = [];
419 
420  $this->acc_mail->reset();
421  $this->prefs = [];
422  $this->currentPrefKey = null;
423  $this->auth_mode_set = false;
424  $this->approve_date_set = false;
425  $this->time_limit_set = false;
426  $this->time_limit_owner_set = false;
427  $this->updateLookAndSkin = false;
428  $this->skin = '';
429  $this->style = '';
430  $this->personalPicture = null;
431  $this->userCount++;
432  $this->userObj = new ilObjUser();
433 
434  // user defined fields
435  $this->udf_data = [];
436 
437  // if we have an object id, store it
438  $this->user_id = -1;
439  if (isset($a_attribs['Id']) && $this->getUserMappingMode() === self::IL_USER_MAPPING_ID) {
440  if (is_numeric($a_attribs['Id'])) {
441  $this->user_id = (int) $a_attribs['Id'];
442  } elseif (($id = (int) ilUtil::__extractId($a_attribs['Id'], (int) IL_INST_ID)) > 0) {
443  $this->user_id = $id;
444  }
445  }
446 
447  $this->userObj->setPref(
448  'skin',
449  $this->ilias->ini->readVariable('layout', 'skin')
450  );
451  $this->userObj->setPref(
452  'style',
453  $this->ilias->ini->readVariable('layout', 'style')
454  );
455 
456  if (isset($a_attribs['Language'])) {
457  $this->containedTags[] = 'Language';
458  }
459  $this->userObj->setLanguage($a_attribs['Language'] ?? '');
460  $this->userObj->setImportId($a_attribs['Id'] ?? '');
461  $this->action = (is_null($a_attribs['Action'])) ? 'Insert' : $a_attribs['Action'];
462  $this->currPassword = null;
463  $this->currPasswordType = null;
464  $this->currActive = null;
465  $this->multi_values = [];
466  break;
467 
468  case 'Password':
469  $this->currPasswordType = $a_attribs['Type'];
470  break;
471  case 'AuthMode':
472  if (array_key_exists('type', $a_attribs)) {
473  switch ($a_attribs['type']) {
474  case 'saml':
475  case 'ldap':
476  if (strcmp('saml', $a_attribs['type']) === 0) {
477  $list = ilSamlIdp::getActiveIdpList();
478  if (count($list) === 1) {
479  $this->auth_mode_set = true;
480  $idp = current($list);
481  $this->userObj->setAuthMode('saml_' . $idp->getIdpId());
482  }
483  break;
484  }
485  if (strcmp('ldap', $a_attribs['type']) === 0) {
486  // no server id provided => use default server
488  if (count($list) == 1) {
489  $this->auth_mode_set = true;
490  $ldap_id = current($list);
491  $this->userObj->setAuthMode('ldap_' . $ldap_id);
492  }
493  }
494  break;
495 
496  case 'default':
497  case 'local':
498  case 'shibboleth':
499  case 'script':
500  case 'soap':
501  case 'openid':
502  // begin-patch auth_plugin
503  default:
504  $this->auth_mode_set = true;
505  $this->userObj->setAuthMode($a_attribs['type']);
506  break;
507  }
508  } else {
509  $this->logFailure(
510  $this->userObj->getLogin(),
511  sprintf($this->lng->txt('usrimport_xml_element_inapplicable'), 'AuthMode', $this->stripTags($a_attribs['type']))
512  );
513  }
514  break;
515 
516  case 'UserDefinedField':
517  $this->tmp_udf_id = $a_attribs['Id'];
518  $this->tmp_udf_name = $a_attribs['Name'];
519  break;
520 
521  case 'AccountInfo':
522  $this->current_messenger_type = strtolower($a_attribs['Type']);
523  break;
524  case 'GMapInfo':
525  $this->userObj->setLatitude($a_attribs['latitude']);
526  $this->userObj->setLongitude($a_attribs['longitude']);
527  $this->userObj->setLocationZoom($a_attribs['zoom']);
528  break;
529  case 'Pref':
530  $this->currentPrefKey = $a_attribs['key'];
531  break;
532  }
533  }
534 
538  public function verifyBeginTag(
539  $a_xml_parser,
540  string $a_name,
541  array $a_attribs
542  ): void {
543  switch ($a_name) {
544  case 'Role':
545  if ($a_attribs['Id'] == '') {
546  $this->logFailure($this->userObj->getLogin(), sprintf($this->lng->txt('usrimport_xml_attribute_missing'), 'Role', 'Id'));
547  }
548  $this->current_role_id = $a_attribs['Id'];
549  $this->current_role_type = $a_attribs['Type'];
550  if ($this->current_role_type !== 'Global'
551  && $this->current_role_type !== 'Local') {
552  $this->logFailure($this->userObj->getLogin(), sprintf($this->lng->txt('usrimport_xml_attribute_missing'), 'Role', 'Type'));
553  }
554  $this->current_role_action = (!isset($a_attribs['Action'])) ? 'Assign' : $a_attribs['Action'];
555  if ($this->current_role_action !== 'Assign'
556  && $this->current_role_action !== 'AssignWithParents'
557  && $this->current_role_action !== 'Detach') {
558  $this->logFailure($this->userObj->getLogin(), sprintf($this->lng->txt('usrimport_xml_attribute_value_illegal'), 'Role', 'Action', $this->stripTags($a_attribs['Action'])));
559  }
560  if ($this->action === 'Insert'
561  && $this->current_role_action === 'Detach') {
562  $this->logFailure($this->userObj->getLogin(), sprintf($this->lng->txt('usrimport_xml_attribute_value_inapplicable'), 'Role', 'Action', $this->stripTags($this->current_role_action), $this->stripTags($this->action)));
563  }
564  if ($this->action === 'Delete') {
565  $this->logFailure($this->userObj->getLogin(), sprintf($this->lng->txt('usrimport_xml_element_inapplicable'), 'Role', 'Delete'));
566  }
567  break;
568 
569  case 'User':
570  $this->userCount++;
571  $this->containedTags = [];
572  $this->userObj = new ilObjUser();
573  $this->userObj->setLanguage($a_attribs['Language'] ?? '');
574  $this->userObj->setImportId($a_attribs['Id'] ?? '');
575  $this->currentPrefKey = null;
576  // if we have an object id, store it
577  $this->user_id = -1;
578 
579  if (isset($a_attribs['Id']) && $this->getUserMappingMode() === self::IL_USER_MAPPING_ID) {
580  if (is_numeric($a_attribs['Id'])) {
581  $this->user_id = (int) $a_attribs['Id'];
582  } elseif (($id = (int) ilUtil::__extractId($a_attribs['Id'], (int) IL_INST_ID)) > 0) {
583  $this->user_id = $id;
584  }
585  }
586 
587  $this->action = !isset($a_attribs['Action']) ? 'Insert' : $a_attribs['Action'];
588  if ($this->action !== 'Insert'
589  && $this->action !== 'Update'
590  && $this->action !== 'Delete') {
591  $this->logFailure($this->userObj->getImportId(), sprintf($this->lng->txt('usrimport_xml_attribute_value_illegal'), 'User', 'Action', $this->stripTags($a_attribs['Action'])));
592  }
593  $this->currPassword = null;
594  $this->currPasswordType = null;
595  break;
596 
597  case 'Password':
598  $this->currPasswordType = $a_attribs['Type'];
599  break;
600  case 'AuthMode':
601  if (array_key_exists('type', $a_attribs)) {
602  switch ($a_attribs['type']) {
603  case 'saml':
604  case 'ldap':
605  if (strcmp('saml', $a_attribs['type']) === 0) {
606  $list = ilSamlIdp::getActiveIdpList();
607  if (count($list) !== 1) {
608  $this->logFailure(
609  $this->userObj->getImportId(),
610  sprintf($this->lng->txt('usrimport_xml_attribute_value_illegal'), 'AuthMode', 'type', $this->stripTags($a_attribs['type']))
611  );
612  }
613  break;
614  }
615  if (strcmp('ldap', $a_attribs['type']) === 0) {
616  // no server id provided
618  if (count($list) != 1) {
619  $this->logFailure(
620  $this->userObj->getImportId(),
621  sprintf($this->lng->txt('usrimport_xml_attribute_value_illegal'), 'AuthMode', 'type', $this->stripTags($a_attribs['type']))
622  );
623  }
624  }
625  break;
626 
627  case 'default':
628  case 'local':
629  case 'shibboleth':
630  case 'script':
631  case 'soap':
632  case 'openid':
633  // begin-patch auth_plugin
634  default:
635  $this->userObj->setAuthMode($a_attribs['type']);
636  break;
637  }
638  } else {
639  $this->logFailure($this->userObj->getImportId(), sprintf($this->lng->txt('usrimport_xml_attribute_value_illegal'), 'AuthMode', 'type', ''));
640  }
641  break;
642  case 'Pref':
643  $this->currentPrefKey = $a_attribs['key'];
644  break;
645  }
646  }
647 
648  public function handlerEndTag(
649  $a_xml_parser,
650  string $a_name
651  ): void {
652  switch ($this->mode) {
653  case self::IL_EXTRACT_ROLES:
654  $this->extractRolesEndTag($a_xml_parser, $a_name);
655  break;
656  case self::IL_USER_IMPORT:
657  $this->importEndTag($a_xml_parser, $a_name);
658  break;
659  case self::IL_VERIFY:
660  $this->verifyEndTag($a_xml_parser, $a_name);
661  break;
662  }
663  }
664 
668  public function extractRolesEndTag(
669  $a_xml_parser,
670  string $a_name
671  ): void {
672  switch ($a_name) {
673  case 'Role':
674  $this->roles[$this->current_role_id]['name'] = $this->cdata;
675  $this->roles[$this->current_role_id]['type'] =
677  break;
678  }
679  }
680 
684  public function getRoleObject(int $a_role_id): ilObjRole
685  {
686  if (array_key_exists($a_role_id, $this->localRoleCache)) {
687  return $this->localRoleCache[$a_role_id];
688  } else {
689  $role_obj = new ilObjRole($a_role_id, false);
690  $role_obj->read();
691  $this->localRoleCache[$a_role_id] = $role_obj;
692  return $role_obj;
693  }
694  }
695 
699  public function getCourseMembersObjectForRole(int $a_role_id): ilCourseParticipants
700  {
701  if (array_key_exists($a_role_id . '_courseMembersObject', $this->localRoleCache)) {
702  return $this->localRoleCache[$a_role_id . '_courseMembersObject'];
703  } else {
704  $course_refs = $this->rbac_review->getFoldersAssignedToRole($a_role_id, true);
705  $course_ref = $course_refs[0];
706  $course_obj = new ilObjCourse($course_ref, true);
707  $crsmembers_obj = ilCourseParticipants::_getInstanceByObjId($course_obj->getId());
708  $this->localRoleCache[$a_role_id . '_courseMembersObject'] = $crsmembers_obj;
709  return $crsmembers_obj;
710  }
711  }
712 
716  public function assignToRole(ilObjUser $a_user_obj, int $a_role_id): void
717  {
718  // Do nothing, if the user is already assigned to the role.
719  // Specifically, we do not want to put a course object or
720  // group object on the personal desktop again, if a user
721  // has removed it from the personal desktop.
722  if ($this->rbac_review->isAssigned($a_user_obj->getId(), $a_role_id)) {
723  return;
724  }
725 
726  // If it is a course role, use the ilCourseMember object to assign
727  // the user to the role
728 
729  $this->rbac_admin->assignUser($a_role_id, $a_user_obj->getId(), true);
730  $obj_id = $this->rbac_review->getObjectOfRole($a_role_id);
731  switch (ilObject::_lookupType($obj_id)) {
732  case 'grp':
733  case 'crs':
734  $ref_ids = ilObject::_getAllReferences($obj_id);
735  $ref_id = current((array) $ref_ids);
736  if ($ref_id) {
737  // deactivated for now, see discussion at
738  // https://docu.ilias.de/goto_docu_wiki_wpage_5620_1357.html
739  //$this->recommended_content_manager->addObjectRecommendation($a_user_obj->getId(), $ref_id);
740  }
741  break;
742  default:
743  break;
744  }
745  }
746 
752  public function getParentRoleIds(int $a_role_id): array
753  {
754  if (!array_key_exists($a_role_id, $this->parentRolesCache)) {
755  $parent_role_ids = [];
756 
757  $role_obj = $this->getRoleObject($a_role_id);
758  $short_role_title = substr($role_obj->getTitle(), 0, 12);
759  $folders = $this->rbac_review->getFoldersAssignedToRole($a_role_id, true);
760  if (count($folders) > 0) {
761  $all_parent_role_ids = $this->rbac_review->getParentRoleIds($folders[0]);
762  foreach ($all_parent_role_ids as $parent_role_id => $parent_role_data) {
763  if ($parent_role_id != $a_role_id) {
764  switch (substr($parent_role_data['title'], 0, 12)) {
765  case 'il_crs_admin':
766  case 'il_grp_admin':
767  if ($short_role_title === 'il_crs_admin' || $short_role_title === 'il_grp_admin') {
768  $parent_role_ids[] = $parent_role_id;
769  }
770  break;
771  case 'il_crs_tutor':
772  case 'il_grp_tutor':
773  if ($short_role_title === 'il_crs_tutor' || $short_role_title === 'il_grp_tutor') {
774  $parent_role_ids[] = $parent_role_id;
775  }
776  break;
777  case 'il_crs_membe':
778  case 'il_grp_membe':
779  if ($short_role_title === 'il_crs_membe' || $short_role_title === 'il_grp_membe') {
780  $parent_role_ids[] = $parent_role_id;
781  }
782  break;
783  default:
784  break;
785  }
786  }
787  }
788  }
789  $this->parentRolesCache[$a_role_id] = $parent_role_ids;
790  }
791  return $this->parentRolesCache[$a_role_id];
792  }
793 
797  public function assignToRoleWithParents(
798  ilObjUser $a_user_obj,
799  int $a_role_id
800  ): void {
801  $this->assignToRole($a_user_obj, $a_role_id);
802 
803  $parent_role_ids = $this->getParentRoleIds($a_role_id);
804  foreach ($parent_role_ids as $parent_role_id) {
805  $this->assignToRole($a_user_obj, $parent_role_id);
806  }
807  }
808 
812  public function detachFromRole(
813  ilObjUser $a_user_obj,
814  int $a_role_id
815  ): void {
816  $this->rbac_admin->deassignUser($a_role_id, $a_user_obj->getId());
817 
818  if (substr(ilObject::_lookupTitle($a_role_id), 0, 6) !== 'il_crs'
819  && substr(ilObject::_lookupTitle($a_role_id), 0, 6) !== 'il_grp') {
820  return;
821  }
822 
824  $this->rbac_review->getObjectOfRole($a_role_id)
825  );
826  $ref_id = end($ref);
827  if (!$ref_id) {
828  return;
829  }
830  $this->recommended_content_manager->removeObjectRecommendation($a_user_obj->getId(), $ref_id);
831  }
832 
833  protected function tagContained(string $tagname): bool
834  {
835  return in_array($tagname, $this->containedTags, true);
836  }
837 
841  public function importEndTag(
842  $a_xml_parser,
843  string $a_name
844  ): void {
845  $this->containedTags[] = $a_name;
846 
847  switch ($a_name) {
848  case 'Role':
849  $this->roles[$this->current_role_id]['name'] = $this->cdata;
850  $this->roles[$this->current_role_id]['type'] = $this->current_role_type;
851  $this->roles[$this->current_role_id]['action'] = $this->current_role_action;
852  break;
853 
854  case 'PersonalPicture':
855  switch ($this->personalPicture['encoding']) {
856  case 'Base64':
857  $this->personalPicture['content'] = base64_decode($this->cdata);
858  break;
859  case 'UUEncode':
860  $this->personalPicture['content'] = convert_uudecode($this->cdata);
861  break;
862  }
863  break;
864 
865  case 'User':
866  $this->userObj->setFullname();
867  // Fetch the user_id from the database, if we didn't have it in xml file
868  // fetch as well, if we are trying to insert -> recognize duplicates!
869  if ($this->user_id == -1 || $this->action === 'Insert') {
870  $user_id = ilObjUser::getUserIdByLogin($this->userObj->getLogin());
871  } else {
872  $user_id = $this->user_id;
873  }
874 
875  if ($user_id === (int) ANONYMOUS_USER_ID || $user_id === (int) SYSTEM_USER_ID) {
876  return;
877  }
878 
879  // Handle conflicts
880  switch ($this->conflict_rule) {
881  case self::IL_FAIL_ON_CONFLICT:
882  // do not change action
883  break;
884  case self::IL_UPDATE_ON_CONFLICT:
885  switch ($this->action) {
886  case 'Insert':
887  if ($user_id) {
888  $this->logWarning($this->userObj->getLogin(), sprintf($this->lng->txt('usrimport_action_replaced'), 'Insert', 'Update'));
889  $this->action = 'Update';
890  }
891  break;
892  case 'Update':
893  if (!$user_id) {
894  $this->logWarning($this->userObj->getLogin(), sprintf($this->lng->txt('usrimport_action_replaced'), 'Update', 'Insert'));
895  $this->action = 'Insert';
896  }
897  break;
898  case 'Delete':
899  if (!$user_id) {
900  $this->logWarning($this->userObj->getLogin(), sprintf($this->lng->txt('usrimport_action_ignored'), 'Delete'));
901  $this->action = 'Ignore';
902  }
903  break;
904  }
905  break;
906  case self::IL_IGNORE_ON_CONFLICT:
907  switch ($this->action) {
908  case 'Insert':
909  if ($user_id) {
910  $this->logWarning($this->userObj->getLogin(), sprintf($this->lng->txt('usrimport_action_ignored'), 'Insert'));
911  $this->action = 'Ignore';
912  }
913  break;
914  case 'Update':
915  if (!$user_id) {
916  $this->logWarning($this->userObj->getLogin(), sprintf($this->lng->txt('usrimport_action_ignored'), 'Update'));
917  $this->action = 'Ignore';
918  }
919  break;
920  case 'Delete':
921  if (!$user_id) {
922  $this->logWarning($this->userObj->getLogin(), sprintf($this->lng->txt('usrimport_action_ignored'), 'Delete'));
923  $this->action = 'Ignore';
924  }
925  break;
926  }
927  break;
928  }
929 
930  // check external account conflict (if external account is already used)
931  // note: we cannot apply conflict rules in the same manner as to logins here
932  // so we ignore records with already existing external accounts.
933  //echo $this->userObj->getAuthMode().'h';
934  $am = ($this->userObj->getAuthMode() === 'default' || $this->userObj->getAuthMode() == '')
935  ? ilAuthUtils::_getAuthModeName($this->settings->get('auth_mode'))
936  : $this->userObj->getAuthMode();
937  $loginForExternalAccount = ($this->userObj->getExternalAccount() == '')
938  ? ''
939  : ilObjUser::_checkExternalAuthAccount($am, $this->userObj->getExternalAccount());
940  switch ($this->action) {
941  case 'Insert':
942  if ($loginForExternalAccount != '') {
943  $this->logWarning(
944  $this->userObj->getLogin(),
945  $this->lng->txt('usrimport_no_insert_ext_account_exists')
946  . ' (' . $this->stripTags($this->userObj->getExternalAccount()) . ')'
947  );
948  $this->action = 'Ignore';
949  }
950  break;
951 
952  case 'Update':
953  // this variable describes the ILIAS login which belongs to the given external account!!!
954  // it is NOT nescessarily the ILIAS login of the current user record !!
955  // so if we found an ILIAS login according to the authentication method
956  // check if the ILIAS login belongs to the current user record, otherwise somebody else is using it!
957  if ($loginForExternalAccount != '') {
958  // check if we changed the value!
959  $externalAccountHasChanged = $this->userObj->getExternalAccount() != ilObjUser::_lookupExternalAccount($this->user_id);
960  // if it has changed and the external login
961  if ($externalAccountHasChanged && trim($loginForExternalAccount) != trim($this->userObj->getLogin())) {
962  $this->logWarning(
963  $this->userObj->getLogin(),
964  $this->lng->txt('usrimport_no_update_ext_account_exists')
965  . ' (' . $this->stripTags($this->userObj->getExternalAccount()) . ')'
966  );
967  $this->action = 'Ignore';
968  }
969  }
970  break;
971  }
972 
973  if (count($this->multi_values)) {
974  if (isset($this->multi_values['GeneralInterest'])) {
975  $this->userObj->setGeneralInterests($this->multi_values['GeneralInterest']);
976  }
977  if (isset($this->multi_values['OfferingHelp'])) {
978  $this->userObj->setOfferingHelp($this->multi_values['OfferingHelp']);
979  }
980  if (isset($this->multi_values['LookingForHelp'])) {
981  $this->userObj->setLookingForHelp($this->multi_values['LookingForHelp']);
982  }
983  }
984 
985  // Perform the action
986  switch ($this->action) {
987  case 'Insert':
988  if ($user_id) {
989  $this->logFailure($this->userObj->getLogin(), $this->lng->txt('usrimport_cant_insert'));
990  } else {
991  if ($this->currPassword !== null) {
992  switch (strtoupper($this->currPasswordType)) {
993  case 'BCRYPT':
994  $this->userObj->setPasswd($this->currPassword, ilObjUser::PASSWD_CRYPTED);
995  $this->userObj->setPasswordEncodingType('bcryptphp');
996  $this->userObj->setPasswordSalt(null);
997  break;
998 
999  case 'PLAIN':
1000  $this->userObj->setPasswd($this->currPassword, ilObjUser::PASSWD_PLAIN);
1001  $this->acc_mail->setUserPassword((string) $this->currPassword);
1002  break;
1003 
1004  default:
1005  $this->logFailure($this->userObj->getLogin(), sprintf($this->lng->txt('usrimport_xml_attribute_value_illegal'), 'Type', 'Password', $this->stripTags($this->currPasswordType)));
1006  break;
1007  }
1008  } else {
1009  // this does the trick for empty passwords
1010  // since a MD5 string has always 32 characters,
1011  // no hashed password combination will ever equal to
1012  // an empty string
1013  $this->userObj->setPasswd('', ilObjUser::PASSWD_CRYPTED);
1014  }
1015 
1016  $this->userObj->setTitle($this->userObj->getFullname());
1017  $this->userObj->setDescription($this->userObj->getEmail());
1018 
1019  if (!$this->time_limit_owner_set) {
1020  $this->userObj->setTimeLimitOwner($this->getFolderId());
1021  }
1022 
1023  // default time limit settings
1024  if (!$this->time_limit_set) {
1025  $this->userObj->setTimeLimitUnlimited(true);
1026  $this->userObj->setTimeLimitMessage('');
1027 
1028  if (!$this->approve_date_set) {
1029  $this->userObj->setApproveDate(date('Y-m-d H:i:s'));
1030  }
1031  }
1032 
1033 
1034  $this->userObj->setActive($this->currActive === 'true' || is_null($this->currActive));
1035 
1036  // Finally before saving new user.
1037  // Check if profile is incomplete
1038 
1039  // #8759
1040  if (count($this->udf_data)) {
1041  $this->userObj->setUserDefinedData($this->udf_data);
1042  }
1043 
1044  if (!$this->userObj->getLanguage()) {
1045  $this->userObj->setLanguage($this->lng->getDefaultLanguage());
1046  }
1047 
1048  $this->userObj->setProfileIncomplete($this->checkProfileIncomplete($this->userObj));
1049  $this->userObj->create();
1050 
1051  //insert user data in table user_data
1052  $this->userObj->saveAsNew();
1053 
1054  if (count($this->prefs)) {
1055  foreach ($this->prefs as $key => $value) {
1056  if ($key !== 'mail_incoming_type' &&
1057  $key !== 'mail_signature' &&
1058  $key !== 'mail_linebreak'
1059  ) {
1060  $this->userObj->setPref($key, $value);
1061  }
1062  }
1063  }
1064 
1065  if (!is_array($this->prefs) || !array_key_exists('chat_osc_accept_msg', $this->prefs)) {
1066  $this->userObj->setPref('chat_osc_accept_msg', $this->settings->get('chat_osc_accept_msg', 'n'));
1067  }
1068  if (!is_array($this->prefs) || !array_key_exists('chat_broadcast_typing', $this->prefs)) {
1069  $this->userObj->setPref('chat_broadcast_typing', $this->settings->get('chat_broadcast_typing', 'n'));
1070  }
1071  if (!is_array($this->prefs) || !array_key_exists('bs_allow_to_contact_me', $this->prefs)) {
1072  $this->userObj->setPref('bs_allow_to_contact_me', $this->settings->get('bs_allow_to_contact_me', 'n'));
1073  }
1074 
1075  $this->userObj->writePrefs();
1076 
1077  // update mail preferences, to be extended
1078  $this->updateMailPreferences($this->userObj->getId());
1079 
1080  if (is_array($this->personalPicture)) {
1081  if (strlen($this->personalPicture['content'])) {
1082  $extension = 'jpg';
1083  if (preg_match('/.*(png|jpg|gif|jpeg)$/', $this->personalPicture['imagetype'], $matches)) {
1084  $extension = $matches[1];
1085  }
1086  $tmp_name = $this->saveTempImage($this->personalPicture['content'], ".{$extension}");
1087  if (strlen($tmp_name)) {
1088  ilObjUser::_uploadPersonalPicture($tmp_name, $this->userObj->getId());
1089  unlink($tmp_name);
1090  }
1091  }
1092  }
1093 
1094  //set role entries
1095  foreach ($this->roles as $role_id => $role) {
1096  if (isset($this->role_assign[$role_id]) && $this->role_assign[$role_id]) {
1097  $this->assignToRole($this->userObj, (int) $this->role_assign[$role_id]);
1098  }
1099  }
1100 
1101  if (count($this->udf_data)) {
1102  $udd = new ilUserDefinedData($this->userObj->getId());
1103  foreach ($this->udf_data as $field => $value) {
1104  $udd->set('f_' . $field, $value);
1105  }
1106  $udd->update();
1107  }
1108 
1109  $this->sendAccountMail();
1110  $this->logSuccess($this->userObj->getLogin(), $this->userObj->getId(), 'Insert');
1111  // reset account mail object
1112  $this->acc_mail->reset();
1113  }
1114  break;
1115 
1116  case 'Update':
1117  if (!$user_id) {
1118  $this->logFailure($this->userObj->getLogin(), $this->lng->txt('usrimport_cant_update'));
1119  } else {
1120  $updateUser = new ilObjUser($user_id);
1121  $updateUser->read();
1122  $updateUser->readPrefs();
1123  if ($this->currPassword != null) {
1124  switch (strtoupper($this->currPasswordType)) {
1125  case 'BCRYPT':
1126  $updateUser->setPasswd($this->currPassword, ilObjUser::PASSWD_CRYPTED);
1127  $updateUser->setPasswordEncodingType('bcryptphp');
1128  $updateUser->setPasswordSalt(null);
1129  break;
1130 
1131  case 'PLAIN':
1132  $updateUser->setPasswd($this->currPassword, ilObjUser::PASSWD_PLAIN);
1133  $this->acc_mail->setUserPassword((string) $this->currPassword);
1134  break;
1135 
1136  default:
1137  $this->logFailure($this->userObj->getLogin(), sprintf($this->lng->txt('usrimport_xml_attribute_value_illegal'), 'Type', 'Password', $this->stripTags($this->currPasswordType)));
1138  break;
1139  }
1140  }
1141  if ($this->tagContained('Firstname')) {
1142  $updateUser->setFirstname($this->userObj->getFirstname());
1143  }
1144  if ($this->tagContained('Lastname')) {
1145  $updateUser->setLastname($this->userObj->getLastname());
1146  }
1147  if ($this->tagContained('Title')) {
1148  $updateUser->setUTitle($this->userObj->getUTitle());
1149  }
1150  if ($this->tagContained('Gender')) {
1151  $updateUser->setGender($this->userObj->getGender());
1152  }
1153  if ($this->tagContained('Email')) {
1154  $updateUser->setEmail($this->userObj->getEmail());
1155  }
1156  if ($this->tagContained('SecondEmail')) {
1157  $updateUser->setSecondEmail($this->userObj->getSecondEmail());
1158  }
1159  if ($this->tagContained('Birthday')) {
1160  $updateUser->setBirthday($this->userObj->getBirthday());
1161  }
1162  if ($this->tagContained('Institution')) {
1163  $updateUser->setInstitution($this->userObj->getInstitution());
1164  }
1165  if ($this->tagContained('Street')) {
1166  $updateUser->setStreet($this->userObj->getStreet());
1167  }
1168  if ($this->tagContained('City')) {
1169  $updateUser->setCity($this->userObj->getCity());
1170  }
1171  if ($this->tagContained('PostalCode')) {
1172  $updateUser->setZipcode($this->userObj->getZipcode());
1173  }
1174  if ($this->tagContained('Country')) {
1175  $updateUser->setCountry($this->userObj->getCountry());
1176  }
1177  if ($this->tagContained('SelCountry')) {
1178  $updateUser->setSelectedCountry($this->userObj->getSelectedCountry());
1179  }
1180  if ($this->tagContained('PhoneOffice')) {
1181  $updateUser->setPhoneOffice($this->userObj->getPhoneOffice());
1182  }
1183  if ($this->tagContained('PhoneHome')) {
1184  $updateUser->setPhoneHome($this->userObj->getPhoneHome());
1185  }
1186  if ($this->tagContained('PhoneMobile')) {
1187  $updateUser->setPhoneMobile($this->userObj->getPhoneMobile());
1188  }
1189  if ($this->tagContained('Fax')) {
1190  $updateUser->setFax($this->userObj->getFax());
1191  }
1192  if ($this->tagContained('Hobby')) {
1193  $updateUser->setHobby($this->userObj->getHobby());
1194  }
1195  if ($this->tagContained('GeneralInterest')) {
1196  $updateUser->setGeneralInterests($this->userObj->getGeneralInterests());
1197  }
1198  if ($this->tagContained('OfferingHelp')) {
1199  $updateUser->setOfferingHelp($this->userObj->getOfferingHelp());
1200  }
1201  if ($this->tagContained('LookingForHelp')) {
1202  $updateUser->setLookingForHelp($this->userObj->getLookingForHelp());
1203  }
1204  if ($this->tagContained('Comment')) {
1205  $updateUser->setComment($this->userObj->getComment());
1206  }
1207  if ($this->tagContained('Department')) {
1208  $updateUser->setDepartment($this->userObj->getDepartment());
1209  }
1210  if ($this->tagContained('Matriculation')) {
1211  $updateUser->setMatriculation($this->userObj->getMatriculation());
1212  }
1213  if (!is_null($this->currActive)) {
1214  $updateUser->setActive($this->currActive === 'true', is_object($this->user) ? $this->user->getId() : 0);
1215  }
1216  if ($this->tagContained('ClientIP')) {
1217  $updateUser->setClientIP($this->userObj->getClientIP());
1218  }
1219  if ($this->time_limit_set) {
1220  $updateUser->setTimeLimitUnlimited($this->userObj->getTimeLimitUnlimited());
1221  }
1222  if ($this->tagContained('TimeLimitFrom')) {
1223  $updateUser->setTimeLimitFrom($this->userObj->getTimeLimitFrom());
1224  }
1225  if ($this->tagContained('TimeLimitUntil')) {
1226  $updateUser->setTimeLimitUntil($this->userObj->getTimeLimitUntil());
1227  }
1228  if ($this->tagContained('TimeLimitMessage')) {
1229  $updateUser->setTimeLimitMessage($this->userObj->getTimeLimitMessage());
1230  }
1231  if ($this->tagContained('ApproveDate')) {
1232  $updateUser->setApproveDate($this->userObj->getApproveDate());
1233  }
1234  if ($this->tagContained('AgreeDate')) {
1235  $updateUser->setAgreeDate($this->userObj->getAgreeDate());
1236  }
1237  if ($this->tagContained('Language')) {
1238  $updateUser->setLanguage($this->userObj->getLanguage());
1239  }
1240  if ($this->tagContained('ExternalAccount')) {
1241  $updateUser->setExternalAccount($this->userObj->getExternalAccount());
1242  }
1243 
1244  // Fixed: if auth_mode is not set, it was always overwritten with auth_default
1245  #if (! is_null($this->userObj->getAuthMode())) $updateUser->setAuthMode($this->userObj->getAuthMode());
1246  if ($this->auth_mode_set) {
1247  $updateUser->setAuthMode($this->userObj->getAuthMode());
1248  }
1249 
1250  // Special handlin since it defaults to 7 (USER_FOLDER_ID)
1251  if ($this->time_limit_owner_set) {
1252  $updateUser->setTimeLimitOwner($this->userObj->getTimeLimitOwner());
1253  }
1254 
1255  if (count($this->prefs)) {
1256  foreach ($this->prefs as $key => $value) {
1257  if ($key !== 'mail_incoming_type' &&
1258  $key !== 'mail_signature' &&
1259  $key !== 'mail_linebreak'
1260  ) {
1261  $updateUser->setPref($key, $value);
1262  }
1263  }
1264  }
1265 
1266  // save user preferences (skin and style)
1267  if ($this->updateLookAndSkin) {
1268  $updateUser->setPref('skin', $this->userObj->getPref('skin'));
1269  $updateUser->setPref('style', $this->userObj->getPref('style'));
1270  }
1271 
1272 
1273  $updateUser->writePrefs();
1274 
1275  // update mail preferences, to be extended
1276  $this->updateMailPreferences($updateUser->getId());
1277 
1278  // #8759
1279  if (count($this->udf_data)) {
1280  $updateUser->setUserDefinedData($this->udf_data);
1281  }
1282 
1283  $updateUser->setProfileIncomplete($this->checkProfileIncomplete($updateUser));
1284  $updateUser->setFullname();
1285  $updateUser->setTitle($updateUser->getFullname());
1286  $updateUser->setDescription($updateUser->getEmail());
1287  $updateUser->update();
1288 
1289  if (count($this->udf_data)) {
1290  $udd = new ilUserDefinedData($updateUser->getId());
1291  foreach ($this->udf_data as $field => $value) {
1292  $udd->set('f_' . $field, $value);
1293  }
1294  $udd->update();
1295  }
1296 
1297  // update login
1298  if ($this->tagContained('Login') && $this->user_id != -1) {
1299  try {
1300  $updateUser->updateLogin($this->userObj->getLogin());
1301  } catch (ilUserException $e) {
1302  }
1303  }
1304 
1305 
1306  // if language has changed
1307 
1308  if (is_array($this->personalPicture)) {
1309  if (strlen($this->personalPicture['content'])) {
1310  $extension = 'jpg';
1311  if (preg_match('/.*(png|jpg|gif|jpeg)$/', $this->personalPicture['imagetype'], $matches)) {
1312  $extension = $matches[1];
1313  }
1314  $tmp_name = $this->saveTempImage($this->personalPicture['content'], ".{$extension}");
1315  if (strlen($tmp_name)) {
1316  ilObjUser::_uploadPersonalPicture($tmp_name, $updateUser->getId());
1317  unlink($tmp_name);
1318  }
1319  }
1320  }
1321 
1322 
1323  //update role entries
1324  //-------------------
1325  foreach ($this->roles as $role_id => $role) {
1326  if (array_key_exists($role_id, $this->role_assign)) {
1327  switch ($role['action']) {
1328  case 'Assign':
1329  $this->assignToRole($updateUser, (int) $this->role_assign[$role_id]);
1330  break;
1331  case 'AssignWithParents':
1332  $this->assignToRoleWithParents($updateUser, (int) $this->role_assign[$role_id]);
1333  break;
1334  case 'Detach':
1335  $this->detachFromRole($updateUser, (int) $this->role_assign[$role_id]);
1336  break;
1337  }
1338  }
1339  }
1340  $this->logSuccess($updateUser->getLogin(), $user_id, 'Update');
1341  }
1342  break;
1343  case 'Delete':
1344  if (!$user_id) {
1345  $this->logFailure($this->userObj->getLogin(), $this->lng->txt('usrimport_cant_delete'));
1346  } else {
1347  $deleteUser = new ilObjUser($user_id);
1348  $deleteUser->delete();
1349 
1350  $this->logSuccess($this->userObj->getLogin(), $user_id, 'Delete');
1351  }
1352  break;
1353  }
1354 
1355  // init role array for next user
1356  $this->roles = [];
1357  break;
1358 
1359  case 'Login':
1360  $this->userObj->setLogin($this->getCDataWithoutTags($this->cdata));
1361  break;
1362 
1363  case 'Password':
1364  $this->currPassword = $this->cdata;
1365  break;
1366 
1367  case 'Firstname':
1368  $this->userObj->setFirstname($this->getCDataWithoutTags($this->cdata));
1369  break;
1370 
1371  case 'Lastname':
1372  $this->userObj->setLastname($this->getCDataWithoutTags($this->cdata));
1373  break;
1374 
1375  case 'Title':
1376  $this->userObj->setUTitle($this->getCDataWithoutTags($this->cdata));
1377  break;
1378 
1379  case 'Gender':
1380  $this->userObj->setGender($this->cdata);
1381  break;
1382 
1383  case 'Email':
1384  $this->userObj->setEmail($this->getCDataWithoutTags($this->cdata));
1385  break;
1386  case 'SecondEmail':
1387  $this->userObj->setSecondEmail($this->getCDataWithoutTags($this->cdata));
1388  break;
1389  case 'Birthday':
1390  $birthday = $this->getCDataWithoutTags($this->cdata);
1391  if (strtotime($birthday) !== false) {
1392  $this->userObj->setBirthday($birthday);
1393  }
1394  break;
1395  case 'Institution':
1396  $this->userObj->setInstitution($this->getCDataWithoutTags($this->cdata));
1397  break;
1398 
1399  case 'Street':
1400  $this->userObj->setStreet($this->getCDataWithoutTags($this->cdata));
1401  break;
1402 
1403  case 'City':
1404  $this->userObj->setCity($this->getCDataWithoutTags($this->cdata));
1405  break;
1406 
1407  case 'PostalCode':
1408  $this->userObj->setZipcode($this->getCDataWithoutTags($this->cdata));
1409  break;
1410 
1411  case 'Country':
1412  $this->userObj->setCountry($this->getCDataWithoutTags($this->cdata));
1413  break;
1414 
1415  case 'SelCountry':
1416  $this->userObj->setSelectedCountry($this->getCDataWithoutTags($this->cdata));
1417  break;
1418 
1419  case 'PhoneOffice':
1420  $this->userObj->setPhoneOffice($this->getCDataWithoutTags($this->cdata));
1421  break;
1422 
1423  case 'PhoneHome':
1424  $this->userObj->setPhoneHome($this->getCDataWithoutTags($this->cdata));
1425  break;
1426 
1427  case 'PhoneMobile':
1428  $this->userObj->setPhoneMobile($this->getCDataWithoutTags($this->cdata));
1429  break;
1430 
1431  case 'Fax':
1432  $this->userObj->setFax($this->getCDataWithoutTags($this->cdata));
1433  break;
1434 
1435  case 'Hobby':
1436  $this->userObj->setHobby($this->getCDataWithoutTags($this->cdata));
1437  break;
1438 
1439  case 'GeneralInterest':
1440  case 'OfferingHelp':
1441  case 'LookingForHelp':
1442  $this->multi_values[$a_name][] = $this->getCDataWithoutTags($this->cdata);
1443  break;
1444 
1445  case 'Comment':
1446  $this->userObj->setComment($this->getCDataWithoutTags($this->cdata));
1447  break;
1448 
1449  case 'Department':
1450  $this->userObj->setDepartment($this->getCDataWithoutTags($this->cdata));
1451  break;
1452 
1453  case 'Matriculation':
1454  $this->userObj->setMatriculation($this->getCDataWithoutTags($this->cdata));
1455  break;
1456 
1457  case 'Active':
1458  $this->currActive = $this->cdata;
1459  break;
1460 
1461  case 'ClientIP':
1462  $this->userObj->setClientIP($this->getCDataWithoutTags($this->cdata));
1463  break;
1464 
1465  case 'TimeLimitOwner':
1466  $this->time_limit_owner_set = true;
1467  $this->userObj->setTimeLimitOwner((int) $this->cdata);
1468  break;
1469 
1470  case 'TimeLimitUnlimited':
1471  $this->time_limit_set = true;
1472  $this->userObj->setTimeLimitUnlimited((bool) $this->cdata);
1473  break;
1474 
1475  case 'TimeLimitFrom':
1476  if (is_numeric($this->cdata)) {
1477  // Treat cdata as a unix timestamp
1478  $this->userObj->setTimeLimitFrom((int) $this->cdata);
1479  } else {
1480  // Try to convert cdata into unix timestamp, or ignore it
1481  $timestamp = strtotime($this->cdata);
1482  if ($timestamp !== false && trim($this->cdata) !== '0000-00-00 00:00:00') {
1483  $this->userObj->setTimeLimitFrom($timestamp);
1484  } elseif ($this->cdata === '0000-00-00 00:00:00') {
1485  $this->userObj->setTimeLimitFrom(null);
1486  }
1487  }
1488  break;
1489 
1490  case 'TimeLimitUntil':
1491  if (is_numeric($this->cdata)) {
1492  // Treat cdata as a unix timestamp
1493  $this->userObj->setTimeLimitUntil((int) $this->cdata);
1494  } else {
1495  // Try to convert cdata into unix timestamp, or ignore it
1496  $timestamp = strtotime($this->cdata);
1497  if ($timestamp !== false && trim($this->cdata) !== '0000-00-00 00:00:00') {
1498  $this->userObj->setTimeLimitUntil($timestamp);
1499  } elseif ($this->cdata === '0000-00-00 00:00:00') {
1500  $this->userObj->setTimeLimitUntil(null);
1501  }
1502  }
1503  break;
1504 
1505  case 'TimeLimitMessage':
1506  $this->userObj->setTimeLimitMessage($this->cdata);
1507  break;
1508 
1509  case 'ApproveDate':
1510  $this->approve_date_set = true;
1511  if (is_numeric($this->cdata)) {
1512  // Treat cdata as a unix timestamp
1513  $tmp_date = new ilDateTime($this->cdata, IL_CAL_UNIX);
1514  $this->userObj->setApproveDate($tmp_date->get(IL_CAL_DATETIME));
1515  } else {
1516  // Try to convert cdata into unix timestamp, or ignore it
1517  $timestamp = strtotime($this->cdata);
1518  if ($timestamp !== false && trim($this->cdata) !== '0000-00-00 00:00:00') {
1519  $tmp_date = new ilDateTime($timestamp, IL_CAL_UNIX);
1520  $this->userObj->setApproveDate($tmp_date->get(IL_CAL_DATETIME));
1521  } elseif ($this->cdata === '0000-00-00 00:00:00') {
1522  $this->userObj->setApproveDate(null);
1523  }
1524  }
1525  break;
1526 
1527  case 'AgreeDate':
1528  if (is_numeric($this->cdata)) {
1529  // Treat cdata as a unix timestamp
1530  $tmp_date = new ilDateTime($this->cdata, IL_CAL_UNIX);
1531  $this->userObj->setAgreeDate($tmp_date->get(IL_CAL_DATETIME));
1532  } else {
1533  // Try to convert cdata into unix timestamp, or ignore it
1534  $timestamp = strtotime($this->cdata);
1535  if ($timestamp !== false && trim($this->cdata) !== '0000-00-00 00:00:00') {
1536  $tmp_date = new ilDateTime($timestamp, IL_CAL_UNIX);
1537  $this->userObj->setAgreeDate($tmp_date->get(IL_CAL_DATETIME));
1538  } elseif ($this->cdata === '0000-00-00 00:00:00') {
1539  $this->userObj->setAgreeDate(null);
1540  }
1541  }
1542  break;
1543 
1544  case 'ExternalAccount':
1545  $this->userObj->setExternalAccount($this->getCDataWithoutTags($this->cdata));
1546  break;
1547 
1548  case 'Look':
1549  $this->updateLookAndSkin = false;
1550  if ($this->skin !== '' && $this->style !== '') {
1551  if (is_array($this->userStyles)) {
1552  if (in_array($this->skin . ':' . $this->style, $this->userStyles)) {
1553  $this->userObj->setPref('skin', $this->skin);
1554  $this->userObj->setPref('style', $this->style);
1555  $this->updateLookAndSkin = true;
1556  }
1557  }
1558  }
1559  break;
1560 
1561  case 'UserDefinedField':
1563 
1564  $field_id = $udf->fetchFieldIdFromImportId($this->tmp_udf_id);
1565 
1566  if ($field_id === 0) {
1567  $field_id = $udf->fetchFieldIdFromName($this->tmp_udf_name);
1568  }
1569 
1570  if ($field_id === 0) {
1571  break;
1572  }
1573 
1574  $this->udf_data[$field_id] = strip_tags($this->cdata, ilRTESettings::_getUsedHTMLTags('textarea'));
1575 
1576  break;
1577  case 'AccountInfo':
1578  if ($this->current_messenger_type === 'external') {
1579  $this->userObj->setExternalAccount($this->cdata);
1580  }
1581  break;
1582  case 'Pref':
1583  if ($this->currentPrefKey != null && strlen(trim($this->cdata)) > 0
1584  && ilUserXMLWriter::isPrefExportable($this->currentPrefKey)) {
1585  $this->prefs[$this->currentPrefKey] = trim($this->cdata);
1586  }
1587  $this->currentPrefKey = null;
1588  break;
1589  }
1590  }
1591 
1596  public function saveTempImage(
1597  string $image_data,
1598  string $filename
1599  ): string {
1600  $tempname = ilFileUtils::ilTempnam() . $filename;
1601  $fh = fopen($tempname, 'wb');
1602  if ($fh == false) {
1603  return '';
1604  }
1605  fwrite($fh, $image_data);
1606  fclose($fh);
1607  return $tempname;
1608  }
1609 
1613  public function verifyEndTag(
1614  $a_xml_parser,
1615  string $a_name
1616  ): void {
1617  $externalAccountHasChanged = false;
1618 
1619  switch ($a_name) {
1620  case 'Role':
1621  $this->roles[$this->current_role_id]['name'] = $this->cdata;
1622  $this->roles[$this->current_role_id]['type'] = $this->current_role_type;
1623  $this->roles[$this->current_role_id]['action'] = $this->current_role_action;
1624  break;
1625 
1626  case 'User':
1627  $this->userObj->setFullname();
1628  if ($this->user_id != -1 && ($this->action === 'Update' || $this->action === 'Delete')) {
1629  $user_id = $this->user_id;
1630  $user_exists = !is_null(ilObjUser::_lookupLogin($user_id));
1631  } else {
1632  $user_id = ilObjUser::getUserIdByLogin($this->userObj->getLogin());
1633  $user_exists = $user_id != 0;
1634  }
1635  if (is_null($this->userObj->getLogin())) {
1636  $this->logFailure('---', sprintf($this->lng->txt('usrimport_xml_element_for_action_required'), 'Login', 'Insert'));
1637  }
1638 
1639  if ($user_id === (int) ANONYMOUS_USER_ID || $user_id === (int) SYSTEM_USER_ID) {
1640  $this->logWarning($this->userObj->getLogin(), $this->lng->txt('usrimport_xml_anonymous_or_root_not_allowed'));
1641  break;
1642  }
1643 
1644  switch ($this->action) {
1645  case 'Insert':
1646  if ($user_exists and $this->conflict_rule === self::IL_FAIL_ON_CONFLICT) {
1647  $this->logWarning($this->userObj->getLogin(), $this->lng->txt('usrimport_cant_insert'));
1648  }
1649  if (is_null($this->userObj->getGender()) && $this->isFieldRequired('gender')) {
1650  $this->logFailure($this->userObj->getLogin(), sprintf($this->lng->txt('usrimport_xml_element_for_action_required'), 'Gender', 'Insert'));
1651  }
1652  if (is_null($this->userObj->getFirstname())) {
1653  $this->logFailure($this->userObj->getLogin(), sprintf($this->lng->txt('usrimport_xml_element_for_action_required'), 'Firstname', 'Insert'));
1654  }
1655  if (is_null($this->userObj->getLastname())) {
1656  $this->logFailure($this->userObj->getLogin(), sprintf($this->lng->txt('usrimport_xml_element_for_action_required'), 'Lastname', 'Insert'));
1657  }
1658  if (count($this->roles) == 0) {
1659  $this->logFailure($this->userObj->getLogin(), sprintf($this->lng->txt('usrimport_xml_element_for_action_required'), 'Role', 'Insert'));
1660  } else {
1661  $has_global_role = false;
1662  foreach ($this->roles as $role) {
1663  if ($role['type'] === 'Global') {
1664  $has_global_role = true;
1665  break;
1666  }
1667  }
1668  if (!$has_global_role) {
1669  $this->logFailure($this->userObj->getLogin(), sprintf($this->lng->txt('usrimport_global_role_for_action_required'), 'Insert'));
1670  }
1671  }
1672  break;
1673  case 'Update':
1674  if (!$user_exists) {
1675  $this->logWarning($this->userObj->getLogin(), $this->lng->txt('usrimport_cant_update'));
1676  } elseif ($this->user_id != -1 && $this->tagContained('Login')) {
1677  // check if someone owns the new login name!
1678  $someonesId = ilObjUser::_lookupId($this->userObj->getLogin());
1679 
1680  if (is_numeric($someonesId) && $someonesId != $this->user_id) {
1681  $this->logFailure($this->userObj->getLogin(), $this->lng->txt('usrimport_login_is_not_unique'));
1682  }
1683  }
1684  break;
1685  case 'Delete':
1686  if (!$user_exists) {
1687  $this->logWarning($this->userObj->getLogin(), $this->lng->txt('usrimport_cant_delete'));
1688  }
1689  break;
1690  }
1691 
1692  // init role array for next user
1693  $this->roles = [];
1694  break;
1695 
1696  case 'Login':
1697  if (array_key_exists($this->cdata, $this->logins)) {
1698  $this->logWarning($this->cdata, $this->lng->txt('usrimport_login_is_not_unique'));
1699  } else {
1700  $this->logins[$this->cdata] = $this->cdata;
1701  }
1702  $this->userObj->setLogin($this->stripTags($this->cdata));
1703  break;
1704 
1705  case 'Password':
1706  switch ($this->currPasswordType) {
1707  case 'BCRYPT':
1708  $this->userObj->setPasswd($this->cdata, ilObjUser::PASSWD_CRYPTED);
1709  $this->userObj->setPasswordEncodingType('bcryptphp');
1710  $this->userObj->setPasswordSalt(null);
1711  break;
1712 
1713  case 'PLAIN':
1714  $this->userObj->setPasswd($this->cdata, ilObjUser::PASSWD_PLAIN);
1715  $this->acc_mail->setUserPassword((string) $this->currPassword);
1716  break;
1717 
1718  default:
1719  $this->logFailure($this->userObj->getLogin(), sprintf($this->lng->txt('usrimport_xml_attribute_value_illegal'), 'Type', 'Password', $this->stripTags($this->currPasswordType)));
1720  break;
1721  }
1722  break;
1723 
1724  case 'Firstname':
1725  $this->userObj->setFirstname($this->cdata);
1726  break;
1727 
1728  case 'Lastname':
1729  $this->userObj->setLastname($this->cdata);
1730  break;
1731 
1732  case 'Title':
1733  $this->userObj->setUTitle($this->cdata);
1734  break;
1735 
1736  case 'Gender':
1737  if (!in_array(strtolower($this->cdata), ['n', 'm', 'f', ''])) {
1738  $this->logFailure(
1739  $this->userObj->getLogin(),
1740  sprintf($this->lng->txt('usrimport_xml_element_content_illegal'), 'Gender', $this->stripTags($this->cdata))
1741  );
1742  }
1743  $this->userObj->setGender($this->cdata);
1744  break;
1745 
1746  case 'Email':
1747  $this->userObj->setEmail($this->cdata);
1748  break;
1749  case 'SecondEmail':
1750  $this->userObj->setSecondEmail($this->cdata);
1751  break;
1752  case 'Institution':
1753  $this->userObj->setInstitution($this->cdata);
1754  break;
1755 
1756  case 'Street':
1757  $this->userObj->setStreet($this->cdata);
1758  break;
1759 
1760  case 'City':
1761  $this->userObj->setCity($this->cdata);
1762  break;
1763 
1764  case 'PostalCode':
1765  $this->userObj->setZipcode($this->cdata);
1766  break;
1767 
1768  case 'Country':
1769  $this->userObj->setCountry($this->cdata);
1770  break;
1771 
1772  case 'SelCountry':
1773  if (mb_strlen($this->cdata) !== 2) {
1774  $this->logFailure(
1775  $this->userObj->getLogin(),
1776  sprintf($this->lng->txt('usrimport_xml_element_content_illegal'), 'SelCountry', $this->stripTags($this->cdata))
1777  );
1778  }
1779  $this->userObj->setSelectedCountry($this->cdata);
1780  break;
1781 
1782  case 'PhoneOffice':
1783  $this->userObj->setPhoneOffice($this->cdata);
1784  break;
1785 
1786  case 'PhoneHome':
1787  $this->userObj->setPhoneHome($this->cdata);
1788  break;
1789 
1790  case 'PhoneMobile':
1791  $this->userObj->setPhoneMobile($this->cdata);
1792  break;
1793 
1794  case 'Fax':
1795  $this->userObj->setFax($this->cdata);
1796  break;
1797 
1798  case 'Hobby':
1799  $this->userObj->setHobby($this->cdata);
1800  break;
1801 
1802  case 'GeneralInterest':
1803  case 'OfferingHelp':
1804  case 'LookingForHelp':
1805  $this->multi_values[$a_name][] = $this->cdata;
1806  break;
1807 
1808  case 'Comment':
1809  $this->userObj->setComment($this->cdata);
1810  break;
1811 
1812  case 'Department':
1813  $this->userObj->setDepartment($this->cdata);
1814  break;
1815 
1816  case 'Matriculation':
1817  $this->userObj->setMatriculation($this->cdata);
1818  break;
1819 
1820  case 'ExternalAccount':
1821  $am = ($this->userObj->getAuthMode() === 'default' || $this->userObj->getAuthMode() == '')
1822  ? ilAuthUtils::_getAuthModeName($this->settings->get('auth_mode'))
1823  : $this->userObj->getAuthMode();
1824  $loginForExternalAccount = (trim($this->cdata) == '')
1825  ? ''
1826  : ilObjUser::_checkExternalAuthAccount($am, trim($this->cdata));
1827  switch ($this->action) {
1828  case 'Insert':
1829  if ($loginForExternalAccount != '') {
1830  $this->logWarning($this->userObj->getLogin(), $this->lng->txt('usrimport_no_insert_ext_account_exists') . ' (' . $this->stripTags($this->cdata) . ')');
1831  }
1832  break;
1833 
1834  case 'Update':
1835  if ($loginForExternalAccount != '') {
1836  $externalAccountHasChanged = trim($this->cdata) != ilObjUser::_lookupExternalAccount($this->user_id);
1837  if ($externalAccountHasChanged && trim($loginForExternalAccount) != trim($this->userObj->getLogin())) {
1838  $this->logWarning(
1839  $this->userObj->getLogin(),
1840  $this->lng->txt('usrimport_no_update_ext_account_exists') . ' (' . $this->stripTags($this->cdata) . ' for ' . $this->stripTags($loginForExternalAccount) . ')'
1841  );
1842  }
1843  }
1844  break;
1845  }
1846  if ($externalAccountHasChanged) {
1847  $this->userObj->setExternalAccount(trim($this->cdata));
1848  }
1849  break;
1850 
1851  case 'Active':
1852  if ($this->cdata !== 'true'
1853  && $this->cdata !== 'false') {
1854  $this->logFailure(
1855  $this->userObj->getLogin(),
1856  sprintf($this->lng->txt('usrimport_xml_element_content_illegal'), 'Active', $this->stripTags($this->cdata))
1857  );
1858  }
1859  $this->currActive = $this->cdata;
1860  break;
1861  case 'TimeLimitOwner':
1862  if (!preg_match('/\d+/', $this->cdata)) {
1863  $this->logFailure(
1864  $this->userObj->getLogin(),
1865  sprintf($this->lng->txt('usrimport_xml_element_content_illegal'), 'TimeLimitOwner', $this->stripTags($this->cdata))
1866  );
1867  } elseif (!$this->access->checkAccess('cat_administrate_users', '', (int) $this->cdata)) {
1868  $this->logFailure(
1869  $this->userObj->getLogin(),
1870  sprintf($this->lng->txt('usrimport_xml_element_content_illegal'), 'TimeLimitOwner', $this->stripTags($this->cdata))
1871  );
1872  } elseif ($this->object_data_cache->lookupType($this->object_data_cache->lookupObjId((int) $this->cdata)) !== 'cat' && !(int) $this->cdata == USER_FOLDER_ID) {
1873  $this->logFailure(
1874  $this->userObj->getLogin(),
1875  sprintf($this->lng->txt('usrimport_xml_element_content_illegal'), 'TimeLimitOwner', $this->stripTags($this->cdata))
1876  );
1877  }
1878  $this->userObj->setTimeLimitOwner((int) $this->cdata);
1879  break;
1880  case 'TimeLimitUnlimited':
1881  switch (strtolower($this->cdata)) {
1882  case 'true':
1883  case '1':
1884  $this->userObj->setTimeLimitUnlimited(true);
1885  break;
1886  case 'false':
1887  case '0':
1888  $this->userObj->setTimeLimitUnlimited(false);
1889  break;
1890  default:
1891  $this->logFailure($this->userObj->getLogin(), sprintf($this->lng->txt('usrimport_xml_element_content_illegal'), 'TimeLimitUnlimited', $this->stripTags($this->cdata)));
1892  break;
1893  }
1894  break;
1895  case 'TimeLimitFrom':
1896  // Accept datetime or Unix timestamp
1897  if (strtotime($this->cdata) === false && !is_numeric($this->cdata)) {
1898  $this->logFailure($this->userObj->getLogin(), sprintf($this->lng->txt('usrimport_xml_element_content_illegal'), 'TimeLimitFrom', $this->stripTags($this->cdata)));
1899  }
1900  $this->userObj->setTimeLimitFrom((int) $this->cdata);
1901  break;
1902  case 'TimeLimitUntil':
1903  // Accept datetime or Unix timestamp
1904  if (strtotime($this->cdata) === false && !is_numeric($this->cdata)) {
1905  $this->logFailure($this->userObj->getLogin(), sprintf($this->lng->txt('usrimport_xml_element_content_illegal'), 'TimeLimitUntil', $this->stripTags($this->cdata)));
1906  }
1907  $this->userObj->setTimeLimitUntil((int) $this->cdata);
1908  break;
1909  case 'TimeLimitMessage':
1910  switch (strtolower($this->cdata)) {
1911  case '1':
1912  $this->userObj->setTimeLimitMessage('1');
1913  break;
1914  case '0':
1915  $this->userObj->setTimeLimitMessage('0');
1916  break;
1917  default:
1918  $this->logFailure($this->userObj->getLogin(), sprintf($this->lng->txt('usrimport_xml_element_content_illegal'), 'TimeLimitMessage', $this->stripTags($this->cdata)));
1919  break;
1920  }
1921  break;
1922  case 'ApproveDate':
1923  // Accept datetime or Unix timestamp
1924  if (strtotime($this->cdata) === false && !is_numeric($this->cdata) && !$this->cdata === '0000-00-00 00:00:00') {
1925  $this->logFailure($this->userObj->getLogin(), sprintf($this->lng->txt('usrimport_xml_element_content_illegal'), 'ApproveDate', $this->stripTags($this->cdata)));
1926  }
1927  break;
1928  case 'AgreeDate':
1929  // Accept datetime or Unix timestamp
1930  if (strtotime($this->cdata) === false && !is_numeric($this->cdata) && !$this->cdata === '0000-00-00 00:00:00') {
1931  $this->logFailure($this->userObj->getLogin(), sprintf($this->lng->txt('usrimport_xml_element_content_illegal'), 'AgreeDate', $this->stripTags($this->cdata)));
1932  }
1933  break;
1934  case 'Pref':
1935  if ($this->currentPrefKey != null) {
1936  $this->verifyPref($this->currentPrefKey, $this->cdata);
1937  }
1938  }
1939  }
1940 
1945  public function handlerCharacterData(
1946  $a_xml_parser,
1947  string $a_data
1948  ): void {
1949  if ($a_data !== "\n") {
1950  $a_data = preg_replace('/\t+/', ' ', $a_data);
1951  }
1952 
1953  if (strlen($a_data) > 0) {
1954  $this->cdata .= $a_data;
1955  }
1956  }
1957 
1961  public function getCollectedRoles(): array
1962  {
1963  return $this->roles;
1964  }
1965 
1966  public function getUserCount(): int
1967  {
1968  return $this->userCount;
1969  }
1970 
1974  public function logWarning(
1975  string $aLogin,
1976  string $aMessage
1977  ): void {
1978  if (!array_key_exists($aLogin, $this->protocol)) {
1979  $this->protocol[$aLogin] = [];
1980  }
1981  if ($aMessage) {
1982  $this->protocol[$aLogin][] = $aMessage;
1983  }
1984  if ($this->error_level === self::IL_IMPORT_SUCCESS) {
1985  $this->error_level = self::IL_IMPORT_WARNING;
1986  }
1987  }
1988 
1992  public function logFailure(
1993  string $aLogin,
1994  string $aMessage
1995  ): void {
1996  if (!array_key_exists($aLogin, $this->protocol)) {
1997  $this->protocol[$aLogin] = [];
1998  }
1999  if ($aMessage) {
2000  $this->protocol[$aLogin][] = $aMessage;
2001  }
2002  $this->error_level = self::IL_IMPORT_FAILURE;
2003  }
2004 
2008  public function logSuccess(
2009  string $aLogin,
2010  int $userid,
2011  string $action
2012  ): void {
2013  $this->user_mapping[$userid] = ['login' => $aLogin, 'action' => $action, 'message' => 'successful'];
2014  }
2015 
2016 
2024  public function getProtocol(): array
2025  {
2026  return $this->protocol;
2027  }
2028 
2032  public function getProtocolAsHTML(string $a_log_title): string
2033  {
2034  $block = new ilTemplate('tpl.usr_import_log_block.html', true, true, 'components/ILIAS/User');
2035  $block->setVariable('TXT_LOG_TITLE', $a_log_title);
2036  $block->setVariable('TXT_MESSAGE_ID', $this->lng->txt('login'));
2037  $block->setVariable('TXT_MESSAGE_TEXT', $this->lng->txt('message'));
2038  foreach ($this->getProtocol() as $login => $messages) {
2039  $block->setCurrentBlock('log_row');
2040  $reason = '';
2041  foreach ($messages as $message) {
2042  if ($reason == '') {
2043  $reason = $message;
2044  } else {
2045  $reason .= '<br>' . $message;
2046  }
2047  }
2048  $block->setVariable('MESSAGE_ID', $login);
2049  $block->setVariable('MESSAGE_TEXT', $reason);
2050  $block->parseCurrentBlock();
2051  }
2052  return $block->get();
2053  }
2054 
2058  public function isSuccess(): bool
2059  {
2060  return $this->error_level === self::IL_IMPORT_SUCCESS;
2061  }
2062 
2067  public function getErrorLevel(): int
2068  {
2069  return $this->error_level;
2070  }
2071 
2076  public function getUserMapping(): array
2077  {
2078  return $this->user_mapping;
2079  }
2080 
2084  public function sendAccountMail(): void
2085  {
2086  if ($this->req_send_mail != '' ||
2087  ($this->isSendMail() && $this->userObj->getEmail() != '')) {
2088  $this->acc_mail->setUser($this->userObj);
2089  $this->acc_mail->send();
2090  }
2091  }
2092 
2093  public function setSendMail(bool $value): void
2094  {
2095  $this->send_mail = $value;
2096  }
2097 
2098  public function isSendMail(): bool
2099  {
2100  return $this->send_mail;
2101  }
2102 
2108  public function setUserMappingMode(int $value): void
2109  {
2110  if ($value === self::IL_USER_MAPPING_ID || $value === self::IL_USER_MAPPING_LOGIN) {
2111  $this->mapping_mode = $value;
2112  } else {
2113  die('wrong argument using methode setUserMappingMethod in ' . __FILE__);
2114  }
2115  }
2116 
2121  public function getUserMappingMode(): int
2122  {
2123  return $this->mapping_mode;
2124  }
2125 
2129  private function readRequiredFields(): array
2130  {
2131  if (is_array($this->required_fields)) {
2132  return $this->required_fields;
2133  }
2134  foreach ($this->settings->getAll() as $field => $value) {
2135  if (strpos($field, 'require_') === 0 && $value == 1) {
2136  $value = substr($field, 8);
2137  $this->required_fields[$value] = $value;
2138  }
2139  }
2140  return $this->required_fields ?: [];
2141  }
2142 
2147  private function checkProfileIncomplete(ilObjUser $user_obj): bool
2148  {
2149  return $this->user_profile->isProfileIncomplete($user_obj);
2150  }
2151 
2158  protected function isFieldRequired(string $fieldname): bool
2159  {
2160  $requiredFields = $this->readRequiredFields();
2161  $fieldname = strtolower(trim($fieldname));
2162  return array_key_exists($fieldname, $requiredFields);
2163  }
2164 
2165  private function verifyPref(string $key, string $value): void
2166  {
2167  switch ($key) {
2168  case 'mail_linebreak':
2169  case 'language':
2170  case 'skin':
2171  case 'style':
2172  case 'ilPageEditor_HTMLMode':
2173  case 'ilPageEditor_JavaScript':
2174  case 'ilPageEditor_MediaMode':
2175  case 'tst_javascript':
2176  case 'tst_lastquestiontype':
2177  case 'tst_multiline_answers':
2178  case 'tst_use_previous_answers':
2179  case 'graphicalAnswerSetting':
2180  case 'priv_feed_pass':
2181  $this->logFailure('---', "Preference {$this->stripTags($key)} is not supported.");
2182  break;
2183  case 'public_city':
2184  case 'public_country':
2185  case 'public_department':
2186  case 'public_email':
2187  case 'public_second_email':
2188  case 'public_fax':
2189  case 'public_hobby':
2190  case 'public_institution':
2191  case 'public_matriculation':
2192  case 'public_phone':
2193  case 'public_phone_home':
2194  case 'public_phone_mobile':
2195  case 'public_phone_office':
2196  case 'public_street':
2197  case 'public_upload':
2198  case 'public_zip':
2199  case 'public_interests_general':
2200  case 'public_interests_help_offered':
2201  case 'public_interests_help_looking':
2202  case 'send_info_mails':
2203  case 'bs_allow_to_contact_me':
2204  case 'chat_osc_accept_msg':
2205  case 'chat_broadcast_typing':
2206  case 'hide_own_online_status':
2207  if (!in_array($value, ['y', 'n', ''])) {
2208  $this->logFailure('---', "Wrong value '{$this->stripTags($value)}': Value 'y' or 'n' expected for preference {$this->stripTags($key)}.");
2209  }
2210  break;
2211  case 'public_profile':
2212  if (!in_array($value, ['y', 'n', 'g'])) {
2213  $this->logFailure('---', "Wrong value '{$this->stripTags($value)}': Value 'y', 'g' or 'n' expected for preference {$this->stripTags($key)}.");
2214  }
2215  break;
2216  case 'show_users_online':
2217  if (!in_array($value, ['y', 'n', 'associated'])) {
2218  $this->logFailure('---', "Wrong value '{$this->stripTags($value)}': Value 'y' or 'n' or 'associated' expected for preference {$this->stripTags($key)}.");
2219  }
2220  break;
2221  case 'mail_incoming_type':
2222  if (!in_array((int) $value, ['0','1','2'])) {
2223  $this->logFailure('---', "Wrong value '{$this->stripTags($value)}': Value '0' (LOCAL),'1' (EMAIL) or '2' (BOTH) expected for preference {$this->stripTags($key)}.");
2224  }
2225  break;
2226  case 'weekstart':
2227  if (!in_array($value, ['0','1'])) {
2228  $this->logFailure('---', "Wrong value '{$this->stripTags($value)}': Value '0' (Sunday) or '1' (Monday) expected for preference {$this->stripTags($key)}.");
2229  }
2230  break;
2231 
2232  case 'mail_signature':
2233  break;
2234  case 'user_tz':
2235  try {
2236  ilTimeZone::_getInstance($value);
2237  return;
2238  } catch (ilTimeZoneException $tze) {
2239  $this->logFailure('---', "Wrong value '{$this->stripTags($value)}': Invalid timezone $value detected for preference {$this->stripTags($key)}.");
2240  }
2241  break;
2242  default:
2243  if (!ilUserXMLWriter::isPrefExportable($key)) {
2244  $this->logFailure('---', "Preference {$this->stripTags($key)} is not supported.");
2245  }
2246  break;
2247  }
2248  }
2249 
2250  private function updateMailPreferences(int $usr_id): void
2251  {
2252  if (array_key_exists('mail_incoming_type', $this->prefs) ||
2253  array_key_exists('mail_signature', $this->prefs) ||
2254  array_key_exists('mail_linebreak', $this->prefs)
2255  ) {
2256  $mailOptions = new ilMailOptions($usr_id);
2257 
2258  $mailOptions->setSignature(array_key_exists('mail_signature', $this->prefs) ? $this->prefs['mail_signature'] : $mailOptions->getSignature());
2259  $mailOptions->setIncomingType(array_key_exists('mail_incoming_type', $this->prefs) ? (int) $this->prefs['mail_incoming_type'] : $mailOptions->getIncomingType());
2260  $mailOptions->updateOptions();
2261  }
2262  }
2263 
2264  private function getCDataWithoutTags(): string
2265  {
2266  return $this->stripTags($this->cdata);
2267  }
2268 
2269  private function stripTags(string $string): string
2270  {
2271  return $this->refinery->string()->stripTags()->transform($string);
2272  }
2273 }
Class ilObjRole.
ilRecommendedContentManager $recommended_content_manager
ilUserSettingsConfig $user_settings_config
sendAccountMail()
send account mail
const IL_INST_ID
Definition: constants.php:40
const IL_CAL_DATETIME
extractRolesEndTag( $a_xml_parser, string $a_name)
const ANONYMOUS_USER_ID
Definition: constants.php:27
const USER_FOLDER_ID
Definition: constants.php:33
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static _lookupActivatedStyle(string $a_skin, string $a_style)
lookup if a style is activated
saveTempImage(string $image_data, string $filename)
Saves binary image data to a temporary image file and returns the name of the image file on success...
getCourseMembersObjectForRole(int $a_role_id)
Returns the parent object of the role folder object which contains the specified role.
static _getInstance(string $a_tz='')
get instance by timezone
assignToRoleWithParents(ilObjUser $a_user_obj, int $a_role_id)
Assigns a user to a role and to all parent roles.
handlerBeginTag( $a_xml_parser, string $a_name, array $a_attribs)
Interface Observer Contains several chained tasks and infos about them.
verifyBeginTag( $a_xml_parser, string $a_name, array $a_attribs)
importEndTag( $a_xml_parser, string $a_name)
getUserMappingMode()
read access to user mapping mode
const SYSTEM_USER_ID
This file contains constants for PHPStan analyis, see: https://phpstan.org/config-reference#constants...
Definition: constants.php:26
static _getAllReferences(int $id)
get all reference ids for object ID
setRoleAssignment(array $a_assign)
set import to local role assignemt
isFieldRequired(string $fieldname)
determine if a field $fieldname is to a required field (global setting)
const PASSWD_PLAIN
checkProfileIncomplete(ilObjUser $user_obj)
Check if profile is incomplete Will set the usr_data field profile_incomplete if any required field i...
ilObjectDataCache $object_data_cache
setUserMappingMode(int $value)
write access to user mapping mode
Class ilUserProfile.
handlerCharacterData( $a_xml_parser, string $a_data)
handler for character data
static _lookupId($a_user_str)
logWarning(string $aLogin, string $aMessage)
Writes a warning log message to the protocol.
extractRolesBeginTag( $a_xml_parser, string $a_name, array $a_attribs)
isSuccess()
Returns true, if the import was successful.
array $userStyles
User assigned styles.
detachFromRole(ilObjUser $a_user_obj, int $a_role_id)
Detaches a user from a role.
static _checkExternalAuthAccount(string $a_auth, string $a_account, bool $tryFallback=true)
check whether external account and authentication method matches with a user
static _getActiveServerList()
Get active server list.
static _lookupExternalAccount(int $a_user_id)
$http
Definition: deliver.php:30
const IL_CAL_UNIX
static _getAuthModeName($a_auth_key)
static _uploadPersonalPicture(string $tmp_file, int $obj_id)
Create a personal picture image file from a temporary image file.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
static _getUsedHTMLTags(string $module='')
static getUserIdByLogin(string $a_login)
$messages
Definition: xapiexit.php:21
handlerEndTag( $a_xml_parser, string $a_name)
logSuccess(string $aLogin, int $userid, string $action)
Writes a success log message to the protocol.
$ref_id
Definition: ltiauth.php:65
static _lookupTitle(int $obj_id)
static _getInstanceByObjId(int $a_obj_id)
setHandlers($a_xml_parser)
set event handler should be overwritten by inherited class private
getProtocol()
The protocol is an associative array.
array $logins
This variable is used to collect each login that we encounter in the import data. ...
Class for TimeZone exceptions.
global $DIC
Definition: shib_login.php:26
Class ilObjForumAdministration.
array $localRoleCache
Cached local roles.
set(string $a_field, string $a_value)
verifyPref(string $key, string $value)
getUserMapping()
returns a map user_id <=> login
int $error_level
This variable is used to report the error level of the validation process or the importing process...
$filename
Definition: buildRTE.php:78
setFolderId(int $a_folder_id)
assign users to this folder (normally the usr_folder) But if called from local admin => the ref_id of...
logFailure(string $aLogin, string $aMessage)
Writes a failure log message to the protocol.
const PASSWD_CRYPTED
foreach($mandatory_scripts as $file) $timestamp
Definition: buildRTE.php:70
importBeginTag( $a_xml_parser, string $a_name, array $a_attribs)
static ilTempnam(?string $a_temp_path=null)
Returns a unique and non existing Path for e temporary file or directory.
getProtocolAsHTML(string $a_log_title)
Returns the protocol as a HTML table.
getErrorLevel()
Returns the error level.
static isPrefExportable(string $key)
returns wether a key from db is exportable or not
array $personalPicture
Cached personal picture of the actual user This is used because the ilObjUser object has no field for...
static __extractId(string $ilias_id, int $inst_id)
extract ref id from role title, e.g.
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins
Definition: plugin.php:23
__construct(Container $dic, ilPlugin $plugin)
buildTag(string $type, string $name, ?array $attr=null)
generate a tag with given name and attributes
array $protocol
The variable holds the protocol of the import.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
getParentRoleIds(int $a_role_id)
Get array of parent role ids from cache.
$message
Definition: xapiexit.php:31
getRoleObject(int $a_role_id)
Returns the parent object of the role folder object which contains the specified role.
Class ilRbacAdmin Core functions for role based access control.
static getActiveIdpList()
verifyEndTag( $a_xml_parser, string $a_name)
handler for end of element when in verify mode.
static _lookupType(int $id, bool $reference=false)
__construct(?string $path_to_file='', ?bool $throw_exception=false)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
array $parentRolesCache
Cached parent roles.
static _lookupLogin(int $a_user_id)
assignToRole(ilObjUser $a_user_obj, int $a_role_id)
Assigns a user to a role.