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